Optimization of joints solver

This commit is contained in:
Daniel Chappuis 2020-10-12 23:56:33 +02:00
parent 916cefa96d
commit 2078971331
4 changed files with 66 additions and 586 deletions

View File

@ -47,6 +47,8 @@ SolveBallAndSocketJointSystem::SolveBallAndSocketJointSystem(PhysicsWorld& world
// Initialize before solving the constraint
void SolveBallAndSocketJointSystem::initBeforeSolve() {
const decimal biasFactor = (BETA / mTimeStep);
// For each joint
const uint32 nbJoints = mBallAndSocketJointComponents.getNbEnabledComponents();
for (uint32 i=0; i < nbJoints; i++) {
@ -64,17 +66,6 @@ void SolveBallAndSocketJointSystem::initBeforeSolve() {
// Get the inertia tensor of bodies
mBallAndSocketJointComponents.mI1[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body1Entity);
mBallAndSocketJointComponents.mI2[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body2Entity);
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mBallAndSocketJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
@ -82,13 +73,6 @@ void SolveBallAndSocketJointSystem::initBeforeSolve() {
// Compute the vector from body center to the anchor point in world-space
mBallAndSocketJointComponents.mR1World[i] = orientationBody1 * mBallAndSocketJointComponents.mLocalAnchorPointBody1[i];
mBallAndSocketJointComponents.mR2World[i] = orientationBody2 * mBallAndSocketJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mBallAndSocketJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Compute the corresponding skew-symmetric matrices
const Vector3& r1World = mBallAndSocketJointComponents.mR1World[i];
@ -96,10 +80,6 @@ void SolveBallAndSocketJointSystem::initBeforeSolve() {
Matrix3x3 skewSymmetricMatrixU1 = Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(r1World);
Matrix3x3 skewSymmetricMatrixU2 = Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(r2World);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
@ -121,22 +101,6 @@ void SolveBallAndSocketJointSystem::initBeforeSolve() {
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mBallAndSocketJointComponents.mInverseMassMatrix[i] = massMatrix.getInverse();
}
}
const decimal biasFactor = (BETA / mTimeStep);
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mBallAndSocketJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Vector3& r1World = mBallAndSocketJointComponents.mR1World[i];
const Vector3& r2World = mBallAndSocketJointComponents.mR2World[i];
const Vector3& x1 = mRigidBodyComponents.getCenterOfMassWorld(body1Entity);
const Vector3& x2 = mRigidBodyComponents.getCenterOfMassWorld(body2Entity);
@ -146,14 +110,10 @@ void SolveBallAndSocketJointSystem::initBeforeSolve() {
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] == JointsPositionCorrectionTechnique::BAUMGARTE_JOINTS) {
mBallAndSocketJointComponents.mBiasVector[i] = biasFactor * (x2 + r2World - x1 - r1World);
}
}
// If warm-starting is not enabled
if (!mIsWarmStartingActive) {
// For each joint
for (uint32 i=0; i < mBallAndSocketJointComponents.getNbEnabledComponents(); i++) {
// Reset the accumulated impulse
mBallAndSocketJointComponents.mImpulse[i].setToZero();
}
@ -271,51 +231,23 @@ void SolveBallAndSocketJointSystem::solvePositionConstraint() {
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Recompute the world inverse inertia tensors
const Matrix3x3 orientation1 = mTransformComponents.getTransform(body1Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation1, mRigidBodyComponents.getInertiaTensorLocalInverse(body1Entity),
RigidBody::computeWorldInertiaTensorInverse(orientation1, mRigidBodyComponents.mInverseInertiaTensorsLocal[componentIndexBody1],
mBallAndSocketJointComponents.mI1[i]);
const Matrix3x3 orientation2 = mTransformComponents.getTransform(body2Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.getInertiaTensorLocalInverse(body2Entity),
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.mInverseInertiaTensorsLocal[componentIndexBody2],
mBallAndSocketJointComponents.mI2[i]);
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mBallAndSocketJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Compute the vector from body center to the anchor point in world-space
mBallAndSocketJointComponents.mR1World[i] = mRigidBodyComponents.getConstrainedOrientation(body1Entity) *
mBallAndSocketJointComponents.mR1World[i] = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1] *
mBallAndSocketJointComponents.mLocalAnchorPointBody1[i];
mBallAndSocketJointComponents.mR2World[i] = mRigidBodyComponents.getConstrainedOrientation(body2Entity) *
mBallAndSocketJointComponents.mR2World[i] = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2] *
mBallAndSocketJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mBallAndSocketJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
const Vector3& r1World = mBallAndSocketJointComponents.mR1World[i];
const Vector3& r2World = mBallAndSocketJointComponents.mR2World[i];
@ -340,30 +272,10 @@ void SolveBallAndSocketJointSystem::solvePositionConstraint() {
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mBallAndSocketJointComponents.mInverseMassMatrix[i] = massMatrix.getInverse();
}
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mBallAndSocketJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
Vector3& x1 = mRigidBodyComponents.mConstrainedPositions[componentIndexBody1];
Vector3& x2 = mRigidBodyComponents.mConstrainedPositions[componentIndexBody2];
const Vector3& r1World = mBallAndSocketJointComponents.mR1World[i];
const Vector3& r2World = mBallAndSocketJointComponents.mR2World[i];
// Compute the constraint error (value of the C(x) function)
const Vector3 constraintError = (x2 + r2World - x1 - r1World);
@ -376,10 +288,6 @@ void SolveBallAndSocketJointSystem::solvePositionConstraint() {
const Vector3 linearImpulseBody1 = -lambda;
const Vector3 angularImpulseBody1 = lambda.cross(r1World);
// Get the inverse mass and inverse inertia tensors of the bodies
const decimal inverseMassBody1 = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
const decimal inverseMassBody2 = mRigidBodyComponents.mInverseMasses[componentIndexBody2];
// Compute the pseudo velocity of body 1
const Vector3 v1 = inverseMassBody1 * linearImpulseBody1;
const Vector3 w1 = mBallAndSocketJointComponents.mI1[i] * angularImpulseBody1;

View File

@ -47,6 +47,8 @@ SolveFixedJointSystem::SolveFixedJointSystem(PhysicsWorld& world, RigidBodyCompo
// Initialize before solving the constraint
void SolveFixedJointSystem::initBeforeSolve() {
const decimal biasFactor = BETA / mTimeStep;
// For each joint
const uint32 nbJoints = mFixedJointComponents.getNbEnabledComponents();
for (uint32 i=0; i < nbJoints; i++) {
@ -64,17 +66,6 @@ void SolveFixedJointSystem::initBeforeSolve() {
// Get the inertia tensor of bodies
mFixedJointComponents.mI1[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body1Entity);
mFixedJointComponents.mI2[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body2Entity);
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
@ -82,17 +73,6 @@ void SolveFixedJointSystem::initBeforeSolve() {
// Compute the vector from body center to the anchor point in world-space
mFixedJointComponents.mR1World[i] = orientationBody1 * mFixedJointComponents.mLocalAnchorPointBody1[i];
mFixedJointComponents.mR2World[i] = orientationBody2 * mFixedJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Compute the corresponding skew-symmetric matrices
Matrix3x3 skewSymmetricMatrixU1 = Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(mFixedJointComponents.mR1World[i]);
@ -117,19 +97,6 @@ void SolveFixedJointSystem::initBeforeSolve() {
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mFixedJointComponents.mInverseMassMatrixTranslation[i] = massMatrix.getInverse();
}
}
const decimal biasFactor = BETA / mTimeStep;
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Get the bodies positions and orientations
const Vector3& x1 = mRigidBodyComponents.getCenterOfMassWorld(body1Entity);
@ -143,17 +110,6 @@ void SolveFixedJointSystem::initBeforeSolve() {
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] == JointsPositionCorrectionTechnique::BAUMGARTE_JOINTS) {
mFixedJointComponents.mBiasTranslation[i] = biasFactor * (x2 + r2World - x1 - r1World);
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Compute the inverse of the mass matrix K=JM^-1J^t for the 3 rotation contraints (3x3 matrix)
mFixedJointComponents.mInverseMassMatrixRotation[i] = mFixedJointComponents.mI1[i] + mFixedJointComponents.mI2[i];
@ -161,36 +117,18 @@ void SolveFixedJointSystem::initBeforeSolve() {
mRigidBodyComponents.getBodyType(body2Entity) == BodyType::DYNAMIC) {
mFixedJointComponents.mInverseMassMatrixRotation[i] = mFixedJointComponents.mInverseMassMatrixRotation[i].getInverse();
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Compute the bias "b" for the 3 rotation constraints
mFixedJointComponents.mBiasRotation[i].setToZero();
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] == JointsPositionCorrectionTechnique::BAUMGARTE_JOINTS) {
const Quaternion qError = orientationBody2 * mFixedJointComponents.mInitOrientationDifferenceInv[i] * orientationBody1.getInverse();
mFixedJointComponents.mBiasRotation[i] = biasFactor * decimal(2.0) * qError.getVectorV();
}
}
// If warm-starting is not enabled
if (!mIsWarmStartingActive) {
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
// Reset the accumulated impulses
mFixedJointComponents.mImpulseTranslation[i].setToZero();
mFixedJointComponents.mImpulseRotation[i].setToZero();
@ -367,47 +305,17 @@ void SolveFixedJointSystem::solvePositionConstraint() {
const Matrix3x3 orientation2 = mTransformComponents.getTransform(body2Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.getInertiaTensorLocalInverse(body2Entity),
mFixedJointComponents.mI2[i]);
}
// For each joint
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Get the bodies positions and orientations
const Quaternion& q1 = mRigidBodyComponents.getConstrainedOrientation(body1Entity);
const Quaternion& q2 = mRigidBodyComponents.getConstrainedOrientation(body2Entity);
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
// Compute the vector from body center to the anchor point in world-space
mFixedJointComponents.mR1World[i] = q1 * mFixedJointComponents.mLocalAnchorPointBody1[i];
mFixedJointComponents.mR2World[i] = q2 * mFixedJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Get the inverse mass and inverse inertia tensors of the bodies
decimal inverseMassBody1 = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
@ -434,33 +342,9 @@ void SolveFixedJointSystem::solvePositionConstraint() {
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mFixedJointComponents.mInverseMassMatrixTranslation[i] = massMatrix.getInverse();
}
}
// For each joint
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mFixedJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Vector3& r1World = mFixedJointComponents.mR1World[i];
const Vector3& r2World = mFixedJointComponents.mR2World[i];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
Vector3& x1 = mRigidBodyComponents.mConstrainedPositions[componentIndexBody1];
Vector3& x2 = mRigidBodyComponents.mConstrainedPositions[componentIndexBody2];
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
// Compute position error for the 3 translation constraints
const Vector3 errorTranslation = x2 + r2World - x1 - r1World;
@ -471,8 +355,6 @@ void SolveFixedJointSystem::solvePositionConstraint() {
Vector3 linearImpulseBody1 = -lambdaTranslation;
Vector3 angularImpulseBody1 = lambdaTranslation.cross(r1World);
const decimal inverseMassBody1 = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
// Compute the pseudo velocity of body 1
const Vector3 v1 = inverseMassBody1 * linearImpulseBody1;
Vector3 w1 = mFixedJointComponents.mI2[i] * angularImpulseBody1;
@ -485,8 +367,6 @@ void SolveFixedJointSystem::solvePositionConstraint() {
// Compute the impulse of body 2
Vector3 angularImpulseBody2 = -lambdaTranslation.cross(r2World);
const decimal inverseMassBody2 = mRigidBodyComponents.mInverseMasses[componentIndexBody2];
// Compute the pseudo velocity of body 2
const Vector3 v2 = inverseMassBody2 * lambdaTranslation;
Vector3 w2 = mFixedJointComponents.mI2[i] * angularImpulseBody2;

View File

@ -47,6 +47,8 @@ SolveHingeJointSystem::SolveHingeJointSystem(PhysicsWorld& world, RigidBodyCompo
// Initialize before solving the constraint
void SolveHingeJointSystem::initBeforeSolve() {
const decimal biasFactor = (BETA / mTimeStep);
// For each joint
const uint32 nbJoints = mHingeJointComponents.getNbEnabledComponents();
for (uint32 i=0; i < nbJoints; i++) {
@ -58,23 +60,15 @@ void SolveHingeJointSystem::initBeforeSolve() {
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
assert(!mRigidBodyComponents.getIsEntityDisabled(body1Entity));
assert(!mRigidBodyComponents.getIsEntityDisabled(body2Entity));
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
assert(!mRigidBodyComponents.mIsEntityDisabled[componentIndexBody1]);
assert(!mRigidBodyComponents.mIsEntityDisabled[componentIndexBody2]);
// Get the inertia tensor of bodies
mHingeJointComponents.mI1[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body1Entity);
mHingeJointComponents.mI2[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body2Entity);
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
mHingeJointComponents.mI1[i] = mRigidBodyComponents.mInverseInertiaTensorsWorld[componentIndexBody1];
mHingeJointComponents.mI2[i] = mRigidBodyComponents.mInverseInertiaTensorsWorld[componentIndexBody2];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
@ -82,22 +76,6 @@ void SolveHingeJointSystem::initBeforeSolve() {
// Compute the vector from body center to the anchor point in world-space
mHingeJointComponents.mR1World[i] = orientationBody1 * mHingeJointComponents.mLocalAnchorPointBody1[i];
mHingeJointComponents.mR2World[i] = orientationBody2 * mHingeJointComponents.mLocalAnchorPointBody2[i];
}
const decimal biasFactor = (BETA / mTimeStep);
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
// Compute vectors needed in the Jacobian
Vector3& a1 = mHingeJointComponents.mA1[i];
@ -116,25 +94,11 @@ void SolveHingeJointSystem::initBeforeSolve() {
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] == JointsPositionCorrectionTechnique::BAUMGARTE_JOINTS) {
mHingeJointComponents.mBiasRotation[i] = biasFactor * Vector2(a1.dot(b2), a1.dot(c2));
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Compute the corresponding skew-symmetric matrices
Matrix3x3 skewSymmetricMatrixU1= Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(mHingeJointComponents.mR1World[i]);
Matrix3x3 skewSymmetricMatrixU2= Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(mHingeJointComponents.mR2World[i]);
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Compute the inverse mass matrix K=JM^-1J^t for the 3 translation constraints (3x3 matrix)
decimal body1MassInverse = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
decimal body2MassInverse = mRigidBodyComponents.mInverseMasses[componentIndexBody2];
@ -150,38 +114,16 @@ void SolveHingeJointSystem::initBeforeSolve() {
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mHingeJointComponents.mInverseMassMatrixTranslation[i] = massMatrix.getInverse();
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Get the bodies positions and orientations
const Vector3& x1 = mRigidBodyComponents.getCenterOfMassWorld(body1Entity);
const Vector3& x2 = mRigidBodyComponents.getCenterOfMassWorld(body2Entity);
const Vector3& x1 = mRigidBodyComponents.mCentersOfMassWorld[componentIndexBody1];
const Vector3& x2 = mRigidBodyComponents.mCentersOfMassWorld[componentIndexBody2];
// Compute the bias "b" of the translation constraints
mHingeJointComponents.mBiasTranslation[i].setToZero();
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] == JointsPositionCorrectionTechnique::BAUMGARTE_JOINTS) {
mHingeJointComponents.mBiasTranslation[i] = biasFactor * (x2 + mHingeJointComponents.mR2World[i] - x1 - mHingeJointComponents.mR1World[i]);
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Matrix3x3& i1 = mHingeJointComponents.mI1[i];
const Matrix3x3& i2 = mHingeJointComponents.mI2[i];
@ -199,18 +141,14 @@ void SolveHingeJointSystem::initBeforeSolve() {
const decimal el22 = c2CrossA1.dot(i1C2CrossA1) + c2CrossA1.dot(i2C2CrossA1);
const Matrix2x2 matrixKRotation(el11, el12, el21, el22);
mHingeJointComponents.mInverseMassMatrixRotation[i].setToZero();
if (mRigidBodyComponents.getBodyType(body1Entity) == BodyType::DYNAMIC ||
mRigidBodyComponents.getBodyType(body2Entity) == BodyType::DYNAMIC) {
if (mRigidBodyComponents.mBodyTypes[componentIndexBody1] == BodyType::DYNAMIC ||
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mHingeJointComponents.mInverseMassMatrixRotation[i] = matrixKRotation.getInverse();
}
}
// If warm-starting is not enabled
if (!mIsWarmStartingActive) {
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
// Reset all the accumulated impulses
mHingeJointComponents.mImpulseTranslation[i].setToZero();
mHingeJointComponents.mImpulseRotation[i].setToZero();
@ -218,20 +156,6 @@ void SolveHingeJointSystem::initBeforeSolve() {
mHingeJointComponents.mImpulseUpperLimit[i] = decimal(0.0);
mHingeJointComponents.mImpulseMotor[i] = decimal(0.0);
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
// Compute the current angle around the hinge axis
decimal hingeAngle = computeCurrentHingeAngle(jointEntity, orientationBody1, orientationBody2);
@ -553,49 +477,24 @@ void SolveHingeJointSystem::solvePositionConstraint() {
Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Recompute the world inverse inertia tensors
const Matrix3x3 orientation1 = mTransformComponents.getTransform(body1Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation1, mRigidBodyComponents.getInertiaTensorLocalInverse(body1Entity),
RigidBody::computeWorldInertiaTensorInverse(orientation1, mRigidBodyComponents.mInverseInertiaTensorsLocal[componentIndexBody1],
mHingeJointComponents.mI1[i]);
const Matrix3x3 orientation2 = mTransformComponents.getTransform(body2Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.getInertiaTensorLocalInverse(body2Entity),
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.mInverseInertiaTensorsLocal[componentIndexBody2],
mHingeJointComponents.mI2[i]);
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& q1 = mRigidBodyComponents.getConstrainedOrientation(body1Entity);
const Quaternion& q2 = mRigidBodyComponents.getConstrainedOrientation(body2Entity);
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
// Compute the vector from body center to the anchor point in world-space
mHingeJointComponents.mR1World[i] = q1 * mHingeJointComponents.mLocalAnchorPointBody1[i];
mHingeJointComponents.mR2World[i] = q2 * mHingeJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
// Compute the corresponding skew-symmetric matrices
Matrix3x3 skewSymmetricMatrixU1 = Matrix3x3::computeSkewSymmetricMatrixForCrossProduct(mHingeJointComponents.mR1World[i]);
@ -603,9 +502,6 @@ void SolveHingeJointSystem::solvePositionConstraint() {
// --------------- Translation Constraints --------------- //
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Compute the matrix K=JM^-1J^t (3x3 matrix) for the 3 translation constraints
const decimal body1InverseMass = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
const decimal body2InverseMass = mRigidBodyComponents.mInverseMasses[componentIndexBody2];
@ -620,26 +516,6 @@ void SolveHingeJointSystem::solvePositionConstraint() {
mRigidBodyComponents.mBodyTypes[componentIndexBody2] == BodyType::DYNAMIC) {
mHingeJointComponents.mInverseMassMatrixTranslation[i] = massMatrix.getInverse();
}
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
Vector3& b2CrossA1 = mHingeJointComponents.mB2CrossA1[i];
Vector3& c2CrossA1 = mHingeJointComponents.mC2CrossA1[i];
@ -744,23 +620,6 @@ void SolveHingeJointSystem::solvePositionConstraint() {
// Update the body position/orientation of body 2
q2 += Quaternion(0, w2) * q2 * decimal(0.5);
q2.normalize();
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mHingeJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) continue;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
Quaternion& q1 = mRigidBodyComponents.getConstrainedOrientation(body1Entity);
Quaternion& q2 = mRigidBodyComponents.getConstrainedOrientation(body2Entity);
// Compute the current angle around the hinge axis
const decimal hingeAngle = computeCurrentHingeAngle(jointEntity, q1, q2);

View File

@ -47,6 +47,8 @@ SolveSliderJointSystem::SolveSliderJointSystem(PhysicsWorld& world, RigidBodyCom
// Initialize before solving the constraint
void SolveSliderJointSystem::initBeforeSolve() {
const decimal biasFactor = (BETA / mTimeStep);
// For each joint
const uint32 nbJoints = mSliderJointComponents.getNbEnabledComponents();
for (uint32 i=0; i < nbJoints; i++) {
@ -58,23 +60,15 @@ void SolveSliderJointSystem::initBeforeSolve() {
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
assert(!mRigidBodyComponents.getIsEntityDisabled(body1Entity));
assert(!mRigidBodyComponents.getIsEntityDisabled(body2Entity));
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
assert(!mRigidBodyComponents.mIsEntityDisabled[componentIndexBody1]);
assert(!mRigidBodyComponents.mIsEntityDisabled[componentIndexBody2]);
// Get the inertia tensor of bodies
mSliderJointComponents.mI1[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body1Entity);
mSliderJointComponents.mI2[i] = mRigidBodyComponents.getInertiaTensorWorldInverse(body2Entity);
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
mSliderJointComponents.mI1[i] = mRigidBodyComponents.mInverseInertiaTensorsWorld[componentIndexBody1];
mSliderJointComponents.mI2[i] = mRigidBodyComponents.mInverseInertiaTensorsWorld[componentIndexBody2];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
@ -82,43 +76,13 @@ void SolveSliderJointSystem::initBeforeSolve() {
// Vector from body center to the anchor point
mSliderJointComponents.mR1[i] = orientationBody1 * mSliderJointComponents.mLocalAnchorPointBody1[i];
mSliderJointComponents.mR2[i] = orientationBody2 * mSliderJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
// Compute the two orthogonal vectors to the slider axis in world-space
mSliderJointComponents.mSliderAxisWorld[i] = orientationBody1 * mSliderJointComponents.mSliderAxisBody1[i];
mSliderJointComponents.mSliderAxisWorld[i].normalize();
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
mSliderJointComponents.mN1[i] = mSliderJointComponents.mSliderAxisWorld[i].getOneUnitOrthogonalVector();
mSliderJointComponents.mN2[i] = mSliderJointComponents.mSliderAxisWorld[i].cross(mSliderJointComponents.mN1[i]);
}
const decimal biasFactor = (BETA / mTimeStep);
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
const Vector3& x1 = mRigidBodyComponents.mCentersOfMassWorld[componentIndexBody1];
const Vector3& x2 = mRigidBodyComponents.mCentersOfMassWorld[componentIndexBody2];
@ -188,26 +152,11 @@ void SolveSliderJointSystem::initBeforeSolve() {
mSliderJointComponents.mBUpperLimit[i] = biasFactor * upperLimitError;
}
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
// Compute the cross products used in the Jacobians
mSliderJointComponents.mR2CrossN1[i] = mSliderJointComponents.mR2[i].cross(mSliderJointComponents.mN1[i]);
mSliderJointComponents.mR2CrossN2[i] = mSliderJointComponents.mR2[i].cross(mSliderJointComponents.mN2[i]);
mSliderJointComponents.mR2CrossSliderAxis[i] = mSliderJointComponents.mR2[i].cross(mSliderJointComponents.mSliderAxisWorld[i]);
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Vector3& r2CrossN1 = mSliderJointComponents.mR2CrossN1[i];
const Vector3& r2CrossN2 = mSliderJointComponents.mR2CrossN2[i];
@ -217,9 +166,6 @@ void SolveSliderJointSystem::initBeforeSolve() {
const Matrix3x3& i1 = mSliderJointComponents.mI1[i];
const Matrix3x3& i2 = mSliderJointComponents.mI2[i];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Compute the inverse of the mass matrix K=JM^-1J^t for the 2 translation
// constraints (2x2 matrix)
const decimal body1MassInverse = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
@ -253,20 +199,6 @@ void SolveSliderJointSystem::initBeforeSolve() {
mSliderJointComponents.mInverseMassMatrixRotation[i] = mSliderJointComponents.mInverseMassMatrixRotation[i].getInverse();
}
}
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& orientationBody1 = mTransformComponents.getTransform(body1Entity).getOrientation();
const Quaternion& orientationBody2 = mTransformComponents.getTransform(body2Entity).getOrientation();
// Compute the bias "b" of the rotation constraint
mSliderJointComponents.mBiasRotation[i].setToZero();
@ -278,8 +210,8 @@ void SolveSliderJointSystem::initBeforeSolve() {
// If the motor is enabled
if (mSliderJointComponents.mIsMotorEnabled[i]) {
const decimal body1MassInverse = mRigidBodyComponents.getMassInverse(body1Entity);
const decimal body2MassInverse = mRigidBodyComponents.getMassInverse(body2Entity);
const decimal body1MassInverse = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
const decimal body2MassInverse = mRigidBodyComponents.mInverseMasses[componentIndexBody2];
const decimal sumInverseMass = body1MassInverse + body2MassInverse;
// Compute the inverse of mass matrix K=JM^-1J^t for the motor (1x1 matrix)
@ -287,14 +219,10 @@ void SolveSliderJointSystem::initBeforeSolve() {
mSliderJointComponents.mInverseMassMatrixMotor[i] = (mSliderJointComponents.mInverseMassMatrixMotor[i] > decimal(0.0)) ?
decimal(1.0) / mSliderJointComponents.mInverseMassMatrixMotor[i] : decimal(0.0);
}
}
// If warm-starting is not enabled
if (!mIsWarmStartingActive) {
// For each joint
for (uint32 i=0; i < nbJoints; i++) {
// Reset all the accumulated impulses
mSliderJointComponents.mImpulseTranslation[i].setToZero();
mSliderJointComponents.mImpulseRotation[i].setToZero();
@ -452,26 +380,9 @@ void SolveSliderJointSystem::solveVelocityConstraint() {
// Apply the impulse to the body 2
v2 += inverseMassBody2 * linearImpulseBody2;
w2 += i2 * angularImpulseBody2;
}
// For each joint component
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// --------------- Rotation Constraints --------------- //
Vector3& w1 = mRigidBodyComponents.mConstrainedAngularVelocities[componentIndexBody1];
Vector3& w2 = mRigidBodyComponents.mConstrainedAngularVelocities[componentIndexBody2];
// Compute J*v for the 3 rotation constraints
const Vector3 JvRotation = w2 - w1;
@ -481,36 +392,16 @@ void SolveSliderJointSystem::solveVelocityConstraint() {
mSliderJointComponents.mImpulseRotation[i] += deltaLambda2;
// Compute the impulse P=J^T * lambda for the 3 rotation constraints of body 1
Vector3 angularImpulseBody1 = -deltaLambda2;
angularImpulseBody1 = -deltaLambda2;
// Apply the impulse to the body to body 1
// Apply the impulse to the body 1
w1 += mSliderJointComponents.mI1[i] * angularImpulseBody1;
// Compute the impulse P=J^T * lambda for the 3 rotation constraints of body 2
Vector3 angularImpulseBody2 = deltaLambda2;
angularImpulseBody2 = deltaLambda2;
// Apply the impulse to the body 2
w2 += mSliderJointComponents.mI2[i] * angularImpulseBody2;
}
// For each joint component
for (uint32 i=0; i < nbJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
Vector3& v1 = mRigidBodyComponents.mConstrainedLinearVelocities[componentIndexBody1];
Vector3& v2 = mRigidBodyComponents.mConstrainedLinearVelocities[componentIndexBody2];
decimal inverseMassBody1 = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
decimal inverseMassBody2 = mRigidBodyComponents.mInverseMasses[componentIndexBody2];
const Vector3& r2CrossSliderAxis = mSliderJointComponents.mR2CrossSliderAxis[i];
const Vector3& r1PlusUCrossSliderAxis = mSliderJointComponents.mR1PlusUCrossSliderAxis[i];
@ -634,54 +525,24 @@ void SolveSliderJointSystem::solvePositionConstraint() {
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Recompute the world inverse inertia tensors
const Matrix3x3 orientation1 = mTransformComponents.getTransform(body1Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation1, mRigidBodyComponents.getInertiaTensorLocalInverse(body1Entity),
RigidBody::computeWorldInertiaTensorInverse(orientation1, mRigidBodyComponents.mInverseInertiaTensorsLocal[componentIndexBody1],
mSliderJointComponents.mI1[i]);
const Matrix3x3 orientation2 = mTransformComponents.getTransform(body2Entity).getOrientation().getMatrix();
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.getInertiaTensorLocalInverse(body2Entity),
RigidBody::computeWorldInertiaTensorInverse(orientation2, mRigidBodyComponents.mInverseInertiaTensorsLocal[componentIndexBody2],
mSliderJointComponents.mI2[i]);
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) return;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const Quaternion& q1 = mRigidBodyComponents.getConstrainedOrientation(body1Entity);
const Quaternion& q2 = mRigidBodyComponents.getConstrainedOrientation(body2Entity);
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
// Vector from body center to the anchor point
mSliderJointComponents.mR1[i] = q1 * mSliderJointComponents.mLocalAnchorPointBody1[i];
mSliderJointComponents.mR2[i] = q2 * mSliderJointComponents.mLocalAnchorPointBody2[i];
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) return;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
// Get the inverse mass and inverse inertia tensors of the bodies
const decimal inverseMassBody1 = mRigidBodyComponents.mInverseMasses[componentIndexBody1];
@ -699,9 +560,6 @@ void SolveSliderJointSystem::solvePositionConstraint() {
// Compute the vector u (difference between anchor points)
const Vector3 u = x2 + r2 - x1 - r1;
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
// Compute the two orthogonal vectors to the slider axis in world-space
mSliderJointComponents.mSliderAxisWorld[i] = q1 * mSliderJointComponents.mSliderAxisBody1[i];
mSliderJointComponents.mSliderAxisWorld[i].normalize();
@ -790,31 +648,6 @@ void SolveSliderJointSystem::solvePositionConstraint() {
x2 += v2;
q2 += Quaternion(0, w2) * q2 * decimal(0.5);
q2.normalize();
}
// For each joint component
for (uint32 i=0; i < nbEnabledJoints; i++) {
const Entity jointEntity = mSliderJointComponents.mJointEntities[i];
const uint32 jointIndex = mJointComponents.getEntityIndex(jointEntity);
// If the error position correction technique is not the non-linear-gauss-seidel, we do
// do not execute this method
if (mJointComponents.mPositionCorrectionTechniques[jointIndex] != JointsPositionCorrectionTechnique::NON_LINEAR_GAUSS_SEIDEL) return;
// Get the bodies entities
const Entity body1Entity = mJointComponents.mBody1Entities[jointIndex];
const Entity body2Entity = mJointComponents.mBody2Entities[jointIndex];
const uint32 componentIndexBody1 = mRigidBodyComponents.getEntityIndex(body1Entity);
const uint32 componentIndexBody2 = mRigidBodyComponents.getEntityIndex(body2Entity);
Quaternion& q1 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody1];
Quaternion& q2 = mRigidBodyComponents.mConstrainedOrientations[componentIndexBody2];
// Get the velocities
Vector3& w1 = mRigidBodyComponents.mConstrainedAngularVelocities[componentIndexBody1];
Vector3& w2 = mRigidBodyComponents.mConstrainedAngularVelocities[componentIndexBody2];
// --------------- Rotation Constraints --------------- //
@ -858,7 +691,7 @@ void SolveSliderJointSystem::solvePositionConstraint() {
Vector3 lambdaRotation = mSliderJointComponents.mInverseMassMatrixRotation[i] * (-errorRotation);
// Compute the impulse P=J^T * lambda for the 3 rotation constraints of body 1
Vector3 angularImpulseBody1 = -lambdaRotation;
angularImpulseBody1 = -lambdaRotation;
// Apply the impulse to the body 1
w1 = mSliderJointComponents.mI1[i] * angularImpulseBody1;
@ -868,7 +701,7 @@ void SolveSliderJointSystem::solvePositionConstraint() {
q1.normalize();
// Compute the impulse P=J^T * lambda for the 3 rotation constraints of body 2
Vector3 angularImpulseBody2 = lambdaRotation;
angularImpulseBody2 = lambdaRotation;
// Apply the impulse to the body 2
w2 = mSliderJointComponents.mI2[i] * angularImpulseBody2;