From 99a1310711b92bf4795c8ca12060c1a20a7b3881 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 8 Mar 2016 22:17:44 -0800 Subject: [PATCH 1/3] change properties at 127 priority, grab at 128 --- libraries/entities/src/EntityItem.h | 3 +- .../entities/src/EntityScriptingInterface.cpp | 31 ++++++++----------- libraries/entities/src/SimulationFlags.h | 7 +++-- libraries/entities/src/SimulationOwner.h | 7 +++-- libraries/physics/src/EntityMotionState.cpp | 27 ++++++++++------ libraries/physics/src/EntityMotionState.h | 6 ++-- libraries/physics/src/ObjectMotionState.h | 2 +- 7 files changed, 45 insertions(+), 38 deletions(-) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 62cc8ad69a..5bd761b4e3 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -368,7 +368,8 @@ public: void getAllTerseUpdateProperties(EntityItemProperties& properties) const; - void flagForOwnership() { _dirtyFlags |= Simulation::DIRTY_SIMULATOR_OWNERSHIP; } + void pokeSimulationOwnership() { _dirtyFlags |= Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_POKE; } + void grabSimulationOwnership() { _dirtyFlags |= Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB; } void flagForMotionStateChange() { _dirtyFlags |= Simulation::DIRTY_MOTION_TYPE; } bool addAction(EntitySimulation* simulation, EntityActionPointer action); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 26f73eb65a..702b1ed916 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -157,8 +157,8 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties const QUuid myNodeID = nodeList->getSessionUUID(); // and make note of it now, so we can act on it right away. - propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); - entity->setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); + propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY); + entity->setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY); } entity->setLastBroadcast(usecTimestampNow()); @@ -321,20 +321,19 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& // TODO: if we knew that ONLY TerseUpdate properties have changed in properties AND the object // is dynamic AND it is active in the physics simulation then we could chose to NOT queue an update // and instead let the physics simulation decide when to send a terse update. This would remove - // the "slide-no-rotate" glitch (and typical a double-update) that we see during the "poke rolling + // the "slide-no-rotate" glitch (and typical double-update) that we see during the "poke rolling // balls" test. However, even if we solve this problem we still need to provide a "slerp the visible // proxy toward the true physical position" feature to hide the final glitches in the remote watcher's // simulation. - if (entity->getSimulationPriority() < SCRIPT_EDIT_SIMULATION_PRIORITY) { + if (entity->getSimulationPriority() < SCRIPT_POKE_SIMULATION_PRIORITY) { // we re-assert our simulation ownership at a higher priority - properties.setSimulationOwner(myNodeID, - glm::max(entity->getSimulationPriority(), SCRIPT_EDIT_SIMULATION_PRIORITY)); + properties.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY); } } else { // we make a bid for simulation ownership - properties.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); - entity->flagForOwnership(); + properties.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY); + entity->pokeSimulationOwnership(); } } if (properties.parentRelatedPropertyChanged() && entity->computePuffedQueryAACube()) { @@ -806,11 +805,7 @@ QUuid EntityScriptingInterface::addAction(const QString& actionTypeString, return false; } success = entity->addAction(simulation, action); - auto nodeList = DependencyManager::get(); - const QUuid myNodeID = nodeList->getSessionUUID(); - if (entity->getSimulatorID() != myNodeID) { - entity->flagForOwnership(); - } + entity->grabSimulationOwnership(); return false; // Physics will cause a packet to be sent, so don't send from here. }); if (success) { @@ -824,11 +819,7 @@ bool EntityScriptingInterface::updateAction(const QUuid& entityID, const QUuid& return actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) { bool success = entity->updateAction(simulation, actionID, arguments); if (success) { - auto nodeList = DependencyManager::get(); - const QUuid myNodeID = nodeList->getSessionUUID(); - if (entity->getSimulatorID() != myNodeID) { - entity->flagForOwnership(); - } + entity->grabSimulationOwnership(); } return success; }); @@ -838,6 +829,10 @@ bool EntityScriptingInterface::deleteAction(const QUuid& entityID, const QUuid& bool success = false; actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) { success = entity->removeAction(simulation, actionID); + if (success) { + // reduce from grab to poke + entity->pokeSimulationOwnership(); + } return false; // Physics will cause a packet to be sent, so don't send from here. }); return success; diff --git a/libraries/entities/src/SimulationFlags.h b/libraries/entities/src/SimulationFlags.h index 91db978e1d..dbcf51afc0 100644 --- a/libraries/entities/src/SimulationFlags.h +++ b/libraries/entities/src/SimulationFlags.h @@ -25,10 +25,13 @@ namespace Simulation { const uint32_t DIRTY_UPDATEABLE = 0x0200; const uint32_t DIRTY_MATERIAL = 0x00400; const uint32_t DIRTY_PHYSICS_ACTIVATION = 0x0800; // should activate object in physics engine - const uint32_t DIRTY_SIMULATOR_OWNERSHIP = 0x1000; // should claim simulator ownership - const uint32_t DIRTY_SIMULATOR_ID = 0x2000; // the simulatorID has changed + const uint32_t DIRTY_SIMULATOR_ID = 0x1000; // the simulatorID has changed + const uint32_t DIRTY_SIMULATION_OWNERSHIP_FOR_POKE = 0x2000; // bid for simulation ownership at "poke" + const uint32_t DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB = 0x4000; // bid for simulation ownership at "grab" + const uint32_t DIRTY_TRANSFORM = DIRTY_POSITION | DIRTY_ROTATION; const uint32_t DIRTY_VELOCITIES = DIRTY_LINEAR_VELOCITY | DIRTY_ANGULAR_VELOCITY; + const uint32_t DIRTY_SIMULATION_OWNERSHIP_PRIORITY = DIRTY_SIMULATION_OWNERSHIP_FOR_POKE | DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB; }; #endif // hifi_SimulationFlags_h diff --git a/libraries/entities/src/SimulationOwner.h b/libraries/entities/src/SimulationOwner.h index bd17128003..2ce2129bde 100644 --- a/libraries/entities/src/SimulationOwner.h +++ b/libraries/entities/src/SimulationOwner.h @@ -27,11 +27,12 @@ const quint8 VOLUNTEER_SIMULATION_PRIORITY = 0x01; const quint8 RECRUIT_SIMULATION_PRIORITY = VOLUNTEER_SIMULATION_PRIORITY + 1; // When poking objects with scripts an observer will bid at SCRIPT_EDIT priority. -const quint8 SCRIPT_EDIT_SIMULATION_PRIORITY = 0x80; +const quint8 SCRIPT_GRAB_SIMULATION_PRIORITY = 0x80; +const quint8 SCRIPT_POKE_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY - 1; // PERSONAL priority (needs a better name) is the level at which a simulation observer will bid for -// objects that collide its MyAvatar. -const quint8 PERSONAL_SIMULATION_PRIORITY = SCRIPT_EDIT_SIMULATION_PRIORITY - 1; +// objects that collide with MyAvatar. +const quint8 PERSONAL_SIMULATION_PRIORITY = SCRIPT_POKE_SIMULATION_PRIORITY; class SimulationOwner { diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 6a818a1972..24522a4129 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -111,7 +111,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) { } else { // unowned object is still moving --> we should volunteer to own it // TODO? put a delay in here proportional to distance from object? - setOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY); + upgradeOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY); _loopsWithoutOwner = LOOPS_FOR_SIMULATION_ORPHAN; _nextOwnershipBid = 0; } @@ -125,11 +125,15 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) { } } } - if (flags & Simulation::DIRTY_SIMULATOR_OWNERSHIP) { - // The DIRTY_SIMULATOR_OWNERSHIP bit really means "we should bid for ownership at SCRIPT priority". - // Since that bit is set there must be a local script that is updating the physics properties of the objects - // therefore we upgrade _outgoingPriority to trigger a bid for ownership. - setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); + if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) { + // The DIRTY_SIMULATOR_OWNERSHIP_PRIORITY bits really mean "we should bid for ownership because + // a local script has been changing physics properties, or we should adjust our own ownership priority". + // The desired priority is determined by which bits were set. + if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB) { + _outgoingPriority = SCRIPT_GRAB_SIMULATION_PRIORITY; + } else { + _outgoingPriority = SCRIPT_POKE_SIMULATION_PRIORITY; + } } if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { _body->activate(); @@ -209,7 +213,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { _loopsWithoutOwner++; if (_loopsWithoutOwner > LOOPS_FOR_SIMULATION_ORPHAN && usecTimestampNow() > _nextOwnershipBid) { - setOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY); + upgradeOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY); } } @@ -298,7 +302,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { } if (_entity->actionDataNeedsTransmit()) { - setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); + _outgoingPriority = _entity->hasActions() ? SCRIPT_GRAB_SIMULATION_PRIORITY : SCRIPT_POKE_SIMULATION_PRIORITY; return true; } @@ -503,6 +507,9 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q // we don't own the simulation for this entity yet, but we're sending a bid for it properties.setSimulationOwner(sessionID, glm::max(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY)); _nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS; + } else if (_outgoingPriority != _entity->getSimulationPriority()) { + // we own the simulation but need to update the priority + properties.setSimulationOwner(sessionID, _outgoingPriority); } EntityItemID id(_entity->getID()); @@ -578,7 +585,7 @@ QUuid EntityMotionState::getSimulatorID() const { } void EntityMotionState::bump(uint8_t priority) { - setOutgoingPriority(glm::max(VOLUNTEER_SIMULATION_PRIORITY, --priority)); + upgradeOutgoingPriority(glm::max(VOLUNTEER_SIMULATION_PRIORITY, --priority)); } void EntityMotionState::resetMeasuredBodyAcceleration() { @@ -640,6 +647,6 @@ void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& ma _entity->computeCollisionGroupAndFinalMask(group, mask); } -void EntityMotionState::setOutgoingPriority(uint8_t priority) { +void EntityMotionState::upgradeOutgoingPriority(uint8_t priority) { _outgoingPriority = glm::max(_outgoingPriority, priority); } diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index cab8448dd9..c18fcc5862 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -82,12 +82,12 @@ public: virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; - // eternal logic can suggest a simuator priority bid for the next outgoing update - void setOutgoingPriority(uint8_t priority); - friend class PhysicalEntitySimulation; protected: + // changes _outgoingPriority only if priority is larger + void upgradeOutgoingPriority(uint8_t priority); + #ifdef WANT_DEBUG_ENTITY_TREE_LOCKS bool entityTreeIsLocked() const; #endif diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 073571c1c9..bb78eb12d6 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -50,7 +50,7 @@ const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TY Simulation::DIRTY_COLLISION_GROUP); const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES | Simulation::DIRTY_MASS | Simulation::DIRTY_MATERIAL | - Simulation::DIRTY_SIMULATOR_ID | Simulation::DIRTY_SIMULATOR_OWNERSHIP); + Simulation::DIRTY_SIMULATOR_ID | Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY); // These are the set of incoming flags that the PhysicsEngine needs to hear about: const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS | From 9157ff6eda7d00bc38208f483767c4f19f943a8d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Mar 2016 11:02:50 -0800 Subject: [PATCH 2/3] more correct notion of desired simulation priority --- libraries/entities/src/SimulationOwner.cpp | 6 +- libraries/entities/src/SimulationOwner.h | 8 +-- libraries/physics/src/EntityMotionState.cpp | 63 +++++++++++---------- libraries/physics/src/EntityMotionState.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 8 +-- 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/libraries/entities/src/SimulationOwner.cpp b/libraries/entities/src/SimulationOwner.cpp index 669d811df9..2db9f2a122 100644 --- a/libraries/entities/src/SimulationOwner.cpp +++ b/libraries/entities/src/SimulationOwner.cpp @@ -70,13 +70,15 @@ bool SimulationOwner::setID(const QUuid& id) { } bool SimulationOwner::set(const QUuid& id, quint8 priority) { + uint8_t oldPriority = _priority; setPriority(priority); - return setID(id); + return setID(id) || oldPriority != _priority; } bool SimulationOwner::set(const SimulationOwner& owner) { + uint8_t oldPriority = _priority; setPriority(owner._priority); - return setID(owner._id); + return setID(owner._id) || oldPriority != _priority; } void SimulationOwner::updateExpiry() { diff --git a/libraries/entities/src/SimulationOwner.h b/libraries/entities/src/SimulationOwner.h index 2ce2129bde..242d0eb272 100644 --- a/libraries/entities/src/SimulationOwner.h +++ b/libraries/entities/src/SimulationOwner.h @@ -18,8 +18,6 @@ #include #include -const quint8 ZERO_SIMULATION_PRIORITY = 0x00; - // Simulation observers will bid to simulate unowned active objects at the lowest possible priority // which is VOLUNTEER. If the server accepts a VOLUNTEER bid it will automatically bump it // to RECRUIT priority so that other volunteers don't accidentally take over. @@ -30,9 +28,9 @@ const quint8 RECRUIT_SIMULATION_PRIORITY = VOLUNTEER_SIMULATION_PRIORITY + 1; const quint8 SCRIPT_GRAB_SIMULATION_PRIORITY = 0x80; const quint8 SCRIPT_POKE_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY - 1; -// PERSONAL priority (needs a better name) is the level at which a simulation observer will bid for -// objects that collide with MyAvatar. -const quint8 PERSONAL_SIMULATION_PRIORITY = SCRIPT_POKE_SIMULATION_PRIORITY; +// PERSONAL priority (needs a better name) is the level at which a simulation observer owns its own avatar +// which really just means: things that collide with it will be bid at a priority level one lower +const quint8 PERSONAL_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY; class SimulationOwner { diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 24522a4129..d3359b7925 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -65,7 +65,7 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItemPointer _loopsWithoutOwner(0), _accelerationNearlyGravityCount(0), _numInactiveUpdates(1), - _outgoingPriority(ZERO_SIMULATION_PRIORITY) + _outgoingPriority(0) { _type = MOTIONSTATE_TYPE_ENTITY; assert(_entity); @@ -103,31 +103,31 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) { if (_entity->getSimulatorID().isNull()) { // simulation ownership has been removed by an external simulator if (glm::length2(_entity->getVelocity()) == 0.0f) { - // this object is coming to rest --> clear the ACTIVATION flag and outgoing priority + // this object is coming to rest --> clear the ACTIVATION flag and _outgoingPriority flags &= ~Simulation::DIRTY_PHYSICS_ACTIVATION; _body->setActivationState(WANTS_DEACTIVATION); - _outgoingPriority = ZERO_SIMULATION_PRIORITY; - _loopsWithoutOwner = 0; + _outgoingPriority = 0; } else { - // unowned object is still moving --> we should volunteer to own it + // disowned object is still moving --> start timer for ownership bid // TODO? put a delay in here proportional to distance from object? upgradeOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY); - _loopsWithoutOwner = LOOPS_FOR_SIMULATION_ORPHAN; - _nextOwnershipBid = 0; - } - } else { - // this entity's simulation is owned by someone, so we push its ownership expiry into the future - _nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; - if (Physics::getSessionUUID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) { - // either we already own the simulation or our old outgoing priority momentarily looses to current owner - // so we clear it - _outgoingPriority = ZERO_SIMULATION_PRIORITY; + _nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; } + _loopsWithoutOwner = 0; + } else if (_entity->getSimulatorID() == Physics::getSessionUUID()) { + // we just inherited ownership, make sure our desired priority matches what we have + upgradeOutgoingPriority(_entity->getSimulationPriority()); } } if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) { // The DIRTY_SIMULATOR_OWNERSHIP_PRIORITY bits really mean "we should bid for ownership because // a local script has been changing physics properties, or we should adjust our own ownership priority". + if (_outgoingPriority <= VOLUNTEER_SIMULATION_PRIORITY) { + // we were previously uninterested in owning this object + // which means this is our first frame of interest + // therefore we should bid immediately + _nextOwnershipBid = 0; + } // The desired priority is determined by which bits were set. if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB) { _outgoingPriority = SCRIPT_GRAB_SIMULATION_PRIORITY; @@ -247,7 +247,7 @@ bool EntityMotionState::isCandidateForOwnership(const QUuid& sessionID) const { assert(_body); assert(_entity); assert(entityTreeIsLocked()); - return _outgoingPriority != ZERO_SIMULATION_PRIORITY || sessionID == _entity->getSimulatorID() || _entity->actionDataNeedsTransmit(); + return _outgoingPriority != 0 || sessionID == _entity->getSimulatorID() || _entity->actionDataNeedsTransmit(); } bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { @@ -389,16 +389,9 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& s if (_entity->getSimulatorID() != sessionID) { // we don't own the simulation - if (_outgoingPriority != ZERO_SIMULATION_PRIORITY) { - // but we would like to own it - if (_outgoingPriority < _entity->getSimulationPriority()) { - // but our priority loses to remote, so we don't bother trying - _outgoingPriority = ZERO_SIMULATION_PRIORITY; - return false; - } - return usecTimestampNow() > _nextOwnershipBid; - } - return false; + return _outgoingPriority > 0 && // but we would like to own it and + _outgoingPriority >= _entity->getSimulationPriority() && // we are sufficiently interested and + usecTimestampNow() > _nextOwnershipBid; // it is time to bid again } return remoteSimulationOutOfSync(simulationStep); @@ -499,17 +492,24 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q #endif //def WANT_DEBUG if (_numInactiveUpdates > 0) { - // 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 + // we own the simulation but the entity has stopped so we tell the server we're clearing simulatorID + // but we remember we do still own it... and rely on the server to tell us we don't properties.clearSimulationOwner(); - _outgoingPriority = ZERO_SIMULATION_PRIORITY; + _outgoingPriority = 0; } else if (sessionID != _entity->getSimulatorID()) { // we don't own the simulation for this entity yet, but we're sending a bid for it properties.setSimulationOwner(sessionID, glm::max(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY)); _nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS; + _outgoingPriority = 0; // reset outgoing priority whenever we bid } else if (_outgoingPriority != _entity->getSimulationPriority()) { - // we own the simulation but need to update the priority - properties.setSimulationOwner(sessionID, _outgoingPriority); + // we own the simulation but our desired priority has changed + if (_outgoingPriority == 0) { + // we should release ownership + properties.clearSimulationOwner(); + } else { + // we just need to change the priority + properties.setSimulationOwner(sessionID, _outgoingPriority); + } } EntityItemID id(_entity->getID()); @@ -585,6 +585,7 @@ QUuid EntityMotionState::getSimulatorID() const { } void EntityMotionState::bump(uint8_t priority) { + assert(priority != 0); upgradeOutgoingPriority(glm::max(VOLUNTEER_SIMULATION_PRIORITY, --priority)); } diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index c18fcc5862..ac16ec6d5d 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -125,7 +125,7 @@ protected: uint8_t _loopsWithoutOwner; uint8_t _accelerationNearlyGravityCount; uint8_t _numInactiveUpdates { 1 }; - uint8_t _outgoingPriority { ZERO_SIMULATION_PRIORITY }; + uint8_t _outgoingPriority { 0 }; }; #endif // hifi_EntityMotionState_h diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 9a0580d31f..0040c19c3d 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -291,8 +291,8 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const // NOTE: we might own the simulation of a kinematic object (A) // but we don't claim ownership of kinematic objects (B) based on collisions here. if (!objectB->isStaticOrKinematicObject() && motionStateB->getSimulatorID() != _sessionID) { - quint8 priority = motionStateA ? motionStateA->getSimulationPriority() : PERSONAL_SIMULATION_PRIORITY; - motionStateB->bump(priority); + quint8 priorityA = motionStateA ? motionStateA->getSimulationPriority() : PERSONAL_SIMULATION_PRIORITY; + motionStateB->bump(priorityA); } } else if (motionStateA && ((motionStateB && motionStateB->getSimulatorID() == _sessionID && !objectB->isStaticObject()) || @@ -300,8 +300,8 @@ void PhysicsEngine::doOwnershipInfection(const btCollisionObject* objectA, const // SIMILARLY: we might own the simulation of a kinematic object (B) // but we don't claim ownership of kinematic objects (A) based on collisions here. if (!objectA->isStaticOrKinematicObject() && motionStateA->getSimulatorID() != _sessionID) { - quint8 priority = motionStateB ? motionStateB->getSimulationPriority() : PERSONAL_SIMULATION_PRIORITY; - motionStateA->bump(priority); + quint8 priorityB = motionStateB ? motionStateB->getSimulationPriority() : PERSONAL_SIMULATION_PRIORITY; + motionStateA->bump(priorityB); } } } From 4ae94c06117a6ac3b87a2ddb98a1021f7bb992a2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Mar 2016 13:06:34 -0800 Subject: [PATCH 3/3] fine tuning for when to make simulation bid --- libraries/physics/src/EntityMotionState.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index d3359b7925..e3952ba1d6 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -117,23 +117,22 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) { } else if (_entity->getSimulatorID() == Physics::getSessionUUID()) { // we just inherited ownership, make sure our desired priority matches what we have upgradeOutgoingPriority(_entity->getSimulationPriority()); + } else { + _outgoingPriority = 0; + _nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; } } if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) { // The DIRTY_SIMULATOR_OWNERSHIP_PRIORITY bits really mean "we should bid for ownership because // a local script has been changing physics properties, or we should adjust our own ownership priority". - if (_outgoingPriority <= VOLUNTEER_SIMULATION_PRIORITY) { - // we were previously uninterested in owning this object - // which means this is our first frame of interest - // therefore we should bid immediately - _nextOwnershipBid = 0; - } // The desired priority is determined by which bits were set. if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_FOR_GRAB) { _outgoingPriority = SCRIPT_GRAB_SIMULATION_PRIORITY; } else { _outgoingPriority = SCRIPT_POKE_SIMULATION_PRIORITY; } + // reset bid expiry so that we bid ASAP + _nextOwnershipBid = 0; } if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { _body->activate(); @@ -389,9 +388,15 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& s if (_entity->getSimulatorID() != sessionID) { // we don't own the simulation - return _outgoingPriority > 0 && // but we would like to own it and - _outgoingPriority >= _entity->getSimulationPriority() && // we are sufficiently interested and + bool shouldBid = _outgoingPriority > 0 && // but we would like to own it and usecTimestampNow() > _nextOwnershipBid; // it is time to bid again + if (shouldBid && _outgoingPriority < _entity->getSimulationPriority()) { + // we are insufficiently interested so clear our interest + // and reset the bid expiry + _outgoingPriority = 0; + _nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; + } + return shouldBid; } return remoteSimulationOutOfSync(simulationStep);