mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:50:00 +02:00
Merge pull request #4804 from AndrewMeadows/nova
fix for physics wakeup when moving camera view
This commit is contained in:
commit
671a38beee
1 changed files with 70 additions and 78 deletions
|
@ -151,10 +151,10 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||||
_movingStepsWithoutSimulationOwner = 0;
|
_movingStepsWithoutSimulationOwner = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController?
|
uint32_t ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController?
|
||||||
|
|
||||||
if (_movingStepsWithoutSimulationOwner > ownershipClaimDelay) {
|
if (_movingStepsWithoutSimulationOwner > ownershipClaimDelay) {
|
||||||
qDebug() << "Warning -- claiming something I saw moving." << getName();
|
//qDebug() << "Warning -- claiming something I saw moving." << getName();
|
||||||
setShouldClaimSimulationOwnership(true);
|
setShouldClaimSimulationOwnership(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
const int MAX_NUM_NON_MOVING_UPDATES = 5;
|
const int MAX_NUM_NON_MOVING_UPDATES = 5;
|
||||||
|
|
||||||
bool EntityMotionState::doesNotNeedToSendUpdate() const {
|
bool EntityMotionState::doesNotNeedToSendUpdate() const {
|
||||||
return !_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES;
|
return !_body || (_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
|
@ -232,6 +232,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
_serverPosition += dt * _serverVelocity;
|
_serverPosition += dt * _serverVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: compensate for simulation offset here
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
btTransform worldTrans = _body->getWorldTransform();
|
||||||
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
|
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
|
||||||
|
|
||||||
|
@ -310,86 +311,60 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
return; // never update entities that are unknown
|
return; // never update entities that are unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool active = _body->isActive();
|
||||||
|
if (!active) {
|
||||||
|
if (_sentMoving) {
|
||||||
|
// make sure all derivatives are zero
|
||||||
|
glm::vec3 zero(0.0f);
|
||||||
|
_entity->setVelocity(zero);
|
||||||
|
_entity->setAngularVelocity(zero);
|
||||||
|
_entity->setAcceleration(zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float gravityLength = glm::length(_entity->getGravity());
|
||||||
|
float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength);
|
||||||
|
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
|
||||||
|
// acceleration measured during the most recent simulation step was close to gravity.
|
||||||
|
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
|
||||||
|
// only increment this if we haven't reached the threshold yet. this is to avoid
|
||||||
|
// overflowing the counter.
|
||||||
|
incrementAccelerationNearlyGravityCount();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
|
||||||
|
resetAccelerationNearlyGravityCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
|
||||||
|
// the entity server's estimates include gravity.
|
||||||
|
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
|
||||||
|
_entity->setAcceleration(_entity->getGravity());
|
||||||
|
} else {
|
||||||
|
_entity->setAcceleration(glm::vec3(0.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember properties for local server prediction
|
||||||
|
_serverPosition = _entity->getPosition();
|
||||||
|
_serverRotation = _entity->getRotation();
|
||||||
|
_serverVelocity = _entity->getVelocity();
|
||||||
|
_serverAcceleration = _entity->getAcceleration();
|
||||||
|
_serverAngularVelocity = _entity->getAngularVelocity();
|
||||||
|
|
||||||
|
_sentMoving = _serverVelocity != glm::vec3(0.0f) || _serverAngularVelocity != glm::vec3(0.0f);
|
||||||
|
|
||||||
EntityItemProperties properties = _entity->getProperties();
|
EntityItemProperties properties = _entity->getProperties();
|
||||||
|
|
||||||
float gravityLength = glm::length(_entity->getGravity());
|
// explicitly set the properties that changed
|
||||||
float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength);
|
properties.setPosition(_serverPosition);
|
||||||
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
|
|
||||||
// acceleration measured during the most recent simulation step was close to gravity.
|
|
||||||
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
|
|
||||||
// only increment this if we haven't reached the threshold yet. this is to avoid
|
|
||||||
// overflowing the counter.
|
|
||||||
incrementAccelerationNearlyGravityCount();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
|
|
||||||
resetAccelerationNearlyGravityCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
|
|
||||||
// the entity server's estimates include gravity.
|
|
||||||
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
|
|
||||||
_entity->setAcceleration(_entity->getGravity());
|
|
||||||
} else {
|
|
||||||
_entity->setAcceleration(glm::vec3(0.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
btTransform worldTrans = _body->getWorldTransform();
|
|
||||||
_serverPosition = bulletToGLM(worldTrans.getOrigin());
|
|
||||||
properties.setPosition(_serverPosition + ObjectMotionState::getWorldOffset());
|
|
||||||
|
|
||||||
_serverRotation = bulletToGLM(worldTrans.getRotation());
|
|
||||||
properties.setRotation(_serverRotation);
|
properties.setRotation(_serverRotation);
|
||||||
|
|
||||||
bool zeroSpeed = true;
|
|
||||||
bool zeroSpin = true;
|
|
||||||
|
|
||||||
if (_body->isActive()) {
|
|
||||||
_serverVelocity = bulletToGLM(_body->getLinearVelocity());
|
|
||||||
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
|
||||||
|
|
||||||
// if the speeds are very small we zero them out
|
|
||||||
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 1.0e-4f; // 1cm/sec
|
|
||||||
zeroSpeed = (glm::length2(_serverVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
|
|
||||||
if (zeroSpeed) {
|
|
||||||
_serverVelocity = glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
const float MINIMUM_EXTRAPOLATION_SPIN_SQUARED = 0.004f; // ~0.01 rotation/sec
|
|
||||||
zeroSpin = glm::length2(_serverAngularVelocity) < MINIMUM_EXTRAPOLATION_SPIN_SQUARED;
|
|
||||||
if (zeroSpin) {
|
|
||||||
_serverAngularVelocity = glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
_sentMoving = ! (zeroSpeed && zeroSpin);
|
|
||||||
} else {
|
|
||||||
_serverVelocity = _serverAngularVelocity = glm::vec3(0.0f);
|
|
||||||
_sentMoving = false;
|
|
||||||
}
|
|
||||||
properties.setVelocity(_serverVelocity);
|
properties.setVelocity(_serverVelocity);
|
||||||
_serverGravity = _entity->getGravity();
|
|
||||||
properties.setGravity(_entity->getGravity());
|
|
||||||
_serverAcceleration = _entity->getAcceleration();
|
|
||||||
properties.setAcceleration(_serverAcceleration);
|
properties.setAcceleration(_serverAcceleration);
|
||||||
properties.setAngularVelocity(_serverAngularVelocity);
|
properties.setAngularVelocity(_serverAngularVelocity);
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
// RELIABLE_SEND_HACK: count number of updates for entities at rest
|
||||||
QUuid myNodeID = nodeList->getSessionUUID();
|
// so we can stop sending them after some limit.
|
||||||
QUuid simulatorID = _entity->getSimulatorID();
|
|
||||||
|
|
||||||
if (getShouldClaimSimulationOwnership()) {
|
|
||||||
properties.setSimulatorID(myNodeID);
|
|
||||||
setShouldClaimSimulationOwnership(false);
|
|
||||||
} else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) {
|
|
||||||
// we are the simulator and the entity has stopped. give up "simulator" status
|
|
||||||
_entity->setSimulatorID(QUuid());
|
|
||||||
properties.setSimulatorID(QUuid());
|
|
||||||
} else if (simulatorID == myNodeID && !_body->isActive()) {
|
|
||||||
// it's not active. don't keep simulation ownership.
|
|
||||||
_entity->setSimulatorID(QUuid());
|
|
||||||
properties.setSimulatorID(QUuid());
|
|
||||||
}
|
|
||||||
|
|
||||||
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.
|
|
||||||
if (_sentMoving) {
|
if (_sentMoving) {
|
||||||
_numNonMovingUpdates = 0;
|
_numNonMovingUpdates = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -397,8 +372,6 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
}
|
}
|
||||||
if (_numNonMovingUpdates <= 1) {
|
if (_numNonMovingUpdates <= 1) {
|
||||||
// we only update lastEdited when we're sending new physics data
|
// we only update lastEdited when we're sending new physics data
|
||||||
// (i.e. NOT when we just simulate the positions forward, nor when we resend non-moving data)
|
|
||||||
// NOTE: Andrew & Brad to discuss. Let's make sure we're using lastEdited, lastSimulated, and lastUpdated correctly
|
|
||||||
quint64 lastSimulated = _entity->getLastSimulated();
|
quint64 lastSimulated = _entity->getLastSimulated();
|
||||||
_entity->setLastEdited(lastSimulated);
|
_entity->setLastEdited(lastSimulated);
|
||||||
properties.setLastEdited(lastSimulated);
|
properties.setLastEdited(lastSimulated);
|
||||||
|
@ -415,6 +388,25 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
||||||
properties.setLastEdited(_entity->getLastEdited());
|
properties.setLastEdited(_entity->getLastEdited());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
QUuid myNodeID = nodeList->getSessionUUID();
|
||||||
|
QUuid simulatorID = _entity->getSimulatorID();
|
||||||
|
|
||||||
|
if (getShouldClaimSimulationOwnership()) {
|
||||||
|
// we think we should own it, so we tell the server that we do,
|
||||||
|
// but we don't remember that we own it...
|
||||||
|
// instead we expect the sever to tell us later whose ownership it has accepted
|
||||||
|
properties.setSimulatorID(myNodeID);
|
||||||
|
setShouldClaimSimulationOwnership(false);
|
||||||
|
} else if (simulatorID == myNodeID
|
||||||
|
&& !_sentMoving
|
||||||
|
&& _numNonMovingUpdates == MAX_NUM_NON_MOVING_UPDATES) {
|
||||||
|
// we own it, the entity has stopped, and we're sending the last non-moving update
|
||||||
|
// --> give up ownership
|
||||||
|
_entity->setSimulatorID(QUuid());
|
||||||
|
properties.setSimulatorID(QUuid());
|
||||||
|
}
|
||||||
|
|
||||||
if (EntityItem::getSendPhysicsUpdates()) {
|
if (EntityItem::getSendPhysicsUpdates()) {
|
||||||
EntityItemID id(_entity->getID());
|
EntityItemID id(_entity->getID());
|
||||||
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);
|
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);
|
||||||
|
|
Loading…
Reference in a new issue