From b06cc60665c9b05e7836b9983240065e7b5ff1a9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 20 May 2013 12:14:32 -0700 Subject: [PATCH 01/23] moved constructor --- libraries/avatars/src/AvatarData.cpp | 27 +++++++++++++++++++++++++++ libraries/avatars/src/AvatarData.h | 24 +----------------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 2e11e8aa84..21e0397619 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -33,6 +33,33 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo return sizeof(uint16_t); } +AvatarData::AvatarData() : + _handPosition(0,0,0), + _bodyYaw(-90.0), + _bodyPitch(0.0), + _bodyRoll(0.0), + _headYaw(0), + _headPitch(0), + _headRoll(0), + _headLeanSideways(0), + _headLeanForward(0), + _audioLoudness(0), + _handState(0), + _cameraPosition(0,0,0), + _cameraDirection(0,0,0), + _cameraUp(0,0,0), + _cameraRight(0,0,0), + _cameraFov(0.0f), + _cameraAspectRatio(0.0f), + _cameraNearClip(0.0f), + _cameraFarClip(0.0f), + _keyState(NO_KEY_DOWN), + _wantResIn(false), + _wantColor(true) +{ +}; + + int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { unsigned char* bufferStart = destinationBuffer; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index f37c4f3396..eeb2e1eb7e 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -28,29 +28,7 @@ enum KeyState class AvatarData : public AgentData { public: - AvatarData() : - _handPosition(0,0,0), - _bodyYaw(-90.0), - _bodyPitch(0.0), - _bodyRoll(0.0), - _headYaw(0), - _headPitch(0), - _headRoll(0), - _headLeanSideways(0), - _headLeanForward(0), - _audioLoudness(0), - _handState(0), - _cameraPosition(0,0,0), - _cameraDirection(0,0,0), - _cameraUp(0,0,0), - _cameraRight(0,0,0), - _cameraFov(0.0f), - _cameraAspectRatio(0.0f), - _cameraNearClip(0.0f), - _cameraFarClip(0.0f), - _keyState(NO_KEY_DOWN), - _wantResIn(false), - _wantColor(true) { }; + AvatarData(); const glm::vec3& getPosition() const { return _position; } void setPosition(const glm::vec3 position) { _position = position; } From 321d1952d652bef13cf77e5238a71572757b1aee Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 20 May 2013 12:56:59 -0700 Subject: [PATCH 02/23] first cut at exists bits --- interface/src/Application.cpp | 9 +- interface/src/Application.h | 1 + interface/src/VoxelSystem.cpp | 11 +- interface/src/VoxelSystem.h | 5 + libraries/avatars/src/AvatarData.cpp | 17 +-- libraries/shared/src/SharedUtil.h | 4 + libraries/voxels/src/VoxelNode.cpp | 16 ++- libraries/voxels/src/VoxelTree.cpp | 165 +++++++++++++++++++++------ libraries/voxels/src/VoxelTree.h | 13 ++- tools/sendvoxels.php | 2 +- voxel-server/src/main.cpp | 20 +++- 11 files changed, 208 insertions(+), 55 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7974b2bdf8..0d7b416fe0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1106,6 +1106,10 @@ void Application::setWantsResIn(bool wantsResIn) { _myAvatar.setWantResIn(wantsResIn); } +void Application::setWantsExistsBits(bool wantsExistsBits) { + _myAvatar.setWantExistsBits(wantsExistsBits); + _voxels.setWantExistsBits(wantsExistsBits); +} void Application::setWantsDelta(bool wantsDelta) { _myAvatar.setWantDelta(wantsDelta); @@ -1255,7 +1259,7 @@ void Application::initMenu() { QMenu* debugMenu = menuBar->addMenu("Debug"); debugMenu->addAction("Show Render Pipeline Warnings", this, SLOT(setRenderWarnings(bool)))->setCheckable(true); 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 Voxel Every Other Randomly", this, SLOT(doFalseRandomizeEveryOtherVoxelColors())); 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 Monochrome", this, SLOT(setWantsMonochrome(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() { @@ -2035,7 +2040,7 @@ void Application::deleteVoxelUnderCursor() { sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel); // 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 _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); diff --git a/interface/src/Application.h b/interface/src/Application.h index da3898ab9f..d072eefe24 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -90,6 +90,7 @@ private slots: void doTreeStats(); void setWantsMonochrome(bool wantsMonochrome); void setWantsResIn(bool wantsResIn); + void setWantsExistsBits(bool wantsExistsBits); void setWantsDelta(bool wantsDelta); void updateVoxelModeActions(); void addVoxelInFrontOfAvatar(); diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index d578bb3504..75d9a15a4d 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -102,21 +102,25 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { switch(command) { case PACKET_HEADER_VOXEL_DATA: { +//printLog("PACKET_HEADER_VOXEL_DATA voxelData="); +//outputBufferBits(sourceBuffer, numBytes); + PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree - _tree->readBitstreamToTree(voxelData, numBytes - 1); + _tree->readBitstreamToTree(voxelData, numBytes - 1, true, _wantsExistBits); } break; case PACKET_HEADER_VOXEL_DATA_MONOCHROME: { PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // 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; case PACKET_HEADER_ERASE_VOXEL: // ask the tree to read the "remove" bitstream - _tree->processRemoveVoxelBitstream(sourceBuffer, numBytes); + //_tree->processRemoveVoxelBitstream(sourceBuffer, numBytes); + //printLog("ignoring PACKET_HEADER_ERASE_VOXEL\n"); break; case PACKET_HEADER_Z_COMMAND: @@ -419,6 +423,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { void VoxelSystem::init() { + _wantsExistBits = false; _renderWarningsOn = false; _callsToTreesToArrays = 0; _setupNewVoxelsForDrawingLastFinished = 0; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 2d6d9717f6..1f2597763c 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -79,6 +79,9 @@ public: 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, creationMode mode, bool destructive = false, bool debug = false); + + void setWantExistsBits(bool on) { _wantsExistBits = on; }; + bool getWantExistsBits() const { return _wantsExistBits; }; private: // disallow copying of VoxelSystem objects @@ -151,6 +154,8 @@ private: void copyWrittenDataToReadArrays(); bool _voxelsDirty; + + bool _wantsExistBits; public: void updateVBOs(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 21e0397619..db5718a516 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -128,9 +128,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // voxel sending features... // voxel sending features... unsigned char wantItems = 0; - if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); } - if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); } - if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); } + if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); } + if (_wantExistsBits) { setAtBit(wantItems,WANT_EXISTS_BITS_BIT); } + if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); } + if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); } *destinationBuffer++ = wantItems; return destinationBuffer - bufferStart; @@ -210,11 +211,11 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { // voxel sending features... unsigned char wantItems = 0; 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; } @@ -223,4 +224,4 @@ void AvatarData::setHeadPitch(float p) { const float MAX_PITCH = 60; const float MIN_PITCH = -60; _headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH); -} \ No newline at end of file +} diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index d0e71ec71e..ebaa802890 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -80,4 +80,8 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex, void** valueArray, float* keyArray, int* originalIndexArray, int currentCount, int maxCount); +class debugHelpers { +public: + static const char* booleanValue(bool checkValue) { return checkValue ? "yes" : "no"; }; +}; #endif /* defined(__hifi__SharedUtil__) */ diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 6bab72cf61..37abc3505b 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -242,8 +242,20 @@ void VoxelNode::setRandomColor(int minimumBrightness) { } void VoxelNode::printDebugDetails(const char* label) const { - printLog("%s - Voxel at corner=(%f,%f,%f) size=%f octcode=", label, - _box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getSize().x); + unsigned char childBits = 0; + 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); } diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 249a70212e..452ff6fa96 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -103,15 +103,22 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char 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->getChildAtIndex(indexOfNewChild)) { + lastParentNode->addChildAtIndex(indexOfNewChild); + } + +/**** if (lastParentNode->isLeaf() && lastParentNode->isColored()) { // for colored leaves, we must add *all* the children 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->getChildAtIndex(i)->setColor(lastParentNode->getColor()); } } else 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->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 - int bytesRead = 1; + int bytesRead = includeExistsBits ? 2 : 1; 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)) { + if (oneAtBit(colorInPacketMask, i)) { // create the child if it doesn't exist if (!destinationNode->getChildAtIndex(i)) { +//printLog(">>>>>>>> readNodeData() colorInPacketMask area -- calling addChildAtIndex() at %d colorInTreeBitSet=%s<<<<<<<\n",i, +// debugHelpers::booleanValue(oneAtBit(colorInTreeMask, i))); + destinationNode->addChildAtIndex(i); if (destinationNode->isDirty()) { _isDirty = true; @@ -156,13 +177,27 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, this->voxelsColored++; 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 - 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; - bytesRead++; + bytesRead += includeExistsBits ? 2 : 1; while (bytesLeftToRead - bytesRead > 0 && childIndex < NUMBER_OF_CHILDREN) { // 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)) { // add a child at that index, if it doesn't exist bool nodeWasDirty = destinationNode->isDirty(); +//printLog(">>>>>>>> readNodeData() childMask area -- calling addChildAtIndex() at %d colorInTreeBitSet=%s<<<<<<<\n",childIndex, +// debugHelpers::booleanValue(oneAtBit(childrenInTreeMask, childIndex))); + + destinationNode->addChildAtIndex(childIndex); bool nodeIsDirty = destinationNode->isDirty(); if (nodeIsDirty) { @@ -185,17 +224,38 @@ 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, includeColor); + nodeData + bytesRead, bytesLeftToRead - bytesRead, includeColor, includeExistsBits); } - 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; } -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; unsigned char* bitstreamAt = bitstream; @@ -224,7 +284,7 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, unsigned long int int theseBytesRead = 0; theseBytesRead += octalCodeBytes; theseBytesRead += readNodeData(bitstreamRootNode, bitstreamAt + octalCodeBytes, - bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor); + bufferSizeBytes - (bytesRead + octalCodeBytes), includeColor, includeExistsBits); // skip bitstream to new startPoint 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 // this only finds and deletes the node from the tree. void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { +//printLog(">>>>>>>> deleteVoxelCodeFromTree() <<<<<<<\n"); VoxelNode* parentNode = NULL; VoxelNode* nodeToDelete = nodeForOctalCode(rootNode, codeBuffer, &parentNode); @@ -271,6 +332,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { int index = branchIndexWithDescendant(ancestorNode->getOctalCode(), codeBuffer); for (int i = 0; i < 8; i++) { if (i != index) { +//printLog(">>>>>>>> deleteVoxelCodeFromTree() calling addChildAtIndex() at %d <<<<<<<\n",i); ancestorNode->addChildAtIndex(i); ancestorNode->getChildAtIndex(i)->setColor(nodeToDelete->getColor()); } @@ -278,6 +340,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { if (*ancestorNode->getOctalCode() == *codeBuffer - 1) { break; } +//printLog(">>>>>>>> deleteVoxelCodeFromTree() calling addChildAtIndex() at %d <<<<<<<\n",index); ancestorNode->addChildAtIndex(index); ancestorNode = ancestorNode->getChildAtIndex(index); 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, - VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, + VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { // 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 int currentEncodeLevel = 0; - int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, - node, outputBuffer, availableBytes, bag, viewFrustum, includeColor, + int childBytesWritten = encodeTreeBitstreamRecursion(maxEncodeLevel, currentEncodeLevel, node, outputBuffer, availableBytes, + bag, viewFrustum, includeColor, includeExistsBits, deltaViewFrustum, lastViewFrustum); // 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; } -int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, - VoxelNode* node, unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, +int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, VoxelNode* node, + unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, + const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { // How many bytes have we written so far at this level; int bytesAtThisLevel = 0; @@ -855,7 +918,9 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco unsigned char thisLevelBuffer[MAX_LEVEL_BYTES]; 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; int inViewCount = 0; int inViewNotLeafCount = 0; @@ -865,6 +930,16 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco // add them to our distance ordered array of children for (int i = 0; i < NUMBER_OF_CHILDREN; 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))); 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 // subtree to exist if (!(childNode && childNode->isLeaf())) { - childrenExistBits += (1 << (7 - i)); + childrenExistInPacketBits += (1 << (7 - i)); inViewNotLeafCount++; } @@ -897,6 +972,20 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco *writeToThisLevelBuffer = childrenColoredBits; writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer 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... 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 - bytesAtThisLevel += sizeof(childrenExistBits); // keep track of byte count - + // if the caller wants to include childExistsBits, then include them even if not in view, put them before the + // 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. 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. // // 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 // 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. // - // we know the last thing we wrote to the outputBuffer was our childrenExistBits. Let's remember where that was! - unsigned char* childExistsPlaceHolder = outputBuffer-sizeof(childrenExistBits); + // we know the last thing we wrote to the outputBuffer was our childrenExistInPacketBits. Let's remember where that was! + unsigned char* childExistsPlaceHolder = outputBuffer-sizeof(childrenExistInPacketBits); for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { - if (oneAtBit(childrenExistBits, i)) { + if (oneAtBit(childrenExistInPacketBits, i)) { VoxelNode* childNode = node->getChildAtIndex(i); int thisLevel = currentEncodeLevel; int childTreeBytesOut = encodeTreeBitstreamRecursion(maxEncodeLevel, thisLevel, childNode, outputBuffer, availableBytes, bag, - viewFrustum, includeColor, + viewFrustum, includeColor, includeExistsBits, deltaViewFrustum, lastViewFrustum); // 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 if (includeColor && childTreeBytesOut == 2) { 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; @@ -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, // then we want to remove their bit from the childExistsPlaceHolder bitmask if (childTreeBytesOut == 0) { +printLog("childTreeBytesOut == 0... actually lopping empty lower tree\n"); // remove this child's bit... - childrenExistBits -= (1 << (7 - i)); + childrenExistInPacketBits -= (1 << (7 - i)); // repair the child exists mask - *childExistsPlaceHolder = childrenExistBits; + *childExistsPlaceHolder = childrenExistInPacketBits; // Note: no need to move the pointer, cause we already stored this } // end if (childTreeBytesOut == 0) - } // end if (oneAtBit(childrenExistBits, i)) + } // end if (oneAtBit(childrenExistInPacketBits, i)) } // end for } // end keepDiggingDeeper + return bytesAtThisLevel; } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 6d384f0244..c4a5631abf 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -40,7 +40,8 @@ public: void eraseAllVoxels(); 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 deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false); void printTreeForDebugging(VoxelNode *startNode); @@ -57,7 +58,8 @@ public: void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); 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; int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag, @@ -82,8 +84,8 @@ public: private: int encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEncodeLevel, - VoxelNode* node, unsigned char* outputBuffer, int availableBytes, - VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, + VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, + const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const; int searchForColoredNodesRecursion(int maxSearchLevel, int& currentSearchLevel, @@ -95,7 +97,8 @@ 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, bool includeColor = true); + int readNodeData(VoxelNode *destinationNode, unsigned char* nodeData, int bufferSizeBytes, + bool includeColor = true, bool includeExistsBits = false); bool _isDirty; unsigned long int _nodesChangedFromBitstream; diff --git a/tools/sendvoxels.php b/tools/sendvoxels.php index 438c9a1b8a..ed3b7b6095 100644 --- a/tools/sendvoxels.php +++ b/tools/sendvoxels.php @@ -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 packet server=$serverIP port=$serverSendPort $voxNum size=$packetSize result=$result\n"; $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 $voxNum++; } diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index c268031e74..3561559e89 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -168,13 +168,15 @@ void resInVoxelDistributor(AgentList* agentList, bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, agentData->nodeBag, &viewFrustum, - agentData->getWantColor()); + agentData->getWantColor(),agentData->getWantExistsBits()); if (agentData->getAvailable() >= bytesWritten) { agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); } else { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); + printf("sending packet..."); + outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; packetsSentThisInterval++; @@ -185,6 +187,8 @@ void resInVoxelDistributor(AgentList* agentList, if (agentData->isPacketWaiting()) { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); + printf("sending packet..."); + outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; agentData->resetVoxelPacket(); @@ -254,6 +258,10 @@ void deepestLevelVoxelDistributor(AgentList* agentList, maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(), 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); } @@ -288,13 +296,17 @@ void deepestLevelVoxelDistributor(AgentList* agentList, bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, agentData->nodeBag, &agentData->getCurrentViewFrustum(), - agentData->getWantColor(), wantDelta, lastViewFrustum); + agentData->getWantColor(), agentData->getWantExistsBits(), + wantDelta, lastViewFrustum); if (agentData->getAvailable() >= bytesWritten) { agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); } else { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); + + printf("sending packet..."); + outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; packetsSentThisInterval++; @@ -305,6 +317,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList, if (agentData->isPacketWaiting()) { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); + printf("sending packet..."); + outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; agentData->resetVoxelPacket(); @@ -532,6 +546,8 @@ int main(int argc, const char * argv[]) persistVoxelsWhenDirty(); 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 if (packetData[0] == PACKET_HEADER_SET_VOXEL || packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) { bool destructive = (packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE); From e9caa40d9a9d5046ad1ff913d490afd527063683 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 20 May 2013 13:54:02 -0700 Subject: [PATCH 03/23] added exists bits to avatar data --- libraries/avatars/src/AvatarData.cpp | 8 +++++--- libraries/avatars/src/AvatarData.h | 16 ++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index db5718a516..43259298fb 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -55,7 +55,9 @@ AvatarData::AvatarData() : _cameraFarClip(0.0f), _keyState(NO_KEY_DOWN), _wantResIn(false), - _wantColor(true) + _wantColor(true), + _wantDelta(true), + _wantExistsBits(true) { }; @@ -129,9 +131,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // voxel sending features... unsigned char wantItems = 0; if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); } - if (_wantExistsBits) { setAtBit(wantItems,WANT_EXISTS_BITS_BIT); } if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); } if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); } + if (_wantExistsBits) { setAtBit(wantItems,WANT_EXISTS_BITS_BIT); } *destinationBuffer++ = wantItems; return destinationBuffer - bufferStart; @@ -212,9 +214,9 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char wantItems = 0; 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); + _wantExistsBits = oneAtBit(wantItems,WANT_EXISTS_BITS_BIT); return sourceBuffer - startPosition; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index eeb2e1eb7e..57edf3c452 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -18,6 +18,7 @@ const int WANT_RESIN_AT_BIT = 0; const int WANT_COLOR_AT_BIT = 1; const int WANT_DELTA_AT_BIT = 2; +const int WANT_EXISTS_BITS_BIT = 4; enum KeyState { @@ -102,12 +103,14 @@ public: const std::string& chatMessage () const { return _chatMessage; } // related to Voxel Sending strategies - bool getWantResIn() const { return _wantResIn; } - bool getWantColor() const { return _wantColor; } - bool getWantDelta() const { return _wantDelta; } - void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } - void setWantColor(bool wantColor) { _wantColor = wantColor; } - void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } + bool getWantResIn() const { return _wantResIn; } + bool getWantColor() const { return _wantColor; } + bool getWantDelta() const { return _wantDelta; } + bool getWantExistsBits() const { return _wantExistsBits; } + void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } + void setWantColor(bool wantColor) { _wantColor = wantColor; } + void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } + void setWantExistsBits(bool wantExistsBits) { _wantExistsBits = wantExistsBits; } protected: // privatize the copy constructor and assignment operator so they cannot be called @@ -158,6 +161,7 @@ protected: bool _wantResIn; bool _wantColor; bool _wantDelta; + bool _wantExistsBits; }; #endif /* defined(__hifi__AvatarData__) */ From a53f84fcb9f8a23c3ae1d60a1793689ea845ba84 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 20 May 2013 15:51:47 -0700 Subject: [PATCH 04/23] latest hacking --- interface/src/VoxelSystem.cpp | 4 +++ libraries/avatars/src/AvatarData.cpp | 4 +-- libraries/voxels/src/VoxelNode.h | 1 + libraries/voxels/src/VoxelTree.cpp | 48 +++++++++++++++++----------- voxel-server/src/main.cpp | 21 +++++++----- 5 files changed, 49 insertions(+), 29 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 75d9a15a4d..bc3f927d22 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -107,6 +107,10 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree +// printLog("PACKET_HEADER_VOXEL_DATA = \n"); +// outputBufferBits(sourceBuffer, numBytes); + + _tree->readBitstreamToTree(voxelData, numBytes - 1, true, _wantsExistBits); } break; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 658551e726..b43e8f1e93 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -56,8 +56,8 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _wantResIn(false), _wantColor(true), - _wantDelta(true), - _wantExistsBits(true) + _wantDelta(false), + _wantExistsBits(false) { }; diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index cf80bcab46..10ad889ba3 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -67,6 +67,7 @@ public: float distanceToPoint(const glm::vec3& point) const; bool isLeaf() const { return _childCount == 0; } + int getChildCount() const { return _childCount; } void printDebugDetails(const char* label) const; bool isDirty() const { return _isDirty; }; void clearDirtyBit() { _isDirty = false; }; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 452ff6fa96..b26a70e365 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -102,23 +102,21 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char 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->getChildAtIndex(indexOfNewChild)) { lastParentNode->addChildAtIndex(indexOfNewChild); } - -/**** +***/ if (lastParentNode->isLeaf() && lastParentNode->isColored()) { // for colored leaves, we must add *all* the children 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->getChildAtIndex(i)->setColor(lastParentNode->getColor()); } } else 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->getChildAtIndex(indexOfNewChild)->getOctalCode() == *codeToReach) { @@ -304,15 +302,16 @@ 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 // this only finds and deletes the node from the tree. -void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { -//printLog(">>>>>>>> deleteVoxelCodeFromTree() <<<<<<<\n"); +void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage) { + VoxelNode* parentNode = NULL; VoxelNode* nodeToDelete = nodeForOctalCode(rootNode, codeBuffer, &parentNode); // If the node exists... int lengthInBytes = bytesRequiredForCodeLength(*codeBuffer); // includes octet count, not color! - if (0 == memcmp(nodeToDelete->getOctalCode(),codeBuffer,lengthInBytes)) { + // if the code we got back matches our target, then we know we can actually delete it + if (0 == memcmp(nodeToDelete->getOctalCode(), codeBuffer, lengthInBytes)) { if (parentNode) { int childIndex = branchIndexWithDescendant(parentNode->getOctalCode(), codeBuffer); @@ -322,6 +321,17 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { parentNode->deleteChildAtIndex(childIndex); } + // ok, also make sure, that if this is the last child of this parent, then we should + // delete the parent also... is that right? + if (parentNode->getChildCount() < 2) { + printLog("deleteVoxelCodeFromTree()... parentNode->getChildCount() = %d\n", parentNode->getChildCount() ); + parentNode->printDebugDetails("deleteVoxelCodeFromTree()"); + if (parentNode->getChildCount() == 0 && !parentNode->isColored()) { + printLog("deleteVoxelCodeFromTree()... no more children and not colored... deleting parentNode\n" ); + deleteVoxelCodeFromTree(parentNode->getOctalCode(),stage); + } + } + reaverageVoxelColors(rootNode); // Fix our colors!! Need to call it on rootNode _isDirty = true; } @@ -332,7 +342,6 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { int index = branchIndexWithDescendant(ancestorNode->getOctalCode(), codeBuffer); for (int i = 0; i < 8; i++) { if (i != index) { -//printLog(">>>>>>>> deleteVoxelCodeFromTree() calling addChildAtIndex() at %d <<<<<<<\n",i); ancestorNode->addChildAtIndex(i); ancestorNode->getChildAtIndex(i)->setColor(nodeToDelete->getColor()); } @@ -340,7 +349,6 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage) { if (*ancestorNode->getOctalCode() == *codeBuffer - 1) { break; } -//printLog(">>>>>>>> deleteVoxelCodeFromTree() calling addChildAtIndex() at %d <<<<<<<\n",index); ancestorNode->addChildAtIndex(index); ancestorNode = ancestorNode->getChildAtIndex(index); ancestorNode->setColor(nodeToDelete->getColor()); @@ -874,6 +882,8 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { + +//printLog("encodeTreeBitstreamRecursion() currentEncodeLevel=%d\n",currentEncodeLevel); // How many bytes have we written so far at this level; int bytesAtThisLevel = 0; @@ -974,13 +984,13 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco 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); +//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 @@ -1001,7 +1011,7 @@ outputBits(childrenExistInTreeBits); // if the caller wants to include childExistsBits, then include them even if not in view, put them before the // childrenExistInPacketBits, so that the lower code can properly repair the packet exists bits if (includeExistsBits) { -printLog("includeExistsBits, writing subtree exists bits\n"); +//printLog("includeExistsBits, writing subtree exists bits\n"); *writeToThisLevelBuffer = childrenExistInTreeBits; writeToThisLevelBuffer += sizeof(childrenExistInTreeBits); // move the pointer bytesAtThisLevel += sizeof(childrenExistInTreeBits); // keep track of byte count @@ -1068,7 +1078,7 @@ printLog("includeExistsBits, writing subtree exists bits\n"); // we can make this act like no bytes out, by just resetting the bytes out in this case if (includeColor && childTreeBytesOut == 2) { 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"); +//printLog("childTreeBytesOut==2.... lopping empty lower tree\n"); } bytesAtThisLevel += childTreeBytesOut; @@ -1078,7 +1088,7 @@ printLog("childTreeBytesOut==2.... lopping empty lower tree\n"); // 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 if (childTreeBytesOut == 0) { -printLog("childTreeBytesOut == 0... actually lopping empty lower tree\n"); +//printLog("childTreeBytesOut == 0... actually lopping empty lower tree\n"); // remove this child's bit... childrenExistInPacketBits -= (1 << (7 - i)); // repair the child exists mask diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 3561559e89..4cfe492baf 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -175,8 +175,8 @@ void resInVoxelDistributor(AgentList* agentList, } else { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - printf("sending packet..."); - outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); + //printf("sending packet..."); + //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; packetsSentThisInterval++; @@ -187,8 +187,8 @@ void resInVoxelDistributor(AgentList* agentList, if (agentData->isPacketWaiting()) { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - printf("sending packet..."); - outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); + //printf("sending packet..."); + //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; agentData->resetVoxelPacket(); @@ -236,6 +236,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList, VoxelAgentData* agentData, bool viewFrustumChanged) { +//printf("deepestLevelVoxelDistributor()\n"); + int maxLevelReached = 0; double start = usecTimestampNow(); @@ -254,12 +256,15 @@ void deepestLevelVoxelDistributor(AgentList* agentList, // If the current view frustum has changed OR we have nothing to send, then search against // the current view frustum for things to send. if (viewFrustumChanged || agentData->nodeBag.isEmpty()) { + +//printf("bag empty, search for stuff in view...\n"); // If the bag was empty, then send everything in view, not just the delta maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(), agentData->nodeBag, wantDelta, lastViewFrustum); // if nothing was found in view, send the root node. if (agentData->nodeBag.isEmpty()){ +//printf("huh... bag STILL empty, what to do? Add the root?...\n"); agentData->nodeBag.insert(randomTree.rootNode); } agentData->setViewSent(false); @@ -305,8 +310,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList, agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - printf("sending packet..."); - outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); + //printf("sending packet..."); + //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; packetsSentThisInterval++; @@ -317,8 +322,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList, if (agentData->isPacketWaiting()) { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - printf("sending packet..."); - outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); + //printf("sending packet..."); + //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; agentData->resetVoxelPacket(); From ef2d27aba6b339555b7c2d9cccbd8cc6bfde952e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 10:43:31 -0700 Subject: [PATCH 05/23] getting closer to working delete --- interface/src/VoxelSystem.cpp | 12 ----- libraries/voxels/src/VoxelNode.cpp | 27 +++++++++++ libraries/voxels/src/VoxelNode.h | 6 ++- libraries/voxels/src/VoxelTree.cpp | 77 +++++++----------------------- voxel-server/src/main.cpp | 7 ++- 5 files changed, 55 insertions(+), 74 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index be79acae0f..5ead332fbf 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -104,15 +104,8 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { switch(command) { case PACKET_HEADER_VOXEL_DATA: { -//printLog("PACKET_HEADER_VOXEL_DATA voxelData="); -//outputBufferBits(sourceBuffer, numBytes); - PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree -// printLog("PACKET_HEADER_VOXEL_DATA = \n"); -// outputBufferBits(sourceBuffer, numBytes); - - _tree->readBitstreamToTree(voxelData, numBytes - 1, true, _wantsExistBits); } break; @@ -123,11 +116,6 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { _tree->readBitstreamToTree(voxelData, numBytes - 1, false, _wantsExistBits); } break; - case PACKET_HEADER_ERASE_VOXEL: - // ask the tree to read the "remove" bitstream - //_tree->processRemoveVoxelBitstream(sourceBuffer, numBytes); - //printLog("ignoring PACKET_HEADER_ERASE_VOXEL\n"); - break; case PACKET_HEADER_Z_COMMAND: // the Z command is a special command that allows the sender to send high level semantic diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 37abc3505b..d33b7c1051 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -119,6 +119,33 @@ void VoxelNode::addChildAtIndex(int childIndex) { } } +// handles staging or deletion of all deep children +void VoxelNode::safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeletion) { + VoxelNode* childToDelete = getChildAtIndex(childIndex); + if (childToDelete) { + // If the child is not a leaf, then call ourselves recursively on all the children + if (!childToDelete->isLeaf()) { + // delete all it's children + for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { + childToDelete->safeDeepDeleteChildAtIndex(i, stagedForDeletion); + } + } + // if this node has a BufferIndex then we need to stage it for deletion + // instead of actually deleting it from the tree + if (childToDelete->isKnownBufferIndex()) { + stagedForDeletion = true; + } + if (stagedForDeletion) { + childToDelete->stageForDeletion(); + _isDirty = true; + } else { + deleteChildAtIndex(childIndex); + _isDirty = true; + } + } +} + + // will average the child colors... void VoxelNode::setColorFromAverageOfChildren() { int colorArray[4] = {0,0,0,0}; diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 10ad889ba3..710963b5b8 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -43,10 +43,12 @@ public: ~VoxelNode(); unsigned char* getOctalCode() const { return _octalCode; }; - VoxelNode* getChildAtIndex(int i) const { return _children[i]; }; + VoxelNode* getChildAtIndex(int childIndex) const { return _children[childIndex]; }; void deleteChildAtIndex(int childIndex); VoxelNode* removeChildAtIndex(int childIndex); void addChildAtIndex(int childIndex); + void safeDeepDeleteChildAtIndex(int childIndex, bool& stagedForDeletion); // handles staging or deletion of all descendents + void setColorFromAverageOfChildren(); void setRandomColor(int minimumBrightness); bool collapseIdenticalLeaves(); @@ -80,7 +82,7 @@ public: bool getShouldRender() const { return _shouldRender; } // Used by VoxelSystem to mark a node as to be deleted on next render pass - void stageForDeletion() { _isStagedForDeletion = true; }; + void stageForDeletion() { _isStagedForDeletion = true; _isDirty = true; }; bool isStagedForDeletion() const { return _isStagedForDeletion; } #ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index b26a70e365..ea77d0175f 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -128,11 +128,6 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char 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; @@ -145,9 +140,6 @@ if (includeExistsBits) { if (oneAtBit(colorInPacketMask, i)) { // create the child if it doesn't exist if (!destinationNode->getChildAtIndex(i)) { -//printLog(">>>>>>>> readNodeData() colorInPacketMask area -- calling addChildAtIndex() at %d colorInTreeBitSet=%s<<<<<<<\n",i, -// debugHelpers::booleanValue(oneAtBit(colorInTreeMask, i))); - destinationNode->addChildAtIndex(i); if (destinationNode->isDirty()) { _isDirty = true; @@ -175,19 +167,6 @@ if (includeExistsBits) { this->voxelsColored++; 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 @@ -204,10 +183,6 @@ if (includeExistsBits) { if (!destinationNode->getChildAtIndex(childIndex)) { // add a child at that index, if it doesn't exist bool nodeWasDirty = destinationNode->isDirty(); -//printLog(">>>>>>>> readNodeData() childMask area -- calling addChildAtIndex() at %d colorInTreeBitSet=%s<<<<<<<\n",childIndex, -// debugHelpers::booleanValue(oneAtBit(childrenInTreeMask, childIndex))); - - destinationNode->addChildAtIndex(childIndex); bool nodeIsDirty = destinationNode->isDirty(); if (nodeIsDirty) { @@ -226,29 +201,19 @@ if (includeExistsBits) { } 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; - } - } - } + + if (includeExistsBits) { + 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)) { + bool stagedForDeletion = false; // assume staging is not needed + destinationNode->safeDeepDeleteChildAtIndex(i, stagedForDeletion); + _isDirty = true; // by definition! + } + } + } return bytesRead; } @@ -303,10 +268,8 @@ 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 // this only finds and deletes the node from the tree. void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage) { - VoxelNode* parentNode = NULL; VoxelNode* nodeToDelete = nodeForOctalCode(rootNode, codeBuffer, &parentNode); - // If the node exists... int lengthInBytes = bytesRequiredForCodeLength(*codeBuffer); // includes octet count, not color! @@ -314,24 +277,20 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage) { if (0 == memcmp(nodeToDelete->getOctalCode(), codeBuffer, lengthInBytes)) { if (parentNode) { int childIndex = branchIndexWithDescendant(parentNode->getOctalCode(), codeBuffer); - if (stage) { nodeToDelete->stageForDeletion(); } else { parentNode->deleteChildAtIndex(childIndex); } - - // ok, also make sure, that if this is the last child of this parent, then we should - // delete the parent also... is that right? - if (parentNode->getChildCount() < 2) { - printLog("deleteVoxelCodeFromTree()... parentNode->getChildCount() = %d\n", parentNode->getChildCount() ); - parentNode->printDebugDetails("deleteVoxelCodeFromTree()"); - if (parentNode->getChildCount() == 0 && !parentNode->isColored()) { - printLog("deleteVoxelCodeFromTree()... no more children and not colored... deleting parentNode\n" ); + + // If we're not a colored leaf, and we have no children, then delete ourselves + // This will collapse the empty tree above us. + if (parentNode->getChildCount() == 0 && !parentNode->isColored()) { + // Can't delete the root this way. + if (parentNode != rootNode) { deleteVoxelCodeFromTree(parentNode->getOctalCode(),stage); } } - reaverageVoxelColors(rootNode); // Fix our colors!! Need to call it on rootNode _isDirty = true; } diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 4cfe492baf..e5d70567ca 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -257,6 +257,10 @@ void deepestLevelVoxelDistributor(AgentList* agentList, // the current view frustum for things to send. if (viewFrustumChanged || agentData->nodeBag.isEmpty()) { + // just add the rootNode, to see if this addresses the delete problem + agentData->nodeBag.insert(randomTree.rootNode); + +/*** //printf("bag empty, search for stuff in view...\n"); // If the bag was empty, then send everything in view, not just the delta maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(), @@ -264,10 +268,11 @@ void deepestLevelVoxelDistributor(AgentList* agentList, // if nothing was found in view, send the root node. if (agentData->nodeBag.isEmpty()){ -//printf("huh... bag STILL empty, what to do? Add the root?...\n"); +printf("huh... bag STILL empty, what to do? Add the root?...\n"); agentData->nodeBag.insert(randomTree.rootNode); } agentData->setViewSent(false); +**/ } double end = usecTimestampNow(); From 4f9c7fed59da00933a304c0d1e7175ac30f57e46 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:25:50 -0700 Subject: [PATCH 06/23] removed UI for want exists bits, defaults to true --- interface/src/Application.cpp | 6 ------ interface/src/Application.h | 1 - interface/src/VoxelSystem.cpp | 5 ++--- interface/src/VoxelSystem.h | 6 ------ libraries/avatars/src/AvatarData.cpp | 5 +---- libraries/avatars/src/AvatarData.h | 4 ---- libraries/voxels/src/VoxelTree.h | 2 ++ voxel-server/src/main.cpp | 4 ++-- 8 files changed, 7 insertions(+), 26 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3c565d5eea..68237bf63f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1116,11 +1116,6 @@ void Application::setWantsResIn(bool wantsResIn) { _myAvatar.setWantResIn(wantsResIn); } -void Application::setWantsExistsBits(bool wantsExistsBits) { - _myAvatar.setWantExistsBits(wantsExistsBits); - _voxels.setWantExistsBits(wantsExistsBits); -} - void Application::setWantsDelta(bool wantsDelta) { _myAvatar.setWantDelta(wantsDelta); } @@ -1283,7 +1278,6 @@ void Application::initMenu() { debugMenu->addAction("Wants Res-In", this, SLOT(setWantsResIn(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 Exists Bits", this, SLOT(setWantsExistsBits(bool)), Qt::CTRL | Qt::Key_M)->setCheckable(true); } void Application::updateFrustumRenderModeAction() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 95f448d120..dae7f8d71b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -90,7 +90,6 @@ private slots: void doTreeStats(); void setWantsMonochrome(bool wantsMonochrome); void setWantsResIn(bool wantsResIn); - void setWantsExistsBits(bool wantsExistsBits); void setWantsDelta(bool wantsDelta); void updateVoxelModeActions(); void addVoxelInFrontOfAvatar(); diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 5ead332fbf..e6d27a3921 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -106,14 +106,14 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { { PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree - _tree->readBitstreamToTree(voxelData, numBytes - 1, true, _wantsExistBits); + _tree->readBitstreamToTree(voxelData, numBytes - 1, true, WANT_EXISTS_BITS); } break; case PACKET_HEADER_VOXEL_DATA_MONOCHROME: { PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the MONOCHROME bitstream into the tree - _tree->readBitstreamToTree(voxelData, numBytes - 1, false, _wantsExistBits); + _tree->readBitstreamToTree(voxelData, numBytes - 1, false, WANT_EXISTS_BITS); } break; case PACKET_HEADER_Z_COMMAND: @@ -424,7 +424,6 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { void VoxelSystem::init() { - _wantsExistBits = false; _renderWarningsOn = false; _callsToTreesToArrays = 0; _setupNewVoxelsForDrawingLastFinished = 0; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 9997444d37..316ed46f67 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -79,10 +79,6 @@ public: 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, creationMode mode, bool destructive = false, bool debug = false); - - void setWantExistsBits(bool on) { _wantsExistBits = on; }; - bool getWantExistsBits() const { return _wantsExistBits; }; - private: // disallow copying of VoxelSystem objects VoxelSystem(const VoxelSystem&); @@ -157,8 +153,6 @@ private: bool _voxelsDirty; - bool _wantsExistBits; - public: void updateVBOs(); void updateFullVBOs(); // all voxels in the VBO diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b6e8c4be6a..ad969853e1 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -57,8 +57,7 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _wantResIn(false), _wantColor(true), - _wantDelta(false), - _wantExistsBits(false) + _wantDelta(false) { }; @@ -137,7 +136,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); } if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); } if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); } - if (_wantExistsBits) { setAtBit(wantItems,WANT_EXISTS_BITS_BIT); } *destinationBuffer++ = wantItems; return destinationBuffer - bufferStart; @@ -224,7 +222,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { _wantResIn = oneAtBit(wantItems,WANT_RESIN_AT_BIT); _wantColor = oneAtBit(wantItems,WANT_COLOR_AT_BIT); _wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT); - _wantExistsBits = oneAtBit(wantItems,WANT_EXISTS_BITS_BIT); return sourceBuffer - startPosition; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 41335c33fe..c961ff596a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -18,7 +18,6 @@ const int WANT_RESIN_AT_BIT = 0; const int WANT_COLOR_AT_BIT = 1; const int WANT_DELTA_AT_BIT = 2; -const int WANT_EXISTS_BITS_BIT = 4; enum KeyState { @@ -105,11 +104,9 @@ public: bool getWantResIn() const { return _wantResIn; } bool getWantColor() const { return _wantColor; } bool getWantDelta() const { return _wantDelta; } - bool getWantExistsBits() const { return _wantExistsBits; } void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } void setWantColor(bool wantColor) { _wantColor = wantColor; } void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } - void setWantExistsBits(bool wantExistsBits) { _wantExistsBits = wantExistsBits; } protected: // privatize the copy constructor and assignment operator so they cannot be called @@ -161,7 +158,6 @@ protected: bool _wantResIn; bool _wantColor; bool _wantDelta; - bool _wantExistsBits; }; #endif /* defined(__hifi__AvatarData__) */ diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index c4a5631abf..b2b50da169 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -19,6 +19,8 @@ typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; +#define WANT_EXISTS_BITS true + class VoxelTree { public: // when a voxel is created in the tree (object new'd) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index e5d70567ca..a55e415e50 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -168,7 +168,7 @@ void resInVoxelDistributor(AgentList* agentList, bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, agentData->nodeBag, &viewFrustum, - agentData->getWantColor(),agentData->getWantExistsBits()); + agentData->getWantColor(),WANT_EXISTS_BITS); if (agentData->getAvailable() >= bytesWritten) { agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); @@ -306,7 +306,7 @@ printf("huh... bag STILL empty, what to do? Add the root?...\n"); bytesWritten = randomTree.encodeTreeBitstream(INT_MAX, subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, agentData->nodeBag, &agentData->getCurrentViewFrustum(), - agentData->getWantColor(), agentData->getWantExistsBits(), + agentData->getWantColor(), WANT_EXISTS_BITS, wantDelta, lastViewFrustum); if (agentData->getAvailable() >= bytesWritten) { From 0dde5b64116519cb41d0fbc96f95ad8cb1e681a1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:28:12 -0700 Subject: [PATCH 07/23] remove dead code, comment cleanup --- interface/src/Application.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 68237bf63f..0adaa3aadf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2049,11 +2049,9 @@ void Application::maybeEditVoxelUnderCursor() { void Application::deleteVoxelUnderCursor() { if (_mouseVoxel.s != 0) { + // sending delete to the server is sufficient, server will send new version so we see updates soon enough sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel); - // delete the voxel locally so it disappears immediately - //_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - // remember the position for drag detection _justEditedVoxel = true; } From a7f0a66aeeaa13e03d71c568c6ffff74957d3fa6 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:31:47 -0700 Subject: [PATCH 08/23] code cleanup --- interface/src/VoxelSystem.cpp | 4 ++-- libraries/voxels/src/VoxelTree.h | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index e6d27a3921..ac8b71f66e 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -106,14 +106,14 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { { PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree - _tree->readBitstreamToTree(voxelData, numBytes - 1, true, WANT_EXISTS_BITS); + _tree->readBitstreamToTree(voxelData, numBytes - 1, WANT_COLOR, WANT_EXISTS_BITS); } break; case PACKET_HEADER_VOXEL_DATA_MONOCHROME: { PerformanceWarning warn(_renderWarningsOn, "readBitstreamToTree()"); // ask the VoxelTree to read the MONOCHROME bitstream into the tree - _tree->readBitstreamToTree(voxelData, numBytes - 1, false, WANT_EXISTS_BITS); + _tree->readBitstreamToTree(voxelData, numBytes - 1, NO_COLOR, WANT_EXISTS_BITS); } break; case PACKET_HEADER_Z_COMMAND: diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index b2b50da169..d0056534f5 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -19,7 +19,10 @@ typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; +#define NO_EXISTS_BITS false #define WANT_EXISTS_BITS true +#define NO_COLOR false +#define WANT_COLOR true class VoxelTree { public: @@ -43,7 +46,7 @@ public: void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes); void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, - bool includeColor = true, bool includeExistsBits = false); + bool includeColor = WANT_COLOR, bool includeExistsBits = false); void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false); void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false); void printTreeForDebugging(VoxelNode *startNode); @@ -61,7 +64,7 @@ public: int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum, - bool includeColor = true, bool includeExistsBits = false, + bool includeColor = WANT_COLOR, bool includeExistsBits = false, bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const; int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag, @@ -100,7 +103,7 @@ private: 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, - bool includeColor = true, bool includeExistsBits = false); + bool includeColor = WANT_COLOR, bool includeExistsBits = false); bool _isDirty; unsigned long int _nodesChangedFromBitstream; From 3220f986d60aa17e0ac32092f053cbf6bbd0665f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:33:32 -0700 Subject: [PATCH 09/23] code cleanup --- libraries/avatars/src/AvatarData.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ad969853e1..d63d4d1563 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -59,7 +59,7 @@ AvatarData::AvatarData() : _wantColor(true), _wantDelta(false) { -}; +} int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { unsigned char* bufferStart = destinationBuffer; @@ -133,9 +133,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // voxel sending features... // voxel sending features... unsigned char wantItems = 0; - if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); } - if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); } - if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); } + if (_wantResIn) { setAtBit(wantItems,WANT_RESIN_AT_BIT); } + if (_wantColor) { setAtBit(wantItems,WANT_COLOR_AT_BIT); } + if (_wantDelta) { setAtBit(wantItems,WANT_DELTA_AT_BIT); } *destinationBuffer++ = wantItems; return destinationBuffer - bufferStart; @@ -219,9 +219,9 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { // voxel sending features... unsigned char wantItems = 0; wantItems = (unsigned char)*sourceBuffer++; - _wantResIn = oneAtBit(wantItems,WANT_RESIN_AT_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; } From e29bc9972f4f7e934caacb1b138853bacd837abd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:34:31 -0700 Subject: [PATCH 10/23] code cleanup --- libraries/avatars/src/AvatarData.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c961ff596a..2c676d6120 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -101,12 +101,12 @@ public: const std::string& chatMessage () const { return _chatMessage; } // related to Voxel Sending strategies - bool getWantResIn() const { return _wantResIn; } - bool getWantColor() const { return _wantColor; } - bool getWantDelta() const { return _wantDelta; } - void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } - void setWantColor(bool wantColor) { _wantColor = wantColor; } - void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } + bool getWantResIn() const { return _wantResIn; } + bool getWantColor() const { return _wantColor; } + bool getWantDelta() const { return _wantDelta; } + void setWantResIn(bool wantResIn) { _wantResIn = wantResIn; } + void setWantColor(bool wantColor) { _wantColor = wantColor; } + void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } protected: // privatize the copy constructor and assignment operator so they cannot be called From 7c9be4b9f5c93e3305a09ca8a03b5b30e8055d22 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:42:13 -0700 Subject: [PATCH 11/23] cleanup code --- interface/src/VoxelSystem.cpp | 8 ++++---- libraries/shared/src/SharedUtil.h | 5 +++-- libraries/voxels/src/ViewFrustum.cpp | 2 +- libraries/voxels/src/VoxelNode.cpp | 4 ++-- voxel-server/src/main.cpp | 17 ++++++++--------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index ac8b71f66e..a610adf517 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -182,7 +182,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { if (_tree->isDirty()) { static char buffer[64] = { 0 }; if (_renderWarningsOn) { - sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", (_writeRenderFullVBO ? "yes" : "no")); + sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", debug::valueOf(_writeRenderFullVBO)); }; PerformanceWarning warn(_renderWarningsOn, buffer); _callsToTreesToArrays++; @@ -610,7 +610,7 @@ void VoxelSystem::updatePartialVBOs() { void VoxelSystem::updateVBOs() { static char buffer[40] = { 0 }; if (_renderWarningsOn) { - sprintf(buffer, "updateVBOs() _readRenderFullVBO=%s", (_readRenderFullVBO ? "yes" : "no")); + sprintf(buffer, "updateVBOs() _readRenderFullVBO=%s", debug::valueOf(_readRenderFullVBO)); }; PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays if (_voxelsDirty) { @@ -1011,7 +1011,7 @@ bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* ex if (args->hasIndexFound[nodeIndex]) { args->duplicateVBOIndex++; printLog("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex, - node->isDirty() ? "yes" : "no" , node->getShouldRender() ? "yes" : "no" ); + debug::valueOf(node->isDirty()), debug::valueOf(node->getShouldRender())); } else { args->hasIndexFound[nodeIndex] = true; } @@ -1040,7 +1040,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { args.expectedMax = _voxelsInWriteArrays; _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args); - printLog("_voxelsDirty=%s _voxelsInWriteArrays=%ld minDirty=%ld maxDirty=%ld \n", (_voxelsDirty ? "yes" : "no"), + printLog("_voxelsDirty=%s _voxelsInWriteArrays=%ld minDirty=%ld maxDirty=%ld \n", debug::valueOf(_voxelsDirty), _voxelsInWriteArrays, minDirty, maxDirty); printLog("stats: total %ld, leaves %ld, dirty %ld, colored %ld, shouldRender %ld, inVBO %ld\n", diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index ebaa802890..2458e1e5a2 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -80,8 +80,9 @@ int insertIntoSortedArrays(void* value, float key, int originalIndex, void** valueArray, float* keyArray, int* originalIndexArray, int currentCount, int maxCount); -class debugHelpers { +// Helper Class for debugging +class debug { public: - static const char* booleanValue(bool checkValue) { return checkValue ? "yes" : "no"; }; + static const char* valueOf(bool checkValue) { return checkValue ? "yes" : "no"; }; }; #endif /* defined(__hifi__SharedUtil__) */ diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index cce3eac76f..d03678ce42 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -243,7 +243,7 @@ bool ViewFrustum::matches(const ViewFrustum& compareTo) const { compareTo._eyeOffsetOrientation == _eyeOffsetOrientation; if (!result && debug) { - printLog("ViewFrustum::matches()... result=%s\n", (result ? "yes" : "no")); + printLog("ViewFrustum::matches()... result=%s\n", debug::valueOf(result)); printLog("%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f\n", (compareTo._position == _position ? "MATCHES " : "NO MATCH"), compareTo._position.x, compareTo._position.y, compareTo._position.z, diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index d33b7c1051..cb9558a466 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -278,8 +278,8 @@ void VoxelNode::printDebugDetails(const char* label) const { 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()) ); + debug::valueOf(isLeaf()), debug::valueOf(isColored()), debug::valueOf(isDirty()), + debug::valueOf(getShouldRender()) ); outputBits(childBits,false); printLog("\n octalCode="); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index a55e415e50..930356a7b5 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -247,9 +247,8 @@ void deepestLevelVoxelDistributor(AgentList* agentList, if (::debugVoxelSending) { printf("deepestLevelVoxelDistributor() viewFrustumChanged=%s, nodeBag.isEmpty=%s, viewSent=%s\n", - viewFrustumChanged ? "yes" : "no", - agentData->nodeBag.isEmpty() ? "yes" : "no", - agentData->getViewSent() ? "yes" : "no" + debug::valueOf(viewFrustumChanged), debug::valueOf(agentData->nodeBag.isEmpty()), + debug::valueOf(agentData->getViewSent()) ); } @@ -416,7 +415,7 @@ void *distributeVoxelsToListeners(void *args) { if (agentData) { bool viewFrustumChanged = agentData->updateCurrentViewFrustum(); if (::debugVoxelSending) { - printf("agentData->updateCurrentViewFrustum() changed=%s\n", (viewFrustumChanged ? "yes" : "no")); + printf("agentData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged)); } if (agentData->getWantResIn()) { @@ -468,22 +467,22 @@ int main(int argc, const char * argv[]) const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending"; ::debugVoxelSending = cmdOptionExists(argc, argv, DEBUG_VOXEL_SENDING); - printf("debugVoxelSending=%s\n", (::debugVoxelSending ? "yes" : "no")); + printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending)); const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug"; ::shouldShowAnimationDebug = cmdOptionExists(argc, argv, WANT_ANIMATION_DEBUG); - printf("shouldShowAnimationDebug=%s\n", (::shouldShowAnimationDebug ? "yes" : "no")); + printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug)); const char* WANT_COLOR_RANDOMIZER = "--wantColorRandomizer"; ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); + printf("wantColorRandomizer=%s\n", debug::valueOf(::wantColorRandomizer)); // By default we will voxel persist, if you want to disable this, then pass in this parameter const char* NO_VOXEL_PERSIST = "--NoVoxelPersist"; if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) { ::wantVoxelPersist = false; } - printf("wantVoxelPersist=%s\n", (::wantVoxelPersist ? "yes" : "no")); + printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist)); // if we want Voxel Persistance, load the local file now... bool persistantFileRead = false; @@ -491,7 +490,7 @@ int main(int argc, const char * argv[]) printf("loading voxels from file...\n"); persistantFileRead = ::randomTree.readFromFileV2(::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE); ::randomTree.clearDirtyBit(); // the tree is clean since we just loaded it - printf("DONE loading voxels from file... fileRead=%s\n", persistantFileRead ? "yes" : "no" ); + printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead)); unsigned long nodeCount = ::randomTree.getVoxelCount(); printf("Nodes after loading scene %ld nodes\n", nodeCount); } From e47d9ea21fb10d927ca6bc4148881c242f24b286 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:44:48 -0700 Subject: [PATCH 12/23] cleanup code --- libraries/voxels/src/VoxelTree.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index ea77d0175f..5a8ed2368a 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -99,15 +99,7 @@ VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * // returns the node created! VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char* 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->getChildAtIndex(indexOfNewChild)) { - lastParentNode->addChildAtIndex(indexOfNewChild); - } -***/ if (lastParentNode->isLeaf() && lastParentNode->isColored()) { // for colored leaves, we must add *all* the children for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { From b61d6cf4e81e638fde710853fdbd2af608d5cb75 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:48:30 -0700 Subject: [PATCH 13/23] cleanup code --- libraries/voxels/src/VoxelTree.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 5a8ed2368a..b398e89d61 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -100,6 +100,8 @@ VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * // returns the node created! VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char* codeToReach) { int indexOfNewChild = branchIndexWithDescendant(lastParentNode->getOctalCode(), codeToReach); + // If this parent node is a leaf, then you know the child path doesn't exist, so deal with + // breaking up the leaf first, which will also create a child path if (lastParentNode->isLeaf() && lastParentNode->isColored()) { // for colored leaves, we must add *all* the children for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { @@ -107,6 +109,7 @@ VoxelNode* VoxelTree::createMissingNode(VoxelNode* lastParentNode, unsigned char lastParentNode->getChildAtIndex(i)->setColor(lastParentNode->getColor()); } } else if (!lastParentNode->getChildAtIndex(indexOfNewChild)) { + // we could be coming down a branch that was already created, so don't stomp on it. lastParentNode->addChildAtIndex(indexOfNewChild); } From e8fd96018b665701bc27caa19f39904d7211f6bf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:52:57 -0700 Subject: [PATCH 14/23] cleanup code --- libraries/voxels/src/VoxelTree.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index b398e89d61..3f19fea785 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -129,7 +129,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, unsigned char colorInTreeMask = includeExistsBits ? *(nodeData+1) : ALL_CHILDREN_ASSUMED_TO_EXIST; // instantiate variable for bytes already read - int bytesRead = includeExistsBits ? 2 : 1; + int bytesRead = includeExistsBits ? sizeof(colorInPacketMask) + sizeof(colorInTreeMask): sizeof(colorInPacketMask); 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(colorInPacketMask, i)) { @@ -166,10 +166,10 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, // give this destination node the child mask from the packet unsigned char childrenInTreeMask = includeExistsBits ? *(nodeData + bytesRead) : ALL_CHILDREN_ASSUMED_TO_EXIST; - unsigned char childMask = *(nodeData + bytesRead + (includeExistsBits ? 1 : 0) ); + unsigned char childMask = *(nodeData + bytesRead + (includeExistsBits ? sizeof(childrenInTreeMask) : 0) ); int childIndex = 0; - bytesRead += includeExistsBits ? 2 : 1; + bytesRead += includeExistsBits ? sizeof(childrenInTreeMask) + sizeof(childMask) : sizeof(childMask); while (bytesLeftToRead - bytesRead > 0 && childIndex < NUMBER_OF_CHILDREN) { // check the exists mask to see if we have a child to traverse into From edcc92cfb6d82d4f21de02b253b5fbf558e7b299 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 11:58:48 -0700 Subject: [PATCH 15/23] cleanup code --- libraries/voxels/src/VoxelTree.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 3f19fea785..3248989ab9 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -452,7 +452,6 @@ void VoxelTree::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { bool bail = false; while (!file.eof() && !bail) { file.get(octets); - //printLog("octets=%d...\n",octets); totalBytesRead++; lengthInBytes = bytesRequiredForCodeLength(octets) - 1; unsigned char * voxelData = new unsigned char[lengthInBytes + 1 + 3]; @@ -837,7 +836,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco const ViewFrustum* viewFrustum, bool includeColor, bool includeExistsBits, bool deltaViewFrustum, const ViewFrustum* lastViewFrustum) const { -//printLog("encodeTreeBitstreamRecursion() currentEncodeLevel=%d\n",currentEncodeLevel); // How many bytes have we written so far at this level; int bytesAtThisLevel = 0; @@ -897,7 +895,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco // 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)); @@ -938,14 +935,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco 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 @@ -965,7 +954,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco // if the caller wants to include childExistsBits, then include them even if not in view, put them before the // 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 @@ -1032,7 +1020,6 @@ 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 if (includeColor && childTreeBytesOut == 2) { 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; @@ -1042,7 +1029,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco // 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 if (childTreeBytesOut == 0) { -//printLog("childTreeBytesOut == 0... actually lopping empty lower tree\n"); // remove this child's bit... childrenExistInPacketBits -= (1 << (7 - i)); // repair the child exists mask From d637ef40781c9121814ba8a22f3a37e45215f10d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 12:02:26 -0700 Subject: [PATCH 16/23] cleanup code --- voxel-server/src/main.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 930356a7b5..ceb36de219 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -175,8 +175,6 @@ void resInVoxelDistributor(AgentList* agentList, } else { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - //printf("sending packet..."); - //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; packetsSentThisInterval++; @@ -187,8 +185,6 @@ void resInVoxelDistributor(AgentList* agentList, if (agentData->isPacketWaiting()) { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - //printf("sending packet..."); - //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; agentData->resetVoxelPacket(); @@ -236,8 +232,6 @@ void deepestLevelVoxelDistributor(AgentList* agentList, VoxelAgentData* agentData, bool viewFrustumChanged) { -//printf("deepestLevelVoxelDistributor()\n"); - int maxLevelReached = 0; double start = usecTimestampNow(); @@ -313,9 +307,6 @@ printf("huh... bag STILL empty, what to do? Add the root?...\n"); } else { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - - //printf("sending packet..."); - //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; packetsSentThisInterval++; @@ -326,8 +317,6 @@ printf("huh... bag STILL empty, what to do? Add the root?...\n"); if (agentData->isPacketWaiting()) { agentList->getAgentSocket()->send(agent->getActiveSocket(), agentData->getPacket(), agentData->getPacketLength()); - //printf("sending packet..."); - //outputBufferBits((unsigned char*)agentData->getPacket(), agentData->getPacketLength()); trueBytesSent += agentData->getPacketLength(); truePacketsSent++; agentData->resetVoxelPacket(); @@ -555,18 +544,12 @@ int main(int argc, const char * argv[]) persistVoxelsWhenDirty(); 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 if (packetData[0] == PACKET_HEADER_SET_VOXEL || packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) { bool destructive = (packetData[0] == PACKET_HEADER_SET_VOXEL_DESTRUCTIVE); - PerformanceWarning warn(::shouldShowAnimationDebug, destructive ? "PACKET_HEADER_SET_VOXEL_DESTRUCTIVE" : "PACKET_HEADER_SET_VOXEL", ::shouldShowAnimationDebug); - unsigned short int itemNumber = (*((unsigned short int*)&packetData[1])); - if (::shouldShowAnimationDebug) { printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n", destructive ? "PACKET_HEADER_SET_VOXEL_DESTRUCTIVE" : "PACKET_HEADER_SET_VOXEL", From 9b5ee051413e798424947cd70961567f0c9111fd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 12:04:48 -0700 Subject: [PATCH 17/23] added some sample files --- tools/samples/cube1.hio | Bin 0 -> 42 bytes tools/samples/oneRedVoxel.hio | Bin 0 -> 6 bytes tools/samples/simple1.hio | Bin 0 -> 6 bytes tools/samples/single.hio | Bin 0 -> 7 bytes tools/samples/small.hio | Bin 0 -> 14 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 tools/samples/cube1.hio create mode 100755 tools/samples/oneRedVoxel.hio create mode 100644 tools/samples/simple1.hio create mode 100755 tools/samples/single.hio create mode 100644 tools/samples/small.hio diff --git a/tools/samples/cube1.hio b/tools/samples/cube1.hio new file mode 100755 index 0000000000000000000000000000000000000000..8c2b2c80b49c4c10978a1e7c3c3f4b021be5066e GIT binary patch literal 42 fcmZQ$;Ba90&%nmO$pEG}8X(jKh#*9+0VD?iri2KY literal 0 HcmV?d00001 diff --git a/tools/samples/oneRedVoxel.hio b/tools/samples/oneRedVoxel.hio new file mode 100755 index 0000000000000000000000000000000000000000..4168d58ae24129505310c55d21e68d8422b37984 GIT binary patch literal 6 NcmZSn-|(M-0RRdR0)hYl literal 0 HcmV?d00001 diff --git a/tools/samples/simple1.hio b/tools/samples/simple1.hio new file mode 100644 index 0000000000000000000000000000000000000000..30164b7cc7f24c9bef151b87f30a8ad381897865 GIT binary patch literal 6 NcmZQ>VEF%^0RRV+0)hYl literal 0 HcmV?d00001 diff --git a/tools/samples/single.hio b/tools/samples/single.hio new file mode 100755 index 0000000000000000000000000000000000000000..f2b541326a9f563026deda17fd1be15937300bd3 GIT binary patch literal 7 OcmZQ)U|?YQ&j0`dHUS3! literal 0 HcmV?d00001 diff --git a/tools/samples/small.hio b/tools/samples/small.hio new file mode 100644 index 0000000000000000000000000000000000000000..c49f667491d6c286885daf51abf71bbaa443cbe9 GIT binary patch literal 14 VcmZQ)U|?YQ&%n;WpuoWJ9{>v%0xbXl literal 0 HcmV?d00001 From 6c309d2ecea5d812dff58ab96be90b0689e466c1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 12:40:03 -0700 Subject: [PATCH 18/23] made wantSearchForColoredNodes a command line option defautl to false --- voxel-server/src/main.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index ceb36de219..27362e26db 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -57,8 +57,7 @@ bool wantLocalDomain = false; bool wantColorRandomizer = false; bool debugVoxelSending = false; bool shouldShowAnimationDebug = false; - - +bool wantSearchForColoredNodes = false; EnvironmentData environmentData; @@ -249,23 +248,24 @@ void deepestLevelVoxelDistributor(AgentList* agentList, // If the current view frustum has changed OR we have nothing to send, then search against // the current view frustum for things to send. if (viewFrustumChanged || agentData->nodeBag.isEmpty()) { - - // just add the rootNode, to see if this addresses the delete problem - agentData->nodeBag.insert(randomTree.rootNode); -/*** -//printf("bag empty, search for stuff in view...\n"); - // If the bag was empty, then send everything in view, not just the delta - maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(), - agentData->nodeBag, wantDelta, lastViewFrustum); + // For now, we're going to disable the "search for colored nodes" because that strategy doesn't work when we support + // deletion of nodes. Instead if we just start at the root we get the correct behavior we want. We are keeping this + // code for now because we want to be able to go back to it and find a solution to support both. The search method + // helps improve overall bitrate performance. + if (::wantSearchForColoredNodes) { + // If the bag was empty, then send everything in view, not just the delta + maxLevelReached = randomTree.searchForColoredNodes(INT_MAX, randomTree.rootNode, agentData->getCurrentViewFrustum(), + agentData->nodeBag, wantDelta, lastViewFrustum); - // if nothing was found in view, send the root node. - if (agentData->nodeBag.isEmpty()){ -printf("huh... bag STILL empty, what to do? Add the root?...\n"); + // if nothing was found in view, send the root node. + if (agentData->nodeBag.isEmpty()){ + agentData->nodeBag.insert(randomTree.rootNode); + } + agentData->setViewSent(false); + } else { agentData->nodeBag.insert(randomTree.rootNode); } - agentData->setViewSent(false); -**/ } double end = usecTimestampNow(); @@ -466,6 +466,10 @@ int main(int argc, const char * argv[]) ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); printf("wantColorRandomizer=%s\n", debug::valueOf(::wantColorRandomizer)); + const char* WANT_SEARCH_FOR_NODES = "--wantSearchForColoredNodes"; + ::wantSearchForColoredNodes = cmdOptionExists(argc, argv, WANT_SEARCH_FOR_NODES); + printf("wantSearchForColoredNodes=%s\n", debug::valueOf(::wantSearchForColoredNodes)); + // By default we will voxel persist, if you want to disable this, then pass in this parameter const char* NO_VOXEL_PERSIST = "--NoVoxelPersist"; if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) { From d6d9b053f5e073fd05f7273a3bbec536337bdf5a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 12:45:40 -0700 Subject: [PATCH 19/23] removed extra color exists bitmask since we weren't using it and it was redundant --- libraries/voxels/src/VoxelTree.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 3248989ab9..d7b7a11d87 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -126,10 +126,9 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, // 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 - int bytesRead = includeExistsBits ? sizeof(colorInPacketMask) + sizeof(colorInTreeMask): sizeof(colorInPacketMask); + int bytesRead = sizeof(colorInPacketMask); 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(colorInPacketMask, i)) { @@ -881,7 +880,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco unsigned char* writeToThisLevelBuffer = &thisLevelBuffer[0]; unsigned char childrenExistInTreeBits = 0; - unsigned char colorsExistInTreeBits = 0; unsigned char childrenExistInPacketBits = 0; unsigned char childrenColoredBits = 0; int inViewCount = 0; @@ -896,9 +894,6 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco // if the caller wants to include childExistsBits, then include them even if not in view if (includeExistsBits && childNode) { childrenExistInTreeBits += (1 << (7 - i)); - if (childNode->isColored()) { - colorsExistInTreeBits += (1 << (7 - i)); - } } bool childIsInView = (childNode && (!viewFrustum || childNode->isInView(*viewFrustum))); @@ -933,13 +928,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(int maxEncodeLevel, int& currentEnco *writeToThisLevelBuffer = childrenColoredBits; writeToThisLevelBuffer += sizeof(childrenColoredBits); // move the pointer 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) { - *writeToThisLevelBuffer = colorsExistInTreeBits; - writeToThisLevelBuffer += sizeof(colorsExistInTreeBits); // move the pointer - bytesAtThisLevel += sizeof(colorsExistInTreeBits); // keep track of byte count - } - + // write the color data... if (includeColor) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { From 869a100486dbea9bad2f8749aec51fa7c6406040 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 13:37:58 -0700 Subject: [PATCH 20/23] cleanup --- libraries/voxels/src/VoxelTree.cpp | 4 ++-- libraries/voxels/src/VoxelTree.h | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index d7b7a11d87..3bf8b7a7a8 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1043,7 +1043,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, true); + readBitstreamToTree(entireFile, fileLength, WANT_COLOR, NO_EXISTS_BITS); delete[] entireFile; file.close(); @@ -1068,7 +1068,7 @@ 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, true); + MAX_VOXEL_PACKET_SIZE - 1, nodeBag, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); file.write((const char*)&outputBuffer[0], bytesWritten); } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index d0056534f5..4cc2e722e4 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -19,10 +19,11 @@ typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, void* extraData); typedef enum {GRADIENT, RANDOM, NATURAL} creationMode; -#define NO_EXISTS_BITS false -#define WANT_EXISTS_BITS true -#define NO_COLOR false -#define WANT_COLOR true +#define NO_EXISTS_BITS false +#define WANT_EXISTS_BITS true +#define NO_COLOR false +#define WANT_COLOR true +#define IGNORE_VIEW_FRUSTUM NULL class VoxelTree { public: @@ -46,7 +47,7 @@ public: void processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes); void readBitstreamToTree(unsigned char * bitstream, unsigned long int bufferSizeBytes, - bool includeColor = WANT_COLOR, bool includeExistsBits = false); + bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS); void readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool destructive = false); void deleteVoxelCodeFromTree(unsigned char *codeBuffer, bool stage = false); void printTreeForDebugging(VoxelNode *startNode); @@ -64,7 +65,7 @@ public: int encodeTreeBitstream(int maxEncodeLevel, VoxelNode* node, unsigned char* outputBuffer, int availableBytes, VoxelNodeBag& bag, const ViewFrustum* viewFrustum, - bool includeColor = WANT_COLOR, bool includeExistsBits = false, + bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, bool deltaViewFrustum = false, const ViewFrustum* lastViewFrustum = NULL) const; int searchForColoredNodes(int maxSearchLevel, VoxelNode* node, const ViewFrustum& viewFrustum, VoxelNodeBag& bag, @@ -103,7 +104,7 @@ private: 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, - bool includeColor = WANT_COLOR, bool includeExistsBits = false); + bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS); bool _isDirty; unsigned long int _nodesChangedFromBitstream; From fb4424e975f33702197a8c94ae0a10f19efb2bce Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 14:07:03 -0700 Subject: [PATCH 21/23] don't rebroadcase PACKET_HEADER_ERASE_VOXEL messages --- voxel-server/src/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 27362e26db..e4fa76dc60 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -606,11 +606,6 @@ int main(int argc, const char * argv[]) // Send these bits off to the VoxelTree class to process them printf("got Erase Voxels message, have voxel tree do the work... randomTree.processRemoveVoxelBitstream()\n"); randomTree.processRemoveVoxelBitstream((unsigned char*)packetData,receivedBytes); - - // Now send this to the connected agents so they know to delete - printf("rebroadcasting delete voxel message to connected agents... agentList.broadcastToAgents()\n"); - agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_AVATAR, 1); - } if (packetData[0] == PACKET_HEADER_Z_COMMAND) { From 166ad4f73d4ac5857c33bb444fd9d7db1ed6c057 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 17:37:21 -0700 Subject: [PATCH 22/23] CR feedback --- libraries/voxels/src/VoxelNode.cpp | 4 ++-- libraries/voxels/src/VoxelTree.cpp | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 9fe1de2af4..5125e2d574 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -279,9 +279,9 @@ void VoxelNode::printDebugDetails(const char* label) const { 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, debug::valueOf(isLeaf()), debug::valueOf(isColored()), debug::valueOf(isDirty()), - debug::valueOf(getShouldRender()) ); + debug::valueOf(getShouldRender())); - outputBits(childBits,false); + outputBits(childBits, false); printLog("\n octalCode="); printOctalCode(_octalCode); } diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index c340b40572..4922a22f5a 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -165,7 +165,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, // give this destination node the child mask from the packet unsigned char childrenInTreeMask = includeExistsBits ? *(nodeData + bytesRead) : ALL_CHILDREN_ASSUMED_TO_EXIST; - unsigned char childMask = *(nodeData + bytesRead + (includeExistsBits ? sizeof(childrenInTreeMask) : 0) ); + unsigned char childMask = *(nodeData + bytesRead + (includeExistsBits ? sizeof(childrenInTreeMask) : 0)); int childIndex = 0; bytesRead += includeExistsBits ? sizeof(childrenInTreeMask) + sizeof(childMask) : sizeof(childMask); @@ -354,17 +354,12 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer, bool d void VoxelTree::processRemoveVoxelBitstream(unsigned char * bitstream, int bufferSizeBytes) { // XXXBHG: validate buffer is at least 4 bytes long? other guards?? unsigned short int itemNumber = (*((unsigned short int*)&bitstream[1])); - printLog("processRemoveVoxelBitstream() receivedBytes=%d itemNumber=%d\n",bufferSizeBytes,itemNumber); int atByte = 3; unsigned char* pVoxelData = (unsigned char*)&bitstream[3]; while (atByte < bufferSizeBytes) { unsigned char octets = (unsigned char)*pVoxelData; int voxelDataSize = bytesRequiredForCodeLength(octets)+3; // 3 for color! - float* vertices = firstVertexForCode(pVoxelData); - printLog("deleting voxel at: %f,%f,%f\n",vertices[0],vertices[1],vertices[2]); - delete []vertices; - deleteVoxelCodeFromTree(pVoxelData); pVoxelData+=voxelDataSize; From c316899f27164fe45e40b4ffd20e4929b617c712 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 21 May 2013 17:42:55 -0700 Subject: [PATCH 23/23] CR feedback --- libraries/voxels/src/VoxelTree.cpp | 2 +- voxel-server/src/main.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 4922a22f5a..31d68ecc45 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -268,7 +268,7 @@ void VoxelTree::deleteVoxelCodeFromTree(unsigned char* codeBuffer, bool stage) { int lengthInBytes = bytesRequiredForCodeLength(*codeBuffer); // includes octet count, not color! // if the code we got back matches our target, then we know we can actually delete it - if (0 == memcmp(nodeToDelete->getOctalCode(), codeBuffer, lengthInBytes)) { + if (memcmp(nodeToDelete->getOctalCode(), codeBuffer, lengthInBytes) == 0) { if (parentNode) { int childIndex = branchIndexWithDescendant(parentNode->getOctalCode(), codeBuffer); if (stage) { diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index e4fa76dc60..c258ad052c 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -167,7 +167,7 @@ void resInVoxelDistributor(AgentList* agentList, bytesWritten = randomTree.encodeTreeBitstream(agentData->getMaxSearchLevel(), subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, agentData->nodeBag, &viewFrustum, - agentData->getWantColor(),WANT_EXISTS_BITS); + agentData->getWantColor(), WANT_EXISTS_BITS); if (agentData->getAvailable() >= bytesWritten) { agentData->writeToPacket(&tempOutputBuffer[0], bytesWritten); @@ -604,7 +604,7 @@ int main(int argc, const char * argv[]) if (packetData[0] == PACKET_HEADER_ERASE_VOXEL) { // Send these bits off to the VoxelTree class to process them - printf("got Erase Voxels message, have voxel tree do the work... randomTree.processRemoveVoxelBitstream()\n"); + //printf("got Erase Voxels message, have voxel tree do the work... randomTree.processRemoveVoxelBitstream()\n"); randomTree.processRemoveVoxelBitstream((unsigned char*)packetData,receivedBytes); } if (packetData[0] == PACKET_HEADER_Z_COMMAND) {