From b4f13308de720524e91f07a03c82744d59b6eba5 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Tue, 13 Sep 2016 22:58:17 +0200 Subject: [PATCH] Optimize warmstarting in contact solver --- src/engine/ContactSolver.cpp | 141 +++++++++++++++++++++++++++++++++-- src/engine/ContactSolver.h | 24 ++++++ src/engine/DynamicsWorld.cpp | 4 +- src/engine/Island.h | 4 +- 4 files changed, 164 insertions(+), 9 deletions(-) diff --git a/src/engine/ContactSolver.cpp b/src/engine/ContactSolver.cpp index 22359b10..4e2e0eec 100644 --- a/src/engine/ContactSolver.cpp +++ b/src/engine/ContactSolver.cpp @@ -38,15 +38,13 @@ const decimal ContactSolver::BETA = decimal(0.2); const decimal ContactSolver::BETA_SPLIT_IMPULSE = decimal(0.2); const decimal ContactSolver::SLOP= decimal(0.01); -// TODO : Enable warmstarting again - // Constructor ContactSolver::ContactSolver(const std::map& mapBodyToVelocityIndex) :mSplitLinearVelocities(nullptr), mSplitAngularVelocities(nullptr), mContactConstraints(nullptr), mPenetrationConstraints(nullptr), mFrictionConstraints(nullptr), mLinearVelocities(nullptr), mAngularVelocities(nullptr), mMapBodyToConstrainedVelocityIndex(mapBodyToVelocityIndex), - mIsWarmStartingActive(false), mIsSplitImpulseActive(true), + mIsWarmStartingActive(true), mIsSplitImpulseActive(true), mIsSolveFrictionAtContactManifoldCenterActive(true) { } @@ -83,7 +81,7 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) { assert(mFrictionConstraints != nullptr); // For each contact manifold of the island - ContactManifold** contactManifolds = island->getContactManifold(); + ContactManifold** contactManifolds = island->getContactManifolds(); for (uint i=0; imCenterOfMassWorld; @@ -131,6 +130,7 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) { mFrictionConstraints[mNbFrictionConstraints].frictionCoefficient = computeMixedFrictionCoefficient(body1, body2); mFrictionConstraints[mNbFrictionConstraints].rollingResistanceFactor = computeMixedRollingResistance(body1, body2); internalManifold.externalContactManifold = externalManifold; + mFrictionConstraints[mNbFrictionConstraints].hasAtLeastOneRestingContactPoint = false; //internalManifold.isBody1DynamicType = body1->getType() == BodyType::DYNAMIC; //internalManifold.isBody2DynamicType = body2->getType() == BodyType::DYNAMIC; @@ -167,6 +167,7 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) { mPenetrationConstraints[mNbPenetrationConstraints].massInverseBody2 = body2->mMassInverse; mPenetrationConstraints[mNbPenetrationConstraints].restitutionFactor = restitutionFactor; mPenetrationConstraints[mNbPenetrationConstraints].indexFrictionConstraint = mNbFrictionConstraints; + mPenetrationConstraints[mNbPenetrationConstraints].contactPoint = externalContact; // Get the contact point on the two bodies Vector3 p1 = externalContact->getWorldPointOnBody1(); @@ -178,7 +179,10 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) { //mPenetrationConstraints[penConstIndex].externalContact = externalContact; mPenetrationConstraints[mNbPenetrationConstraints].normal = externalContact->getNormal(); mPenetrationConstraints[mNbPenetrationConstraints].penetrationDepth = externalContact->getPenetrationDepth(); - //mPenetrationConstraints[penConstIndex].isRestingContact = externalContact->getIsRestingContact(); + mPenetrationConstraints[mNbPenetrationConstraints].isRestingContact = externalContact->getIsRestingContact(); + + mFrictionConstraints[mNbFrictionConstraints].hasAtLeastOneRestingContactPoint |= mPenetrationConstraints[mNbPenetrationConstraints].isRestingContact; + externalContact->setIsRestingContact(true); //mPenetrationConstraints[penConstIndex].oldFrictionVector1 = externalContact->getFrictionVector1(); //mPenetrationConstraints[penConstIndex].oldFrictionVector2 = externalContact->getFrictionVector2(); @@ -467,9 +471,116 @@ void ContactSolver::initializeContactConstraints() { /// the solution of the linear system void ContactSolver::warmStart() { - /* PROFILE("ContactSolver::warmStart()"); + // Penetration constraints + for (uint i=0; isetPenetrationImpulse(mPenetrationConstraints[i].penetrationImpulse); + + } + + // Friction constraints + for (uint i=0; isetFrictionImpulse1(mFrictionConstraints[i].friction1Impulse); + mFrictionConstraints[i].contactManifold->setFrictionImpulse2(mFrictionConstraints[i].friction2Impulse); + mFrictionConstraints[i].contactManifold->setFrictionTwistImpulse(mFrictionConstraints[i].frictionTwistImpulse); + mFrictionConstraints[i].contactManifold->setRollingResistanceImpulse(mFrictionConstraints[i].rollingResistanceImpulse); + mFrictionConstraints[i].contactManifold->setFrictionVector1(mFrictionConstraints[i].frictionVector1); + mFrictionConstraints[i].contactManifold->setFrictionVector2(mFrictionConstraints[i].frictionVector2); + } + /* // For each contact manifold for (uint c=0; c