History

fixed LOD bug, added support for false colors - fixed LOD bug related to mismatch with getting node position - changed VoxelSystem to honor new VoxelNode color support for false color - added some implementations of tree recursion that do things like false color the tree for distance, randomly, or resetting to true color, or stomping on the local version of the true color to debug packet sending

ZappoMan committed 13 years ago

Commit 75a79a01 parent 7dbc6bc2 files · +317 −42Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+295−41
@@ -161,9 +161,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 160 unmodified lines
161161 writeVerticesEndPointer = writeVerticesArray;
162162 // call recursive function to populate in memory arrays
163163 // it will return the number of voxels added
164− float treeRoot[3] = {0,0,0};
164+ glm::vec3 treeRoot = glm::vec3(0,0,0);
165165 voxelsRendered = treeToArrays(tree->rootNode, treeRoot);
166−
167166 // copy the newly written data to the arrays designated for reading
168167 copyWrittenDataToReadArrays();
169168 }
@@ -176,42 +175,35 @@ void VoxelSystem::copyWrittenDataToReadArrays() { · 6 unmodified lines
176175 // copy the vertices and colors
177176 memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));
178177 memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));
179−
180178 // set the read vertices end pointer to the correct spot so the GPU knows how much to pull
181179 readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);
182180 pthread_mutex_unlock(&bufferWriteLock);
183181 }
184182
185−int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) {
183+int VoxelSystem::treeToArrays(VoxelNode *currentNode, const glm::vec3& nodePosition) {
186184 int voxelsAdded = 0;
187185
188186 float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
189187 glm::vec3 viewerPosition = viewerHead->getBodyPosition();
190188
191− // XXXBHG - Note: It appears as if the X and Z coordinates of Head or Agent are flip-flopped relative to the
192− // coords of the voxel space. This flip flop causes LOD behavior to be extremely odd. This is my temporary hack
193− // to fix this behavior. To disable this swap, set swapXandZ to false.
194− bool swapXandZ=true;
195− float viewerX = swapXandZ ? viewerPosition[2] : viewerPosition[0];
196− float viewerZ = swapXandZ ? viewerPosition[0] : viewerPosition[2];
197−
198− // debugging code.
199− //printLog("treeToArrays() halfUnitForVoxel=%f\n",halfUnitForVoxel);
200− //printLog("treeToArrays() viewerPosition {x,y,z or [0],[1],[2]} ={%f,%f,%f}\n",
201− // viewerPosition[0],viewerPosition[1],viewerPosition[2]);
202− //printLog("treeToArrays() nodePosition {x,y,z or [0],[1],[2]} = {%f,%f,%f}\n",
203− // nodePosition[0],nodePosition[1],nodePosition[2]);
204− //float* vertices = firstVertexForCode(currentNode->octalCode);
205− //printLog("treeToArrays() firstVerticesForCode(currentNode->octalCode)={x,y,z or [0],[1],[2]} = {%f,%f,%f}\n",
206− // vertices[0],vertices[1],vertices[2]);
207− //delete []vertices;
208−
209− float distanceToVoxelCenter = sqrtf(powf(viewerX - nodePosition[0] - halfUnitForVoxel, 2) +
210− powf(viewerPosition[1] - nodePosition[1] - halfUnitForVoxel, 2) +
211− powf(viewerZ - nodePosition[2] - halfUnitForVoxel, 2));
189+ // debug LOD code
190+ glm::vec3 debugNodePosition;
191+ copyFirstVertexForCode(currentNode->octalCode,(float*)&debugNodePosition);
212192
213− int boundaryPosition = boundaryDistanceForRenderLevel(*currentNode->octalCode + 1);
214− //printLog("treeToArrays() distanceToVoxelCenter=%f boundaryPosition=%d\n",distanceToVoxelCenter,boundaryPosition);
193+ //printf("-----------------\n");
194+ //printf("halfUnitForVoxel=%f\n",halfUnitForVoxel);
195+ //printf("viewer.x=%f y=%f z=%f \n", viewerPosition.x, viewerPosition.y, viewerPosition.z);
196+ //printf("node.x=%f y=%f z=%f \n", nodePosition[0], nodePosition[1], nodePosition[2]);
197+ //printf("debugNodePosition.x=%f y=%f z=%f \n", debugNodePosition[0], debugNodePosition[1], debugNodePosition[2]);
198+
199+ float distanceToVoxelCenter = sqrtf(powf(viewerPosition.x - nodePosition[0] - halfUnitForVoxel, 2) +
200+ powf(viewerPosition.y - nodePosition[1] - halfUnitForVoxel, 2) +
201+ powf(viewerPosition.z - nodePosition[2] - halfUnitForVoxel, 2));
202+
203+ int renderLevel = *currentNode->octalCode + 1;
204+ int boundaryPosition = boundaryDistanceForRenderLevel(renderLevel);
205+ //printLog("treeToArrays() renderLevel=%d distanceToVoxelCenter=%f boundaryPosition=%d\n",
206+ // renderLevel,distanceToVoxelCenter,boundaryPosition);
215207
216208 bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring
217209
@@ -220,43 +212,46 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) { · 2 unmodified lines
220212 // check if there is a child here
221213 if (currentNode->children[i] != NULL) {
222214
223− // calculate the child's position based on the parent position
224− float childNodePosition[3];
215+ glm::vec3 childNodePosition;
216+ copyFirstVertexForCode(currentNode->children[i]->octalCode,(float*)&childNodePosition);
217+ childNodePosition *= (float)TREE_SCALE; // scale it up
225218
219+ /**** disabled ************************************************************************************************
220+ // Note: Stephen, I intentionally left this in so you would talk to me about it. Here's the deal, this code
221+ // doesn't seem to work correctly. It returns X and Z flipped and the values are negative. Since we use the
222+ // firstVertexForCode() function below to calculate the child vertex and that DOES work, I've decided to use
223+ // that function to calculate our position for LOD handling.
224+ //
225+ // calculate the child's position based on the parent position
226226 for (int j = 0; j < 3; j++) {
227227 childNodePosition[j] = nodePosition[j];
228228
229− if (oneAtBit(branchIndexWithDescendant(currentNode->octalCode,
230− currentNode->children[i]->octalCode),
231− (7 - j))) {
229+ if (oneAtBit(branchIndexWithDescendant(currentNode->octalCode,currentNode->children[i]->octalCode),(7 - j))) {
232230 childNodePosition[j] -= (powf(0.5, *currentNode->children[i]->octalCode) * TREE_SCALE);
233231 }
234232 }
233+ **** disabled ************************************************************************************************/
235234 voxelsAdded += treeToArrays(currentNode->children[i], childNodePosition);
236235 }
237236 }
238237 }
239−
240−
241−
238+
242239 // if we didn't get any voxels added then we're a leaf
243240 // add our vertex and color information to the interleaved array
244− if (voxelsAdded == 0 && currentNode->color[3] == 1) {
245− float * startVertex = firstVertexForCode(currentNode->octalCode);
241+ if (voxelsAdded == 0 && currentNode->isColored()) {
242+ float startVertex[3];
243+ copyFirstVertexForCode(currentNode->octalCode,(float*)&startVertex);
246244 float voxelScale = 1 / powf(2, *currentNode->octalCode);
247245
248246 // populate the array with points for the 8 vertices
249247 // and RGB color for each added vertex
250248 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
251249 *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
252− *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3];
250+ *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->getColor()[j % 3];
253251
254252 writeVerticesEndPointer++;
255253 }
256−
257254 voxelsAdded++;
258−
259− delete [] startVertex;
260255 }
261256
262257 return voxelsAdded;
@@ -363,4 +358,263 @@ void VoxelSystem::simulate(float deltaTime) { · 100 unmodified lines
363358
364359 }
365360
361+int VoxelSystem::_nodeCount = 0;
362+
363+bool VoxelSystem::randomColorOperation(VoxelNode* node, bool down, void* extraData) {
364+
365+ // we do our operations on the way up!
366+ if (down) {
367+ return true;
368+ }
369+
370+ _nodeCount++;
371+ if (node->isColored()) {
372+ nodeColor newColor = { 0,0,0,1 };
373+ newColor[0] = randomColorValue(150);
374+ newColor[1] = randomColorValue(150);
375+ newColor[1] = randomColorValue(150);
376+
377+ //printf("randomize color node %d was %x,%x,%x NOW %x,%x,%x\n",
378+ // _nodeCount,node->getTrueColor()[0],node->getTrueColor()[1],node->getTrueColor()[2],
379+ // newColor[0],newColor[1],newColor[2]);
380+ node->setColor(newColor);
381+ } else {
382+ //printf("not randomizing color node of %d since it has no color\n",_nodeCount);
383+ }
384+ return true;
385+}
386+
387+void VoxelSystem::randomizeVoxelColors() {
388+ _nodeCount = 0;
389+ tree->recurseTreeWithOperation(randomColorOperation);
390+ printf("setting randomized true color for %d nodes\n",_nodeCount);
391+ setupNewVoxelsForDrawing();
392+}
393+
394+bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, bool down, void* extraData) {
395+
396+ // we do our operations on the way up!
397+ if (down) {
398+ return true;
399+ }
400+
401+ _nodeCount++;
402+
403+ // always false colorize
404+ unsigned char newR = randomColorValue(150);
405+ unsigned char newG = randomColorValue(150);
406+ unsigned char newB = randomColorValue(150);
407+
408+ printf("randomize FALSE color node %d was %x,%x,%x NOW %x,%x,%x\n",
409+ _nodeCount,node->getTrueColor()[0],node->getTrueColor()[1],node->getTrueColor()[2],
410+ newR,newG,newB);
411+ node->setFalseColor(newR,newG,newB);
412+
413+ return true; // keep going!
414+}
415+
416+void VoxelSystem::falseColorizeRandom() {
417+ _nodeCount = 0;
418+ tree->recurseTreeWithOperation(falseColorizeRandomOperation);
419+ printf("setting randomized false color for %d nodes\n",_nodeCount);
420+ setupNewVoxelsForDrawing();
421+}
422+
423+bool VoxelSystem::trueColorizeOperation(VoxelNode* node, bool down, void* extraData) {
424+
425+ // we do our operations on the way up!
426+ if (down) {
427+ return true;
428+ }
429+
430+ _nodeCount++;
431+ node->setFalseColored(false);
432+ //printf("setting true color for node %d\n",_nodeCount);
433+ return true;
434+}
435+
436+void VoxelSystem::trueColorize() {
437+ _nodeCount = 0;
438+ tree->recurseTreeWithOperation(trueColorizeOperation);
439+ printf("setting true color for %d nodes\n",_nodeCount);
440+ setupNewVoxelsForDrawing();
441+}
442+
443+// Will false colorize voxels that are not in view
444+bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* extraData) {
366445
446+ // we do our operations on the way up!
447+ if (down) {
448+ return true;
449+ }
450+
451+ ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
452+
453+ _nodeCount++;
454+
455+ // only do this for truely colored voxels...
456+ if (node->isColored()) {
457+ // first calculate the AAbox for the voxel
458+ AABox voxelBox;
459+ node->getAABox(voxelBox);
460+
461+ voxelBox.scale(TREE_SCALE);
462+
463+ printf("voxelBox corner=(%f,%f,%f) x=%f y=%f z=%f\n",
464+ voxelBox.corner.x, voxelBox.corner.y, voxelBox.corner.z,
465+ voxelBox.x, voxelBox.y, voxelBox.z);
466+
467+ // If the voxel is outside of the view frustum, then false color it red
468+ if (ViewFrustum::OUTSIDE == viewFrustum->boxInFrustum(voxelBox)) {
469+ // Out of view voxels are colored RED
470+ unsigned char newR = 255;
471+ unsigned char newG = 0;
472+ unsigned char newB = 0;
473+
474+ //printf("voxel OUTSIDE view - FALSE colorizing node %d TRUE color is %x,%x,%x \n",
475+ // _nodeCount,node->getTrueColor()[0],node->getTrueColor()[1],node->getTrueColor()[2]);
476+ node->setFalseColor(newR,newG,newB);
477+ } else {
478+ printf("voxel NOT OUTSIDE view\n");
479+ }
480+ } else {
481+ printf("voxel not colored, don't consider it\n");
482+ }
483+
484+ return true; // keep going!
485+}
486+
487+void VoxelSystem::falseColorizeInView(ViewFrustum* viewFrustum) {
488+ _nodeCount = 0;
489+ tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)viewFrustum);
490+ printf("setting in view false color for %d nodes\n",_nodeCount);
491+ setupNewVoxelsForDrawing();
492+}
493+
494+// Will false colorize voxels based on distance from view
495+bool VoxelSystem::falseColorizeDistanceFromViewOperation(VoxelNode* node, bool down, void* extraData) {
496+
497+ //printf("falseColorizeDistanceFromViewOperation() down=%s\n",(down ? "TRUE" : "FALSE"));
498+
499+ // we do our operations on the way up!
500+ if (down) {
501+ return true;
502+ }
503+
504+ ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
505+
506+ // only do this for truly colored voxels...
507+ if (node->isColored()) {
508+
509+ // We need our distance for both up and down
510+ glm::vec3 nodePosition;
511+ float* startVertex = firstVertexForCode(node->octalCode);
512+ nodePosition.x = startVertex[0];
513+ nodePosition.y = startVertex[1];
514+ nodePosition.z = startVertex[2];
515+ delete startVertex;
516+
517+ // scale up the node position
518+ nodePosition = nodePosition*(float)TREE_SCALE;
519+
520+ float halfUnitForVoxel = powf(0.5, *node->octalCode) * (0.5 * TREE_SCALE);
521+ glm::vec3 viewerPosition = viewFrustum->getPosition();
522+
523+ //printf("halfUnitForVoxel=%f\n",halfUnitForVoxel);
524+ //printf("viewer.x=%f y=%f z=%f \n", viewerPosition.x, viewerPosition.y, viewerPosition.z);
525+ //printf("node.x=%f y=%f z=%f \n", nodePosition.x, nodePosition.y, nodePosition.z);
526+
527+ float distance = sqrtf(powf(viewerPosition.x - nodePosition.x - halfUnitForVoxel, 2) +
528+ powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) +
529+ powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2));
530+
531+ // actually colorize
532+ _nodeCount++;
533+
534+ float distanceRatio = (_minDistance==_maxDistance) ? 1 : (distance - _minDistance)/(_maxDistance - _minDistance);
535+
536+ // We want to colorize this in 16 bug chunks of color
537+ const unsigned char maxColor = 255;
538+ const unsigned char colorBands = 16;
539+ const unsigned char gradientOver = 128;
540+ unsigned char colorBand = (colorBands*distanceRatio);
541+ unsigned char newR = (colorBand*(gradientOver/colorBands))+(maxColor-gradientOver);
542+ unsigned char newG = 0;
543+ unsigned char newB = 0;
544+ //printf("Setting color down=%s distance=%f min=%f max=%f distanceRatio=%f color=%d \n",
545+ // (down ? "TRUE" : "FALSE"), distance, _minDistance, _maxDistance, distanceRatio, (int)newR);
546+
547+ node->setFalseColor(newR,newG,newB);
548+ } else {
549+ //printf("voxel not colored, don't consider it - down=%s\n",(down ? "TRUE" : "FALSE"));
550+ }
551+ return true; // keep going!
552+}
553+
554+float VoxelSystem::_maxDistance = 0.0;
555+float VoxelSystem::_minDistance = FLT_MAX;
556+
557+// Helper function will get the distance from view range, would be nice if you could just keep track
558+// of this as voxels are created and/or colored... seems like some transform math could do that so
559+// we wouldn't need to do two passes of the tree
560+bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, bool down, void* extraData) {
561+
562+ // we do our operations on the way up!
563+ if (down) {
564+ return true;
565+ }
566+
567+ //printf("getDistanceFromViewRangeOperation() down=%s\n",(down ? "TRUE" : "FALSE"));
568+
569+ ViewFrustum* viewFrustum = (ViewFrustum*) extraData;
570+
571+ // only do this for truly colored voxels...
572+ if (node->isColored()) {
573+
574+ // We need our distance for both up and down
575+ glm::vec3 nodePosition;
576+ float* startVertex = firstVertexForCode(node->octalCode);
577+ nodePosition.x = startVertex[0];
578+ nodePosition.y = startVertex[1];
579+ nodePosition.z = startVertex[2];
580+ delete startVertex;
581+
582+ // scale up the node position
583+ nodePosition = nodePosition*(float)TREE_SCALE;
584+
585+ float halfUnitForVoxel = powf(0.5, *node->octalCode) * (0.5 * TREE_SCALE);
586+ glm::vec3 viewerPosition = viewFrustum->getPosition();
587+
588+ float distance = sqrtf(powf(viewerPosition.x - nodePosition.x - halfUnitForVoxel, 2) +
589+ powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) +
590+ powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2));
591+
592+ // on way down, calculate the range of distances
593+ if (distance > _maxDistance) {
594+ _maxDistance = distance;
595+ //printf("new maxDistance=%f down=%s\n",_maxDistance, (down ? "TRUE" : "FALSE"));
596+ }
597+ if (distance < _minDistance) {
598+ _minDistance = distance;
599+ //printf("new minDistance=%f down=%s\n",_minDistance, (down ? "TRUE" : "FALSE"));
600+ }
601+
602+ _nodeCount++;
603+ }
604+ return true; // keep going!
605+}
606+
607+void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) {
608+ _nodeCount = 0;
609+
610+ _maxDistance = 0.0;
611+ _minDistance = FLT_MAX;
612+ tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation,(void*)viewFrustum);
613+ printf("determining distance range for %d nodes\n",_nodeCount);
614+
615+ _nodeCount = 0;
616+
617+ tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation,(void*)viewFrustum);
618+ printf("setting in distance false color for %d nodes\n",_nodeCount);
619+ setupNewVoxelsForDrawing();
620+}