mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
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:
parent
34982227e4
commit
2c8c6a2600
9 changed files with 132 additions and 112 deletions
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue