mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:51:20 +02:00
first cut at exists bits
This commit is contained in:
parent
b06cc60665
commit
321d1952d6
11 changed files with 208 additions and 55 deletions
|
@ -1106,6 +1106,10 @@ void Application::setWantsResIn(bool wantsResIn) {
|
||||||
_myAvatar.setWantResIn(wantsResIn);
|
_myAvatar.setWantResIn(wantsResIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::setWantsExistsBits(bool wantsExistsBits) {
|
||||||
|
_myAvatar.setWantExistsBits(wantsExistsBits);
|
||||||
|
_voxels.setWantExistsBits(wantsExistsBits);
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setWantsDelta(bool wantsDelta) {
|
void Application::setWantsDelta(bool wantsDelta) {
|
||||||
_myAvatar.setWantDelta(wantsDelta);
|
_myAvatar.setWantDelta(wantsDelta);
|
||||||
|
@ -1255,7 +1259,7 @@ void Application::initMenu() {
|
||||||
QMenu* debugMenu = menuBar->addMenu("Debug");
|
QMenu* debugMenu = menuBar->addMenu("Debug");
|
||||||
debugMenu->addAction("Show Render Pipeline Warnings", this, SLOT(setRenderWarnings(bool)))->setCheckable(true);
|
debugMenu->addAction("Show Render Pipeline Warnings", this, SLOT(setRenderWarnings(bool)))->setCheckable(true);
|
||||||
debugMenu->addAction("Kill Local Voxels", this, SLOT(doKillLocalVoxels()));
|
debugMenu->addAction("Kill Local Voxels", this, SLOT(doKillLocalVoxels()));
|
||||||
debugMenu->addAction("Randomize Voxel TRUE Colors", this, SLOT(doRandomizeVoxelColors()));
|
debugMenu->addAction("Randomize Voxel TRUE Colors", this, SLOT(doRandomizeVoxelColors()), Qt::CTRL | Qt::Key_R);
|
||||||
debugMenu->addAction("FALSE Color Voxels Randomly", this, SLOT(doFalseRandomizeVoxelColors()));
|
debugMenu->addAction("FALSE Color Voxels Randomly", this, SLOT(doFalseRandomizeVoxelColors()));
|
||||||
debugMenu->addAction("FALSE Color Voxel Every Other Randomly", this, SLOT(doFalseRandomizeEveryOtherVoxelColors()));
|
debugMenu->addAction("FALSE Color Voxel Every Other Randomly", this, SLOT(doFalseRandomizeEveryOtherVoxelColors()));
|
||||||
debugMenu->addAction("FALSE Color Voxels by Distance", this, SLOT(doFalseColorizeByDistance()));
|
debugMenu->addAction("FALSE Color Voxels by Distance", this, SLOT(doFalseColorizeByDistance()));
|
||||||
|
@ -1265,6 +1269,7 @@ void Application::initMenu() {
|
||||||
debugMenu->addAction("Wants Res-In", this, SLOT(setWantsResIn(bool)))->setCheckable(true);
|
debugMenu->addAction("Wants Res-In", this, SLOT(setWantsResIn(bool)))->setCheckable(true);
|
||||||
debugMenu->addAction("Wants Monochrome", this, SLOT(setWantsMonochrome(bool)))->setCheckable(true);
|
debugMenu->addAction("Wants Monochrome", this, SLOT(setWantsMonochrome(bool)))->setCheckable(true);
|
||||||
debugMenu->addAction("Wants View Delta Sending", this, SLOT(setWantsDelta(bool)))->setCheckable(true);
|
debugMenu->addAction("Wants View Delta Sending", this, SLOT(setWantsDelta(bool)))->setCheckable(true);
|
||||||
|
debugMenu->addAction("Wants Exists Bits", this, SLOT(setWantsExistsBits(bool)), Qt::CTRL | Qt::Key_M)->setCheckable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateFrustumRenderModeAction() {
|
void Application::updateFrustumRenderModeAction() {
|
||||||
|
@ -2035,7 +2040,7 @@ void Application::deleteVoxelUnderCursor() {
|
||||||
sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel);
|
sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel);
|
||||||
|
|
||||||
// delete the voxel locally so it disappears immediately
|
// delete the voxel locally so it disappears immediately
|
||||||
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
//_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||||
|
|
||||||
// remember the position for drag detection
|
// remember the position for drag detection
|
||||||
_lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
|
_lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
|
||||||
|
|
|
@ -90,6 +90,7 @@ private slots:
|
||||||
void doTreeStats();
|
void doTreeStats();
|
||||||
void setWantsMonochrome(bool wantsMonochrome);
|
void setWantsMonochrome(bool wantsMonochrome);
|
||||||
void setWantsResIn(bool wantsResIn);
|
void setWantsResIn(bool wantsResIn);
|
||||||
|
void setWantsExistsBits(bool wantsExistsBits);
|
||||||
void setWantsDelta(bool wantsDelta);
|
void setWantsDelta(bool wantsDelta);
|
||||||
void updateVoxelModeActions();
|
void updateVoxelModeActions();
|
||||||
void addVoxelInFrontOfAvatar();
|
void addVoxelInFrontOfAvatar();
|
||||||
|
|
|
@ -102,21 +102,25 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
switch(command) {
|
switch(command) {
|
||||||
case PACKET_HEADER_VOXEL_DATA:
|
case PACKET_HEADER_VOXEL_DATA:
|
||||||
{
|
{
|
||||||
|
//printLog("PACKET_HEADER_VOXEL_DATA voxelData=");
|
||||||
|
//outputBufferBits(sourceBuffer, numBytes);
|
||||||
|
|
||||||
PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()");
|
PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()");
|
||||||
// ask the VoxelTree to read the bitstream into the tree
|
// ask the VoxelTree to read the bitstream into the tree
|
||||||
_tree->readBitstreamToTree(voxelData, numBytes - 1);
|
_tree->readBitstreamToTree(voxelData, numBytes - 1, true, _wantsExistBits);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PACKET_HEADER_VOXEL_DATA_MONOCHROME:
|
case PACKET_HEADER_VOXEL_DATA_MONOCHROME:
|
||||||
{
|
{
|
||||||
PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()");
|
PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()");
|
||||||
// ask the VoxelTree to read the MONOCHROME bitstream into the tree
|
// ask the VoxelTree to read the MONOCHROME bitstream into the tree
|
||||||
_tree->readBitstreamToTree(voxelData, numBytes - 1, false);
|
_tree->readBitstreamToTree(voxelData, numBytes - 1, false, _wantsExistBits);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PACKET_HEADER_ERASE_VOXEL:
|
case PACKET_HEADER_ERASE_VOXEL:
|
||||||
// ask the tree to read the "remove" bitstream
|
// ask the tree to read the "remove" bitstream
|
||||||
_tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);
|
//_tree->processRemoveVoxelBitstream(sourceBuffer, numBytes);
|
||||||
|
//printLog("ignoring PACKET_HEADER_ERASE_VOXEL\n");
|
||||||
break;
|
break;
|
||||||
case PACKET_HEADER_Z_COMMAND:
|
case PACKET_HEADER_Z_COMMAND:
|
||||||
|
|
||||||
|
@ -419,6 +423,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) {
|
||||||
|
|
||||||
void VoxelSystem::init() {
|
void VoxelSystem::init() {
|
||||||
|
|
||||||
|
_wantsExistBits = false;
|
||||||
_renderWarningsOn = false;
|
_renderWarningsOn = false;
|
||||||
_callsToTreesToArrays = 0;
|
_callsToTreesToArrays = 0;
|
||||||
_setupNewVoxelsForDrawingLastFinished = 0;
|
_setupNewVoxelsForDrawingLastFinished = 0;
|
||||||
|
|
|
@ -79,6 +79,9 @@ public:
|
||||||
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
|
void createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive = false);
|
||||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
|
void createSphere(float r,float xc, float yc, float zc, float s, bool solid,
|
||||||
creationMode mode, bool destructive = false, bool debug = false);
|
creationMode mode, bool destructive = false, bool debug = false);
|
||||||
|
|
||||||
|
void setWantExistsBits(bool on) { _wantsExistBits = on; };
|
||||||
|
bool getWantExistsBits() const { return _wantsExistBits; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// disallow copying of VoxelSystem objects
|
// disallow copying of VoxelSystem objects
|
||||||
|
@ -151,6 +154,8 @@ private:
|
||||||
void copyWrittenDataToReadArrays();
|
void copyWrittenDataToReadArrays();
|
||||||
|
|
||||||
bool _voxelsDirty;
|
bool _voxelsDirty;
|
||||||
|
|
||||||
|
bool _wantsExistBits;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void updateVBOs();
|
void updateVBOs();
|
||||||
|
|
|
@ -128,9 +128,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
// voxel sending features...
|
// voxel sending features...
|
||||||
// voxel sending features...
|
// voxel sending features...
|
||||||
unsigned char wantItems = 0;
|
unsigned char wantItems = 0;
|
||||||
if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); }
|
if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); }
|
||||||
if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); }
|
if (_wantExistsBits) { setAtBit(wantItems,WANT_EXISTS_BITS_BIT); }
|
||||||
if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); }
|
if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); }
|
||||||
|
if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); }
|
||||||
*destinationBuffer++ = wantItems;
|
*destinationBuffer++ = wantItems;
|
||||||
|
|
||||||
return destinationBuffer - bufferStart;
|
return destinationBuffer - bufferStart;
|
||||||
|
@ -210,11 +211,11 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
// voxel sending features...
|
// voxel sending features...
|
||||||
unsigned char wantItems = 0;
|
unsigned char wantItems = 0;
|
||||||
wantItems = (unsigned char)*sourceBuffer++;
|
wantItems = (unsigned char)*sourceBuffer++;
|
||||||
|
_wantResIn = oneAtBit(wantItems,WANT_RESIN_AT_BIT);
|
||||||
|
_wantExistsBits = oneAtBit(wantItems,WANT_EXISTS_BITS_BIT);
|
||||||
|
_wantColor = oneAtBit(wantItems,WANT_COLOR_AT_BIT);
|
||||||
|
_wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT);
|
||||||
|
|
||||||
_wantResIn = oneAtBit(wantItems,WANT_RESIN_AT_BIT);
|
|
||||||
_wantColor = oneAtBit(wantItems,WANT_COLOR_AT_BIT);
|
|
||||||
_wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT);
|
|
||||||
|
|
||||||
return sourceBuffer - startPosition;
|
return sourceBuffer - startPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,4 +224,4 @@ void AvatarData::setHeadPitch(float p) {
|
||||||
const float MAX_PITCH = 60;
|
const float MAX_PITCH = 60;
|
||||||
const float MIN_PITCH = -60;
|
const float MIN_PITCH = -60;
|
||||||
_headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH);
|
_headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,4 +80,8 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex,
|
||||||
void** valueArray, float* keyArray, int* originalIndexArray,
|
void** valueArray, float* keyArray, int* originalIndexArray,
|
||||||
int currentCount, int maxCount);
|
int currentCount, int maxCount);
|
||||||
|
|
||||||
|
class debugHelpers {
|
||||||
|
public:
|
||||||
|
static const char* booleanValue(bool checkValue) { return checkValue ? "yes" : "no"; };
|
||||||
|
};
|
||||||
#endif /* defined(__hifi__SharedUtil__) */
|
#endif /* defined(__hifi__SharedUtil__) */
|
||||||
|
|
|
@ -242,8 +242,20 @@ void VoxelNode::setRandomColor(int minimumBrightness) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelNode::printDebugDetails(const char* label) const {
|
void VoxelNode::printDebugDetails(const char* label) const {
|
||||||
printLog("%s - Voxel at corner=(%f,%f,%f) size=%f octcode=", label,
|
unsigned char childBits = 0;
|
||||||
_box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getSize().x);
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
|
if (_children[i]) {
|
||||||
|
setAtBit(childBits,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printLog("%s - Voxel at corner=(%f,%f,%f) size=%f\n isLeaf=%s isColored=%s isDirty=%s shouldRender=%s\n children=", label,
|
||||||
|
_box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getSize().x,
|
||||||
|
debugHelpers::booleanValue(isLeaf()), debugHelpers::booleanValue(isColored()), debugHelpers::booleanValue(isDirty()),
|
||||||
|
debugHelpers::booleanValue(getShouldRender()) );
|
||||||
|
|
||||||
|
outputBits(childBits,false);
|
||||||
|
printLog("\n octalCode=");
|
||||||
printOctalCode(_octalCode);
|
printOctalCode(_octalCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,15 +103,22 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char
|
||||||
int indexOfNewChild = branchIndexWithDescendant(lastParentNode->getOctalCode(), codeToReach);
|
int indexOfNewChild = branchIndexWithDescendant(lastParentNode->getOctalCode(), codeToReach);
|
||||||
|
|
||||||
// we could be coming down a branch that was already created, so don't stomp on it.
|
// we could be coming down a branch that was already created, so don't stomp on it.
|
||||||
|
if (!lastParentNode->getChildAtIndex(indexOfNewChild)) {
|
||||||
|
lastParentNode->addChildAtIndex(indexOfNewChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
if (lastParentNode->isLeaf() && lastParentNode->isColored()) {
|
if (lastParentNode->isLeaf() && lastParentNode->isColored()) {
|
||||||
// for colored leaves, we must add *all* the children
|
// for colored leaves, we must add *all* the children
|
||||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
|
printLog(">>>>>>>> createMissingNode() add *all* the children - calling addChildAtIndex() at %d <<<<<<<\n",i);
|
||||||
lastParentNode->addChildAtIndex(i);
|
lastParentNode->addChildAtIndex(i);
|
||||||
lastParentNode->getChildAtIndex(i)->setColor(lastParentNode->getColor());
|
lastParentNode->getChildAtIndex(i)->setColor(lastParentNode->getColor());
|
||||||
}
|
}
|
||||||
} else if (!lastParentNode->getChildAtIndex(indexOfNewChild)) {
|
} else if (!lastParentNode->getChildAtIndex(indexOfNewChild)) {
|
||||||
lastParentNode->addChildAtIndex(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
|
// 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->getChildAtIndex(indexOfNewChild)->getOctalCode() == *codeToReach) {
|
if (*lastParentNode->getChildAtIndex(indexOfNewChild)->getOctalCode() == *codeToReach) {
|
||||||
|
@ -121,14 +128,28 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead, bool includeColor) {
|
int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, int bytesLeftToRead,
|
||||||
|
bool includeColor, bool includeExistsBits) {
|
||||||
|
|
||||||
|
|
||||||
|
if (includeExistsBits) {
|
||||||
|
//printLog("readNodeData() expecting includeExistsBits\n");
|
||||||
|
}
|
||||||
|
// give this destination node the child mask from the packet
|
||||||
|
const unsigned char ALL_CHILDREN_ASSUMED_TO_EXIST = 0xFF;
|
||||||
|
unsigned char colorInPacketMask = *nodeData;
|
||||||
|
unsigned char colorInTreeMask = includeExistsBits ? *(nodeData+1) : ALL_CHILDREN_ASSUMED_TO_EXIST;
|
||||||
|
|
||||||
// instantiate variable for bytes already read
|
// instantiate variable for bytes already read
|
||||||
int bytesRead = 1;
|
int bytesRead = includeExistsBits ? 2 : 1;
|
||||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
// check the colors mask to see if we have a child to color in
|
// check the colors mask to see if we have a child to color in
|
||||||
if (oneAtBit(*nodeData, i)) {
|
if (oneAtBit(colorInPacketMask, i)) {
|
||||||
// create the child if it doesn't exist
|
// create the child if it doesn't exist
|
||||||
if (!destinationNode->getChildAtIndex(i)) {
|
if (!destinationNode->getChildAtIndex(i)) {
|
||||||
|
//printLog(">>>>>>>> readNodeData() colorInPacketMask area -- calling addChildAtIndex() at %d colorInTreeBitSet=%s<<<<<<<\n",i,
|
||||||
|
// debugHelpers::booleanValue(oneAtBit(colorInTreeMask, i)));
|
||||||
|
|
||||||
destinationNode->addChildAtIndex(i);
|
destinationNode->addChildAtIndex(i);
|
||||||
if (destinationNode->isDirty()) {
|
if (destinationNode->isDirty()) {
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
|
@ -156,13 +177,27 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
||||||
this->voxelsColored++;
|
this->voxelsColored++;
|
||||||
this->voxelsColoredStats.updateAverage(1);
|
this->voxelsColoredStats.updateAverage(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now also check the colorInTreeMask, if the mask is missing the bit, then it means we need to delete this child
|
||||||
|
// node, because it shouldn't actually exist in the tree.
|
||||||
|
/**
|
||||||
|
if (!oneAtBit(colorInTreeMask, i) && destinationNode->getChildAtIndex(i) &&
|
||||||
|
destinationNode->getChildAtIndex(i)->isColored()) {
|
||||||
|
|
||||||
|
destinationNode->printDebugDetails("colorInTreeMask mismatch ");
|
||||||
|
// we should delete this node!!!
|
||||||
|
printLog("colorInTreeMask for child %d missing, should delete this node? colorInTreeMask=",i);
|
||||||
|
outputBits(colorInTreeMask, true);
|
||||||
|
}
|
||||||
|
**/
|
||||||
}
|
}
|
||||||
|
|
||||||
// give this destination node the child mask from the packet
|
// give this destination node the child mask from the packet
|
||||||
unsigned char childMask = *(nodeData + bytesRead);
|
unsigned char childrenInTreeMask = includeExistsBits ? *(nodeData + bytesRead) : ALL_CHILDREN_ASSUMED_TO_EXIST;
|
||||||
|
unsigned char childMask = *(nodeData + bytesRead + (includeExistsBits ? 1 : 0) );
|
||||||
|
|
||||||
int childIndex = 0;
|
int childIndex = 0;
|
||||||
bytesRead++;
|
bytesRead += includeExistsBits ? 2 : 1;
|
||||||
|
|
||||||
while (bytesLeftToRead - bytesRead > 0 && childIndex < NUMBER_OF_CHILDREN) {
|
while (bytesLeftToRead - bytesRead > 0 && childIndex < NUMBER_OF_CHILDREN) {
|
||||||
// check the exists mask to see if we have a child to traverse into
|
// check the exists mask to see if we have a child to traverse into
|
||||||
|
@ -171,6 +206,10 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
||||||
if (!destinationNode->getChildAtIndex(childIndex)) {
|
if (!destinationNode->getChildAtIndex(childIndex)) {
|
||||||
// add a child at that index, if it doesn't exist
|
// add a child at that index, if it doesn't exist
|
||||||
bool nodeWasDirty = destinationNode->isDirty();
|
bool nodeWasDirty = destinationNode->isDirty();
|
||||||
|
//printLog(">>>>>>>> readNodeData() childMask area -- calling addChildAtIndex() at %d colorInTreeBitSet=%s<<<<<<<\n",childIndex,
|
||||||
|
// debugHelpers::booleanValue(oneAtBit(childrenInTreeMask, childIndex)));
|
||||||
|
|
||||||
|
|
||||||
destinationNode->addChildAtIndex(childIndex);
|
destinationNode->addChildAtIndex(childIndex);
|
||||||
bool nodeIsDirty = destinationNode->isDirty();
|
bool nodeIsDirty = destinationNode->isDirty();
|
||||||
if (nodeIsDirty) {
|
if (nodeIsDirty) {
|
||||||
|
@ -185,17 +224,38 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData,
|
||||||
|
|
||||||
// tell the child to read the subsequent data
|
// tell the child to read the subsequent data
|
||||||
bytesRead += readNodeData(destinationNode->getChildAtIndex(childIndex),
|
bytesRead += readNodeData(destinationNode->getChildAtIndex(childIndex),
|
||||||
nodeData + bytesRead,
|
nodeData + bytesRead, bytesLeftToRead - bytesRead, includeColor, includeExistsBits);
|
||||||
bytesLeftToRead - bytesRead, includeColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
childIndex++;
|
childIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
|
// now also check the childrenInTreeMask, if the mask is missing the bit, then it means we need to delete this child
|
||||||
|
// subtree/node, because it shouldn't actually exist in the tree.
|
||||||
|
if (!oneAtBit(childrenInTreeMask, i) && destinationNode->getChildAtIndex(i)) {
|
||||||
|
// we should delete this node!!!
|
||||||
|
//destinationNode->printDebugDetails("childrenInTreeMask mismatch ");
|
||||||
|
//printLog("childrenInTreeMask for child %d missing, should delete this node? childrenInTreeMask=",i);
|
||||||
|
//outputBits(childrenInTreeMask, true);
|
||||||
|
|
||||||
|
// If this node has a VBO index, then we can only stage it for deletion, otherwise delete away!
|
||||||
|
if (destinationNode->getChildAtIndex(i)->isKnownBufferIndex()) {
|
||||||
|
printLog("childrenInTreeMask for child %d missing, staging for deletion\n",i);
|
||||||
|
destinationNode->getChildAtIndex(i)->stageForDeletion();
|
||||||
|
_isDirty = true;
|
||||||
|
} else {
|
||||||
|
printLog("childrenInTreeMask for child %d missing, deleting now\n",i);
|
||||||
|
destinationNode->deleteChildAtIndex(i);
|
||||||
|
_isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor) {
|
void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes,
|
||||||
|
bool includeColor, bool includeExistsBits) {
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
unsigned char* bitstreamAt = bitstream;
|
unsigned char* bitstreamAt = bitstream;
|
||||||
|
|
||||||
|
@ -224,7 +284,7 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int
|
||||||
int theseBytesRead = 0;
|
int theseBytesRead = 0;
|
||||||
theseBytesRead += octalCodeBytes;
|
theseBytesRead += octalCodeBytes;
|
||||||
theseBytesRead += readNodeData(bitstreamRootNode, bitstreamAt + octalCodeBytes,
|
theseBytesRead += readNodeData(bitstreamRootNode, bitstreamAt + octalCodeBytes,
|
||||||
bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor);
|
bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor, includeExistsBits);
|
||||||
|
|
||||||
// skip bitstream to new startPoint
|
// skip bitstream to new startPoint
|
||||||
bitstreamAt += theseBytesRead;
|
bitstreamAt += theseBytesRead;
|
||||||
|
@ -245,6 +305,7 @@ void VoxelTree::deleteVoxelAt(float x, float y, float z, float s, bool stage) {
|
||||||
// Note: uses the codeColorBuffer format, but the color's are ignored, because
|
// Note: uses the codeColorBuffer format, but the color's are ignored, because
|
||||||
// this only finds and deletes the node from the tree.
|
// this only finds and deletes the node from the tree.
|
||||||
void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) {
|
void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) {
|
||||||
|
//printLog(">>>>>>>> deleteVoxelCodeFromTree() <<<<<<<\n");
|
||||||
VoxelNode* parentNode = NULL;
|
VoxelNode* parentNode = NULL;
|
||||||
VoxelNode* nodeToDelete = nodeForOctalCode(rootNode, codeBuffer, &parentNode);
|
VoxelNode* nodeToDelete = nodeForOctalCode(rootNode, codeBuffer, &parentNode);
|
||||||
|
|
||||||
|
@ -271,6 +332,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) {
|
||||||
int index = branchIndexWithDescendant(ancestorNode->getOctalCode(), codeBuffer);
|
int index = branchIndexWithDescendant(ancestorNode->getOctalCode(), codeBuffer);
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
if (i != index) {
|
if (i != index) {
|
||||||
|
//printLog(">>>>>>>> deleteVoxelCodeFromTree() calling addChildAtIndex() at %d <<<<<<<\n",i);
|
||||||
ancestorNode->addChildAtIndex(i);
|
ancestorNode->addChildAtIndex(i);
|
||||||
ancestorNode->getChildAtIndex(i)->setColor(nodeToDelete->getColor());
|
ancestorNode->getChildAtIndex(i)->setColor(nodeToDelete->getColor());
|
||||||
}
|
}
|
||||||
|
@ -278,6 +340,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) {
|
||||||
if (*ancestorNode->getOctalCode() == *codeBuffer - 1) {
|
if (*ancestorNode->getOctalCode() == *codeBuffer - 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//printLog(">>>>>>>> deleteVoxelCodeFromTree() calling addChildAtIndex() at %d <<<<<<<\n",index);
|
||||||
ancestorNode->addChildAtIndex(index);
|
ancestorNode->addChildAtIndex(index);
|
||||||
ancestorNode = ancestorNode->getChildAtIndex(index);
|
ancestorNode = ancestorNode->getChildAtIndex(index);
|
||||||
ancestorNode->setColor(nodeToDelete->getColor());
|
ancestorNode->setColor(nodeToDelete->getColor());
|
||||||
|
@ -764,7 +827,7 @@ int VoxelTree::searchForColoredNodesRecursion(int maxSearchLevel, int& currentSe
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
|
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
|
||||||
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
|
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
|
||||||
|
|
||||||
// How many bytes have we written so far at this level;
|
// How many bytes have we written so far at this level;
|
||||||
|
@ -784,8 +847,8 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
||||||
availableBytes -= codeLength; // keep track or remaining space
|
availableBytes -= codeLength; // keep track or remaining space
|
||||||
|
|
||||||
int currentEncodeLevel = 0;
|
int currentEncodeLevel = 0;
|
||||||
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel,
|
int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, node, outputBuffer, availableBytes,
|
||||||
node, outputBuffer, availableBytes, bag, viewFrustum, includeColor,
|
bag, viewFrustum, includeColor, includeExistsBits,
|
||||||
deltaViewFrustum, lastViewFrustum);
|
deltaViewFrustum, lastViewFrustum);
|
||||||
|
|
||||||
// if childBytesWritten == 1 then something went wrong... that's not possible
|
// if childBytesWritten == 1 then something went wrong... that's not possible
|
||||||
|
@ -807,9 +870,9 @@ int VoxelTree::encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node,
|
||||||
VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
||||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
|
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
|
||||||
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
|
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const {
|
||||||
// How many bytes have we written so far at this level;
|
// How many bytes have we written so far at this level;
|
||||||
int bytesAtThisLevel = 0;
|
int bytesAtThisLevel = 0;
|
||||||
|
@ -855,7 +918,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
unsigned char thisLevelBuffer[MAX_LEVEL_BYTES];
|
unsigned char thisLevelBuffer[MAX_LEVEL_BYTES];
|
||||||
unsigned char* writeToThisLevelBuffer = &thisLevelBuffer[0];
|
unsigned char* writeToThisLevelBuffer = &thisLevelBuffer[0];
|
||||||
|
|
||||||
unsigned char childrenExistBits = 0;
|
unsigned char childrenExistInTreeBits = 0;
|
||||||
|
unsigned char colorsExistInTreeBits = 0;
|
||||||
|
unsigned char childrenExistInPacketBits = 0;
|
||||||
unsigned char childrenColoredBits = 0;
|
unsigned char childrenColoredBits = 0;
|
||||||
int inViewCount = 0;
|
int inViewCount = 0;
|
||||||
int inViewNotLeafCount = 0;
|
int inViewNotLeafCount = 0;
|
||||||
|
@ -865,6 +930,16 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
// add them to our distance ordered array of children
|
// add them to our distance ordered array of children
|
||||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||||
|
|
||||||
|
// if the caller wants to include childExistsBits, then include them even if not in view
|
||||||
|
if (includeExistsBits && childNode) {
|
||||||
|
//printLog("includeExistsBits, calculating exists bits\n");
|
||||||
|
childrenExistInTreeBits += (1 << (7 - i));
|
||||||
|
if (childNode->isColored()) {
|
||||||
|
colorsExistInTreeBits += (1 << (7 - i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
|
bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum)));
|
||||||
|
|
||||||
if (childIsInView) {
|
if (childIsInView) {
|
||||||
|
@ -879,7 +954,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
// we don't care about recursing deeper on them, and we don't consider their
|
// we don't care about recursing deeper on them, and we don't consider their
|
||||||
// subtree to exist
|
// subtree to exist
|
||||||
if (!(childNode && childNode->isLeaf())) {
|
if (!(childNode && childNode->isLeaf())) {
|
||||||
childrenExistBits += (1 << (7 - i));
|
childrenExistInPacketBits += (1 << (7 - i));
|
||||||
inViewNotLeafCount++;
|
inViewNotLeafCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,6 +972,20 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
*writeToThisLevelBuffer = childrenColoredBits;
|
*writeToThisLevelBuffer = childrenColoredBits;
|
||||||
writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer
|
writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer
|
||||||
bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count
|
bytesAtThisLevel += sizeof(childrenColoredBits); // keep track of byte count
|
||||||
|
// if the caller wants to include childExistsBits, then include them even if not in view
|
||||||
|
if (includeExistsBits) {
|
||||||
|
printLog("includeExistsBits, writing color exists bits...\n");
|
||||||
|
printLog("childrenColoredBits=");
|
||||||
|
outputBits(childrenColoredBits);
|
||||||
|
printLog(" colorsExistInTreeBits=");
|
||||||
|
outputBits(colorsExistInTreeBits);
|
||||||
|
printLog(" childrenExistInTreeBits=");
|
||||||
|
outputBits(childrenExistInTreeBits);
|
||||||
|
|
||||||
|
*writeToThisLevelBuffer = colorsExistInTreeBits;
|
||||||
|
writeToThisLevelBuffer += sizeof(colorsExistInTreeBits); // move the pointer
|
||||||
|
bytesAtThisLevel += sizeof(colorsExistInTreeBits); // keep track of byte count
|
||||||
|
}
|
||||||
|
|
||||||
// write the color data...
|
// write the color data...
|
||||||
if (includeColor) {
|
if (includeColor) {
|
||||||
|
@ -908,12 +997,21 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// write the child exist bits
|
|
||||||
*writeToThisLevelBuffer = childrenExistBits;
|
|
||||||
|
|
||||||
writeToThisLevelBuffer += sizeof(childrenExistBits); // move the pointer
|
// if the caller wants to include childExistsBits, then include them even if not in view, put them before the
|
||||||
bytesAtThisLevel += sizeof(childrenExistBits); // keep track of byte count
|
// childrenExistInPacketBits, so that the lower code can properly repair the packet exists bits
|
||||||
|
if (includeExistsBits) {
|
||||||
|
printLog("includeExistsBits, writing subtree exists bits\n");
|
||||||
|
*writeToThisLevelBuffer = childrenExistInTreeBits;
|
||||||
|
writeToThisLevelBuffer += sizeof(childrenExistInTreeBits); // move the pointer
|
||||||
|
bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the child exist bits
|
||||||
|
*writeToThisLevelBuffer = childrenExistInPacketBits;
|
||||||
|
writeToThisLevelBuffer += sizeof(childrenExistInPacketBits); // move the pointer
|
||||||
|
bytesAtThisLevel += sizeof(childrenExistInPacketBits); // keep track of byte count
|
||||||
|
|
||||||
// We only need to keep digging, if there is at least one child that is inView, and not a leaf.
|
// We only need to keep digging, if there is at least one child that is inView, and not a leaf.
|
||||||
keepDiggingDeeper = (inViewNotLeafCount > 0);
|
keepDiggingDeeper = (inViewNotLeafCount > 0);
|
||||||
|
|
||||||
|
@ -933,23 +1031,23 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
// and we need to determine if there's a deeper tree below them that we care about.
|
// and we need to determine if there's a deeper tree below them that we care about.
|
||||||
//
|
//
|
||||||
// Since this recursive function assumes we're already writing, we know we've already written our
|
// Since this recursive function assumes we're already writing, we know we've already written our
|
||||||
// childrenExistBits. But... we don't really know how big the child tree will be. And we don't know if
|
// childrenExistInPacketBits. But... we don't really know how big the child tree will be. And we don't know if
|
||||||
// we'll have room in our buffer to actually write all these child trees. What we kinda would like to do is
|
// we'll have room in our buffer to actually write all these child trees. What we kinda would like to do is
|
||||||
// write our childExistsBits as a place holder. Then let each potential tree have a go at it. If they
|
// write our childExistsBits as a place holder. Then let each potential tree have a go at it. If they
|
||||||
// write something, we keep them in the bits, if they don't, we take them out.
|
// write something, we keep them in the bits, if they don't, we take them out.
|
||||||
//
|
//
|
||||||
// we know the last thing we wrote to the outputBuffer was our childrenExistBits. Let's remember where that was!
|
// we know the last thing we wrote to the outputBuffer was our childrenExistInPacketBits. Let's remember where that was!
|
||||||
unsigned char* childExistsPlaceHolder = outputBuffer-sizeof(childrenExistBits);
|
unsigned char* childExistsPlaceHolder = outputBuffer-sizeof(childrenExistInPacketBits);
|
||||||
|
|
||||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||||
|
|
||||||
if (oneAtBit(childrenExistBits, i)) {
|
if (oneAtBit(childrenExistInPacketBits, i)) {
|
||||||
VoxelNode* childNode = node->getChildAtIndex(i);
|
VoxelNode* childNode = node->getChildAtIndex(i);
|
||||||
|
|
||||||
int thisLevel = currentEncodeLevel;
|
int thisLevel = currentEncodeLevel;
|
||||||
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
|
int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode,
|
||||||
outputBuffer, availableBytes, bag,
|
outputBuffer, availableBytes, bag,
|
||||||
viewFrustum, includeColor,
|
viewFrustum, includeColor, includeExistsBits,
|
||||||
deltaViewFrustum, lastViewFrustum);
|
deltaViewFrustum, lastViewFrustum);
|
||||||
|
|
||||||
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
|
// if the child wrote 0 bytes, it means that nothing below exists or was in view, or we ran out of space,
|
||||||
|
@ -970,6 +1068,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
// we can make this act like no bytes out, by just resetting the bytes out in this case
|
// we can make this act like no bytes out, by just resetting the bytes out in this case
|
||||||
if (includeColor && childTreeBytesOut == 2) {
|
if (includeColor && childTreeBytesOut == 2) {
|
||||||
childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees
|
childTreeBytesOut = 0; // this is the degenerate case of a tree with no colors and no child trees
|
||||||
|
printLog("childTreeBytesOut==2.... lopping empty lower tree\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesAtThisLevel += childTreeBytesOut;
|
bytesAtThisLevel += childTreeBytesOut;
|
||||||
|
@ -979,15 +1078,17 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco
|
||||||
// If we had previously started writing, and if the child DIDN'T write any bytes,
|
// If we had previously started writing, and if the child DIDN'T write any bytes,
|
||||||
// then we want to remove their bit from the childExistsPlaceHolder bitmask
|
// then we want to remove their bit from the childExistsPlaceHolder bitmask
|
||||||
if (childTreeBytesOut == 0) {
|
if (childTreeBytesOut == 0) {
|
||||||
|
printLog("childTreeBytesOut == 0... actually lopping empty lower tree\n");
|
||||||
// remove this child's bit...
|
// remove this child's bit...
|
||||||
childrenExistBits -= (1 << (7 - i));
|
childrenExistInPacketBits -= (1 << (7 - i));
|
||||||
// repair the child exists mask
|
// repair the child exists mask
|
||||||
*childExistsPlaceHolder = childrenExistBits;
|
*childExistsPlaceHolder = childrenExistInPacketBits;
|
||||||
// Note: no need to move the pointer, cause we already stored this
|
// Note: no need to move the pointer, cause we already stored this
|
||||||
} // end if (childTreeBytesOut == 0)
|
} // end if (childTreeBytesOut == 0)
|
||||||
} // end if (oneAtBit(childrenExistBits, i))
|
} // end if (oneAtBit(childrenExistInPacketBits, i))
|
||||||
} // end for
|
} // end for
|
||||||
} // end keepDiggingDeeper
|
} // end keepDiggingDeeper
|
||||||
|
|
||||||
return bytesAtThisLevel;
|
return bytesAtThisLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ public:
|
||||||
void eraseAllVoxels();
|
void eraseAllVoxels();
|
||||||
|
|
||||||
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
|
void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes);
|
||||||
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, bool includeColor = true);
|
void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes,
|
||||||
|
bool includeColor = true, bool includeExistsBits = false);
|
||||||
void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false);
|
void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false);
|
||||||
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
|
void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false);
|
||||||
void printTreeForDebugging(VoxelNode *startNode);
|
void printTreeForDebugging(VoxelNode *startNode);
|
||||||
|
@ -57,7 +58,8 @@ public:
|
||||||
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
|
void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL);
|
||||||
|
|
||||||
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
||||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor = true,
|
VoxelNodeBag& bag, const ViewFrustum* viewFrustum,
|
||||||
|
bool includeColor = true, bool includeExistsBits = false,
|
||||||
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const;
|
bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const;
|
||||||
|
|
||||||
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
|
int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag,
|
||||||
|
@ -82,8 +84,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel,
|
||||||
VoxelNode* node, unsigned char* outputBuffer, int availableBytes,
|
VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag,
|
||||||
VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor,
|
const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits,
|
||||||
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
|
bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const;
|
||||||
|
|
||||||
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
|
int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel,
|
||||||
|
@ -95,7 +97,8 @@ private:
|
||||||
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
|
void recurseNodeWithOperation(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
|
||||||
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;
|
VoxelNode* nodeForOctalCode(VoxelNode* ancestorNode, unsigned char* needleCode, VoxelNode** parentOfFoundNode) const;
|
||||||
VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate);
|
VoxelNode* createMissingNode(VoxelNode* lastParentNode, unsigned char* deepestCodeToCreate);
|
||||||
int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes, bool includeColor = true);
|
int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes,
|
||||||
|
bool includeColor = true, bool includeExistsBits = false);
|
||||||
|
|
||||||
bool _isDirty;
|
bool _isDirty;
|
||||||
unsigned long int _nodesChangedFromBitstream;
|
unsigned long int _nodesChangedFromBitstream;
|
||||||
|
|
|
@ -30,8 +30,8 @@ function send_voxels($inputFileName,$server,$port,$command) {
|
||||||
echo "sending adding octets=$octets size=$size to packet packetSize=$packetSize\n";
|
echo "sending adding octets=$octets size=$size to packet packetSize=$packetSize\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "sending packet server=$serverIP port=$serverSendPort $voxNum size=$packetSize result=$result\n";
|
|
||||||
$result = socket_sendto($socketHandle, $netData, $packetSize, 0, $serverIP, $serverSendPort);
|
$result = socket_sendto($socketHandle, $netData, $packetSize, 0, $serverIP, $serverSendPort);
|
||||||
|
echo "sent packet server=$serverIP port=$serverSendPort $voxNum size=$packetSize result=$result\n";
|
||||||
usleep(20000); // 1,000,000 per second
|
usleep(20000); // 1,000,000 per second
|
||||||
$voxNum++;
|
$voxNum++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,13 +168,15 @@ void resInVoxelDistributor(AgentList* agentList,
|
||||||
bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree,
|
bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree,
|
||||||
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
||||||
agentData->nodeBag, &viewFrustum,
|
agentData->nodeBag, &viewFrustum,
|
||||||
agentData->getWantColor());
|
agentData->getWantColor(),agentData->getWantExistsBits());
|
||||||
|
|
||||||
if (agentData->getAvailable() >= bytesWritten) {
|
if (agentData->getAvailable() >= bytesWritten) {
|
||||||
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||||
} else {
|
} else {
|
||||||
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
||||||
agentData->getPacket(), agentData->getPacketLength());
|
agentData->getPacket(), agentData->getPacketLength());
|
||||||
|
printf("sending packet...");
|
||||||
|
outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength());
|
||||||
trueBytesSent += agentData->getPacketLength();
|
trueBytesSent += agentData->getPacketLength();
|
||||||
truePacketsSent++;
|
truePacketsSent++;
|
||||||
packetsSentThisInterval++;
|
packetsSentThisInterval++;
|
||||||
|
@ -185,6 +187,8 @@ void resInVoxelDistributor(AgentList* agentList,
|
||||||
if (agentData->isPacketWaiting()) {
|
if (agentData->isPacketWaiting()) {
|
||||||
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
||||||
agentData->getPacket(), agentData->getPacketLength());
|
agentData->getPacket(), agentData->getPacketLength());
|
||||||
|
printf("sending packet...");
|
||||||
|
outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength());
|
||||||
trueBytesSent += agentData->getPacketLength();
|
trueBytesSent += agentData->getPacketLength();
|
||||||
truePacketsSent++;
|
truePacketsSent++;
|
||||||
agentData->resetVoxelPacket();
|
agentData->resetVoxelPacket();
|
||||||
|
@ -254,6 +258,10 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
||||||
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(),
|
maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(),
|
||||||
agentData->nodeBag, wantDelta, lastViewFrustum);
|
agentData->nodeBag, wantDelta, lastViewFrustum);
|
||||||
|
|
||||||
|
// if nothing was found in view, send the root node.
|
||||||
|
if (agentData->nodeBag.isEmpty()){
|
||||||
|
agentData->nodeBag.insert(randomTree.rootNode);
|
||||||
|
}
|
||||||
agentData->setViewSent(false);
|
agentData->setViewSent(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -288,13 +296,17 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
||||||
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
|
bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree,
|
||||||
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
&tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1,
|
||||||
agentData->nodeBag, &agentData->getCurrentViewFrustum(),
|
agentData->nodeBag, &agentData->getCurrentViewFrustum(),
|
||||||
agentData->getWantColor(), wantDelta, lastViewFrustum);
|
agentData->getWantColor(), agentData->getWantExistsBits(),
|
||||||
|
wantDelta, lastViewFrustum);
|
||||||
|
|
||||||
if (agentData->getAvailable() >= bytesWritten) {
|
if (agentData->getAvailable() >= bytesWritten) {
|
||||||
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||||
} else {
|
} else {
|
||||||
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
||||||
agentData->getPacket(), agentData->getPacketLength());
|
agentData->getPacket(), agentData->getPacketLength());
|
||||||
|
|
||||||
|
printf("sending packet...");
|
||||||
|
outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength());
|
||||||
trueBytesSent += agentData->getPacketLength();
|
trueBytesSent += agentData->getPacketLength();
|
||||||
truePacketsSent++;
|
truePacketsSent++;
|
||||||
packetsSentThisInterval++;
|
packetsSentThisInterval++;
|
||||||
|
@ -305,6 +317,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList,
|
||||||
if (agentData->isPacketWaiting()) {
|
if (agentData->isPacketWaiting()) {
|
||||||
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
agentList->getAgentSocket()->send(agent->getActiveSocket(),
|
||||||
agentData->getPacket(), agentData->getPacketLength());
|
agentData->getPacket(), agentData->getPacketLength());
|
||||||
|
printf("sending packet...");
|
||||||
|
outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength());
|
||||||
trueBytesSent += agentData->getPacketLength();
|
trueBytesSent += agentData->getPacketLength();
|
||||||
truePacketsSent++;
|
truePacketsSent++;
|
||||||
agentData->resetVoxelPacket();
|
agentData->resetVoxelPacket();
|
||||||
|
@ -532,6 +546,8 @@ int main(int argc, const char * argv[])
|
||||||
persistVoxelsWhenDirty();
|
persistVoxelsWhenDirty();
|
||||||
|
|
||||||
if (agentList->getAgentSocket()->receive(&agentPublicAddress, packetData, &receivedBytes)) {
|
if (agentList->getAgentSocket()->receive(&agentPublicAddress, packetData, &receivedBytes)) {
|
||||||
|
|
||||||
|
//printf("got a packet with message %d %c\n",(int)packetData[0],packetData[0]);
|
||||||
// XXXBHG: Hacked in support for 'S' SET command
|
// XXXBHG: Hacked in support for 'S' SET command
|
||||||
if (packetData[0] == PACKET_HEADER_SET_VOXEL || packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) {
|
if (packetData[0] == PACKET_HEADER_SET_VOXEL || packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) {
|
||||||
bool destructive = (packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE);
|
bool destructive = (packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE);
|
||||||
|
|
Loading…
Reference in a new issue