History

First cut are removing out of view voxels and switch to using PerformanceWarnings

ZappoMan committed 13 years ago

Commit 7ba9d4a1 parent e0d040a2 files · +83 −63Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+74−63
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <fstream> // to load voxels from file
1616 #include <SharedUtil.h>
1717 #include <PacketHeaders.h>
18+#include <PerfStat.h>
1819 #include <OctalCode.h>
1920 #include <pthread.h>
2021 #include "Log.h"
@@ -44,6 +45,7 @@ VoxelSystem::VoxelSystem() { · 23 unmodified lines
4445 _voxelsInArrays = _voxelsUpdated = 0;
4546 _tree = new VoxelTree();
4647 pthread_mutex_init(&_bufferWriteLock, NULL);
48+ pthread_mutex_init(&_voxelCleanupLock, NULL);
4749 }
4850
4951 VoxelSystem::~VoxelSystem() {
@@ -54,6 +56,7 @@ VoxelSystem::~VoxelSystem() { · 4 unmodified lines
5456 delete[] _voxelDirtyArray;
5557 delete _tree;
5658 pthread_mutex_destroy(&_bufferWriteLock);
59+ pthread_mutex_destroy(&_voxelCleanupLock);
5760 }
5861
5962 void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
@@ -98,24 +101,13 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 38 unmodified lines
98101 switch(command) {
99102 case PACKET_HEADER_VOXEL_DATA:
100103 {
101− double start = usecTimestampNow();
104+ PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()");
102105 // ask the VoxelTree to read the bitstream into the tree
103106 _tree->readBitstreamToTree(voxelData, numBytes - 1);
104107 if (_renderWarningsOn && _tree->getNodesChangedFromBitstream()) {
105108 printLog("readBitstreamToTree()... getNodesChangedFromBitstream=%ld _tree->isDirty()=%s \n",
106109 _tree->getNodesChangedFromBitstream(), (_tree->isDirty() ? "yes" : "no") );
107110 }
108−
109− double end = usecTimestampNow();
110− double elapsedmsec = (end - start)/1000.0;
111− if (_renderWarningsOn && elapsedmsec > 1) {
112− if (elapsedmsec > 1000) {
113− double elapsedsec = (end - start)/1000000.0;
114− printLog("WARNING! readBitstreamToTree() took %lf seconds\n",elapsedsec);
115− } else {
116− printLog("WARNING! readBitstreamToTree() took %lf milliseconds\n",elapsedmsec);
117− }
118− }
119111 }
120112 break;
121113 case PACKET_HEADER_ERASE_VOXEL:
@@ -153,14 +145,19 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 31 unmodified lines
153145 }
154146
155147 void VoxelSystem::setupNewVoxelsForDrawing() {
148+ PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); // would like to include _voxelsInArrays, _voxelsUpdated
156149 double start = usecTimestampNow();
157−
158150 double sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished);
159151
160152 if (sinceLastTime <= std::max(_setupNewVoxelsForDrawingLastElapsed,SIXTY_FPS_IN_MILLISECONDS)) {
161153 return; // bail early, it hasn't been long enough since the last time we ran
162154 }
163155
156+ // If the view frustum has changed, since last time, then remove nodes that are out of view
157+ //if (hasViewChanged()) {
158+ // removeOutOfView();
159+ //}
160+
164161 if (_tree->isDirty()) {
165162 _callsToTreesToArrays++;
166163 _voxelsUpdated = newTreeToArrays(_tree->rootNode);
@@ -179,21 +176,12 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 12 unmodified lines
179176
180177 double end = usecTimestampNow();
181178 double elapsedmsec = (end - start)/1000.0;
182− if (_renderWarningsOn && elapsedmsec > 1) {
183− if (elapsedmsec > 1000) {
184− double elapsedsec = (end - start)/1000000.0;
185− printLog("WARNING! newTreeToArrays() took %lf seconds %ld voxels updated\n", elapsedsec, _voxelsUpdated);
186− } else {
187− printLog("WARNING! newTreeToArrays() took %lf milliseconds %ld voxels updated\n", elapsedmsec, _voxelsUpdated);
188− }
189− }
190−
191179 _setupNewVoxelsForDrawingLastFinished = end;
192180 _setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
193181 }
194182
195183 void VoxelSystem::copyWrittenDataToReadArrays() {
196− double start = usecTimestampNow();
184+ PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); // would like to include _voxelsInArrays, _voxelsUpdated
197185 if (_voxelsDirty && _voxelsUpdated) {
198186 // lock on the buffer write lock so we can't modify the data when the GPU is reading it
199187 pthread_mutex_lock(&_bufferWriteLock);
@@ -203,18 +191,6 @@ void VoxelSystem::copyWrittenDataToReadArrays() { · 3 unmodified lines
203191 memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
204192 pthread_mutex_unlock(&_bufferWriteLock);
205193 }
206− double end = usecTimestampNow();
207− double elapsedmsec = (end - start)/1000.0;
208− if (_renderWarningsOn && elapsedmsec > 1) {
209− if (elapsedmsec > 1000) {
210− double elapsedsec = (end - start)/1000000.0;
211− printLog("WARNING! copyWrittenDataToReadArrays() took %lf seconds for %ld voxels %ld updated\n",
212− elapsedsec, _voxelsInArrays, _voxelsUpdated);
213− } else {
214− printLog("WARNING! copyWrittenDataToReadArrays() took %lf milliseconds for %ld voxels %ld updated\n",
215− elapsedmsec, _voxelsInArrays, _voxelsUpdated);
216− }
217− }
218194 }
219195
220196 int VoxelSystem::newTreeToArrays(VoxelNode* node) {
@@ -301,6 +277,7 @@ void VoxelSystem::init() { · 80 unmodified lines
301277 // When we change voxels representations in the arrays, we'll update this
302278 _voxelsDirty = false;
303279 _voxelsInArrays = 0;
280+ _unusedArraySpace = 0;
304281
305282 // we will track individual dirty sections with this array of bools
306283 _voxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM];
@@ -369,7 +346,7 @@ void VoxelSystem::init() { · 62 unmodified lines
369346 }
370347
371348 void VoxelSystem::updateVBOs() {
372− double start = usecTimestampNow();
349+ PerformanceWarning warn(_renderWarningsOn, "updateVBOs()"); // would like to include _callsToTreesToArrays
373350 if (_voxelsDirty) {
374351 glBufferIndex segmentStart = 0;
375352 glBufferIndex segmentEnd = 0;
@@ -401,28 +378,13 @@ void VoxelSystem::updateVBOs() { · 25 unmodified lines
401378 }
402379 _voxelsDirty = false;
403380 }
404− double end = usecTimestampNow();
405− double elapsedmsec = (end - start)/1000.0;
406− if (_renderWarningsOn && elapsedmsec > 1) {
407− if (elapsedmsec > 1) {
408− if (elapsedmsec > 1000) {
409− double elapsedsec = (end - start)/1000000.0;
410− printLog("WARNING! updateVBOs() took %lf seconds after %d calls to newTreeToArrays()\n",
411− elapsedsec, _callsToTreesToArrays);
412− } else {
413− printLog("WARNING! updateVBOs() took %lf milliseconds after %d calls to newTreeToArrays()\n",
414− elapsedmsec, _callsToTreesToArrays);
415− }
416− } else {
417− printLog("WARNING! updateVBOs() called after %d calls to newTreeToArrays()\n",_callsToTreesToArrays);
418− }
419− }
420381 _callsToTreesToArrays = 0; // clear it
421382 }
422383
423384 void VoxelSystem::render() {
424− double start = usecTimestampNow();
385+ PerformanceWarning warn(_renderWarningsOn, "render()");
425386 glPushMatrix();
387+ //cleanupRemovedVoxels();
426388 updateVBOs();
427389 // tell OpenGL where to find vertex and color information
428390 glEnableClientState(GL_VERTEX_ARRAY);
@@ -454,16 +416,6 @@ void VoxelSystem::render() { · 25 unmodified lines
454416
455417 // scale back down to 1 so heads aren't massive
456418 glPopMatrix();
457− double end = usecTimestampNow();
458− double elapsedmsec = (end - start)/1000.0;
459− if (_renderWarningsOn && elapsedmsec > 1) {
460− if (elapsedmsec > 1000) {
461− double elapsedsec = (end - start)/1000000.0;
462− printLog("WARNING! render() took %lf seconds\n",elapsedsec);
463− } else {
464− printLog("WARNING! render() took %lf milliseconds\n",elapsedmsec);
465− }
466− }
467419 }
468420
469421 int VoxelSystem::_nodeCount = 0;
@@ -591,4 +543,63 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) { · 121 unmodified lines
591543 setupNewVoxelsForDrawing();
592544 }
593545
546+// "Remove" voxels from the tree that are not in view. We don't actually delete them,
547+// we remove them from the tree and place them into a holding area for later deletion
548+int removedCount;
549+bool VoxelSystem::removeOutOfViewOperation(VoxelNode* node, void* extraData) {
550+ VoxelSystem* thisVoxelSystem = (VoxelSystem*) extraData;
551+ _nodeCount++;
552+ // Need to operate on our child nodes, so we can remove them
553+ for (int i = 0; i < 8; i++) {
554+ VoxelNode* childNode = node->getChildAtIndex(i);
555+ if (childNode && !childNode->isInView(*thisVoxelSystem->_viewFrustum)) {
556+ node->removeChildAtIndex(i);
557+ removedCount++;
558+
559+ // Note: VoxelNodeBag is more expensive than we need, because it checks octal code matches,
560+ // we really just want a simple bag that checks pointers only, consider switching
561+ thisVoxelSystem->_removedVoxels.insert(childNode);
562+ }
563+ }
564+ return true; // keep going!
565+}
594566
567+bool VoxelSystem::hasViewChanged() {
568+ bool result = false; // assume the best
569+ if (_viewFrustum && !_lastKnowViewFrustum.matches(_viewFrustum)) {
570+ result = true;
571+ _lastKnowViewFrustum = *_viewFrustum; // save last known
572+ }
573+ return result;
574+}
575+
576+void VoxelSystem::removeOutOfView() {
577+ PerformanceWarning warn(_renderWarningsOn, "removeOutOfView()"); // would like to include removedCount, _nodeCount, _removedVoxels.count()
578+ pthread_mutex_lock(&_voxelCleanupLock);
579+ _nodeCount = 0;
580+ removedCount = 0;
581+ _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this);
582+ pthread_mutex_unlock(&_voxelCleanupLock);
583+}
584+
585+// Deletes the VoxelNodes from the _removedVoxels bag, but also cleans up those items from the vertex arrays
586+void VoxelSystem::cleanupRemovedVoxels() {
587+ if (!pthread_mutex_trylock(&_voxelCleanupLock)) {
588+ while (!_removedVoxels.isEmpty()){
589+ VoxelNode* node = _removedVoxels.extract();
590+ // If the voxel is in the vertex, and it was previously rendered, then set it's vertices to "hidden"
591+ if (node->isKnownBufferIndex() && node->getShouldRender()) {
592+ unsigned long nodeIndex = node->getBufferIndex();
593+ _voxelDirtyArray[nodeIndex] = true;
594+ for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
595+ GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
596+ *(writeVerticesAt+j) = FLT_MAX;
597+ }
598+ _voxelsDirty = true; // yep
599+ }
600+ _unusedArraySpace++; // track this so we can blow away our arrays if they get too much
601+ delete node; // actually delete the node
602+ }
603+ pthread_mutex_unlock(&_voxelCleanupLock);
604+ }
605+}