Showing the changes to interface/src/VoxelSystem.cpp (1 of 202 files). Show all
Unified · Split
| @@ -103,9 +103,6 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 102 unmodified lines | ||
| 103 | 103 | |
| 104 | 104 | _culledOnce = false; |
| 105 | 105 | _inhideOutOfView = false; |
| 106 | − _treeIsBusy = false; | |
| 107 | − | |
| 108 | − | |
| 109 | 106 | } |
| 110 | 107 | |
| 111 | 108 | void VoxelSystem::elementDeleted(OctreeElement* element) { |
| @@ -570,30 +567,30 @@ int VoxelSystem::parseData(const QByteArray& packet) { · 458 unmodified lines | ||
| 570 | 567 | |
| 571 | 568 | const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader; |
| 572 | 569 | |
| 573 | − VOXEL_PACKET_FLAGS flags = (*(VOXEL_PACKET_FLAGS*)(dataAt)); | |
| 574 | − dataAt += sizeof(VOXEL_PACKET_FLAGS); | |
| 575 | − VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt); | |
| 576 | − dataAt += sizeof(VOXEL_PACKET_SEQUENCE); | |
| 570 | + OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt)); | |
| 571 | + dataAt += sizeof(OCTREE_PACKET_FLAGS); | |
| 572 | + OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt); | |
| 573 | + dataAt += sizeof(OCTREE_PACKET_SEQUENCE); | |
| 577 | 574 | |
| 578 | − VOXEL_PACKET_SENT_TIME sentAt = (*(VOXEL_PACKET_SENT_TIME*)dataAt); | |
| 579 | − dataAt += sizeof(VOXEL_PACKET_SENT_TIME); | |
| 575 | + OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); | |
| 576 | + dataAt += sizeof(OCTREE_PACKET_SENT_TIME); | |
| 580 | 577 | |
| 581 | 578 | bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); |
| 582 | 579 | bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); |
| 583 | 580 | |
| 584 | − VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); | |
| 581 | + OCTREE_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); | |
| 585 | 582 | int flightTime = arrivedAt - sentAt; |
| 586 | 583 | |
| 587 | − VOXEL_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; | |
| 588 | − int dataBytes = packet.size() - VOXEL_PACKET_HEADER_SIZE; | |
| 584 | + OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; | |
| 585 | + int dataBytes = packet.size() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); | |
| 589 | 586 | |
| 590 | 587 | int subsection = 1; |
| 591 | 588 | while (dataBytes > 0) { |
| 592 | 589 | if (packetIsCompressed) { |
| 593 | − if (dataBytes > sizeof(VOXEL_PACKET_INTERNAL_SECTION_SIZE)) { | |
| 594 | − sectionLength = (*(VOXEL_PACKET_INTERNAL_SECTION_SIZE*)dataAt); | |
| 595 | − dataAt += sizeof(VOXEL_PACKET_INTERNAL_SECTION_SIZE); | |
| 596 | − dataBytes -= sizeof(VOXEL_PACKET_INTERNAL_SECTION_SIZE); | |
| 590 | + if (dataBytes > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { | |
| 591 | + sectionLength = (*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)dataAt); | |
| 592 | + dataAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); | |
| 593 | + dataBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); | |
| 597 | 594 | } else { |
| 598 | 595 | sectionLength = 0; |
| 599 | 596 | dataBytes = 0; // stop looping something is wrong |
| @@ -603,9 +600,10 @@ int VoxelSystem::parseData(const QByteArray& packet) { · 3 unmodified lines | ||
| 603 | 600 | } |
| 604 | 601 | |
| 605 | 602 | if (sectionLength) { |
| 603 | + PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData() section"); | |
| 606 | 604 | // ask the VoxelTree to read the bitstream into the tree |
| 607 | 605 | ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID()); |
| 608 | − lockTree(); | |
| 606 | + _tree->lockForWrite(); | |
| 609 | 607 | VoxelPacketData packetData(packetIsCompressed); |
| 610 | 608 | packetData.loadFinalizedContent(dataAt, sectionLength); |
| 611 | 609 | if (Application::getInstance()->getLogger()->extraDebugging()) { |
| @@ -617,7 +615,7 @@ int VoxelSystem::parseData(const QByteArray& packet) { · 5 unmodified lines | ||
| 617 | 615 | packetData.getUncompressedSize()); |
| 618 | 616 | } |
| 619 | 617 | _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); |
| 620 | − unlockTree(); | |
| 618 | + _tree->unlock(); | |
| 621 | 619 | |
| 622 | 620 | dataBytes -= sectionLength; |
| 623 | 621 | dataAt += sectionLength; |
| @@ -1467,9 +1465,11 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { · 843 unmodified lines | ||
| 1467 | 1465 | int VoxelSystem::_nodeCount = 0; |
| 1468 | 1466 | |
| 1469 | 1467 | void VoxelSystem::killLocalVoxels() { |
| 1470 | − lockTree(); | |
| 1468 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 1469 | + "VoxelSystem::killLocalVoxels()"); | |
| 1470 | + _tree->lockForWrite(); | |
| 1471 | 1471 | _tree->eraseAllOctreeElements(); |
| 1472 | − unlockTree(); | |
| 1472 | + _tree->unlock(); | |
| 1473 | 1473 | clearFreeBufferIndexes(); |
| 1474 | 1474 | _renderer->release(); |
| 1475 | 1475 | _voxelsInReadArrays = 0; // do we need to do this? |
| @@ -1490,10 +1490,12 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void · 14 unmodified lines | ||
| 1490 | 1490 | } |
| 1491 | 1491 | |
| 1492 | 1492 | void VoxelSystem::clearAllNodesBufferIndex() { |
| 1493 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 1494 | + "VoxelSystem::clearAllNodesBufferIndex()"); | |
| 1493 | 1495 | _nodeCount = 0; |
| 1494 | − lockTree(); | |
| 1496 | + _tree->lockForRead(); // we won't change the tree so it's ok to treat this as a read | |
| 1495 | 1497 | _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); |
| 1496 | − unlockTree(); | |
| 1498 | + _tree->unlock(); | |
| 1497 | 1499 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { |
| 1498 | 1500 | qDebug("clearing buffer index of %d nodes", _nodeCount); |
| 1499 | 1501 | } |
| @@ -1681,9 +1683,9 @@ void VoxelSystem::cullSharedFaces() { · 181 unmodified lines | ||
| 1681 | 1683 | _usePrimitiveRenderer = false; |
| 1682 | 1684 | _renderer->release(); |
| 1683 | 1685 | clearAllNodesBufferIndex(); |
| 1684 | − lockTree(); | |
| 1686 | + _tree->lockForRead(); | |
| 1685 | 1687 | _tree->recurseTreeWithOperation(clearOcclusionsOperation); |
| 1686 | − unlockTree(); | |
| 1688 | + _tree->unlock(); | |
| 1687 | 1689 | |
| 1688 | 1690 | |
| 1689 | 1691 | qDebug("unculling shared faces in %d nodes", _nodeCount); |
| @@ -1720,10 +1722,10 @@ void VoxelSystem::inspectForOcclusions() { · 30 unmodified lines | ||
| 1720 | 1722 | bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| 1721 | 1723 | PerformanceWarning warn(showDebugDetails, "inspectForOcclusions()"); |
| 1722 | 1724 | |
| 1723 | − lockTree(); | |
| 1725 | + _tree->lockForRead(); | |
| 1724 | 1726 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); |
| 1725 | 1727 | _tree->recurseTreeWithOperation(inspectForInteriorOcclusionsOperation); |
| 1726 | − unlockTree(); | |
| 1728 | + _tree->unlock(); | |
| 1727 | 1729 | |
| 1728 | 1730 | _inInspectForOcclusions = false; |
| 1729 | 1731 | } |
| @@ -1784,7 +1786,8 @@ bool VoxelSystem::trueColorizeOperation(OctreeElement* element, void* extraData) · 54 unmodified lines | ||
| 1784 | 1786 | } |
| 1785 | 1787 | |
| 1786 | 1788 | void VoxelSystem::trueColorize() { |
| 1787 | − PerformanceWarning warn(true, "trueColorize()",true); | |
| 1789 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 1790 | + "trueColorize()",true); | |
| 1788 | 1791 | _nodeCount = 0; |
| 1789 | 1792 | _tree->recurseTreeWithOperation(trueColorizeOperation); |
| 1790 | 1793 | qDebug("setting true color for %d nodes", _nodeCount); |
| @@ -2254,9 +2257,13 @@ void VoxelSystem::hideOutOfView(bool forceFullFrustum) { · 463 unmodified lines | ||
| 2254 | 2257 | return; |
| 2255 | 2258 | } |
| 2256 | 2259 | |
| 2257 | − lockTree(); | |
| 2258 | − _tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args); | |
| 2259 | − unlockTree(); | |
| 2260 | + { | |
| 2261 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 2262 | + "VoxelSystem::... recurseTreeWithOperation(hideOutOfViewOperation)"); | |
| 2263 | + _tree->lockForRead(); | |
| 2264 | + _tree->recurseTreeWithOperation(hideOutOfViewOperation,(void*)&args); | |
| 2265 | + _tree->unlock(); | |
| 2266 | + } | |
| 2260 | 2267 | _lastCulledViewFrustum = args.thisViewFrustum; // save last stable |
| 2261 | 2268 | _culledOnce = true; |
| 2262 | 2269 | |
| @@ -2459,35 +2466,47 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData · 196 unmodified lines | ||
| 2459 | 2466 | |
| 2460 | 2467 | bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, |
| 2461 | 2468 | VoxelDetail& detail, float& distance, BoxFace& face) { |
| 2462 | − lockTree(); | |
| 2463 | − OctreeElement* element; | |
| 2464 | − if (!_tree->findRayIntersection(origin, direction, element, distance, face)) { | |
| 2465 | − unlockTree(); | |
| 2466 | − return false; | |
| 2469 | + | |
| 2470 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 2471 | + "VoxelSystem::findRayIntersection()"); | |
| 2472 | + bool result = false; // assume no intersection | |
| 2473 | + if (_tree->tryLockForRead()) { | |
| 2474 | + OctreeElement* element; | |
| 2475 | + result = _tree->findRayIntersection(origin, direction, element, distance, face); | |
| 2476 | + if (result) { | |
| 2477 | + VoxelTreeElement* voxel = (VoxelTreeElement*)element; | |
| 2478 | + detail.x = voxel->getCorner().x; | |
| 2479 | + detail.y = voxel->getCorner().y; | |
| 2480 | + detail.z = voxel->getCorner().z; | |
| 2481 | + detail.s = voxel->getScale(); | |
| 2482 | + detail.red = voxel->getColor()[0]; | |
| 2483 | + detail.green = voxel->getColor()[1]; | |
| 2484 | + detail.blue = voxel->getColor()[2]; | |
| 2485 | + } | |
| 2486 | + _tree->unlock(); | |
| 2467 | 2487 | } |
| 2468 | − VoxelTreeElement* voxel = (VoxelTreeElement*)element; | |
| 2469 | − detail.x = voxel->getCorner().x; | |
| 2470 | − detail.y = voxel->getCorner().y; | |
| 2471 | − detail.z = voxel->getCorner().z; | |
| 2472 | − detail.s = voxel->getScale(); | |
| 2473 | − detail.red = voxel->getColor()[0]; | |
| 2474 | − detail.green = voxel->getColor()[1]; | |
| 2475 | − detail.blue = voxel->getColor()[2]; | |
| 2476 | − unlockTree(); | |
| 2477 | − return true; | |
| 2488 | + return result; | |
| 2478 | 2489 | } |
| 2479 | 2490 | |
| 2480 | 2491 | bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) { |
| 2481 | − lockTree(); | |
| 2482 | − bool result = _tree->findSpherePenetration(center, radius, penetration); | |
| 2483 | − unlockTree(); | |
| 2492 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 2493 | + "VoxelSystem::findSpherePenetration()"); | |
| 2494 | + bool result = false; // assume no penetration | |
| 2495 | + if (_tree->tryLockForRead()) { | |
| 2496 | + result = _tree->findSpherePenetration(center, radius, penetration); | |
| 2497 | + _tree->unlock(); | |
| 2498 | + } | |
| 2484 | 2499 | return result; |
| 2485 | 2500 | } |
| 2486 | 2501 | |
| 2487 | 2502 | bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) { |
| 2488 | − lockTree(); | |
| 2489 | − bool result = _tree->findCapsulePenetration(start, end, radius, penetration); | |
| 2490 | − unlockTree(); | |
| 2503 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 2504 | + "VoxelSystem::findCapsulePenetration()"); | |
| 2505 | + bool result = false; // assume no penetration | |
| 2506 | + if (_tree->tryLockForRead()) { | |
| 2507 | + result = _tree->findCapsulePenetration(start, end, radius, penetration); | |
| 2508 | + _tree->unlock(); | |
| 2509 | + } | |
| 2491 | 2510 | return result; |
| 2492 | 2511 | } |
| 2493 | 2512 | |
| @@ -2695,13 +2714,14 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 201 unmodified lines | ||
| 2695 | 2714 | |
| 2696 | 2715 | |
| 2697 | 2716 | void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) { |
| 2698 | − lockTree(); | |
| 2717 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 2718 | + "VoxelSystem::deleteVoxelAt()"); | |
| 2719 | + _tree->lockForWrite(); | |
| 2699 | 2720 | _tree->deleteVoxelAt(x, y, z, s); |
| 2700 | − unlockTree(); | |
| 2721 | + _tree->unlock(); | |
| 2701 | 2722 | |
| 2702 | 2723 | // redraw! |
| 2703 | 2724 | setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in? |
| 2704 | − | |
| 2705 | 2725 | }; |
| 2706 | 2726 | |
| 2707 | 2727 | VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const { |
| @@ -2711,10 +2731,12 @@ VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) co · 3 unmodified lines | ||
| 2711 | 2731 | void VoxelSystem::createVoxel(float x, float y, float z, float s, |
| 2712 | 2732 | unsigned char red, unsigned char green, unsigned char blue, bool destructive) { |
| 2713 | 2733 | |
| 2714 | − //qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s); | |
| 2715 | − lockTree(); | |
| 2734 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | |
| 2735 | + "VoxelSystem::createVoxel()"); | |
| 2736 | + | |
| 2737 | + _tree->lockForWrite(); | |
| 2716 | 2738 | _tree->createVoxel(x, y, z, s, red, green, blue, destructive); |
| 2717 | − unlockTree(); | |
| 2739 | + _tree->unlock(); | |
| 2718 | 2740 | |
| 2719 | 2741 | setupNewVoxelsForDrawing(); |
| 2720 | 2742 | }; |
| @@ -3085,38 +3107,6 @@ unsigned long VoxelSystem::getVoxelMemoryUsageGPU() { · 364 unmodified lines | ||
| 3085 | 3107 | return (_initialMemoryUsageGPU - currentFreeMemory); |
| 3086 | 3108 | } |
| 3087 | 3109 | |
| 3088 | −void VoxelSystem::lockTree() { | |
| 3089 | − _treeLock.lock(); | |
| 3090 | − _treeIsBusy = true; | |
| 3091 | −} | |
| 3092 | − | |
| 3093 | −void VoxelSystem::unlockTree() { | |
| 3094 | − _treeIsBusy = false; | |
| 3095 | − _treeLock.unlock(); | |
| 3096 | −} | |
| 3097 | − | |
| 3098 | − | |
| 3099 | −void VoxelSystem::localVoxelCacheLoaded() { | |
| 3100 | − qDebug() << "localVoxelCacheLoaded()"; | |
| 3101 | − | |
| 3102 | − // Make sure that the application has properly set up the view frustum for our loaded state | |
| 3103 | − Application::getInstance()->initAvatarAndViewFrustum(); | |
| 3104 | − | |
| 3105 | − _tree->setDirtyBit(); // make sure the tree thinks it's dirty | |
| 3106 | − _setupNewVoxelsForDrawingLastFinished = 0; // don't allow the setupNewVoxelsForDrawing() shortcuts | |
| 3107 | − _writeRenderFullVBO = true; // this will disable individual node updates, was reset by killLocalVoxels() | |
| 3108 | − setupNewVoxelsForDrawing(); | |
| 3109 | − _inhideOutOfView = false; // reenable hideOutOfView behavior | |
| 3110 | −} | |
| 3111 | − | |
| 3112 | −void VoxelSystem::beginLoadingLocalVoxelCache() { | |
| 3113 | − qDebug() << "beginLoadingLocalVoxelCache()"; | |
| 3114 | − _writeRenderFullVBO = true; // this will disable individual node updates | |
| 3115 | − _inhideOutOfView = true; // this will disable hidOutOfView which we want to do until local cache is loaded | |
| 3116 | − killLocalVoxels(); | |
| 3117 | − qDebug() << "DONE beginLoadingLocalVoxelCache()"; | |
| 3118 | −} | |
| 3119 | − | |
| 3120 | 3110 | // Octant bitmask array indexed by octant. The mask value indicates the octant's halfspace partitioning. The index |
| 3121 | 3111 | // value corresponds to the voxel's octal code derived in "pointToVoxel" in SharedUtil.cpp, which, BTW, does *not* |
| 3122 | 3112 | // correspond to the "ChildIndex" enum value in OctreeElement.h |