History

Merge branch 'master' of https://github.com/highfidelity/hifi into local_voxels

Atlante45 committed 12 years ago

Commit f1ce0342 parents ef9ff0f 5c0ec0f140 files · +1208 −1986Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+13−1044
@@ -18,8 +18,6 @@ · 17 unmodified lines
1818 #include <NodeList.h>
1919
2020 #include "Application.h"
21−#include "CoverageMap.h"
22−#include "CoverageMapV2.h"
2321 #include "InterfaceConfig.h"
2422 #include "Menu.h"
2523 #include "renderer/ProgramObject.h"
@@ -84,9 +82,6 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) · 58 unmodified lines
8482
8583 _viewFrustum = Application::getInstance()->getViewFrustum();
8684
87− connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
88− connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));
89−
9085 _useVoxelShader = false;
9186 _voxelsAsPoints = false;
9287 _voxelShaderModeWhenVoxelsAsPointsEnabled = false;
@@ -206,31 +201,16 @@ void VoxelSystem::freeBufferIndex(glBufferIndex index) { · 113 unmodified lines
206201 qDebug() << "freeBufferIndex() called when _voxelsInWriteArrays == 0!";
207202 }
208203
209− // if the "freed" index was our max index, then just drop the _voxelsInWriteArrays down one...
210− bool inList = false;
211−
212− // make sure the index isn't already in the free list..., this is a debugging measure only done if you've enabled audits
213− if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
214− for (unsigned long i = 0; i < _freeIndexes.size(); i++) {
215− if (_freeIndexes[i] == index) {
216− printf("freeBufferIndex(glBufferIndex index)... index=%ld already in free list!", index);
217− inList = true;
218− break;
219− }
220− }
221− }
222− if (!inList) {
223− // make the index available for next node that needs to be drawn
224− _freeIndexLock.lock();
225− _freeIndexes.push_back(index);
226− _freeIndexLock.unlock();
204+ // make the index available for next node that needs to be drawn
205+ _freeIndexLock.lock();
206+ _freeIndexes.push_back(index);
207+ _freeIndexLock.unlock();
227208
228− // make the VBO slot "invisible" in case this slot is not used
229− const glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX);
230− const float voxelScale = 0;
231− const nodeColor BLACK = {0, 0, 0, 0};
232− updateArraysDetails(index, startVertex, voxelScale, BLACK);
233− }
209+ // make the VBO slot "invisible" in case this slot is not used
210+ const glm::vec3 startVertex(FLT_MAX, FLT_MAX, FLT_MAX);
211+ const float voxelScale = 0;
212+ const nodeColor BLACK = {0, 0, 0, 0};
213+ updateArraysDetails(index, startVertex, voxelScale, BLACK);
234214 }
235215
236216 // This will run through the list of _freeIndexes and reset their VBO array values to be "invisible".
@@ -541,34 +521,6 @@ void VoxelSystem::initVoxelMemory() { · 304 unmodified lines
541521 _readArraysLock.unlock();
542522 }
543523
544−void VoxelSystem::writeToSVOFile(const char* filename, VoxelTreeElement* element) const {
545− _tree->writeToSVOFile(filename, element);
546−}
547−
548−bool VoxelSystem::readFromSVOFile(const char* filename) {
549− bool result = _tree->readFromSVOFile(filename);
550− if (result) {
551− setupNewVoxelsForDrawing();
552− }
553− return result;
554−}
555−
556−bool VoxelSystem::readFromSquareARGB32Pixels(const char *filename) {
557− bool result = _tree->readFromSquareARGB32Pixels(filename);
558− if (result) {
559− setupNewVoxelsForDrawing();
560− }
561− return result;
562−}
563−
564−bool VoxelSystem::readFromSchematicFile(const char* filename) {
565− bool result = _tree->readFromSchematicFile(filename);
566− if (result) {
567− setupNewVoxelsForDrawing();
568− }
569− return result;
570−}
571−
572524 int VoxelSystem::parseData(const QByteArray& packet) {
573525 bool showTimingDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
574526 PerformanceWarning warn(showTimingDetails, "VoxelSystem::parseData()",showTimingDetails);
@@ -618,7 +570,7 @@ int VoxelSystem::parseData(const QByteArray& packet) { · 43 unmodified lines
618570 // ask the VoxelTree to read the bitstream into the tree
619571 ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID());
620572 _tree->lockForWrite();
621− VoxelPacketData packetData(packetIsCompressed);
573+ OctreePacketData packetData(packetIsCompressed);
622574 packetData.loadFinalizedContent(dataAt, sectionLength);
623575 if (Application::getInstance()->getLogger()->extraDebugging()) {
624576 qDebug("VoxelSystem::parseData() ... Got Packet Section"
@@ -692,8 +644,6 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 67 unmodified lines
692644 _abandonedVBOSlots = 0; // reset the count of our abandoned slots, why is this here and not earlier????
693645 }
694646
695− // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are
696− // ok again, until/unless we call removeOutOfView()
697647 _writeRenderFullVBO = false;
698648 } else {
699649 _voxelsUpdated = 0;
@@ -886,15 +836,6 @@ void VoxelSystem::checkForCulling() { · 186 unmodified lines
886836 // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on
887837 // VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
888838 cleanupRemovedVoxels();
889−
890− quint64 sinceLastAudit = (start - _lastAudit) / 1000;
891−
892− if (Menu::getInstance()->isOptionChecked(MenuOption::AutomaticallyAuditTree)) {
893− if (sinceLastAudit >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) {
894− _lastAudit = start;
895− collectStatsForTreesAndVBOs();
896− }
897− }
898839 }
899840
900841 void VoxelSystem::cleanupRemovedVoxels() {
@@ -1241,9 +1182,6 @@ void VoxelSystem::changeTree(VoxelTree* newTree) { · 340 unmodified lines
12411182 _tree->setDirtyBit();
12421183 _tree->getRoot()->setVoxelSystem(this);
12431184
1244− connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
1245− connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));
1246−
12471185 setupNewVoxelsForDrawing();
12481186 }
12491187
@@ -1830,329 +1768,6 @@ void VoxelSystem::forceRedrawEntireTree() { · 580 unmodified lines
18301768 setupNewVoxelsForDrawing();
18311769 }
18321770
1833−bool VoxelSystem::randomColorOperation(OctreeElement* element, void* extraData) {
1834− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
1835− _nodeCount++;
1836− if (voxel->isColored()) {
1837− nodeColor newColor = { 255, randomColorValue(150), randomColorValue(150), 1 };
1838− voxel->setColor(newColor);
1839− }
1840− return true;
1841−}
1842−
1843−void VoxelSystem::randomizeVoxelColors() {
1844− _nodeCount = 0;
1845− _tree->recurseTreeWithOperation(randomColorOperation);
1846− qDebug("setting randomized true color for %d nodes", _nodeCount);
1847− _tree->setDirtyBit();
1848− setupNewVoxelsForDrawing();
1849−}
1850−
1851−bool VoxelSystem::falseColorizeRandomOperation(OctreeElement* element, void* extraData) {
1852− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
1853− _nodeCount++;
1854− // always false colorize
1855− voxel->setFalseColor(255, randomColorValue(150), randomColorValue(150));
1856− return true; // keep going!
1857−}
1858−
1859−void VoxelSystem::falseColorizeRandom() {
1860− _nodeCount = 0;
1861− _tree->recurseTreeWithOperation(falseColorizeRandomOperation);
1862− qDebug("setting randomized false color for %d nodes", _nodeCount);
1863− _tree->setDirtyBit();
1864− setupNewVoxelsForDrawing();
1865−}
1866−
1867−bool VoxelSystem::trueColorizeOperation(OctreeElement* element, void* extraData) {
1868− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
1869− _nodeCount++;
1870− voxel->setFalseColored(false);
1871− return true;
1872−}
1873−
1874−void VoxelSystem::trueColorize() {
1875− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
1876− "trueColorize()",true);
1877− _nodeCount = 0;
1878− _tree->recurseTreeWithOperation(trueColorizeOperation);
1879− qDebug("setting true color for %d nodes", _nodeCount);
1880− _tree->setDirtyBit();
1881− setupNewVoxelsForDrawing();
1882−}
1883−
1884−// Will false colorize voxels that are not in view
1885−bool VoxelSystem::falseColorizeInViewOperation(OctreeElement* element, void* extraData) {
1886− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
1887− const ViewFrustum* viewFrustum = (const ViewFrustum*) extraData;
1888− _nodeCount++;
1889− if (voxel->isColored()) {
1890− if (!voxel->isInView(*viewFrustum)) {
1891− // Out of view voxels are colored RED
1892− voxel->setFalseColor(255, 0, 0);
1893− }
1894− }
1895− return true; // keep going!
1896−}
1897−
1898−void VoxelSystem::falseColorizeInView() {
1899− _nodeCount = 0;
1900− _tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)_viewFrustum);
1901− qDebug("setting in view false color for %d nodes", _nodeCount);
1902− _tree->setDirtyBit();
1903− setupNewVoxelsForDrawing();
1904−}
1905−
1906−class VoxelAndPoint {
1907−public:
1908− VoxelTreeElement* voxel;
1909− glm::vec3 point;
1910−};
1911−
1912−// Find the smallest colored voxel enclosing a point (if there is one)
1913−bool VoxelSystem::getVoxelEnclosingOperation(OctreeElement* element, void* extraData) {
1914− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
1915− VoxelAndPoint* args = (VoxelAndPoint*) extraData;
1916− AABox voxelBox = voxel->getAABox();
1917− if (voxelBox.contains(args->point)) {
1918− if (voxel->isColored() && voxel->isLeaf()) {
1919− // we've reached a solid leaf containing the point, return the node.
1920− args->voxel = voxel;
1921− return false;
1922− }
1923− } else {
1924− // The point is not inside this voxel, so stop recursing.
1925− return false;
1926− }
1927− return true; // keep looking
1928−}
1929−
1930−VoxelTreeElement* VoxelSystem::getVoxelEnclosing(const glm::vec3& point) {
1931− VoxelAndPoint voxelAndPoint;
1932− voxelAndPoint.point = point;
1933− voxelAndPoint.voxel = NULL;
1934− _tree->recurseTreeWithOperation(getVoxelEnclosingOperation, (void*) &voxelAndPoint);
1935− return voxelAndPoint.voxel;
1936−}
1937−
1938−
1939−// helper classes and args for falseColorizeBySource
1940−class groupColor {
1941−public:
1942− unsigned char red, green, blue;
1943− groupColor(unsigned char red, unsigned char green, unsigned char blue) :
1944− red(red), green(green), blue(blue) { }
1945−
1946− groupColor() :
1947− red(0), green(0), blue(0) { }
1948−};
1949−
1950−class colorizeBySourceArgs {
1951−public:
1952− std::map<uint16_t, groupColor> colors;
1953−};
1954−
1955−// Will false colorize voxels that are not in view
1956−bool VoxelSystem::falseColorizeBySourceOperation(OctreeElement* element, void* extraData) {
1957− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
1958− colorizeBySourceArgs* args = (colorizeBySourceArgs*)extraData;
1959− _nodeCount++;
1960− if (voxel->isColored()) {
1961− // pick a color based on the source - we want each source to be obviously different
1962− uint16_t nodeIDKey = voxel->getSourceUUIDKey();
1963− voxel->setFalseColor(args->colors[nodeIDKey].red, args->colors[nodeIDKey].green, args->colors[nodeIDKey].blue);
1964− }
1965− return true; // keep going!
1966−}
1967−
1968−void VoxelSystem::falseColorizeBySource() {
1969− _nodeCount = 0;
1970− colorizeBySourceArgs args;
1971− const int NUMBER_OF_COLOR_GROUPS = 6;
1972− const unsigned char MIN_COLOR = 128;
1973− int voxelServerCount = 0;
1974− groupColor groupColors[NUMBER_OF_COLOR_GROUPS] = {
1975− groupColor(255, 0, 0),
1976− groupColor( 0, 255, 0),
1977− groupColor( 0, 0, 255),
1978− groupColor(255, 0, 255),
1979− groupColor( 0, 255, 255),
1980− groupColor(255, 255, 255)
1981− };
1982−
1983− // create a bunch of colors we'll use during colorization
1984−
1985− foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
1986− if (node->getType() == NodeType::VoxelServer) {
1987− uint16_t nodeID = VoxelTreeElement::getSourceNodeUUIDKey(node->getUUID());
1988− int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS;
1989− args.colors[nodeID] = groupColors[groupColor];
1990−
1991− if (groupColors[groupColor].red > 0) {
1992− groupColors[groupColor].red = ((groupColors[groupColor].red - MIN_COLOR)/2) + MIN_COLOR;
1993− }
1994− if (groupColors[groupColor].green > 0) {
1995− groupColors[groupColor].green = ((groupColors[groupColor].green - MIN_COLOR)/2) + MIN_COLOR;
1996− }
1997− if (groupColors[groupColor].blue > 0) {
1998− groupColors[groupColor].blue = ((groupColors[groupColor].blue - MIN_COLOR)/2) + MIN_COLOR;
1999− }
2000−
2001− voxelServerCount++;
2002− }
2003− }
2004−
2005− _tree->recurseTreeWithOperation(falseColorizeBySourceOperation, &args);
2006− qDebug("setting false color by source for %d nodes", _nodeCount);
2007− _tree->setDirtyBit();
2008− setupNewVoxelsForDrawing();
2009−}
2010−
2011−// Will false colorize voxels based on distance from view
2012−bool VoxelSystem::falseColorizeDistanceFromViewOperation(OctreeElement* element, void* extraData) {
2013− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2014− ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
2015− if (voxel->isColored()) {
2016− float distance = voxel->distanceToCamera(*viewFrustum);
2017− _nodeCount++;
2018− float distanceRatio = (_minDistance == _maxDistance) ? 1 : (distance - _minDistance) / (_maxDistance - _minDistance);
2019−
2020− // We want to colorize this in 16 bug chunks of color
2021− const unsigned char maxColor = 255;
2022− const unsigned char colorBands = 16;
2023− const unsigned char gradientOver = 128;
2024− unsigned char colorBand = (colorBands * distanceRatio);
2025− voxel->setFalseColor((colorBand * (gradientOver / colorBands)) + (maxColor - gradientOver), 0, 0);
2026− }
2027− return true; // keep going!
2028−}
2029−
2030−float VoxelSystem::_maxDistance = 0.0;
2031−float VoxelSystem::_minDistance = FLT_MAX;
2032−
2033−// Helper function will get the distance from view range, would be nice if you could just keep track
2034−// of this as voxels are created and/or colored... seems like some transform math could do that so
2035−// we wouldn't need to do two passes of the tree
2036−bool VoxelSystem::getDistanceFromViewRangeOperation(OctreeElement* element, void* extraData) {
2037− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2038− ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
2039− // only do this for truly colored voxels...
2040− if (voxel->isColored()) {
2041− float distance = voxel->distanceToCamera(*viewFrustum);
2042− // calculate the range of distances
2043− if (distance > _maxDistance) {
2044− _maxDistance = distance;
2045− }
2046− if (distance < _minDistance) {
2047− _minDistance = distance;
2048− }
2049− _nodeCount++;
2050− }
2051− return true; // keep going!
2052−}
2053−
2054−void VoxelSystem::falseColorizeDistanceFromView() {
2055− _nodeCount = 0;
2056− _maxDistance = 0.0;
2057− _minDistance = FLT_MAX;
2058− _tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation, (void*) _viewFrustum);
2059− qDebug("determining distance range for %d nodes", _nodeCount);
2060− _nodeCount = 0;
2061− _tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation, (void*) _viewFrustum);
2062− qDebug("setting in distance false color for %d nodes", _nodeCount);
2063− _tree->setDirtyBit();
2064− setupNewVoxelsForDrawing();
2065−}
2066−
2067−// combines the removeOutOfView args into a single class
2068−class removeOutOfViewArgs {
2069−public:
2070− VoxelSystem* thisVoxelSystem;
2071− ViewFrustum thisViewFrustum;
2072− OctreeElementBag dontRecurseBag;
2073− unsigned long nodesScanned;
2074− unsigned long nodesRemoved;
2075− unsigned long nodesInside;
2076− unsigned long nodesIntersect;
2077− unsigned long nodesOutside;
2078− VoxelTreeElement* insideRoot;
2079− VoxelTreeElement* outsideRoot;
2080−
2081− removeOutOfViewArgs(VoxelSystem* voxelSystem, bool widenViewFrustum = true) :
2082− thisVoxelSystem(voxelSystem),
2083− thisViewFrustum(*voxelSystem->getViewFrustum()),
2084− dontRecurseBag(),
2085− nodesScanned(0),
2086− nodesRemoved(0),
2087− nodesInside(0),
2088− nodesIntersect(0),
2089− nodesOutside(0),
2090− insideRoot(NULL),
2091− outsideRoot(NULL)
2092− {
2093− // Widen the FOV for trimming
2094− if (widenViewFrustum) {
2095− float originalFOV = thisViewFrustum.getFieldOfView();
2096− float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
2097− thisViewFrustum.setFieldOfView(wideFOV);
2098− thisViewFrustum.calculate();
2099− }
2100− }
2101−};
2102−
2103−void VoxelSystem::cancelImport() {
2104− _tree->cancelImport();
2105−}
2106−
2107−// "Remove" voxels from the tree that are not in view. We don't actually delete them,
2108−// we remove them from the tree and place them into a holding area for later deletion
2109−bool VoxelSystem::removeOutOfViewOperation(OctreeElement* element, void* extraData) {
2110− VoxelTreeElement* voxel = (VoxelTreeElement*) element;
2111− removeOutOfViewArgs* args = (removeOutOfViewArgs*)extraData;
2112−
2113− // If our node was previously added to the don't recurse bag, then return false to
2114− // stop the further recursion. This means that the whole node and it's children are
2115− // known to be in view, so don't recurse them
2116− if (args->dontRecurseBag.contains(voxel)) {
2117− args->dontRecurseBag.remove(voxel);
2118− return false; // stop recursion
2119− }
2120−
2121− VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
2122− args->nodesScanned++;
2123− // Need to operate on our child nodes, so we can remove them
2124− for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
2125− VoxelTreeElement* childNode = voxel->getChildAtIndex(i);
2126− if (childNode) {
2127− ViewFrustum::location inFrustum = childNode->inFrustum(args->thisViewFrustum);
2128− switch (inFrustum) {
2129− case ViewFrustum::OUTSIDE: {
2130− args->nodesOutside++;
2131− args->nodesRemoved++;
2132− voxel->removeChildAtIndex(i);
2133− thisVoxelSystem->_removedVoxels.insert(childNode);
2134− // by removing the child, it will not get recursed!
2135− } break;
2136− case ViewFrustum::INSIDE: {
2137− // if the child node is fully INSIDE the view, then there's no need to recurse it
2138− // because we know all it's children will also be in the view, so we want to
2139− // tell the caller to NOT recurse this child
2140− args->nodesInside++;
2141− args->dontRecurseBag.insert(childNode);
2142− } break;
2143− case ViewFrustum::INTERSECT: {
2144− // if the child node INTERSECTs the view, then we don't want to remove it because
2145− // it is at least partially in view. But we DO want to recurse the children because
2146− // some of them may not be in view... nothing specifically to do, just keep iterating
2147− // the children
2148− args->nodesIntersect++;
2149− } break;
2150− }
2151− }
2152− }
2153− return true; // keep going!
2154−}
2155−
21561771 bool VoxelSystem::isViewChanging() {
21571772 bool result = false; // assume the best
21581773
@@ -2180,74 +1795,6 @@ bool VoxelSystem::hasViewChanged() { · 21 unmodified lines
21801795 return result;
21811796 }
21821797
2183−void VoxelSystem::removeOutOfView() {
2184− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "removeOutOfView()");
2185− removeOutOfViewArgs args(this);
2186− _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
2187−
2188− if (args.nodesRemoved) {
2189− _tree->setDirtyBit();
2190− }
2191− bool showRemoveDebugDetails = false;
2192− if (showRemoveDebugDetails) {
2193− qDebug("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d",
2194− args.nodesScanned, args.nodesRemoved, args.nodesInside,
2195− args.nodesIntersect, args.nodesOutside, _removedVoxels.count()
2196− );
2197− }
2198−}
2199−
2200−// combines the removeOutOfView args into a single class
2201−class showAllLocalVoxelsArgs {
2202−public:
2203− VoxelSystem* thisVoxelSystem;
2204− ViewFrustum thisViewFrustum;
2205− unsigned long nodesScanned;
2206−
2207− showAllLocalVoxelsArgs(VoxelSystem* voxelSystem) :
2208− thisVoxelSystem(voxelSystem),
2209− thisViewFrustum(*voxelSystem->getViewFrustum()),
2210− nodesScanned(0)
2211− {
2212− }
2213−};
2214−
2215−void VoxelSystem::showAllLocalVoxels() {
2216− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "showAllLocalVoxels()");
2217− showAllLocalVoxelsArgs args(this);
2218− _tree->recurseTreeWithOperation(showAllLocalVoxelsOperation,(void*)&args);
2219−
2220− bool showRemoveDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
2221− if (showRemoveDebugDetails) {
2222− qDebug("showAllLocalVoxels() scanned=%ld",args.nodesScanned );
2223− }
2224−}
2225−
2226−bool VoxelSystem::showAllLocalVoxelsOperation(OctreeElement* element, void* extraData) {
2227− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2228− showAllLocalVoxelsArgs* args = (showAllLocalVoxelsArgs*)extraData;
2229−
2230− args->nodesScanned++;
2231−
2232− float voxelSizeScale = Menu::getInstance()->getVoxelSizeScale();;
2233− int boundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust();
2234− bool shouldRender = voxel->calculateShouldRender(&args->thisViewFrustum, voxelSizeScale, boundaryLevelAdjust);
2235− voxel->setShouldRender(shouldRender);
2236−
2237− if (shouldRender) {
2238− bool falseColorize = false;
2239− if (falseColorize) {
2240− voxel->setFalseColor(0,0,255); // false colorize
2241− }
2242− // These are both needed to force redraw...
2243− voxel->setDirtyBit();
2244− voxel->markWithChangedTime();
2245− }
2246−
2247− return true; // keep recursing!
2248−}
2249−
2250−
22511798 // combines the removeOutOfView args into a single class
22521799 class hideOutOfViewArgs {
22531800 public:
@@ -2396,15 +1943,9 @@ bool VoxelSystem::hideAllSubTreeOperation(OctreeElement* element, void* extraDat · 142 unmodified lines
23961943 args->nodesOutside++;
23971944 if (voxel->isKnownBufferIndex()) {
23981945 args->nodesRemoved++;
2399− bool falseColorize = false;
2400− if (falseColorize) {
2401− voxel->setFalseColor(255,0,0); // false colorize
2402− } else {
2403− VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
2404− thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->forceRemoveNodeFromArrays(voxel);
2405− thisVoxelSystem->setupNewVoxelsForDrawingSingleNode();
2406− }
2407−
1946+ VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
1947+ thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->forceRemoveNodeFromArrays(voxel);
1948+ thisVoxelSystem->setupNewVoxelsForDrawingSingleNode();
24081949 }
24091950
24101951 return true;
@@ -2437,20 +1978,9 @@ bool VoxelSystem::showAllSubTreeOperation(OctreeElement* element, void* extraDat · 26 unmodified lines
24371978 voxel->setShouldRender(shouldRender);
24381979
24391980 if (shouldRender && !voxel->isKnownBufferIndex()) {
2440− bool falseColorize = false;
2441− if (falseColorize) {
2442− voxel->setFalseColor(0,0,255); // false colorize
2443− }
24441981 // These are both needed to force redraw...
24451982 voxel->setDirtyBit();
24461983 voxel->markWithChangedTime();
2447− // and this?
2448−// no, not needed, because markWithChangedTime notifies hooks, which calls elementUpdated, which calls updateNodeInArrays
2449−// {
2450−// VoxelSystem* thisVoxelSystem = args->thisVoxelSystem;
2451−// thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->updateNodeInArrays(voxel, true, true);
2452−// thisVoxelSystem->setupNewVoxelsForDrawingSingleNode();
2453−// }
24541984 args->nodesShown++;
24551985 }
24561986
@@ -2552,567 +2082,6 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData · 95 unmodified lines
25522082 }
25532083
25542084
2555−bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
2556− VoxelDetail& detail, float& distance, BoxFace& face) {
2557−
2558− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
2559− "VoxelSystem::findRayIntersection()");
2560− bool result = false; // assume no intersection
2561− if (_tree->tryLockForRead()) {
2562− OctreeElement* element;
2563− result = _tree->findRayIntersection(origin, direction, element, distance, face);
2564− if (result) {
2565− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2566− detail.x = voxel->getCorner().x;
2567− detail.y = voxel->getCorner().y;
2568− detail.z = voxel->getCorner().z;
2569− detail.s = voxel->getScale();
2570− detail.red = voxel->getColor()[0];
2571− detail.green = voxel->getColor()[1];
2572− detail.blue = voxel->getColor()[2];
2573− }
2574− _tree->unlock();
2575− }
2576− return result;
2577−}
2578−
2579−bool VoxelSystem::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) {
2580− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
2581− "VoxelSystem::findSpherePenetration()");
2582− bool result = false; // assume no penetration
2583− if (_tree->tryLockForRead()) {
2584− result = _tree->findSpherePenetration(center, radius, penetration);
2585− _tree->unlock();
2586− }
2587− return result;
2588−}
2589−
2590−bool VoxelSystem::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) {
2591− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
2592− "VoxelSystem::findCapsulePenetration()");
2593− bool result = false; // assume no penetration
2594− if (_tree->tryLockForRead()) {
2595− result = _tree->findCapsulePenetration(start, end, radius, penetration);
2596− _tree->unlock();
2597− }
2598− return result;
2599−}
2600−
2601−class falseColorizeRandomEveryOtherArgs {
2602−public:
2603− falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {};
2604− unsigned long totalNodes;
2605− unsigned long colorableNodes;
2606− unsigned long coloredNodes;
2607− bool colorThis;
2608−};
2609−
2610−bool VoxelSystem::falseColorizeRandomEveryOtherOperation(OctreeElement* element, void* extraData) {
2611− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2612− falseColorizeRandomEveryOtherArgs* args = (falseColorizeRandomEveryOtherArgs*)extraData;
2613− args->totalNodes++;
2614− if (voxel->isColored()) {
2615− args->colorableNodes++;
2616− if (args->colorThis) {
2617− args->coloredNodes++;
2618− voxel->setFalseColor(255, randomColorValue(150), randomColorValue(150));
2619− }
2620− args->colorThis = !args->colorThis;
2621− }
2622− return true; // keep going!
2623−}
2624−
2625−void VoxelSystem::falseColorizeRandomEveryOther() {
2626− falseColorizeRandomEveryOtherArgs args;
2627− _tree->recurseTreeWithOperation(falseColorizeRandomEveryOtherOperation,&args);
2628− qDebug("randomized false color for every other node: total %ld, colorable %ld, colored %ld",
2629− args.totalNodes, args.colorableNodes, args.coloredNodes);
2630− _tree->setDirtyBit();
2631− setupNewVoxelsForDrawing();
2632−}
2633−
2634−class collectStatsForTreesAndVBOsArgs {
2635−public:
2636− collectStatsForTreesAndVBOsArgs(int maxVoxels) :
2637− totalNodes(0),
2638− dirtyNodes(0),
2639− shouldRenderNodes(0),
2640− coloredNodes(0),
2641− nodesInVBO(0),
2642− nodesInVBONotShouldRender(0),
2643− nodesInVBOOverExpectedMax(0),
2644− duplicateVBOIndex(0),
2645− leafNodes(0),
2646− culledLeafNodes(0),
2647− nodesInPrimitiveRenderer(0)
2648− {
2649− hasIndexFound = new bool[maxVoxels];
2650− memset(hasIndexFound, false, maxVoxels * sizeof(bool));
2651− };
2652−
2653− ~collectStatsForTreesAndVBOsArgs() {
2654− delete[] hasIndexFound;
2655− }
2656−
2657− unsigned long totalNodes;
2658− unsigned long dirtyNodes;
2659− unsigned long shouldRenderNodes;
2660− unsigned long coloredNodes;
2661− unsigned long nodesInVBO;
2662− unsigned long nodesInVBONotShouldRender;
2663− unsigned long nodesInVBOOverExpectedMax;
2664− unsigned long duplicateVBOIndex;
2665− unsigned long leafNodes;
2666− unsigned long culledLeafNodes; ///< Number of completely culled nodes because of face sharing
2667− unsigned long nodesInPrimitiveRenderer;
2668−
2669− unsigned long expectedMax;
2670−
2671− bool* hasIndexFound;
2672−};
2673−
2674−bool VoxelSystem::collectStatsForTreesAndVBOsOperation(OctreeElement* element, void* extraData) {
2675− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2676−
2677− collectStatsForTreesAndVBOsArgs* args = (collectStatsForTreesAndVBOsArgs*)extraData;
2678− args->totalNodes++;
2679−
2680− if (voxel->isLeaf()) {
2681− args->leafNodes++;
2682− if (voxel->getInteriorOcclusions() == OctreeElement::HalfSpace::All) {
2683− args->culledLeafNodes++;
2684− }
2685− }
2686−
2687− if (voxel->isColored()) {
2688− args->coloredNodes++;
2689− }
2690−
2691− if (voxel->getShouldRender()) {
2692− args->shouldRenderNodes++;
2693− }
2694−
2695− if (voxel->isDirty()) {
2696− args->dirtyNodes++;
2697− }
2698−
2699− unsigned long nodeIndex = 0;
2700− if (voxel->getBufferIndex()) {
2701− args->nodesInPrimitiveRenderer++;
2702− nodeIndex = voxel->getBufferIndex();
2703−
2704− const bool extraDebugging = false; // enable for extra debugging
2705− if (extraDebugging) {
2706− qDebug("node In Renderer... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s, culledFaces=0x%02x \n",
2707− voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(),
2708− nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()),
2709− voxel->getInteriorOcclusions());
2710− }
2711− }
2712−
2713− if (voxel->isKnownBufferIndex()) {
2714− args->nodesInVBO++;
2715− nodeIndex = voxel->getBufferIndex();
2716−
2717− const bool extraDebugging = false; // enable for extra debugging
2718− if (extraDebugging) {
2719− qDebug("node In VBO... [%f,%f,%f] %f ... index=%ld, isDirty=%s, shouldRender=%s \n",
2720− voxel->getCorner().x, voxel->getCorner().y, voxel->getCorner().z, voxel->getScale(),
2721− nodeIndex, debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
2722− }
2723−
2724− if (args->hasIndexFound[nodeIndex]) {
2725− args->duplicateVBOIndex++;
2726− qDebug("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s", nodeIndex,
2727− debug::valueOf(voxel->isDirty()), debug::valueOf(voxel->getShouldRender()));
2728− } else {
2729− args->hasIndexFound[nodeIndex] = true;
2730− }
2731− if (nodeIndex > args->expectedMax) {
2732− args->nodesInVBOOverExpectedMax++;
2733− }
2734−
2735− // if it's in VBO but not-shouldRender, track that also...
2736− if (!voxel->getShouldRender()) {
2737− args->nodesInVBONotShouldRender++;
2738− }
2739− }
2740−
2741− return true; // keep going!
2742−}
2743−
2744−void VoxelSystem::collectStatsForTreesAndVBOs() {
2745− PerformanceWarning warn(true, "collectStatsForTreesAndVBOs()", true);
2746−
2747− glBufferIndex minDirty = GLBUFFER_INDEX_UNKNOWN;
2748− glBufferIndex maxDirty = 0;
2749−
2750− if (!_usePrimitiveRenderer) {
2751− for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) {
2752− if (_writeVoxelDirtyArray[i]) {
2753− minDirty = std::min(minDirty,i);
2754− maxDirty = std::max(maxDirty,i);
2755− }
2756− }
2757− }
2758−
2759− collectStatsForTreesAndVBOsArgs args(_maxVoxels);
2760− args.expectedMax = _voxelsInWriteArrays;
2761−
2762− qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>");
2763−
2764− _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args);
2765−
2766− qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n",
2767− args.totalNodes, args.leafNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes);
2768−
2769− if (!_usePrimitiveRenderer) {
2770− qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld", debug::valueOf(_voxelsDirty),
2771− _voxelsInWriteArrays, minDirty, maxDirty);
2772−
2773− qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld",
2774− args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender);
2775−
2776− qDebug(" memory usage %ld \n gpu memory usage %ld \n", _memoryUsageRAM, _memoryUsageVBO);
2777−
2778− glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN;
2779− glBufferIndex maxInVBO = 0;
2780−
2781− for (glBufferIndex i = 0; i < _maxVoxels; i++) {
2782− if (args.hasIndexFound[i]) {
2783− minInVBO = std::min(minInVBO,i);
2784− maxInVBO = std::max(maxInVBO,i);
2785− }
2786− }
2787−
2788− qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld",
2789− minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays);
2790−
2791− qDebug(" _freeIndexes.size()=%ld",
2792− _freeIndexes.size());
2793− } else {
2794− qDebug(" PrimitiveRenderer nodes %ld \n completely culled nodes %ld \n",
2795− args.nodesInPrimitiveRenderer, args.culledLeafNodes);
2796−
2797− qDebug(" memory usage %ld \n gpu memory usage %ld \n",
2798− _renderer->getMemoryUsage(), _renderer->getMemoryUsageGPU());
2799− }
2800− qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>");
2801−}
2802−
2803−
2804−void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) {
2805− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
2806− "VoxelSystem::deleteVoxelAt()");
2807− _tree->lockForWrite();
2808− _tree->deleteVoxelAt(x, y, z, s);
2809− _tree->unlock();
2810−
2811− // redraw!
2812− setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in?
2813−};
2814−
2815−VoxelTreeElement* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const {
2816− return _tree->getVoxelAt(x, y, z, s);
2817−};
2818−
2819−void VoxelSystem::createVoxel(float x, float y, float z, float s,
2820− unsigned char red, unsigned char green, unsigned char blue, bool destructive) {
2821−
2822− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
2823− "VoxelSystem::createVoxel()");
2824−
2825− _tree->lockForWrite();
2826− _tree->createVoxel(x, y, z, s, red, green, blue, destructive);
2827− _tree->unlock();
2828−
2829− setupNewVoxelsForDrawing();
2830−};
2831−
2832−void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) {
2833− _tree->createLine(point1, point2, unitSize, color, destructive);
2834− setupNewVoxelsForDrawing();
2835−};
2836−
2837−void VoxelSystem::copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelSystem* destination, bool rebaseToRoot) {
2838− _tree->copySubTreeIntoNewTree(startNode, destination->_tree, rebaseToRoot);
2839− destination->setupNewVoxelsForDrawing();
2840−}
2841−
2842−void VoxelSystem::copySubTreeIntoNewTree(VoxelTreeElement* startNode, VoxelTree* destination, bool rebaseToRoot) {
2843− _tree->copySubTreeIntoNewTree(startNode, destination, rebaseToRoot);
2844−}
2845−
2846−void VoxelSystem::copyFromTreeIntoSubTree(VoxelTree* sourceTree, VoxelTreeElement* destinationNode) {
2847− _tree->copyFromTreeIntoSubTree(sourceTree, destinationNode);
2848−}
2849−
2850−void VoxelSystem::recurseTreeWithOperation(RecurseOctreeOperation operation, void* extraData) {
2851− _tree->recurseTreeWithOperation(operation, extraData);
2852−}
2853−
2854−struct FalseColorizeOccludedArgs {
2855− ViewFrustum* viewFrustum;
2856− CoverageMap* map;
2857− CoverageMapV2* mapV2;
2858− VoxelTree* tree;
2859− long totalVoxels;
2860− long coloredVoxels;
2861− long occludedVoxels;
2862− long notOccludedVoxels;
2863− long outOfView;
2864− long subtreeVoxelsSkipped;
2865− long nonLeaves;
2866− long nonLeavesOutOfView;
2867− long nonLeavesOccluded;
2868−};
2869−
2870−struct FalseColorizeSubTreeOperationArgs {
2871− unsigned char color[NUMBER_OF_COLORS];
2872− long voxelsTouched;
2873−};
2874−
2875−bool VoxelSystem::falseColorizeSubTreeOperation(OctreeElement* element, void* extraData) {
2876− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2877− if (voxel->getShouldRender()) {
2878− FalseColorizeSubTreeOperationArgs* args = (FalseColorizeSubTreeOperationArgs*) extraData;
2879− voxel->setFalseColor(args->color[0], args->color[1], args->color[2]);
2880− args->voxelsTouched++;
2881− }
2882− return true;
2883−}
2884−
2885−bool VoxelSystem::falseColorizeOccludedOperation(OctreeElement* element, void* extraData) {
2886− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
2887−
2888− FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData;
2889− args->totalVoxels++;
2890−
2891− // If we are a parent, let's see if we're completely occluded.
2892− if (!voxel->isLeaf()) {
2893− args->nonLeaves++;
2894−
2895− AABox voxelBox = voxel->getAABox();
2896− voxelBox.scale(TREE_SCALE);
2897− OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));
2898−
2899− // If we're not all in view, then ignore it, and just return. But keep searching...
2900− if (!voxelPolygon->getAllInView()) {
2901− args->nonLeavesOutOfView++;
2902− delete voxelPolygon;
2903− return true;
2904− }
2905−
2906− CoverageMapStorageResult result = args->map->checkMap(voxelPolygon, false);
2907− if (result == OCCLUDED) {
2908− args->nonLeavesOccluded++;
2909− delete voxelPolygon;
2910−
2911− FalseColorizeSubTreeOperationArgs subArgs;
2912− subArgs.color[0] = 0;
2913− subArgs.color[1] = 255;
2914− subArgs.color[2] = 0;
2915− subArgs.voxelsTouched = 0;
2916−
2917− args->tree->recurseNodeWithOperation(voxel, falseColorizeSubTreeOperation, &subArgs );
2918−
2919− args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);
2920− args->totalVoxels += (subArgs.voxelsTouched - 1);
2921−
2922− return false;
2923− }
2924−
2925− delete voxelPolygon;
2926− return true; // keep looking...
2927− }
2928−
2929− if (voxel->isLeaf() && voxel->isColored() && voxel->getShouldRender()) {
2930− args->coloredVoxels++;
2931−
2932− AABox voxelBox = voxel->getAABox();
2933− voxelBox.scale(TREE_SCALE);
2934− OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));
2935−
2936− // If we're not all in view, then ignore it, and just return. But keep searching...
2937− if (!voxelPolygon->getAllInView()) {
2938− args->outOfView++;
2939− delete voxelPolygon;
2940− return true;
2941− }
2942−
2943− CoverageMapStorageResult result = args->map->checkMap(voxelPolygon, true);
2944− if (result == OCCLUDED) {
2945− voxel->setFalseColor(255, 0, 0);
2946− args->occludedVoxels++;
2947− } else if (result == STORED) {
2948− args->notOccludedVoxels++;
2949− //qDebug("***** falseColorizeOccludedOperation() NODE is STORED *****\n");
2950− } else if (result == DOESNT_FIT) {
2951− //qDebug("***** falseColorizeOccludedOperation() NODE DOESNT_FIT???? *****\n");
2952− }
2953− }
2954− return true; // keep going!
2955−}
2956−
2957−void VoxelSystem::falseColorizeOccluded() {
2958− PerformanceWarning warn(true, "falseColorizeOccluded()",true);
2959− myCoverageMap.erase();
2960−
2961− FalseColorizeOccludedArgs args;
2962− args.viewFrustum = _viewFrustum;
2963− args.map = &myCoverageMap;
2964− args.totalVoxels = 0;
2965− args.coloredVoxels = 0;
2966− args.occludedVoxels = 0;
2967− args.notOccludedVoxels = 0;
2968− args.outOfView = 0;
2969− args.subtreeVoxelsSkipped = 0;
2970− args.nonLeaves = 0;
2971− args.nonLeavesOutOfView = 0;
2972− args.nonLeavesOccluded = 0;
2973− args.tree = _tree;
2974−
2975− OctreeProjectedPolygon::pointInside_calls = 0;
2976− OctreeProjectedPolygon::occludes_calls = 0;
2977− OctreeProjectedPolygon::intersects_calls = 0;
2978−
2979− glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);
2980−
2981− _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedOperation, position, (void*)&args);
2982−
2983− 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",
2984− position.x, position.y,
2985− args.totalVoxels, args.coloredVoxels, args.occludedVoxels,
2986− args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,
2987− args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,
2988− OctreeProjectedPolygon::pointInside_calls,
2989− OctreeProjectedPolygon::occludes_calls,
2990− OctreeProjectedPolygon::intersects_calls
2991− );
2992−
2993−
2994− //myCoverageMap.erase();
2995−
2996− _tree->setDirtyBit();
2997− setupNewVoxelsForDrawing();
2998−}
2999−
3000−bool VoxelSystem::falseColorizeOccludedV2Operation(OctreeElement* element, void* extraData) {
3001− VoxelTreeElement* voxel = (VoxelTreeElement*)element;
3002−
3003− FalseColorizeOccludedArgs* args = (FalseColorizeOccludedArgs*) extraData;
3004− args->totalVoxels++;
3005−
3006− // If we are a parent, let's see if we're completely occluded.
3007− if (!voxel->isLeaf()) {
3008− args->nonLeaves++;
3009−
3010− AABox voxelBox = voxel->getAABox();
3011− voxelBox.scale(TREE_SCALE);
3012− OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));
3013−
3014− // If we're not all in view, then ignore it, and just return. But keep searching...
3015− if (!voxelPolygon->getAllInView()) {
3016− args->nonLeavesOutOfView++;
3017− delete voxelPolygon;
3018− return true;
3019− }
3020−
3021− CoverageMapV2StorageResult result = args->mapV2->checkMap(voxelPolygon, false);
3022− if (result == V2_OCCLUDED) {
3023− args->nonLeavesOccluded++;
3024− delete voxelPolygon;
3025−
3026− FalseColorizeSubTreeOperationArgs subArgs;
3027− subArgs.color[0] = 0;
3028− subArgs.color[1] = 255;
3029− subArgs.color[2] = 0;
3030− subArgs.voxelsTouched = 0;
3031−
3032− args->tree->recurseNodeWithOperation(voxel, falseColorizeSubTreeOperation, &subArgs );
3033−
3034− args->subtreeVoxelsSkipped += (subArgs.voxelsTouched - 1);
3035− args->totalVoxels += (subArgs.voxelsTouched - 1);
3036−
3037− return false;
3038− }
3039−
3040− delete voxelPolygon;
3041− return true; // keep looking...
3042− }
3043−
3044− if (voxel->isLeaf() && voxel->isColored() && voxel->getShouldRender()) {
3045− args->coloredVoxels++;
3046−
3047− AABox voxelBox = voxel->getAABox();
3048− voxelBox.scale(TREE_SCALE);
3049− OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(args->viewFrustum->getProjectedPolygon(voxelBox));
3050−
3051− // If we're not all in view, then ignore it, and just return. But keep searching...
3052− if (!voxelPolygon->getAllInView()) {
3053− args->outOfView++;
3054− delete voxelPolygon;
3055− return true;
3056− }
3057−
3058− CoverageMapV2StorageResult result = args->mapV2->checkMap(voxelPolygon, true);
3059− if (result == V2_OCCLUDED) {
3060− voxel->setFalseColor(255, 0, 0);
3061− args->occludedVoxels++;
3062− } else if (result == V2_STORED) {
3063− args->notOccludedVoxels++;
3064− //qDebug("***** falseColorizeOccludedOperation() NODE is STORED *****\n");
3065− } else if (result == V2_DOESNT_FIT) {
3066− //qDebug("***** falseColorizeOccludedOperation() NODE DOESNT_FIT???? *****\n");
3067− }
3068− delete voxelPolygon; // V2 maps don't store polygons, so we're always in charge of freeing
3069− }
3070− return true; // keep going!
3071−}
3072−
3073−
3074−void VoxelSystem::falseColorizeOccludedV2() {
3075− PerformanceWarning warn(true, "falseColorizeOccludedV2()",true);
3076− myCoverageMapV2.erase();
3077−
3078− CoverageMapV2::wantDebugging = true;
3079−
3080− OctreeProjectedPolygon::pointInside_calls = 0;
3081− OctreeProjectedPolygon::occludes_calls = 0;
3082− OctreeProjectedPolygon::intersects_calls = 0;
3083−
3084− FalseColorizeOccludedArgs args;
3085− args.viewFrustum = _viewFrustum;
3086− args.mapV2 = &myCoverageMapV2;
3087− args.totalVoxels = 0;
3088− args.coloredVoxels = 0;
3089− args.occludedVoxels = 0;
3090− args.notOccludedVoxels = 0;
3091− args.outOfView = 0;
3092− args.subtreeVoxelsSkipped = 0;
3093− args.nonLeaves = 0;
3094− args.nonLeavesOutOfView = 0;
3095− args.nonLeavesOccluded = 0;
3096− args.tree = _tree;
3097−
3098− glm::vec3 position = args.viewFrustum->getPosition() * (1.0f/TREE_SCALE);
3099−
3100− _tree->recurseTreeWithOperationDistanceSorted(falseColorizeOccludedV2Operation, position, (void*)&args);
3101−
3102− 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",
3103− position.x, position.y,
3104− args.totalVoxels, args.coloredVoxels, args.occludedVoxels,
3105− args.notOccludedVoxels, args.outOfView, args.subtreeVoxelsSkipped,
3106− args.nonLeaves, args.nonLeavesOutOfView, args.nonLeavesOccluded,
3107− OctreeProjectedPolygon::pointInside_calls,
3108− OctreeProjectedPolygon::occludes_calls,
3109− OctreeProjectedPolygon::intersects_calls
3110− );
3111− //myCoverageMapV2.erase();
3112− _tree->setDirtyBit();
3113− setupNewVoxelsForDrawing();
3114−}
3115−
31162085 void VoxelSystem::nodeAdded(SharedNodePointer node) {
31172086 if (node->getType() == NodeType::VoxelServer) {
31182087 qDebug("VoxelSystem... voxel server %s added...", node->getUUID().toString().toLocal8Bit().constData());