// virtual bool EntityMotionState::handleEasyChanges(uint32_t& flags, PhysicsEngine* engine) { assert(entityTreeIsLocked()); updateServerPhysicsVariables(engine->getSessionID()); ObjectMotionState::handleEasyChanges(flags, engine); if (flags & Simulation::DIRTY_SIMULATOR_ID) { _loopsWithoutOwner = 0; if (_entity->getSimulatorID().isNull()) { // simulation ownership is being removed // remove the ACTIVATION flag because this object is coming to rest // according to a remote simulation and we don't want to wake it up again flags &= ~Simulation::DIRTY_PHYSICS_ACTIVATION; // hint to Bullet that the object is deactivating _body->setActivationState(WANTS_DEACTIVATION); _outgoingPriority = NO_PRORITY; } else { _nextOwnershipBid = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; if (engine->getSessionID() == _entity->getSimulatorID() || _entity->getSimulationPriority() >= _outgoingPriority) { // we own the simulation or our priority looses to (or ties with) remote _outgoingPriority = NO_PRORITY; } } } if (flags & Simulation::DIRTY_SIMULATOR_OWNERSHIP) { // (DIRTY_SIMULATOR_OWNERSHIP really means "we should bid for ownership with SCRIPT priority") // we're manipulating this object directly via script, so we artificially // manipulate the logic to trigger an immediate bid for ownership setOutgoingPriority(SCRIPT_EDIT_SIMULATION_PRIORITY); } if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { _body->activate(); } return true; }
// virtual void EntityMotionState::handleEasyChanges(uint32_t flags) { updateServerPhysicsVariables(flags); ObjectMotionState::handleEasyChanges(flags); if (flags & EntityItem::DIRTY_SIMULATOR_ID) { _loopsWithoutOwner = 0; _candidateForOwnership = 0; if (_entity->getSimulatorID().isNull() && !_entity->isMoving() && _body->isActive()) { // remove the ACTIVATION flag because this object is coming to rest // according to a remote simulation and we don't want to wake it up again flags &= ~EntityItem::DIRTY_PHYSICS_ACTIVATION; _body->setActivationState(WANTS_DEACTIVATION); } else { auto nodeList = DependencyManager::get<NodeList>(); const QUuid& sessionID = nodeList->getSessionUUID(); if (_entity->getSimulatorID() != sessionID) { _loopsSinceOwnershipBid = 0; } } } if ((flags & EntityItem::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { _body->activate(); } }
// virtual void EntityMotionState::handleEasyChanges(uint32_t& flags) { assert(entityTreeIsLocked()); updateServerPhysicsVariables(); ObjectMotionState::handleEasyChanges(flags); if (flags & Simulation::DIRTY_SIMULATOR_ID) { 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 _outgoingPriority flags &= ~Simulation::DIRTY_PHYSICS_ACTIVATION; _body->setActivationState(WANTS_DEACTIVATION); _outgoingPriority = 0; } else { // 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); _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()); } 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". // 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()) { if (_body->isKinematicObject()) { // only force activate kinematic bodies (dynamic shouldn't need force and // active static bodies are special (see PhysicsEngine::_activeStaticBodies)) _body->activate(true); _lastKinematicStep = ObjectMotionState::getWorldSimulationStep(); } else { _body->activate(); } } }
// virtual void EntityMotionState::handleEasyChanges(uint32_t& flags) { assert(entityTreeIsLocked()); updateServerPhysicsVariables(); ObjectMotionState::handleEasyChanges(flags); if (flags & Simulation::DIRTY_SIMULATOR_ID) { if (_entity->getSimulatorID().isNull()) { // simulation ownership has been removed if (glm::length2(_entity->getWorldVelocity()) == 0.0f) { // TODO: also check angularVelocity // this object is coming to rest flags &= ~Simulation::DIRTY_PHYSICS_ACTIVATION; _body->setActivationState(WANTS_DEACTIVATION); const float ACTIVATION_EXPIRY = 3.0f; // something larger than the 2.0 hard coded in Bullet _body->setDeactivationTime(ACTIVATION_EXPIRY); } else { // disowned object is still moving --> start timer for ownership bid // TODO? put a delay in here proportional to distance from object? _bumpedPriority = glm::max(_bumpedPriority, VOLUNTEER_SIMULATION_PRIORITY); _nextBidExpiry = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; } _loopsWithoutOwner = 0; _numInactiveUpdates = 0; } else if (!isLocallyOwned()) { // the entity is owned by someone else _nextBidExpiry = usecTimestampNow() + USECS_BETWEEN_OWNERSHIP_BIDS; _numInactiveUpdates = 0; } } if (flags & Simulation::DIRTY_SIMULATION_OWNERSHIP_PRIORITY) { // The DIRTY_SIMULATOR_OWNERSHIP_PRIORITY bit means one of the following: // (1) we own it but may need to change the priority OR... // (2) we don't own it but should bid (because a local script has been changing physics properties) // reset bid expiry so that we bid ASAP _nextBidExpiry = 0; } if ((flags & Simulation::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) { if (_body->isKinematicObject()) { // only force activate kinematic bodies (dynamic shouldn't need force and // active static bodies are special (see PhysicsEngine::_activeStaticBodies)) _body->activate(true); _lastKinematicStep = ObjectMotionState::getWorldSimulationStep(); } else { _body->activate(); } } }
// virtual bool EntityMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) { updateServerPhysicsVariables(engine->getSessionID()); return ObjectMotionState::handleHardAndEasyChanges(flags, engine); }
// virtual void EntityMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine) { updateServerPhysicsVariables(); ObjectMotionState::handleHardAndEasyChanges(flags, engine); }