diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 89df058e8d..8fd6380f1d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2451,7 +2451,7 @@ void Application::update(float deltaTime) { if (_physicsEngine.hasOutgoingChanges()) { _entitySimulation.lock(); - _entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges()); + _entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID()); _entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents()); _entitySimulation.unlock(); _physicsEngine.dumpStatsIfNecessary(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 4ac66678e7..759ce68e16 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -35,9 +35,9 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItem* entity _serverGravity(0.0f), _serverAcceleration(0.0f), _accelerationNearlyGravityCount(0), - _touchesOurSimulation(false), - _framesSinceSimulatorBid(0), - _movingFramesWithoutSimulationOwner(0) + _candidateForOwnership(false), + _loopsSinceOwnershipBid(0), + _loopsWithoutOwner(0) { _type = MOTION_STATE_TYPE_ENTITY; assert(entity != nullptr); @@ -65,9 +65,9 @@ void EntityMotionState::updateServerPhysicsVariables(uint32_t flags) { auto nodeList = DependencyManager::get(); const QUuid& sessionID = nodeList->getSessionUUID(); if (_entity->getSimulatorID() != sessionID) { - _touchesOurSimulation = false; - _movingFramesWithoutSimulationOwner = 0; - _framesSinceSimulatorBid = 0; + _candidateForOwnership = false; + _loopsWithoutOwner = 0; + _loopsSinceOwnershipBid = 0; } } } @@ -154,15 +154,15 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { _entity->setLastSimulated(usecTimestampNow()); if (_entity->getSimulatorID().isNull()) { - _movingFramesWithoutSimulationOwner++; + _loopsWithoutOwner++; - const uint32_t ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController? - if (_movingFramesWithoutSimulationOwner > ownershipClaimDelay) { + const uint32_t OWNERSHIP_BID_DELAY = 50; + if (_loopsWithoutOwner > OWNERSHIP_BID_DELAY) { //qDebug() << "Warning -- claiming something I saw moving." << getName(); - _touchesOurSimulation = true; + _candidateForOwnership = true; } } else { - _movingFramesWithoutSimulationOwner = 0; + _loopsWithoutOwner = 0; } #ifdef WANT_DEBUG @@ -184,12 +184,11 @@ void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) { // we alwasy resend packets for objects that have stopped moving up to some max limit. const int MAX_NUM_NON_MOVING_UPDATES = 5; -bool EntityMotionState::doesNotNeedToSendUpdate(const QUuid& sessionID) const { +bool EntityMotionState::isCandidateForOwnership(const QUuid& sessionID) const { if (!_body || !_entity) { - return true; + return false; } - - return (sessionID != _entity->getSimulatorID() && !_touchesOurSimulation); + return _candidateForOwnership || sessionID == _entity->getSimulatorID(); } bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { @@ -297,13 +296,13 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { return (fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT); } -bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame, const QUuid& sessionID) { +bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& sessionID) { // NOTE: we expect _entity and _body to be valid in this context, since shouldSendUpdate() is only called // after doesNotNeedToSendUpdate() returns false and that call should return 'true' if _entity or _body are NULL. assert(_entity); assert(_body); - if (!remoteSimulationOutOfSync(simulationFrame)) { + if (!remoteSimulationOutOfSync(simulationStep)) { return false; } @@ -313,9 +312,9 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationFrame, const QUuid& } const uint32_t FRAMES_BETWEEN_OWNERSHIP_CLAIMS = 30; - if (_touchesOurSimulation) { - ++_framesSinceSimulatorBid; - if (_framesSinceSimulatorBid > FRAMES_BETWEEN_OWNERSHIP_CLAIMS) { + if (_candidateForOwnership) { + ++_loopsSinceOwnershipBid; + if (_loopsSinceOwnershipBid > FRAMES_BETWEEN_OWNERSHIP_CLAIMS) { // we don't own the simulation, but it's time to bid for it return true; } @@ -411,7 +410,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q // we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID // but we remember that we do still own it... and rely on the server to tell us that we don't properties.setSimulatorID(QUuid()); - _touchesOurSimulation = false; + _candidateForOwnership = false; } else { // explicitly set the property's simulatorID so that it is flagged as changed and will be packed properties.setSimulatorID(sessionID); @@ -467,7 +466,7 @@ QUuid EntityMotionState::getSimulatorID() const { // virtual void EntityMotionState::bump() { - _touchesOurSimulation = true; + _candidateForOwnership = true; } void EntityMotionState::resetMeasuredBodyAcceleration() { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index afb7d257a6..4c1b469261 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -46,10 +46,9 @@ public: virtual void computeObjectShapeInfo(ShapeInfo& shapeInfo); - // TODO: Andrew to rename doesNotNeedToSendUpdate() - bool doesNotNeedToSendUpdate(const QUuid& sessionID) const; + bool isCandidateForOwnership(const QUuid& sessionID) const; bool remoteSimulationOutOfSync(uint32_t simulationStep); - bool shouldSendUpdate(uint32_t simulationFrame, const QUuid& sessionID); + bool shouldSendUpdate(uint32_t simulationStep, const QUuid& sessionID); void sendUpdate(OctreeEditPacketSender* packetSender, const QUuid& sessionID, uint32_t step); virtual uint32_t getAndClearIncomingDirtyFlags() const; @@ -107,9 +106,9 @@ protected: glm::vec3 _measuredAcceleration; quint8 _accelerationNearlyGravityCount; - bool _touchesOurSimulation; - uint32_t _framesSinceOwnershipBid; - uint32_t _movingFramesWithoutSimulationOwner; + bool _candidateForOwnership; + uint32_t _loopsSinceOwnershipBid; + uint32_t _loopsWithoutOwner; }; #endif // hifi_EntityMotionState_h diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 922fa0ce4f..3e43ab7454 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -188,7 +188,7 @@ VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToChange() { return _tempVector; } -void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motionStates) { +void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motionStates, const QUuid& sessionID) { // walk the motionStates looking for those that correspond to entities for (auto stateItr : motionStates) { ObjectMotionState* state = &(*stateItr); @@ -196,7 +196,7 @@ void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motio EntityMotionState* entityState = static_cast(state); EntityItem* entity = entityState->getEntity(); if (entity) { - if (entity->isKnownID()) { + if (entity->isKnownID() && entityState->isCandidateForOwnership(sessionID)) { _outgoingChanges.insert(entityState); } _entitiesToSort.insert(entityState->getEntity()); @@ -204,23 +204,21 @@ void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motio } } - auto nodeList = DependencyManager::get(); - const QUuid& sessionID = nodeList->getSessionUUID(); - if (sessionID.isNull()) { - // no updates to send - _outgoingChanges.clear(); - return; - } - - // send outgoing packets uint32_t numSubsteps = _physicsEngine->getNumSubsteps(); if (_lastStepSendPackets != numSubsteps) { _lastStepSendPackets = numSubsteps; + if (sessionID.isNull()) { + // usually don't get here, but if so --> nothing to do + _outgoingChanges.clear(); + return; + } + + // send outgoing packets QSet::iterator stateItr = _outgoingChanges.begin(); while (stateItr != _outgoingChanges.end()) { EntityMotionState* state = *stateItr; - if (state->doesNotNeedToSendUpdate(sessionID)) { + if (!state->isCandidateForOwnership(sessionID)) { stateItr = _outgoingChanges.erase(stateItr); } else if (state->shouldSendUpdate(numSubsteps, sessionID)) { state->sendUpdate(_entityPacketSender, sessionID, numSubsteps); diff --git a/libraries/physics/src/PhysicalEntitySimulation.h b/libraries/physics/src/PhysicalEntitySimulation.h index 4fd54c60fb..b3ee7af1e1 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.h +++ b/libraries/physics/src/PhysicalEntitySimulation.h @@ -48,7 +48,7 @@ public: VectorOfMotionStates& getObjectsToAdd(); VectorOfMotionStates& getObjectsToChange(); - void handleOutgoingChanges(VectorOfMotionStates& motionStates); + void handleOutgoingChanges(VectorOfMotionStates& motionStates, const QUuid& sessionID); void handleCollisionEvents(CollisionEvents& collisionEvents); private: diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 8b947d2510..d1dc5bcd79 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -53,6 +53,7 @@ public: void init(); void setSessionUUID(const QUuid& sessionID) { _sessionID = sessionID; } + const QUuid& getSessionID() const { return _sessionID; } void addObject(ObjectMotionState* motionState); void removeObject(ObjectMotionState* motionState);