mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 03:53:52 +02:00
Added PointerStack class, and implemented support for monochrome in VoxelTree
This commit is contained in:
parent
af7057619a
commit
777dd6dc53
4 changed files with 133 additions and 28 deletions
42
libraries/shared/src/PointerStack.cpp
Normal file
42
libraries/shared/src/PointerStack.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// PointerStack.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 5/11/2013
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "PointerStack.h"
|
||||
#include <stdio.h>
|
||||
|
||||
PointerStack::~PointerStack() {
|
||||
deleteAll();
|
||||
}
|
||||
|
||||
void PointerStack::deleteAll() {
|
||||
if (_elements) {
|
||||
delete[] _elements;
|
||||
}
|
||||
_elements = NULL;
|
||||
_elementsInUse = 0;
|
||||
_sizeOfElementsArray = 0;
|
||||
}
|
||||
|
||||
const int GROW_BY = 100;
|
||||
|
||||
void PointerStack::growAndPush(void* element) {
|
||||
//printf("PointerStack::growAndPush() _sizeOfElementsArray=%d",_sizeOfElementsArray);
|
||||
void** oldElements = _elements;
|
||||
_elements = new void* [_sizeOfElementsArray + GROW_BY];
|
||||
_sizeOfElementsArray += GROW_BY;
|
||||
|
||||
// If we had an old stack...
|
||||
if (oldElements) {
|
||||
// copy old elements into the new stack
|
||||
memcpy(_elements, oldElements, _elementsInUse * sizeof(void*));
|
||||
delete[] oldElements;
|
||||
}
|
||||
_elements[_elementsInUse] = element;
|
||||
_elementsInUse++;
|
||||
}
|
||||
|
59
libraries/shared/src/PointerStack.h
Normal file
59
libraries/shared/src/PointerStack.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// PointerStack.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 4/25/2013
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__PointerStack__
|
||||
#define __hifi__PointerStack__
|
||||
|
||||
#include <cstring> // for NULL
|
||||
|
||||
class PointerStack {
|
||||
|
||||
public:
|
||||
PointerStack() :
|
||||
_elements(NULL),
|
||||
_elementsInUse(0),
|
||||
_sizeOfElementsArray(0) {};
|
||||
|
||||
~PointerStack();
|
||||
|
||||
void push(void* element) {
|
||||
if (_sizeOfElementsArray < _elementsInUse + 1) {
|
||||
return growAndPush(element);
|
||||
}
|
||||
_elements[_elementsInUse] = element;
|
||||
_elementsInUse++;
|
||||
};
|
||||
|
||||
void* pop() {
|
||||
if (_elementsInUse) {
|
||||
// get the last element
|
||||
void* element = _elements[_elementsInUse - 1];
|
||||
// reduce the count
|
||||
_elementsInUse--;
|
||||
return element;
|
||||
}
|
||||
return NULL;
|
||||
};
|
||||
|
||||
|
||||
void* top() const { return (_elementsInUse) ? _elements[_elementsInUse - 1] : NULL; }
|
||||
bool isEmpty() const { return (_elementsInUse == 0); };
|
||||
bool empty() const { return (_elementsInUse == 0); };
|
||||
int count() const { return _elementsInUse; };
|
||||
int size() const { return _elementsInUse; };
|
||||
|
||||
private:
|
||||
void growAndPush(void* element);
|
||||
void deleteAll();
|
||||
void** _elements;
|
||||
int _elementsInUse;
|
||||
int _sizeOfElementsArray;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__PointerStack__) */
|
|
@ -115,7 +115,7 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char
|
|||
}
|
||||
}
|
||||
|
||||
int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead) {
|
||||
int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead, bool includeColor) {
|
||||
// instantiate variable for bytes already read
|
||||
int bytesRead = 1;
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
|
@ -133,9 +133,11 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
|||
}
|
||||
|
||||
// pull the color for this child
|
||||
nodeColor newColor;
|
||||
memcpy(newColor, nodeData + bytesRead, 3);
|
||||
newColor[3] = 1;
|
||||
nodeColor newColor = { 128, 128, 128, 1};
|
||||
if (includeColor) {
|
||||
memcpy(newColor, nodeData + bytesRead, 3);
|
||||
bytesRead += 3;
|
||||
}
|
||||
bool nodeWasDirty = destinationNode->getChildAtIndex(i)->isDirty();
|
||||
destinationNode->getChildAtIndex(i)->setColor(newColor);
|
||||
bool nodeIsDirty = destinationNode->getChildAtIndex(i)->isDirty();
|
||||
|
@ -147,8 +149,6 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
|||
}
|
||||
this->voxelsColored++;
|
||||
this->voxelsColoredStats.updateAverage(1);
|
||||
|
||||
bytesRead += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
|||
// tell the child to read the subsequent data
|
||||
bytesRead += readNodeData(destinationNode->getChildAtIndex(childIndex),
|
||||
nodeData + bytesRead,
|
||||
bytesLeftToRead - bytesRead);
|
||||
bytesLeftToRead - bytesRead, includeColor);
|
||||
}
|
||||
|
||||
childIndex++;
|
||||
|
@ -189,7 +189,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
|||
return bytesRead;
|
||||
}
|
||||
|
||||
void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes) {
|
||||
void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor) {
|
||||
int bytesRead = 0;
|
||||
unsigned char* bitstreamAt = bitstream;
|
||||
|
||||
|
@ -218,7 +218,7 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int
|
|||
int theseBytesRead = 0;
|
||||
theseBytesRead += octalCodeBytes;
|
||||
theseBytesRead += readNodeData(bitstreamRootNode, bitstreamAt + octalCodeBytes,
|
||||
bufferSizeBytes - (bytesRead + octalCodeBytes));
|
||||
bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor);
|
||||
|
||||
// skip bitstream to new startPoint
|
||||
bitstreamAt += theseBytesRead;
|
||||
|
@ -719,7 +719,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
|
|||
}
|
||||
|
||||
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const {
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const {
|
||||
|
||||
// How many bytes have we written so far at this level;
|
||||
int bytesWritten = 0;
|
||||
|
@ -739,14 +739,14 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
|||
|
||||
int currentEncodeLevel = 0;
|
||||
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel,
|
||||
node, outputBuffer, availableBytes, bag, viewFrustum);
|
||||
node, outputBuffer, availableBytes, bag, viewFrustum, includeColor);
|
||||
|
||||
// if childBytesWritten == 1 then something went wrong... that's not possible
|
||||
assert(childBytesWritten != 1);
|
||||
|
||||
// if childBytesWritten == 2, then it can only mean that the lower level trees don't exist or for some reason
|
||||
// couldn't be written... so reset them here...
|
||||
if (childBytesWritten == 2) {
|
||||
// if includeColor and childBytesWritten == 2, then it can only mean that the lower level trees don't exist or for some reason
|
||||
// couldn't be written... so reset them here... This isn't true for the non-color included case
|
||||
if (includeColor && childBytesWritten == 2) {
|
||||
childBytesWritten = 0;
|
||||
}
|
||||
|
||||
|
@ -762,7 +762,7 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
|||
|
||||
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||
VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const {
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const {
|
||||
// How many bytes have we written so far at this level;
|
||||
int bytesAtThisLevel = 0;
|
||||
|
||||
|
@ -847,11 +847,13 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count
|
||||
|
||||
// write the color data...
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
if (oneAtBit(childrenColoredBits, i)) {
|
||||
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
|
||||
if (includeColor) {
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
if (oneAtBit(childrenColoredBits, i)) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
// write the child exist bits
|
||||
|
@ -894,7 +896,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
|
||||
int thisLevel = currentEncodeLevel;
|
||||
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
|
||||
outputBuffer, availableBytes, bag, viewFrustum);
|
||||
outputBuffer, availableBytes, bag,
|
||||
viewFrustum, includeColor);
|
||||
|
||||
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
|
||||
// basically, the children below don't contain any info.
|
||||
|
@ -912,7 +915,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
|||
// so, if the child returns 2 bytes out, we can actually consider that an empty tree also!!
|
||||
//
|
||||
// we can make this act like no bytes out, by just resetting the bytes out in this case
|
||||
if (childTreeBytesOut == 2) {
|
||||
if (includeColor && childTreeBytesOut == 2) {
|
||||
childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees
|
||||
}
|
||||
|
||||
|
@ -947,7 +950,7 @@ bool VoxelTree::readFromFileV2(const char* fileName) {
|
|||
// read the entire file into a buffer, WHAT!? Why not.
|
||||
unsigned char* entireFile = new unsigned char[fileLength];
|
||||
file.read((char*)entireFile, fileLength);
|
||||
readBitstreamToTree(entireFile, fileLength);
|
||||
readBitstreamToTree(entireFile, fileLength, true);
|
||||
delete[] entireFile;
|
||||
|
||||
file.close();
|
||||
|
@ -971,7 +974,8 @@ void VoxelTree::writeToFileV2(const char* fileName) const {
|
|||
|
||||
while (!nodeBag.isEmpty()) {
|
||||
VoxelNode* subTree = nodeBag.extract();
|
||||
bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeBag, NULL);
|
||||
bytesWritten = encodeTreeBitstream(INT_MAX, subTree, &outputBuffer[0],
|
||||
MAX_VOXEL_PACKET_SIZE - 1, nodeBag, NULL, true);
|
||||
|
||||
file.write((const char*)&outputBuffer[0], bytesWritten);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
void eraseAllVoxels();
|
||||
|
||||
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
|
||||
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes);
|
||||
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor = true);
|
||||
void readCodeColorBufferToTree(unsigned char *codeColorBuffer);
|
||||
void deleteVoxelCodeFromTree(unsigned char *codeBuffer);
|
||||
void printTreeForDebugging(VoxelNode *startNode);
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
|
||||
|
||||
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const;
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor = true) const;
|
||||
|
||||
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag);
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
private:
|
||||
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||
VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum) const;
|
||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor) const;
|
||||
|
||||
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
|
||||
VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag);
|
||||
|
@ -89,7 +89,7 @@ private:
|
|||
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
|
||||
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;
|
||||
VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate);
|
||||
int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes);
|
||||
int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes, bool includeColor = true);
|
||||
|
||||
bool _isDirty;
|
||||
unsigned long int _nodesChangedFromBitstream;
|
||||
|
|
Loading…
Reference in a new issue