cleanup and optimization rotational integration

This commit is contained in:
Andrew Meadows 2018-07-10 11:18:38 -07:00
parent 9171fcbe8b
commit dd6be374fa

View file

@ -42,22 +42,27 @@ glm::quat computeBulletRotationStep(const glm::vec3& angularVelocity, float time
// Exponential map // Exponential map
// google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia // google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
float speed = glm::length(angularVelocity); glm::vec3 axis = angularVelocity;
float angle = glm::length(axis) * timeStep;
// limit the angular motion because the exponential approximation fails for large steps // limit the angular motion because the exponential approximation fails for large steps
const float ANGULAR_MOTION_THRESHOLD = 0.5f * PI_OVER_TWO; const float ANGULAR_MOTION_THRESHOLD = 0.5f * PI_OVER_TWO;
if (speed * timeStep > ANGULAR_MOTION_THRESHOLD) { if (angle > ANGULAR_MOTION_THRESHOLD) {
speed = ANGULAR_MOTION_THRESHOLD / timeStep; angle = ANGULAR_MOTION_THRESHOLD;
} }
glm::vec3 axis = angularVelocity; const float MIN_ANGLE = 0.001f;
if (speed < 0.001f) { if (angle < MIN_ANGLE) {
// use Taylor's expansions of sync function // for small angles use Taylor's expansion of sin(x):
axis *= (0.5f * timeStep - (timeStep * timeStep * timeStep) * (0.020833333333f * speed * speed)); // sin(x) = x - (x^3)/(3!) + ...
// where: x = angle/2
// sin(angle/2) = angle/2 - (angle*angle*angle)/48
// but (angle = speed * timeStep) and we want to normalize the axis by dividing by speed
// which gives us:
axis *= timeStep * (0.5f - 0.020833333333f * angle * angle);
} else { } else {
// sync(speed) = sin(c * speed)/t axis *= (sinf(0.5f * angle) * timeStep / angle);
axis *= (sinf(0.5f * speed * timeStep) / speed );
} }
return glm::quat(cosf(0.5f * speed * timeStep), axis.x, axis.y, axis.z); return glm::quat(cosf(0.5f * angle), axis.x, axis.y, axis.z);
} }
/* end Bullet code derivation*/ /* end Bullet code derivation*/