bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& sessionID) { // NOTE: we expect _entity and _body to be valid in this context, since shouldSendUpdate() is only called // after doesNotNeedToSendUpdate() returns false and that call should return 'true' if _entity or _body are NULL. assert(_entity); assert(_body); assert(entityTreeIsLocked()); if (_entity->actionDataNeedsTransmit()) { return true; } if (_entity->queryAABoxNeedsUpdate()) { return true; } if (_entity->getSimulatorID() != sessionID) { // we don't own the simulation, but maybe we should... if (_outgoingPriority != NO_PRORITY) { if (_outgoingPriority < _entity->getSimulationPriority()) { // our priority loses to remote, so we don't bother to bid _outgoingPriority = NO_PRORITY; return false; } return usecTimestampNow() > _nextOwnershipBid; } return false; } return remoteSimulationOutOfSync(simulationStep); }
bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep, const QUuid& sessionID) { // NOTE: we expect _entity and _body to be valid in this context, since shouldSendUpdate() is only called // after doesNotNeedToSendUpdate() returns false and that call should return 'true' if _entity or _body are NULL. assert(_entity); assert(_body); if (!remoteSimulationOutOfSync(simulationStep)) { _candidateForOwnership = false; return false; } if (_entity->getSimulatorID() == sessionID) { // we own the simulation _candidateForOwnership = false; return true; } const uint32_t FRAMES_BETWEEN_OWNERSHIP_CLAIMS = 30; if (_candidateForOwnership) { _candidateForOwnership = false; ++_loopsSinceOwnershipBid; if (_loopsSinceOwnershipBid > FRAMES_BETWEEN_OWNERSHIP_CLAIMS) { // we don't own the simulation, but it's time to bid for it _loopsSinceOwnershipBid = 0; return true; } } _candidateForOwnership = false; return false; }
bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep) { // NOTE: we expect _entity and _body to be valid in this context, since shouldSendUpdate() is only called // after doesNotNeedToSendUpdate() returns false and that call should return 'true' if _entity or _body are NULL. assert(_entity); assert(_body); assert(entityTreeIsLocked()); if (_entity->getClientOnly() && _entity->getOwningAvatarID() != Physics::getSessionUUID()) { // don't send updates for someone else's avatarEntities return false; } if (_entity->actionDataNeedsTransmit()) { return true; } if (_entity->queryAABoxNeedsUpdate()) { return true; } if (_entity->getSimulatorID() != Physics::getSessionUUID()) { // we don't own the simulation // NOTE: we do not volunteer to own kinematic or static objects uint8_t insufficientPriority = _body->isStaticOrKinematicObject() ? VOLUNTEER_SIMULATION_PRIORITY : 0; bool shouldBid = _outgoingPriority > insufficientPriority && // 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); }
bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep) { // NOTE: this method is only ever called when the entity simulation is locally owned DETAILED_PROFILE_RANGE(simulation_physics, "ShouldSend"); // NOTE: we expect _entity and _body to be valid in this context, since shouldSendUpdate() is only called // after doesNotNeedToSendUpdate() returns false and that call should return 'true' if _entity or _body are NULL. assert(entityTreeIsLocked()); // this case is prevented by setting _ownershipState to UNOWNABLE in EntityMotionState::ctor assert(!(_entity->isAvatarEntity() && _entity->getOwningAvatarID() != Physics::getSessionUUID())); if (_entity->getTransitingWithAvatar()) { return false; } if (_entity->dynamicDataNeedsTransmit()) { return true; } if (_entity->shouldSuppressLocationEdits()) { // "shouldSuppressLocationEdits" really means: "the entity has a 'Hold' action therefore // we don't need send an update unless the entity is not contained by its queryAACube" return _entity->queryAACubeNeedsUpdate(); } return remoteSimulationOutOfSync(simulationStep); }