diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index 19dc92686a..154d22f253 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -174,7 +174,7 @@ bool EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O // Send EntityQueryInitialResultsComplete reliable packet ... auto initialCompletion = NLPacket::create(PacketType::EntityQueryInitialResultsComplete, -1, true); QDataStream initialCompletionStream(initialCompletion.get()); - initialCompletionStream << _lastSequenceNumber; + initialCompletionStream << OCTREE_PACKET_SEQUENCE(nodeData->getSequenceNumber() - 1U); DependencyManager::get()->sendPacket(std::move(initialCompletion), *node.data()); } diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 54a7bbfa2d..ab357f4146 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -195,7 +195,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // actually send it OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(statsPacket, *node); - _lastSequenceNumber = (decltype(_lastSequenceNumber)) statsPacket.getSequenceNumber(); } else { // not enough room in the packet, send two packets @@ -232,7 +231,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // second packet OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(sentPacket, *node); - _lastSequenceNumber = (decltype(_lastSequenceNumber)) sentPacket.getSequenceNumber(); numBytes = sentPacket.getDataSize(); _totalBytes += numBytes; @@ -266,7 +264,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* OctreeServer::didCallWriteDatagram(this); NLPacket& sentPacket = nodeData->getPacket(); DependencyManager::get()->sendUnreliablePacket(sentPacket, *node); - _lastSequenceNumber = (decltype(_lastSequenceNumber)) sentPacket.getSequenceNumber(); int numBytes = sentPacket.getDataSize(); _totalBytes += numBytes; diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index fc529c3e3a..bdf0f03364 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -60,7 +60,6 @@ protected: QWeakPointer _node; OctreeServer* _myServer { nullptr }; QUuid _nodeUuid; - udt::SequenceNumber::Type _lastSequenceNumber { 0 }; private: /// Called before a packetDistributor pass to allow for pre-distribution processing diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 94f89a66ad..ed67b7464c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5476,8 +5476,9 @@ void Application::update(float deltaTime) { // for nearby entities before starting bullet up. quint64 now = usecTimestampNow(); const int PHYSICS_CHECK_TIMEOUT = 2 * USECS_PER_SECOND; - - if (now - _lastPhysicsCheckTime > PHYSICS_CHECK_TIMEOUT || _fullSceneReceivedCounter > _fullSceneCounterAtLastPhysicsCheck) { + auto entityTreeRenderer = getEntities(); + if (entityTreeRenderer && _octreeProcessor.octreeSequenceIsComplete(entityTreeRenderer->getLastOctreeMessageSequence()) ) { + /*if (now - _lastPhysicsCheckTime > PHYSICS_CHECK_TIMEOUT || _fullSceneReceivedCounter > _fullSceneCounterAtLastPhysicsCheck) {*/ // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway _lastPhysicsCheckTime = now; _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; @@ -6134,7 +6135,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType) { auto lodManager = DependencyManager::get(); _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); - _octreeQuery.setReportInitialCompletion(true); + _octreeQuery.setReportInitialCompletion(!_physicsEnabled); auto nodeList = DependencyManager::get(); @@ -6279,6 +6280,7 @@ void Application::clearDomainOctreeDetails() { _octreeServerSceneStats.clear(); }); + _octreeProcessor.resetCompletionSequenceNumber(); // reset the model renderer getEntities()->clear(); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 7d38e29710..5ab2218f67 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -21,9 +21,9 @@ OctreePacketProcessor::OctreePacketProcessor() { setObjectName("Octree Packet Processor"); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - - packetReceiver.registerDirectListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase }, - this, "handleOctreePacket"); + const PacketReceiver::PacketTypeList octreePackets = + { PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase, PacketType::EntityQueryInitialResultsComplete }; + packetReceiver.registerDirectListenerForTypes(octreePackets, this, "handleOctreePacket"); } void OctreePacketProcessor::handleOctreePacket(QSharedPointer message, SharedNodePointer senderNode) { @@ -111,8 +111,36 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } } break; + case PacketType::EntityQueryInitialResultsComplete: { + // Read sequence # + OCTREE_PACKET_SEQUENCE completionNumber; + message->readPrimitive(&completionNumber); + _completionSequenceNumber = completionNumber; + _completionSequenceNumberValid = true; + } break; + default: { // nothing to do } break; } } + +void OctreePacketProcessor::resetCompletionSequenceNumber() { + _completionSequenceNumber = false; +} + +namespace { + template constexpr bool lessThanWraparound(int a, int b) { + static const int MAX_T_VALUE = std::numeric_limits::max(); + if (b < a) { + b += MAX_T_VALUE; + } + return (b - a) < (MAX_T_VALUE / 2); + } +} + +bool OctreePacketProcessor::octreeSequenceIsComplete(int sequenceNumber) const { + const int completionSequenceNumber = _completionSequenceNumber; + return _completionSequenceNumberValid && + !lessThanWraparound(completionSequenceNumber, sequenceNumber); +} diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index d04cab3584..f7e001fbde 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -22,13 +22,23 @@ class OctreePacketProcessor : public ReceivedPacketProcessor { public: OctreePacketProcessor(); + bool octreeSequenceIsComplete(int sequenceNumber) const; + signals: void packetVersionMismatch(); +public slots: + void resetCompletionSequenceNumber(); + protected: virtual void processPacket(QSharedPointer message, SharedNodePointer sendingNode) override; private slots: void handleOctreePacket(QSharedPointer message, SharedNodePointer senderNode); + +private: + bool _completionSequenceNumberValid { false }; + std::atomic _completionSequenceNumber { 0 }; + }; #endif // hifi_OctreePacketProcessor_h diff --git a/libraries/octree/src/OctreeProcessor.cpp b/libraries/octree/src/OctreeProcessor.cpp index beaac1198c..206ff399d9 100644 --- a/libraries/octree/src/OctreeProcessor.cpp +++ b/libraries/octree/src/OctreeProcessor.cpp @@ -192,6 +192,8 @@ void OctreeProcessor::processDatagram(ReceivedMessage& message, SharedNodePointe _elementsInLastWindow = 0; _entitiesInLastWindow = 0; } + + _lastOctreeMessageSequence = sequence; } } diff --git a/libraries/octree/src/OctreeProcessor.h b/libraries/octree/src/OctreeProcessor.h index 325b33cd15..8085682fa5 100644 --- a/libraries/octree/src/OctreeProcessor.h +++ b/libraries/octree/src/OctreeProcessor.h @@ -56,6 +56,8 @@ public: float getAverageUncompressPerPacket() const { return _uncompressPerPacket.getAverage(); } float getAverageReadBitstreamPerPacket() const { return _readBitstreamPerPacket.getAverage(); } + OCTREE_PACKET_SEQUENCE getLastOctreeMessageSequence() const { return _lastOctreeMessageSequence; } + protected: virtual OctreePointer createTree() = 0; @@ -77,6 +79,7 @@ protected: int _packetsInLastWindow = 0; int _elementsInLastWindow = 0; int _entitiesInLastWindow = 0; + std::atomic _lastOctreeMessageSequence = 0; };