diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2700ac3ad7..4e18a99259 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2377,16 +2377,14 @@ void Application::queryVoxels() { } } - // make sure there's at least one voxel server + // assume there's at least one voxel server if (voxelServerCount < 1) { - return; // no voxel servers to talk to, we can bail. + voxelServerCount = 1; } // set our preferred PPS to be exactly evenly divided among all of the voxel servers... int perServerPPS = DEFAULT_MAX_VOXEL_PPS/voxelServerCount; - _voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS); - UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { // only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER @@ -2408,25 +2406,30 @@ void Application::queryVoxels() { ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); if (serverFrustumLocation != ViewFrustum::OUTSIDE) { - // set up the packet for sending... - unsigned char* endOfVoxelQueryPacket = voxelQueryPacket; - - // insert packet type/version and node UUID - endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, PACKET_TYPE_VOXEL_QUERY); - QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122(); - memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size()); - endOfVoxelQueryPacket += ownerUUID.size(); - - // encode the query data... - endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket); - - int packetLength = endOfVoxelQueryPacket - voxelQueryPacket; - - nodeSocket->send(node->getActiveSocket(), voxelQueryPacket, packetLength); - - // Feed number of bytes to corresponding channel of the bandwidth meter - _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); + //printf("_voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS=%d)\n",perServerPPS); + _voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS); + } else { + //printf("_voxelQuery.setMaxVoxelPacketsPerSecond(0)\n"); + _voxelQuery.setMaxVoxelPacketsPerSecond(0); } + // set up the packet for sending... + unsigned char* endOfVoxelQueryPacket = voxelQueryPacket; + + // insert packet type/version and node UUID + endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, PACKET_TYPE_VOXEL_QUERY); + QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122(); + memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size()); + endOfVoxelQueryPacket += ownerUUID.size(); + + // encode the query data... + endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket); + + int packetLength = endOfVoxelQueryPacket - voxelQueryPacket; + + nodeSocket->send(node->getActiveSocket(), voxelQueryPacket, packetLength); + + // Feed number of bytes to corresponding channel of the bandwidth meter + _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); } } } diff --git a/libraries/voxel-server-library/src/NodeWatcher.cpp b/libraries/voxel-server-library/src/NodeWatcher.cpp index 894e53b4b5..03384569b8 100644 --- a/libraries/voxel-server-library/src/NodeWatcher.cpp +++ b/libraries/voxel-server-library/src/NodeWatcher.cpp @@ -20,7 +20,9 @@ void NodeWatcher::nodeKilled(Node* node) { // Use this to cleanup our node if (node->getType() == NODE_TYPE_AGENT) { VoxelNodeData* nodeData = (VoxelNodeData*)node->getLinkedData(); - node->setLinkedData(NULL); - delete nodeData; + if (nodeData) { + node->setLinkedData(NULL); + delete nodeData; + } } }; diff --git a/libraries/voxel-server-library/src/VoxelNodeData.cpp b/libraries/voxel-server-library/src/VoxelNodeData.cpp index 741e33e07d..705ea8b2e7 100644 --- a/libraries/voxel-server-library/src/VoxelNodeData.cpp +++ b/libraries/voxel-server-library/src/VoxelNodeData.cpp @@ -108,6 +108,7 @@ void VoxelNodeData::writeToPacket(unsigned char* buffer, int bytes) { VoxelNodeData::~VoxelNodeData() { delete[] _voxelPacket; + delete[] _lastVoxelPacket; if (_voxelSendThread) { _voxelSendThread->terminate(); diff --git a/libraries/voxel-server-library/src/VoxelSendThread.cpp b/libraries/voxel-server-library/src/VoxelSendThread.cpp index 3ecbd6434e..3a3904e218 100644 --- a/libraries/voxel-server-library/src/VoxelSendThread.cpp +++ b/libraries/voxel-server-library/src/VoxelSendThread.cpp @@ -63,6 +63,7 @@ void VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int& // obscure the packet and not send it. This allows the callers and upper level logic to not need to know about // this rate control savings. if (nodeData->shouldSuppressDuplicatePacket()) { + nodeData->resetVoxelPacket(); // we still need to reset it though! return; // without sending... } diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index e83ffc1c16..456a2d8e58 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -75,7 +75,12 @@ void VoxelNode::init(unsigned char * octalCode) { _childrenArray[i] = NULL; } #endif // def HAS_AUDIT_CHILDREN - + +#ifdef SIMPLE_CHILD_ARRAY + for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { + _simpleChildArray[i] = NULL; + } +#endif _unknownBufferIndex = true; setBufferIndex(GLBUFFER_INDEX_UNKNOWN); @@ -320,6 +325,9 @@ uint64_t VoxelNode::_couldStoreFourChildrenInternally = 0; uint64_t VoxelNode::_couldNotStoreFourChildrenInternally = 0; VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const { +#ifdef SIMPLE_CHILD_ARRAY + return _simpleChildArray[childIndex]; +#else PerformanceWarning warn(false,"getChildAtIndex",false,&_getChildAtIndexTime,&_getChildAtIndexCalls); VoxelNode* result = NULL; int childCount = getChildCount(); @@ -428,6 +436,7 @@ VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const { } #endif // def HAS_AUDIT_CHILDREN return result; +#endif } void VoxelNode::storeTwoChildren(VoxelNode* childOne, VoxelNode* childTwo) { @@ -680,6 +689,14 @@ void VoxelNode::deleteAllChildren() { } void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) { +#ifdef SIMPLE_CHILD_ARRAY + if (child) { + setAtBit(_childBitmask, childIndex); + } else { + clearAtBit(_childBitmask, childIndex); + } + _simpleChildArray[childIndex] = child; +#else PerformanceWarning warn(false,"setChildAtIndex",false,&_setChildAtIndexTime,&_setChildAtIndexCalls); // Here's how we store things... @@ -1020,6 +1037,8 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) { _childrenArray[childIndex] = child; auditChildren("setChildAtIndex()"); #endif // def HAS_AUDIT_CHILDREN + +#endif } diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index f76be6227f..c9e892ebb9 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -10,6 +10,7 @@ #define __hifi__VoxelNode__ //#define HAS_AUDIT_CHILDREN +#define SIMPLE_CHILD_ARRAY #include #include "AABox.h" @@ -172,6 +173,10 @@ private: uint64_t _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes /// Client and server, pointers to child nodes, various encodings +#ifdef SIMPLE_CHILD_ARRAY + VoxelNode* _simpleChildArray[8]; /// Only used when HAS_AUDIT_CHILDREN is enabled to help debug children encoding +#endif + union children_t { VoxelNode* single; int32_t offsetsTwoChildren[2];