mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-24 01:24:00 +02:00
adding OctreeHeadlessViewer::queryOctree()
This commit is contained in:
parent
7a2419a5bd
commit
dee9d48b5f
2 changed files with 197 additions and 0 deletions
|
@ -7,6 +7,8 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <NodeList.h>
|
||||||
|
|
||||||
#include "OctreeHeadlessViewer.h"
|
#include "OctreeHeadlessViewer.h"
|
||||||
|
|
||||||
OctreeHeadlessViewer::OctreeHeadlessViewer() :
|
OctreeHeadlessViewer::OctreeHeadlessViewer() :
|
||||||
|
@ -21,3 +23,181 @@ void OctreeHeadlessViewer::init() {
|
||||||
setViewFrustum(&_viewFrustum);
|
setViewFrustum(&_viewFrustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OctreeHeadlessViewer::queryOctree() {
|
||||||
|
NodeType_t serverType = getMyNodeType();
|
||||||
|
PacketType packetType = getMyQueryMessageType();
|
||||||
|
NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions();
|
||||||
|
|
||||||
|
bool wantExtraDebugging = false;
|
||||||
|
|
||||||
|
// These will be the same for all servers, so we can set them up once and then reuse for each server we send to.
|
||||||
|
_octreeQuery.setWantLowResMoving(true);
|
||||||
|
_octreeQuery.setWantColor(true);
|
||||||
|
_octreeQuery.setWantDelta(true);
|
||||||
|
_octreeQuery.setWantOcclusionCulling(false);
|
||||||
|
_octreeQuery.setWantCompression(true); // TODO: should be on by default
|
||||||
|
|
||||||
|
_octreeQuery.setCameraPosition(_viewFrustum.getPosition());
|
||||||
|
_octreeQuery.setCameraOrientation(_viewFrustum.getOrientation());
|
||||||
|
_octreeQuery.setCameraFov(_viewFrustum.getFieldOfView());
|
||||||
|
_octreeQuery.setCameraAspectRatio(_viewFrustum.getAspectRatio());
|
||||||
|
_octreeQuery.setCameraNearClip(_viewFrustum.getNearClip());
|
||||||
|
_octreeQuery.setCameraFarClip(_viewFrustum.getFarClip());
|
||||||
|
_octreeQuery.setCameraEyeOffsetPosition(_viewFrustum.getEyeOffsetPosition());
|
||||||
|
_octreeQuery.setOctreeSizeScale(getVoxelSizeScale());
|
||||||
|
_octreeQuery.setBoundaryLevelAdjust(getBoundaryLevelAdjust());
|
||||||
|
|
||||||
|
unsigned char queryPacket[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
|
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
||||||
|
int totalServers = 0;
|
||||||
|
int inViewServers = 0;
|
||||||
|
int unknownJurisdictionServers = 0;
|
||||||
|
|
||||||
|
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||||
|
// only send to the NodeTypes that are serverType
|
||||||
|
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
||||||
|
totalServers++;
|
||||||
|
|
||||||
|
// get the server bounds for this server
|
||||||
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
|
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||||
|
// can get the jurisdiction...
|
||||||
|
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||||
|
unknownJurisdictionServers++;
|
||||||
|
} else {
|
||||||
|
const JurisdictionMap& map = (jurisdictions)[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);
|
||||||
|
|
||||||
|
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||||
|
|
||||||
|
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||||
|
inViewServers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
||||||
|
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
|
||||||
|
totalServers, inViewServers, unknownJurisdictionServers);
|
||||||
|
}
|
||||||
|
|
||||||
|
int perServerPPS = 0;
|
||||||
|
const int SMALL_BUDGET = 10;
|
||||||
|
int perUnknownServer = SMALL_BUDGET;
|
||||||
|
int totalPPS = getMaxPacketsPerSecond();
|
||||||
|
|
||||||
|
// 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 = (totalPPS / inViewServers) - (unknownJurisdictionServers * perUnknownServer);
|
||||||
|
} else {
|
||||||
|
if (unknownJurisdictionServers > 0) {
|
||||||
|
perUnknownServer = (totalPPS / unknownJurisdictionServers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
|
||||||
|
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
|
// only send to the NodeTypes that are serverType
|
||||||
|
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
|
||||||
|
|
||||||
|
|
||||||
|
// get the server bounds for this server
|
||||||
|
QUuid nodeUUID = node->getUUID();
|
||||||
|
|
||||||
|
bool inView = false;
|
||||||
|
bool unknownView = false;
|
||||||
|
|
||||||
|
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||||
|
// can get the jurisdiction...
|
||||||
|
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||||
|
unknownView = true; // assume it's in view
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "no known jurisdiction for node " << *node << ", assume it's visible.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const JurisdictionMap& map = (jurisdictions)[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);
|
||||||
|
|
||||||
|
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
|
||||||
|
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
|
||||||
|
inView = true;
|
||||||
|
} else {
|
||||||
|
inView = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inView) {
|
||||||
|
_octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS);
|
||||||
|
} else if (unknownView) {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
|
||||||
|
<< perUnknownServer << " to send us jurisdiction.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
|
||||||
|
// If there's only one server, then don't do this, and just let the normal voxel query pass through
|
||||||
|
// as expected... this way, we will actually get a valid scene if there is one to be seen
|
||||||
|
if (totalServers > 1) {
|
||||||
|
_octreeQuery.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);
|
||||||
|
_octreeQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE);
|
||||||
|
_octreeQuery.setCameraNearClip(0.1f);
|
||||||
|
_octreeQuery.setCameraFarClip(0.1f);
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "Using 'minimal' camera position for node" << *node;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (wantExtraDebugging) {
|
||||||
|
qDebug() << "Using regular camera position for node" << *node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_octreeQuery.setMaxOctreePacketsPerSecond(perUnknownServer);
|
||||||
|
} else {
|
||||||
|
_octreeQuery.setMaxOctreePacketsPerSecond(0);
|
||||||
|
}
|
||||||
|
// set up the packet for sending...
|
||||||
|
unsigned char* endOfQueryPacket = queryPacket;
|
||||||
|
|
||||||
|
// insert packet type/version and node UUID
|
||||||
|
endOfQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
|
||||||
|
|
||||||
|
// encode the query data...
|
||||||
|
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
|
||||||
|
|
||||||
|
int packetLength = endOfQueryPacket - queryPacket;
|
||||||
|
|
||||||
|
// make sure we still have an active socket
|
||||||
|
nodeList->writeDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
#include "JurisdictionListener.h"
|
||||||
#include "Octree.h"
|
#include "Octree.h"
|
||||||
|
#include "OctreeQuery.h"
|
||||||
#include "OctreeRenderer.h"
|
#include "OctreeRenderer.h"
|
||||||
#include "Octree.h"
|
#include "Octree.h"
|
||||||
#include "ViewFrustum.h"
|
#include "ViewFrustum.h"
|
||||||
|
@ -27,8 +29,23 @@ public:
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void render() { /* swallow these */ };
|
virtual void render() { /* swallow these */ };
|
||||||
|
|
||||||
|
void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; }
|
||||||
|
void queryOctree();
|
||||||
|
|
||||||
|
void setVoxelSizeScale(float sizeScale);
|
||||||
|
float getVoxelSizeScale() const { return _voxelSizeScale; }
|
||||||
|
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
|
||||||
|
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
|
||||||
|
int getMaxPacketsPerSecond() const { return _maxTotalPPS; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ViewFrustum _viewFrustum;
|
ViewFrustum _viewFrustum;
|
||||||
|
JurisdictionListener* _jurisdictionListener;
|
||||||
|
OctreeQuery _octreeQuery;
|
||||||
|
float _voxelSizeScale;
|
||||||
|
int _boundaryLevelAdjust;
|
||||||
|
int _maxTotalPPS;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__OctreeHeadlessViewer__) */
|
#endif /* defined(__hifi__OctreeHeadlessViewer__) */
|
Loading…
Reference in a new issue