|
|
|
@ -90,7 +90,8 @@ void ContactSolverSystem::init(List<ContactManifold>* contactManifolds, List<Con
|
|
|
|
|
assert(mContactConstraints != nullptr);
|
|
|
|
|
|
|
|
|
|
// For each island of the world
|
|
|
|
|
for (uint i = 0; i < mIslands.getNbIslands(); i++) {
|
|
|
|
|
const uint nbIslands = mIslands.getNbIslands();
|
|
|
|
|
for (uint i = 0; i < nbIslands; i++) {
|
|
|
|
|
|
|
|
|
|
if (mIslands.nbContactManifolds[i] > 0) {
|
|
|
|
|
initializeForIsland(i);
|
|
|
|
@ -117,25 +118,24 @@ void ContactSolverSystem::initializeForIsland(uint islandIndex) {
|
|
|
|
|
assert(mIslands.nbContactManifolds[islandIndex] > 0);
|
|
|
|
|
|
|
|
|
|
// For each contact manifold of the island
|
|
|
|
|
uint contactManifoldsIndex = mIslands.contactManifoldsIndices[islandIndex];
|
|
|
|
|
uint nbContactManifolds = mIslands.nbContactManifolds[islandIndex];
|
|
|
|
|
const uint contactManifoldsIndex = mIslands.contactManifoldsIndices[islandIndex];
|
|
|
|
|
const uint nbContactManifolds = mIslands.nbContactManifolds[islandIndex];
|
|
|
|
|
for (uint m=contactManifoldsIndex; m < contactManifoldsIndex + nbContactManifolds; m++) {
|
|
|
|
|
|
|
|
|
|
ContactManifold& externalManifold = (*mAllContactManifolds)[m];
|
|
|
|
|
|
|
|
|
|
assert(externalManifold.nbContactPoints > 0);
|
|
|
|
|
|
|
|
|
|
const uint rigidBodyIndex1 = mRigidBodyComponents.getEntityIndex(externalManifold.bodyEntity1);
|
|
|
|
|
const uint rigidBodyIndex2 = mRigidBodyComponents.getEntityIndex(externalManifold.bodyEntity2);
|
|
|
|
|
const uint rigidBodyIndex1 = externalManifold.rigidBody1Index;
|
|
|
|
|
const uint rigidBodyIndex2 = externalManifold.rigidBody2Index;
|
|
|
|
|
|
|
|
|
|
// Get the two bodies of the contact
|
|
|
|
|
RigidBody* body1 = mRigidBodyComponents.mRigidBodies[rigidBodyIndex1];
|
|
|
|
|
RigidBody* body2 = mRigidBodyComponents.mRigidBodies[rigidBodyIndex2];
|
|
|
|
|
assert(body1 != nullptr);
|
|
|
|
|
assert(body2 != nullptr);
|
|
|
|
|
assert(!mBodyComponents.getIsEntityDisabled(externalManifold.bodyEntity1));
|
|
|
|
|
assert(!mBodyComponents.getIsEntityDisabled(externalManifold.bodyEntity2));
|
|
|
|
|
|
|
|
|
|
// TODO OPTI : Do not use pointers to colliders here, maybe we call totally remove those pointers
|
|
|
|
|
Collider* collider1 = mColliderComponents.getCollider(externalManifold.colliderEntity1);
|
|
|
|
|
Collider* collider2 = mColliderComponents.getCollider(externalManifold.colliderEntity2);
|
|
|
|
|
|
|
|
|
@ -152,7 +152,9 @@ void ContactSolverSystem::initializeForIsland(uint islandIndex) {
|
|
|
|
|
mContactConstraints[mNbContactManifolds].massInverseBody1 = mRigidBodyComponents.mInverseMasses[rigidBodyIndex1];
|
|
|
|
|
mContactConstraints[mNbContactManifolds].massInverseBody2 = mRigidBodyComponents.mInverseMasses[rigidBodyIndex2];
|
|
|
|
|
mContactConstraints[mNbContactManifolds].nbContacts = externalManifold.nbContactPoints;
|
|
|
|
|
// TODO OPTI : Do not compute this using colliders pointers
|
|
|
|
|
mContactConstraints[mNbContactManifolds].frictionCoefficient = computeMixedFrictionCoefficient(collider1, collider2);
|
|
|
|
|
// TODO OPTI : Do not compute this using colliders pointers
|
|
|
|
|
mContactConstraints[mNbContactManifolds].rollingResistanceFactor = computeMixedRollingResistance(collider1, collider2);
|
|
|
|
|
mContactConstraints[mNbContactManifolds].externalContactManifold = &externalManifold;
|
|
|
|
|
mContactConstraints[mNbContactManifolds].normal.setToZero();
|
|
|
|
@ -165,17 +167,21 @@ void ContactSolverSystem::initializeForIsland(uint islandIndex) {
|
|
|
|
|
const Vector3& v2 = mRigidBodyComponents.mLinearVelocities[rigidBodyIndex2];
|
|
|
|
|
const Vector3& w2 = mRigidBodyComponents.mAngularVelocities[rigidBodyIndex2];
|
|
|
|
|
|
|
|
|
|
// TODO OPTI : Maybe use collider index here
|
|
|
|
|
const Transform& collider1LocalToWorldTransform = mColliderComponents.getLocalToWorldTransform(externalManifold.colliderEntity1);
|
|
|
|
|
const Transform& collider2LocalToWorldTransform = mColliderComponents.getLocalToWorldTransform(externalManifold.colliderEntity2);
|
|
|
|
|
|
|
|
|
|
// For each contact point of the contact manifold
|
|
|
|
|
assert(externalManifold.nbContactPoints > 0);
|
|
|
|
|
uint contactPointsStartIndex = externalManifold.contactPointsIndex;
|
|
|
|
|
uint nbContactPoints = static_cast<uint>(externalManifold.nbContactPoints);
|
|
|
|
|
const uint contactPointsStartIndex = externalManifold.contactPointsIndex;
|
|
|
|
|
const uint nbContactPoints = static_cast<uint>(externalManifold.nbContactPoints);
|
|
|
|
|
for (uint c=contactPointsStartIndex; c < contactPointsStartIndex + nbContactPoints; c++) {
|
|
|
|
|
|
|
|
|
|
ContactPoint& externalContact = (*mAllContactPoints)[c];
|
|
|
|
|
|
|
|
|
|
// Get the contact point on the two bodies
|
|
|
|
|
Vector3 p1 = mColliderComponents.getLocalToWorldTransform(externalManifold.colliderEntity1) * externalContact.getLocalPointOnShape1();
|
|
|
|
|
Vector3 p2 = mColliderComponents.getLocalToWorldTransform(externalManifold.colliderEntity2) * externalContact.getLocalPointOnShape2();
|
|
|
|
|
const Vector3 p1 = collider1LocalToWorldTransform * externalContact.getLocalPointOnShape1();
|
|
|
|
|
const Vector3 p2 = collider2LocalToWorldTransform * externalContact.getLocalPointOnShape2();
|
|
|
|
|
|
|
|
|
|
new (mContactPoints + mNbContactPoints) ContactPointSolver();
|
|
|
|
|
mContactPoints[mNbContactPoints].externalContact = &externalContact;
|
|
|
|
@ -270,20 +276,20 @@ void ContactSolverSystem::initializeForIsland(uint islandIndex) {
|
|
|
|
|
mContactConstraints[mNbContactManifolds].frictionTwistImpulse = externalManifold.frictionTwistImpulse;
|
|
|
|
|
|
|
|
|
|
// Compute the inverse K matrix for the rolling resistance constraint
|
|
|
|
|
bool isBody1DynamicType = body1->getType() == BodyType::DYNAMIC;
|
|
|
|
|
bool isBody2DynamicType = body2->getType() == BodyType::DYNAMIC;
|
|
|
|
|
const bool isBody1DynamicType = mRigidBodyComponents.mBodyTypes[rigidBodyIndex1] == BodyType::DYNAMIC;
|
|
|
|
|
const bool isBody2DynamicType = mRigidBodyComponents.mBodyTypes[rigidBodyIndex2] == BodyType::DYNAMIC;
|
|
|
|
|
mContactConstraints[mNbContactManifolds].inverseRollingResistance.setToZero();
|
|
|
|
|
if (mContactConstraints[mNbContactManifolds].rollingResistanceFactor > 0 && (isBody1DynamicType || isBody2DynamicType)) {
|
|
|
|
|
|
|
|
|
|
mContactConstraints[mNbContactManifolds].inverseRollingResistance = mContactConstraints[mNbContactManifolds].inverseInertiaTensorBody1 + mContactConstraints[mNbContactManifolds].inverseInertiaTensorBody2;
|
|
|
|
|
decimal det = mContactConstraints[mNbContactManifolds].inverseRollingResistance.getDeterminant();
|
|
|
|
|
const decimal det = mContactConstraints[mNbContactManifolds].inverseRollingResistance.getDeterminant();
|
|
|
|
|
|
|
|
|
|
// If the matrix is not inversible
|
|
|
|
|
if (approxEqual(det, decimal(0.0))) {
|
|
|
|
|
mContactConstraints[mNbContactManifolds].inverseRollingResistance.setToZero();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mContactConstraints[mNbContactManifolds].inverseRollingResistance = mContactConstraints[mNbContactManifolds].inverseRollingResistance.getInverse();
|
|
|
|
|
mContactConstraints[mNbContactManifolds].inverseRollingResistance = mContactConstraints[mNbContactManifolds].inverseRollingResistance.getInverseWithDeterminant(det);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -352,10 +358,12 @@ void ContactSolverSystem::warmStart() {
|
|
|
|
|
|
|
|
|
|
for (short int i=0; i<mContactConstraints[c].nbContacts; i++) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If it is not a new contact (this contact was already existing at last time step)
|
|
|
|
|
if (mContactPoints[contactPointIndex].isRestingContact) {
|
|
|
|
|
|
|
|
|
|
const uint32 rigidBody1Index = mContactConstraints[c].rigidBodyComponentIndexBody1;
|
|
|
|
|
const uint32 rigidBody2Index = mContactConstraints[c].rigidBodyComponentIndexBody2;
|
|
|
|
|
|
|
|
|
|
atLeastOneRestingContactPoint = true;
|
|
|
|
|
|
|
|
|
|
// --------- Penetration --------- //
|
|
|
|
@ -364,22 +372,22 @@ void ContactSolverSystem::warmStart() {
|
|
|
|
|
Vector3 impulsePenetration(mContactPoints[contactPointIndex].normal.x * mContactPoints[contactPointIndex].penetrationImpulse,
|
|
|
|
|
mContactPoints[contactPointIndex].normal.y * mContactPoints[contactPointIndex].penetrationImpulse,
|
|
|
|
|
mContactPoints[contactPointIndex].normal.z * mContactPoints[contactPointIndex].penetrationImpulse);
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactConstraints[c].massInverseBody1 * impulsePenetration.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactConstraints[c].massInverseBody1 * impulsePenetration.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactConstraints[c].massInverseBody1 * impulsePenetration.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * impulsePenetration.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * impulsePenetration.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * impulsePenetration.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactConstraints[c].massInverseBody2 * impulsePenetration.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactConstraints[c].massInverseBody2 * impulsePenetration.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactConstraints[c].massInverseBody2 * impulsePenetration.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * impulsePenetration.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * impulsePenetration.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * impulsePenetration.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
}
|
|
|
|
|
else { // If it is a new contact point
|
|
|
|
|
|
|
|
|
@ -418,13 +426,16 @@ void ContactSolverSystem::warmStart() {
|
|
|
|
|
mContactConstraints[c].r2CrossT1.y * mContactConstraints[c].friction1Impulse,
|
|
|
|
|
mContactConstraints[c].r2CrossT1.z * mContactConstraints[c].friction1Impulse);
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1] -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1] += mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
const uint32 rigidBody1Index = mContactConstraints[c].rigidBodyComponentIndexBody1;
|
|
|
|
|
const uint32 rigidBody2Index = mContactConstraints[c].rigidBodyComponentIndexBody2;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2] += mContactConstraints[c].massInverseBody2 * linearImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index] -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index] += mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index] += mContactConstraints[c].massInverseBody2 * linearImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
|
|
|
|
|
// ------ Second friction constraint at the center of the contact manifold ----- //
|
|
|
|
|
|
|
|
|
@ -440,18 +451,18 @@ void ContactSolverSystem::warmStart() {
|
|
|
|
|
angularImpulseBody2.z = mContactConstraints[c].r2CrossT2.z * mContactConstraints[c].friction2Impulse;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1] += mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index] += mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
|
|
|
|
|
// ------ Twist friction constraint at the center of the contact manifold ------ //
|
|
|
|
|
|
|
|
|
@ -465,10 +476,10 @@ void ContactSolverSystem::warmStart() {
|
|
|
|
|
angularImpulseBody2.z = mContactConstraints[c].normal.z * mContactConstraints[c].frictionTwistImpulse;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1] += mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index] += mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
|
|
|
|
|
// ------ Rolling resistance at the center of the contact manifold ------ //
|
|
|
|
|
|
|
|
|
@ -476,10 +487,10 @@ void ContactSolverSystem::warmStart() {
|
|
|
|
|
angularImpulseBody2 = mContactConstraints[c].rollingResistanceImpulse;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1] -= mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index] -= mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody2;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
}
|
|
|
|
|
else { // If it is a new contact manifold
|
|
|
|
|
|
|
|
|
@ -508,11 +519,14 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
|
|
|
|
|
decimal sumPenetrationImpulse = 0.0;
|
|
|
|
|
|
|
|
|
|
const uint32 rigidBody1Index = mContactConstraints[c].rigidBodyComponentIndexBody1;
|
|
|
|
|
const uint32 rigidBody2Index = mContactConstraints[c].rigidBodyComponentIndexBody2;
|
|
|
|
|
|
|
|
|
|
// Get the constrained velocities
|
|
|
|
|
const Vector3& v1 = mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1];
|
|
|
|
|
const Vector3& w1 = mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1];
|
|
|
|
|
const Vector3& v2 = mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2];
|
|
|
|
|
const Vector3& w2 = mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2];
|
|
|
|
|
const Vector3& v1 = mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index];
|
|
|
|
|
const Vector3& w1 = mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index];
|
|
|
|
|
const Vector3& v2 = mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index];
|
|
|
|
|
const Vector3& w2 = mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index];
|
|
|
|
|
|
|
|
|
|
for (short int i=0; i<mContactConstraints[c].nbContacts; i++) {
|
|
|
|
|
|
|
|
|
@ -554,22 +568,22 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
mContactPoints[contactPointIndex].normal.z * deltaLambda);
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactConstraints[c].massInverseBody1 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactConstraints[c].massInverseBody1 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactConstraints[c].massInverseBody1 * linearImpulse.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * linearImpulse.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * deltaLambda;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactConstraints[c].massInverseBody2 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactConstraints[c].massInverseBody2 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactConstraints[c].massInverseBody2 * linearImpulse.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * linearImpulse.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * deltaLambda;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * deltaLambda;
|
|
|
|
|
|
|
|
|
|
sumPenetrationImpulse += mContactPoints[contactPointIndex].penetrationImpulse;
|
|
|
|
|
|
|
|
|
@ -577,10 +591,10 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
if (mIsSplitImpulseActive) {
|
|
|
|
|
|
|
|
|
|
// Split impulse (position correction)
|
|
|
|
|
const Vector3& v1Split = mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1];
|
|
|
|
|
const Vector3& w1Split = mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1];
|
|
|
|
|
const Vector3& v2Split = mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2];
|
|
|
|
|
const Vector3& w2Split = mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2];
|
|
|
|
|
const Vector3& v1Split = mRigidBodyComponents.mSplitLinearVelocities[rigidBody1Index];
|
|
|
|
|
const Vector3& w1Split = mRigidBodyComponents.mSplitAngularVelocities[rigidBody1Index];
|
|
|
|
|
const Vector3& v2Split = mRigidBodyComponents.mSplitLinearVelocities[rigidBody2Index];
|
|
|
|
|
const Vector3& w2Split = mRigidBodyComponents.mSplitAngularVelocities[rigidBody2Index];
|
|
|
|
|
|
|
|
|
|
//Vector3 deltaVSplit = v2Split + w2Split.cross(mContactPoints[contactPointIndex].r2) - v1Split - w1Split.cross(mContactPoints[contactPointIndex].r1);
|
|
|
|
|
Vector3 deltaVSplit(v2Split.x + w2Split.y * mContactPoints[contactPointIndex].r2.z - w2Split.z * mContactPoints[contactPointIndex].r2.y - v1Split.x -
|
|
|
|
@ -605,22 +619,22 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
mContactPoints[contactPointIndex].normal.z * deltaLambdaSplit);
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactConstraints[c].massInverseBody1 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactConstraints[c].massInverseBody1 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactConstraints[c].massInverseBody1 * linearImpulse.z;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * linearImpulse.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[rigidBody1Index].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[rigidBody1Index].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[rigidBody1Index].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * deltaLambdaSplit;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactConstraints[c].massInverseBody2 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactConstraints[c].massInverseBody2 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactConstraints[c].massInverseBody2 * linearImpulse.z;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * linearImpulse.x;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * linearImpulse.y;
|
|
|
|
|
mRigidBodyComponents.mSplitLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * linearImpulse.z;
|
|
|
|
|
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[rigidBody2Index].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[rigidBody2Index].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * deltaLambdaSplit;
|
|
|
|
|
mRigidBodyComponents.mSplitAngularVelocities[rigidBody2Index].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * deltaLambdaSplit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contactPointIndex++;
|
|
|
|
@ -664,24 +678,24 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.z;
|
|
|
|
|
|
|
|
|
|
Vector3 angularVelocity1 = mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x += angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y += angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z += angularVelocity1.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x += angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y += angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z += angularVelocity1.z;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.z;
|
|
|
|
|
|
|
|
|
|
Vector3 angularVelocity2 = mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += angularVelocity2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += angularVelocity2.z;
|
|
|
|
|
|
|
|
|
|
// ------ Second friction constraint at the center of the contact manifold ----- //
|
|
|
|
|
|
|
|
|
@ -719,24 +733,24 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
angularImpulseBody2.z = mContactConstraints[c].r2CrossT2.z * deltaLambda;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.z;
|
|
|
|
|
|
|
|
|
|
angularVelocity1 = mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody1;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x += angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y += angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z += angularVelocity1.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x += angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y += angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z += angularVelocity1.z;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * linearImpulseBody2.z;
|
|
|
|
|
|
|
|
|
|
angularVelocity2 = mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += angularVelocity2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += angularVelocity2.z;
|
|
|
|
|
|
|
|
|
|
// ------ Twist friction constraint at the center of the contact manifol ------ //
|
|
|
|
|
|
|
|
|
@ -760,15 +774,15 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
angularVelocity1 = mContactConstraints[c].inverseInertiaTensorBody1 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= angularVelocity1.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x -= angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y -= angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z -= angularVelocity1.z;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
angularVelocity2 = mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += angularVelocity2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += angularVelocity2.z;
|
|
|
|
|
|
|
|
|
|
// --------- Rolling resistance constraint at the center of the contact manifold --------- //
|
|
|
|
|
|
|
|
|
@ -787,15 +801,15 @@ void ContactSolverSystem::solve() {
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 1 by applying the impulse P
|
|
|
|
|
angularVelocity1 = mContactConstraints[c].inverseInertiaTensorBody1 * deltaLambdaRolling;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].x -= angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].y -= angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody1].z -= angularVelocity1.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x -= angularVelocity1.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y -= angularVelocity1.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z -= angularVelocity1.z;
|
|
|
|
|
|
|
|
|
|
// Update the velocities of the body 2 by applying the impulse P
|
|
|
|
|
angularVelocity2 = mContactConstraints[c].inverseInertiaTensorBody2 * deltaLambdaRolling;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[mContactConstraints[c].rigidBodyComponentIndexBody2].z += angularVelocity2.z;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += angularVelocity2.x;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += angularVelocity2.y;
|
|
|
|
|
mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += angularVelocity2.z;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -813,12 +827,11 @@ decimal ContactSolverSystem::computeMixedRestitutionFactor(Collider* collider1,
|
|
|
|
|
decimal ContactSolverSystem::computeMixedFrictionCoefficient(Collider* collider1, Collider* collider2) const {
|
|
|
|
|
|
|
|
|
|
// Use the geometric mean to compute the mixed friction coefficient
|
|
|
|
|
return std::sqrt(collider1->getMaterial().getFrictionCoefficient() *
|
|
|
|
|
collider2->getMaterial().getFrictionCoefficient());
|
|
|
|
|
return collider1->getMaterial().getFrictionCoefficientSqrt() * collider2->getMaterial().getFrictionCoefficientSqrt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compute th mixed rolling resistance factor between two colliders
|
|
|
|
|
RP3D_FORCE_INLINE decimal ContactSolverSystem::computeMixedRollingResistance(Collider* collider1, Collider* collider2) const {
|
|
|
|
|
decimal ContactSolverSystem::computeMixedRollingResistance(Collider* collider1, Collider* collider2) const {
|
|
|
|
|
return decimal(0.5f) * (collider1->getMaterial().getRollingResistance() + collider2->getMaterial().getRollingResistance());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -851,8 +864,7 @@ void ContactSolverSystem::storeImpulses() {
|
|
|
|
|
|
|
|
|
|
// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction plane
|
|
|
|
|
// for a contact manifold. The two vectors have to be such that : t1 x t2 = contactNormal.
|
|
|
|
|
void ContactSolverSystem::computeFrictionVectors(const Vector3& deltaVelocity,
|
|
|
|
|
ContactManifoldSolver& contact) const {
|
|
|
|
|
void ContactSolverSystem::computeFrictionVectors(const Vector3& deltaVelocity, ContactManifoldSolver& contact) const {
|
|
|
|
|
|
|
|
|
|
RP3D_PROFILE("ContactSolver::computeFrictionVectors()", mProfiler);
|
|
|
|
|
|
|
|
|
|