Some optimizations in the constraint solver have been made

git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@386 92aac97c-a6ce-11dd-a772-7fcde58d38e6
This commit is contained in:
chappuis.daniel 2010-09-07 20:08:54 +00:00
parent b9ddb0e2f1
commit f61a9eeff7
5 changed files with 199 additions and 209 deletions

View File

@ -25,8 +25,7 @@ using namespace reactphysics3d;
// Constructor
Constraint::Constraint(Body* const body1, Body* const body2, uint nbAuxConstraints, bool active)
:body1(body1), body2(body2), active(active), nbAuxConstraints(nbAuxConstraints),
lowerBound(lowerBound), upperBound(upperBound) {
:body1(body1), body2(body2), active(active), nbAuxConstraints(nbAuxConstraints) {
}

View File

@ -44,38 +44,26 @@ namespace reactphysics3d {
*/
class Constraint {
protected :
Body* const body1; // Pointer to the first body of the constraint
Body* const body2; // Pointer to the second body of the constraint
bool active; // True if the constraint is active
Matrix body1Jacobian; // Jacobian matrix of the constraint for body1 (dimension 1x6)
Matrix body2Jacobian; // Jacobian matrix of the constraint for body2 (dimension 1x6)
Matrix auxJacobian; // Jacobian matrix for all the auxiliary constraints jacobian associated with this constraint
// (dimension nx12 where n is the number of auxiliary constraints)
uint nbAuxConstraints; // Number of auxiliary constraints associated with this constraint
double lowerBound; // Lower bound of the constraint
double upperBound; // Upper bound of the constraint
Vector auxLowerBounds; // Vector that contains all the lower bounds of the auxiliary constraints
Vector auxUpperBounds; // Vector that contains all the upper bounds of the auxiliary constraints
double errorValue; // Error value (bias) of the constraint
Vector auxErrorValues; // Error values for the auxiliary constraints
Body* const body1; // Pointer to the first body of the constraint
Body* const body2; // Pointer to the second body of the constraint
bool active; // True if the constraint is active
uint nbAuxConstraints; // Number of auxiliary constraints associated with this constraint
public :
Constraint(Body* const body1, Body* const body2, uint nbAuxConstraints, bool active); // Constructor // Constructor
virtual ~Constraint(); // Destructor
Body* const getBody1() const; // Return the reference to the body 1
Body* const getBody2() const; // Return the reference to the body 2
virtual void evaluate()=0; // Evaluate the constraint
bool isActive() const; // Return true if the constraint is active
const Matrix& getBody1Jacobian() const; // Return the jacobian matrix of body 1
const Matrix& getBody2Jacobian() const; // Return the jacobian matrix of body 2
unsigned int getNbAuxConstraints() const; // Return the number of auxiliary constraints
const Matrix& getAuxJacobian() const; // Return the jacobian matrix of auxiliary constraints
double getLowerBound() const; // Return the lower bound value of the constraint
double getUpperBound() const; // Return the upper bound value of the constraint
const Vector& getAuxLowerBounds() const; // Return the vector of lower bounds values
const Vector& getAuxUpperBounds() const; // Return the vector of the upper bounds values
double getErrorValue() const; // Return the error value (bias) of the constraint
const Vector& getAuxErrorValues() const; // Return the auxiliary error values
Body* const getBody2() const; // Return the reference to the body 2 // Evaluate the constraint
bool isActive() const; // Return true if the constraint is active // Return the jacobian matrix of body 2
virtual void computeJacobian(int noBody, Matrix& jacobian) const=0; // Compute a part of the jacobian for a given body
virtual void computeAuxJacobian(int noBody, int noAuxConstraint, Matrix& auxJacobian) const=0; // Compute a part of the jacobian for an auxiliary constraint
virtual double computeLowerBound() const=0; // Compute the lowerbound of the constraint
virtual double computeUpperBound() const=0; // Compute the upperbound of the constraint
virtual void computeAuxLowerBounds(int beginIndex, Vector& auxLowerBounds) const=0; // Compute lowerbounds for the auxiliary constraints
virtual void computeAuxUpperBounds(int beginIndex, Vector& auxUpperBounds) const=0; // Compute upperbounds for the auxiliary constraints
virtual double computeErrorValue() const=0; // Compute the error value for the constraint
virtual void computeAuxErrorValues(int beginIndex, Vector& errorValues) const=0; // Compute the errors values of the auxiliary constraints
unsigned int getNbAuxConstraints() const; // Return the number of auxiliary constraints // Return the number of auxiliary constraints
};
// Return the reference to the body 1
@ -93,56 +81,11 @@ inline bool Constraint::isActive() const {
return active;
}
// Return the jacobian matrix of body 1
inline const Matrix& Constraint::getBody1Jacobian() const {
return body1Jacobian;
}
// Return the jacobian matrix of body 2
inline const Matrix& Constraint::getBody2Jacobian() const {
return body2Jacobian;
}
// Return the number auxiliary constraints
inline uint Constraint::getNbAuxConstraints() const {
return nbAuxConstraints;
}
// Return the auxiliary jacobian matrix
inline const Matrix& Constraint::getAuxJacobian() const {
return auxJacobian;
}
// Return the lower bound value of the constraint
inline double Constraint::getLowerBound() const {
return lowerBound;
}
// Return the upper bound value of the constraint
inline double Constraint::getUpperBound() const {
return upperBound;
}
// Return the vector of lower bounds values
inline const Vector& Constraint::getAuxLowerBounds() const {
return auxLowerBounds;
}
// Return the vector of the upper bounds values
inline const Vector& Constraint::getAuxUpperBounds() const {
return auxUpperBounds;
}
// Return the error value (bias) of the constraint
inline double Constraint::getErrorValue() const {
return errorValue;
}
// Return the auxiliary error values
inline const Vector& Constraint::getAuxErrorValues() const {
return auxErrorValues;
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -19,9 +19,6 @@
// Libraries
#include "Contact.h"
#include "../body/RigidBody.h"
#include <GL/freeglut.h> // TODO : Remove this in the final version
#include <GL/gl.h> // TODO : Remove this in the final version
// We want to use the ReactPhysics3D namespace
using namespace reactphysics3d;
@ -29,115 +26,17 @@ using namespace reactphysics3d;
// Constructor
Contact::Contact(Body* const body1, Body* const body2, const Vector3D& normal, double penetrationDepth, const Vector3D& point)
:Constraint(body1, body2, 2, true), normal(normal), penetrationDepth(penetrationDepth), point(point) {
body1Jacobian.changeSize(1,6);
body2Jacobian.changeSize(1,6);
auxJacobian.changeSize(nbAuxConstraints, 12);
auxLowerBounds.changeSize(nbAuxConstraints);
auxUpperBounds.changeSize(nbAuxConstraints);
auxErrorValues.changeSize(nbAuxConstraints);
body1Jacobian = Matrix(1, 6);
body2Jacobian = Matrix(1, 6);
auxJacobian = Matrix(nbAuxConstraints, 12);
auxLowerBounds = Vector(nbAuxConstraints);
auxUpperBounds = Vector(nbAuxConstraints);
auxErrorValues = Vector(nbAuxConstraints);
// Compute the auxiliary lower and upper bounds
// TODO : Now mC is only the mass of the first body but it is probably wrong
// TODO : Now g is 9.81 but we should use the true gravity value of the physics world.
mu_mc_g = FRICTION_COEFFICIENT * body1->getMass() * 9.81;
// Compute the friction vectors that span the tangential friction plane
computeFrictionVectors();
}
// Destructor
Contact::~Contact() {
}
// Evaluate the constraint
// This method computes the jacobian matrices of the constraint
void Contact::evaluate() {
RigidBody* rigidBody1 = dynamic_cast<RigidBody*>(body1);
RigidBody* rigidBody2 = dynamic_cast<RigidBody*>(body2);
assert(rigidBody1 != 0);
assert(rigidBody2 != 0);
// Compute the friction vectors that span the tangential friction plane
computeFrictionVectors();
Vector3D r1 = point - rigidBody1->getPosition();
Vector3D r2 = point - rigidBody2->getPosition();
Vector3D r1CrossN = r1.crossProduct(normal);
Vector3D r2CrossN = r2.crossProduct(normal);
// Compute the jacobian matrix for the body 1
body1Jacobian.setValue(0, 0, -normal.getX());
body1Jacobian.setValue(0, 1, -normal.getY());
body1Jacobian.setValue(0, 2, -normal.getZ());
body1Jacobian.setValue(0, 3, -r1CrossN.getX());
body1Jacobian.setValue(0, 4, -r1CrossN.getY());
body1Jacobian.setValue(0, 5, -r1CrossN.getZ());
// Compute the jacobian matrix for the body 2
body2Jacobian.setValue(0, 0, normal.getX());
body2Jacobian.setValue(0, 1, normal.getY());
body2Jacobian.setValue(0, 2, normal.getZ());
body2Jacobian.setValue(0, 3, r2CrossN.getX());
body2Jacobian.setValue(0, 4, r2CrossN.getY());
body2Jacobian.setValue(0, 5, r2CrossN.getZ());
// Compute the lower and upper bounds values
lowerBound = 0.0;
upperBound = INFINITY_CONST;
// Compute the error value of the constraint
Vector3D velocity1 = rigidBody1->getLinearVelocity();
Vector3D velocity2 = rigidBody2->getLinearVelocity();
double restitutionCoeff = rigidBody1->getRestitution() * rigidBody2->getRestitution();
errorValue = restitutionCoeff * (normal.scalarProduct(velocity1) - normal.scalarProduct(velocity2)) + PENETRATION_FACTOR * penetrationDepth;
// Compute the auxiliary jacobian matrix (this corresponds to the friction constraint)
Vector3D r1CrossU1 = r1.crossProduct(frictionVectors[0]);
Vector3D r2CrossU1 = r2.crossProduct(frictionVectors[0]);
Vector3D r1CrossU2 = r1.crossProduct(frictionVectors[1]);
Vector3D r2CrossU2 = r2.crossProduct(frictionVectors[1]);
auxJacobian.setValue(0, 0, -frictionVectors[0].getX());
auxJacobian.setValue(0, 1, -frictionVectors[0].getY());
auxJacobian.setValue(0, 2, -frictionVectors[0].getZ());
auxJacobian.setValue(0, 3, -r1CrossU1.getX());
auxJacobian.setValue(0, 4, -r1CrossU1.getY());
auxJacobian.setValue(0, 5, -r1CrossU1.getZ());
auxJacobian.setValue(0, 6, frictionVectors[0].getX());
auxJacobian.setValue(0, 7, frictionVectors[0].getY());
auxJacobian.setValue(0, 8, frictionVectors[0].getZ());
auxJacobian.setValue(0, 9, r2CrossU1.getX());
auxJacobian.setValue(0, 10, r2CrossU1.getY());
auxJacobian.setValue(0, 11, r2CrossU1.getZ());
auxJacobian.setValue(1, 0, -frictionVectors[1].getX());
auxJacobian.setValue(1, 1, -frictionVectors[1].getY());
auxJacobian.setValue(1, 2, -frictionVectors[1].getZ());
auxJacobian.setValue(1, 3, -r1CrossU2.getX());
auxJacobian.setValue(1, 4, -r1CrossU2.getY());
auxJacobian.setValue(1, 5, -r1CrossU2.getZ());
auxJacobian.setValue(1, 6, frictionVectors[1].getX());
auxJacobian.setValue(1, 7, frictionVectors[1].getY());
auxJacobian.setValue(1, 8, frictionVectors[1].getZ());
auxJacobian.setValue(1, 9, r2CrossU2.getX());
auxJacobian.setValue(1, 10, r2CrossU2.getY());
auxJacobian.setValue(1, 11, r2CrossU2.getZ());
// Compute the auxiliary lower and upper bounds
// TODO : Now mC is only the mass of the first body but it is probably wrong
// TODO : Now g is 9.81 but we should use the true gravity value of the physics world.
double mu_mc_g = FRICTION_COEFFICIENT * rigidBody1->getMass() * 9.81;
auxLowerBounds.setValue(0, -mu_mc_g);
auxLowerBounds.setValue(1, -mu_mc_g);
auxUpperBounds.setValue(0, mu_mc_g);
auxUpperBounds.setValue(1, mu_mc_g);
// Compute the error auxiliary values
auxErrorValues.setValue(0, 0.0);
auxErrorValues.setValue(1, 0.0);
;}
// TODO : Delete this (Used to debug collision detection)
void Contact::draw() const {
glColor3f(1.0, 0.0, 0.0);
glutSolidSphere(0.5, 20, 20);
}

View File

@ -23,7 +23,10 @@
// Libraries
#include "../typeDefinitions.h"
#include "Constraint.h"
#include "../body/RigidBody.h"
#include "../mathematics/mathematics.h"
#include <GL/freeglut.h> // TODO : Remove this in the final version
#include <GL/gl.h> // TODO : Remove this in the final version
// ReactPhysics3D namespace
namespace reactphysics3d {
@ -50,20 +53,27 @@ class Contact : public Constraint {
const double penetrationDepth; // Penetration depth
const Vector3D point; // Contact point
std::vector<Vector3D> frictionVectors; // Two orthogonal vectors that span the tangential friction plane
double mu_mc_g;
void computeFrictionVectors(); // Compute the two friction vectors that span the tangential friction plane
public :
Contact(Body* const body1, Body* const body2, const Vector3D& normal, double penetrationDepth, const Vector3D& point); // Constructor
virtual ~Contact(); // Destructor
Vector3D getNormal() const; // Return the normal vector of the contact
Vector3D getPoint() const; // Return the contact point
virtual void evaluate(); // Evaluate the constraint
uint getNbAuxConstraints() const; // Return the number of auxiliary constraints
double getPenetrationDepth() const; // Return the penetration depth
void draw() const; // TODO : Delete this (Used to debug collision detection)
Vector3D getNormal() const; // Return the normal vector of the contact
Vector3D getPoint() const; // Return the contact point
virtual void computeJacobian(int noBody, Matrix& jacobian) const; // Compute a part of the jacobian for a given body
virtual void computeAuxJacobian(int noBody, int noAuxConstraint, Matrix& auxJacobian) const; // Compute a part of the jacobian for an auxiliary constraint
virtual double computeLowerBound() const; // Compute the lowerbound of the constraint
virtual double computeUpperBound() const; // Compute the upperbound of the constraint
virtual void computeAuxLowerBounds(int beginIndex, Vector& auxLowerBounds) const; // Compute the lowerbounds for the auxiliary constraints
virtual void computeAuxUpperBounds(int beginIndex, Vector& auxLowerBounds) const; // Compute the upperbounds for the auxiliary constraints
virtual double computeErrorValue() const; // Compute the error value for the constraint
virtual void computeAuxErrorValues(int beginIndex, Vector& errorValues) const; // Compute the errors values of the auxiliary constraints
uint getNbAuxConstraints() const; // Return the number of auxiliary constraints
double getPenetrationDepth() const; // Return the penetration depth
void draw() const; // TODO : Delete this (Used to debug collision detection)
};
// Compute the two unit orthogonal vectors "v1" and "v2" that span the tangential friction plane
@ -90,10 +100,142 @@ inline Vector3D Contact::getPoint() const {
return point;
}
// Return the penetration depth of the contact
inline double Contact::getPenetrationDepth() const {
return penetrationDepth;
}
// This method computes a part of the jacobian matrix for a given body.
// The argument "noBody" is 1 or 2 and corresponds to which one of the two
// bodies of the constraint we will compute the jacobian part. The argument
// "jacobian" is a 1x6 jacobian matrix of the constraint corresponding to one of
// the two bodies of the constraint.
inline void Contact::computeJacobian(int noBody, Matrix& jacobian) const {
RigidBody* rigidBody;
Vector3D rCrossN;
Vector3D r;
Vector3D norm = normal;
assert(noBody == 1 || noBody == 2);
assert(jacobian.getNbRow() == 1 && jacobian.getNbColumn() == 6);
if (noBody == 1) {
rigidBody = dynamic_cast<RigidBody*>(body1);
assert(rigidBody);
r = point - rigidBody->getPosition();
rCrossN = r.crossProduct(normal).getOpposite();
norm = normal.getOpposite();
}
else {
rigidBody = dynamic_cast<RigidBody*>(body2);
assert(rigidBody);
r = point - rigidBody->getPosition();
rCrossN = r.crossProduct(normal);
}
// Compute the jacobian matrix for the body 1
jacobian.setValue(0, 0, norm.getX());
jacobian.setValue(0, 1, norm.getY());
jacobian.setValue(0, 2, norm.getZ());
jacobian.setValue(0, 3, rCrossN.getX());
jacobian.setValue(0, 4, rCrossN.getY());
jacobian.setValue(0, 5, rCrossN.getZ());
}
// Compute a part of the jacobian matrix for an auxiliary constraint (given by "noAuxConstraint")
// and one of the two bodies (given by "noBody") of the contact. The argument "noBody" is 1 or 2 and
// argument auxJacobian is a 1x6 matrix.
inline void Contact::computeAuxJacobian(int noBody, int noAuxConstraint, Matrix& auxJacobian) const {
Vector3D r;
Vector3D rCrossU;
RigidBody* rigidBody;
double sign;
assert(noBody == 1 || noBody == 2);
assert(noAuxConstraint == 1 || noAuxConstraint == 2);
assert(auxJacobian.getNbRow() == 1 && auxJacobian.getNbColumn() == 6);
if (noBody == 1) {
rigidBody = dynamic_cast<RigidBody*>(body1);
assert(rigidBody);
r = point - rigidBody->getPosition();
sign = -1.0;
}
else {
rigidBody = dynamic_cast<RigidBody*>(body2);
assert(rigidBody);
r = point - rigidBody->getPosition();
sign = 1.0;
}
rCrossU = r.crossProduct(frictionVectors[noAuxConstraint-1]);
auxJacobian.setValue(0, 0, sign * frictionVectors[noAuxConstraint-1].getX());
auxJacobian.setValue(0, 1, sign * frictionVectors[noAuxConstraint-1].getY());
auxJacobian.setValue(0, 2, sign * frictionVectors[noAuxConstraint-1].getZ());
auxJacobian.setValue(0, 3, sign * rCrossU.getX());
auxJacobian.setValue(0, 4, sign * rCrossU.getY());
auxJacobian.setValue(0, 5, sign * rCrossU.getZ());
}
// Compute the lowerbounds for the auxiliary constraints
inline double Contact::computeLowerBound() const {
return 0.0;
}
// Compute the upperbounds for the auxiliary constraints
inline double Contact::computeUpperBound() const {
return INFINITY_CONST;
}
// Compute the lowerbounds for the auxiliary constraints. This method fills the "auxLowerBounds"
// vector starting at the index "beginIndex" in this vector.
inline void Contact::computeAuxLowerBounds(int beginIndex, Vector& auxLowerBounds) const {
assert(beginIndex + nbAuxConstraints <= auxLowerBounds.getNbComponent());
auxLowerBounds.setValue(beginIndex, -mu_mc_g);
auxLowerBounds.setValue(beginIndex + 1, -mu_mc_g);
}
// Compute the upperbounds for the auxiliary constraints. This method fills the "auxUpperBounds"
// vector starting at the index "beginIndex" in this vector.
inline void Contact::computeAuxUpperBounds(int beginIndex, Vector& auxUpperBounds) const {
assert(beginIndex + nbAuxConstraints <= auxUpperBounds.getNbComponent());
auxUpperBounds.setValue(beginIndex, mu_mc_g);
auxUpperBounds.setValue(beginIndex + 1, mu_mc_g);
}
// Compute the error value for the constraint
inline double Contact::computeErrorValue() const {
RigidBody* rigidBody1 = dynamic_cast<RigidBody*>(body1);
RigidBody* rigidBody2 = dynamic_cast<RigidBody*>(body2);
assert(rigidBody1);
assert(rigidBody2);
Vector3D velocity1 = rigidBody1->getLinearVelocity();
Vector3D velocity2 = rigidBody2->getLinearVelocity();
double restitutionCoeff = rigidBody1->getRestitution() * rigidBody2->getRestitution();
double errorValue = restitutionCoeff * (normal.scalarProduct(velocity1) - normal.scalarProduct(velocity2)) + PENETRATION_FACTOR * penetrationDepth;
return errorValue;
}
// Compute the errors values of the auxiliary constraints
inline void Contact::computeAuxErrorValues(int beginIndex, Vector& errorValues) const {
assert(beginIndex + nbAuxConstraints <= errorValues.getNbComponent());
errorValues.setValue(beginIndex, 0.0);
errorValues.setValue(beginIndex + 1, 0.0);
}
// TODO : Delete this (Used to debug collision detection)
inline void Contact::draw() const {
glColor3f(1.0, 0.0, 0.0);
glutSolidSphere(0.3, 20, 20);
}
} // End of the ReactPhysics3D namespace
#endif

View File

@ -50,9 +50,6 @@ void ConstraintSolver::initialize() {
for (it = physicsWorld->getConstraintsBeginIterator(); it != physicsWorld->getConstraintsEndIterator(); it++) {
constraint = *it;
// Evaluate the constraint
constraint->evaluate();
// If the constraint is active
if (constraint->isActive()) {
activeConstraints.push_back(constraint);
@ -178,36 +175,39 @@ void ConstraintSolver::freeMemory(bool freeBodiesMemory) {
// Fill in all the matrices needed to solve the LCP problem
// Notice that all the active constraints should have been evaluated first
void ConstraintSolver::fillInMatrices() {
Constraint* constraint;
Contact* contact;
ContactCachingInfo* contactInfo;
// For each active constraint
uint noConstraint = 0;
uint nbAuxConstraints = 0;
for (uint c=0; c<activeConstraints.size(); c++) {
Constraint* constraint = activeConstraints.at(c);
constraint = activeConstraints.at(c);
// Fill in the J_sp matrix
J_sp[noConstraint][0].changeSize(1, 6);
J_sp[noConstraint][1].changeSize(1, 6);
J_sp[noConstraint][0] = constraint->getBody1Jacobian();
J_sp[noConstraint][1] = constraint->getBody2Jacobian();
constraint->computeJacobian(1, J_sp[noConstraint][0]);
constraint->computeJacobian(2, J_sp[noConstraint][1]);
// Fill in the body mapping matrix
bodyMapping[noConstraint][0] = constraint->getBody1();
bodyMapping[noConstraint][1] = constraint->getBody2();
// Fill in the limit vectors for the constraint
lowerBounds.setValue(noConstraint, constraint->getLowerBound());
upperBounds.setValue(noConstraint, constraint->getUpperBound());
lowerBounds.setValue(noConstraint, constraint->computeLowerBound());
upperBounds.setValue(noConstraint, constraint->computeUpperBound());
// Fill in the error vector
errorValues.setValue(noConstraint, constraint->getErrorValue());
errorValues.setValue(noConstraint, constraint->computeErrorValue());
// If it's a contact constraint
Contact* contact = dynamic_cast<Contact*>(constraint);
contact = dynamic_cast<Contact*>(constraint);
if (contact) {
// Get the lambda init value from the cache if exists
ContactCachingInfo* contactInfo = contactCache.getContactCachingInfo(contact->getBody1(), contact->getBody2(), contact->getPoint());
contactInfo = contactCache.getContactCachingInfo(contact->getBody1(), contact->getBody2(), contact->getPoint());
if (contactInfo) {
// The last lambda init value was in the cache
lambdaInit.setValue(noConstraint, contactInfo->lambda);
@ -232,8 +232,8 @@ void ConstraintSolver::fillInMatrices() {
// Fill in the J_sp matrix
J_sp[noConstraint+i][0].changeSize(1, 6);
J_sp[noConstraint+i][1].changeSize(1, 6);
J_sp[noConstraint+i][0] = constraint->getAuxJacobian().getSubMatrix(i-1, 0, 1, 6);
J_sp[noConstraint+i][1] = constraint->getAuxJacobian().getSubMatrix(i-1, 6, 1, 6);
constraint->computeAuxJacobian(1, i, J_sp[noConstraint+i][0]);
constraint->computeAuxJacobian(2, i, J_sp[noConstraint+i][1]);
// Fill in the body mapping matrix
bodyMapping[noConstraint+i][0] = constraint->getBody1();
@ -244,8 +244,11 @@ void ConstraintSolver::fillInMatrices() {
}
// Fill in the limit vectors for the auxilirary constraints
lowerBounds.fillInSubVector(noConstraint+1, constraint->getAuxLowerBounds());
upperBounds.fillInSubVector(noConstraint+1, constraint->getAuxUpperBounds());
constraint->computeAuxLowerBounds(noConstraint+1, lowerBounds);
constraint->computeAuxUpperBounds(noConstraint+1, upperBounds);
// Fill in the errorValues vector for the auxiliary constraints
constraint->computeAuxErrorValues(noConstraint+1, errorValues);
}
noConstraint += 1 + nbAuxConstraints;
@ -256,6 +259,8 @@ void ConstraintSolver::fillInMatrices() {
Body* body;
Vector v(6);
Vector f(6);
Matrix identity = Matrix::identity(3);
Matrix mInv(6,6);
uint b=0;
for (set<Body*>::iterator it = constraintBodies.begin(); it != constraintBodies.end(); it++, b++) {
body = *it;
@ -282,10 +287,9 @@ void ConstraintSolver::fillInMatrices() {
Fext[bodyNumber] = f;
// Compute the inverse sparse mass matrix
Matrix mInv(6,6);
mInv.initWithValue(0.0);
if (rigidBody->getIsMotionEnabled()) {
mInv.fillInSubMatrix(0, 0, rigidBody->getMassInverse() * Matrix::identity(3));
mInv.fillInSubMatrix(0, 0, rigidBody->getMassInverse() * identity);
mInv.fillInSubMatrix(3, 3, rigidBody->getInertiaTensorInverseWorld());
}
Minv_sp[bodyNumber].changeSize(6, 6);
@ -348,6 +352,9 @@ void ConstraintSolver::computeVectorVconstraint(double dt) {
// Clear and Fill in the contact cache with the new lambda values
void ConstraintSolver::updateContactCache() {
Contact* contact;
ContactCachingInfo* contactInfo;
// Clear the contact cache
contactCache.clear();
@ -356,10 +363,10 @@ void ConstraintSolver::updateContactCache() {
for (uint c=0; c<activeConstraints.size(); c++) {
// If it's a contact constraint
Contact* contact = dynamic_cast<Contact*>(activeConstraints.at(c));
contact = dynamic_cast<Contact*>(activeConstraints.at(c));
if (contact) {
// Create a new ContactCachingInfo
ContactCachingInfo* contactInfo = new ContactCachingInfo(contact->getBody1(), contact->getBody2(), contact->getPoint(), lambda.getValue(noConstraint));
contactInfo = new ContactCachingInfo(contact->getBody1(), contact->getBody2(), contact->getPoint(), lambda.getValue(noConstraint));
// Add it to the contact cache
contactCache.addContactCachingInfo(contactInfo);