Showing the changes to interface/src/VoxelSystem.cpp (1 of 80 files). Show all
Unified · Split
| @@ -57,13 +57,16 @@ GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 }; · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) | 58 | VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) |
| 59 | : NodeData(), | 59 | : NodeData(), |
| 60 | _treeScale(treeScale), | 60 | _treeScale(treeScale), |
| 61 | _maxVoxels(maxVoxels), | 61 | _maxVoxels(maxVoxels), |
| 62 | _initialized(false), | 62 | _initialized(false), |
| 63 | _inOcclusions(false), | 63 | _writeArraysLock(QReadWriteLock::Recursive), |
| 64 | _showCulledSharedFaces(false), | 64 | _readArraysLock(QReadWriteLock::Recursive), |
| 65 | _usePrimitiveRenderer(false), | 65 | _inOcclusions(false), |
| 66 | _renderer(0) { | 66 | _showCulledSharedFaces(false), |
| 67 | _usePrimitiveRenderer(false), | ||
| 68 | _renderer(0) | ||
| 69 | { | ||
| 67 | 70 | ||
| 68 | _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; | 71 | _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; |
| 69 | _writeRenderFullVBO = true; | 72 | _writeRenderFullVBO = true; |
| @@ -103,6 +106,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 33 unmodified lines | |||
| 103 | 106 | ||
| 104 | _culledOnce = false; | 107 | _culledOnce = false; |
| 105 | _inhideOutOfView = false; | 108 | _inhideOutOfView = false; |
| 109 | |||
| 110 | _lastKnownVoxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE; | ||
| 111 | _lastKnownBoundaryLevelAdjust = 0; | ||
| 106 | } | 112 | } |
| 107 | 113 | ||
| 108 | void VoxelSystem::elementDeleted(OctreeElement* element) { | 114 | void VoxelSystem::elementDeleted(OctreeElement* element) { |
| @@ -125,6 +131,7 @@ void VoxelSystem::setDisableFastVoxelPipeline(bool disableFastVoxelPipeline) { · 16 unmodified lines | |||
| 125 | 131 | ||
| 126 | void VoxelSystem::elementUpdated(OctreeElement* element) { | 132 | void VoxelSystem::elementUpdated(OctreeElement* element) { |
| 127 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 133 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| 134 | |||
| 128 | // If we're in SetupNewVoxelsForDrawing() or _writeRenderFullVBO then bail.. | 135 | // If we're in SetupNewVoxelsForDrawing() or _writeRenderFullVBO then bail.. |
| 129 | if (!_useFastVoxelPipeline || _inSetupNewVoxelsForDrawing || _writeRenderFullVBO) { | 136 | if (!_useFastVoxelPipeline || _inSetupNewVoxelsForDrawing || _writeRenderFullVBO) { |
| 130 | return; | 137 | return; |
| @@ -253,6 +260,9 @@ VoxelSystem::~VoxelSystem() { · 122 unmodified lines | |||
| 253 | delete _tree; | 260 | delete _tree; |
| 254 | } | 261 | } |
| 255 | 262 | ||
| 263 | |||
| 264 | // This is called by the main application thread on both the initialization of the application and when | ||
| 265 | // the preferences dialog box is called/saved | ||
| 256 | void VoxelSystem::setMaxVoxels(int maxVoxels) { | 266 | void VoxelSystem::setMaxVoxels(int maxVoxels) { |
| 257 | if (maxVoxels == _maxVoxels) { | 267 | if (maxVoxels == _maxVoxels) { |
| 258 | return; | 268 | return; |
| @@ -271,6 +281,8 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) { · 12 unmodified lines | |||
| 271 | } | 281 | } |
| 272 | } | 282 | } |
| 273 | 283 | ||
| 284 | // This is called by the main application thread on both the initialization of the application and when | ||
| 285 | // the use voxel shader menu item is chosen | ||
| 274 | void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { | 286 | void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { |
| 275 | if (_useVoxelShader == useVoxelShader) { | 287 | if (_useVoxelShader == useVoxelShader) { |
| 276 | return; | 288 | return; |
| @@ -335,7 +347,7 @@ void VoxelSystem::setVoxelsAsPoints(bool voxelsAsPoints) { · 58 unmodified lines | |||
| 335 | 347 | ||
| 336 | void VoxelSystem::cleanupVoxelMemory() { | 348 | void VoxelSystem::cleanupVoxelMemory() { |
| 337 | if (_initialized) { | 349 | if (_initialized) { |
| 338 | _bufferWriteLock.lock(); | 350 | _readArraysLock.lockForWrite(); |
| 339 | _initialized = false; // no longer initialized | 351 | _initialized = false; // no longer initialized |
| 340 | if (_useVoxelShader) { | 352 | if (_useVoxelShader) { |
| 341 | // these are used when in VoxelShader mode. | 353 | // these are used when in VoxelShader mode. |
| @@ -376,7 +388,7 @@ void VoxelSystem::cleanupVoxelMemory() { · 34 unmodified lines | |||
| 376 | delete[] _writeVoxelDirtyArray; | 388 | delete[] _writeVoxelDirtyArray; |
| 377 | delete[] _readVoxelDirtyArray; | 389 | delete[] _readVoxelDirtyArray; |
| 378 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; | 390 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; |
| 379 | _bufferWriteLock.unlock(); | 391 | _readArraysLock.unlock(); |
| 380 | } | 392 | } |
| 381 | } | 393 | } |
| 382 | 394 | ||
| @@ -409,7 +421,8 @@ void VoxelSystem::setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndice · 26 unmodified lines | |||
| 409 | } | 421 | } |
| 410 | 422 | ||
| 411 | void VoxelSystem::initVoxelMemory() { | 423 | void VoxelSystem::initVoxelMemory() { |
| 412 | _bufferWriteLock.lock(); | 424 | _readArraysLock.lockForWrite(); |
| 425 | _writeArraysLock.lockForWrite(); | ||
| 413 | 426 | ||
| 414 | _memoryUsageRAM = 0; | 427 | _memoryUsageRAM = 0; |
| 415 | _memoryUsageVBO = 0; // our VBO allocations as we know them | 428 | _memoryUsageVBO = 0; // our VBO allocations as we know them |
| @@ -524,7 +537,8 @@ void VoxelSystem::initVoxelMemory() { · 108 unmodified lines | |||
| 524 | 537 | ||
| 525 | _initialized = true; | 538 | _initialized = true; |
| 526 | 539 | ||
| 527 | _bufferWriteLock.unlock(); | 540 | _writeArraysLock.unlock(); |
| 541 | _readArraysLock.unlock(); | ||
| 528 | } | 542 | } |
| 529 | 543 | ||
| 530 | void VoxelSystem::writeToSVOFile(const char* filename, VoxelTreeElement* element) const { | 544 | void VoxelSystem::writeToSVOFile(const char* filename, VoxelTreeElement* element) const { |
| @@ -654,7 +668,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 123 unmodified lines | |||
| 654 | } | 668 | } |
| 655 | 669 | ||
| 656 | _inSetupNewVoxelsForDrawing = true; | 670 | _inSetupNewVoxelsForDrawing = true; |
| 657 | 671 | ||
| 658 | bool didWriteFullVBO = _writeRenderFullVBO; | 672 | bool didWriteFullVBO = _writeRenderFullVBO; |
| 659 | if (_tree->isDirty()) { | 673 | if (_tree->isDirty()) { |
| 660 | static char buffer[64] = { 0 }; | 674 | static char buffer[64] = { 0 }; |
| @@ -688,10 +702,9 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 27 unmodified lines | |||
| 688 | if (_voxelsUpdated) { | 702 | if (_voxelsUpdated) { |
| 689 | _voxelsDirty=true; | 703 | _voxelsDirty=true; |
| 690 | } | 704 | } |
| 691 | } | 705 | } else { |
| 692 | else { | ||
| 693 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it | 706 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 694 | _bufferWriteLock.lock(); | 707 | _readArraysLock.lockForWrite(); |
| 695 | 708 | ||
| 696 | if (_voxelsUpdated) { | 709 | if (_voxelsUpdated) { |
| 697 | _voxelsDirty=true; | 710 | _voxelsDirty=true; |
| @@ -699,8 +712,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 1 unmodified line | |||
| 699 | 712 | ||
| 700 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated | 713 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated |
| 701 | copyWrittenDataToReadArrays(didWriteFullVBO); | 714 | copyWrittenDataToReadArrays(didWriteFullVBO); |
| 715 | _readArraysLock.unlock(); | ||
| 702 | 716 | ||
| 703 | _bufferWriteLock.unlock(); | ||
| 704 | } | 717 | } |
| 705 | 718 | ||
| 706 | quint64 end = usecTimestampNow(); | 719 | quint64 end = usecTimestampNow(); |
| @@ -732,13 +745,12 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 25 unmodified lines | |||
| 732 | if (_usePrimitiveRenderer) { | 745 | if (_usePrimitiveRenderer) { |
| 733 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty | 746 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty |
| 734 | _voxelsUpdated = 0; | 747 | _voxelsUpdated = 0; |
| 735 | } | 748 | } else { |
| 736 | else { | ||
| 737 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it | 749 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 738 | { | 750 | { |
| 739 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 751 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 740 | "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); | 752 | "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); |
| 741 | _bufferWriteLock.lock(); | 753 | _readArraysLock.lockForWrite(); |
| 742 | } | 754 | } |
| 743 | 755 | ||
| 744 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty | 756 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty |
| @@ -748,8 +760,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 3 unmodified lines | |||
| 748 | 760 | ||
| 749 | // after... | 761 | // after... |
| 750 | _voxelsUpdated = 0; | 762 | _voxelsUpdated = 0; |
| 751 | 763 | _readArraysLock.unlock(); | |
| 752 | _bufferWriteLock.unlock(); | ||
| 753 | } | 764 | } |
| 754 | quint64 end = usecTimestampNow(); | 765 | quint64 end = usecTimestampNow(); |
| 755 | int elapsedmsec = (end - start) / 1000; | 766 | int elapsedmsec = (end - start) / 1000; |
| @@ -757,8 +768,73 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 1 unmodified line | |||
| 757 | _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; | 768 | _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; |
| 758 | } | 769 | } |
| 759 | 770 | ||
| 760 | void VoxelSystem::checkForCulling() { | ||
| 761 | 771 | ||
| 772 | |||
| 773 | class recreateVoxelGeometryInViewArgs { | ||
| 774 | public: | ||
| 775 | VoxelSystem* thisVoxelSystem; | ||
| 776 | ViewFrustum thisViewFrustum; | ||
| 777 | unsigned long nodesScanned; | ||
| 778 | float voxelSizeScale; | ||
| 779 | int boundaryLevelAdjust; | ||
| 780 | |||
| 781 | recreateVoxelGeometryInViewArgs(VoxelSystem* voxelSystem) : | ||
| 782 | thisVoxelSystem(voxelSystem), | ||
| 783 | thisViewFrustum(*voxelSystem->getViewFrustum()), | ||
| 784 | nodesScanned(0), | ||
| 785 | voxelSizeScale(Menu::getInstance()->getVoxelSizeScale()), | ||
| 786 | boundaryLevelAdjust(Menu::getInstance()->getBoundaryLevelAdjust()) | ||
| 787 | { | ||
| 788 | } | ||
| 789 | }; | ||
| 790 | |||
| 791 | // The goal of this operation is to remove any old references to old geometry, and if the voxel | ||
| 792 | // should be visible, create new geometry for it. | ||
| 793 | bool VoxelSystem::recreateVoxelGeometryInViewOperation(OctreeElement* element, void* extraData) { | ||
| 794 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | ||
| 795 | recreateVoxelGeometryInViewArgs* args = (recreateVoxelGeometryInViewArgs*)extraData; | ||
| 796 | |||
| 797 | args->nodesScanned++; | ||
| 798 | |||
| 799 | // reset the old geometry... | ||
| 800 | // note: this doesn't "mark the voxel as changed", so it only releases the old buffer index thereby forgetting the | ||
| 801 | // old geometry | ||
| 802 | voxel->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); | ||
| 803 | |||
| 804 | bool shouldRender = voxel->calculateShouldRender(&args->thisViewFrustum, args->voxelSizeScale, args->boundaryLevelAdjust); | ||
| 805 | bool inView = voxel->isInView(args->thisViewFrustum); | ||
| 806 | voxel->setShouldRender(inView && shouldRender); | ||
| 807 | if (shouldRender && inView) { | ||
| 808 | // recreate the geometry | ||
| 809 | args->thisVoxelSystem->updateNodeInArrays(voxel, false, true); // DONT_REUSE_INDEX, FORCE_REDRAW | ||
| 810 | } | ||
| 811 | |||
| 812 | return true; // keep recursing! | ||
| 813 | } | ||
| 814 | |||
| 815 | |||
| 816 | // TODO: does cleanupRemovedVoxels() ever get called? | ||
| 817 | // TODO: other than cleanupRemovedVoxels() is there anyplace we attempt to detect too many abandoned slots??? | ||
| 818 | void VoxelSystem::recreateVoxelGeometryInView() { | ||
| 819 | |||
| 820 | qDebug() << "recreateVoxelGeometryInView()..."; | ||
| 821 | |||
| 822 | recreateVoxelGeometryInViewArgs args(this); | ||
| 823 | _writeArraysLock.lockForWrite(); // don't let anyone read or write our write arrays until we're done | ||
| 824 | _tree->lockForRead(); // don't let anyone change our tree structure until we're run | ||
| 825 | |||
| 826 | // reset our write arrays bookkeeping to think we've got no voxels in it | ||
| 827 | clearFreeBufferIndexes(); | ||
| 828 | |||
| 829 | // do we need to reset out _writeVoxelDirtyArray arrays?? | ||
| 830 | memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); | ||
| 831 | |||
| 832 | _tree->recurseTreeWithOperation(recreateVoxelGeometryInViewOperation,(void*)&args); | ||
| 833 | _tree->unlock(); | ||
| 834 | _writeArraysLock.unlock(); | ||
| 835 | } | ||
| 836 | |||
| 837 | void VoxelSystem::checkForCulling() { | ||
| 762 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()"); | 838 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()"); |
| 763 | quint64 start = usecTimestampNow(); | 839 | quint64 start = usecTimestampNow(); |
| 764 | 840 | ||
| @@ -786,7 +862,20 @@ void VoxelSystem::checkForCulling() { · 21 unmodified lines | |||
| 786 | _hasRecentlyChanged = false; | 862 | _hasRecentlyChanged = false; |
| 787 | } | 863 | } |
| 788 | 864 | ||
| 789 | hideOutOfView(forceFullFrustum); | 865 | // This would be a good place to do a special processing pass, for example, switching the LOD of the scene |
| 866 | bool fullRedraw = (_lastKnownVoxelSizeScale != Menu::getInstance()->getVoxelSizeScale() || | ||
| 867 | _lastKnownBoundaryLevelAdjust != Menu::getInstance()->getBoundaryLevelAdjust()); | ||
| 868 | |||
| 869 | // track that these values | ||
| 870 | _lastKnownVoxelSizeScale = Menu::getInstance()->getVoxelSizeScale(); | ||
| 871 | _lastKnownBoundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust(); | ||
| 872 | |||
| 873 | if (fullRedraw) { | ||
| 874 | // this will remove all old geometry and recreate the correct geometry for all in view voxels | ||
| 875 | recreateVoxelGeometryInView(); | ||
| 876 | } else { | ||
| 877 | hideOutOfView(forceFullFrustum); | ||
| 878 | } | ||
| 790 | 879 | ||
| 791 | if (forceFullFrustum) { | 880 | if (forceFullFrustum) { |
| 792 | quint64 endViewCulling = usecTimestampNow(); | 881 | quint64 endViewCulling = usecTimestampNow(); |
| @@ -905,12 +994,26 @@ void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) { · 112 unmodified lines | |||
| 905 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 994 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 906 | "copyWrittenDataToReadArrays()"); | 995 | "copyWrittenDataToReadArrays()"); |
| 907 | 996 | ||
| 908 | if (_voxelsDirty && _voxelsUpdated) { | 997 | // attempt to get the writeArraysLock for reading and the readArraysLock for writing |
| 909 | if (fullVBOs) { | 998 | // so we can copy from the write to the read... if we fail, that's ok, we'll get it the next |
| 910 | copyWrittenDataToReadArraysFullVBOs(); | 999 | // time around, the only side effect is the VBOs won't be updated this frame |
| 1000 | const int WAIT_FOR_LOCK_IN_MS = 5; | ||
| 1001 | if (_readArraysLock.tryLockForWrite(WAIT_FOR_LOCK_IN_MS)) { | ||
| 1002 | if (_writeArraysLock.tryLockForRead(WAIT_FOR_LOCK_IN_MS)) { | ||
| 1003 | if (_voxelsDirty && _voxelsUpdated) { | ||
| 1004 | if (fullVBOs) { | ||
| 1005 | copyWrittenDataToReadArraysFullVBOs(); | ||
| 1006 | } else { | ||
| 1007 | copyWrittenDataToReadArraysPartialVBOs(); | ||
| 1008 | } | ||
| 1009 | } | ||
| 1010 | _writeArraysLock.unlock(); | ||
| 911 | } else { | 1011 | } else { |
| 912 | copyWrittenDataToReadArraysPartialVBOs(); | 1012 | qDebug() << "couldn't get _writeArraysLock.LockForRead()..."; |
| 913 | } | 1013 | } |
| 1014 | _readArraysLock.unlock(); | ||
| 1015 | } else { | ||
| 1016 | qDebug() << "couldn't get _readArraysLock.LockForWrite()..."; | ||
| 914 | } | 1017 | } |
| 915 | } | 1018 | } |
| 916 | 1019 | ||
| @@ -1204,18 +1307,28 @@ void VoxelSystem::updateVBOs() { · 287 unmodified lines | |||
| 1204 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); | 1307 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); |
| 1205 | if (! _usePrimitiveRenderer) { | 1308 | if (! _usePrimitiveRenderer) { |
| 1206 | if (_voxelsDirty) { | 1309 | if (_voxelsDirty) { |
| 1207 | if (_readRenderFullVBO) { | 1310 | |
| 1208 | updateFullVBOs(); | 1311 | // attempt to lock the read arrays, to for copying from them to the actual GPU VBOs. |
| 1312 | // if we fail to get the lock, that's ok, our VBOs will update on the next frame... | ||
| 1313 | const int WAIT_FOR_LOCK_IN_MS = 5; | ||
| 1314 | if (_readArraysLock.tryLockForRead(WAIT_FOR_LOCK_IN_MS)) { | ||
| 1315 | if (_readRenderFullVBO) { | ||
| 1316 | updateFullVBOs(); | ||
| 1317 | } else { | ||
| 1318 | updatePartialVBOs(); | ||
| 1319 | } | ||
| 1320 | _voxelsDirty = false; | ||
| 1321 | _readRenderFullVBO = false; | ||
| 1322 | _readArraysLock.unlock(); | ||
| 1209 | } else { | 1323 | } else { |
| 1210 | updatePartialVBOs(); | 1324 | qDebug() << "updateVBOs().... couldn't get _readArraysLock.tryLockForRead()"; |
| 1211 | } | 1325 | } |
| 1212 | _voxelsDirty = false; | ||
| 1213 | _readRenderFullVBO = false; | ||
| 1214 | } | 1326 | } |
| 1215 | } | 1327 | } |
| 1216 | _callsToTreesToArrays = 0; // clear it | 1328 | _callsToTreesToArrays = 0; // clear it |
| 1217 | } | 1329 | } |
| 1218 | 1330 | ||
| 1331 | // this should only be called on the main application thread during render | ||
| 1219 | void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) { | 1332 | void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex segmentEnd) { |
| 1220 | bool showWarning = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); | 1333 | bool showWarning = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| 1221 | PerformanceWarning warn(showWarning, "updateVBOSegment()"); | 1334 | PerformanceWarning warn(showWarning, "updateVBOSegment()"); |
| @@ -1261,7 +1374,8 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg · 39 unmodified lines | |||
| 1261 | } | 1374 | } |
| 1262 | } | 1375 | } |
| 1263 | 1376 | ||
| 1264 | void VoxelSystem::render(bool texture) { | 1377 | void VoxelSystem::render() { |
| 1378 | bool texture = Menu::getInstance()->isOptionChecked(MenuOption::VoxelTextures); | ||
| 1265 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); | 1379 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| 1266 | PerformanceWarning warn(showWarnings, "render()"); | 1380 | PerformanceWarning warn(showWarnings, "render()"); |
| 1267 | 1381 | ||
| @@ -1478,11 +1592,7 @@ void VoxelSystem::killLocalVoxels() { · 210 unmodified lines | |||
| 1478 | setupNewVoxelsForDrawing(); | 1592 | setupNewVoxelsForDrawing(); |
| 1479 | } | 1593 | } |
| 1480 | 1594 | ||
| 1481 | void VoxelSystem::redrawInViewVoxels() { | 1595 | // only called on main thread |
| 1482 | hideOutOfView(true); | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | |||
| 1486 | bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void* extraData) { | 1596 | bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void* extraData) { |
| 1487 | _nodeCount++; | 1597 | _nodeCount++; |
| 1488 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 1598 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| @@ -1491,12 +1601,15 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void · 2 unmodified lines | |||
| 1491 | return true; | 1601 | return true; |
| 1492 | } | 1602 | } |
| 1493 | 1603 | ||
| 1604 | // only called on main thread, and also always followed by a call to cleanupVoxelMemory() | ||
| 1605 | // you shouldn't be calling this on any other thread or without also cleaning up voxel memory | ||
| 1494 | void VoxelSystem::clearAllNodesBufferIndex() { | 1606 | void VoxelSystem::clearAllNodesBufferIndex() { |
| 1495 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 1607 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 1496 | "VoxelSystem::clearAllNodesBufferIndex()"); | 1608 | "VoxelSystem::clearAllNodesBufferIndex()"); |
| 1497 | _nodeCount = 0; | 1609 | _nodeCount = 0; |
| 1498 | _tree->lockForRead(); // we won't change the tree so it's ok to treat this as a read | 1610 | _tree->lockForRead(); // we won't change the tree so it's ok to treat this as a read |
| 1499 | _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); | 1611 | _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); |
| 1612 | clearFreeBufferIndexes(); // this should be called too | ||
| 1500 | _tree->unlock(); | 1613 | _tree->unlock(); |
| 1501 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | 1614 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { |
| 1502 | qDebug("clearing buffer index of %d nodes", _nodeCount); | 1615 | qDebug("clearing buffer index of %d nodes", _nodeCount); |