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
161 writeVerticesEndPointer = writeVerticesArray;161 writeVerticesEndPointer = writeVerticesArray;
162 // call recursive function to populate in memory arrays162 // call recursive function to populate in memory arrays
163 // it will return the number of voxels added163 // it will return the number of voxels added
164 float treeRoot[3] = {0,0,0};164 glm::vec3 treeRoot = glm::vec3(0,0,0);
165 voxelsRendered = treeToArrays(tree->rootNode, treeRoot);165 voxelsRendered = treeToArrays(tree->rootNode, treeRoot);
166
167 // copy the newly written data to the arrays designated for reading166 // copy the newly written data to the arrays designated for reading
168 copyWrittenDataToReadArrays();167 copyWrittenDataToReadArrays();
169}168}
@@ -176,42 +175,35 @@ void VoxelSystem::copyWrittenDataToReadArrays() { · 6 unmodified lines
176 // copy the vertices and colors175 // copy the vertices and colors
177 memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));176 memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));
178 memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));177 memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));
179
180 // set the read vertices end pointer to the correct spot so the GPU knows how much to pull178 // set the read vertices end pointer to the correct spot so the GPU knows how much to pull
181 readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);179 readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);
182 pthread_mutex_unlock(&bufferWriteLock);180 pthread_mutex_unlock(&bufferWriteLock);
183}181}
184 182
185int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) {183int VoxelSystem::treeToArrays(VoxelNode *currentNode, const glm::vec3& nodePosition) {
186 int voxelsAdded = 0;184 int voxelsAdded = 0;
187 185
188 float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);186 float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
189 glm::vec3 viewerPosition = viewerHead->getBodyPosition();187 glm::vec3 viewerPosition = viewerHead->getBodyPosition();
190 188
191 // XXXBHG - Note: It appears as if the X and Z coordinates of Head or Agent are flip-flopped relative to the 189 // debug LOD code
192 // coords of the voxel space. This flip flop causes LOD behavior to be extremely odd. This is my temporary hack 190 glm::vec3 debugNodePosition;
193 // to fix this behavior. To disable this swap, set swapXandZ to false.191 copyFirstVertexForCode(currentNode->octalCode,(float*)&debugNodePosition);
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));
212 192
213 int boundaryPosition = boundaryDistanceForRenderLevel(*currentNode->octalCode + 1);193 //printf("-----------------\n");
214 //printLog("treeToArrays() distanceToVoxelCenter=%f boundaryPosition=%d\n",distanceToVoxelCenter,boundaryPosition);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);
215 207
216 bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring208 bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring
217 209
@@ -220,43 +212,46 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) { · 2 unmodified lines
220 // check if there is a child here212 // check if there is a child here
221 if (currentNode->children[i] != NULL) {213 if (currentNode->children[i] != NULL) {
222 214
223 // calculate the child's position based on the parent position215 glm::vec3 childNodePosition;
224 float childNodePosition[3];216 copyFirstVertexForCode(currentNode->children[i]->octalCode,(float*)&childNodePosition);
217 childNodePosition *= (float)TREE_SCALE; // scale it up
225 218
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
226 for (int j = 0; j < 3; j++) {226 for (int j = 0; j < 3; j++) {
227 childNodePosition[j] = nodePosition[j];227 childNodePosition[j] = nodePosition[j];
228 228
229 if (oneAtBit(branchIndexWithDescendant(currentNode->octalCode,229 if (oneAtBit(branchIndexWithDescendant(currentNode->octalCode,currentNode->children[i]->octalCode),(7 - j))) {
230 currentNode->children[i]->octalCode),
231 (7 - j))) {
232 childNodePosition[j] -= (powf(0.5, *currentNode->children[i]->octalCode) * TREE_SCALE);230 childNodePosition[j] -= (powf(0.5, *currentNode->children[i]->octalCode) * TREE_SCALE);
233 }231 }
234 }232 }
233 **** disabled ************************************************************************************************/
235 voxelsAdded += treeToArrays(currentNode->children[i], childNodePosition);234 voxelsAdded += treeToArrays(currentNode->children[i], childNodePosition);
236 }235 }
237 }236 }
238 }237 }
239 238
240
241
242 // if we didn't get any voxels added then we're a leaf239 // if we didn't get any voxels added then we're a leaf
243 // add our vertex and color information to the interleaved array240 // add our vertex and color information to the interleaved array
244 if (voxelsAdded == 0 && currentNode->color[3] == 1) {241 if (voxelsAdded == 0 && currentNode->isColored()) {
245 float * startVertex = firstVertexForCode(currentNode->octalCode);242 float startVertex[3];
243 copyFirstVertexForCode(currentNode->octalCode,(float*)&startVertex);
246 float voxelScale = 1 / powf(2, *currentNode->octalCode);244 float voxelScale = 1 / powf(2, *currentNode->octalCode);
247 245
248 // populate the array with points for the 8 vertices246 // populate the array with points for the 8 vertices
249 // and RGB color for each added vertex247 // and RGB color for each added vertex
250 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {248 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
251 *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);249 *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
252 *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3];250 *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->getColor()[j % 3];
253 251
254 writeVerticesEndPointer++;252 writeVerticesEndPointer++;
255 }253 }
256
257 voxelsAdded++;254 voxelsAdded++;
258
259 delete [] startVertex;
260 }255 }
261 256
262 return voxelsAdded;257 return voxelsAdded;
@@ -363,4 +358,263 @@ void VoxelSystem::simulate(float deltaTime) { · 100 unmodified lines
363 358
364}359}
365 360
361int VoxelSystem::_nodeCount = 0;
362
363bool 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
387void VoxelSystem::randomizeVoxelColors() {
388 _nodeCount = 0;
389 tree->recurseTreeWithOperation(randomColorOperation);
390 printf("setting randomized true color for %d nodes\n",_nodeCount);
391 setupNewVoxelsForDrawing();
392}
393
394bool 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
416void VoxelSystem::falseColorizeRandom() {
417 _nodeCount = 0;
418 tree->recurseTreeWithOperation(falseColorizeRandomOperation);
419 printf("setting randomized false color for %d nodes\n",_nodeCount);
420 setupNewVoxelsForDrawing();
421}
422
423bool 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
436void 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
444bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* extraData) {
366 445
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
487void 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
495bool 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
554float VoxelSystem::_maxDistance = 0.0;
555float 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
560bool 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
607void 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}