Jolt Physics
A multi core friendly Game Physics Engine
|
#include <RotationQuatConstraintPart.h>
Public Member Functions | |
void | CalculateConstraintProperties (const Body &inBody1, Mat44Arg inRotation1, const Body &inBody2, Mat44Arg inRotation2, QuatArg inInvInitialOrientation) |
Calculate properties used during the functions below. | |
void | Deactivate () |
Deactivate this constraint. | |
bool | IsActive () const |
Check if constraint is active. | |
void | WarmStart (Body &ioBody1, Body &ioBody2, float inWarmStartImpulseRatio) |
Must be called from the WarmStartVelocityConstraint call to apply the previous frame's impulses. | |
bool | SolveVelocityConstraint (Body &ioBody1, Body &ioBody2) |
Iteratively update the velocity constraint. Makes sure d/dt C(...) = 0, where C is the constraint equation. | |
bool | SolvePositionConstraint (Body &ioBody1, Body &ioBody2, QuatArg inInvInitialOrientation, float inBaumgarte) const |
Iteratively update the position constraint. Makes sure C(...) = 0. | |
Vec3 | GetTotalLambda () const |
Return lagrange multiplier. | |
void | SaveState (StateRecorder &inStream) const |
Save state of this constraint part. | |
void | RestoreState (StateRecorder &inStream) |
Restore state of this constraint part. | |
Static Public Member Functions | |
static Quat | sGetInvInitialOrientation (const Body &inBody1, const Body &inBody2) |
Return inverse of initial rotation from body 1 to body 2 in body 1 space. | |
Quaternion based constraint that constrains rotation around all axis so that only translation is allowed.
NOTE: This constraint part is more expensive than the RotationEulerConstraintPart and slightly more correct since RotationEulerConstraintPart::SolvePositionConstraint contains an approximation. In practice the difference is small, so the RotationEulerConstraintPart is probably the better choice.
Rotation is fixed between bodies like this:
q2 = q1 r0
Where: q1, q2 = world space quaternions representing rotation of body 1 and 2. r0 = initial rotation between bodies in local space of body 1, this can be calculated by:
q20 = q10 r0 <=> r0 = q10^* q20
Where: q10, q20 = initial world space rotations of body 1 and 2. q10^* = conjugate of quaternion q10 (which is the same as the inverse for a unit quaternion)
We exclusively use the conjugate below:
r0^* = q20^* q10
The error in the rotation is (in local space of body 1):
q2 = q1 error r0 <=> error = q1^* q2 r0^*
The imaginary part of the quaternion represents the rotation axis * sin(angle / 2). The real part of the quaternion does not add any additional information (we know the quaternion in normalized) and we're removing 3 degrees of freedom so we want 3 parameters. Therefore we define the constraint equation like:
C = A q1^* q2 r0^* = 0
Where (if you write a quaternion as [real-part, i-part, j-part, k-part]):
[0, 1, 0, 0] A = [0, 0, 1, 0] [0, 0, 0, 1]
or in our case since we store a quaternion like [i-part, j-part, k-part, real-part]:
[1, 0, 0, 0] A = [0, 1, 0, 0] [0, 0, 1, 0]
Time derivative:
d/dt C = A (q1^* d/dt(q2) + d/dt(q1^*) q2) r0^* = A (q1^* (1/2 W2 q2) + (1/2 W1 q1)^* q2) r0^* = 1/2 A (q1^* W2 q2 + q1^* W1^* q2) r0^* = 1/2 A (q1^* W2 q2 - q1^* W1 * q2) r0^* = 1/2 A ML(q1^*) MR(q2 r0^*) (W2 - W1) = 1/2 A ML(q1^*) MR(q2 r0^*) A^T (w2 - w1)
Where: W1 = [0, w1], W2 = [0, w2] (converting angular velocity to imaginary part of quaternion). w1, w2 = angular velocity of body 1 and 2. d/dt(q) = 1/2 W q (time derivative of a quaternion). W^* = -W (conjugate negates angular velocity as quaternion). ML(q): 4x4 matrix so that q * p = ML(q) * p, where q and p are quaternions. MR(p): 4x4 matrix so that q * p = MR(p) * q, where q and p are quaternions. A^T: Transpose of A.
Jacobian:
J = [0, -1/2 A ML(q1^*) MR(q2 r0^*) A^T, 0, 1/2 A ML(q1^*) MR(q2 r0^*) A^T] = [0, -JP, 0, JP]
Suggested reading:
|
inline |
Calculate properties used during the functions below.
|
inline |
Deactivate this constraint.
|
inline |
Return lagrange multiplier.
|
inline |
Check if constraint is active.
|
inline |
Restore state of this constraint part.
|
inline |
Save state of this constraint part.
|
inlinestatic |
Return inverse of initial rotation from body 1 to body 2 in body 1 space.
|
inline |
Iteratively update the position constraint. Makes sure C(...) = 0.
Iteratively update the velocity constraint. Makes sure d/dt C(...) = 0, where C is the constraint equation.
|
inline |
Must be called from the WarmStartVelocityConstraint call to apply the previous frame's impulses.