more correct notion of desired simulation priority

This commit is contained in:
Andrew Meadows 2016-03-09 11:02:50 -08:00
parent 99a1310711
commit 9157ff6eda
5 changed files with 44 additions and 43 deletions

View file

@ -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() {

View file

@ -18,8 +18,6 @@
#include <SharedUtil.h>
#include <UUID.h>
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 {

View file

@ -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<uint8_t>(_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));
}

View file

@ -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

View file

@ -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);
}
}
}