diff --git a/src/engine/ConstraintSolver.cpp b/src/engine/ConstraintSolver.cpp index 87e0f3e4..5190d1f4 100644 --- a/src/engine/ConstraintSolver.cpp +++ b/src/engine/ConstraintSolver.cpp @@ -34,7 +34,8 @@ using namespace std; // Constructor ConstraintSolver::ConstraintSolver(DynamicsWorld* world) - :world(world), nbConstraints(0), mNbIterations(10), mContactConstraints(0), Vconstraint(0), Wconstraint(0), V1(0), W1(0) { + :world(world), nbConstraints(0), mNbIterations(10), mContactConstraints(0), + mLinearVelocities(0), mAngularVelocities(0) { } @@ -45,7 +46,7 @@ ConstraintSolver::~ConstraintSolver() { // Initialize the constraint solver before each solving void ConstraintSolver::initialize() { - + nbConstraints = 0; // TOOD : Use better allocation here @@ -111,10 +112,8 @@ void ConstraintSolver::initialize() { // Compute the number of bodies that are part of some active constraint nbBodies = mConstraintBodies.size(); - Vconstraint = new Vector3[nbBodies]; - Wconstraint = new Vector3[nbBodies]; - V1 = new Vector3[nbBodies]; - W1 = new Vector3[nbBodies]; + mLinearVelocities = new Vector3[nbBodies]; + mAngularVelocities = new Vector3[nbBodies]; assert(mMapBodyToIndex.size() == nbBodies); } @@ -135,12 +134,9 @@ void ConstraintSolver::initializeBodies() { // Compute the vector V1 with initial velocities values int bodyIndexArray = 6 * bodyNumber; - V1[bodyNumber] = rigidBody->getLinearVelocity(); - W1[bodyNumber] = rigidBody->getAngularVelocity(); - // Compute the vector Vconstraint with final constraint velocities - Vconstraint[bodyNumber] = Vector3(0, 0, 0); - Wconstraint[bodyNumber] = Vector3(0, 0, 0); + mLinearVelocities[bodyNumber] = rigidBody->getLinearVelocity() + mTimeStep * rigidBody->getMassInverse() * rigidBody->getExternalForce(); + mAngularVelocities[bodyNumber] = rigidBody->getAngularVelocity() + mTimeStep * rigidBody->getInertiaTensorInverseWorld() * rigidBody->getExternalTorque(); // Initialize the mass and inertia tensor matrices Minv_sp_inertia[bodyNumber].setAllValues(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); @@ -225,8 +221,6 @@ void ConstraintSolver::initializeContactConstraints(decimal dt) { // Fill in the error vector realContact->computeErrorPenetration(contact.errorPenetration); - contact.errorFriction1 = 0.0; - contact.errorFriction2 = 0.0; // Get the cached lambda values of the constraint contact.penetrationImpulse = realContact->getCachedLambda(0); @@ -239,27 +233,15 @@ void ConstraintSolver::initializeContactConstraints(decimal dt) { contact.errorPenetration = 0.0; decimal slop = 0.005; if (realContact->getPenetrationDepth() > slop) { - contact.errorPenetration += 0.2 * oneOverDT * std::max(double(realContact->getPenetrationDepth() - slop), 0.0); + contact.errorPenetration -= 0.2 * oneOverDT * std::max(double(realContact->getPenetrationDepth() - slop), 0.0); } - contact.errorFriction1 = 0.0; - contact.errorFriction2 = 0.0; // ---------- Penetration ---------- // // b = errorValues * oneOverDT; - contact.b_Penetration = contact.errorPenetration * oneOverDT; - - // ---------- Friction 1 ---------- // - - contact.b_Friction1 = contact.errorFriction1 * oneOverDT; - - // ---------- Friction 2 ---------- // - - contact.b_Friction2 = contact.errorFriction2 * oneOverDT; + contact.b_Penetration = contact.errorPenetration; } } - - } // Compute the matrix B_sp @@ -373,67 +355,9 @@ void ConstraintSolver::computeMatrixB_sp() { } } -// Compute the vector V_constraint (which corresponds to the constraint part of -// the final V2 vector) according to the formula -// V_constraint = dt * (M^-1 * J^T * lambda) -// Note that we use the vector V to store both V1 and V_constraint. -// Note that M^-1 * J^T = B. -// This method is called after that the LCP solver has computed lambda -void ConstraintSolver::computeVectorVconstraint(decimal dt) { - uint indexBody1Array, indexBody2Array; - uint j; - - // Compute dt * (M^-1 * J^T * lambda - for (uint c=0; c::iterator it = mConstraintBodies.begin(); it != mConstraintBodies.end(); ++it) { - RigidBody* rigidBody = *it; - uint bodyNumber = mMapBodyToIndex[rigidBody]; - - aLinear[bodyNumber] = oneOverDt * V1[bodyNumber] + rigidBody->getMassInverse() * rigidBody->getExternalForce(); - aAngular[bodyNumber] = oneOverDt * W1[bodyNumber] + rigidBody->getInertiaTensorInverseWorld() * rigidBody->getExternalTorque(); - } // For each constraint for (uint c=0; cgetMassInverse() * rigidBody->getExternalForce(); + newAngularVelocity += dt * rigidBody->getInertiaTensorInverseWorld() * rigidBody->getExternalTorque(); - // Compute V_forces = dt * (M^-1 * F_ext) which is the velocity of the body due to the - // external forces and torques. - newLinearVelocity += dt * rigidBody->getMassInverse() * rigidBody->getExternalForce(); - newAngularVelocity += dt * rigidBody->getInertiaTensorInverseWorld() * rigidBody->getExternalTorque(); - - // Add the velocity V1 to the new velocity - newLinearVelocity += rigidBody->getLinearVelocity(); - newAngularVelocity += rigidBody->getAngularVelocity(); + // Add the velocity V1 to the new velocity + newLinearVelocity += rigidBody->getLinearVelocity(); + newAngularVelocity += rigidBody->getAngularVelocity(); + } // Update the position and the orientation of the body according to the new velocity updatePositionAndOrientationOfBody(*it, newLinearVelocity, newAngularVelocity);