change properties at 127 priority, grab at 128

This commit is contained in:
Andrew Meadows 2016-03-08 22:17:44 -08:00
parent 9db528d7a3
commit 99a1310711
7 changed files with 45 additions and 38 deletions

View file

@ -368,7 +368,8 @@ public:
void getAllTerseUpdateProperties(EntityItemProperties& properties) const; 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; } void flagForMotionStateChange() { _dirtyFlags |= Simulation::DIRTY_MOTION_TYPE; }
bool addAction(EntitySimulation* simulation, EntityActionPointer action); bool addAction(EntitySimulation* simulation, EntityActionPointer action);

View file

@ -157,8 +157,8 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
const QUuid myNodeID = nodeList->getSessionUUID(); const QUuid myNodeID = nodeList->getSessionUUID();
// and make note of it now, so we can act on it right away. // and make note of it now, so we can act on it right away.
propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); propertiesWithSimID.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY);
entity->setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); entity->setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY);
} }
entity->setLastBroadcast(usecTimestampNow()); 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 // 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 // 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 // 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 // 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 // proxy toward the true physical position" feature to hide the final glitches in the remote watcher's
// simulation. // 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 // we re-assert our simulation ownership at a higher priority
properties.setSimulationOwner(myNodeID, properties.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY);
glm::max(entity->getSimulationPriority(), SCRIPT_EDIT_SIMULATION_PRIORITY));
} }
} else { } else {
// we make a bid for simulation ownership // we make a bid for simulation ownership
properties.setSimulationOwner(myNodeID, SCRIPT_EDIT_SIMULATION_PRIORITY); properties.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY);
entity->flagForOwnership(); entity->pokeSimulationOwnership();
} }
} }
if (properties.parentRelatedPropertyChanged() && entity->computePuffedQueryAACube()) { if (properties.parentRelatedPropertyChanged() && entity->computePuffedQueryAACube()) {
@ -806,11 +805,7 @@ QUuid EntityScriptingInterface::addAction(const QString& actionTypeString,
return false; return false;
} }
success = entity->addAction(simulation, action); success = entity->addAction(simulation, action);
auto nodeList = DependencyManager::get<NodeList>(); entity->grabSimulationOwnership();
const QUuid myNodeID = nodeList->getSessionUUID();
if (entity->getSimulatorID() != myNodeID) {
entity->flagForOwnership();
}
return false; // Physics will cause a packet to be sent, so don't send from here. return false; // Physics will cause a packet to be sent, so don't send from here.
}); });
if (success) { if (success) {
@ -824,11 +819,7 @@ bool EntityScriptingInterface::updateAction(const QUuid& entityID, const QUuid&
return actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) { return actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) {
bool success = entity->updateAction(simulation, actionID, arguments); bool success = entity->updateAction(simulation, actionID, arguments);
if (success) { if (success) {
auto nodeList = DependencyManager::get<NodeList>(); entity->grabSimulationOwnership();
const QUuid myNodeID = nodeList->getSessionUUID();
if (entity->getSimulatorID() != myNodeID) {
entity->flagForOwnership();
}
} }
return success; return success;
}); });
@ -838,6 +829,10 @@ bool EntityScriptingInterface::deleteAction(const QUuid& entityID, const QUuid&
bool success = false; bool success = false;
actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) { actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) {
success = entity->removeAction(simulation, actionID); 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 false; // Physics will cause a packet to be sent, so don't send from here.
}); });
return success; return success;

View file

@ -25,10 +25,13 @@ namespace Simulation {
const uint32_t DIRTY_UPDATEABLE = 0x0200; const uint32_t DIRTY_UPDATEABLE = 0x0200;
const uint32_t DIRTY_MATERIAL = 0x00400; const uint32_t DIRTY_MATERIAL = 0x00400;
const uint32_t DIRTY_PHYSICS_ACTIVATION = 0x0800; // should activate object in physics engine 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 = 0x1000; // the simulatorID has changed
const uint32_t DIRTY_SIMULATOR_ID = 0x2000; // 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_TRANSFORM = DIRTY_POSITION | DIRTY_ROTATION;
const uint32_t DIRTY_VELOCITIES = DIRTY_LINEAR_VELOCITY | DIRTY_ANGULAR_VELOCITY; 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 #endif // hifi_SimulationFlags_h

View file

@ -27,11 +27,12 @@ const quint8 VOLUNTEER_SIMULATION_PRIORITY = 0x01;
const quint8 RECRUIT_SIMULATION_PRIORITY = VOLUNTEER_SIMULATION_PRIORITY + 1; const quint8 RECRUIT_SIMULATION_PRIORITY = VOLUNTEER_SIMULATION_PRIORITY + 1;
// When poking objects with scripts an observer will bid at SCRIPT_EDIT priority. // 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 // PERSONAL priority (needs a better name) is the level at which a simulation observer will bid for
// objects that collide its MyAvatar. // objects that collide with MyAvatar.
const quint8 PERSONAL_SIMULATION_PRIORITY = SCRIPT_EDIT_SIMULATION_PRIORITY - 1; const quint8 PERSONAL_SIMULATION_PRIORITY = SCRIPT_POKE_SIMULATION_PRIORITY;
class SimulationOwner { class SimulationOwner {

View file

@ -111,7 +111,7 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
} else { } else {
// unowned object is still moving --> we should volunteer to own it // unowned object is still moving --> we should volunteer to own it
// TODO? put a delay in here proportional to distance from object? // TODO? put a delay in here proportional to distance from object?
setOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY); upgradeOutgoingPriority(VOLUNTEER_SIMULATION_PRIORITY);
_loopsWithoutOwner = LOOPS_FOR_SIMULATION_ORPHAN; _loopsWithoutOwner = LOOPS_FOR_SIMULATION_ORPHAN;
_nextOwnershipBid = 0; _nextOwnershipBid = 0;
} }
@ -125,11 +125,15 @@ bool EntityMotionState::handleEasyChanges(uint32_t& flags) {
} }
} }
} }
if (flags & Simulation::DIRTY_SIMULATOR_OWNERSHIP) { if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) {
// The DIRTY_SIMULATOR_OWNERSHIP bit really means "we should bid for ownership at SCRIPT priority". // The DIRTY_SIMULATOR_OWNERSHIP_PRIORITY bits really mean "we should bid for ownership because
// Since that bit is set there must be a local script that is updating the physics properties of the objects // a local script has been changing physics properties, or we should adjust our own ownership priority".
// therefore we upgrade _outgoingPriority to trigger a bid for ownership. // The desired priority is determined by which bits were set.
setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); 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()) { if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
_body->activate(); _body->activate();
@ -209,7 +213,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
_loopsWithoutOwner++; _loopsWithoutOwner++;
if (_loopsWithoutOwner > LOOPS_FOR_SIMULATION_ORPHAN && usecTimestampNow() > _nextOwnershipBid) { 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()) { if (_entity->actionDataNeedsTransmit()) {
setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); _outgoingPriority = _entity->hasActions() ? SCRIPT_GRAB_SIMULATION_PRIORITY : SCRIPT_POKE_SIMULATION_PRIORITY;
return true; 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 // we don't own the simulation for this entity yet, but we're sending a bid for it
properties.setSimulationOwner(sessionID, glm::max<uint8_t>(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY)); properties.setSimulationOwner(sessionID, glm::max<uint8_t>(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY));
_nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS; _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()); EntityItemID id(_entity->getID());
@ -578,7 +585,7 @@ QUuid EntityMotionState::getSimulatorID() const {
} }
void EntityMotionState::bump(uint8_t priority) { void EntityMotionState::bump(uint8_t priority) {
setOutgoingPriority(glm::max(VOLUNTEER_SIMULATION_PRIORITY, --priority)); upgradeOutgoingPriority(glm::max(VOLUNTEER_SIMULATION_PRIORITY, --priority));
} }
void EntityMotionState::resetMeasuredBodyAcceleration() { void EntityMotionState::resetMeasuredBodyAcceleration() {
@ -640,6 +647,6 @@ void EntityMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& ma
_entity->computeCollisionGroupAndFinalMask(group, mask); _entity->computeCollisionGroupAndFinalMask(group, mask);
} }
void EntityMotionState::setOutgoingPriority(uint8_t priority) { void EntityMotionState::upgradeOutgoingPriority(uint8_t priority) {
_outgoingPriority = glm::max<uint8_t>(_outgoingPriority, priority); _outgoingPriority = glm::max<uint8_t>(_outgoingPriority, priority);
} }

View file

@ -82,12 +82,12 @@ public:
virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; 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; friend class PhysicalEntitySimulation;
protected: protected:
// changes _outgoingPriority only if priority is larger
void upgradeOutgoingPriority(uint8_t priority);
#ifdef WANT_DEBUG_ENTITY_TREE_LOCKS #ifdef WANT_DEBUG_ENTITY_TREE_LOCKS
bool entityTreeIsLocked() const; bool entityTreeIsLocked() const;
#endif #endif

View file

@ -50,7 +50,7 @@ const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_MOTION_TY
Simulation::DIRTY_COLLISION_GROUP); Simulation::DIRTY_COLLISION_GROUP);
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES | const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES |
Simulation::DIRTY_MASS | Simulation::DIRTY_MATERIAL | 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: // 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 | const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS |