History

first cut at local voxel cache

Brad Hefta-Gaub committed 12 years ago

Commit c181d0a1 parent 03794f79 files · +416 −344Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+230−194
@@ -35,7 +35,6 @@ · 34 unmodified lines
35 35
36const bool VoxelSystem::DONT_BAIL_EARLY = false;36const bool VoxelSystem::DONT_BAIL_EARLY = false;
37 37
38
39float identityVerticesGlobalNormals[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 };38float identityVerticesGlobalNormals[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 };
40 39
41float identityVertices[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, //0-740float identityVertices[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, //0-7
@@ -107,16 +106,18 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 65 unmodified lines
107 106
108 _inSetupNewVoxelsForDrawing = false;107 _inSetupNewVoxelsForDrawing = false;
109 _useFastVoxelPipeline = false;108 _useFastVoxelPipeline = false;
110 109
111 _culledOnce = false;110 _culledOnce = false;
112 _inhideOutOfView = false;111 _inhideOutOfView = false;
113 _treeIsBusy = false;112 _treeIsBusy = false;
113
114}114}
115 115
116void VoxelSystem::elementDeleted(OctreeElement* element) {116void VoxelSystem::elementDeleted(OctreeElement* element) {
117 VoxelTreeElement* voxel = (VoxelTreeElement*)element;117 VoxelTreeElement* voxel = (VoxelTreeElement*)element;
118 if (voxel->getVoxelSystem() == this) {118 if (voxel->getVoxelSystem() == this) {
119 if (_voxelsInWriteArrays != 0) {119 if (_voxelsInWriteArrays != 0) {
120qDebug() << "elementDeleted()... about to call forceRemoveNodeFromArrays()\n";
120 forceRemoveNodeFromArrays(voxel);121 forceRemoveNodeFromArrays(voxel);
121 } else {122 } else {
122 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {123 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
@@ -148,11 +149,11 @@ void VoxelSystem::elementUpdated(OctreeElement* element) { · 25 unmodified lines
148 if (voxel->getShouldRender() != shouldRender) {149 if (voxel->getShouldRender() != shouldRender) {
149 voxel->setShouldRender(shouldRender);150 voxel->setShouldRender(shouldRender);
150 }151 }
151 152
152 if (!voxel->isLeaf()) {153 if (!voxel->isLeaf()) {
153 154
154 // As we check our children, see if any of them went from shouldRender to NOT shouldRender155 // As we check our children, see if any of them went from shouldRender to NOT shouldRender
155 // then we probably dropped LOD and if we don't have color, we want to average our children 156 // then we probably dropped LOD and if we don't have color, we want to average our children
156 // for a new color.157 // for a new color.
157 int childrenGotHiddenCount = 0;158 int childrenGotHiddenCount = 0;
158 for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {159 for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
@@ -176,7 +177,7 @@ void VoxelSystem::elementUpdated(OctreeElement* element) { · 17 unmodified lines
176 _voxelsUpdated++;177 _voxelsUpdated++;
177 178
178 voxel->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.179 voxel->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.
179 180
180 setupNewVoxelsForDrawingSingleNode();181 setupNewVoxelsForDrawingSingleNode();
181 }182 }
182}183}
@@ -219,7 +220,7 @@ void VoxelSystem::freeBufferIndex(glBufferIndex index) { · 36 unmodified lines
219 break;220 break;
220 }221 }
221 }222 }
222 } 223 }
223 if (!inList) {224 if (!inList) {
224 // make the index available for next node that needs to be drawn225 // make the index available for next node that needs to be drawn
225 pthread_mutex_lock(&_freeIndexLock);226 pthread_mutex_lock(&_freeIndexLock);
@@ -308,7 +309,7 @@ void VoxelSystem::setVoxelsAsPoints(bool voxelsAsPoints) { · 82 unmodified lines
308 }309 }
309 310
310 bool wasInitialized = _initialized;311 bool wasInitialized = _initialized;
311 312
312 // If we're "turning on" Voxels as points, we need to double check that we're in voxel shader mode.313 // If we're "turning on" Voxels as points, we need to double check that we're in voxel shader mode.
313 // Voxels as points uses the VoxelShader memory model, so if we're not in voxel shader mode,314 // Voxels as points uses the VoxelShader memory model, so if we're not in voxel shader mode,
314 // then set it to voxel shader mode.315 // then set it to voxel shader mode.
@@ -318,7 +319,7 @@ void VoxelSystem::setVoxelsAsPoints(bool voxelsAsPoints) { · 3 unmodified lines
318 // If enabling this... then do it before checking voxel shader status, that way, if voxel319 // If enabling this... then do it before checking voxel shader status, that way, if voxel
319 // shader is already enabled, we just start drawing as points.320 // shader is already enabled, we just start drawing as points.
320 _voxelsAsPoints = true;321 _voxelsAsPoints = true;
321 322
322 if (!_useVoxelShader) {323 if (!_useVoxelShader) {
323 setUseVoxelShader(true);324 setUseVoxelShader(true);
324 _voxelShaderModeWhenVoxelsAsPointsEnabled = false;325 _voxelShaderModeWhenVoxelsAsPointsEnabled = false;
@@ -354,7 +355,7 @@ void VoxelSystem::cleanupVoxelMemory() { · 29 unmodified lines
354 355
355 delete[] _writeVoxelShaderData;356 delete[] _writeVoxelShaderData;
356 delete[] _readVoxelShaderData;357 delete[] _readVoxelShaderData;
357 358
358 _writeVoxelShaderData = _readVoxelShaderData = NULL;359 _writeVoxelShaderData = _readVoxelShaderData = NULL;
359 360
360 } else {361 } else {
@@ -368,7 +369,7 @@ void VoxelSystem::cleanupVoxelMemory() { · 7 unmodified lines
368 glDeleteBuffers(1, &_vboIndicesRight);369 glDeleteBuffers(1, &_vboIndicesRight);
369 glDeleteBuffers(1, &_vboIndicesFront);370 glDeleteBuffers(1, &_vboIndicesFront);
370 glDeleteBuffers(1, &_vboIndicesBack);371 glDeleteBuffers(1, &_vboIndicesBack);
371 372
372 delete[] _readVerticesArray;373 delete[] _readVerticesArray;
373 delete[] _writeVerticesArray;374 delete[] _writeVerticesArray;
374 delete[] _readColorsArray;375 delete[] _readColorsArray;
@@ -420,12 +421,12 @@ void VoxelSystem::initVoxelMemory() { · 45 unmodified lines
420 421
421 _memoryUsageRAM = 0;422 _memoryUsageRAM = 0;
422 _memoryUsageVBO = 0; // our VBO allocations as we know them423 _memoryUsageVBO = 0; // our VBO allocations as we know them
423 424
424 // if _voxelsAsPoints then we must have _useVoxelShader425 // if _voxelsAsPoints then we must have _useVoxelShader
425 if (_voxelsAsPoints && !_useVoxelShader) {426 if (_voxelsAsPoints && !_useVoxelShader) {
426 _useVoxelShader = true;427 _useVoxelShader = true;
427 }428 }
428 429
429 if (_useVoxelShader) {430 if (_useVoxelShader) {
430 GLuint* indicesArray = new GLuint[_maxVoxels];431 GLuint* indicesArray = new GLuint[_maxVoxels];
431 432
@@ -445,7 +446,7 @@ void VoxelSystem::initVoxelMemory() { · 13 unmodified lines
445 glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);446 glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID);
446 glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);447 glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW);
447 _memoryUsageVBO += _maxVoxels * sizeof(VoxelShaderVBOData);448 _memoryUsageVBO += _maxVoxels * sizeof(VoxelShaderVBOData);
448 449
449 // delete the indices and normals arrays that are no longer needed450 // delete the indices and normals arrays that are no longer needed
450 delete[] indicesArray;451 delete[] indicesArray;
451 452
@@ -474,7 +475,7 @@ void VoxelSystem::initVoxelMemory() { · 22 unmodified lines
474 setupFaceIndices(_vboIndicesRight, identityIndicesRight);475 setupFaceIndices(_vboIndicesRight, identityIndicesRight);
475 setupFaceIndices(_vboIndicesFront, identityIndicesFront);476 setupFaceIndices(_vboIndicesFront, identityIndicesFront);
476 setupFaceIndices(_vboIndicesBack, identityIndicesBack);477 setupFaceIndices(_vboIndicesBack, identityIndicesBack);
477 478
478 // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel479 // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel
479 int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL;480 int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL;
480 glGenBuffers(1, &_vboVerticesID);481 glGenBuffers(1, &_vboVerticesID);
@@ -519,10 +520,10 @@ void VoxelSystem::initVoxelMemory() { · 38 unmodified lines
519 _perlinModulateProgram.bind();520 _perlinModulateProgram.bind();
520 _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);521 _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0);
521 _perlinModulateProgram.release();522 _perlinModulateProgram.release();
522 523
523 _shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/shadow_map.frag");524 _shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/shadow_map.frag");
524 _shadowMapProgram.link();525 _shadowMapProgram.link();
525 526
526 _shadowMapProgram.bind();527 _shadowMapProgram.bind();
527 _shadowMapProgram.setUniformValue("shadowMap", 0);528 _shadowMapProgram.setUniformValue("shadowMap", 0);
528 _shadowMapProgram.release();529 _shadowMapProgram.release();
@@ -571,26 +572,26 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 42 unmodified lines
571 switch(command) {572 switch(command) {
572 case PACKET_TYPE_VOXEL_DATA: {573 case PACKET_TYPE_VOXEL_DATA: {
573 PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() PACKET_TYPE_VOXEL_DATA part...",showTimingDetails);574 PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() PACKET_TYPE_VOXEL_DATA part...",showTimingDetails);
574 575
575 unsigned char* dataAt = sourceBuffer + numBytesPacketHeader;576 unsigned char* dataAt = sourceBuffer + numBytesPacketHeader;
576 577
577 VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));578 VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt));
578 dataAt += sizeof(VOXEL_PACKET_FLAGS);579 dataAt += sizeof(VOXEL_PACKET_FLAGS);
579 VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);580 VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);
580 dataAt += sizeof(VOXEL_PACKET_SEQUENCE);581 dataAt += sizeof(VOXEL_PACKET_SEQUENCE);
581 582
582 VOXEL_PACKET_SENT_TIME sentAt = (*(VOXEL_PACKET_SENT_TIME*)dataAt);583 VOXEL_PACKET_SENT_TIME sentAt = (*(VOXEL_PACKET_SENT_TIME*)dataAt);
583 dataAt += sizeof(VOXEL_PACKET_SENT_TIME);584 dataAt += sizeof(VOXEL_PACKET_SENT_TIME);
584 585
585 bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT);586 bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT);
586 bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT);587 bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT);
587 588
588 VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();589 VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
589 int flightTime = arrivedAt - sentAt;590 int flightTime = arrivedAt - sentAt;
590 591
591 VOXEL_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0;592 VOXEL_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0;
592 int dataBytes = numBytes - VOXEL_PACKET_HEADER_SIZE;593 int dataBytes = numBytes - VOXEL_PACKET_HEADER_SIZE;
593 594
594 int subsection = 1;595 int subsection = 1;
595 while (dataBytes > 0) {596 while (dataBytes > 0) {
596 if (packetIsCompressed) {597 if (packetIsCompressed) {
@@ -605,7 +606,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 8 unmodified lines
605 } else {606 } else {
606 sectionLength = dataBytes;607 sectionLength = dataBytes;
607 }608 }
608 609
609 if (sectionLength) {610 if (sectionLength) {
610 // ask the VoxelTree to read the bitstream into the tree611 // ask the VoxelTree to read the bitstream into the tree
611 ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());612 ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
@@ -616,12 +617,12 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 4 unmodified lines
616 qDebug("VoxelSystem::parseData() ... Got Packet Section"617 qDebug("VoxelSystem::parseData() ... Got Packet Section"
617 " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"618 " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d"
618 " subsection:%d sectionLength:%d uncompressed:%d\n",619 " subsection:%d sectionLength:%d uncompressed:%d\n",
619 debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), 620 debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed),
620 sequence, flightTime, numBytes, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());621 sequence, flightTime, numBytes, dataBytes, subsection, sectionLength, packetData.getUncompressedSize());
621 }622 }
622 _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);623 _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args);
623 unlockTree();624 unlockTree();
624 625
625 dataBytes -= sectionLength;626 dataBytes -= sectionLength;
626 dataAt += sectionLength;627 dataAt += sectionLength;
627 }628 }
@@ -635,15 +636,13 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 7 unmodified lines
635 } else {636 } else {
636 setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);637 setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
637 }638 }
638 639
639 Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(numBytes);640 Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(numBytes);
640 641
641 return numBytes;642 return numBytes;
642}643}
643 644
644void VoxelSystem::setupNewVoxelsForDrawing() {645void VoxelSystem::setupNewVoxelsForDrawing() {
645
646
647 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),646 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
648 "setupNewVoxelsForDrawing()");647 "setupNewVoxelsForDrawing()");
649 648
@@ -653,7 +652,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 3 unmodified lines
653 652
654 uint64_t start = usecTimestampNow();653 uint64_t start = usecTimestampNow();
655 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;654 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
656 655
657 bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging656 bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
658 if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {657 if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
659 return; // bail early, it hasn't been long enough since the last time we ran658 return; // bail early, it hasn't been long enough since the last time we ran
@@ -665,7 +664,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 5 unmodified lines
665 if (_tree->isDirty()) {664 if (_tree->isDirty()) {
666 static char buffer[64] = { 0 };665 static char buffer[64] = { 0 };
667 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {666 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
668 sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", debug::valueOf(_writeRenderFullVBO)); 667 sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", debug::valueOf(_writeRenderFullVBO));
669 };668 };
670 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer);669 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer);
671 _callsToTreesToArrays++;670 _callsToTreesToArrays++;
@@ -678,17 +677,17 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 6 unmodified lines
678 if (_writeRenderFullVBO) {677 if (_writeRenderFullVBO) {
679 _abandonedVBOSlots = 0; // reset the count of our abandoned slots, why is this here and not earlier????678 _abandonedVBOSlots = 0; // reset the count of our abandoned slots, why is this here and not earlier????
680 }679 }
681 680
682 // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are681 // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are
683 // ok again, until/unless we call removeOutOfView() 682 // ok again, until/unless we call removeOutOfView()
684 _writeRenderFullVBO = false; 683 _writeRenderFullVBO = false;
685 } else {684 } else {
686 _voxelsUpdated = 0;685 _voxelsUpdated = 0;
687 }686 }
688 687
689 // lock on the buffer write lock so we can't modify the data when the GPU is reading it688 // lock on the buffer write lock so we can't modify the data when the GPU is reading it
690 pthread_mutex_lock(&_bufferWriteLock);689 pthread_mutex_lock(&_bufferWriteLock);
691 690
692 if (_voxelsUpdated) {691 if (_voxelsUpdated) {
693 _voxelsDirty=true;692 _voxelsDirty=true;
694 }693 }
@@ -703,6 +702,11 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 8 unmodified lines
703 _setupNewVoxelsForDrawingLastFinished = end;702 _setupNewVoxelsForDrawingLastFinished = end;
704 _setupNewVoxelsForDrawingLastElapsed = elapsedmsec;703 _setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
705 _inSetupNewVoxelsForDrawing = false;704 _inSetupNewVoxelsForDrawing = false;
705
706 bool extraDebugging = Application::getInstance()->getLogger()->extraDebugging();
707 if (extraDebugging) {
708 qDebug("setupNewVoxelsForDrawing()... _voxelsUpdated=%lu...\n",_voxelsUpdated);
709 }
706}710}
707 711
708void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {712void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) {
@@ -713,7 +717,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 4 unmodified lines
713 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;717 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
714 718
715 bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging719 bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
716 if (allowBailEarly && !iAmDebugging && 720 if (allowBailEarly && !iAmDebugging &&
717 sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {721 sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
718 return; // bail early, it hasn't been long enough since the last time we ran722 return; // bail early, it hasn't been long enough since the last time we ran
719 }723 }
@@ -745,19 +749,17 @@ void VoxelSystem::checkForCulling() { · 25 unmodified lines
745 749
746 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()");750 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()");
747 uint64_t start = usecTimestampNow();751 uint64_t start = usecTimestampNow();
748 752
749
750 // track how long its been since we were last moving. If we have recently moved then only use delta frustums, if753 // track how long its been since we were last moving. If we have recently moved then only use delta frustums, if
751 // it's been a long time since we last moved, then go ahead and do a full frustum cull.754 // it's been a long time since we last moved, then go ahead and do a full frustum cull.
752 if (isViewChanging()) {755 if (isViewChanging()) {
753 _lastViewIsChanging = start;756 _lastViewIsChanging = start;
754 }757 }
755 uint64_t sinceLastMoving = (start - _lastViewIsChanging) / 1000;758 uint64_t sinceLastMoving = (start - _lastViewIsChanging) / 1000;
756
757 bool enoughTime = (sinceLastMoving >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS));759 bool enoughTime = (sinceLastMoving >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS));
758 760
759 // These has changed events will occur before we stop. So we need to remember this for when we finally have stopped761 // These has changed events will occur before we stop. So we need to remember this for when we finally have stopped
760 // moving long enough to be enoughTime 762 // moving long enough to be enoughTime
761 if (hasViewChanged()) {763 if (hasViewChanged()) {
762 _hasRecentlyChanged = true;764 _hasRecentlyChanged = true;
763 }765 }
@@ -767,25 +769,25 @@ void VoxelSystem::checkForCulling() { · 3 unmodified lines
767 bool forceFullFrustum = enoughTime && _hasRecentlyChanged;769 bool forceFullFrustum = enoughTime && _hasRecentlyChanged;
768 770
769 // in hide mode, we only track the full frustum culls, because we don't care about the partials.771 // in hide mode, we only track the full frustum culls, because we don't care about the partials.
770 if (forceFullFrustum) { 772 if (forceFullFrustum) {
771 _lastViewCulling = start;773 _lastViewCulling = start;
772 _hasRecentlyChanged = false;774 _hasRecentlyChanged = false;
773 }775 }
774 776
775 hideOutOfView(forceFullFrustum);777 hideOutOfView(forceFullFrustum);
776 778
777 if (forceFullFrustum) { 779 if (forceFullFrustum) {
778 uint64_t endViewCulling = usecTimestampNow();780 uint64_t endViewCulling = usecTimestampNow();
779 _lastViewCullingElapsed = (endViewCulling - start) / 1000;781 _lastViewCullingElapsed = (endViewCulling - start) / 1000;
780 }782 }
781 783
782 // Once we call cleanupRemovedVoxels() we do need to rebuild our VBOs (if anything was actually removed). So,784 // Once we call cleanupRemovedVoxels() we do need to rebuild our VBOs (if anything was actually removed). So,
783 // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on785 // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on
784 // VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.786 // VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
785 cleanupRemovedVoxels();787 cleanupRemovedVoxels();
786 788
787 uint64_t sinceLastAudit = (start - _lastAudit) / 1000;789 uint64_t sinceLastAudit = (start - _lastAudit) / 1000;
788 790
789 if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {791 if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
790 if (sinceLastAudit >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) {792 if (sinceLastAudit >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) {
791 _lastAudit = start;793 _lastAudit = start;
@@ -812,7 +814,7 @@ void VoxelSystem::cleanupRemovedVoxels() { · 20 unmodified lines
812 const float TOO_MANY_ABANDONED_RATIO = 0.5f;814 const float TOO_MANY_ABANDONED_RATIO = 0.5f;
813 if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) {815 if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) {
814 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {816 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
815 qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots [" 817 qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots ["
816 << _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO \n";818 << _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO \n";
817 }819 }
818 _writeRenderFullVBO = true;820 _writeRenderFullVBO = true;
@@ -822,10 +824,10 @@ void VoxelSystem::cleanupRemovedVoxels() { · 3 unmodified lines
822void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() {824void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() {
823 copyWrittenDataSegmentToReadArrays(0, _voxelsInWriteArrays - 1);825 copyWrittenDataSegmentToReadArrays(0, _voxelsInWriteArrays - 1);
824 _voxelsInReadArrays = _voxelsInWriteArrays;826 _voxelsInReadArrays = _voxelsInWriteArrays;
825 827
826 // clear our dirty flags828 // clear our dirty flags
827 memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool));829 memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool));
828 830
829 // let the reader know to get the full array831 // let the reader know to get the full array
830 _readRenderFullVBO = true;832 _readRenderFullVBO = true;
831}833}
@@ -851,7 +853,7 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { · 19 unmodified lines
851 }853 }
852 }854 }
853 }855 }
854 856
855 // if we got to the end of the array, and we're in an active dirty segment...857 // if we got to the end of the array, and we're in an active dirty segment...
856 if (inSegment) {858 if (inSegment) {
857 copyWrittenDataSegmentToReadArrays(segmentStart, _voxelsInWriteArrays - 1);859 copyWrittenDataSegmentToReadArrays(segmentStart, _voxelsInWriteArrays - 1);
@@ -910,9 +912,9 @@ int VoxelSystem::newTreeToArrays(VoxelTreeElement* voxel) { · 52 unmodified lines
910 voxel->setShouldRender(shouldRender);912 voxel->setShouldRender(shouldRender);
911 // let children figure out their renderness913 // let children figure out their renderness
912 if (!voxel->isLeaf()) {914 if (!voxel->isLeaf()) {
913 915
914 // As we check our children, see if any of them went from shouldRender to NOT shouldRender916 // As we check our children, see if any of them went from shouldRender to NOT shouldRender
915 // then we probably dropped LOD and if we don't have color, we want to average our children 917 // then we probably dropped LOD and if we don't have color, we want to average our children
916 // for a new color.918 // for a new color.
917 int childrenGotHiddenCount = 0;919 int childrenGotHiddenCount = 0;
918 for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {920 for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
@@ -930,17 +932,23 @@ int VoxelSystem::newTreeToArrays(VoxelTreeElement* voxel) { · 11 unmodified lines
930 voxel->calculateAverageFromChildren();932 voxel->calculateAverageFromChildren();
931 }933 }
932 }934 }
933 if (_writeRenderFullVBO) {935
934 const bool DONT_REUSE_INDEX = false;936 // for either voxels that should not render, or those that should render and are in view
935 const bool FORCE_REDRAW = true;937 // update their geometry in the array.if the voxel "should render" but is not in view, then
936 voxelsUpdated += updateNodeInArrays(voxel, DONT_REUSE_INDEX, FORCE_REDRAW);938 // it actually doesn't need to be rendered
937 } else {939 if (!shouldRender || voxel->isInView(*_viewFrustum)) {
938 const bool REUSE_INDEX = true;940 if (_writeRenderFullVBO) {
939 const bool DONT_FORCE_REDRAW = false;941 const bool DONT_REUSE_INDEX = false;
940 voxelsUpdated += updateNodeInArrays(voxel, REUSE_INDEX, DONT_FORCE_REDRAW);942 const bool FORCE_REDRAW = true;
943 voxelsUpdated += updateNodeInArrays(voxel, DONT_REUSE_INDEX, FORCE_REDRAW);
944 } else {
945 const bool REUSE_INDEX = true;
946 const bool DONT_FORCE_REDRAW = false;
947 voxelsUpdated += updateNodeInArrays(voxel, REUSE_INDEX, DONT_FORCE_REDRAW);
948 }
941 }949 }
942 voxel->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.950 voxel->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.
943 951
944 return voxelsUpdated;952 return voxelsUpdated;
945}953}
946 954
@@ -959,7 +967,7 @@ int VoxelSystem::forceRemoveNodeFromArrays(VoxelTreeElement* node) { · 12 unmodified lines
959 // If this node has not yet been written to the array, then add it to the end of the array.967 // If this node has not yet been written to the array, then add it to the end of the array.
960 glBufferIndex nodeIndex = node->getBufferIndex();968 glBufferIndex nodeIndex = node->getBufferIndex();
961 node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);969 node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
962 freeBufferIndex(nodeIndex); // NOTE: This is make the node invisible!970 freeBufferIndex(nodeIndex); // NOTE: This will make the node invisible!
963 return 1; // updated!971 return 1; // updated!
964 }972 }
965 return 0; // not-updated973 return 0; // not-updated
@@ -982,11 +990,11 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo · 16 unmodified lines
982 if (!_initialized) {990 if (!_initialized) {
983 return 0;991 return 0;
984 }992 }
985 993
986 // If we've changed any attributes (our renderness, our color, etc), or we've been told to force a redraw994 // If we've changed any attributes (our renderness, our color, etc), or we've been told to force a redraw
987 // then update the Arrays...995 // then update the Arrays...
988 if (forceDraw || node->isDirty()) {996 if (forceDraw || node->isDirty()) {
989 // If we're should render, use our legit location and scale, 997 // If we're should render, use our legit location and scale,
990 if (node->getShouldRender()) {998 if (node->getShouldRender()) {
991 glm::vec3 startVertex = node->getCorner();999 glm::vec3 startVertex = node->getCorner();
992 float voxelScale = node->getScale();1000 float voxelScale = node->getScale();
@@ -1016,9 +1024,9 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo · 23 unmodified lines
1016void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,1024void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
1017 float voxelScale, const nodeColor& color) {1025 float voxelScale, const nodeColor& color) {
1018 1026
1019 if (_initialized) {1027 if (_initialized && nodeIndex <= _maxVoxels) {
1020 _writeVoxelDirtyArray[nodeIndex] = true;1028 _writeVoxelDirtyArray[nodeIndex] = true;
1021 1029
1022 if (_useVoxelShader) {1030 if (_useVoxelShader) {
1023 if (_writeVoxelShaderData) {1031 if (_writeVoxelShaderData) {
1024 VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];1032 VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
@@ -1071,15 +1079,17 @@ void VoxelSystem::init() { · 46 unmodified lines
1071 // VBO for the verticesArray1079 // VBO for the verticesArray
1072 _initialMemoryUsageGPU = getFreeMemoryGPU();1080 _initialMemoryUsageGPU = getFreeMemoryGPU();
1073 initVoxelMemory();1081 initVoxelMemory();
1074 1082
1075 // our own _removedVoxels doesn't need to be notified of voxel deletes1083 // our own _removedVoxels doesn't need to be notified of voxel deletes
1076 VoxelTreeElement::removeDeleteHook(&_removedVoxels);1084 VoxelTreeElement::removeDeleteHook(&_removedVoxels);
1085
1077}1086}
1078 1087
1079void VoxelSystem::changeTree(VoxelTree* newTree) {1088void VoxelSystem::changeTree(VoxelTree* newTree) {
1080 disconnect(_tree, 0, this, 0);1089 disconnect(_tree, 0, this, 0);
1081 1090
1082 _tree = newTree;1091 _tree = newTree;
1092
1083 _tree->setDirtyBit();1093 _tree->setDirtyBit();
1084 _tree->getRoot()->setVoxelSystem(this);1094 _tree->getRoot()->setVoxelSystem(this);
1085 1095
@@ -1102,7 +1112,7 @@ void VoxelSystem::updateFullVBOs() { · 16 unmodified lines
1102 PerformanceWarning warn(outputWarning,buffer);1112 PerformanceWarning warn(outputWarning,buffer);
1103 updateVBOSegment(0, _voxelsInReadArrays);1113 updateVBOSegment(0, _voxelsInReadArrays);
1104 }1114 }
1105 1115
1106 {1116 {
1107 PerformanceWarning warn(outputWarning,"updateFullVBOs() : memset(_readVoxelDirtyArray...)");1117 PerformanceWarning warn(outputWarning,"updateFullVBOs() : memset(_readVoxelDirtyArray...)");
1108 // consider the _readVoxelDirtyArray[] clean!1118 // consider the _readVoxelDirtyArray[] clean!
@@ -1131,7 +1141,7 @@ void VoxelSystem::updatePartialVBOs() { · 22 unmodified lines
1131 _readVoxelDirtyArray[i] = false; // consider us clean!1141 _readVoxelDirtyArray[i] = false; // consider us clean!
1132 }1142 }
1133 }1143 }
1134 1144
1135 // if we got to the end of the array, and we're in an active dirty segment...1145 // if we got to the end of the array, and we're in an active dirty segment...
1136 if (inSegment) {1146 if (inSegment) {
1137 updateVBOSegment(segmentStart, _voxelsInReadArrays - 1);1147 updateVBOSegment(segmentStart, _voxelsInReadArrays - 1);
@@ -1195,7 +1205,7 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg · 57 unmodified lines
1195 PerformanceWarning warn(showWarning, "updateVBOSegment() : glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);");1205 PerformanceWarning warn(showWarning, "updateVBOSegment() : glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);");
1196 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);1206 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
1197 }1207 }
1198 1208
1199 {1209 {
1200 PerformanceWarning warn(showWarning, "updateVBOSegment() : glBufferSubData() _vboColorsID);");1210 PerformanceWarning warn(showWarning, "updateVBOSegment() : glBufferSubData() _vboColorsID);");
1201 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);1211 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
@@ -1206,14 +1216,14 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg · 4 unmodified lines
1206void VoxelSystem::render(bool texture) {1216void VoxelSystem::render(bool texture) {
1207 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);1217 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
1208 PerformanceWarning warn(showWarnings, "render()");1218 PerformanceWarning warn(showWarnings, "render()");
1209 1219
1210 // If we got here and we're not initialized then bail!1220 // If we got here and we're not initialized then bail!
1211 if (!_initialized) {1221 if (!_initialized) {
1212 return;1222 return;
1213 }1223 }
1214 1224
1215 updateVBOs();1225 updateVBOs();
1216 1226
1217 bool dontCallOpenGLDraw = Menu::getInstance()->isOptionChecked(MenuOption::DontCallOpenGLForVoxels);1227 bool dontCallOpenGLDraw = Menu::getInstance()->isOptionChecked(MenuOption::DontCallOpenGLForVoxels);
1218 // if not don't... then do...1228 // if not don't... then do...
1219 if (_useVoxelShader) {1229 if (_useVoxelShader) {
@@ -1253,8 +1263,8 @@ void VoxelSystem::render(bool texture) { · 33 unmodified lines
1253 glEnableVertexAttribArray(attributeLocation);1263 glEnableVertexAttribArray(attributeLocation);
1254 glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float)));1264 glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float)));
1255 }1265 }
1256 1266
1257 1267
1258 glEnableClientState(GL_COLOR_ARRAY);1268 glEnableClientState(GL_COLOR_ARRAY);
1259 glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(4*sizeof(float)));//The starting point of colors1269 glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(4*sizeof(float)));//The starting point of colors
1260 1270
@@ -1285,7 +1295,7 @@ void VoxelSystem::render(bool texture) { · 24 unmodified lines
1285 1295
1286 {1296 {
1287 PerformanceWarning warn(showWarnings,"render().. setup before glDrawRangeElementsEXT()...");1297 PerformanceWarning warn(showWarnings,"render().. setup before glDrawRangeElementsEXT()...");
1288 1298
1289 // tell OpenGL where to find vertex and color information1299 // tell OpenGL where to find vertex and color information
1290 glEnableClientState(GL_VERTEX_ARRAY);1300 glEnableClientState(GL_VERTEX_ARRAY);
1291 glEnableClientState(GL_COLOR_ARRAY);1301 glEnableClientState(GL_COLOR_ARRAY);
@@ -1306,7 +1316,7 @@ void VoxelSystem::render(bool texture) { · 14 unmodified lines
1306 1316
1307 if (!dontCallOpenGLDraw) {1317 if (!dontCallOpenGLDraw) {
1308 PerformanceWarning warn(showWarnings, "render().. glDrawRangeElementsEXT()...");1318 PerformanceWarning warn(showWarnings, "render().. glDrawRangeElementsEXT()...");
1309 1319
1310 glNormal3f(0,1.0f,0);1320 glNormal3f(0,1.0f,0);
1311 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesTop);1321 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesTop);
1312 glDrawRangeElementsEXT(GL_TRIANGLES, 0, GLOBAL_NORMALS_VERTICES_PER_VOXEL * _voxelsInReadArrays - 1,1322 glDrawRangeElementsEXT(GL_TRIANGLES, 0, GLOBAL_NORMALS_VERTICES_PER_VOXEL * _voxelsInReadArrays - 1,
@@ -1340,7 +1350,7 @@ void VoxelSystem::render(bool texture) { · 27 unmodified lines
1340 1350
1341 {1351 {
1342 PerformanceWarning warn(showWarnings, "render().. cleanup after glDrawRangeElementsEXT()...");1352 PerformanceWarning warn(showWarnings, "render().. cleanup after glDrawRangeElementsEXT()...");
1343 1353
1344 glDisable(GL_CULL_FACE);1354 glDisable(GL_CULL_FACE);
1345 1355
1346 removeScaleAndReleaseProgram(texture);1356 removeScaleAndReleaseProgram(texture);
@@ -1365,16 +1375,16 @@ void VoxelSystem::applyScaleAndBindProgram(bool texture) { · 18 unmodified lines
1365 glEnable(GL_TEXTURE_GEN_T);1375 glEnable(GL_TEXTURE_GEN_T);
1366 glEnable(GL_TEXTURE_GEN_R);1376 glEnable(GL_TEXTURE_GEN_R);
1367 glEnable(GL_TEXTURE_2D);1377 glEnable(GL_TEXTURE_2D);
1368 1378
1369 glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[0]);1379 glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[0]);
1370 glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[1]);1380 glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[1]);
1371 glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[2]);1381 glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&Application::getInstance()->getShadowMatrix()[2]);
1372 1382
1373 } else if (texture) {1383 } else if (texture) {
1374 _perlinModulateProgram.bind();1384 _perlinModulateProgram.bind();
1375 glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());1385 glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());
1376 }1386 }
1377 1387
1378 glPushMatrix();1388 glPushMatrix();
1379 glScalef(_treeScale, _treeScale, _treeScale);1389 glScalef(_treeScale, _treeScale, _treeScale);
1380}1390}
@@ -1382,7 +1392,7 @@ void VoxelSystem::applyScaleAndBindProgram(bool texture) { · 1 unmodified line
1382void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {1392void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
1383 // scale back down to 1 so heads aren't massive1393 // scale back down to 1 so heads aren't massive
1384 glPopMatrix();1394 glPopMatrix();
1385 1395
1386 if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {1396 if (Menu::getInstance()->isOptionChecked(MenuOption::Shadows)) {
1387 _shadowMapProgram.release();1397 _shadowMapProgram.release();
1388 glBindTexture(GL_TEXTURE_2D, 0);1398 glBindTexture(GL_TEXTURE_2D, 0);
@@ -1390,7 +1400,7 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { · 1 unmodified line
1390 glDisable(GL_TEXTURE_GEN_T);1400 glDisable(GL_TEXTURE_GEN_T);
1391 glDisable(GL_TEXTURE_GEN_R);1401 glDisable(GL_TEXTURE_GEN_R);
1392 glDisable(GL_TEXTURE_2D);1402 glDisable(GL_TEXTURE_2D);
1393 1403
1394 } else if (texture) {1404 } else if (texture) {
1395 _perlinModulateProgram.release();1405 _perlinModulateProgram.release();
1396 glBindTexture(GL_TEXTURE_2D, 0);1406 glBindTexture(GL_TEXTURE_2D, 0);
@@ -1403,7 +1413,7 @@ void VoxelSystem::killLocalVoxels() { · 6 unmodified lines
1403 lockTree();1413 lockTree();
1404 _tree->eraseAllOctreeElements();1414 _tree->eraseAllOctreeElements();
1405 unlockTree();1415 unlockTree();
1406 clearFreeBufferIndexes(); 1416 clearFreeBufferIndexes();
1407 _voxelsInReadArrays = 0; // do we need to do this?1417 _voxelsInReadArrays = 0; // do we need to do this?
1408 setupNewVoxelsForDrawing();1418 setupNewVoxelsForDrawing();
1409}1419}
@@ -1422,7 +1432,7 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void · 12 unmodified lines
1422 1432
1423void VoxelSystem::clearAllNodesBufferIndex() {1433void VoxelSystem::clearAllNodesBufferIndex() {
1424 _nodeCount = 0;1434 _nodeCount = 0;
1425 lockTree(); 1435 lockTree();
1426 _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);1436 _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation);
1427 unlockTree();1437 unlockTree();
1428 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {1438 if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
@@ -1584,9 +1594,9 @@ void VoxelSystem::falseColorizeBySource() { · 155 unmodified lines
1584 const int NUMBER_OF_COLOR_GROUPS = 6;1594 const int NUMBER_OF_COLOR_GROUPS = 6;
1585 const unsigned char MIN_COLOR = 128;1595 const unsigned char MIN_COLOR = 128;
1586 int voxelServerCount = 0;1596 int voxelServerCount = 0;
1587 groupColor groupColors[NUMBER_OF_COLOR_GROUPS] = { 1597 groupColor groupColors[NUMBER_OF_COLOR_GROUPS] = {
1588 groupColor(255, 0, 0), 1598 groupColor(255, 0, 0),
1589 groupColor( 0, 255, 0), 1599 groupColor( 0, 255, 0),
1590 groupColor( 0, 0, 255),1600 groupColor( 0, 0, 255),
1591 groupColor(255, 0, 255),1601 groupColor(255, 0, 255),
1592 groupColor( 0, 255, 255),1602 groupColor( 0, 255, 255),
@@ -1614,7 +1624,7 @@ void VoxelSystem::falseColorizeBySource() { · 21 unmodified lines
1614 voxelServerCount++;1624 voxelServerCount++;
1615 }1625 }
1616 }1626 }
1617 1627
1618 _tree->recurseTreeWithOperation(falseColorizeBySourceOperation, &args);1628 _tree->recurseTreeWithOperation(falseColorizeBySourceOperation, &args);
1619 qDebug("setting false color by source for %d nodes\n", _nodeCount);1629 qDebug("setting false color by source for %d nodes\n", _nodeCount);
1620 _tree->setDirtyBit();1630 _tree->setDirtyBit();
@@ -1690,7 +1700,7 @@ public: · 69 unmodified lines
1690 unsigned long nodesOutside;1700 unsigned long nodesOutside;
1691 VoxelTreeElement* insideRoot;1701 VoxelTreeElement* insideRoot;
1692 VoxelTreeElement* outsideRoot;1702 VoxelTreeElement* outsideRoot;
1693 1703
1694 removeOutOfViewArgs(VoxelSystem* voxelSystem, bool widenViewFrustum = true) :1704 removeOutOfViewArgs(VoxelSystem* voxelSystem, bool widenViewFrustum = true) :
1695 thisVoxelSystem(voxelSystem),1705 thisVoxelSystem(voxelSystem),
1696 thisViewFrustum(*voxelSystem->getViewFrustum()),1706 thisViewFrustum(*voxelSystem->getViewFrustum()),
@@ -1730,7 +1740,7 @@ bool VoxelSystem::removeOutOfViewOperation(OctreeElement* element, void* extraDa · 33 unmodified lines
1730 args->dontRecurseBag.remove(voxel);1740 args->dontRecurseBag.remove(voxel);
1731 return false; // stop recursion1741 return false; // stop recursion
1732 }1742 }
1733 1743
1734 VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;1744 VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
1735 args->nodesScanned++;1745 args->nodesScanned++;
1736 // Need to operate on our child nodes, so we can remove them1746 // Need to operate on our child nodes, so we can remove them
@@ -1748,7 +1758,7 @@ bool VoxelSystem::removeOutOfViewOperation(OctreeElement* element, void* extraDa · 11 unmodified lines
1748 } break;1758 } break;
1749 case ViewFrustum::INSIDE: {1759 case ViewFrustum::INSIDE: {
1750 // if the child node is fully INSIDE the view, then there's no need to recurse it1760 // if the child node is fully INSIDE the view, then there's no need to recurse it
1751 // because we know all it's children will also be in the view, so we want to 1761 // because we know all it's children will also be in the view, so we want to
1752 // tell the caller to NOT recurse this child1762 // tell the caller to NOT recurse this child
1753 args->nodesInside++;1763 args->nodesInside++;
1754 args->dontRecurseBag.insert(childNode);1764 args->dontRecurseBag.insert(childNode);
@@ -1779,12 +1789,12 @@ bool VoxelSystem::isViewChanging() { · 24 unmodified lines
1779 1789
1780bool VoxelSystem::hasViewChanged() {1790bool VoxelSystem::hasViewChanged() {
1781 bool result = false; // assume the best1791 bool result = false; // assume the best
1782 1792
1783 // If we're still changing, report no change yet.1793 // If we're still changing, report no change yet.
1784 if (isViewChanging()) {1794 if (isViewChanging()) {
1785 return false;1795 return false;
1786 }1796 }
1787 1797
1788 // If our viewFrustum has changed since our _lastKnownViewFrustum1798 // If our viewFrustum has changed since our _lastKnownViewFrustum
1789 if (!_lastStableViewFrustum.isVerySimilar(_viewFrustum)) {1799 if (!_lastStableViewFrustum.isVerySimilar(_viewFrustum)) {
1790 result = true;1800 result = true;
@@ -1803,8 +1813,8 @@ void VoxelSystem::removeOutOfView() { · 12 unmodified lines
1803 }1813 }
1804 bool showRemoveDebugDetails = false;1814 bool showRemoveDebugDetails = false;
1805 if (showRemoveDebugDetails) {1815 if (showRemoveDebugDetails) {
1806 qDebug("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n", 1816 qDebug("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n",
1807 args.nodesScanned, args.nodesRemoved, args.nodesInside, 1817 args.nodesScanned, args.nodesRemoved, args.nodesInside,
1808 args.nodesIntersect, args.nodesOutside, _removedVoxels.count()1818 args.nodesIntersect, args.nodesOutside, _removedVoxels.count()
1809 );1819 );
1810 }1820 }
@@ -1816,9 +1826,9 @@ public: · 5 unmodified lines
1816 VoxelSystem* thisVoxelSystem;1826 VoxelSystem* thisVoxelSystem;
1817 ViewFrustum thisViewFrustum;1827 ViewFrustum thisViewFrustum;
1818 unsigned long nodesScanned;1828 unsigned long nodesScanned;
1819 1829
1820 showAllLocalVoxelsArgs(VoxelSystem* voxelSystem) :1830 showAllLocalVoxelsArgs(VoxelSystem* voxelSystem) :
1821 thisVoxelSystem(voxelSystem), 1831 thisVoxelSystem(voxelSystem),
1822 thisViewFrustum(*voxelSystem->getViewFrustum()),1832 thisViewFrustum(*voxelSystem->getViewFrustum()),
1823 nodesScanned(0)1833 nodesScanned(0)
1824 {1834 {
@@ -1880,8 +1890,9 @@ public: · 55 unmodified lines
1880 unsigned long nodesOutsideInside;1890 unsigned long nodesOutsideInside;
1881 unsigned long nodesInsideOutside;1891 unsigned long nodesInsideOutside;
1882 unsigned long nodesOutsideOutside;1892 unsigned long nodesOutsideOutside;
1883 1893 unsigned long nodesShown;
1884 hideOutOfViewArgs(VoxelSystem* voxelSystem, VoxelTree* tree, 1894
1895 hideOutOfViewArgs(VoxelSystem* voxelSystem, VoxelTree* tree,
1885 bool culledOnce, bool widenViewFrustum, bool wantDeltaFrustums) :1896 bool culledOnce, bool widenViewFrustum, bool wantDeltaFrustums) :
1886 thisVoxelSystem(voxelSystem),1897 thisVoxelSystem(voxelSystem),
1887 tree(tree),1898 tree(tree),
@@ -1898,7 +1909,8 @@ public: · 10 unmodified lines
1898 nodesIntersectInside(0),1909 nodesIntersectInside(0),
1899 nodesOutsideInside(0),1910 nodesOutsideInside(0),
1900 nodesInsideOutside(0),1911 nodesInsideOutside(0),
1901 nodesOutsideOutside(0)1912 nodesOutsideOutside(0),
1913 nodesShown(0)
1902 {1914 {
1903 // Widen the FOV for trimming1915 // Widen the FOV for trimming
1904 if (widenViewFrustum) {1916 if (widenViewFrustum) {
@@ -1916,13 +1928,14 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) { · 11 unmodified lines
1916 if (_inhideOutOfView) {1928 if (_inhideOutOfView) {
1917 return;1929 return;
1918 }1930 }
1919 1931
1920 _inhideOutOfView = true;1932 _inhideOutOfView = true;
1921 1933
1922 bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);1934 bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
1923 PerformanceWarning warn(showDebugDetails, "hideOutOfView()");1935 PerformanceWarning warn(showDebugDetails, "hideOutOfView()");
1924 bool widenFrustum = true;1936 bool widenFrustum = true;
1925 1937
1938
1926 // When using "delta" view frustums and only hide/show items that are in the difference1939 // When using "delta" view frustums and only hide/show items that are in the difference
1927 // between the two view frustums. There are some potential problems with this mode.1940 // between the two view frustums. There are some potential problems with this mode.
1928 //1941 //
@@ -1932,7 +1945,7 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) { · 3 unmodified lines
1932 //1945 //
1933 // 2) Also, voxels will arrive from the network that are OUTSIDE of the view1946 // 2) Also, voxels will arrive from the network that are OUTSIDE of the view
1934 // frustum... these won't get hidden... and so we can't assume they are correctly1947 // frustum... these won't get hidden... and so we can't assume they are correctly
1935 // hidden... 1948 // hidden...
1936 //1949 //
1937 // Both these problems are solved by intermittently calling this with forceFullFrustum set1950 // Both these problems are solved by intermittently calling this with forceFullFrustum set
1938 // to true. This will essentially clean up the improperly hidden or shown voxels.1951 // to true. This will essentially clean up the improperly hidden or shown voxels.
@@ -1947,13 +1960,13 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) { · 8 unmodified lines
1947 args.lastViewFrustum.printDebugDetails();1960 args.lastViewFrustum.printDebugDetails();
1948 }1961 }
1949 }1962 }
1950 1963
1951 if (!forceFullFrustum && _culledOnce && args.lastViewFrustum.isVerySimilar(args.thisViewFrustum)) {1964 if (!forceFullFrustum && _culledOnce && args.lastViewFrustum.isVerySimilar(args.thisViewFrustum)) {
1952 _inhideOutOfView = false;1965 _inhideOutOfView = false;
1953 return;1966 return;
1954 }1967 }
1955 1968
1956 lockTree(); 1969 lockTree();
1957 _tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);1970 _tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args);
1958 unlockTree();1971 unlockTree();
1959 _lastCulledViewFrustum = args.thisViewFrustum; // save last stable1972 _lastCulledViewFrustum = args.thisViewFrustum; // save last stable
@@ -1963,16 +1976,19 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) { · 3 unmodified lines
1963 _tree->setDirtyBit();1976 _tree->setDirtyBit();
1964 setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);1977 setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY);
1965 }1978 }
1966 1979
1967 bool extraDebugDetails = Application::getInstance()->getLogger()->extraDebugging();1980 bool extraDebugDetails = false; // Application::getInstance()->getLogger()->extraDebugging();
1968 if (extraDebugDetails) {1981 if (extraDebugDetails) {
1969 qDebug("hideOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld\n", 1982 qDebug("hideOutOfView() scanned=%ld removed=%ld show=%ld inside=%ld intersect=%ld outside=%ld\n",
1970 args.nodesScanned, args.nodesRemoved, args.nodesInside, 1983 args.nodesScanned, args.nodesRemoved, args.nodesShown, args.nodesInside,
1971 args.nodesIntersect, args.nodesOutside1984 args.nodesIntersect, args.nodesOutside
1972 );1985 );
1973 qDebug(" inside/inside=%ld intersect/inside=%ld outside/outside=%ld\n", 1986 qDebug(" inside/inside=%ld intersect/inside=%ld outside/outside=%ld\n",
1974 args.nodesInsideInside, args.nodesIntersectInside, args.nodesOutsideOutside1987 args.nodesInsideInside, args.nodesIntersectInside, args.nodesOutsideOutside
1975 );1988 );
1989
1990 qDebug() << "args.thisViewFrustum....\n";
1991 args.thisViewFrustum.printDebugDetails();
1976 }1992 }
1977 _inhideOutOfView = false;1993 _inhideOutOfView = false;
1978}1994}
@@ -1985,10 +2001,10 @@ bool VoxelSystem::hideAllSubTreeOperation(OctreeElement* element, void* extraDat · 6 unmodified lines
1985 // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not2001 // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not
1986 // consider that case.2002 // consider that case.
1987 ViewFrustum::location inLastCulledFrustum;2003 ViewFrustum::location inLastCulledFrustum;
1988 2004
1989 if (args->culledOnce && args->wantDeltaFrustums) {2005 if (args->culledOnce && args->wantDeltaFrustums) {
1990 inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum);2006 inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum);
1991 2007
1992 // if this node is fully OUTSIDE our last culled view frustum, then we don't need to recurse further2008 // if this node is fully OUTSIDE our last culled view frustum, then we don't need to recurse further
1993 if (inLastCulledFrustum == ViewFrustum::OUTSIDE) {2009 if (inLastCulledFrustum == ViewFrustum::OUTSIDE) {
1994 args->nodesOutsideOutside++;2010 args->nodesOutsideOutside++;
@@ -2009,7 +2025,7 @@ bool VoxelSystem::hideAllSubTreeOperation(OctreeElement* element, void* extraDat · 14 unmodified lines
2009 }2025 }
2010 2026
2011 }2027 }
2012 2028
2013 return true;2029 return true;
2014}2030}
2015 2031
@@ -2021,10 +2037,10 @@ bool VoxelSystem::showAllSubTreeOperation(OctreeElement* element, void* extraDat · 5 unmodified lines
2021 // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not2037 // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not
2022 // consider that case.2038 // consider that case.
2023 ViewFrustum::location inLastCulledFrustum;2039 ViewFrustum::location inLastCulledFrustum;
2024 2040
2025 if (args->culledOnce && args->wantDeltaFrustums) {2041 if (args->culledOnce && args->wantDeltaFrustums) {
2026 inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum);2042 inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum);
2027 2043
2028 // if this node is fully inside our last culled view frustum, then we don't need to recurse further2044 // if this node is fully inside our last culled view frustum, then we don't need to recurse further
2029 if (inLastCulledFrustum == ViewFrustum::INSIDE) {2045 if (inLastCulledFrustum == ViewFrustum::INSIDE) {
2030 args->nodesInsideInside++;2046 args->nodesInsideInside++;
@@ -2047,35 +2063,36 @@ bool VoxelSystem::showAllSubTreeOperation(OctreeElement* element, void* extraDat · 16 unmodified lines
2047 // These are both needed to force redraw...2063 // These are both needed to force redraw...
2048 voxel->setDirtyBit();2064 voxel->setDirtyBit();
2049 voxel->markWithChangedTime();2065 voxel->markWithChangedTime();
2066 args->nodesShown++;
2050 }2067 }
2051 2068
2052 return true; // keep recursing!2069 return true; // keep recursing!
2053}2070}
2054 2071
2055// "hide" voxels in the VBOs that are still in the tree that but not in view. 2072// "hide" voxels in the VBOs that are still in the tree that but not in view.
2056// We don't remove them from the tree, we don't delete them, we do remove them2073// We don't remove them from the tree, we don't delete them, we do remove them
2057// from the VBOs and mark them as such in the tree.2074// from the VBOs and mark them as such in the tree.
2058bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData) {2075bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData) {
2059 VoxelTreeElement* voxel = (VoxelTreeElement*)element;2076 VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2060 hideOutOfViewArgs* args = (hideOutOfViewArgs*)extraData;2077 hideOutOfViewArgs* args = (hideOutOfViewArgs*)extraData;
2061 2078
2062 // If we're still recursing the tree using this operator, then we don't know if we're inside or outside... 2079 // If we're still recursing the tree using this operator, then we don't know if we're inside or outside...
2063 // so before we move forward we need to determine our frustum location2080 // so before we move forward we need to determine our frustum location
2064 ViewFrustum::location inFrustum = voxel->inFrustum(args->thisViewFrustum);2081 ViewFrustum::location inFrustum = voxel->inFrustum(args->thisViewFrustum);
2065 2082
2066 // If we've culled at least once, then we will use the status of this voxel in the last culled frustum to determine2083 // If we've culled at least once, then we will use the status of this voxel in the last culled frustum to determine
2067 // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not2084 // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not
2068 // consider that case.2085 // consider that case.
2069 ViewFrustum::location inLastCulledFrustum;2086 ViewFrustum::location inLastCulledFrustum;
2070 2087
2071 if (args->culledOnce && args->wantDeltaFrustums) {2088 if (args->culledOnce && args->wantDeltaFrustums) {
2072 inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum);2089 inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum);
2073 }2090 }
2074 2091
2075 // ok, now do some processing for this node...2092 // ok, now do some processing for this node...
2076 switch (inFrustum) {2093 switch (inFrustum) {
2077 case ViewFrustum::OUTSIDE: {2094 case ViewFrustum::OUTSIDE: {
2078 2095
2079 // If this node is outside the current view, then we might want to hide it... unless it was previously OUTSIDE,2096 // If this node is outside the current view, then we might want to hide it... unless it was previously OUTSIDE,
2080 // if it was previously outside, then we can safely assume it's already hidden, and we can also safely assume2097 // if it was previously outside, then we can safely assume it's already hidden, and we can also safely assume
2081 // that all of it's children are outside both of our views, in which case we can just stop recursing...2098 // that all of it's children are outside both of our views, in which case we can just stop recursing...
@@ -2084,17 +2101,17 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData · 2 unmodified lines
2084 args->nodesOutsideOutside++;2101 args->nodesOutsideOutside++;
2085 return false; // stop recursing this branch!2102 return false; // stop recursing this branch!
2086 }2103 }
2087 2104
2088 // if this node is fully OUTSIDE the view, but previously intersected and/or was inside the last view, then2105 // if this node is fully OUTSIDE the view, but previously intersected and/or was inside the last view, then
2089 // we need to hide it. Additionally we know that ALL of it's children are also fully OUTSIDE so we can recurse 2106 // we need to hide it. Additionally we know that ALL of it's children are also fully OUTSIDE so we can recurse
2090 // the children and simply mark them as hidden2107 // the children and simply mark them as hidden
2091 args->tree->recurseNodeWithOperation(voxel, hideAllSubTreeOperation, args );2108 args->tree->recurseNodeWithOperation(voxel, hideAllSubTreeOperation, args );
2092 2109
2093 return false;2110 return false;
2094 2111
2095 } break;2112 } break;
2096 case ViewFrustum::INSIDE: {2113 case ViewFrustum::INSIDE: {
2097 2114
2098 // If this node is INSIDE the current view, then we might want to show it... unless it was previously INSIDE,2115 // If this node is INSIDE the current view, then we might want to show it... unless it was previously INSIDE,
2099 // if it was previously INSIDE, then we can safely assume it's already shown, and we can also safely assume2116 // if it was previously INSIDE, then we can safely assume it's already shown, and we can also safely assume
2100 // that all of it's children are INSIDE both of our views, in which case we can just stop recursing...2117 // that all of it's children are INSIDE both of our views, in which case we can just stop recursing...
@@ -2103,18 +2120,18 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData · 2 unmodified lines
2103 args->nodesInsideInside++;2120 args->nodesInsideInside++;
2104 return false; // stop recursing this branch!2121 return false; // stop recursing this branch!
2105 }2122 }
2106 2123
2107 // if this node is fully INSIDE the view, but previously INTERSECTED and/or was OUTSIDE the last view, then2124 // if this node is fully INSIDE the view, but previously INTERSECTED and/or was OUTSIDE the last view, then
2108 // we need to show it. Additionally we know that ALL of it's children are also fully INSIDE so we can recurse 2125 // we need to show it. Additionally we know that ALL of it's children are also fully INSIDE so we can recurse
2109 // the children and simply mark them as visible (as appropriate based on LOD)2126 // the children and simply mark them as visible (as appropriate based on LOD)
2110 args->tree->recurseNodeWithOperation(voxel, showAllSubTreeOperation, args);2127 args->tree->recurseNodeWithOperation(voxel, showAllSubTreeOperation, args);
2111 2128
2112 return false; 2129 return false;
2113 } break;2130 } break;
2114 case ViewFrustum::INTERSECT: {2131 case ViewFrustum::INTERSECT: {
2115 args->nodesScanned++;2132 args->nodesScanned++;
2116 2133
2117 // If this node INTERSECTS the current view, then we might want to show it... unless it was previously INSIDE 2134 // If this node INTERSECTS the current view, then we might want to show it... unless it was previously INSIDE
2118 // the last known view, in which case it will already be visible, and we know that all it's children are also2135 // the last known view, in which case it will already be visible, and we know that all it's children are also
2119 // previously INSIDE and visible. So in this case stop recursing2136 // previously INSIDE and visible. So in this case stop recursing
2120 if (args->culledOnce && args->wantDeltaFrustums && inLastCulledFrustum == ViewFrustum::INSIDE) {2137 if (args->culledOnce && args->wantDeltaFrustums && inLastCulledFrustum == ViewFrustum::INSIDE) {
@@ -2125,21 +2142,22 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData · 4 unmodified lines
2125 args->nodesIntersect++;2142 args->nodesIntersect++;
2126 2143
2127 // if the child node INTERSECTs the view, then we want to check to see if it thinks it should render2144 // if the child node INTERSECTs the view, then we want to check to see if it thinks it should render
2128 // if it should render but is missing it's VBO index, then we want to flip it on, and we can stop recursing from 2145 // if it should render but is missing it's VBO index, then we want to flip it on, and we can stop recursing from
2129 // here because we know will block any children anyway2146 // here because we know will block any children anyway
2130 if (voxel->getShouldRender() && !voxel->isKnownBufferIndex()) {2147 if (voxel->getShouldRender() && !voxel->isKnownBufferIndex()) {
2131 voxel->setDirtyBit(); // will this make it draw?2148 voxel->setDirtyBit(); // will this make it draw?
2149 args->nodesShown++;
2132 return false;2150 return false;
2133 }2151 }
2134 2152
2135 // If it INTERSECTS but shouldn't be displayed, then it's probably a parent and it is at least partially in view.2153 // If it INTERSECTS but shouldn't be displayed, then it's probably a parent and it is at least partially in view.
2136 // So we DO want to recurse the children because some of them may not be in view... nothing specifically to do, 2154 // So we DO want to recurse the children because some of them may not be in view... nothing specifically to do,
2137 // just keep iterating the children2155 // just keep iterating the children
2138 return true; 2156 return true;
2139 2157
2140 } break;2158 } break;
2141 } // switch2159 } // switch
2142 2160
2143 2161
2144 return true; // keep going!2162 return true; // keep going!
2145}2163}
@@ -2147,7 +2165,7 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData · 1 unmodified line
2147 2165
2148bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,2166bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
2149 VoxelDetail& detail, float& distance, BoxFace& face) {2167 VoxelDetail& detail, float& distance, BoxFace& face) {
2150 lockTree(); 2168 lockTree();
2151 OctreeElement* element;2169 OctreeElement* element;
2152 if (!_tree->findRayIntersection(origin, direction, element, distance, face)) {2170 if (!_tree->findRayIntersection(origin, direction, element, distance, face)) {
2153 unlockTree();2171 unlockTree();
@@ -2206,7 +2224,7 @@ bool VoxelSystem::falseColorizeRandomEveryOtherOperation(OctreeElement* element, · 52 unmodified lines
2206void VoxelSystem::falseColorizeRandomEveryOther() {2224void VoxelSystem::falseColorizeRandomEveryOther() {
2207 falseColorizeRandomEveryOtherArgs args;2225 falseColorizeRandomEveryOtherArgs args;
2208 _tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);2226 _tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);
2209 qDebug("randomized false color for every other node: total %ld, colorable %ld, colored %ld\n", 2227 qDebug("randomized false color for every other node: total %ld, colorable %ld, colored %ld\n",
2210 args.totalNodes, args.colorableNodes, args.coloredNodes);2228 args.totalNodes, args.colorableNodes, args.coloredNodes);
2211 _tree->setDirtyBit();2229 _tree->setDirtyBit();
2212 setupNewVoxelsForDrawing();2230 setupNewVoxelsForDrawing();
@@ -2214,9 +2232,9 @@ void VoxelSystem::falseColorizeRandomEveryOther() { · 1 unmodified line
2214 2232
2215class collectStatsForTreesAndVBOsArgs {2233class collectStatsForTreesAndVBOsArgs {
2216public:2234public:
2217 collectStatsForTreesAndVBOsArgs(int maxVoxels) : 2235 collectStatsForTreesAndVBOsArgs(int maxVoxels) :
2218 totalNodes(0), 2236 totalNodes(0),
2219 dirtyNodes(0), 2237 dirtyNodes(0),
2220 shouldRenderNodes(0),2238 shouldRenderNodes(0),
2221 coloredNodes(0),2239 coloredNodes(0),
2222 nodesInVBO(0),2240 nodesInVBO(0),
@@ -2228,7 +2246,7 @@ public: · 5 unmodified lines
2228 hasIndexFound = new bool[maxVoxels];2246 hasIndexFound = new bool[maxVoxels];
2229 memset(hasIndexFound, false, maxVoxels * sizeof(bool));2247 memset(hasIndexFound, false, maxVoxels * sizeof(bool));
2230 };2248 };
2231 2249
2232 ~collectStatsForTreesAndVBOsArgs() {2250 ~collectStatsForTreesAndVBOsArgs() {
2233 delete[] hasIndexFound;2251 delete[] hasIndexFound;
2234 }2252 }
@@ -2244,13 +2262,13 @@ public: · 9 unmodified lines
2244 unsigned long leafNodes;2262 unsigned long leafNodes;
2245 2263
2246 unsigned long expectedMax;2264 unsigned long expectedMax;
2247 2265
2248 bool* hasIndexFound;2266 bool* hasIndexFound;
2249};2267};
2250 2268
2251bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, void* extraData) {2269bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, void* extraData) {
2252 VoxelTreeElement* voxel = (VoxelTreeElement*)element;2270 VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2253 2271
2254 collectStatsForTreesAndVBOsArgs* args = (collectStatsForTreesAndVBOsArgs*)extraData;2272 collectStatsForTreesAndVBOsArgs* args = (collectStatsForTreesAndVBOsArgs*)extraData;
2255 args->totalNodes++;2273 args->totalNodes++;
2256 2274
@@ -2273,17 +2291,17 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, v · 16 unmodified lines
2273 if (voxel->isKnownBufferIndex()) {2291 if (voxel->isKnownBufferIndex()) {
2274 args->nodesInVBO++;2292 args->nodesInVBO++;
2275 unsigned long nodeIndex = voxel->getBufferIndex();2293 unsigned long nodeIndex = voxel->getBufferIndex();
2276 2294
2277 const bool extraDebugging = false; // enable for extra debugging2295 const bool extraDebugging = false; // enable for extra debugging
2278 if (extraDebugging) {2296 if (extraDebugging) {
2279 qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s \n", 2297 qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s \n",
2280 voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(), 2298 voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(),
2281 nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));2299 nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
2282 }2300 }
2283 2301
2284 if (args->hasIndexFound[nodeIndex]) {2302 if (args->hasIndexFound[nodeIndex]) {
2285 args->duplicateVBOIndex++;2303 args->duplicateVBOIndex++;
2286 qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex, 2304 qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex,
2287 debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));2305 debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
2288 } else {2306 } else {
2289 args->hasIndexFound[nodeIndex] = true;2307 args->hasIndexFound[nodeIndex] = true;
@@ -2291,7 +2309,7 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, v · 1 unmodified line
2291 if (nodeIndex > args->expectedMax) {2309 if (nodeIndex > args->expectedMax) {
2292 args->nodesInVBOOverExpectedMax++;2310 args->nodesInVBOOverExpectedMax++;
2293 }2311 }
2294 2312
2295 // if it's in VBO but not-shouldRender, track that also...2313 // if it's in VBO but not-shouldRender, track that also...
2296 if (!voxel->getShouldRender()) {2314 if (!voxel->getShouldRender()) {
2297 args->nodesInVBONotShouldRender++;2315 args->nodesInVBONotShouldRender++;
@@ -2316,9 +2334,9 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 18 unmodified lines
2316 2334
2317 collectStatsForTreesAndVBOsArgs args(_maxVoxels);2335 collectStatsForTreesAndVBOsArgs args(_maxVoxels);
2318 args.expectedMax = _voxelsInWriteArrays;2336 args.expectedMax = _voxelsInWriteArrays;
2319 2337
2320 qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>\n");2338 qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>\n");
2321 2339
2322 _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);2340 _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);
2323 2341
2324 qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n",2342 qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n",
@@ -2327,7 +2345,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 2 unmodified lines
2327 qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld \n", debug::valueOf(_voxelsDirty),2345 qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld \n", debug::valueOf(_voxelsDirty),
2328 _voxelsInWriteArrays, minDirty, maxDirty);2346 _voxelsInWriteArrays, minDirty, maxDirty);
2329 2347
2330 qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld \n", 2348 qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld \n",
2331 args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender);2349 args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender);
2332 2350
2333 glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;2351 glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
@@ -2340,10 +2358,10 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 6 unmodified lines
2340 }2358 }
2341 }2359 }
2342 2360
2343 qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld \n", 2361 qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld \n",
2344 minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays);2362 minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays);
2345 2363
2346 qDebug(" _freeIndexes.size()=%ld \n", 2364 qDebug(" _freeIndexes.size()=%ld \n",
2347 _freeIndexes.size());2365 _freeIndexes.size());
2348 2366
2349 qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>\n");2367 qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>\n");
@@ -2354,36 +2372,36 @@ void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) { · 4 unmodified lines
2354 lockTree();2372 lockTree();
2355 _tree->deleteVoxelAt(x, y, z, s);2373 _tree->deleteVoxelAt(x, y, z, s);
2356 unlockTree();2374 unlockTree();
2357 2375
2358 // redraw!2376 // redraw!
2359 setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in?2377 setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in?
2360 2378
2361};2379};
2362 2380
2363VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const { 2381VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const {
2364 return _tree->getVoxelAt(x, y, z, s); 2382 return _tree->getVoxelAt(x, y, z, s);
2365};2383};
2366 2384
2367void VoxelSystem::createVoxel(float x, float y, float z, float s, 2385void VoxelSystem::createVoxel(float x, float y, float z, float s,
2368 unsigned char red, unsigned char green, unsigned char blue, bool destructive) {2386 unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
2369 2387
2370 //qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);2388 //qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s);
2371 lockTree();2389 lockTree();
2372 _tree->createVoxel(x, y, z, s, red, green, blue, destructive); 2390 _tree->createVoxel(x, y, z, s, red, green, blue, destructive);
2373 unlockTree();2391 unlockTree();
2374 2392
2375 setupNewVoxelsForDrawing(); 2393 setupNewVoxelsForDrawing();
2376};2394};
2377 2395
2378void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) { 2396void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
2379 _tree->createLine(point1, point2, unitSize, color, destructive); 2397 _tree->createLine(point1, point2, unitSize, color, destructive);
2380 setupNewVoxelsForDrawing(); 2398 setupNewVoxelsForDrawing();
2381};2399};
2382 2400
2383void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, 2401void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid,
2384 creationMode mode, bool destructive, bool debug) { 2402 creationMode mode, bool destructive, bool debug) {
2385 _tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug); 2403 _tree->createSphere(r, xc, yc, zc, s, solid, mode, destructive, debug);
2386 setupNewVoxelsForDrawing(); 2404 setupNewVoxelsForDrawing();
2387};2405};
2388 2406
2389void VoxelSystem::copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destination, bool rebaseToRoot) {2407void VoxelSystem::copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destination, bool rebaseToRoot) {
@@ -2431,7 +2449,7 @@ bool VoxelSystem::falseColorizeSubTreeOperation(OctreeElement* element, void* ex · 41 unmodified lines
2431 voxel->setFalseColor(args->color[0], args->color[1], args->color[2]);2449 voxel->setFalseColor(args->color[0], args->color[1], args->color[2]);
2432 args->voxelsTouched++;2450 args->voxelsTouched++;
2433 }2451 }
2434 return true; 2452 return true;
2435}2453}
2436 2454
2437bool VoxelSystem::falseColorizeOccludedOperation(OctreeElement* element, void* extraData) {2455bool VoxelSystem::falseColorizeOccludedOperation(OctreeElement* element, void* extraData) {
@@ -2459,18 +2477,18 @@ bool VoxelSystem::falseColorizeOccludedOperation(OctreeElement* element, void* e · 21 unmodified lines
2459 if (result == OCCLUDED) {2477 if (result == OCCLUDED) {
2460 args->nonLeavesOccluded++;2478 args->nonLeavesOccluded++;
2461 delete voxelPolygon;2479 delete voxelPolygon;
2462 2480
2463 FalseColorizeSubTreeOperationArgs subArgs;2481 FalseColorizeSubTreeOperationArgs subArgs;
2464 subArgs.color[0] = 0;2482 subArgs.color[0] = 0;
2465 subArgs.color[1] = 255;2483 subArgs.color[1] = 255;
2466 subArgs.color[2] = 0;2484 subArgs.color[2] = 0;
2467 subArgs.voxelsTouched = 0;2485 subArgs.voxelsTouched = 0;
2468 2486
2469 args->tree->recurseNodeWithOperation(voxel, falseColorizeSubTreeOperation, &subArgs );2487 args->tree->recurseNodeWithOperation(voxel, falseColorizeSubTreeOperation, &subArgs );
2470 2488
2471 args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);2489 args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);
2472 args->totalVoxels += (subArgs.voxelsTouched - 1);2490 args->totalVoxels += (subArgs.voxelsTouched - 1);
2473 2491
2474 return false;2492 return false;
2475 }2493 }
2476 2494
@@ -2509,10 +2527,10 @@ bool VoxelSystem::falseColorizeOccludedOperation(OctreeElement* element, void* e · 32 unmodified lines
2509void VoxelSystem::falseColorizeOccluded() {2527void VoxelSystem::falseColorizeOccluded() {
2510 PerformanceWarning warn(true, "falseColorizeOccluded()",true);2528 PerformanceWarning warn(true, "falseColorizeOccluded()",true);
2511 myCoverageMap.erase();2529 myCoverageMap.erase();
2512 2530
2513 FalseColorizeOccludedArgs args;2531 FalseColorizeOccludedArgs args;
2514 args.viewFrustum = _viewFrustum;2532 args.viewFrustum = _viewFrustum;
2515 args.map = &myCoverageMap; 2533 args.map = &myCoverageMap;
2516 args.totalVoxels = 0;2534 args.totalVoxels = 0;
2517 args.coloredVoxels = 0;2535 args.coloredVoxels = 0;
2518 args.occludedVoxels = 0;2536 args.occludedVoxels = 0;
@@ -2527,15 +2545,15 @@ void VoxelSystem::falseColorizeOccluded() { · 8 unmodified lines
2527 OctreeProjectedPolygon::pointInside_calls = 0;2545 OctreeProjectedPolygon::pointInside_calls = 0;
2528 OctreeProjectedPolygon::occludes_calls = 0;2546 OctreeProjectedPolygon::occludes_calls = 0;
2529 OctreeProjectedPolygon::intersects_calls = 0;2547 OctreeProjectedPolygon::intersects_calls = 0;
2530 2548
2531 glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);2549 glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);
2532 2550
2533 _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args);2551 _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args);
2534 2552
2535 qDebug("falseColorizeOccluded()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n", 2553 qDebug("falseColorizeOccluded()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n",
2536 position.x, position.y,2554 position.x, position.y,
2537 args.totalVoxels, args.coloredVoxels, args.occludedVoxels, 2555 args.totalVoxels, args.coloredVoxels, args.occludedVoxels,
2538 args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped, 2556 args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,
2539 args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,2557 args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,
2540 OctreeProjectedPolygon::pointInside_calls,2558 OctreeProjectedPolygon::pointInside_calls,
2541 OctreeProjectedPolygon::occludes_calls,2559 OctreeProjectedPolygon::occludes_calls,
@@ -2574,18 +2592,18 @@ bool VoxelSystem::falseColorizeOccludedV2Operation(OctreeElement* element, void* · 32 unmodified lines
2574 if (result == V2_OCCLUDED) {2592 if (result == V2_OCCLUDED) {
2575 args->nonLeavesOccluded++;2593 args->nonLeavesOccluded++;
2576 delete voxelPolygon;2594 delete voxelPolygon;
2577 2595
2578 FalseColorizeSubTreeOperationArgs subArgs;2596 FalseColorizeSubTreeOperationArgs subArgs;
2579 subArgs.color[0] = 0;2597 subArgs.color[0] = 0;
2580 subArgs.color[1] = 255;2598 subArgs.color[1] = 255;
2581 subArgs.color[2] = 0;2599 subArgs.color[2] = 0;
2582 subArgs.voxelsTouched = 0;2600 subArgs.voxelsTouched = 0;
2583 2601
2584 args->tree->recurseNodeWithOperation(voxel, falseColorizeSubTreeOperation, &subArgs );2602 args->tree->recurseNodeWithOperation(voxel, falseColorizeSubTreeOperation, &subArgs );
2585 2603
2586 args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);2604 args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);
2587 args->totalVoxels += (subArgs.voxelsTouched - 1);2605 args->totalVoxels += (subArgs.voxelsTouched - 1);
2588 2606
2589 return false;2607 return false;
2590 }2608 }
2591 2609
@@ -2632,10 +2650,10 @@ void VoxelSystem::falseColorizeOccludedV2() { · 40 unmodified lines
2632 OctreeProjectedPolygon::pointInside_calls = 0;2650 OctreeProjectedPolygon::pointInside_calls = 0;
2633 OctreeProjectedPolygon::occludes_calls = 0;2651 OctreeProjectedPolygon::occludes_calls = 0;
2634 OctreeProjectedPolygon::intersects_calls = 0;2652 OctreeProjectedPolygon::intersects_calls = 0;
2635 2653
2636 FalseColorizeOccludedArgs args;2654 FalseColorizeOccludedArgs args;
2637 args.viewFrustum = _viewFrustum;2655 args.viewFrustum = _viewFrustum;
2638 args.mapV2 = &myCoverageMapV2; 2656 args.mapV2 = &myCoverageMapV2;
2639 args.totalVoxels = 0;2657 args.totalVoxels = 0;
2640 args.coloredVoxels = 0;2658 args.coloredVoxels = 0;
2641 args.occludedVoxels = 0;2659 args.occludedVoxels = 0;
@@ -2646,15 +2664,15 @@ void VoxelSystem::falseColorizeOccludedV2() { · 4 unmodified lines
2646 args.nonLeavesOutOfView = 0;2664 args.nonLeavesOutOfView = 0;
2647 args.nonLeavesOccluded = 0;2665 args.nonLeavesOccluded = 0;
2648 args.tree = _tree;2666 args.tree = _tree;
2649 2667
2650 glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);2668 glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);
2651 2669
2652 _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedV2Operation, position, (void*)&args);2670 _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedV2Operation, position, (void*)&args);
2653 2671
2654 qDebug("falseColorizeOccludedV2()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n", 2672 qDebug("falseColorizeOccludedV2()\n position=(%f,%f)\n total=%ld\n colored=%ld\n occluded=%ld\n notOccluded=%ld\n outOfView=%ld\n subtreeVoxelsSkipped=%ld\n nonLeaves=%ld\n nonLeavesOutOfView=%ld\n nonLeavesOccluded=%ld\n pointInside_calls=%ld\n occludes_calls=%ld\n intersects_calls=%ld\n",
2655 position.x, position.y,2673 position.x, position.y,
2656 args.totalVoxels, args.coloredVoxels, args.occludedVoxels, 2674 args.totalVoxels, args.coloredVoxels, args.occludedVoxels,
2657 args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped, 2675 args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,
2658 args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,2676 args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,
2659 OctreeProjectedPolygon::pointInside_calls,2677 OctreeProjectedPolygon::pointInside_calls,
2660 OctreeProjectedPolygon::occludes_calls,2678 OctreeProjectedPolygon::occludes_calls,
@@ -2717,7 +2735,7 @@ unsigned long VoxelSystem::getFreeMemoryGPU() { · 56 unmodified lines
2717 const GLenum VBO_FREE_MEMORY_ATI = 0x87FB;2735 const GLenum VBO_FREE_MEMORY_ATI = 0x87FB;
2718 glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]);2736 glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]);
2719 GLenum errorATI = glGetError();2737 GLenum errorATI = glGetError();
2720 2738
2721 if (errorATI == GL_NO_ERROR) {2739 if (errorATI == GL_NO_ERROR) {
2722 _hasMemoryUsageGPU = true;2740 _hasMemoryUsageGPU = true;
2723 freeMemory = results[0];2741 freeMemory = results[0];
@@ -2730,19 +2748,19 @@ unsigned long VoxelSystem::getFreeMemoryGPU() { · 6 unmodified lines
2730 //const GLenum GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A;2748 //const GLenum GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A;
2731 //const GLenum GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B;2749 //const GLenum GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B;
2732 //const GLenum GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048;2750 //const GLenum GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048;
2733 2751
2734 const GLenum GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049;2752 const GLenum GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049;
2735 results[0] = 0;2753 results[0] = 0;
2736 glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &results[0]);2754 glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &results[0]);
2737 freeMemory += results[0]; 2755 freeMemory += results[0];
2738 GLenum errorNVIDIA = glGetError();2756 GLenum errorNVIDIA = glGetError();
2739 2757
2740 if (errorNVIDIA == GL_NO_ERROR) {2758 if (errorNVIDIA == GL_NO_ERROR) {
2741 _hasMemoryUsageGPU = true;2759 _hasMemoryUsageGPU = true;
2742 freeMemory = results[0];2760 freeMemory = results[0];
2743 }2761 }
2744 }2762 }
2745 2763
2746 const unsigned long BYTES_PER_KBYTE = 1024;2764 const unsigned long BYTES_PER_KBYTE = 1024;
2747 return freeMemory * BYTES_PER_KBYTE; // API results in KB, we want it in bytes2765 return freeMemory * BYTES_PER_KBYTE; // API results in KB, we want it in bytes
2748}2766}
@@ -2763,4 +2781,22 @@ void VoxelSystem::unlockTree() { · 14 unmodified lines
2763}2781}
2764 2782
2765 2783
2784void VoxelSystem::localVoxelCacheLoaded() {
2785 qDebug() << "localVoxelCacheLoaded()\n";
2786
2787 // Make sure that the application has properly set up the view frustum for our loaded state
2788 Application::getInstance()->initAvatarAndViewFrustum();
2789
2790 _tree->setDirtyBit();
2791 setupNewVoxelsForDrawing();
2792 _inhideOutOfView = false; // reenable hideOutOfView behavior
2793}
2794
2795void VoxelSystem::beginLoadingLocalVoxelCache() {
2796 qDebug() << "beginLoadingLocalVoxelCache()\n";
2797 _writeRenderFullVBO = true; // this will disable individual node updates
2798 _inhideOutOfView = true; // this will disable hidOutOfView which we want to do until local cache is loaded
2799}
2800
2801
2766 2802