Coding standard cleanup and VoxelNode optimization

- make octalCode and children members private
- add public getters for accessing these private members
- change constructor to require an OctalCode for all non-roots
- default constructor constructs a rootNode
- make primary access for deleting, adding, and accessing children through public methods that do bookkeeping
- calculate AABox on voxel creation so that we don't need to do all the math when we deal with voxels
- added methods on VoxelNode for common items like getCorner(), getCenter(), getLevel(), etc
This commit is contained in:
ZappoMan 2013-05-05 10:17:02 -07:00
parent 34982227e4
commit 2c8c6a2600
9 changed files with 132 additions and 112 deletions

View file

@ -221,8 +221,8 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
assert(_viewFrustum); // you must set up _viewFrustum before calling this
int voxelsUpdated = 0;
float distanceToNode = node->distanceToCamera(*_viewFrustum);
float boundary = boundaryDistanceForRenderLevel(*node->octalCode + 1);
float childBoundary = boundaryDistanceForRenderLevel(*node->octalCode + 2);
float boundary = boundaryDistanceForRenderLevel(node->getLevel());
float childBoundary = boundaryDistanceForRenderLevel(node->getLevel() + 1);
bool inBoundary = (distanceToNode <= boundary);
bool inChildBoundary = (distanceToNode <= childBoundary);
bool shouldRender = node->isColored() && ((node->isLeaf() && inChildBoundary) || (inBoundary && !inChildBoundary));
@ -230,8 +230,8 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
node->setShouldRender(shouldRender);
// let children figure out their renderness
for (int i = 0; i < 8; i++) {
if (node->children[i]) {
voxelsUpdated += newTreeToArrays(node->children[i]);
if (node->getChildAtIndex(i)) {
voxelsUpdated += newTreeToArrays(node->getChildAtIndex(i));
}
}
@ -242,8 +242,8 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) {
// If we're should render, use our legit location and scale,
if (node->getShouldRender()) {
copyFirstVertexForCode(node->octalCode, (float*)&startVertex);
voxelScale = (1 / powf(2, *node->octalCode));
startVertex = node->getCorner();
voxelScale = node->getScale();
} else {
// if we shouldn't render then set out location to some infinitely distant location,
// and our scale as infinitely small

View file

@ -14,6 +14,7 @@
void AABox::scale(float scale) {
_corner = _corner*scale;
_size = _size*scale;
_center = _center*scale;
}
@ -34,6 +35,7 @@ void AABox::setBox(const glm::vec3& corner, const glm::vec3& size) {
_size.z = -size.z;
_corner.z -= _size.z;
}
_center = _corner + (_size * 0.5f);
}
glm::vec3 AABox::getVertexP(const glm::vec3 &normal) const {

View file

@ -34,9 +34,11 @@ public:
const glm::vec3& getCorner() const { return _corner; };
const glm::vec3& getSize() const { return _size; };
const glm::vec3& getCenter() const { return _center; };
private:
glm::vec3 _corner;
glm::vec3 _center;
glm::vec3 _size;
};

View file

@ -14,6 +14,8 @@
#include <limits.h>
const int NUMBER_OF_CHILDREN = 8;
const int MAX_VOXEL_PACKET_SIZE = 1492;
const int MAX_TREE_SLICE_BYTES = 26;
const int TREE_SCALE = 10;

View file

@ -20,7 +20,17 @@ using voxels_lib::printLog;
// using voxels_lib::printLog;
VoxelNode::VoxelNode() {
octalCode = NULL;
unsigned char* rootCode = new unsigned char[1];
*rootCode = 0;
init(rootCode);
}
VoxelNode::VoxelNode(unsigned char * octalCode) {
init(octalCode);
}
void VoxelNode::init(unsigned char * octalCode) {
_octalCode = octalCode;
#ifdef HAS_FALSE_COLOR
_falseColored = false; // assume true color
@ -28,21 +38,23 @@ VoxelNode::VoxelNode() {
// default pointers to child nodes to NULL
for (int i = 0; i < 8; i++) {
children[i] = NULL;
_children[i] = NULL;
}
_glBufferIndex = GLBUFFER_INDEX_UNKNOWN;
_isDirty = true;
_shouldRender = false;
calculateAABox();
}
VoxelNode::~VoxelNode() {
delete[] octalCode;
delete[] _octalCode;
// delete all of this node's children
for (int i = 0; i < 8; i++) {
if (children[i]) {
delete children[i];
if (_children[i]) {
delete _children[i];
}
}
}
@ -55,33 +67,38 @@ void VoxelNode::setShouldRender(bool shouldRender) {
}
}
void VoxelNode::getAABox(AABox& box) const {
void VoxelNode::calculateAABox() {
glm::vec3 corner;
glm::vec3 size;
// copy corner into box
copyFirstVertexForCode(octalCode,(float*)&corner);
copyFirstVertexForCode(_octalCode,(float*)&corner);
// this tells you the "size" of the voxel
float voxelScale = 1 / powf(2, *octalCode);
float voxelScale = 1 / powf(2, *_octalCode);
size = glm::vec3(voxelScale,voxelScale,voxelScale);
box.setBox(corner,size);
_box.setBox(corner,size);
}
void VoxelNode::deleteChildAtIndex(int childIndex) {
if (_children[childIndex]) {
delete _children[childIndex];
_children[childIndex] = NULL;
}
}
void VoxelNode::addChildAtIndex(int childIndex) {
if (!children[childIndex]) {
children[childIndex] = new VoxelNode();
if (!_children[childIndex]) {
_children[childIndex] = new VoxelNode(childOctalCode(_octalCode, childIndex));
// XXXBHG - When the node is constructed, it should be cleanly set up as
// true colored, but for some reason, not so much. I've added a a basecamp
// to-do to research this. But for now we'll use belt and suspenders and set
// it to not-false-colored here!
children[childIndex]->setFalseColored(false);
_children[childIndex]->setFalseColored(false);
// give this child its octal code
children[childIndex]->octalCode = childOctalCode(octalCode, childIndex);
_isDirty = true;
}
}
@ -90,9 +107,9 @@ 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]->isColored()) {
if (_children[i] != NULL && _children[i]->isColored()) {
for (int j = 0; j < 3; j++) {
colorArray[j] += children[i]->getTrueColor()[j]; // color averaging should always be based on true colors
colorArray[j] += _children[i]->getTrueColor()[j]; // color averaging should always be based on true colors
}
colorArray[3]++;
}
@ -170,17 +187,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]->isColored()) {
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]->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]) {
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;
}
@ -191,8 +208,8 @@ bool VoxelNode::collapseIdenticalLeaves() {
if (allChildrenMatch) {
//printLog("allChildrenMatch: pruning tree\n");
for (int i = 0; i < 8; i++) {
delete children[i]; // delete all the child nodes
children[i]=NULL; // set it to NULL
delete _children[i]; // delete all the child nodes
_children[i]=NULL; // set it to NULL
}
nodeColor collapsedColor;
collapsedColor[0]=red;
@ -216,7 +233,7 @@ void VoxelNode::setRandomColor(int minimumBrightness) {
bool VoxelNode::isLeaf() const {
for (int i = 0; i < 8; i++) {
if (children[i]) {
if (_children[i]) {
return false;
}
}
@ -224,27 +241,22 @@ bool VoxelNode::isLeaf() const {
}
void VoxelNode::printDebugDetails(const char* label) const {
AABox box;
getAABox(box);
printLog("%s - Voxel at corner=(%f,%f,%f) size=%f octcode=", label,
box.getCorner().x, box.getCorner().y, box.getCorner().z, box.getSize().x);
printOctalCode(octalCode);
_box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getSize().x);
printOctalCode(_octalCode);
}
bool VoxelNode::isInView(const ViewFrustum& viewFrustum) const {
AABox box;
getAABox(box);
AABox box = _box; // use temporary box so we can scale it
box.scale(TREE_SCALE);
bool inView = (ViewFrustum::OUTSIDE != viewFrustum.boxInFrustum(box));
return inView;
}
float VoxelNode::distanceToCamera(const ViewFrustum& viewFrustum) const {
AABox box;
getAABox(box);
box.scale(TREE_SCALE);
float distanceToVoxelCenter = sqrtf(powf(viewFrustum.getPosition().x - (box.getCorner().x + box.getSize().x), 2) +
powf(viewFrustum.getPosition().y - (box.getCorner().y + box.getSize().y), 2) +
powf(viewFrustum.getPosition().z - (box.getCorner().z + box.getSize().z), 2));
glm::vec3 center = _box.getCenter() * (float)TREE_SCALE;
float distanceToVoxelCenter = sqrtf(powf(viewFrustum.getPosition().x - center.x, 2) +
powf(viewFrustum.getPosition().y - center.y, 2) +
powf(viewFrustum.getPosition().z - center.z, 2));
return distanceToVoxelCenter;
}

View file

@ -27,23 +27,37 @@ private:
glBufferIndex _glBufferIndex;
bool _isDirty;
bool _shouldRender;
AABox _box;
unsigned char* _octalCode;
VoxelNode* _children[8];
void calculateAABox();
void init(unsigned char * octalCode);
public:
VoxelNode();
VoxelNode(); // root node constructor
VoxelNode(unsigned char * octalCode); // regular constructor
~VoxelNode();
unsigned char* getOctalCode() const { return _octalCode; };
VoxelNode* getChildAtIndex(int i) const { return _children[i]; };
void deleteChildAtIndex(int childIndex);
void addChildAtIndex(int childIndex);
void setColorFromAverageOfChildren();
void setRandomColor(int minimumBrightness);
bool collapseIdenticalLeaves();
unsigned char *octalCode;
VoxelNode *children[8];
const AABox& getAABox() const { return _box; };
const glm::vec3& getCenter() const { return _box.getCenter(); };
const glm::vec3& getCorner() const { return _box.getCorner(); };
float getScale() const { return _box.getSize().x; /* voxelScale = (1 / powf(2, *node->getOctalCode())); */ };
int getLevel() const { return *_octalCode + 1; /* one based or zero based? */ };
bool isColored() const { return (_trueColor[3]==1); };
bool isInView(const ViewFrustum& viewFrustum) const;
float distanceToCamera(const ViewFrustum& viewFrustum) const;
bool isLeaf() const;
void getAABox(AABox& box) const;
void printDebugDetails(const char* label) const;
bool isDirty() const { return _isDirty; };
void clearDirtyBit() { _isDirty = false; };

View file

@ -34,7 +34,7 @@ void VoxelNodeBag::insert(VoxelNode* node) {
for (int i = 0; i < _elementsInUse; i++) {
// compare the newNode to the elements already in the bag
OctalCodeComparison comparison = compareOctalCodes(_bagElements[i]->octalCode, node->octalCode);
OctalCodeComparison comparison = compareOctalCodes(_bagElements[i]->getOctalCode(), node->getOctalCode());
// If we found a code in the bag that matches, then just return, since the element is already in the bag.
if (comparison == EXACT_MATCH) {

View file

@ -37,17 +37,14 @@ VoxelTree::VoxelTree() :
voxelsColoredStats(100),
voxelsBytesReadStats(100),
_isDirty(true) {
rootNode = new VoxelNode();
rootNode->octalCode = new unsigned char[1];
*rootNode->octalCode = 0;
}
VoxelTree::~VoxelTree() {
// delete the children of the root node
// this recursively deletes the tree
for (int i = 0; i < 8; i++) {
delete rootNode->children[i];
delete rootNode->getChildAtIndex(i);
}
}
@ -60,8 +57,8 @@ void VoxelTree::recurseTreeWithOperation(RecurseVoxelTreeOperation operation, vo
// Recurses voxel node with an operation function
void VoxelTree::recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperation operation, void* extraData) {
if (operation(node, extraData)) {
for (int i = 0; i < sizeof(node->children) / sizeof(node->children[0]); i++) {
VoxelNode* child = node->children[i];
for (int i = 0; i < 8; i++) {
VoxelNode* child = node->getChildAtIndex(i);
if (child) {
recurseNodeWithOperation(child, operation, extraData);
}
@ -72,11 +69,11 @@ void VoxelTree::recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperati
VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * needleCode, VoxelNode** parentOfFoundNode) const {
// find the appropriate branch index based on this ancestorNode
if (*needleCode > 0) {
int branchForNeedle = branchIndexWithDescendant(ancestorNode->octalCode, needleCode);
VoxelNode *childNode = ancestorNode->children[branchForNeedle];
int branchForNeedle = branchIndexWithDescendant(ancestorNode->getOctalCode(), needleCode);
VoxelNode *childNode = ancestorNode->getChildAtIndex(branchForNeedle);
if (childNode != NULL) {
if (*childNode->octalCode == *needleCode) {
if (childNode) {
if (*childNode->getOctalCode() == *needleCode) {
// If the caller asked for the parent, then give them that too...
if (parentOfFoundNode) {
@ -101,18 +98,18 @@ VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char *
// returns the node created!
VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char* codeToReach) {
int indexOfNewChild = branchIndexWithDescendant(lastParentNode->octalCode, codeToReach);
int indexOfNewChild = branchIndexWithDescendant(lastParentNode->getOctalCode(), codeToReach);
// we could be coming down a branch that was already created, so don't stomp on it.
if (lastParentNode->children[indexOfNewChild] == NULL) {
if (!lastParentNode->getChildAtIndex(indexOfNewChild)) {
lastParentNode->addChildAtIndex(indexOfNewChild);
}
// This works because we know we traversed down the same tree so if the length is the same, then the whole code is the same
if (*lastParentNode->children[indexOfNewChild]->octalCode == *codeToReach) {
return lastParentNode->children[indexOfNewChild];
if (*lastParentNode->getChildAtIndex(indexOfNewChild)->getOctalCode() == *codeToReach) {
return lastParentNode->getChildAtIndex(indexOfNewChild);
} else {
return createMissingNode(lastParentNode->children[indexOfNewChild], codeToReach);
return createMissingNode(lastParentNode->getChildAtIndex(indexOfNewChild), codeToReach);
}
}
@ -124,11 +121,11 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode,
int bytesLeftToRead) {
// instantiate variable for bytes already read
int bytesRead = 1;
for (int i = 0; i < 8; i++) {
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
// check the colors mask to see if we have a child to color in
if (oneAtBit(*nodeData, i)) {
// create the child if it doesn't exist
if (!destinationNode->children[i]) {
if (!destinationNode->getChildAtIndex(i)) {
destinationNode->addChildAtIndex(i);
if (destinationNode->isDirty()) {
_isDirty = true;
@ -142,9 +139,9 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode,
nodeColor newColor;
memcpy(newColor, nodeData + bytesRead, 3);
newColor[3] = 1;
bool nodeWasDirty = destinationNode->children[i]->isDirty();
destinationNode->children[i]->setColor(newColor);
bool nodeIsDirty = destinationNode->children[i]->isDirty();
bool nodeWasDirty = destinationNode->getChildAtIndex(i)->isDirty();
destinationNode->getChildAtIndex(i)->setColor(newColor);
bool nodeIsDirty = destinationNode->getChildAtIndex(i)->isDirty();
if (nodeIsDirty) {
_isDirty = true;
}
@ -168,7 +165,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode,
// check the exists mask to see if we have a child to traverse into
if (oneAtBit(childMask, childIndex)) {
if (!destinationNode->children[childIndex]) {
if (!destinationNode->getChildAtIndex(childIndex)) {
// add a child at that index, if it doesn't exist
bool nodeWasDirty = destinationNode->isDirty();
destinationNode->addChildAtIndex(childIndex);
@ -184,7 +181,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode,
}
// tell the child to read the subsequent data
bytesRead += readNodeData(destinationNode->children[childIndex],
bytesRead += readNodeData(destinationNode->getChildAtIndex(childIndex),
nodeData + bytesRead,
bytesLeftToRead - bytesRead);
}
@ -207,7 +204,7 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int
while (bitstreamAt < bitstream + bufferSizeBytes) {
VoxelNode* bitstreamRootNode = nodeForOctalCode(rootNode, (unsigned char *)bitstreamAt, NULL);
if (*bitstreamAt != *bitstreamRootNode->octalCode) {
if (*bitstreamAt != *bitstreamRootNode->getOctalCode()) {
// if the octal code returned is not on the same level as
// the code being searched for, we have VoxelNodes to create
@ -251,12 +248,11 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer) {
// If the node exists...
int lengthInBytes = bytesRequiredForCodeLength(*codeBuffer); // includes octet count, not color!
if (0 == memcmp(nodeToDelete->octalCode,codeBuffer,lengthInBytes)) {
if (0 == memcmp(nodeToDelete->getOctalCode(),codeBuffer,lengthInBytes)) {
if (parentNode) {
int childIndex = branchIndexWithDescendant(parentNode->octalCode, codeBuffer);
int childIndex = branchIndexWithDescendant(parentNode->getOctalCode(), codeBuffer);
delete parentNode->children[childIndex]; // delete the child nodes
parentNode->children[childIndex] = NULL; // set it to NULL
parentNode->deleteChildAtIndex(childIndex);
reaverageVoxelColors(rootNode); // Fix our colors!! Need to call it on rootNode
_isDirty = true;
@ -268,8 +264,6 @@ void VoxelTree::eraseAllVoxels() {
// XXXBHG Hack attack - is there a better way to erase the voxel tree?
delete rootNode; // this will recurse and delete all children
rootNode = new VoxelNode();
rootNode->octalCode = new unsigned char[1];
*rootNode->octalCode = 0;
_isDirty = true;
}
@ -277,7 +271,7 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) {
VoxelNode* lastCreatedNode = nodeForOctalCode(rootNode, codeColorBuffer, NULL);
// create the node if it does not exist
if (*lastCreatedNode->octalCode != *codeColorBuffer) {
if (*lastCreatedNode->getOctalCode() != *codeColorBuffer) {
lastCreatedNode = createMissingNode(lastCreatedNode, codeColorBuffer);
_isDirty = true;
}
@ -320,7 +314,7 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) {
// create the color mask
for (int i = 0; i < 8; i++) {
if (startNode->children[i] != NULL && startNode->children[i]->isColored()) {
if (startNode->getChildAtIndex(i) && startNode->getChildAtIndex(i)->isColored()) {
colorMask += (1 << (7 - i));
}
}
@ -330,19 +324,19 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) {
// output the colors we have
for (int j = 0; j < 8; j++) {
if (startNode->children[j] != NULL && startNode->children[j]->isColored()) {
if (startNode->getChildAtIndex(j) && startNode->getChildAtIndex(j)->isColored()) {
printLog("color %d : ",j);
for (int c = 0; c < 3; c++) {
outputBits(startNode->children[j]->getTrueColor()[c],false);
outputBits(startNode->getChildAtIndex(j)->getTrueColor()[c],false);
}
startNode->children[j]->printDebugDetails("");
startNode->getChildAtIndex(j)->printDebugDetails("");
}
}
unsigned char childMask = 0;
for (int k = 0; k < 8; k++) {
if (startNode->children[k] != NULL) {
if (startNode->getChildAtIndex(k)) {
childMask += (1 << (7 - k));
}
}
@ -354,8 +348,8 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) {
// ask children to recursively output their trees
// if they aren't a leaf
for (int l = 0; l < 8; l++) {
if (startNode->children[l] != NULL) {
printTreeForDebugging(startNode->children[l]);
if (startNode->getChildAtIndex(l)) {
printTreeForDebugging(startNode->getChildAtIndex(l));
}
}
}
@ -365,8 +359,8 @@ void VoxelTree::reaverageVoxelColors(VoxelNode *startNode) {
bool hasChildren = false;
for (int i = 0; i < 8; i++) {
if (startNode->children[i] != NULL) {
reaverageVoxelColors(startNode->children[i]);
if (startNode->getChildAtIndex(i)) {
reaverageVoxelColors(startNode->getChildAtIndex(i));
hasChildren = true;
}
}
@ -437,7 +431,7 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
VoxelNode* VoxelTree::getVoxelAt(float x, float y, float z, float s) const {
unsigned char* octalCode = pointToVoxel(x,y,z,s,0,0,0);
VoxelNode* node = nodeForOctalCode(rootNode, octalCode, NULL);
if (*node->octalCode != *octalCode) {
if (*node->getOctalCode() != *octalCode) {
node = NULL;
}
delete octalCode; // cleanup memory
@ -587,11 +581,10 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
// for each child node, check to see if they exist, are colored, and in view, and if so
// add them to our distance ordered array of children
for (int i = 0; i < MAX_CHILDREN; i++) {
VoxelNode* childNode = node->children[i];
bool childExists = (childNode != NULL);
bool childIsColored = (childExists && childNode->isColored());
bool childIsInView = (childExists && childNode->isInView(viewFrustum));
bool childIsLeaf = (childExists && childNode->isLeaf());
VoxelNode* childNode = node->getChildAtIndex(i);
bool childIsColored = (childNode && childNode->isColored());
bool childIsInView = (childNode && childNode->isInView(viewFrustum));
bool childIsLeaf = (childNode && childNode->isLeaf());
if (childIsInView) {
@ -607,7 +600,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
float distance = childNode->distanceToCamera(viewFrustum);
if (distance < boundaryDistanceForRenderLevel(*childNode->octalCode + 1)) {
if (distance < boundaryDistanceForRenderLevel(*childNode->getOctalCode() + 1)) {
inViewCount = insertIntoSortedArrays((void*)childNode, distance, i,
(void**)&inViewChildren, (float*)&distancesToChildren,
(int*)&positionOfChildren, inViewCount, MAX_CHILDREN);
@ -648,8 +641,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
}
// write the octal code
int codeLength = bytesRequiredForCodeLength(*node->octalCode);
memcpy(outputBuffer,node->octalCode,codeLength);
int codeLength = bytesRequiredForCodeLength(*node->getOctalCode());
memcpy(outputBuffer,node->getOctalCode(),codeLength);
outputBuffer += codeLength; // move the pointer
bytesWritten += codeLength; // keep track of byte count
@ -695,7 +688,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// caller can pass NULL as viewFrustum if they want everything
if (viewFrustum) {
float distance = node->distanceToCamera(*viewFrustum);
float boundaryDistance = boundaryDistanceForRenderLevel(*node->octalCode + 1);
float boundaryDistance = boundaryDistanceForRenderLevel(*node->getOctalCode() + 1);
// If we're too far away for our render level, then just return
if (distance >= boundaryDistance) {
@ -735,13 +728,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// for each child node, check to see if they exist, are colored, and in view, and if so
// add them to our distance ordered array of children
for (int i = 0; i < MAX_CHILDREN; i++) {
VoxelNode* childNode = node->children[i];
bool childExists = (childNode != NULL);
bool childIsInView = (childExists && (!viewFrustum || childNode->isInView(*viewFrustum)));
VoxelNode* childNode = node->getChildAtIndex(i);
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
if (childIsInView) {
// Before we determine consider this further, let's see if it's in our LOD scope...
float distance = viewFrustum ? childNode->distanceToCamera(*viewFrustum) : 0;
float boundaryDistance = viewFrustum ? boundaryDistanceForRenderLevel(*childNode->octalCode + 1) : 1;
float boundaryDistance = viewFrustum ? boundaryDistanceForRenderLevel(*childNode->getOctalCode() + 1) : 1;
if (distance < boundaryDistance) {
inViewCount++;
@ -749,13 +741,13 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// track children in view as existing and not a leaf, if they're a leaf,
// we don't care about recursing deeper on them, and we don't consider their
// subtree to exist
if (!(childExists && childNode->isLeaf())) {
if (!(childNode && childNode->isLeaf())) {
childrenExistBits += (1 << (7 - i));
inViewNotLeafCount++;
}
// track children with actual color
if (childExists && childNode->isColored()) {
if (childNode && childNode->isColored()) {
childrenColoredBits += (1 << (7 - i));
inViewWithColorCount++;
}
@ -769,7 +761,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
// write the color data...
for (int i = 0; i < MAX_CHILDREN; i++) {
if (oneAtBit(childrenColoredBits, i)) {
memcpy(writeToThisLevelBuffer, &node->children[i]->getColor(), BYTES_PER_COLOR);
memcpy(writeToThisLevelBuffer, &node->getChildAtIndex(i)->getColor(), BYTES_PER_COLOR);
writeToThisLevelBuffer += BYTES_PER_COLOR; // move the pointer for color
bytesAtThisLevel += BYTES_PER_COLOR; // keep track of byte count for color
}
@ -810,7 +802,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
for (int i = 0; i < MAX_CHILDREN; i++) {
if (oneAtBit(childrenExistBits, i)) {
VoxelNode* childNode = node->children[i];
VoxelNode* childNode = node->getChildAtIndex(i);
int thisLevel = currentEncodeLevel;
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,

View file

@ -153,12 +153,8 @@ void randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
for (int i = 0; i < 8; i++) {
if (true) {
// create a new VoxelNode to put here
currentRootNode->children[i] = new VoxelNode();
// give this child it's octal code
currentRootNode->children[i]->octalCode = childOctalCode(currentRootNode->octalCode, i);
randomlyFillVoxelTree(levelsToGo - 1, currentRootNode->children[i]);
currentRootNode->addChildAtIndex(i);
randomlyFillVoxelTree(levelsToGo - 1, currentRootNode->getChildAtIndex(i));
createdChildren = true;
}
}