mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 04:12:46 +02:00
Made readCodeColorBufferToTree() use self contained recursion so we can
implement color averaging properly
This commit is contained in:
parent
57aff0af64
commit
66ebb7d01c
5 changed files with 88 additions and 36 deletions
|
@ -188,10 +188,6 @@ bool cmdOptionExists(int argc, const char * argv[],const char* option) {
|
||||||
//
|
//
|
||||||
// HACK ATTACK: Well, what if this is larger than the MTU? That's the caller's problem, we
|
// HACK ATTACK: Well, what if this is larger than the MTU? That's the caller's problem, we
|
||||||
// just truncate the message
|
// just truncate the message
|
||||||
// Usage:
|
|
||||||
// unsigned char* voxelData = pointToVoxel(x,y,z,s,red,green,blue);
|
|
||||||
// tree->readCodeColorBufferToTree(voxelData);
|
|
||||||
// delete voxelData;
|
|
||||||
//
|
//
|
||||||
// Complaints: Brad :)
|
// Complaints: Brad :)
|
||||||
#define GUESS_OF_VOXELCODE_SIZE 10
|
#define GUESS_OF_VOXELCODE_SIZE 10
|
||||||
|
|
|
@ -107,13 +107,14 @@ VoxelNode* VoxelNode::removeChildAtIndex(int childIndex) {
|
||||||
return returnedChild;
|
return returnedChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelNode::addChildAtIndex(int childIndex) {
|
VoxelNode* VoxelNode::addChildAtIndex(int childIndex) {
|
||||||
if (!_children[childIndex]) {
|
if (!_children[childIndex]) {
|
||||||
_children[childIndex] = new VoxelNode(childOctalCode(_octalCode, childIndex));
|
_children[childIndex] = new VoxelNode(childOctalCode(_octalCode, childIndex));
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
markWithChangedTime();
|
markWithChangedTime();
|
||||||
_childCount++;
|
_childCount++;
|
||||||
}
|
}
|
||||||
|
return _children[childIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
// handles staging or deletion of all deep children
|
// handles staging or deletion of all deep children
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
VoxelNode* getChildAtIndex(int childIndex) const { return _children[childIndex]; };
|
VoxelNode* getChildAtIndex(int childIndex) const { return _children[childIndex]; };
|
||||||
void deleteChildAtIndex(int childIndex);
|
void deleteChildAtIndex(int childIndex);
|
||||||
VoxelNode* removeChildAtIndex(int childIndex);
|
VoxelNode* removeChildAtIndex(int childIndex);
|
||||||
void addChildAtIndex(int childIndex);
|
VoxelNode* addChildAtIndex(int childIndex);
|
||||||
void safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeletion); // handles staging or deletion of all descendents
|
void safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeletion); // handles staging or deletion of all descendents
|
||||||
|
|
||||||
void setColorFromAverageOfChildren();
|
void setColorFromAverageOfChildren();
|
||||||
|
|
|
@ -401,50 +401,104 @@ void VoxelTree::eraseAllVoxels() {
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive) {
|
class ReadCodeColorBufferToTreeArgs {
|
||||||
VoxelNode* lastCreatedNode = nodeForOctalCode(rootNode, codeColorBuffer, NULL);
|
public:
|
||||||
// create the node if it does not exist
|
unsigned char* codeColorBuffer;
|
||||||
if (*lastCreatedNode->getOctalCode() != *codeColorBuffer) {
|
int lengthOfCode;
|
||||||
lastCreatedNode = createMissingNode(lastCreatedNode, codeColorBuffer);
|
bool destructive;
|
||||||
_isDirty = true;
|
bool pathChanged;
|
||||||
} else {
|
};
|
||||||
// if it does exist, make sure it has no children
|
|
||||||
for (int i = 0; i < 8; i++) {
|
void VoxelTree::readCodeColorBufferToTree(unsigned char* codeColorBuffer, bool destructive) {
|
||||||
if (lastCreatedNode->getChildAtIndex(i)) {
|
ReadCodeColorBufferToTreeArgs args;
|
||||||
if (destructive) {
|
args.codeColorBuffer = codeColorBuffer;
|
||||||
lastCreatedNode->deleteChildAtIndex(i);
|
args.lengthOfCode = numberOfThreeBitSectionsInCode(codeColorBuffer);
|
||||||
} else {
|
args.destructive = destructive;
|
||||||
printLog("WARNING! operation would require deleting child at index %d, add Voxel ignored!\n ", i);
|
args.pathChanged = false;
|
||||||
}
|
|
||||||
|
|
||||||
|
VoxelNode* node = rootNode;
|
||||||
|
|
||||||
|
readCodeColorBufferToTreeRecursion(node, &args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VoxelTree::readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraData) {
|
||||||
|
ReadCodeColorBufferToTreeArgs* args = (ReadCodeColorBufferToTreeArgs*)extraData;
|
||||||
|
|
||||||
|
int lengthOfNodeCode = numberOfThreeBitSectionsInCode(node->getOctalCode());
|
||||||
|
|
||||||
|
// Since we traverse the tree in code order, we know that if our code
|
||||||
|
// matches, then we've reached our target node.
|
||||||
|
if (lengthOfNodeCode == args->lengthOfCode) {
|
||||||
|
// we've reached our target -- we might have found our node, but that node might have children.
|
||||||
|
// in this case, we only allow you to set the color if you explicitly asked for a destructive
|
||||||
|
// write.
|
||||||
|
if (!node->isLeaf() && args->destructive) {
|
||||||
|
// if it does exist, make sure it has no children
|
||||||
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
|
node->deleteChildAtIndex(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!node->isLeaf()) {
|
||||||
|
printLog("WARNING! operation would require deleting children, add Voxel ignored!\n ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we get here, then it means, we either had a true leaf to begin with, or we were in
|
||||||
|
// destructive mode and we deleted all the child trees. So we can color.
|
||||||
|
if (node->isLeaf()) {
|
||||||
|
// give this node its color
|
||||||
|
int octalCodeBytes = bytesRequiredForCodeLength(args->lengthOfCode);
|
||||||
|
|
||||||
|
nodeColor newColor;
|
||||||
|
memcpy(newColor, args->codeColorBuffer + octalCodeBytes, SIZE_OF_COLOR_DATA);
|
||||||
|
newColor[SIZE_OF_COLOR_DATA] = 1;
|
||||||
|
node->setColor(newColor);
|
||||||
|
|
||||||
|
// It's possible we just reset the node to it's exact same color, in
|
||||||
|
// which case we don't consider this to be dirty...
|
||||||
|
if (node->isDirty()) {
|
||||||
|
// track our tree dirtiness
|
||||||
|
_isDirty = true;
|
||||||
|
// track that path has changed
|
||||||
|
args->pathChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastCreatedNode->isLeaf()) {
|
// Ok, we know we haven't reached our target node yet, so keep looking
|
||||||
// give this node its color
|
int childIndex = branchIndexWithDescendant(node->getOctalCode(), args->codeColorBuffer);
|
||||||
int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer);
|
VoxelNode* childNode = node->getChildAtIndex(childIndex);
|
||||||
|
|
||||||
|
// If the branch we need to traverse does not exist, then create it on the way down...
|
||||||
|
if (!childNode) {
|
||||||
|
childNode = node->addChildAtIndex(childIndex);
|
||||||
|
}
|
||||||
|
|
||||||
nodeColor newColor;
|
// recurse...
|
||||||
memcpy(newColor, codeColorBuffer + octalCodeBytes, 3);
|
readCodeColorBufferToTreeRecursion(childNode, args);
|
||||||
newColor[3] = 1;
|
|
||||||
lastCreatedNode->setColor(newColor);
|
// Unwinding...
|
||||||
if (lastCreatedNode->isDirty()) {
|
|
||||||
_isDirty = true;
|
// If the lower level did some work, then we need to track our lastChanged status.
|
||||||
}
|
if (args->pathChanged) {
|
||||||
|
node->markWithChangedTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) {
|
void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) {
|
||||||
//unsigned short int itemNumber = (*((unsigned short int*)&bitstream[sizeof(PACKET_HEADER)]));
|
//unsigned short int itemNumber = (*((unsigned short int*)&bitstream[sizeof(PACKET_HEADER)]));
|
||||||
int atByte = sizeof(short int) + sizeof(PACKET_HEADER);
|
int atByte = sizeof(short int) + sizeof(PACKET_HEADER);
|
||||||
unsigned char* pVoxelData = (unsigned char*)&bitstream[atByte];
|
unsigned char* voxelCode = (unsigned char*)&bitstream[atByte];
|
||||||
while (atByte < bufferSizeBytes) {
|
while (atByte < bufferSizeBytes) {
|
||||||
unsigned char octets = (unsigned char)*pVoxelData;
|
int codeLength = numberOfThreeBitSectionsInCode(voxelCode);
|
||||||
int voxelDataSize = bytesRequiredForCodeLength(octets)+3; // 3 for color!
|
int voxelDataSize = bytesRequiredForCodeLength(codeLength) + SIZE_OF_COLOR_DATA;
|
||||||
|
|
||||||
deleteVoxelCodeFromTree(pVoxelData, ACTUALLY_DELETE, COLLAPSE_EMPTY_TREE);
|
deleteVoxelCodeFromTree(voxelCode, ACTUALLY_DELETE, COLLAPSE_EMPTY_TREE);
|
||||||
|
|
||||||
pVoxelData+=voxelDataSize;
|
voxelCode+=voxelDataSize;
|
||||||
atByte+=voxelDataSize;
|
atByte+=voxelDataSize;
|
||||||
}
|
}
|
||||||
reaverageVoxelColors(rootNode); // Fix our colors!! Need to call it on rootNode
|
reaverageVoxelColors(rootNode); // Fix our colors!! Need to call it on rootNode
|
||||||
|
|
|
@ -101,6 +101,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraData);
|
void deleteVoxelCodeFromTreeRecursion(VoxelNode* node, void* extraData);
|
||||||
|
void readCodeColorBufferToTreeRecursion(VoxelNode* node, void* extraData);
|
||||||
|
|
||||||
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||||
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
||||||
|
|
Loading…
Reference in a new issue