diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 5f36ad9e59..7cae90f744 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -6,17 +6,21 @@ // // +#include #include #include "SharedUtil.h" //#include "voxels_Log.h" #include "VoxelNode.h" #include "OctalCode.h" +#include "AABox.h" // using voxels_lib::printLog; VoxelNode::VoxelNode() { octalCode = NULL; + _falseColored = false; // assume true color + // default pointers to child nodes to NULL for (int i = 0; i < 8; i++) { children[i] = NULL; @@ -28,10 +32,21 @@ VoxelNode::~VoxelNode() { // delete all of this node's children for (int i = 0; i < 8; i++) { - delete children[i]; + if (children[i]) { + delete children[i]; + } } } +void VoxelNode::getAABox(AABox& box) const { + // copy corner into box + copyFirstVertexForCode(octalCode,(float*)&box.corner); + + // this tells you the "size" of the voxel + float voxelScale = 1 / powf(2, *octalCode); + box.x = box.y = box.z = voxelScale; +} + void VoxelNode::addChildAtIndex(int childIndex) { children[childIndex] = new VoxelNode(); @@ -43,28 +58,54 @@ void VoxelNode::addChildAtIndex(int childIndex) { void VoxelNode::setColorFromAverageOfChildren() { int colorArray[4] = {0,0,0,0}; for (int i = 0; i < 8; i++) { - if (children[i] != NULL && children[i]->color[3] == 1) { + if (children[i] != NULL && children[i]->isColored()) { for (int j = 0; j < 3; j++) { - colorArray[j] += children[i]->color[j]; + colorArray[j] += children[i]->getTrueColor()[j]; // color averaging should always be based on true colors } colorArray[3]++; } } + nodeColor newColor = { 0, 0, 0, 0}; if (colorArray[3] > 4) { // we need at least 4 colored children to have an average color value // or if we have none we generate random values for (int c = 0; c < 3; c++) { // set the average color value - color[c] = colorArray[c] / colorArray[3]; + newColor[c] = colorArray[c] / colorArray[3]; } // set the alpha to 1 to indicate that this isn't transparent - color[3] = 1; - } else { - // some children, but not enough - // set this node's alpha to 0 - color[3] = 0; - } + newColor[3] = 1; + } + // actually set our color, note, if we didn't have enough children + // this will be the default value all zeros, and therefore be marked as + // transparent with a 4th element of 0 + setColor(newColor); +} + +void VoxelNode::setFalseColor(colorPart red, colorPart green, colorPart blue) { + _falseColored=true; + _currentColor[0] = red; + _currentColor[1] = green; + _currentColor[2] = blue; + _currentColor[3] = 1; // XXXBHG - False colors are always considered set +} + +void VoxelNode::setFalseColored(bool isFalseColored) { + // if we were false colored, and are no longer false colored, then swap back + if (_falseColored && !isFalseColored) { + memcpy(&_currentColor,&_trueColor,sizeof(nodeColor)); + } + _falseColored = isFalseColored; +}; + + +void VoxelNode::setColor(const nodeColor& color) { + //printf("VoxelNode::setColor() isFalseColored=%s\n",_falseColored ? "Yes" : "No"); + memcpy(&_trueColor,&color,sizeof(nodeColor)); + if (!_falseColored) { + memcpy(&_currentColor,&color,sizeof(nodeColor)); + } } // will detect if children are leaves AND the same color @@ -77,16 +118,17 @@ bool VoxelNode::collapseIdenticalLeaves() { int red,green,blue; for (int i = 0; i < 8; i++) { // if no child, or child doesn't have a color - if (children[i] == NULL || children[i]->color[3] != 1) { + if (children[i] == NULL || !children[i]->isColored()) { allChildrenMatch=false; //printLog("SADNESS child missing or not colored! i=%d\n",i); break; } else { if (i==0) { - red = children[i]->color[0]; - green = children[i]->color[1]; - blue = children[i]->color[2]; - } else if (red != children[i]->color[0] || green != children[i]->color[1] || blue != children[i]->color[2]) { + red = children[i]->getColor()[0]; + green = children[i]->getColor()[1]; + blue = children[i]->getColor()[2]; + } else if (red != children[i]->getColor()[0] || + green != children[i]->getColor()[1] || blue != children[i]->getColor()[2]) { allChildrenMatch=false; break; } @@ -100,18 +142,22 @@ bool VoxelNode::collapseIdenticalLeaves() { delete children[i]; // delete all the child nodes children[i]=NULL; // set it to NULL } - color[0]=red; - color[1]=green; - color[2]=blue; - color[3]=1; // color is set + nodeColor collapsedColor; + collapsedColor[0]=red; + collapsedColor[1]=green; + collapsedColor[2]=blue; + collapsedColor[3]=1; // color is set + setColor(collapsedColor); } return allChildrenMatch; } void VoxelNode::setRandomColor(int minimumBrightness) { + nodeColor newColor; for (int c = 0; c < 3; c++) { - color[c] = randomColorValue(minimumBrightness); + newColor[c] = randomColorValue(minimumBrightness); } - color[3] = 1; + newColor[3] = 1; + setColor(newColor); } diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index b82c07a09d..42b4331440 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -9,7 +9,16 @@ #ifndef __hifi__VoxelNode__ #define __hifi__VoxelNode__ +#include "AABox.h" + +typedef unsigned char colorPart; +typedef unsigned char nodeColor[4]; + class VoxelNode { +private: + nodeColor _trueColor; + nodeColor _currentColor; + bool _falseColored; public: VoxelNode(); ~VoxelNode(); @@ -20,8 +29,18 @@ public: bool collapseIdenticalLeaves(); unsigned char *octalCode; - unsigned char color[4]; VoxelNode *children[8]; + + bool isColored() const { return (_trueColor[3]==1); }; + void setFalseColor(colorPart red, colorPart green, colorPart blue); + void setFalseColored(bool isFalseColored); + bool getFalseColored() { return _falseColored; }; + + void setColor(const nodeColor& color); + const nodeColor& getTrueColor() const { return _trueColor; }; + const nodeColor& getColor() const { return _currentColor; }; + + void getAABox(AABox& box) const; }; #endif /* defined(__hifi__VoxelNode__) */