mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 03:35:47 +02:00
use _gravity rather than _acceleration
also tweaks and comments about supporting low gravity
This commit is contained in:
parent
74058ac049
commit
a53cb2e532
1 changed files with 53 additions and 21 deletions
|
@ -895,9 +895,9 @@ void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
|
||||||
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH_SQUARED = 0.0017453f * 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec
|
const float MIN_KINEMATIC_ANGULAR_SPEED_SQUARED = 0.0017453f * 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec
|
||||||
if (glm::length2(angularVelocity) < EPSILON_ANGULAR_VELOCITY_LENGTH_SQUARED) {
|
if (glm::length2(angularVelocity) < MIN_KINEMATIC_ANGULAR_SPEED_SQUARED) {
|
||||||
angularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
angularVelocity = Vectors::ZERO;
|
||||||
} else {
|
} else {
|
||||||
// for improved agreement with the way Bullet integrates rotations we use an approximation
|
// for improved agreement with the way Bullet integrates rotations we use an approximation
|
||||||
// and break the integration into bullet-sized substeps
|
// and break the integration into bullet-sized substeps
|
||||||
|
@ -912,43 +912,75 @@ void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
|
||||||
isMoving = true;
|
isMoving = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (glm::length2(linearVelocity) > 0.0f) {
|
glm::vec3 position = transform.getTranslation();
|
||||||
|
|
||||||
|
const float MIN_KINEMATIC_LINEAR_SPEED_SQUARED = 1.0e-6f; // 1mm/sec ^2
|
||||||
|
bool hasLinearVelocity = (glm::length2(linearVelocity) > MIN_KINEMATIC_LINEAR_SPEED_SQUARED );
|
||||||
|
if (hasLinearVelocity) {
|
||||||
// linear damping
|
// linear damping
|
||||||
if (_damping > 0.0f) {
|
if (_damping > 0.0f) {
|
||||||
linearVelocity *= powf(1.0f - _damping, timeElapsed);
|
linearVelocity *= powf(1.0f - _damping, timeElapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 linearAcceleration = _acceleration;
|
// integrate position forward sans acceleration
|
||||||
bool nonZeroAcceleration = (glm::length2(_acceleration) > 0.0f);
|
position += linearVelocity * timeElapsed;
|
||||||
if (nonZeroAcceleration) {
|
}
|
||||||
// acceleration is in world-frame but we need it in local-frame
|
|
||||||
bool success;
|
const float MIN_KINEMATIC_GRAVITY_MOTION_SQUARED = 1.0e-6f; // 0.001 mm/sec^2
|
||||||
Transform parentTransform = getParentTransform(success);
|
bool hasGravity = (glm::length2(_gravity) > MIN_KINEMATIC_GRAVITY_MOTION_SQUARED);
|
||||||
if (success) {
|
if (hasGravity) {
|
||||||
linearAcceleration = glm::inverse(parentTransform.getRotation()) * linearAcceleration;
|
// acceleration is in world-frame but we need it in local-frame
|
||||||
}
|
glm::vec3 linearAcceleration = _gravity;
|
||||||
|
bool success;
|
||||||
|
Transform parentTransform = getParentTransform(success);
|
||||||
|
if (success) {
|
||||||
|
linearAcceleration = glm::inverse(parentTransform.getRotation()) * linearAcceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// integrate position forward
|
// integrate position's acceleration term
|
||||||
glm::vec3 position = transform.getTranslation() + (linearVelocity * timeElapsed) + 0.5f * linearAcceleration * timeElapsed * timeElapsed;
|
position += 0.5f * linearAcceleration * timeElapsed * timeElapsed;
|
||||||
transform.setTranslation(position);
|
|
||||||
|
|
||||||
// integrate linearVelocity
|
// integrate linearVelocity
|
||||||
linearVelocity += linearAcceleration * timeElapsed;
|
linearVelocity += linearAcceleration * timeElapsed;
|
||||||
|
}
|
||||||
|
|
||||||
const float EPSILON_LINEAR_VELOCITY_LENGTH_SQUARED = 1.0e-6f; // 1mm/sec ^2
|
if (hasLinearVelocity || hasGravity) {
|
||||||
if (glm::length2(linearVelocity) < EPSILON_LINEAR_VELOCITY_LENGTH_SQUARED) {
|
// We MUST eventually stop kinematic motion for slow entities otherwise they will take
|
||||||
setVelocity(ENTITY_ITEM_ZERO_VEC3);
|
// a looooong time to settle down, so we remeasure linear speed and zero the velocity
|
||||||
if (nonZeroAcceleration) {
|
// if it is too small.
|
||||||
|
if (glm::length2(linearVelocity) < MIN_KINEMATIC_LINEAR_SPEED_SQUARED) {
|
||||||
|
linearVelocity = Vectors::ZERO;
|
||||||
|
if (!hasLinearVelocity) {
|
||||||
|
// Despite some gravity the final linear velocity is still too small to defeat the
|
||||||
|
// "effective resistance of free-space" which means we must reset position back to
|
||||||
|
// where it started since otherwise the entity may creep vveerrryy sslloowwllyy at
|
||||||
|
// a constant speed.
|
||||||
|
position = transform.getTranslation();
|
||||||
|
|
||||||
|
// Ultimately what this means is that there is some minimum gravity we can
|
||||||
|
// fully support for kinematic motion. It's exact value is a function of this
|
||||||
|
// entity's linearDamping and the hardcoded MIN_KINEMATIC_FOO parameters above,
|
||||||
|
// but the theoretical minimum gravity for zero damping at 90Hz is:
|
||||||
|
//
|
||||||
|
// minGravity = minSpeed / dt = 0.001 m/sec * 90 /sec = 0.09 m/sec^2
|
||||||
|
//
|
||||||
|
// In practice the true minimum is half that value, since if the frame rate is ever
|
||||||
|
// less than the expected then sometimes dt will be twice as long.
|
||||||
|
//
|
||||||
|
// Since we don't set isMoving true here this entity is destined to transition to
|
||||||
|
// STATIC unless it has some angular motion keeping it alive.
|
||||||
|
} else {
|
||||||
isMoving = true;
|
isMoving = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isMoving = true;
|
isMoving = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
transform.setTranslation(position);
|
||||||
setLocalTransformAndVelocities(transform, linearVelocity, angularVelocity);
|
setLocalTransformAndVelocities(transform, linearVelocity, angularVelocity);
|
||||||
|
|
||||||
if (!isMoving) {
|
if (!isMoving) {
|
||||||
// flag this entity to be removed from kinematic motion
|
// flag this entity to transition from KINEMATIC to STATIC
|
||||||
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue