Initial code for AC side of Enabling Physics plan

When interface sets query flag send only entities
close to main frustrum origin, until no more available,
then send unreliabe sequence # reliably.
This commit is contained in:
Simon Walton 2018-07-24 16:50:37 -07:00
parent db8846796f
commit 47e99cdeac
12 changed files with 116 additions and 16 deletions

View file

@ -17,6 +17,8 @@
#include "EntityServer.h" #include "EntityServer.h"
// Initially just send all items within this distance.
const float EntityTreeSendThread::INITIAL_RADIUS = 50.0f;
EntityTreeSendThread::EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) : EntityTreeSendThread::EntityTreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) :
OctreeSendThread(myServer, node) OctreeSendThread(myServer, node)
@ -112,6 +114,13 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O
int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST);
newView.lodScaleFactor = powf(2.0f, lodLevelOffset); newView.lodScaleFactor = powf(2.0f, lodLevelOffset);
if (nodeData->wantReportInitialResult() && !newView.viewFrustums.empty()) {
auto& mainView = newView.viewFrustums[0];
// Force acceptance within INITIAL_RADIUS.
mainView.setSimpleRadius(INITIAL_RADIUS);
newView.lodScaleFactor = 0.0f;
}
startNewTraversal(newView, root); startNewTraversal(newView, root);
// When the viewFrustum changed the sort order may be incorrect, so we re-sort // When the viewFrustum changed the sort order may be incorrect, so we re-sort

View file

@ -58,6 +58,8 @@ private:
int32_t _numEntitiesOffset { 0 }; int32_t _numEntitiesOffset { 0 };
uint16_t _numEntities { 0 }; uint16_t _numEntities { 0 };
const static float INITIAL_RADIUS;
private slots: private slots:
void editingEntityPointer(const EntityItemPointer& entity); void editingEntityPointer(const EntityItemPointer& entity);
void deletingEntityPointer(EntityItem* entity); void deletingEntityPointer(EntityItem* entity);

View file

@ -195,6 +195,7 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
// actually send it // actually send it
OctreeServer::didCallWriteDatagram(this); OctreeServer::didCallWriteDatagram(this);
DependencyManager::get<NodeList>()->sendUnreliablePacket(statsPacket, *node); DependencyManager::get<NodeList>()->sendUnreliablePacket(statsPacket, *node);
_lastSequenceNumber = (decltype(_lastSequenceNumber)) statsPacket.getSequenceNumber();
} else { } else {
// not enough room in the packet, send two packets // not enough room in the packet, send two packets
@ -211,10 +212,9 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
//_totalWastedBytes += 0; //_totalWastedBytes += 0;
_trueBytesSent += numBytes; _trueBytesSent += numBytes;
numPackets++; numPackets++;
NLPacket& sentPacket = nodeData->getPacket();
if (debug) { if (debug) {
NLPacket& sentPacket = nodeData->getPacket();
sentPacket.seek(sizeof(OCTREE_PACKET_FLAGS)); sentPacket.seek(sizeof(OCTREE_PACKET_FLAGS));
OCTREE_PACKET_SEQUENCE sequence; OCTREE_PACKET_SEQUENCE sequence;
@ -231,9 +231,10 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
// second packet // second packet
OctreeServer::didCallWriteDatagram(this); OctreeServer::didCallWriteDatagram(this);
DependencyManager::get<NodeList>()->sendUnreliablePacket(nodeData->getPacket(), *node); DependencyManager::get<NodeList>()->sendUnreliablePacket(sentPacket, *node);
_lastSequenceNumber = (decltype(_lastSequenceNumber)) sentPacket.getSequenceNumber();
numBytes = nodeData->getPacket().getDataSize(); numBytes = sentPacket.getDataSize();
_totalBytes += numBytes; _totalBytes += numBytes;
_totalPackets++; _totalPackets++;
// we count wasted bytes here because we were unable to fit the stats packet // we count wasted bytes here because we were unable to fit the stats packet
@ -243,8 +244,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
numPackets++; numPackets++;
if (debug) { if (debug) {
NLPacket& sentPacket = nodeData->getPacket();
sentPacket.seek(sizeof(OCTREE_PACKET_FLAGS)); sentPacket.seek(sizeof(OCTREE_PACKET_FLAGS));
OCTREE_PACKET_SEQUENCE sequence; OCTREE_PACKET_SEQUENCE sequence;
@ -265,9 +264,11 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
if (nodeData->isPacketWaiting() && !nodeData->isShuttingDown()) { if (nodeData->isPacketWaiting() && !nodeData->isShuttingDown()) {
// just send the octree packet // just send the octree packet
OctreeServer::didCallWriteDatagram(this); OctreeServer::didCallWriteDatagram(this);
DependencyManager::get<NodeList>()->sendUnreliablePacket(nodeData->getPacket(), *node); NLPacket& sentPacket = nodeData->getPacket();
DependencyManager::get<NodeList>()->sendUnreliablePacket(sentPacket, *node);
_lastSequenceNumber = (decltype(_lastSequenceNumber)) sentPacket.getSequenceNumber();
int numBytes = nodeData->getPacket().getDataSize(); int numBytes = sentPacket.getDataSize();
_totalBytes += numBytes; _totalBytes += numBytes;
_totalPackets++; _totalPackets++;
int thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; int thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes;
@ -276,8 +277,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode*
_trueBytesSent += numBytes; _trueBytesSent += numBytes;
if (debug) { if (debug) {
NLPacket& sentPacket = nodeData->getPacket();
sentPacket.seek(sizeof(OCTREE_PACKET_FLAGS)); sentPacket.seek(sizeof(OCTREE_PACKET_FLAGS));
OCTREE_PACKET_SEQUENCE sequence; OCTREE_PACKET_SEQUENCE sequence;
@ -512,6 +511,17 @@ void OctreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, Octre
OctreeServer::trackInsideTime((float)(usecTimestampNow() - startInside)); OctreeServer::trackInsideTime((float)(usecTimestampNow() - startInside));
} }
if (params.stopReason == EncodeBitstreamParams::FINISHED && nodeData->wantReportInitialResult()) {
// Dealt with nearby entities.
nodeData->setReportInitialResult(false);
// send EntityQueryInitialResultsComplete reliable packet ...
auto initialCompletion = NLPacket::create(PacketType::EntityQueryInitialResultsComplete, -1, true);
QDataStream initialCompletionStream(initialCompletion.get());
initialCompletionStream << _lastSequenceNumber;
DependencyManager::get<NodeList>()->sendPacket(std::move(initialCompletion), *node.data());
}
if (somethingToSend && _myServer->wantsVerboseDebug()) { if (somethingToSend && _myServer->wantsVerboseDebug()) {
qCDebug(octree) << "Hit PPS Limit, packetsSentThisInterval =" << _packetsSentThisInterval qCDebug(octree) << "Hit PPS Limit, packetsSentThisInterval =" << _packetsSentThisInterval
<< " maxPacketsPerInterval = " << maxPacketsPerInterval << " maxPacketsPerInterval = " << maxPacketsPerInterval

View file

@ -60,6 +60,7 @@ protected:
QWeakPointer<Node> _node; QWeakPointer<Node> _node;
OctreeServer* _myServer { nullptr }; OctreeServer* _myServer { nullptr };
QUuid _nodeUuid; QUuid _nodeUuid;
udt::SequenceNumber::Type _lastSequenceNumber { 0 };
private: private:
/// Called before a packetDistributor pass to allow for pre-distribution processing /// Called before a packetDistributor pass to allow for pre-distribution processing

View file

@ -6134,6 +6134,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType) {
auto lodManager = DependencyManager::get<LODManager>(); auto lodManager = DependencyManager::get<LODManager>();
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
_octreeQuery.setReportInitialResult(true);
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();

View file

@ -95,7 +95,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::AvatarIdentityRequest: case PacketType::AvatarIdentityRequest:
return 22; return 22;
default: default:
return 21; return 22;
} }
} }

View file

@ -126,6 +126,7 @@ public:
EntityScriptCallMethod, EntityScriptCallMethod,
ChallengeOwnershipRequest, ChallengeOwnershipRequest,
ChallengeOwnershipReply, ChallengeOwnershipReply,
EntityQueryInitialResultsComplete,
OctreeDataFileRequest, OctreeDataFileRequest,
OctreeDataFileReply, OctreeDataFileReply,

View file

@ -27,6 +27,10 @@ OctreeQuery::OctreeQuery(bool randomizeConnectionID) {
} }
} }
const OctreeQuery::OctreeQueryFlags operator|=(OctreeQuery::OctreeQueryFlags& lhs, int rhs) {
return lhs = OctreeQuery::OctreeQueryFlags(lhs | rhs);
}
int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) {
unsigned char* bufferStart = destinationBuffer; unsigned char* bufferStart = destinationBuffer;
@ -77,6 +81,11 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) {
destinationBuffer += binaryParametersBytes; destinationBuffer += binaryParametersBytes;
} }
OctreeQueryFlags queryFlags { NoFlags };
queryFlags |= (_reportInitialResult ? OctreeQuery::WantInitialResult : 0);
memcpy(destinationBuffer, &queryFlags, sizeof(queryFlags));
destinationBuffer += sizeof(queryFlags);
return destinationBuffer - bufferStart; return destinationBuffer - bufferStart;
} }
@ -151,5 +160,11 @@ int OctreeQuery::parseData(ReceivedMessage& message) {
_jsonParameters = newJsonDocument.object(); _jsonParameters = newJsonDocument.object();
} }
OctreeQueryFlags queryFlags;
memcpy(&queryFlags, sourceBuffer, sizeof(queryFlags));
sourceBuffer += sizeof(queryFlags);
_reportInitialResult = bool(queryFlags & OctreeQueryFlags::WantInitialResult);
return sourceBuffer - startPosition; return sourceBuffer - startPosition;
} }

View file

@ -52,6 +52,10 @@ public:
bool hasReceivedFirstQuery() const { return _hasReceivedFirstQuery; } bool hasReceivedFirstQuery() const { return _hasReceivedFirstQuery; }
// Want a report when the initial query is complete.
bool wantReportInitialResult() const { return _reportInitialResult; }
void setReportInitialResult(bool reportInitialResult) { _reportInitialResult = reportInitialResult; }
signals: signals:
void incomingConnectionIDChanged(); void incomingConnectionIDChanged();
@ -74,7 +78,11 @@ protected:
QJsonObject _jsonParameters; QJsonObject _jsonParameters;
QReadWriteLock _jsonParametersLock; QReadWriteLock _jsonParametersLock;
enum OctreeQueryFlags : uint16_t { NoFlags = 0x0, WantInitialResult = 0x1 };
friend const OctreeQuery::OctreeQueryFlags operator|=(OctreeQuery::OctreeQueryFlags& lhs, const int rhs);
bool _hasReceivedFirstQuery { false }; bool _hasReceivedFirstQuery { false };
bool _reportInitialResult { false };
}; };
#endif // hifi_OctreeQuery_h #endif // hifi_OctreeQuery_h

View file

@ -144,3 +144,8 @@ int ConicalViewFrustum::deserialize(const unsigned char* sourceBuffer) {
return sourceBuffer - startPosition; return sourceBuffer - startPosition;
} }
void ConicalViewFrustum::setSimpleRadius(float radius) {
_radius = radius;
_farClip = radius / 2.0f;
}

View file

@ -54,6 +54,9 @@ public:
int serialize(unsigned char* destinationBuffer) const; int serialize(unsigned char* destinationBuffer) const;
int deserialize(const unsigned char* sourceBuffer); int deserialize(const unsigned char* sourceBuffer);
// Just test for within radius.
void setSimpleRadius(float radius);
private: private:
glm::vec3 _position { 0.0f, 0.0f, 0.0f }; glm::vec3 _position { 0.0f, 0.0f, 0.0f };
glm::vec3 _direction { 0.0f, 0.0f, 1.0f }; glm::vec3 _direction { 0.0f, 0.0f, 1.0f };

View file

@ -86,12 +86,12 @@ local packet_types = {
[22] = "ICEServerPeerInformation", [22] = "ICEServerPeerInformation",
[23] = "ICEServerQuery", [23] = "ICEServerQuery",
[24] = "OctreeStats", [24] = "OctreeStats",
[25] = "Jurisdiction", [25] = "UNUSED_PACKET_TYPE_1",
[26] = "AvatarIdentityRequest", [26] = "AvatarIdentityRequest",
[27] = "AssignmentClientStatus", [27] = "AssignmentClientStatus",
[28] = "NoisyMute", [28] = "NoisyMute",
[29] = "AvatarIdentity", [29] = "AvatarIdentity",
[30] = "AvatarBillboard", [30] = "NodeIgnoreRequest",
[31] = "DomainConnectRequest", [31] = "DomainConnectRequest",
[32] = "DomainServerRequireDTLS", [32] = "DomainServerRequireDTLS",
[33] = "NodeJsonStats", [33] = "NodeJsonStats",
@ -115,7 +115,52 @@ local packet_types = {
[51] = "AssetUpload", [51] = "AssetUpload",
[52] = "AssetUploadReply", [52] = "AssetUploadReply",
[53] = "AssetGetInfo", [53] = "AssetGetInfo",
[54] = "AssetGetInfoReply" [54] = "AssetGetInfoReply",
[55] = "DomainDisconnectRequest",
[56] = "DomainServerRemovedNode",
[57] = "MessagesData",
[58] = "MessagesSubscribe",
[59] = "MessagesUnsubscribe",
[60] = "ICEServerHeartbeatDenied",
[61] = "AssetMappingOperation",
[62] = "AssetMappingOperationReply",
[63] = "ICEServerHeartbeatACK",
[64] = "NegotiateAudioFormat",
[65] = "SelectedAudioFormat",
[66] = "MoreEntityShapes",
[67] = "NodeKickRequest",
[68] = "NodeMuteRequest",
[69] = "RadiusIgnoreRequest",
[70] = "UsernameFromIDRequest",
[71] = "UsernameFromIDReply",
[72] = "AvatarQuery",
[73] = "RequestsDomainListData",
[74] = "PerAvatarGainSet",
[75] = "EntityScriptGetStatus",
[76] = "EntityScriptGetStatusReply",
[77] = "ReloadEntityServerScript",
[78] = "EntityPhysics",
[79] = "EntityServerScriptLog",
[80] = "AdjustAvatarSorting",
[81] = "OctreeFileReplacement",
[82] = "CollisionEventChanges",
[83] = "ReplicatedMicrophoneAudioNoEcho",
[84] = "ReplicatedMicrophoneAudioWithEcho",
[85] = "ReplicatedInjectAudio",
[86] = "ReplicatedSilentAudioFrame",
[87] = "ReplicatedAvatarIdentity",
[88] = "ReplicatedKillAvatar",
[89] = "ReplicatedBulkAvatarData",
[90] = "DomainContentReplacementFromUrl",
[91] = "ChallengeOwnership",
[92] = "EntityScriptCallMethod",
[93] = "ChallengeOwnershipRequest",
[94] = "ChallengeOwnershipReply",
[95] = "EntityQueryInitialResultsComplete",
[96] = "OctreeDataFileRequest",
[97] = "OctreeDataFileReply",
[98] = "OctreeDataPersist",
[99] = "EntityClone"
} }
local unsourced_packet_types = { local unsourced_packet_types = {