From af1047f5e05236f8f191ad72f34afa5666a6d16d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 31 Oct 2013 12:06:18 -0700 Subject: [PATCH] fix to how voxel servers are queried when they have no known jurisdiction --- interface/src/Application.cpp | 147 ++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 49 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6220600df..38c7e7b074 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2391,39 +2391,63 @@ void Application::queryVoxels() { NodeList* nodeList = NodeList::getInstance(); // Iterate all of the nodes, and get a count of how many voxel servers we have... - int voxelServerCount = 0; + int totalServers = 0; + int inViewServers = 0; + int unknownJurisdictionServers = 0; + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { // only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER) { + totalServers++; // get the server bounds for this server QUuid nodeUUID = node->getUUID(); - const JurisdictionMap& map = (_voxelServerJurisdictions)[nodeUUID]; - - unsigned char* rootCode = map.getRootOctalCode(); - if (rootCode) { - VoxelPositionSize rootDetails; - voxelDetailsForCode(rootCode, rootDetails); - AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); - serverBounds.scale(TREE_SCALE); + // if we haven't heard from this voxel server, go ahead and send it a query, so we + // can get the jurisdiction... + if (_voxelServerJurisdictions.find(nodeUUID) == _voxelServerJurisdictions.end()) { + unknownJurisdictionServers++; + } else { + const JurisdictionMap& map = (_voxelServerJurisdictions)[nodeUUID]; - ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); + unsigned char* rootCode = map.getRootOctalCode(); + + if (rootCode) { + VoxelPositionSize rootDetails; + voxelDetailsForCode(rootCode, rootDetails); + AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); + serverBounds.scale(TREE_SCALE); - if (serverFrustumLocation != ViewFrustum::OUTSIDE) { - voxelServerCount++; + ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); + + if (serverFrustumLocation != ViewFrustum::OUTSIDE) { + inViewServers++; + } } } } } + + //qDebug("Servers: total %d, in view %d, unknown jurisdiction %d \n", + // totalServers, inViewServers, unknownJurisdictionServers); - // assume there's at least one voxel server - if (voxelServerCount < 1) { - voxelServerCount = 1; + int perServerPPS; + const int SMALL_BUDGET = 10; + int perUnknownServer = SMALL_BUDGET; + + // determine PPS based on number of servers + if (inViewServers >= 1) { + // set our preferred PPS to be exactly evenly divided among all of the voxel servers... and allocate 1 PPS + // for each unknown jurisdiction server + perServerPPS = (DEFAULT_MAX_VOXEL_PPS/inViewServers) - (unknownJurisdictionServers * SMALL_BUDGET); + } else { + perServerPPS = 0; + if (unknownJurisdictionServers > 0) { + perUnknownServer = (DEFAULT_MAX_VOXEL_PPS/unknownJurisdictionServers); + } } - // set our preferred PPS to be exactly evenly divided among all of the voxel servers... - int perServerPPS = DEFAULT_MAX_VOXEL_PPS/voxelServerCount; + //qDebug("perServerPPS: %d perUnknownServer: %d\n", perServerPPS, perUnknownServer); UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { @@ -2433,44 +2457,69 @@ void Application::queryVoxels() { // get the server bounds for this server QUuid nodeUUID = node->getUUID(); - const JurisdictionMap& map = (_voxelServerJurisdictions)[nodeUUID]; - unsigned char* rootCode = map.getRootOctalCode(); + bool inView = false; + bool unknownView = false; - if (rootCode) { - VoxelPositionSize rootDetails; - voxelDetailsForCode(rootCode, rootDetails); - AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); - serverBounds.scale(TREE_SCALE); + // if we haven't heard from this voxel server, go ahead and send it a query, so we + // can get the jurisdiction... + if (_voxelServerJurisdictions.find(nodeUUID) == _voxelServerJurisdictions.end()) { + unknownView = true; // assume it's in view + //qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible.\n"; + } else { + const JurisdictionMap& map = (_voxelServerJurisdictions)[nodeUUID]; - ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); + unsigned char* rootCode = map.getRootOctalCode(); - if (serverFrustumLocation != ViewFrustum::OUTSIDE) { - //printf("_voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS=%d)\n",perServerPPS); - _voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS); - } else { - //printf("_voxelQuery.setMaxVoxelPacketsPerSecond(0)\n"); - _voxelQuery.setMaxVoxelPacketsPerSecond(0); + if (rootCode) { + VoxelPositionSize rootDetails; + voxelDetailsForCode(rootCode, rootDetails); + AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); + serverBounds.scale(TREE_SCALE); + + ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); + if (serverFrustumLocation != ViewFrustum::OUTSIDE) { + inView = true; + } else { + inView = false; + } } - // 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); } + + if (inView) { + _voxelQuery.setMaxVoxelPacketsPerSecond(perServerPPS); + } else if (unknownView) { + //qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " + // << perUnknownServer << " to send us jurisdiction.\n"; + + // set the query's position/orientation to be degenerate in a manner that will get the scene quickly + _voxelQuery.setCameraPosition(glm::vec3(-0.1,-0.1,-0.1)); + const glm::quat OFF_IN_NEGATIVE_SPACE = glm::quat(-0.5, 0, -0.5, 1.0); + _voxelQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE); + _voxelQuery.setCameraNearClip(0.1); + _voxelQuery.setCameraFarClip(0.1); + _voxelQuery.setMaxVoxelPacketsPerSecond(perUnknownServer); + } else { + _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); } } }