From 99a1310711b92bf4795c8ca12060c1a20a7b3881 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 8 Mar 2016 22:17:44 -0800 Subject: [PATCH] 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 |