History

first cut at keeping local voxels

ZappoMan committed 13 years ago

Commit c25b03d1 parent 5e6e15d8 files · +271 −121Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 8 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+249−114
@@ -109,12 +109,15 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 108 unmodified lines
109109
110110 void VoxelSystem::voxelDeleted(VoxelNode* node) {
111111 if (node->isKnownBufferIndex() && (node->getVoxelSystem() == this)) {
112+ forceRemoveNodeFromArraysAsPartialVBO(node);
113+
114+ /***
112115 if (!_useFastVoxelPipeline || _inSetupNewVoxelsForDrawing || _writeRenderFullVBO) {
113116 freeBufferIndex(node->getBufferIndex());
114117 } else {
115118 forceRemoveNodeFromArraysAsPartialVBO(node);
116− freeBufferIndex(node->getBufferIndex());
117119 }
120+ ***/
118121 }
119122 }
120123
@@ -160,7 +163,9 @@ void VoxelSystem::voxelUpdated(VoxelNode* node) { · 39 unmodified lines
160163 }
161164 }
162165
163− updateNodeInArraysAsPartialVBO(node);
166+ const bool REUSE_INDEX = true;
167+ const bool DONT_FORCE_REDRAW = false;
168+ updateNodeInArrays(node, REUSE_INDEX, DONT_FORCE_REDRAW);
164169 _voxelsUpdated++;
165170
166171 node->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.
@@ -185,26 +190,44 @@ glBufferIndex VoxelSystem::getNextBufferIndex() { · 18 unmodified lines
185190 return output;
186191 }
187192
188−// Doesn't actually clean up the VBOs for the index, but does release responsibility of the index from the VoxelNode,
189−// and makes the index available for some other node to use
193+// Release responsibility of the buffer/vbo index from the VoxelNode, and makes the index available for some other node to use
194+// will also "clean up" the index data for the buffer/vbo slot, so that if it's in the middle of the draw range, the triangles
195+// will be "invisible"
190196 void VoxelSystem::freeBufferIndex(glBufferIndex index) {
191− _freeIndexes.push_back(index);
197+ assert(_voxelsInWriteArrays > 0);
198+
199+ // if the "freed" index was our max index, then just drop the _voxelsInWriteArrays down one...
200+ if (index == (_voxelsInWriteArrays - 1)) {
201+ _voxelsInWriteArrays--;
202+ } else {
203+ bool inList = false;
204+ // make sure the index isn't already in the free list...
205+ for (long i = 0; i < _freeIndexes.size(); i++) {
206+ if (_freeIndexes[i] == index) {
207+ printf("freeBufferIndex(glBufferIndex index)... index=%ld already in free list!\n", index);
208+ inList = true;
209+ break;
210+ }
211+ }
212+
213+ if (!inList) {
214+ // make the index available for next node that needs to be drawn
215+ _freeIndexes.push_back(index);
216+
217+ // make the VBO slot "invisible" in case this slot is not used
218+ const glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX);
219+ const float voxelScale = 0;
220+ const nodeColor BLACK = {0, 0, 0, 0};
221+ updateArraysDetails(index, startVertex, voxelScale, BLACK);
222+ }
223+ }
192224 }
193225
194226 // This will run through the list of _freeIndexes and reset their VBO array values to be "invisible".
195227 void VoxelSystem::clearFreeBufferIndexes() {
196228 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "###### clearFreeBufferIndexes()");
197−
198− for (int i = 0; i < _freeIndexes.size(); i++) {
199− glBufferIndex nodeIndex = _freeIndexes[i];
200− glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX);
201− float voxelScale = 0;
202− _writeVoxelDirtyArray[nodeIndex] = true;
203− nodeColor color = {0, 0, 0, 0};
204− updateNodeInArrays(nodeIndex, startVertex, voxelScale, color);
205− _abandonedVBOSlots++;
206− }
207229 _freeIndexes.clear();
230+ _abandonedVBOSlots = 0;
208231 }
209232
210233 VoxelSystem::~VoxelSystem() {
@@ -589,8 +612,11 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 378 unmodified lines
589612
590613
591614 if (!_useFastVoxelPipeline || _writeRenderFullVBO) {
615+//printf("parseData about to call setupNewVoxelsForDrawing();\n");
592616 setupNewVoxelsForDrawing();
593617 } else {
618+printf("parseData about to call checkForCulling() and setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY)\n");
619+ checkForCulling();
594620 setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
595621 }
596622
@@ -611,7 +637,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 14 unmodified lines
611637 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
612638
613639 // clear up the VBOs for any nodes that have been recently deleted.
614− clearFreeBufferIndexes();
640+ //clearFreeBufferIndexes();
615641
616642 bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
617643 if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
@@ -631,6 +657,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 13 unmodified lines
631657 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer);
632658 _callsToTreesToArrays++;
633659 if (_writeRenderFullVBO) {
660+ printf("resetting _freeIndexes and _voxelsInWriteArrays\n");
634661 _voxelsInWriteArrays = 0; // reset our VBO
635662 _freeIndexes.clear(); // reset our free indexes
636663 }
@@ -676,7 +703,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 39 unmodified lines
676703 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
677704
678705 // clear up the VBOs for any nodes that have been recently deleted.
679− clearFreeBufferIndexes();
706+ //clearFreeBufferIndexes();
680707
681708 bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
682709 if (allowBailEarly && !iAmDebugging &&
@@ -684,7 +711,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 1 unmodified line
684711 return; // bail early, it hasn't been long enough since the last time we ran
685712 }
686713
687− checkForCulling(); // check for out of view and deleted voxels...
714+ //checkForCulling(); // check for out of view and deleted voxels...
688715
689716 // lock on the buffer write lock so we can't modify the data when the GPU is reading it
690717 {
@@ -723,7 +750,12 @@ void VoxelSystem::checkForCulling() { · 32 unmodified lines
723750 // When we call removeOutOfView() voxels, we don't actually remove the voxels from the VBOs, but we do remove
724751 // them from tree, this makes our tree caclulations faster, but doesn't require us to fully rebuild the VBOs (which
725752 // can be expensive).
726− removeOutOfView();
753+ if (Menu::getInstance()->isOptionChecked(MenuOption::HideOutOfView)) {
754+ hideOutOfView();
755+ }
756+ if (!Menu::getInstance()->isOptionChecked(MenuOption::DontRemoveOutOfView)) {
757+ removeOutOfView();
758+ }
727759
728760 // Once we call cleanupRemovedVoxels() we do need to rebuild our VBOs (if anything was actually removed). So,
729761 // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on
@@ -747,6 +779,7 @@ void VoxelSystem::cleanupRemovedVoxels() { · 17 unmodified lines
747779 }
748780 _writeRenderFullVBO = true; // if we remove voxels, we must update our full VBOs
749781 }
782+
750783 // we also might have VBO slots that have been abandoned, if too many of our VBO slots
751784 // are abandonded we want to rerender our full VBOs
752785 const float TOO_MANY_ABANDONED_RATIO = 0.5f;
@@ -830,6 +863,7 @@ void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, · 77 unmodified lines
830863 void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) {
831864 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
832865 "copyWrittenDataToReadArrays()");
866+
833867 if (_voxelsDirty && _voxelsUpdated) {
834868 if (fullVBOs) {
835869 copyWrittenDataToReadArraysFullVBOs();
@@ -869,39 +903,21 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { · 33 unmodified lines
869903 }
870904 }
871905 if (_writeRenderFullVBO) {
872− voxelsUpdated += updateNodeInArraysAsFullVBO(node);
906+ const bool DONT_REUSE_INDEX = false;
907+ const bool FORCE_REDRAW = true;
908+//printf("newTreeToArrays() about to call updateNodeInArrays(node, DONT_REUSE_INDEX, FORCE_REDRAW);\n");
909+ voxelsUpdated += updateNodeInArrays(node, DONT_REUSE_INDEX, FORCE_REDRAW);
873910 } else {
874− voxelsUpdated += updateNodeInArraysAsPartialVBO(node);
911+ const bool REUSE_INDEX = true;
912+ const bool DONT_FORCE_REDRAW = false;
913+//printf("newTreeToArrays() about to call updateNodeInArrays(node, REUSE_INDEX, DONT_FORCE_REDRAW);\n");
914+ voxelsUpdated += updateNodeInArrays(node, REUSE_INDEX, DONT_FORCE_REDRAW);
875915 }
876916 node->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.
877917
878918 return voxelsUpdated;
879919 }
880920
881−int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) {
882− // If we've run out of room, then just bail...
883− if (_voxelsInWriteArrays >= _maxVoxels) {
884− return 0;
885− }
886−
887− if (node->getShouldRender()) {
888− glm::vec3 startVertex = node->getCorner();
889− float voxelScale = node->getScale();
890− glBufferIndex nodeIndex = getNextBufferIndex();
891−
892− // populate the array with points for the 8 vertices
893− // and RGB color for each added vertex
894− updateNodeInArrays(nodeIndex, startVertex, voxelScale, node->getColor());
895− node->setBufferIndex(nodeIndex);
896− node->setVoxelSystem(this);
897− return 1; // rendered
898− } else {
899− node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
900− }
901−
902− return 0; // not-rendered
903−}
904−
905921 // called as response to voxelDeleted() in fast pipeline case. The node
906922 // is being deleted, but it's state is such that it thinks it should render
907923 // and therefore we can't use the normal render calculations. This method
@@ -914,29 +930,22 @@ int VoxelSystem::forceRemoveNodeFromArraysAsPartialVBO(VoxelNode* node) { · 6 unmodified lines
914930
915931 // if the node is not in the VBOs then we have nothing to do!
916932 if (node->isKnownBufferIndex()) {
917−
918− // if we shouldn't render then set out location to some infinitely distant location,
919− // and our scale as infinitely small
920− glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX);
921− float voxelScale = 0;
922− _abandonedVBOSlots++;
923−
924933 // If this node has not yet been written to the array, then add it to the end of the array.
925934 glBufferIndex nodeIndex = node->getBufferIndex();
926−
927− _writeVoxelDirtyArray[nodeIndex] = true;
928−
929− // populate the array with points for the 8 vertices
930− // and RGB color for each added vertex
931− const nodeColor BLACK = { 0,0,0};
932− updateNodeInArrays(nodeIndex, startVertex, voxelScale, BLACK);
933−
935+ freeBufferIndex(nodeIndex); // NOTE: This is make the node invisible!
936+ node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
934937 return 1; // updated!
935938 }
936939 return 0; // not-updated
937940 }
938941
939−int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
942+int VoxelSystem::updateNodeInArrays(VoxelNode* node, bool reuseIndex, bool forceDraw) {
943+
944+/*
945+printf("updateNodeInArrays(VoxelNode* node=[%f, %f, %f] %f, bool reuseIndex=%s, bool forceDraw=%s)\n",
946+ node->getCorner().x,node->getCorner().y,node->getCorner().z, node->getScale(),
947+ debug::valueOf(reuseIndex),debug::valueOf(forceDraw));
948+*/
940949 // If we've run out of room, then just bail...
941950 if (_voxelsInWriteArrays >= _maxVoxels) {
942951 return 0;
@@ -946,64 +955,76 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 3 unmodified lines
946955 return 0;
947956 }
948957
949− // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays...
950− if (node->isDirty()) {
951− glm::vec3 startVertex;
952− float voxelScale = 0;
958+ // If we've changed any attributes (our renderness, our color, etc), or we've been told to force a redraw
959+ // then update the Arrays...
960+ if (forceDraw || node->isDirty()) {
961+ /*
962+ printf("updateNodeInArrays(VoxelNode* node=[%f, %f, %f] %f, bool reuseIndex=%s, bool forceDraw=%s)\n",
963+ node->getCorner().x,node->getCorner().y,node->getCorner().z, node->getScale(),
964+ debug::valueOf(reuseIndex),debug::valueOf(forceDraw));
965+ */
966+ //printf("....(isDirty() [isDirty()=%s] or forceRedraw=%s_...\n",debug::valueOf(node->isDirty()),debug::valueOf(forceDraw));
967+
953968 // If we're should render, use our legit location and scale,
954969 if (node->getShouldRender()) {
955− startVertex = node->getCorner();
956− voxelScale = node->getScale();
957− } else {
958− // if we shouldn't render then set out location to some infinitely distant location,
959− // and our scale as infinitely small
960− startVertex[0] = startVertex[1] = startVertex[2] = FLT_MAX;
961− voxelScale = 0;
962− _abandonedVBOSlots++;
963− }
964−
965− // If this node has not yet been written to the array, then add it to the end of the array.
966− glBufferIndex nodeIndex;
967− if (node->isKnownBufferIndex()) {
968− nodeIndex = node->getBufferIndex();
970+ //printf("....shouldRender()...\n");
971+ glm::vec3 startVertex = node->getCorner();
972+ float voxelScale = node->getScale();
973+
974+ glBufferIndex nodeIndex = GLBUFFER_INDEX_UNKNOWN;
975+ if (reuseIndex && node->isKnownBufferIndex()) {
976+ //printf("....shouldRender() and reuseIndex && node->isKnownBufferIndex() reusing...\n");
977+ nodeIndex = node->getBufferIndex();
978+ } else {
979+ //printf("....shouldRender() and NOT(reuseIndex && node->isKnownBufferIndex()) getting new index...\n");
980+ nodeIndex = getNextBufferIndex();
981+ node->setBufferIndex(nodeIndex);
982+ node->setVoxelSystem(this);
983+ }
984+ // populate the array with points for the 8 vertices and RGB color for each added vertex
985+ updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor());
986+ return 1; // updated!
969987 } else {
970− nodeIndex = getNextBufferIndex();
971− node->setBufferIndex(nodeIndex);
972− node->setVoxelSystem(this);
988+ //printf("....NOT shouldRender()...\n");
989+ // If we shouldn't render, but we did have a known index, then we will need to release our index
990+ if (reuseIndex && node->isKnownBufferIndex()) {
991+ //printf("....NOT shouldRender() and reuseIndex && node->isKnownBufferIndex() freeBufferIndex!...\n");
992+ freeBufferIndex(node->getBufferIndex()); // this will make the node invisible
993+ return 1; // updated!
994+ }
973995 }
974− _writeVoxelDirtyArray[nodeIndex] = true;
975−
976− // populate the array with points for the 8 vertices
977− // and RGB color for each added vertex
978− updateNodeInArrays(nodeIndex, startVertex, voxelScale, node->getColor());
979−
980− return 1; // updated!
996+ } else {
997+ //printf("....NOT (dirty [isDirty()=%s] or forceRedraw=%s_...\n",debug::valueOf(node->isDirty()),debug::valueOf(forceDraw));
981998 }
982999 return 0; // not-updated
9831000 }
9841001
985−void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& startVertex,
1002+void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
9861003 float voxelScale, const nodeColor& color) {
1004+
1005+ if (_initialized) {
1006+ _writeVoxelDirtyArray[nodeIndex] = true;
9871007
988− if (_useVoxelShader) {
989− if (_writeVoxelShaderData) {
990− VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
991− writeVerticesAt->x = startVertex.x * TREE_SCALE;
992− writeVerticesAt->y = startVertex.y * TREE_SCALE;
993− writeVerticesAt->z = startVertex.z * TREE_SCALE;
994− writeVerticesAt->s = voxelScale * TREE_SCALE;
995− writeVerticesAt->r = color[RED_INDEX];
996− writeVerticesAt->g = color[GREEN_INDEX];
997− writeVerticesAt->b = color[BLUE_INDEX];
998− }
999− } else {
1000− if (_writeVerticesArray && _writeColorsArray) {
1001− int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL;
1002− for (int j = 0; j < vertexPointsPerVoxel; j++ ) {
1003− GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * vertexPointsPerVoxel);
1004− GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * vertexPointsPerVoxel);
1005− *(writeVerticesAt+j) = startVertex[j % 3] + (identityVerticesGlobalNormals[j] * voxelScale);
1006− *(writeColorsAt +j) = color[j % 3];
1008+ if (_useVoxelShader) {
1009+ if (_writeVoxelShaderData) {
1010+ VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
1011+ writeVerticesAt->x = startVertex.x * TREE_SCALE;
1012+ writeVerticesAt->y = startVertex.y * TREE_SCALE;
1013+ writeVerticesAt->z = startVertex.z * TREE_SCALE;
1014+ writeVerticesAt->s = voxelScale * TREE_SCALE;
1015+ writeVerticesAt->r = color[RED_INDEX];
1016+ writeVerticesAt->g = color[GREEN_INDEX];
1017+ writeVerticesAt->b = color[BLUE_INDEX];
1018+ }
1019+ } else {
1020+ if (_writeVerticesArray && _writeColorsArray) {
1021+ int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL;
1022+ for (int j = 0; j < vertexPointsPerVoxel; j++ ) {
1023+ GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * vertexPointsPerVoxel);
1024+ GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * vertexPointsPerVoxel);
1025+ *(writeVerticesAt+j) = startVertex[j % 3] + (identityVerticesGlobalNormals[j] * voxelScale);
1026+ *(writeColorsAt +j) = color[j % 3];
1027+ }
10071028 }
10081029 }
10091030 }
@@ -1517,7 +1538,7 @@ public: · 507 unmodified lines
15171538 unsigned long nodesIntersect;
15181539 unsigned long nodesOutside;
15191540
1520− removeOutOfViewArgs(VoxelSystem* voxelSystem) :
1541+ removeOutOfViewArgs(VoxelSystem* voxelSystem, bool widenViewFrustum = true) :
15211542 thisVoxelSystem(voxelSystem),
15221543 thisViewFrustum(*voxelSystem->getViewFrustum()),
15231544 dontRecurseBag(),
@@ -1528,10 +1549,12 @@ public: · 4 unmodified lines
15281549 nodesOutside(0)
15291550 {
15301551 // Widen the FOV for trimming
1531− float originalFOV = thisViewFrustum.getFieldOfView();
1532− float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
1533− thisViewFrustum.setFieldOfView(wideFOV);
1534− thisViewFrustum.calculate();
1552+ if (widenViewFrustum) {
1553+ float originalFOV = thisViewFrustum.getFieldOfView();
1554+ float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
1555+ thisViewFrustum.setFieldOfView(wideFOV);
1556+ thisViewFrustum.calculate();
1557+ }
15351558 }
15361559 };
15371560
@@ -1587,6 +1610,80 @@ bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) { · 49 unmodified lines
15871610 return true; // keep going!
15881611 }
15891612
1613+// "hide" voxels in the VBOs that are still in the tree that but not in view.
1614+// We don't remove them from the tree, we don't delete them, we do remove them
1615+// from the VBOs and mark them as such in the tree.
1616+bool VoxelSystem::hideOutOfViewOperation(VoxelNode* node, void* extraData) {
1617+ removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData;
1618+
1619+ // If our node was previously added to the don't recurse bag, then return false to
1620+ // stop the further recursion. This means that the whole node and it's children are
1621+ // known to be in view, so don't recurse them
1622+ if (args->dontRecurseBag.contains(node)) {
1623+ args->dontRecurseBag.remove(node);
1624+ return false; // stop recursion
1625+ }
1626+
1627+ VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
1628+ args->nodesScanned++;
1629+ // Need to operate on our child nodes, so we can remove them
1630+ for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
1631+ VoxelNode* childNode = node->getChildAtIndex(i);
1632+ if (childNode) {
1633+ ViewFrustum::location inFrustum = childNode->inFrustum(args->thisViewFrustum);
1634+ switch (inFrustum) {
1635+ case ViewFrustum::OUTSIDE: {
1636+ args->nodesOutside++;
1637+ if (childNode->isKnownBufferIndex()) {
1638+ args->nodesRemoved++;
1639+ thisVoxelSystem->forceRemoveNodeFromArraysAsPartialVBO(childNode);
1640+ thisVoxelSystem->_voxelsUpdated++;
1641+ thisVoxelSystem->setupNewVoxelsForDrawingSingleNode();
1642+ }
1643+ // how to handle recursion???? we probably want to continue
1644+ } break;
1645+ case ViewFrustum::INSIDE: {
1646+
1647+ // if the child node is fully INSIDE the view, then there's no need to recurse it
1648+ // because we know all it's children will also be in the view, so we want to
1649+ // tell the caller to NOT recurse this child
1650+ args->nodesInside++;
1651+
1652+ if (childNode->getShouldRender() && !childNode->isKnownBufferIndex()) {
1653+ /*
1654+ printf("in view, isKnownIndex()=%s isDirty()=%s shouldRender()=%s\n",
1655+ debug::valueOf(childNode->isKnownBufferIndex()),
1656+ debug::valueOf(childNode->isDirty()),
1657+ debug::valueOf(childNode->getShouldRender()));
1658+ */
1659+ childNode->setDirtyBit(); // will this make it draw?
1660+ }
1661+ //args->dontRecurseBag.insert(childNode);
1662+ } break;
1663+ case ViewFrustum::INTERSECT: {
1664+ // if the child node INTERSECTs the view, then we don't want to remove it because
1665+ // it is at least partially in view. But we DO want to recurse the children because
1666+ // some of them may not be in view... nothing specifically to do, just keep iterating
1667+ // the children
1668+ args->nodesIntersect++;
1669+
1670+ if (childNode->getShouldRender() && !childNode->isKnownBufferIndex()) {
1671+ /*
1672+ printf("intersect view, isKnownIndex()=%s isDirty()=%s shouldRender()=%s\n",
1673+ debug::valueOf(childNode->isKnownBufferIndex()),
1674+ debug::valueOf(childNode->isDirty()),
1675+ debug::valueOf(childNode->getShouldRender()));
1676+ */
1677+ childNode->setDirtyBit(); // will this make it draw?
1678+ }
1679+
1680+ } break;
1681+ }
1682+ }
1683+ }
1684+ return true; // keep going!
1685+}
1686+
15901687
15911688 bool VoxelSystem::isViewChanging() {
15921689 bool result = false; // assume the best
@@ -1632,6 +1729,29 @@ void VoxelSystem::removeOutOfView() { · 39 unmodified lines
16321729 }
16331730 }
16341731
1732+void VoxelSystem::hideOutOfView() {
1733+ PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "hideOutOfView()",true);
1734+ removeOutOfViewArgs args(this, true); // widen to match server!
1735+ _tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);
1736+
1737+ if (args.nodesRemoved) {
1738+ _tree->setDirtyBit();
1739+ setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
1740+ }
1741+
1742+
1743+ bool showRemoveDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
1744+ if (showRemoveDebugDetails) {
1745+ qDebug("hideOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld\n",
1746+ args.nodesScanned, args.nodesRemoved, args.nodesInside,
1747+ args.nodesIntersect, args.nodesOutside
1748+ );
1749+ }
1750+
1751+ collectStatsForTreesAndVBOs();
1752+}
1753+
1754+
16351755 bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
16361756 VoxelDetail& detail, float& distance, BoxFace& face) {
16371757 pthread_mutex_lock(&_treeLock);
@@ -1751,6 +1871,14 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* ex · 113 unmodified lines
17511871 if (node->isKnownBufferIndex()) {
17521872 args->nodesInVBO++;
17531873 unsigned long nodeIndex = node->getBufferIndex();
1874+
1875+ const bool extraDebugging = false; // enable for extra debugging
1876+ if (extraDebugging) {
1877+ qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s \n",
1878+ node->getCorner().x, node->getCorner().y, node->getCorner().z, node->getScale(),
1879+ nodeIndex, debug::valueOf(node->isDirty()), debug::valueOf(node->getShouldRender()));
1880+ }
1881+
17541882 if (args->hasIndexFound[nodeIndex]) {
17551883 args->duplicateVBOIndex++;
17561884 qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex,
@@ -1786,6 +1914,9 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 29 unmodified lines
17861914
17871915 collectStatsForTreesAndVBOsArgs args;
17881916 args.expectedMax = _voxelsInWriteArrays;
1917+
1918+ qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>\n");
1919+
17891920 _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);
17901921
17911922 qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n",
@@ -1810,6 +1941,10 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 18 unmodified lines
18101941 qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld \n",
18111942 minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays);
18121943
1944+ qDebug(" _freeIndexes.size()=%ld \n",
1945+ _freeIndexes.size());
1946+
1947+ qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>\n");
18131948 }
18141949
18151950