mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 00:13:53 +02:00
Merge pull request #8039 from sethalves/quiet-es-sim-spam
fix problem related to server-side extrapolation of children of avatars
This commit is contained in:
commit
1a37653364
3 changed files with 64 additions and 30 deletions
|
@ -261,7 +261,14 @@ void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
|||
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
||||
while (itemItr != _simpleKinematicEntities.end()) {
|
||||
EntityItemPointer entity = *itemItr;
|
||||
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
|
||||
|
||||
// The entity-server doesn't know where avatars are, so don't attempt to do simple extrapolation for
|
||||
// children of avatars. See related code in EntityMotionState::remoteSimulationOutOfSync.
|
||||
bool ancestryIsKnown;
|
||||
entity->getMaximumAACube(ancestryIsKnown);
|
||||
bool hasAvatarAncestor = entity->hasAncestorOfType(NestableType::Avatar);
|
||||
|
||||
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo() && ancestryIsKnown && !hasAvatarAncestor) {
|
||||
entity->simulate(now);
|
||||
_entitiesToSort.insert(entity);
|
||||
++itemItr;
|
||||
|
|
|
@ -85,10 +85,10 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
|||
return;
|
||||
}
|
||||
|
||||
_serverPosition = _entity->getPosition();
|
||||
_serverRotation = _entity->getRotation();
|
||||
_serverVelocity = _entity->getVelocity();
|
||||
_serverAngularVelocity = _entity->getAngularVelocity();
|
||||
Transform localTransform;
|
||||
_entity->getLocalTransformAndVelocities(localTransform, _serverVelocity, _serverAngularVelocity);
|
||||
_serverPosition = localTransform.getTranslation();
|
||||
_serverRotation = localTransform.getRotation();
|
||||
_serverAcceleration = _entity->getAcceleration();
|
||||
_serverActionData = _entity->getActionData();
|
||||
}
|
||||
|
@ -271,14 +271,25 @@ bool EntityMotionState::isCandidateForOwnership() const {
|
|||
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||
// NOTE: we only get here if we think we own the simulation
|
||||
assert(_body);
|
||||
|
||||
bool parentTransformSuccess;
|
||||
Transform localToWorld = _entity->getParentTransform(parentTransformSuccess);
|
||||
Transform worldToLocal;
|
||||
Transform worldVelocityToLocal;
|
||||
if (parentTransformSuccess) {
|
||||
localToWorld.evalInverse(worldToLocal);
|
||||
worldVelocityToLocal = worldToLocal;
|
||||
worldVelocityToLocal.setTranslation(glm::vec3(0.0f));
|
||||
}
|
||||
|
||||
// if we've never checked before, our _lastStep will be 0, and we need to initialize our state
|
||||
if (_lastStep == 0) {
|
||||
btTransform xform = _body->getWorldTransform();
|
||||
_serverPosition = bulletToGLM(xform.getOrigin());
|
||||
_serverRotation = bulletToGLM(xform.getRotation());
|
||||
_serverVelocity = getBodyLinearVelocityGTSigma();
|
||||
_serverPosition = worldToLocal.transform(bulletToGLM(xform.getOrigin()));
|
||||
_serverRotation = worldToLocal.getRotation() * bulletToGLM(xform.getRotation());
|
||||
_serverVelocity = worldVelocityToLocal.transform(getBodyLinearVelocityGTSigma());
|
||||
_serverAcceleration = Vectors::ZERO;
|
||||
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
|
||||
_serverAngularVelocity = worldVelocityToLocal.transform(bulletToGLM(_body->getAngularVelocity()));
|
||||
_lastStep = simulationStep;
|
||||
_serverActionData = _entity->getActionData();
|
||||
_numInactiveUpdates = 1;
|
||||
|
@ -315,11 +326,21 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
|||
|
||||
_lastStep = simulationStep;
|
||||
if (glm::length2(_serverVelocity) > 0.0f) {
|
||||
_serverVelocity += _serverAcceleration * dt;
|
||||
_serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt);
|
||||
// NOTE: we ignore the second-order acceleration term when integrating
|
||||
// the position forward because Bullet also does this.
|
||||
_serverPosition += dt * _serverVelocity;
|
||||
// the entity-server doesn't know where avatars are, so it doesn't do simple extrapolation for children of
|
||||
// avatars. We are trying to guess what values the entity server has, so we don't do it here, either. See
|
||||
// related code in EntitySimulation::moveSimpleKinematics.
|
||||
bool ancestryIsKnown;
|
||||
_entity->getMaximumAACube(ancestryIsKnown);
|
||||
bool hasAvatarAncestor = _entity->hasAncestorOfType(NestableType::Avatar);
|
||||
|
||||
if (ancestryIsKnown && !hasAvatarAncestor) {
|
||||
_serverVelocity += _serverAcceleration * dt;
|
||||
_serverVelocity *= powf(1.0f - _body->getLinearDamping(), dt);
|
||||
|
||||
// NOTE: we ignore the second-order acceleration term when integrating
|
||||
// the position forward because Bullet also does this.
|
||||
_serverPosition += dt * _serverVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
if (_entity->actionDataNeedsTransmit()) {
|
||||
|
@ -341,7 +362,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
|||
// compute position error
|
||||
|
||||
btTransform worldTrans = _body->getWorldTransform();
|
||||
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
|
||||
glm::vec3 position = worldToLocal.transform(bulletToGLM(worldTrans.getOrigin()));
|
||||
|
||||
float dx2 = glm::distance2(position, _serverPosition);
|
||||
const float MAX_POSITION_ERROR_SQUARED = 0.000004f; // corresponds to 2mm
|
||||
|
@ -376,7 +397,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
|||
}
|
||||
}
|
||||
const float MIN_ROTATION_DOT = 0.99999f; // This corresponds to about 0.5 degrees of rotation
|
||||
glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
|
||||
glm::quat actualRotation = worldToLocal.getRotation() * bulletToGLM(worldTrans.getRotation());
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
if ((fabsf(glm::dot(actualRotation, _serverRotation)) < MIN_ROTATION_DOT)) {
|
||||
|
@ -481,11 +502,11 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
|
|||
}
|
||||
|
||||
// remember properties for local server prediction
|
||||
_serverPosition = _entity->getPosition();
|
||||
_serverRotation = _entity->getRotation();
|
||||
_serverVelocity = _entity->getVelocity();
|
||||
Transform localTransform;
|
||||
_entity->getLocalTransformAndVelocities(localTransform, _serverVelocity, _serverAngularVelocity);
|
||||
_serverPosition = localTransform.getTranslation();
|
||||
_serverRotation = localTransform.getRotation();
|
||||
_serverAcceleration = _entity->getAcceleration();
|
||||
_serverAngularVelocity = _entity->getAngularVelocity();
|
||||
_serverActionData = _entity->getActionData();
|
||||
|
||||
EntityItemProperties properties;
|
||||
|
@ -590,7 +611,7 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
|
|||
if (_body && _entity) {
|
||||
dirtyFlags = _entity->getDirtyFlags();
|
||||
|
||||
if (dirtyFlags | Simulation::DIRTY_SIMULATOR_ID) {
|
||||
if (dirtyFlags & Simulation::DIRTY_SIMULATOR_ID) {
|
||||
// when SIMULATOR_ID changes we must check for reinterpretation of asymmetric collision mask
|
||||
// bits for the avatar groups (e.g. MY_AVATAR vs OTHER_AVATAR)
|
||||
uint8_t entityCollisionMask = _entity->getCollisionless() ? 0 : _entity->getCollisionMask();
|
||||
|
@ -603,8 +624,12 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() {
|
|||
// we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings
|
||||
int bodyFlags = _body->getCollisionFlags();
|
||||
bool isMoving = _entity->isMovingRelativeToParent();
|
||||
if (((bodyFlags & btCollisionObject::CF_STATIC_OBJECT) && isMoving) ||
|
||||
(bodyFlags & btCollisionObject::CF_KINEMATIC_OBJECT && !isMoving)) {
|
||||
|
||||
if (((bodyFlags & btCollisionObject::CF_STATIC_OBJECT) && isMoving) // ||
|
||||
// TODO -- there is opportunity for an optimization here, but this currently causes
|
||||
// excessive re-insertion of the rigid body.
|
||||
// (bodyFlags & btCollisionObject::CF_KINEMATIC_OBJECT && !isMoving)
|
||||
) {
|
||||
dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,15 @@ public:
|
|||
|
||||
bool hasAncestorOfType(NestableType nestableType);
|
||||
|
||||
void getLocalTransformAndVelocities(Transform& localTransform,
|
||||
glm::vec3& localVelocity,
|
||||
glm::vec3& localAngularVelocity) const;
|
||||
|
||||
void setLocalTransformAndVelocities(
|
||||
const Transform& localTransform,
|
||||
const glm::vec3& localVelocity,
|
||||
const glm::vec3& localAngularVelocity);
|
||||
|
||||
protected:
|
||||
const NestableType _nestableType; // EntityItem or an AvatarData
|
||||
QUuid _id;
|
||||
|
@ -151,13 +160,6 @@ protected:
|
|||
quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to?
|
||||
SpatiallyNestablePointer getParentPointer(bool& success) const;
|
||||
|
||||
void getLocalTransformAndVelocities(Transform& localTransform, glm::vec3& localVelocity, glm::vec3& localAngularVelocity) const;
|
||||
|
||||
void setLocalTransformAndVelocities(
|
||||
const Transform& localTransform,
|
||||
const glm::vec3& localVelocity,
|
||||
const glm::vec3& localAngularVelocity);
|
||||
|
||||
mutable SpatiallyNestableWeakPointer _parent;
|
||||
|
||||
virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
|
||||
|
|
Loading…
Reference in a new issue