History

first cut at improved render pipeline

ZappoMan committed 13 years ago

Commit 4f86b551 parent 04b291810 files · +1226 −241Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+174−181
@@ -41,69 +41,53 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . · 40 unmodified lines
4141 4,5,6, 4,6,7 }; // Z+ .
4242
4343 VoxelSystem::VoxelSystem() {
44− voxelsRendered = 0;
45− tree = new VoxelTree();
46− pthread_mutex_init(&bufferWriteLock, NULL);
44+ _voxelsInArrays = _voxelsUpdated = 0;
45+ _tree = new VoxelTree();
46+ pthread_mutex_init(&_bufferWriteLock, NULL);
4747 }
4848
4949 VoxelSystem::~VoxelSystem() {
50− delete[] readVerticesArray;
51− delete[] writeVerticesArray;
52− delete[] readColorsArray;
53− delete[] writeColorsArray;
54− delete tree;
55− pthread_mutex_destroy(&bufferWriteLock);
50+ delete[] _readVerticesArray;
51+ delete[] _writeVerticesArray;
52+ delete[] _readColorsArray;
53+ delete[] _writeColorsArray;
54+ delete[] _voxelDirtyArray;
55+ delete _tree;
56+ pthread_mutex_destroy(&_bufferWriteLock);
5657 }
5758
58−//////////////////////////////////////////////////////////////////////////////////////////
59−// Method: VoxelSystem::loadVoxelsFile()
60−// Description: Loads HiFidelity encoded Voxels from a binary file. The current file
61−// format is a stream of single voxels with NO color data. Currently
62−// colors are set randomly
63−// Complaints: Brad :)
64−// To Do: Need to add color data to the file.
6559 void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
66−
67− tree->loadVoxelsFile(fileName,wantColorRandomizer);
68−
60+ _tree->loadVoxelsFile(fileName, wantColorRandomizer);
6961 copyWrittenDataToReadArrays();
7062 }
7163
72−//////////////////////////////////////////////////////////////////////////////////////////
73−// Method: VoxelSystem::createSphere()
74−// Description: Creates a sphere of voxels in the local system at a given location/radius
75−// To Do: Move this function someplace better? I put it here because we need a
76−// mechanism to tell the system to redraw it's arrays after voxels are done
77−// being added. This is a concept mostly only understood by VoxelSystem.
78−// Complaints: Brad :)
7964 void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
80−
81− tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
65+ _tree->createSphere(r, xc, yc, zc, s, solid, wantColorRandomizer);
8266 setupNewVoxelsForDrawing();
8367 }
8468
8569 long int VoxelSystem::getVoxelsCreated() {
86− return tree->voxelsCreated;
70+ return _tree->voxelsCreated;
8771 }
8872
8973 float VoxelSystem::getVoxelsCreatedPerSecondAverage() {
90− return (1 / tree->voxelsCreatedStats.getEventDeltaAverage());
74+ return (1 / _tree->voxelsCreatedStats.getEventDeltaAverage());
9175 }
9276
9377 long int VoxelSystem::getVoxelsColored() {
94− return tree->voxelsColored;
78+ return _tree->voxelsColored;
9579 }
9680
9781 float VoxelSystem::getVoxelsColoredPerSecondAverage() {
98− return (1 / tree->voxelsColoredStats.getEventDeltaAverage());
82+ return (1 / _tree->voxelsColoredStats.getEventDeltaAverage());
9983 }
10084
10185 long int VoxelSystem::getVoxelsBytesRead() {
102− return tree->voxelsBytesRead;
86+ return _tree->voxelsBytesRead;
10387 }
10488
10589 float VoxelSystem::getVoxelsBytesReadPerSecondAverage() {
106− return tree->voxelsBytesReadStats.getAverageSampleValuePerSecond();
90+ return _tree->voxelsBytesReadStats.getAverageSampleValuePerSecond();
10791 }
10892
10993 int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
@@ -114,11 +98,11 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 4 unmodified lines
11498 switch(command) {
11599 case PACKET_HEADER_VOXEL_DATA:
116100 // ask the VoxelTree to read the bitstream into the tree
117− tree->readBitstreamToTree(voxelData, numBytes - 1);
101+ _tree->readBitstreamToTree(voxelData, numBytes - 1);
118102 break;
119103 case PACKET_HEADER_ERASE_VOXEL:
120104 // ask the tree to read the "remove" bitstream
121− tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);
105+ _tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);
122106 break;
123107 case PACKET_HEADER_Z_COMMAND:
124108
@@ -135,7 +119,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 10 unmodified lines
135119 while (totalLength <= numBytes) {
136120 if (0==strcmp(command,(char*)"erase all")) {
137121 printLog("got Z message == erase all\n");
138− tree->eraseAllVoxels();
122+ _tree->eraseAllVoxels();
123+ _voxelsInArrays = 0; // better way to do this??
139124 }
140125 if (0==strcmp(command,(char*)"add scene")) {
141126 printLog("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n");
@@ -150,78 +135,87 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 8 unmodified lines
150135 }
151136
152137 void VoxelSystem::setupNewVoxelsForDrawing() {
153− // reset the verticesEndPointer so we're writing to the beginning of the array
154− writeVerticesEndPointer = writeVerticesArray;
155− // call recursive function to populate in memory arrays
156− // it will return the number of voxels added
157− glm::vec3 treeRoot = glm::vec3(0,0,0);
158− voxelsRendered = treeToArrays(tree->rootNode, treeRoot);
138+ _voxelsUpdated = newTreeToArrays(_tree->rootNode);
139+ if (_voxelsUpdated) {
140+ _voxelsDirty=true;
141+ }
142+
159143 // copy the newly written data to the arrays designated for reading
160144 copyWrittenDataToReadArrays();
161145 }
162146
163147 void VoxelSystem::copyWrittenDataToReadArrays() {
164− // lock on the buffer write lock so we can't modify the data when the GPU is reading it
165− pthread_mutex_lock(&bufferWriteLock);
166− // store a pointer to the current end so it doesn't change during copy
167− GLfloat *endOfCurrentVerticesData = writeVerticesEndPointer;
168− // copy the vertices and colors
169− memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));
170− memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));
171− // set the read vertices end pointer to the correct spot so the GPU knows how much to pull
172− readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);
173− pthread_mutex_unlock(&bufferWriteLock);
148+ if (_voxelsDirty) {
149+ // lock on the buffer write lock so we can't modify the data when the GPU is reading it
150+ pthread_mutex_lock(&_bufferWriteLock);
151+ int bytesOfVertices = (_voxelsInArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat);
152+ int bytesOfColors = (_voxelsInArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte);
153+ memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices);
154+ memcpy(_readColorsArray, _writeColorsArray, bytesOfColors );
155+ pthread_mutex_unlock(&_bufferWriteLock);
156+ }
174157 }
175158
176−int VoxelSystem::treeToArrays(VoxelNode* currentNode, const glm::vec3& nodePosition) {
177− int voxelsAdded = 0;
178− float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
179− glm::vec3 viewerPosition = _camera->getPosition(); //_viewerAvatar->getPosition();
180−
181− // debug LOD code
182− glm::vec3 debugNodePosition;
183− copyFirstVertexForCode(currentNode->octalCode,(float*)&debugNodePosition);
184−
185− float distanceToVoxelCenter = sqrtf(powf(viewerPosition.x - nodePosition[0] - halfUnitForVoxel, 2) +
186− powf(viewerPosition.y - nodePosition[1] - halfUnitForVoxel, 2) +
187− powf(viewerPosition.z - nodePosition[2] - halfUnitForVoxel, 2));
188−
189− int renderLevel = *currentNode->octalCode + 1;
190− int boundaryPosition = boundaryDistanceForRenderLevel(renderLevel);
191− bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring
192−
193− if (alwaysDraw || distanceToVoxelCenter < boundaryPosition) {
194− for (int i = 0; i < 8; i++) {
195− // check if there is a child here
196− if (currentNode->children[i] != NULL) {
197−
198− glm::vec3 childNodePosition;
199− copyFirstVertexForCode(currentNode->children[i]->octalCode,(float*)&childNodePosition);
200− childNodePosition *= (float)TREE_SCALE; // scale it up
201− voxelsAdded += treeToArrays(currentNode->children[i], childNodePosition);
202− }
159+int VoxelSystem::newTreeToArrays(VoxelNode* node) {
160+ assert(_viewFrustum); // you must set up _viewFrustum before calling this
161+ int voxelsUpdated = 0;
162+ float distanceToNode = node->distanceToCamera(*_viewFrustum);
163+ float boundary = boundaryDistanceForRenderLevel(*node->octalCode + 1);
164+ float childBoundary = boundaryDistanceForRenderLevel(*node->octalCode + 2);
165+ bool inBoundary = (distanceToNode <= boundary);
166+ bool inChildBoundary = (distanceToNode <= childBoundary);
167+ bool shouldRender = node->isColored() && ((node->isLeaf() && inChildBoundary) || (inBoundary && !inChildBoundary));
168+
169+ node->setShouldRender(shouldRender);
170+ // let children figure out their renderness
171+ for (int i = 0; i < 8; i++) {
172+ if (node->children[i]) {
173+ voxelsUpdated += newTreeToArrays(node->children[i]);
203174 }
204175 }
176+
177+ // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays... for us
178+ if (node->isDirty() && (shouldRender || node->isKnownBufferIndex())) {
179+ glm::vec3 startVertex;
180+ float voxelScale = 0;
181+
182+ // If we're should render, use our legit location and scale,
183+ if (node->getShouldRender()) {
184+ copyFirstVertexForCode(node->octalCode, (float*)&startVertex);
185+ voxelScale = (1 / powf(2, *node->octalCode));
186+ } else {
187+ // if we shouldn't render then set out location to some infinitely distant location,
188+ // and our scale as infinitely small
189+ startVertex[0] = startVertex[1] = startVertex[2] = FLT_MAX;
190+ voxelScale = 0;
191+ }
205192
206− // if we didn't get any voxels added then we're a leaf
207− // add our vertex and color information to the interleaved array
208− if (voxelsAdded == 0 && currentNode->isColored()) {
209− float startVertex[3];
210− copyFirstVertexForCode(currentNode->octalCode,(float*)&startVertex);
211− float voxelScale = 1 / powf(2, *currentNode->octalCode);
193+ // If this node has not yet been written to the array, then add it to the end of the array.
194+ glBufferIndex nodeIndex;
195+ if (node->isKnownBufferIndex()) {
196+ nodeIndex = node->getBufferIndex();
197+ } else {
198+ nodeIndex = _voxelsInArrays;
199+ }
200+
201+ _voxelDirtyArray[nodeIndex] = true;
212202
213203 // populate the array with points for the 8 vertices
214204 // and RGB color for each added vertex
215205 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
216− *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
217− *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->getColor()[j % 3];
218−
219− writeVerticesEndPointer++;
206+ GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
207+ GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL);
208+ *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
209+ *(writeColorsAt +j) = node->getColor()[j % 3];
210+ }
211+ if (!node->isKnownBufferIndex()) {
212+ node->setBufferIndex(nodeIndex);
213+ _voxelsInArrays++; // our know vertices in the arrays
220214 }
221− voxelsAdded++;
215+ voxelsUpdated++;
216+ node->clearDirtyBit();
222217 }
223−
224− return voxelsAdded;
218+ return voxelsUpdated;
225219 }
226220
227221 VoxelSystem* VoxelSystem::clone() const {
@@ -230,20 +224,30 @@ VoxelSystem* VoxelSystem::clone() const { · 2 unmodified lines
230224 }
231225
232226 void VoxelSystem::init() {
227+
228+ // When we change voxels representations in the arrays, we'll update this
229+ _voxelsDirty = false;
230+ _voxelsInArrays = 0;
231+
232+ // we will track individual dirty sections with this array of bools
233+ _voxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM];
234+ memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
235+
233236 // prep the data structures for incoming voxel data
234− writeVerticesEndPointer = writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
235− readVerticesEndPointer = readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
236− writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
237− readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
237+ _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
238+ _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
239+
240+ _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
241+ _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
238242
239− GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
243+ GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
240244
241245 // populate the indicesArray
242246 // this will not change given new voxels, so we can set it all up now
243247 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {
244248 // fill the indices array
245249 int voxelIndexOffset = n * INDICES_PER_VOXEL;
246− GLuint *currentIndicesPos = indicesArray + voxelIndexOffset;
250+ GLuint* currentIndicesPos = indicesArray + voxelIndexOffset;
247251 int startIndex = (n * VERTICES_PER_VOXEL);
248252
249253 for (int i = 0; i < INDICES_PER_VOXEL; i++) {
@@ -252,8 +256,8 @@ void VoxelSystem::init() { · 2 unmodified lines
252256 }
253257 }
254258
255− GLfloat *normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
256− GLfloat *normalsArrayEndPointer = normalsArray;
259+ GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
260+ GLfloat* normalsArrayEndPointer = normalsArray;
257261
258262 // populate the normalsArray
259263 for (int n = 0; n < MAX_VOXELS_PER_SYSTEM; n++) {
@@ -263,25 +267,25 @@ void VoxelSystem::init() { · 3 unmodified lines
263267 }
264268
265269 // VBO for the verticesArray
266− glGenBuffers(1, &vboVerticesID);
267− glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
270+ glGenBuffers(1, &_vboVerticesID);
271+ glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
268272 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
269273
270274 // VBO for the normalsArray
271− glGenBuffers(1, &vboNormalsID);
272− glBindBuffer(GL_ARRAY_BUFFER, vboNormalsID);
275+ glGenBuffers(1, &_vboNormalsID);
276+ glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
273277 glBufferData(GL_ARRAY_BUFFER,
274278 VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM,
275279 normalsArray, GL_STATIC_DRAW);
276280
277281 // VBO for colorsArray
278− glGenBuffers(1, &vboColorsID);
279− glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
282+ glGenBuffers(1, &_vboColorsID);
283+ glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
280284 glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
281285
282286 // VBO for the indicesArray
283− glGenBuffers(1, &vboIndicesID);
284− glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
287+ glGenBuffers(1, &_vboIndicesID);
288+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
285289 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
286290 INDICES_PER_VOXEL * sizeof(GLuint) * MAX_VOXELS_PER_SYSTEM,
287291 indicesArray, GL_STATIC_DRAW);
@@ -291,45 +295,68 @@ void VoxelSystem::init() { · 3 unmodified lines
291295 delete[] normalsArray;
292296 }
293297
294−void VoxelSystem::render() {
295−
296− glPushMatrix();
297−
298− if (readVerticesEndPointer != readVerticesArray) {
299− // try to lock on the buffer write
300− // just avoid pulling new data if it is currently being written
301− if (pthread_mutex_trylock(&bufferWriteLock) == 0) {
302−
303− glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
304− glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLfloat), readVerticesArray);
305−
306− glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
307− glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLubyte), readColorsArray);
308−
309− readVerticesEndPointer = readVerticesArray;
310−
311− pthread_mutex_unlock(&bufferWriteLock);
298+void VoxelSystem::updateVBOs() {
299+ if (_voxelsDirty) {
300+ glBufferIndex segmentStart = 0;
301+ glBufferIndex segmentEnd = 0;
302+
303+ bool inSegment = false;
304+ for (glBufferIndex i = 0; i < _voxelsInArrays; i++) {
305+ if (!inSegment) {
306+ if (_voxelDirtyArray[i]) {
307+ segmentStart = i;
308+ inSegment = true;
309+ _voxelDirtyArray[i] = false; // consider us clean!
310+ }
311+ } else {
312+ if (!_voxelDirtyArray[i] || (i == (_voxelsInArrays - 1)) ) {
313+ segmentEnd = i;
314+ inSegment = false;
315+ int segmentLength = (segmentEnd - segmentStart) + 1;
316+
317+ // vertices for segment - note: we might not need to do this
318+ GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
319+ GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
320+ GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
321+
322+ glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
323+ glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
324+
325+ // colors for segment
326+ segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
327+ segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
328+ GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
329+
330+ glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
331+ glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
332+ }
333+ }
312334 }
335+ _voxelsDirty = false;
313336 }
337+}
314338
339+void VoxelSystem::render() {
340+ glPushMatrix();
341+ updateVBOs();
315342 // tell OpenGL where to find vertex and color information
316343 glEnableClientState(GL_VERTEX_ARRAY);
317344 glEnableClientState(GL_NORMAL_ARRAY);
318345 glEnableClientState(GL_COLOR_ARRAY);
319346
320− glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
347+ glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
321348 glVertexPointer(3, GL_FLOAT, 0, 0);
322349
323− glBindBuffer(GL_ARRAY_BUFFER, vboNormalsID);
350+ glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID);
324351 glNormalPointer(GL_FLOAT, 0, 0);
325352
326− glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
353+ glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
327354 glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
328355
329356 // draw the number of voxels we have
330− glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
357+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID);
331358 glScalef(10, 10, 10);
332− glDrawElements(GL_TRIANGLES, 36 * voxelsRendered, GL_UNSIGNED_INT, 0);
359+ glDrawElements(GL_TRIANGLES, 36 * _voxelsInArrays, GL_UNSIGNED_INT, 0);
333360
334361 // deactivate vertex and color arrays after drawing
335362 glDisableClientState(GL_VERTEX_ARRAY);
@@ -350,12 +377,7 @@ void VoxelSystem::simulate(float deltaTime) { · 14 unmodified lines
350377
351378 int VoxelSystem::_nodeCount = 0;
352379
353−bool VoxelSystem::randomColorOperation(VoxelNode* node, bool down, void* extraData) {
354−
355− // we do our operations on the way up!
356− if (down) {
357− return true;
358− }
380+bool VoxelSystem::randomColorOperation(VoxelNode* node, void* extraData) {
359381
360382 _nodeCount++;
361383 if (node->isColored()) {
@@ -370,17 +392,12 @@ bool VoxelSystem::randomColorOperation(VoxelNode* node, bool down, void* extraDa · 8 unmodified lines
370392
371393 void VoxelSystem::randomizeVoxelColors() {
372394 _nodeCount = 0;
373− tree->recurseTreeWithOperation(randomColorOperation);
395+ _tree->recurseTreeWithOperation(randomColorOperation);
374396 printLog("setting randomized true color for %d nodes\n",_nodeCount);
375397 setupNewVoxelsForDrawing();
376398 }
377399
378−bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, bool down, void* extraData) {
379−
380− // we do our operations on the way up!
381− if (down) {
382− return true;
383− }
400+bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, void* extraData) {
384401
385402 _nodeCount++;
386403
@@ -395,18 +412,12 @@ bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, bool down, void* · 8 unmodified lines
395412
396413 void VoxelSystem::falseColorizeRandom() {
397414 _nodeCount = 0;
398− tree->recurseTreeWithOperation(falseColorizeRandomOperation);
415+ _tree->recurseTreeWithOperation(falseColorizeRandomOperation);
399416 printLog("setting randomized false color for %d nodes\n",_nodeCount);
400417 setupNewVoxelsForDrawing();
401418 }
402419
403−bool VoxelSystem::trueColorizeOperation(VoxelNode* node, bool down, void* extraData) {
404−
405− // we do our operations on the way up!
406− if (down) {
407− return true;
408− }
409−
420+bool VoxelSystem::trueColorizeOperation(VoxelNode* node, void* extraData) {
410421 _nodeCount++;
411422 node->setFalseColored(false);
412423 return true;
@@ -414,19 +425,13 @@ bool VoxelSystem::trueColorizeOperation(VoxelNode* node, bool down, void* extraD · 1 unmodified line
414425
415426 void VoxelSystem::trueColorize() {
416427 _nodeCount = 0;
417− tree->recurseTreeWithOperation(trueColorizeOperation);
428+ _tree->recurseTreeWithOperation(trueColorizeOperation);
418429 printLog("setting true color for %d nodes\n",_nodeCount);
419430 setupNewVoxelsForDrawing();
420431 }
421432
422433 // Will false colorize voxels that are not in view
423−bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* extraData) {
424−
425− // we do our operations on the way up!
426− if (down) {
427− return true;
428− }
429−
434+bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, void* extraData) {
430435 const ViewFrustum* viewFrustum = (const ViewFrustum*) extraData;
431436
432437 _nodeCount++;
@@ -448,25 +453,17 @@ bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* · 15 unmodified lines
448453
449454 void VoxelSystem::falseColorizeInView(ViewFrustum* viewFrustum) {
450455 _nodeCount = 0;
451− tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)viewFrustum);
456+ _tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)viewFrustum);
452457 printLog("setting in view false color for %d nodes\n",_nodeCount);
453458 setupNewVoxelsForDrawing();
454459 }
455460
456461 // Will false colorize voxels based on distance from view
457−bool VoxelSystem::falseColorizeDistanceFromViewOperation(VoxelNode* node, bool down, void* extraData) {
458−
459− // we do our operations on the way up!
460− if (down) {
461− return true;
462− }
463−
462+bool VoxelSystem::falseColorizeDistanceFromViewOperation(VoxelNode* node, void* extraData) {
464463 ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
465464
466465 // only do this for truly colored voxels...
467466 if (node->isColored()) {
468−
469− // We need our distance for both up and down
470467 glm::vec3 nodePosition;
471468 float* startVertex = firstVertexForCode(node->octalCode);
472469 nodePosition.x = startVertex[0];
@@ -508,13 +505,7 @@ float VoxelSystem::_minDistance = FLT_MAX; · 35 unmodified lines
508505 // Helper function will get the distance from view range, would be nice if you could just keep track
509506 // of this as voxels are created and/or colored... seems like some transform math could do that so
510507 // we wouldn't need to do two passes of the tree
511−bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, bool down, void* extraData) {
512−
513− // we do our operations on the way up!
514− if (down) {
515− return true;
516− }
517−
508+bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, void* extraData) {
518509 ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
519510
520511 // only do this for truly colored voxels...
@@ -538,7 +529,7 @@ bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, bool down, · 17 unmodified lines
538529 powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) +
539530 powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2));
540531
541− // on way down, calculate the range of distances
532+ // calculate the range of distances
542533 if (distance > _maxDistance) {
543534 _maxDistance = distance;
544535 }
@@ -556,12 +547,14 @@ void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) { · 11 unmodified lines
556547
557548 _maxDistance = 0.0;
558549 _minDistance = FLT_MAX;
559− tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation,(void*)viewFrustum);
550+ _tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation,(void*)viewFrustum);
560551 printLog("determining distance range for %d nodes\n",_nodeCount);
561552
562553 _nodeCount = 0;
563554
564− tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation,(void*)viewFrustum);
555+ _tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation,(void*)viewFrustum);
565556 printLog("setting in distance false color for %d nodes\n",_nodeCount);
566557 setupNewVoxelsForDrawing();
567558 }
559+
560+