Merge pull request #1080 from ZappoMan/voxelnode_memory_savings

fix voxel nodes to work with new UUID format
This commit is contained in:
Stephen Birarda 2013-10-17 16:35:40 -07:00
commit 964200cdab
7 changed files with 90 additions and 26 deletions

View file

@ -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());
}
}
}

View file

@ -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());
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 {

View file

@ -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;

View file

@ -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;
calculateAABox();
markWithChangedTime();
@ -169,6 +169,53 @@ 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<QString, uint16_t> VoxelNode::_mapSourceUUIDsToKeys;
std::map<uint16_t, QString> 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
@ -1026,6 +1073,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

View file

@ -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<QString, uint16_t> _mapSourceUUIDsToKeys;
static std::map<uint16_t, QString> _mapKeysToSourceUUIDs;
unsigned char _childBitmask; // 1 byte

View file

@ -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

View file

@ -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)
{}
};