Warm start the solver. For each constraint, we apply the previous impulse (from the previous step) at the beginning. With this technique, we will converge faster towards the solution of the linear system
| 324 | /// at the beginning. With this technique, we will converge faster towards |
| 325 | /// the solution of the linear system |
| 326 | void ContactSolverSystem::warmStart() { |
| 327 | |
| 328 | RP3D_PROFILE("ContactSolver::warmStart()", mProfiler); |
| 329 | |
| 330 | uint32 contactPointIndex = 0; |
| 331 | |
| 332 | // For each constraint |
| 333 | for (uint32 c=0; c<mNbContactManifolds; c++) { |
| 334 | |
| 335 | bool atLeastOneRestingContactPoint = false; |
| 336 | |
| 337 | for (short int i=0; i<mContactConstraints[c].nbContacts; i++) { |
| 338 | |
| 339 | // If it is not a new contact (this contact was already existing at last time step) |
| 340 | if (mContactPoints[contactPointIndex].isRestingContact) { |
| 341 | |
| 342 | const uint32 rigidBody1Index = mContactConstraints[c].rigidBodyComponentIndexBody1; |
| 343 | const uint32 rigidBody2Index = mContactConstraints[c].rigidBodyComponentIndexBody2; |
| 344 | |
| 345 | atLeastOneRestingContactPoint = true; |
| 346 | |
| 347 | // --------- Penetration --------- // |
| 348 | |
| 349 | // Update the velocities of the body 1 by applying the impulse P |
| 350 | Vector3 impulsePenetration(mContactPoints[contactPointIndex].normal.x * mContactPoints[contactPointIndex].penetrationImpulse, |
| 351 | mContactPoints[contactPointIndex].normal.y * mContactPoints[contactPointIndex].penetrationImpulse, |
| 352 | mContactPoints[contactPointIndex].normal.z * mContactPoints[contactPointIndex].penetrationImpulse); |
| 353 | mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].x -= mContactConstraints[c].massInverseBody1 * impulsePenetration.x * mContactConstraints[c].linearLockAxisFactorBody1.x; |
| 354 | mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].y -= mContactConstraints[c].massInverseBody1 * impulsePenetration.y * mContactConstraints[c].linearLockAxisFactorBody1.y; |
| 355 | mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody1Index].z -= mContactConstraints[c].massInverseBody1 * impulsePenetration.z * mContactConstraints[c].linearLockAxisFactorBody1.z; |
| 356 | |
| 357 | mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].x -= mContactPoints[contactPointIndex].i1TimesR1CrossN.x * mContactConstraints[c].angularLockAxisFactorBody1.x * mContactPoints[contactPointIndex].penetrationImpulse; |
| 358 | mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].y -= mContactPoints[contactPointIndex].i1TimesR1CrossN.y * mContactConstraints[c].angularLockAxisFactorBody1.y * mContactPoints[contactPointIndex].penetrationImpulse; |
| 359 | mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody1Index].z -= mContactPoints[contactPointIndex].i1TimesR1CrossN.z * mContactConstraints[c].angularLockAxisFactorBody1.z * mContactPoints[contactPointIndex].penetrationImpulse; |
| 360 | |
| 361 | // Update the velocities of the body 2 by applying the impulse P |
| 362 | mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].x += mContactConstraints[c].massInverseBody2 * impulsePenetration.x * mContactConstraints[c].linearLockAxisFactorBody2.x; |
| 363 | mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].y += mContactConstraints[c].massInverseBody2 * impulsePenetration.y * mContactConstraints[c].linearLockAxisFactorBody2.y; |
| 364 | mRigidBodyComponents.mConstrainedLinearVelocities[rigidBody2Index].z += mContactConstraints[c].massInverseBody2 * impulsePenetration.z * mContactConstraints[c].linearLockAxisFactorBody2.z; |
| 365 | |
| 366 | mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].x += mContactPoints[contactPointIndex].i2TimesR2CrossN.x * mContactConstraints[c].angularLockAxisFactorBody2.x * mContactPoints[contactPointIndex].penetrationImpulse; |
| 367 | mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].y += mContactPoints[contactPointIndex].i2TimesR2CrossN.y * mContactConstraints[c].angularLockAxisFactorBody2.y * mContactPoints[contactPointIndex].penetrationImpulse; |
| 368 | mRigidBodyComponents.mConstrainedAngularVelocities[rigidBody2Index].z += mContactPoints[contactPointIndex].i2TimesR2CrossN.z * mContactConstraints[c].angularLockAxisFactorBody2.z * mContactPoints[contactPointIndex].penetrationImpulse; |
| 369 | } |
| 370 | else { // If it is a new contact point |
| 371 | |
| 372 | // Initialize the accumulated impulses to zero |
| 373 | mContactPoints[contactPointIndex].penetrationImpulse = 0.0; |
| 374 | } |
| 375 | |
| 376 | contactPointIndex++; |
| 377 | } |
| 378 | |
| 379 | // If we solve the friction constraints at the center of the contact manifold and there is |
| 380 | // at least one resting contact point in the contact manifold |
| 381 | if (atLeastOneRestingContactPoint) { |
| 382 | |
| 383 | // Project the old friction impulses (with old friction vectors) into the new friction |