From 9b0cc14552d7313093e7a32b5fc7f419131f477c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 17 Oct 2013 16:14:06 -0700 Subject: [PATCH] fix voxel nodes to work with new UUID format --- interface/src/VoxelPacketProcessor.cpp | 4 +- interface/src/VoxelSystem.cpp | 28 +++++++------- interface/src/VoxelSystem.h | 6 +-- libraries/voxels/src/VoxelNode.cpp | 53 +++++++++++++++++++++++++- libraries/voxels/src/VoxelNode.h | 18 +++++++-- libraries/voxels/src/VoxelTree.cpp | 2 +- libraries/voxels/src/VoxelTree.h | 6 +-- 7 files changed, 91 insertions(+), 26 deletions(-) diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index 7d2c59eeb7..9e189aac64 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -50,9 +50,9 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) { app->_environment.parseData(&senderAddress, packetData, messageLength); } else { - app->_voxels.setDataSourceID(0); + app->_voxels.setDataSourceUUID(voxelServer->getUUID()); app->_voxels.parseData(packetData, messageLength); - app->_voxels.setDataSourceID(0); + app->_voxels.setDataSourceUUID(QUuid()); } } } diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 278bc51454..60e27c161a 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -82,7 +82,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) VoxelNode::addUpdateHook(this); _abandonedVBOSlots = 0; _falseColorizeBySource = false; - _dataSourceID = 0; + _dataSourceUUID = QUuid(); _voxelServerCount = 0; _viewFrustum = Application::getInstance()->getViewFrustum(); @@ -576,7 +576,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree - ReadBitstreamToTreeParams args(WANT_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceID()); + ReadBitstreamToTreeParams args(WANT_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID()); pthread_mutex_lock(&_treeLock); _tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args); pthread_mutex_unlock(&_treeLock); @@ -586,7 +586,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "readBitstreamToTree()"); // ask the VoxelTree to read the MONOCHROME bitstream into the tree - ReadBitstreamToTreeParams args(NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceID()); + ReadBitstreamToTreeParams args(NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID()); pthread_mutex_lock(&_treeLock); _tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args); pthread_mutex_unlock(&_treeLock); @@ -1417,8 +1417,8 @@ bool VoxelSystem::falseColorizeBySourceOperation(VoxelNode* node, void* extraDat _nodeCount++; if (node->isColored()) { // pick a color based on the source - we want each source to be obviously different - uint16_t nodeID = node->getSourceID(); - node->setFalseColor(args->colors[nodeID].red, args->colors[nodeID].green, args->colors[nodeID].blue); + uint16_t nodeIDKey = node->getSourceUUIDKey(); + node->setFalseColor(args->colors[nodeIDKey].red, args->colors[nodeIDKey].green, args->colors[nodeIDKey].blue); } return true; // keep going! } @@ -1442,7 +1442,7 @@ void VoxelSystem::falseColorizeBySource() { NodeList* nodeList = NodeList::getInstance(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (node->getType() == NODE_TYPE_VOXEL_SERVER) { - uint16_t nodeID = 0; // hardcoded since removal of 16 bit node IDs + uint16_t nodeID = VoxelNode::getSourceNodeUUIDKey(node->getUUID()); // hardcoded since removal of 16 bit node IDs int groupColor = voxelServerCount % NUMBER_OF_COLOR_GROUPS; args.colors[nodeID] = groupColors[groupColor]; @@ -2305,12 +2305,11 @@ void VoxelSystem::nodeAdded(Node* node) { } bool VoxelSystem::killSourceVoxelsOperation(VoxelNode* node, void* extraData) { - uint16_t killedNodeID = *(uint16_t*)extraData; + QUuid killedNodeID = *(QUuid*)extraData; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { VoxelNode* childNode = node->getChildAtIndex(i); if (childNode) { - uint16_t childNodeID = childNode->getSourceID(); - if (childNodeID == killedNodeID) { + if (childNode->matchesSourceUUID(killedNodeID)) { node->safeDeepDeleteChildAtIndex(i); } } @@ -2321,14 +2320,17 @@ bool VoxelSystem::killSourceVoxelsOperation(VoxelNode* node, void* extraData) { void VoxelSystem::nodeKilled(Node* node) { if (node->getType() == NODE_TYPE_VOXEL_SERVER) { _voxelServerCount--; - qDebug("VoxelSystem... voxel server %s removed...\n", node->getUUID().toString().toLocal8Bit().constData()); + + QUuid nodeUUID = node->getUUID(); + + qDebug("VoxelSystem... voxel server %s removed...\n", nodeUUID.toString().toLocal8Bit().constData()); if (_voxelServerCount > 0) { // Kill any voxels from the local tree that match this nodeID // commenting out for removal of 16 bit node IDs -// pthread_mutex_lock(&_treeLock); -// _tree->recurseTreeWithOperation(killSourceVoxelsOperation, 0); -// pthread_mutex_unlock(&_treeLock); + pthread_mutex_lock(&_treeLock); + _tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeUUID); + pthread_mutex_unlock(&_treeLock); _tree->setDirtyBit(); setupNewVoxelsForDrawing(); } else { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 1af6b19ca7..238b9f6d96 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -44,8 +44,8 @@ public: VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM); ~VoxelSystem(); - void setDataSourceID(int dataSourceID) { _dataSourceID = dataSourceID; } - int getDataSourceID() const { return _dataSourceID; } + void setDataSourceUUID(const QUuid& dataSourceUUID) { _dataSourceUUID = dataSourceUUID; } + const QUuid& getDataSourceUUID() const { return _dataSourceUUID; } int parseData(unsigned char* sourceBuffer, int numBytes); @@ -279,7 +279,7 @@ private: glBufferIndex getNextBufferIndex(); bool _falseColorizeBySource; - int _dataSourceID; + QUuid _dataSourceUUID; int _voxelServerCount; unsigned long _memoryUsageRAM; diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 192e1d3a64..9c5c81c19c 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -82,7 +82,7 @@ void VoxelNode::init(unsigned char * octalCode) { setVoxelSystem(NULL); _isDirty = true; _shouldRender = false; - _sourceID = 0; // hardcoded to 0 for removal of 16 bit node ID + _sourceUUIDKey = 0; // hardcoded to 0 for removal of 16 bit node ID calculateAABox(); markWithChangedTime(); @@ -170,6 +170,54 @@ void VoxelNode::setVoxelSystem(VoxelSystem* voxelSystem) { } +const uint16_t KEY_FOR_NULL = 0; +uint16_t VoxelNode::_nextUUIDKey = KEY_FOR_NULL + 1; // start at 1, 0 is reserved for NULL +std::map VoxelNode::_mapSourceUUIDsToKeys; +std::map VoxelNode::_mapKeysToSourceUUIDs; + +void VoxelNode::setSourceUUID(const QUuid& sourceUUID) { + uint16_t key; + QString sourceUUIDString = sourceUUID.toString(); + if (_mapSourceUUIDsToKeys.end() != _mapSourceUUIDsToKeys.find(sourceUUIDString)) { + key = _mapSourceUUIDsToKeys[sourceUUIDString]; + } else { + key = _nextUUIDKey; + _nextUUIDKey++; + _mapSourceUUIDsToKeys[sourceUUIDString] = key; + _mapKeysToSourceUUIDs[key] = sourceUUIDString; + } + _sourceUUIDKey = key; +} + +QUuid VoxelNode::getSourceUUID() const { + if (_sourceUUIDKey > KEY_FOR_NULL) { + if (_mapKeysToSourceUUIDs.end() != _mapKeysToSourceUUIDs.find(_sourceUUIDKey)) { + return QUuid(_mapKeysToSourceUUIDs[_sourceUUIDKey]); + } + } + return QUuid(); +} + +bool VoxelNode::matchesSourceUUID(const QUuid& sourceUUID) const { + if (_sourceUUIDKey > KEY_FOR_NULL) { + if (_mapKeysToSourceUUIDs.end() != _mapKeysToSourceUUIDs.find(_sourceUUIDKey)) { + return QUuid(_mapKeysToSourceUUIDs[_sourceUUIDKey]) == sourceUUID; + } + } + return sourceUUID.isNull(); +} + +uint16_t VoxelNode::getSourceNodeUUIDKey(const QUuid& sourceUUID) { + uint16_t key = KEY_FOR_NULL; + QString sourceUUIDString = sourceUUID.toString(); + if (_mapSourceUUIDsToKeys.end() != _mapSourceUUIDsToKeys.find(sourceUUIDString)) { + key = _mapSourceUUIDsToKeys[sourceUUIDString]; + } + return key; +} + + + void VoxelNode::setShouldRender(bool shouldRender) { // if shouldRender is changing, then consider ourselves dirty if (shouldRender != _shouldRender) { @@ -1026,6 +1074,9 @@ void VoxelNode::setColor(const nodeColor& color) { } #endif + + + // will detect if children are leaves AND the same color // and in that case will delete the children and make this node // a leaf, returns TRUE if all the leaves are collapsed into a diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 1734bb5c87..4f0fa96ecc 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -101,8 +101,12 @@ public: void setDensity(float density) { _density = density; } float getDensity() const { return _density; } - void setSourceID(uint16_t sourceID) { _sourceID = sourceID; } - uint16_t getSourceID() const { return _sourceID; } + + void setSourceUUID(const QUuid& sourceID); + QUuid getSourceUUID() const; + uint16_t getSourceUUIDKey() const { return _sourceUUIDKey; } + bool matchesSourceUUID(const QUuid& sourceUUID) const; + static uint16_t getSourceNodeUUIDKey(const QUuid& sourceUUID); static void addDeleteHook(VoxelNodeDeleteHook* hook); static void removeDeleteHook(VoxelNodeDeleteHook* hook); @@ -191,7 +195,15 @@ private: nodeColor _trueColor; /// Client and server, true color of this voxel, 4 bytes nodeColor _currentColor; /// Client only, false color of this voxel, 4 bytes - uint16_t _sourceID; /// Client only, stores node id of voxel server that sent his voxel, 2 bytes + + uint16_t _sourceUUIDKey; /// Client only, stores node id of voxel server that sent his voxel, 2 bytes + + // Support for _sourceUUID, we use these static member variables to track the UUIDs that are + // in use by various voxel server nodes. We map the UUID strings into an 16 bit key, this limits us to at + // most 65k voxel servers in use at a time within the client. Which is far more than we need. + static uint16_t _nextUUIDKey; // start at 1, 0 is reserved for NULL + static std::map _mapSourceUUIDsToKeys; + static std::map _mapKeysToSourceUUIDs; unsigned char _childBitmask; // 1 byte diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 283469b32a..eadba04e65 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -221,7 +221,7 @@ int VoxelTree::readNodeData(VoxelNode* destinationNode, unsigned char* nodeData, if (childNodeAt) { nodeWasDirty = childNodeAt->isDirty(); childNodeAt->setColor(newColor); - childNodeAt->setSourceID(args.sourceID); + childNodeAt->setSourceUUID(args.sourceUUID); // if we had a local version of the node already, it's possible that we have it in the VBO but // with the same color data, so this won't count as a change. To address this we check the following diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 0f96e45edc..a38c751133 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -101,19 +101,19 @@ public: bool includeColor; bool includeExistsBits; VoxelNode* destinationNode; - uint16_t sourceID; + QUuid sourceUUID; bool wantImportProgress; ReadBitstreamToTreeParams( bool includeColor = WANT_COLOR, bool includeExistsBits = WANT_EXISTS_BITS, VoxelNode* destinationNode = NULL, - uint16_t sourceID = 0, // hardcoded to 0 for removal of 16 bit node ID + QUuid sourceUUID = QUuid(), bool wantImportProgress = false) : includeColor(includeColor), includeExistsBits(includeExistsBits), destinationNode(destinationNode), - sourceID(sourceID), + sourceUUID(sourceUUID), wantImportProgress(wantImportProgress) {} };