Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -61,8 +61,8 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 60 unmodified lines | |||
| 61 | _maxVoxels(maxVoxels), | 61 | _maxVoxels(maxVoxels), |
| 62 | _initialized(false), | 62 | _initialized(false), |
| 63 | _showCulledSharedFaces(false), | 63 | _showCulledSharedFaces(false), |
| 64 | _usePrimitiveRenderer(false), | 64 | _usePrimitiveRenderer(false), |
| 65 | _renderer(0) { | 65 | _renderer(0) { |
| 66 | 66 | ||
| 67 | _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; | 67 | _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; |
| 68 | _writeRenderFullVBO = true; | 68 | _writeRenderFullVBO = true; |
| @@ -215,16 +215,16 @@ void VoxelSystem::freeBufferIndex(glBufferIndex index) { · 146 unmodified lines | |||
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | if (!inList) { | 217 | if (!inList) { |
| 218 | // make the index available for next node that needs to be drawn | 218 | // make the index available for next node that needs to be drawn |
| 219 | _freeIndexLock.lock(); | 219 | _freeIndexLock.lock(); |
| 220 | _freeIndexes.push_back(index); | 220 | _freeIndexes.push_back(index); |
| 221 | _freeIndexLock.unlock(); | 221 | _freeIndexLock.unlock(); |
| 222 | 222 | ||
| 223 | // make the VBO slot "invisible" in case this slot is not used | 223 | // make the VBO slot "invisible" in case this slot is not used |
| 224 | const glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX); | 224 | const glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX); |
| 225 | const float voxelScale = 0; | 225 | const float voxelScale = 0; |
| 226 | const nodeColor BLACK = {0, 0, 0, 0}; | 226 | const nodeColor BLACK = {0, 0, 0, 0}; |
| 227 | updateArraysDetails(index, startVertex, voxelScale, BLACK); | 227 | updateArraysDetails(index, startVertex, voxelScale, BLACK); |
| 228 | } | 228 | } |
| 229 | } | 229 | } |
| 230 | 230 | ||
| @@ -254,7 +254,7 @@ VoxelSystem::~VoxelSystem() { · 23 unmodified lines | |||
| 254 | cleanupVoxelMemory(); | 254 | cleanupVoxelMemory(); |
| 255 | delete _tree; | 255 | delete _tree; |
| 256 | 256 | ||
| 257 | _renderer = 0; | 257 | _renderer = 0; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | void VoxelSystem::setMaxVoxels(int maxVoxels) { | 260 | void VoxelSystem::setMaxVoxels(int maxVoxels) { |
| @@ -263,12 +263,12 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) { · 2 unmodified lines | |||
| 263 | } | 263 | } |
| 264 | bool wasInitialized = _initialized; | 264 | bool wasInitialized = _initialized; |
| 265 | if (wasInitialized) { | 265 | if (wasInitialized) { |
| 266 | clearAllNodesBufferIndex(); | 266 | clearAllNodesBufferIndex(); |
| 267 | cleanupVoxelMemory(); | 267 | cleanupVoxelMemory(); |
| 268 | } | 268 | } |
| 269 | _maxVoxels = maxVoxels; | 269 | _maxVoxels = maxVoxels; |
| 270 | if (wasInitialized) { | 270 | if (wasInitialized) { |
| 271 | initVoxelMemory(); | 271 | initVoxelMemory(); |
| 272 | } | 272 | } |
| 273 | if (wasInitialized) { | 273 | if (wasInitialized) { |
| 274 | forceRedrawEntireTree(); | 274 | forceRedrawEntireTree(); |
| @@ -286,7 +286,7 @@ void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { · 11 unmodified lines | |||
| 286 | cleanupVoxelMemory(); | 286 | cleanupVoxelMemory(); |
| 287 | } | 287 | } |
| 288 | _useVoxelShader = useVoxelShader; | 288 | _useVoxelShader = useVoxelShader; |
| 289 | _usePrimitiveRenderer = false; | 289 | _usePrimitiveRenderer = false; |
| 290 | if (wasInitialized) { | 290 | if (wasInitialized) { |
| 291 | initVoxelMemory(); | 291 | initVoxelMemory(); |
| 292 | } | 292 | } |
| @@ -373,8 +373,8 @@ void VoxelSystem::cleanupVoxelMemory() { · 80 unmodified lines | |||
| 373 | _readColorsArray = NULL; | 373 | _readColorsArray = NULL; |
| 374 | _writeColorsArray = NULL; | 374 | _writeColorsArray = NULL; |
| 375 | } | 375 | } |
| 376 | delete _renderer; | 376 | delete _renderer; |
| 377 | _renderer = 0; | 377 | _renderer = 0; |
| 378 | delete[] _writeVoxelDirtyArray; | 378 | delete[] _writeVoxelDirtyArray; |
| 379 | delete[] _readVoxelDirtyArray; | 379 | delete[] _readVoxelDirtyArray; |
| 380 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; | 380 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; |
| @@ -522,7 +522,7 @@ void VoxelSystem::initVoxelMemory() { · 141 unmodified lines | |||
| 522 | _shadowMapProgram.release(); | 522 | _shadowMapProgram.release(); |
| 523 | } | 523 | } |
| 524 | } | 524 | } |
| 525 | _renderer = new PrimitiveRenderer(_maxVoxels); | 525 | _renderer = new PrimitiveRenderer(_maxVoxels); |
| 526 | 526 | ||
| 527 | _initialized = true; | 527 | _initialized = true; |
| 528 | 528 | ||
| @@ -666,10 +666,10 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 137 unmodified lines | |||
| 666 | _callsToTreesToArrays++; | 666 | _callsToTreesToArrays++; |
| 667 | 667 | ||
| 668 | if (_writeRenderFullVBO) { | 668 | if (_writeRenderFullVBO) { |
| 669 | if (_usePrimitiveRenderer) { | 669 | if (_usePrimitiveRenderer) { |
| 670 | _renderer->release(); | 670 | _renderer->release(); |
| 671 | } | 671 | } |
| 672 | clearFreeBufferIndexes(); | 672 | clearFreeBufferIndexes(); |
| 673 | } | 673 | } |
| 674 | _voxelsUpdated = newTreeToArrays(_tree->getRoot()); | 674 | _voxelsUpdated = newTreeToArrays(_tree->getRoot()); |
| 675 | _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean | 675 | _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean |
| @@ -685,24 +685,24 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 9 unmodified lines | |||
| 685 | _voxelsUpdated = 0; | 685 | _voxelsUpdated = 0; |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | if (_usePrimitiveRenderer) { | 688 | if (_usePrimitiveRenderer) { |
| 689 | if (_voxelsUpdated) { | 689 | if (_voxelsUpdated) { |
| 690 | _voxelsDirty=true; | 690 | _voxelsDirty=true; |
| 691 | } | 691 | } |
| 692 | } | 692 | } |
| 693 | else { | 693 | else { |
| 694 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it | 694 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 695 | _bufferWriteLock.lock(); | 695 | _bufferWriteLock.lock(); |
| 696 | 696 | ||
| 697 | if (_voxelsUpdated) { | 697 | if (_voxelsUpdated) { |
| 698 | _voxelsDirty=true; | 698 | _voxelsDirty=true; |
| 699 | } | 699 | } |
| 700 | 700 | ||
| 701 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated | 701 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated |
| 702 | copyWrittenDataToReadArrays(didWriteFullVBO); | 702 | copyWrittenDataToReadArrays(didWriteFullVBO); |
| 703 | 703 | ||
| 704 | _bufferWriteLock.unlock(); | 704 | _bufferWriteLock.unlock(); |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | quint64 end = usecTimestampNow(); | 707 | quint64 end = usecTimestampNow(); |
| 708 | int elapsedmsec = (end - start) / 1000; | 708 | int elapsedmsec = (end - start) / 1000; |
| @@ -730,28 +730,28 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 21 unmodified lines | |||
| 730 | return; // bail early, it hasn't been long enough since the last time we ran | 730 | return; // bail early, it hasn't been long enough since the last time we ran |
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | if (_usePrimitiveRenderer) { | 733 | if (_usePrimitiveRenderer) { |
| 734 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty | 734 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty |
| 735 | _voxelsUpdated = 0; | 735 | _voxelsUpdated = 0; |
| 736 | } | 736 | } |
| 737 | else { | 737 | else { |
| 738 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it | 738 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 739 | { | 739 | { |
| 740 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 740 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 741 | "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); | 741 | "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); |
| 742 | _bufferWriteLock.lock(); | 742 | _bufferWriteLock.lock(); |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty | 745 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty |
| 746 | 746 | ||
| 747 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated | 747 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated |
| 748 | copyWrittenDataToReadArrays(_writeRenderFullVBO); | 748 | copyWrittenDataToReadArrays(_writeRenderFullVBO); |
| 749 | 749 | ||
| 750 | // after... | 750 | // after... |
| 751 | _voxelsUpdated = 0; | 751 | _voxelsUpdated = 0; |
| 752 | 752 | ||
| 753 | _bufferWriteLock.unlock(); | 753 | _bufferWriteLock.unlock(); |
| 754 | } | 754 | } |
| 755 | quint64 end = usecTimestampNow(); | 755 | quint64 end = usecTimestampNow(); |
| 756 | int elapsedmsec = (end - start) / 1000; | 756 | int elapsedmsec = (end - start) / 1000; |
| 757 | _setupNewVoxelsForDrawingLastFinished = end; | 757 | _setupNewVoxelsForDrawingLastFinished = end; |
| @@ -972,24 +972,24 @@ int VoxelSystem::forceRemoveNodeFromArrays(VoxelTreeElement* node) { · 214 unmodified lines | |||
| 972 | return 0; | 972 | return 0; |
| 973 | } | 973 | } |
| 974 | 974 | ||
| 975 | if (_usePrimitiveRenderer) { | 975 | if (_usePrimitiveRenderer) { |
| 976 | int primitiveIndex = node->getPrimitiveIndex(); | 976 | int primitiveIndex = node->getPrimitiveIndex(); |
| 977 | if (primitiveIndex) { | 977 | if (primitiveIndex) { |
| 978 | _renderer->remove(primitiveIndex); | 978 | _renderer->remove(primitiveIndex); |
| 979 | node->setPrimitiveIndex(0); | 979 | node->setPrimitiveIndex(0); |
| 980 | return 1; | 980 | return 1; |
| 981 | } | 981 | } |
| 982 | } | 982 | } |
| 983 | else { | 983 | else { |
| 984 | // if the node is not in the VBOs then we have nothing to do! | 984 | // if the node is not in the VBOs then we have nothing to do! |
| 985 | if (node->isKnownBufferIndex()) { | 985 | if (node->isKnownBufferIndex()) { |
| 986 | // If this node has not yet been written to the array, then add it to the end of the array. | 986 | // If this node has not yet been written to the array, then add it to the end of the array. |
| 987 | glBufferIndex nodeIndex = node->getBufferIndex(); | 987 | glBufferIndex nodeIndex = node->getBufferIndex(); |
| 988 | node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); | 988 | node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); |
| 989 | freeBufferIndex(nodeIndex); // NOTE: This will make the node invisible! | 989 | freeBufferIndex(nodeIndex); // NOTE: This will make the node invisible! |
| 990 | return 1; // updated! | 990 | return 1; // updated! |
| 991 | } | 991 | } |
| 992 | } | 992 | } |
| 993 | return 0; // not-updated | 993 | return 0; // not-updated |
| 994 | } | 994 | } |
| 995 | 995 | ||
| @@ -1016,48 +1016,48 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo · 20 unmodified lines | |||
| 1016 | if (forceDraw || node->isDirty()) { | 1016 | if (forceDraw || node->isDirty()) { |
| 1017 | // If we're should render, use our legit location and scale, | 1017 | // If we're should render, use our legit location and scale, |
| 1018 | if (node->getShouldRender()) { | 1018 | if (node->getShouldRender()) { |
| 1019 | glm::vec3 startVertex = node->getCorner(); | 1019 | glm::vec3 startVertex = node->getCorner(); |
| 1020 | float voxelScale = node->getScale(); | 1020 | float voxelScale = node->getScale(); |
| 1021 | nodeColor const & color = node->getColor(); | 1021 | nodeColor const & color = node->getColor(); |
| 1022 | 1022 | ||
| 1023 | if (_usePrimitiveRenderer) { | 1023 | if (_usePrimitiveRenderer) { |
| 1024 | int primitiveIndex = node->getPrimitiveIndex(); | 1024 | int primitiveIndex = node->getPrimitiveIndex(); |
| 1025 | if (primitiveIndex) { | 1025 | if (primitiveIndex) { |
| 1026 | _renderer->remove(primitiveIndex); | 1026 | _renderer->remove(primitiveIndex); |
| 1027 | node->setPrimitiveIndex(0); | 1027 | node->setPrimitiveIndex(0); |
| 1028 | } else { | 1028 | } else { |
| 1029 | node->setVoxelSystem(this); | 1029 | node->setVoxelSystem(this); |
| 1030 | } | 1030 | } |
| 1031 | inspectForInteriorOcclusionsOperation(node, 0); | 1031 | inspectForInteriorOcclusionsOperation(node, 0); |
| 1032 | unsigned char occlusions; | 1032 | unsigned char occlusions; |
| 1033 | if (_showCulledSharedFaces) { | 1033 | if (_showCulledSharedFaces) { |
| 1034 | occlusions = ~node->getInteriorOcclusions(); | 1034 | occlusions = ~node->getInteriorOcclusions(); |
| 1035 | } else { | 1035 | } else { |
| 1036 | occlusions = node->getInteriorOcclusions(); | 1036 | occlusions = node->getInteriorOcclusions(); |
| 1037 | } | 1037 | } |
| 1038 | if (occlusions != OctreeElement::HalfSpace::All) { | 1038 | if (occlusions != OctreeElement::HalfSpace::All) { |
| 1039 | Cube* cube = new Cube( | 1039 | Cube* cube = new Cube( |
| 1040 | startVertex.x, startVertex.y, startVertex.z, voxelScale, | 1040 | startVertex.x, startVertex.y, startVertex.z, voxelScale, |
| 1041 | color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX], | 1041 | color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX], |
| 1042 | occlusions); | 1042 | occlusions); |
| 1043 | if (cube) { | 1043 | if (cube) { |
| 1044 | primitiveIndex = _renderer->add(cube); | 1044 | primitiveIndex = _renderer->add(cube); |
| 1045 | node->setPrimitiveIndex(primitiveIndex); | 1045 | node->setPrimitiveIndex(primitiveIndex); |
| 1046 | } | 1046 | } |
| 1047 | } | 1047 | } |
| 1048 | } else { | 1048 | } else { |
| 1049 | glBufferIndex nodeIndex = GLBUFFER_INDEX_UNKNOWN; | 1049 | glBufferIndex nodeIndex = GLBUFFER_INDEX_UNKNOWN; |
| 1050 | if (reuseIndex && node->isKnownBufferIndex()) { | 1050 | if (reuseIndex && node->isKnownBufferIndex()) { |
| 1051 | nodeIndex = node->getBufferIndex(); | 1051 | nodeIndex = node->getBufferIndex(); |
| 1052 | } else { | 1052 | } else { |
| 1053 | nodeIndex = getNextBufferIndex(); | 1053 | nodeIndex = getNextBufferIndex(); |
| 1054 | node->setBufferIndex(nodeIndex); | 1054 | node->setBufferIndex(nodeIndex); |
| 1055 | node->setVoxelSystem(this); | 1055 | node->setVoxelSystem(this); |
| 1056 | } | 1056 | } |
| 1057 | // populate the array with points for the 8 vertices and RGB color for each added vertex | 1057 | // populate the array with points for the 8 vertices and RGB color for each added vertex |
| 1058 | updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); | 1058 | updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); |
| 1059 | } | 1059 | } |
| 1060 | return 1; // updated! | 1060 | return 1; // updated! |
| 1061 | } else { | 1061 | } else { |
| 1062 | // If we shouldn't render, and we're in reuseIndex mode, then free our index, this only operates | 1062 | // If we shouldn't render, and we're in reuseIndex mode, then free our index, this only operates |
| 1063 | // on nodes with known index values, so it's safe to call for any node. | 1063 | // on nodes with known index values, so it's safe to call for any node. |
| @@ -1204,17 +1204,17 @@ void VoxelSystem::updateVBOs() { · 140 unmodified lines | |||
| 1204 | }; | 1204 | }; |
| 1205 | // would like to include _callsToTreesToArrays | 1205 | // would like to include _callsToTreesToArrays |
| 1206 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); | 1206 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); |
| 1207 | if (! _usePrimitiveRenderer) { | 1207 | if (! _usePrimitiveRenderer) { |
| 1208 | if (_voxelsDirty) { | 1208 | if (_voxelsDirty) { |
| 1209 | if (_readRenderFullVBO) { | 1209 | if (_readRenderFullVBO) { |
| 1210 | updateFullVBOs(); | 1210 | updateFullVBOs(); |
| 1211 | } else { | 1211 | } else { |
| 1212 | updatePartialVBOs(); | 1212 | updatePartialVBOs(); |
| 1213 | } | 1213 | } |
| 1214 | _voxelsDirty = false; | 1214 | _voxelsDirty = false; |
| 1215 | _readRenderFullVBO = false; | 1215 | _readRenderFullVBO = false; |
| 1216 | } | 1216 | } |
| 1217 | } | 1217 | } |
| 1218 | _callsToTreesToArrays = 0; // clear it | 1218 | _callsToTreesToArrays = 0; // clear it |
| 1219 | } | 1219 | } |
| 1220 | 1220 | ||
| @@ -1341,7 +1341,7 @@ void VoxelSystem::render(bool texture) { · 120 unmodified lines | |||
| 1341 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); | 1341 | glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| 1342 | } | 1342 | } |
| 1343 | } else | 1343 | } else |
| 1344 | if (!_usePrimitiveRenderer) { | 1344 | if (!_usePrimitiveRenderer) { |
| 1345 | PerformanceWarning warn(showWarnings, "render().. TRIANGLES..."); | 1345 | PerformanceWarning warn(showWarnings, "render().. TRIANGLES..."); |
| 1346 | 1346 | ||
| 1347 | { | 1347 | { |
| @@ -1415,12 +1415,12 @@ void VoxelSystem::render(bool texture) { · 67 unmodified lines | |||
| 1415 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 1415 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| 1416 | } | 1416 | } |
| 1417 | } | 1417 | } |
| 1418 | else { | 1418 | else { |
| 1419 | applyScaleAndBindProgram(texture); | 1419 | applyScaleAndBindProgram(texture); |
| 1420 | _renderer->render(); | 1420 | _renderer->render(); |
| 1421 | removeScaleAndReleaseProgram(texture); | 1421 | removeScaleAndReleaseProgram(texture); |
| 1422 | 1422 | ||
| 1423 | } | 1423 | } |
| 1424 | } | 1424 | } |
| 1425 | 1425 | ||
| 1426 | void VoxelSystem::applyScaleAndBindProgram(bool texture) { | 1426 | void VoxelSystem::applyScaleAndBindProgram(bool texture) { |
| @@ -1485,7 +1485,7 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void · 58 unmodified lines | |||
| 1485 | _nodeCount++; | 1485 | _nodeCount++; |
| 1486 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 1486 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| 1487 | voxel->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); | 1487 | voxel->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); |
| 1488 | voxel->setPrimitiveIndex(0); | 1488 | voxel->setPrimitiveIndex(0); |
| 1489 | return true; | 1489 | return true; |
| 1490 | } | 1490 | } |
| 1491 | 1491 | ||
| @@ -1503,72 +1503,72 @@ bool VoxelSystem::inspectForInteriorOcclusionsOperation(OctreeElement* element, · 11 unmodified lines | |||
| 1503 | _nodeCount++; | 1503 | _nodeCount++; |
| 1504 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 1504 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| 1505 | 1505 | ||
| 1506 | // Nothing to do at the leaf level | 1506 | // Nothing to do at the leaf level |
| 1507 | if (voxel->isLeaf()) { | 1507 | if (voxel->isLeaf()) { |
| 1508 | return false; | 1508 | return false; |
| 1509 | } | 1509 | } |
| 1510 | 1510 | ||
| 1511 | // Bit mask of occluded shared faces indexed by child | 1511 | // Bit mask of occluded shared faces indexed by child |
| 1512 | unsigned char occludedSharedFace[NUMBER_OF_CHILDREN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 1512 | unsigned char occludedSharedFace[NUMBER_OF_CHILDREN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 1513 | 1513 | ||
| 1514 | // Traverse all pair combinations of children | 1514 | // Traverse all pair combinations of children |
| 1515 | for (int i = NUMBER_OF_CHILDREN; --i >= 0; ) { | 1515 | for (int i = NUMBER_OF_CHILDREN; --i >= 0; ) { |
| 1516 | 1516 | ||
| 1517 | VoxelTreeElement* childA = voxel->getChildAtIndex(i); | 1517 | VoxelTreeElement* childA = voxel->getChildAtIndex(i); |
| 1518 | if (childA) { | 1518 | if (childA) { |
| 1519 | 1519 | ||
| 1520 | // Get the child A's occluding faces, for a leaf that will be | 1520 | // Get the child A's occluding faces, for a leaf that will be |
| 1521 | // all six voxel faces, and for a non leaf, that will be | 1521 | // all six voxel faces, and for a non leaf, that will be |
| 1522 | // all faces which are completely covered by four child octants. | 1522 | // all faces which are completely covered by four child octants. |
| 1523 | unsigned char exteriorOcclusionsA = childA->getExteriorOcclusions(); | 1523 | unsigned char exteriorOcclusionsA = childA->getExteriorOcclusions(); |
| 1524 | 1524 | ||
| 1525 | if (exteriorOcclusionsA == OctreeElement::HalfSpace::None) { | 1525 | if (exteriorOcclusionsA == OctreeElement::HalfSpace::None) { |
| 1526 | // There is nothing to be done with this child, next... | 1526 | // There is nothing to be done with this child, next... |
| 1527 | continue; | 1527 | continue; |
| 1528 | } | 1528 | } |
| 1529 | 1529 | ||
| 1530 | for (int j = i; --j >= 0; ) { | 1530 | for (int j = i; --j >= 0; ) { |
| 1531 | 1531 | ||
| 1532 | VoxelTreeElement* childB = voxel->getChildAtIndex(j); | 1532 | VoxelTreeElement* childB = voxel->getChildAtIndex(j); |
| 1533 | if (childB) { | 1533 | if (childB) { |
| 1534 | 1534 | ||
| 1535 | // Get child B's occluding faces | 1535 | // Get child B's occluding faces |
| 1536 | unsigned char exteriorOcclusionsB = childB->getExteriorOcclusions(); | 1536 | unsigned char exteriorOcclusionsB = childB->getExteriorOcclusions(); |
| 1537 | 1537 | ||
| 1538 | if (exteriorOcclusionsB == OctreeElement::HalfSpace::None) { | 1538 | if (exteriorOcclusionsB == OctreeElement::HalfSpace::None) { |
| 1539 | // There is nothing to be done with this child, next... | 1539 | // There is nothing to be done with this child, next... |
| 1540 | continue; | 1540 | continue; |
| 1541 | } | 1541 | } |
| 1542 | 1542 | ||
| 1543 | // Determine the shared halfspace partition between siblings A and B, | 1543 | // Determine the shared halfspace partition between siblings A and B, |
| 1544 | // i.e., near/far, left/right, or top/bottom | 1544 | // i.e., near/far, left/right, or top/bottom |
| 1545 | unsigned char partition = _sOctantIndexToSharedBitMask[i][j] & | 1545 | unsigned char partition = _sOctantIndexToSharedBitMask[i][j] & |
| 1546 | exteriorOcclusionsA & exteriorOcclusionsB; | 1546 | exteriorOcclusionsA & exteriorOcclusionsB; |
| 1547 | 1547 | ||
| 1548 | // Determine which face of each sibling is occluded. | 1548 | // Determine which face of each sibling is occluded. |
| 1549 | // Note the intentionally crossed indicies. It is necessary because | 1549 | // Note the intentionally crossed indicies. It is necessary because |
| 1550 | // the _sOctantIndexToBitMask is a partition occupancy mask. For | 1550 | // the _sOctantIndexToBitMask is a partition occupancy mask. For |
| 1551 | // example, if the near-left-top (NLT) and near-left-bottom (NLB) child voxels | 1551 | // example, if the near-left-top (NLT) and near-left-bottom (NLB) child voxels |
| 1552 | // exist, the shared partition is top-bottom (TB), and thus the occluded | 1552 | // exist, the shared partition is top-bottom (TB), and thus the occluded |
| 1553 | // shared face of the NLT voxel is its bottom face. | 1553 | // shared face of the NLT voxel is its bottom face. |
| 1554 | occludedSharedFace[i] |= (partition & _sOctantIndexToBitMask[j]); | 1554 | occludedSharedFace[i] |= (partition & _sOctantIndexToBitMask[j]); |
| 1555 | occludedSharedFace[j] |= (partition & _sOctantIndexToBitMask[i]); | 1555 | occludedSharedFace[j] |= (partition & _sOctantIndexToBitMask[i]); |
| 1556 | } | 1556 | } |
| 1557 | } | 1557 | } |
| 1558 | // Combine this voxel's interior excluded shared face only to those children which are coincident | 1558 | // Combine this voxel's interior excluded shared face only to those children which are coincident |
| 1559 | // with the excluded face. | 1559 | // with the excluded face. |
| 1560 | occludedSharedFace[i] |= (voxel->getInteriorOcclusions() & _sOctantIndexToBitMask[i]); | 1560 | occludedSharedFace[i] |= (voxel->getInteriorOcclusions() & _sOctantIndexToBitMask[i]); |
| 1561 | 1561 | ||
| 1562 | // Inform the child | 1562 | // Inform the child |
| 1563 | childA->setInteriorOcclusions(occludedSharedFace[i]); | 1563 | childA->setInteriorOcclusions(occludedSharedFace[i]); |
| 1564 | if (occludedSharedFace[i] != OctreeElement::HalfSpace::None) { | 1564 | if (occludedSharedFace[i] != OctreeElement::HalfSpace::None) { |
| 1565 | //const glm::vec3& v = voxel->getCorner(); | 1565 | //const glm::vec3& v = voxel->getCorner(); |
| 1566 | //float s = voxel->getScale(); | 1566 | //float s = voxel->getScale(); |
| 1567 | 1567 | ||
| 1568 | //qDebug("Child %d of voxel at %f %f %f size: %f has %02x occlusions", i, v.x, v.y, v.z, s, occludedSharedFace[i]); | 1568 | //qDebug("Child %d of voxel at %f %f %f size: %f has %02x occlusions", i, v.x, v.y, v.z, s, occludedSharedFace[i]); |
| 1569 | } | 1569 | } |
| 1570 | } | 1570 | } |
| 1571 | } | 1571 | } |
| 1572 | return true; | 1572 | return true; |
| 1573 | } | 1573 | } |
| 1574 | 1574 | ||
| @@ -1576,71 +1576,71 @@ bool VoxelSystem::inspectForExteriorOcclusionsOperation(OctreeElement* element, · 1 unmodified line | |||
| 1576 | _nodeCount++; | 1576 | _nodeCount++; |
| 1577 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 1577 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| 1578 | 1578 | ||
| 1579 | // Nothing to do at the leaf level | 1579 | // Nothing to do at the leaf level |
| 1580 | if (voxel->isLeaf()) { | 1580 | if (voxel->isLeaf()) { |
| 1581 | return false; | 1581 | return false; |
| 1582 | } | 1582 | } |
| 1583 | 1583 | ||
| 1584 | // Count of exterior occluding faces of this voxel element indexed | 1584 | // Count of exterior occluding faces of this voxel element indexed |
| 1585 | // by half space partition | 1585 | // by half space partition |
| 1586 | unsigned int exteriorOcclusionsCt[6] = { 0, 0, 0, 0, 0, 0 }; | 1586 | unsigned int exteriorOcclusionsCt[6] = { 0, 0, 0, 0, 0, 0 }; |
| 1587 | 1587 | ||
| 1588 | // Traverse all children | 1588 | // Traverse all children |
| 1589 | for (int i = NUMBER_OF_CHILDREN; --i >= 0; ) { | 1589 | for (int i = NUMBER_OF_CHILDREN; --i >= 0; ) { |
| 1590 | 1590 | ||
| 1591 | VoxelTreeElement* child = voxel->getChildAtIndex(i); | 1591 | VoxelTreeElement* child = voxel->getChildAtIndex(i); |
| 1592 | if (child) { | 1592 | if (child) { |
| 1593 | // Get the child's occluding faces, for a leaf, that will be | 1593 | // Get the child's occluding faces, for a leaf, that will be |
| 1594 | // all six voxel faces, and for a non leaf, that will be | 1594 | // all six voxel faces, and for a non leaf, that will be |
| 1595 | // all faces which are completely covered by four child octants. | 1595 | // all faces which are completely covered by four child octants. |
| 1596 | unsigned char exteriorOcclusionsOfChild = child->getExteriorOcclusions(); | 1596 | unsigned char exteriorOcclusionsOfChild = child->getExteriorOcclusions(); |
| 1597 | exteriorOcclusionsOfChild &= _sOctantIndexToBitMask[i]; | 1597 | exteriorOcclusionsOfChild &= _sOctantIndexToBitMask[i]; |
| 1598 | 1598 | ||
| 1599 | for (int j = 6; --j >= 0; ) { | 1599 | for (int j = 6; --j >= 0; ) { |
| 1600 | 1600 | ||
| 1601 | // Determine if the halfspace partition indexed by 1 << j is | 1601 | // Determine if the halfspace partition indexed by 1 << j is |
| 1602 | // present in the exterior occlusions of the child. | 1602 | // present in the exterior occlusions of the child. |
| 1603 | unsigned char partition = exteriorOcclusionsOfChild & (1 << j); | 1603 | unsigned char partition = exteriorOcclusionsOfChild & (1 << j); |
| 1604 | 1604 | ||
| 1605 | if (partition) { | 1605 | if (partition) { |
| 1606 | exteriorOcclusionsCt[j]++; | 1606 | exteriorOcclusionsCt[j]++; |
| 1607 | } | 1607 | } |
| 1608 | } | 1608 | } |
| 1609 | } | 1609 | } |
| 1610 | } | 1610 | } |
| 1611 | { | 1611 | { |
| 1612 | // Derive the exterior occlusions of the voxel elements from the exclusions | 1612 | // Derive the exterior occlusions of the voxel elements from the exclusions |
| 1613 | // of its children | 1613 | // of its children |
| 1614 | unsigned char exteriorOcclusions = OctreeElement::HalfSpace::None; | 1614 | unsigned char exteriorOcclusions = OctreeElement::HalfSpace::None; |
| 1615 | for (int i = 6; --i >= 0; ) { | 1615 | for (int i = 6; --i >= 0; ) { |
| 1616 | if (exteriorOcclusionsCt[i] == 4) { | 1616 | if (exteriorOcclusionsCt[i] == _sNumOctantsPerHemiVoxel) { |
| 1617 | 1617 | ||
| 1618 | // Exactly four octants qualify for full exterior occlusion | 1618 | // Exactly four octants qualify for full exterior occlusion |
| 1619 | exteriorOcclusions |= (1 << i); | 1619 | exteriorOcclusions |= (1 << i); |
| 1620 | } | 1620 | } |
| 1621 | } | 1621 | } |
| 1622 | 1622 | ||
| 1623 | // Inform the voxel element | 1623 | // Inform the voxel element |
| 1624 | voxel->setExteriorOcclusions(exteriorOcclusions); | 1624 | voxel->setExteriorOcclusions(exteriorOcclusions); |
| 1625 | 1625 | ||
| 1626 | if (exteriorOcclusions == OctreeElement::HalfSpace::All) { | 1626 | if (exteriorOcclusions == OctreeElement::HalfSpace::All) { |
| 1627 | //const glm::vec3& v = voxel->getCorner(); | 1627 | //const glm::vec3& v = voxel->getCorner(); |
| 1628 | //float s = voxel->getScale(); | 1628 | //float s = voxel->getScale(); |
| 1629 | 1629 | ||
| 1630 | //qDebug("Completely occupied voxel at %f %f %f size: %f", v.x, v.y, v.z, s); | 1630 | //qDebug("Completely occupied voxel at %f %f %f size: %f", v.x, v.y, v.z, s); |
| 1631 | 1631 | ||
| 1632 | // TODO: All of the exterior faces of this voxel element are | 1632 | // TODO: All of the exterior faces of this voxel element are |
| 1633 | // occluders, which means that this element is completely | 1633 | // occluders, which means that this element is completely |
| 1634 | // occupied. Hence, the subtree from this node could be | 1634 | // occupied. Hence, the subtree from this node could be |
| 1635 | // pruned and replaced by a leaf voxel, if the visible | 1635 | // pruned and replaced by a leaf voxel, if the visible |
| 1636 | // properties of the children are the same | 1636 | // properties of the children are the same |
| 1637 | } else if (exteriorOcclusions != OctreeElement::HalfSpace::None) { | 1637 | } else if (exteriorOcclusions != OctreeElement::HalfSpace::None) { |
| 1638 | //const glm::vec3& v = voxel->getCorner(); | 1638 | //const glm::vec3& v = voxel->getCorner(); |
| 1639 | //float s = voxel->getScale(); | 1639 | //float s = voxel->getScale(); |
| 1640 | 1640 | ||
| 1641 | //qDebug("Partially occupied voxel at %f %f %f size: %f with %02x", v.x, v.y, v.z, s, exteriorOcclusions); | 1641 | //qDebug("Partially occupied voxel at %f %f %f size: %f with %02x", v.x, v.y, v.z, s, exteriorOcclusions); |
| 1642 | } | 1642 | } |
| 1643 | } | 1643 | } |
| 1644 | return true; | 1644 | return true; |
| 1645 | } | 1645 | } |
| 1646 | 1646 | ||
| @@ -1648,55 +1648,55 @@ bool VoxelSystem::clearOcclusionsOperation(OctreeElement* element, void* extraDa · 1 unmodified line | |||
| 1648 | _nodeCount++; | 1648 | _nodeCount++; |
| 1649 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 1649 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| 1650 | 1650 | ||
| 1651 | bool rc; | 1651 | bool rc; |
| 1652 | if (voxel->isLeaf()) { | 1652 | if (voxel->isLeaf()) { |
| 1653 | 1653 | ||
| 1654 | // By definition the the exterior faces of a leaf voxel are | 1654 | // By definition the the exterior faces of a leaf voxel are |
| 1655 | // always occluders. | 1655 | // always occluders. |
| 1656 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::All); | 1656 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::All); |
| 1657 | 1657 | ||
| 1658 | // And the sibling occluders | 1658 | // And the sibling occluders |
| 1659 | voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); | 1659 | voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); |
| 1660 | rc = false; | 1660 | rc = false; |
| 1661 | } else { | 1661 | } else { |
| 1662 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::None); | 1662 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::None); |
| 1663 | voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); | 1663 | voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); |
| 1664 | rc = true; | 1664 | rc = true; |
| 1665 | } | 1665 | } |
| 1666 | 1666 | ||
| 1667 | return rc; | 1667 | return rc; |
| 1668 | } | 1668 | } |
| 1669 | 1669 | ||
| 1670 | void VoxelSystem::cullSharedFaces() { | 1670 | void VoxelSystem::cullSharedFaces() { |
| 1671 | _nodeCount = 0; | 1671 | _nodeCount = 0; |
| 1672 | 1672 | ||
| 1673 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { | 1673 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { |
| 1674 | _useVoxelShader = false; | 1674 | _useVoxelShader = false; |
| 1675 | _usePrimitiveRenderer = true; | 1675 | _usePrimitiveRenderer = true; |
| 1676 | _renderer->release(); | 1676 | _renderer->release(); |
| 1677 | clearAllNodesBufferIndex(); | 1677 | clearAllNodesBufferIndex(); |
| 1678 | lockTree(); | 1678 | lockTree(); |
| 1679 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); | 1679 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); |
| 1680 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); | 1680 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); |
| 1681 | unlockTree(); | 1681 | unlockTree(); |
| 1682 | 1682 | ||
| 1683 | _nodeCount = 0; | 1683 | _nodeCount = 0; |
| 1684 | lockTree(); | 1684 | lockTree(); |
| 1685 | _tree->recurseTreeWithOperation(inspectForInteriorOcclusionsOperation); | 1685 | _tree->recurseTreeWithOperation(inspectForInteriorOcclusionsOperation); |
| 1686 | unlockTree(); | 1686 | unlockTree(); |
| 1687 | qDebug("culling shared faces in %d nodes", _nodeCount); | 1687 | qDebug("culling shared faces in %d nodes", _nodeCount); |
| 1688 | } else { | 1688 | } else { |
| 1689 | _usePrimitiveRenderer = false; | 1689 | _usePrimitiveRenderer = false; |
| 1690 | _renderer->release(); | 1690 | _renderer->release(); |
| 1691 | clearAllNodesBufferIndex(); | 1691 | clearAllNodesBufferIndex(); |
| 1692 | lockTree(); | 1692 | lockTree(); |
| 1693 | _tree->recurseTreeWithOperation(clearOcclusionsOperation); | 1693 | _tree->recurseTreeWithOperation(clearOcclusionsOperation); |
| 1694 | unlockTree(); | 1694 | unlockTree(); |
| 1695 | 1695 | ||
| 1696 | 1696 | ||
| 1697 | qDebug("unculling shared faces in %d nodes", _nodeCount); | 1697 | qDebug("unculling shared faces in %d nodes", _nodeCount); |
| 1698 | } | 1698 | } |
| 1699 | _writeRenderFullVBO = true; | 1699 | _writeRenderFullVBO = true; |
| 1700 | _tree->setDirtyBit(); | 1700 | _tree->setDirtyBit(); |
| 1701 | setupNewVoxelsForDrawing(); | 1701 | setupNewVoxelsForDrawing(); |
| 1702 | 1702 | ||
| @@ -1705,9 +1705,9 @@ void VoxelSystem::cullSharedFaces() { · 2 unmodified lines | |||
| 1705 | void VoxelSystem::showCulledSharedFaces() { | 1705 | void VoxelSystem::showCulledSharedFaces() { |
| 1706 | 1706 | ||
| 1707 | if (Menu::getInstance()->isOptionChecked(MenuOption::ShowCulledSharedFaces)) { | 1707 | if (Menu::getInstance()->isOptionChecked(MenuOption::ShowCulledSharedFaces)) { |
| 1708 | _showCulledSharedFaces = true; | 1708 | _showCulledSharedFaces = true; |
| 1709 | } else { | 1709 | } else { |
| 1710 | _showCulledSharedFaces = false; | 1710 | _showCulledSharedFaces = false; |
| 1711 | } | 1711 | } |
| 1712 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { | 1712 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { |
| 1713 | cullSharedFaces(); | 1713 | cullSharedFaces(); |
| @@ -2337,12 +2337,12 @@ bool VoxelSystem::showAllSubTreeOperation(OctreeElement* element, void* extraDat · 623 unmodified lines | |||
| 2337 | // These are both needed to force redraw... | 2337 | // These are both needed to force redraw... |
| 2338 | voxel->setDirtyBit(); | 2338 | voxel->setDirtyBit(); |
| 2339 | voxel->markWithChangedTime(); | 2339 | voxel->markWithChangedTime(); |
| 2340 | // and this? | 2340 | // and this? |
| 2341 | { | 2341 | { |
| 2342 | VoxelSystem* thisVoxelSystem = args->thisVoxelSystem; | 2342 | VoxelSystem* thisVoxelSystem = args->thisVoxelSystem; |
| 2343 | thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->updateNodeInArrays(voxel, true, true); | 2343 | thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->updateNodeInArrays(voxel, true, true); |
| 2344 | thisVoxelSystem->setupNewVoxelsForDrawingSingleNode(); | 2344 | thisVoxelSystem->setupNewVoxelsForDrawingSingleNode(); |
| 2345 | } | 2345 | } |
| 2346 | args->nodesShown++; | 2346 | args->nodesShown++; |
| 2347 | } | 2347 | } |
| 2348 | 2348 | ||
| @@ -2522,8 +2522,8 @@ public: · 173 unmodified lines | |||
| 2522 | nodesInVBOOverExpectedMax(0), | 2522 | nodesInVBOOverExpectedMax(0), |
| 2523 | duplicateVBOIndex(0), | 2523 | duplicateVBOIndex(0), |
| 2524 | leafNodes(0), | 2524 | leafNodes(0), |
| 2525 | culledLeafNodes(0), | 2525 | culledLeafNodes(0), |
| 2526 | nodesInPrimitiveRenderer(0) | 2526 | nodesInPrimitiveRenderer(0) |
| 2527 | { | 2527 | { |
| 2528 | hasIndexFound = new bool[maxVoxels]; | 2528 | hasIndexFound = new bool[maxVoxels]; |
| 2529 | memset(hasIndexFound, false, maxVoxels * sizeof(bool)); | 2529 | memset(hasIndexFound, false, maxVoxels * sizeof(bool)); |
| @@ -2542,8 +2542,8 @@ public: · 12 unmodified lines | |||
| 2542 | unsigned long nodesInVBOOverExpectedMax; | 2542 | unsigned long nodesInVBOOverExpectedMax; |
| 2543 | unsigned long duplicateVBOIndex; | 2543 | unsigned long duplicateVBOIndex; |
| 2544 | unsigned long leafNodes; | 2544 | unsigned long leafNodes; |
| 2545 | unsigned long culledLeafNodes; ///< Number of completely culled nodes because of face sharing | 2545 | unsigned long culledLeafNodes; ///< Number of completely culled nodes because of face sharing |
| 2546 | unsigned long nodesInPrimitiveRenderer; | 2546 | unsigned long nodesInPrimitiveRenderer; |
| 2547 | 2547 | ||
| 2548 | unsigned long expectedMax; | 2548 | unsigned long expectedMax; |
| 2549 | 2549 | ||
| @@ -2558,9 +2558,9 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, v · 8 unmodified lines | |||
| 2558 | 2558 | ||
| 2559 | if (voxel->isLeaf()) { | 2559 | if (voxel->isLeaf()) { |
| 2560 | args->leafNodes++; | 2560 | args->leafNodes++; |
| 2561 | if (voxel->getInteriorOcclusions() == OctreeElement::HalfSpace::All) { | 2561 | if (voxel->getInteriorOcclusions() == OctreeElement::HalfSpace::All) { |
| 2562 | args->culledLeafNodes++; | 2562 | args->culledLeafNodes++; |
| 2563 | } | 2563 | } |
| 2564 | } | 2564 | } |
| 2565 | 2565 | ||
| 2566 | if (voxel->isColored()) { | 2566 | if (voxel->isColored()) { |
| @@ -2575,16 +2575,16 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, v · 8 unmodified lines | |||
| 2575 | args->dirtyNodes++; | 2575 | args->dirtyNodes++; |
| 2576 | } | 2576 | } |
| 2577 | 2577 | ||
| 2578 | unsigned long nodeIndex = 0; | 2578 | unsigned long nodeIndex = 0; |
| 2579 | if (voxel->isKnownBufferIndex()) { | 2579 | if (voxel->isKnownBufferIndex()) { |
| 2580 | args->nodesInVBO++; | 2580 | args->nodesInVBO++; |
| 2581 | nodeIndex = voxel->getBufferIndex(); | 2581 | nodeIndex = voxel->getBufferIndex(); |
| 2582 | } | 2582 | } |
| 2583 | 2583 | ||
| 2584 | if (voxel->getPrimitiveIndex()) { | 2584 | if (voxel->getPrimitiveIndex()) { |
| 2585 | args->nodesInPrimitiveRenderer++; | 2585 | args->nodesInPrimitiveRenderer++; |
| 2586 | nodeIndex = voxel->getPrimitiveIndex(); | 2586 | nodeIndex = voxel->getPrimitiveIndex(); |
| 2587 | } | 2587 | } |
| 2588 | 2588 | ||
| 2589 | if (voxel->isKnownBufferIndex() || (voxel->getPrimitiveIndex() != 0)) { | 2589 | if (voxel->isKnownBufferIndex() || (voxel->getPrimitiveIndex() != 0)) { |
| 2590 | 2590 | ||
| @@ -2593,7 +2593,7 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, v · 2 unmodified lines | |||
| 2593 | qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s, culledFaces=0x%02x \n", | 2593 | qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s, culledFaces=0x%02x \n", |
| 2594 | voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(), | 2594 | voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(), |
| 2595 | nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()), | 2595 | nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()), |
| 2596 | voxel->getInteriorOcclusions()); | 2596 | voxel->getInteriorOcclusions()); |
| 2597 | } | 2597 | } |
| 2598 | 2598 | ||
| 2599 | if (args->hasIndexFound[nodeIndex]) { | 2599 | if (args->hasIndexFound[nodeIndex]) { |
| @@ -2622,14 +2622,14 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 22 unmodified lines | |||
| 2622 | glBufferIndex minDirty = GLBUFFER_INDEX_UNKNOWN; | 2622 | glBufferIndex minDirty = GLBUFFER_INDEX_UNKNOWN; |
| 2623 | glBufferIndex maxDirty = 0; | 2623 | glBufferIndex maxDirty = 0; |
| 2624 | 2624 | ||
| 2625 | if (!_usePrimitiveRenderer) { | 2625 | if (!_usePrimitiveRenderer) { |
| 2626 | for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { | 2626 | for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { |
| 2627 | if (_writeVoxelDirtyArray[i]) { | 2627 | if (_writeVoxelDirtyArray[i]) { |
| 2628 | minDirty = std::min(minDirty,i); | 2628 | minDirty = std::min(minDirty,i); |
| 2629 | maxDirty = std::max(maxDirty,i); | 2629 | maxDirty = std::max(maxDirty,i); |
| 2630 | } | 2630 | } |
| 2631 | } | 2631 | } |
| 2632 | } | 2632 | } |
| 2633 | 2633 | ||
| 2634 | collectStatsForTreesAndVBOsArgs args(_maxVoxels); | 2634 | collectStatsForTreesAndVBOsArgs args(_maxVoxels); |
| 2635 | args.expectedMax = _voxelsInWriteArrays; | 2635 | args.expectedMax = _voxelsInWriteArrays; |
| @@ -3103,98 +3103,98 @@ void VoxelSystem::beginLoadingLocalVoxelCache() { · 467 unmodified lines | |||
| 3103 | // value corresponds to the voxel's octal code derived in "pointToVoxel" in SharedUtil.cpp, which, BTW, does *not* | 3103 | // value corresponds to the voxel's octal code derived in "pointToVoxel" in SharedUtil.cpp, which, BTW, does *not* |
| 3104 | // correspond to the "ChildIndex" enum value in OctreeElement.h | 3104 | // correspond to the "ChildIndex" enum value in OctreeElement.h |
| 3105 | unsigned char VoxelSystem::_sOctantIndexToBitMask[8] = { | 3105 | unsigned char VoxelSystem::_sOctantIndexToBitMask[8] = { |
| 3106 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Near, | 3106 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Near, |
| 3107 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Far, | 3107 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Far, |
| 3108 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Near, | 3108 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Near, |
| 3109 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Far, | 3109 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Far, |
| 3110 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Near, | 3110 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Near, |
| 3111 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Far, | 3111 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Far, |
| 3112 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Near, | 3112 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Near, |
| 3113 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Far, | 3113 | OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Far, |
| 3114 | }; | 3114 | }; |
| 3115 | 3115 | ||
| 3116 | // Two dimensional array map indexed by octant row and column. The mask value | 3116 | // Two dimensional array map indexed by octant row and column. The mask value |
| 3117 | // indicates the two faces shared by the octants | 3117 | // indicates the two faces shared by the octants |
| 3118 | unsigned char VoxelSystem::_sOctantIndexToSharedBitMask[8][8] = { | 3118 | unsigned char VoxelSystem::_sOctantIndexToSharedBitMask[8][8] = { |
| 3119 | { // Index 0: Bottom-Left-Near | 3119 | { // Index 0: Bottom-Left-Near |
| 3120 | 0, // Bottom-Left-Near | 3120 | 0, // Bottom-Left-Near |
| 3121 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Left-Far | 3121 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Left-Far |
| 3122 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Left-Near | 3122 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Left-Near |
| 3123 | 0, // Top-Left-Far | 3123 | 0, // Top-Left-Far |
| 3124 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Right-Near | 3124 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Right-Near |
| 3125 | 0, // Bottom-Right-Far | 3125 | 0, // Bottom-Right-Far |
| 3126 | 0, // Top-Right-Near | 3126 | 0, // Top-Right-Near |
| 3127 | 0, // Top-Right-Far | 3127 | 0, // Top-Right-Far |
| 3128 | }, | 3128 | }, |
| 3129 | { // Index 1: Bottom-Left-Far | 3129 | { // Index 1: Bottom-Left-Far |
| 3130 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Left-Near | 3130 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Left-Near |
| 3131 | 0, // Bottom-Left-Far | 3131 | 0, // Bottom-Left-Far |
| 3132 | 0, // Top-Left-Near | 3132 | 0, // Top-Left-Near |
| 3133 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Left-Far | 3133 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Left-Far |
| 3134 | 0, // Bottom-Right-Near | 3134 | 0, // Bottom-Right-Near |
| 3135 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Right-Far | 3135 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Right-Far |
| 3136 | 0, // Top-Right-Near | 3136 | 0, // Top-Right-Near |
| 3137 | 0, // Top-Right-Far | 3137 | 0, // Top-Right-Far |
| 3138 | }, | 3138 | }, |
| 3139 | { // Index 2: Top-Left-Near | 3139 | { // Index 2: Top-Left-Near |
| 3140 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Left-Near | 3140 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Left-Near |
| 3141 | 0, // Bottom-Left-Far | 3141 | 0, // Bottom-Left-Far |
| 3142 | 0, // Top-Left-Near | 3142 | 0, // Top-Left-Near |
| 3143 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Left-Far | 3143 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Left-Far |
| 3144 | 0, // Bottom-Right-Near | 3144 | 0, // Bottom-Right-Near |
| 3145 | 0, // Bottom-Right-Far | 3145 | 0, // Bottom-Right-Far |
| 3146 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Right-Near | 3146 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Right-Near |
| 3147 | 0, // Top-Right-Far | 3147 | 0, // Top-Right-Far |
| 3148 | }, | 3148 | }, |
| 3149 | { // Index 3: Top-Left-Far | 3149 | { // Index 3: Top-Left-Far |
| 3150 | 0, // Bottom-Left-Near | 3150 | 0, // Bottom-Left-Near |
| 3151 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Left-Far | 3151 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Left-Far |
| 3152 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Left-Near | 3152 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Left-Near |
| 3153 | 0, // Top-Left-Far | 3153 | 0, // Top-Left-Far |
| 3154 | 0, // Bottom-Right-Near | 3154 | 0, // Bottom-Right-Near |
| 3155 | 0, // Bottom-Right-Far | 3155 | 0, // Bottom-Right-Far |
| 3156 | 0, // Top-Right-Near | 3156 | 0, // Top-Right-Near |
| 3157 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Right-Far | 3157 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Right-Far |
| 3158 | }, | 3158 | }, |
| 3159 | { // Index 4: Bottom-Right-Near | 3159 | { // Index 4: Bottom-Right-Near |
| 3160 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Left-Near | 3160 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Left-Near |
| 3161 | 0, // Bottom-Left-Far | 3161 | 0, // Bottom-Left-Far |
| 3162 | 0, // Top-Left-Near | 3162 | 0, // Top-Left-Near |
| 3163 | 0, // Top-Left-Far | 3163 | 0, // Top-Left-Far |
| 3164 | 0, // Bottom-Right-Near | 3164 | 0, // Bottom-Right-Near |
| 3165 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Right-Far | 3165 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Right-Far |
| 3166 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Right-Near | 3166 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Right-Near |
| 3167 | 0, // Top-Right-Far | 3167 | 0, // Top-Right-Far |
| 3168 | }, | 3168 | }, |
| 3169 | { // Index 5: Bottom-Right-Far | 3169 | { // Index 5: Bottom-Right-Far |
| 3170 | 0, // Bottom-Left-Near | 3170 | 0, // Bottom-Left-Near |
| 3171 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Left-Far | 3171 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Left-Far |
| 3172 | 0, // Top-Left-Near | 3172 | 0, // Top-Left-Near |
| 3173 | 0, // Top-Left-Far | 3173 | 0, // Top-Left-Far |
| 3174 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Right-Near | 3174 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Right-Near |
| 3175 | 0, // Bottom-Right-Far | 3175 | 0, // Bottom-Right-Far |
| 3176 | 0, // Top-Right-Near | 3176 | 0, // Top-Right-Near |
| 3177 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Right-Far | 3177 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Right-Far |
| 3178 | }, | 3178 | }, |
| 3179 | { // Index 6: Top-Right-Near | 3179 | { // Index 6: Top-Right-Near |
| 3180 | 0, // Bottom-Left-Near | 3180 | 0, // Bottom-Left-Near |
| 3181 | 0, // Bottom-Left-Far | 3181 | 0, // Bottom-Left-Far |
| 3182 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Left-Near | 3182 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Left-Near |
| 3183 | 0, // Top-Left-Far | 3183 | 0, // Top-Left-Far |
| 3184 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Right-Near | 3184 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Right-Near |
| 3185 | 0, // Bottom-Right-Far | 3185 | 0, // Bottom-Right-Far |
| 3186 | 0, // Top-Right-Near | 3186 | 0, // Top-Right-Near |
| 3187 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Right-Far | 3187 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Right-Far |
| 3188 | }, | 3188 | }, |
| 3189 | { // Index 7: Top-Right-Far | 3189 | { // Index 7: Top-Right-Far |
| 3190 | 0, // Bottom-Left-Near | 3190 | 0, // Bottom-Left-Near |
| 3191 | 0, // Bottom-Left-Far | 3191 | 0, // Bottom-Left-Far |
| 3192 | 0, // Top-Left-Near | 3192 | 0, // Top-Left-Near |
| 3193 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Left-Far | 3193 | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Left-Far |
| 3194 | 0, // Bottom-Right-Near | 3194 | 0, // Bottom-Right-Near |
| 3195 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Right-Far | 3195 | OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Right-Far |
| 3196 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Right-Near | 3196 | OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Right-Near |
| 3197 | 0, // Top-Right-Far | 3197 | 0, // Top-Right-Far |
| 3198 | }, | 3198 | }, |
| 3199 | }; | 3199 | }; |
| 3200 | 3200 | ||