I need a constraint that works like a simple rope for my application. That means, no collision is needed between the rope and something else, it just has to keep the distance between the connection points on two rigid bodies below a defined rope length. As a second mode, it can be used to keep this distance constant, to simulate a rod connecting the two bodies instead.
So I started writing one. It is based on the btPoint2PointConstraint and the basics are simple enough as it is easy to figure out the direction of the impulse vectors -- always in the direction of the rope/rod.
But I have problems comprehending how to use the Jacobian properly to dimension the magnitude of the impulse in this case. I would really appreciate any hints on how to do this!
Below, the code so far. With the current impulse it works as if the rope was a rubber band (as expected).
If it works properly in the end I'd be happy to give it to bullet if you would like to have it.
Best regards,
Ola
Code: Select all
void btRopeConstraint::solveConstraint(btScalar timeStep)
{
btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*pivot_in_a_;
btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*pivot_in_b_;
// vector from A to B
btVector3 dist_a_b = pivotAInW - pivotBInW;
// absolute distance between A and B
double abs_dist = dist_a_b.length();
// if the distance is shorter than the rope length just quit here (comment out for constant distance)
// if(abs_dist < length_)
// return;
// Create a vector that contains the error (stretch/depth) of the rope
dist_a_b = dist_a_b * length_ / abs_dist;
btVector3 depth = pivotAInW - pivotBInW - dist_a_b;
btScalar abs_depth = depth.length();
btVector3 norm_depth = depth.normalize();
// Velocity stuff
btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1);
btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2);
btVector3 vel = vel1 - vel2;
btScalar rel_vel;
rel_vel = norm_depth.dot(vel);
// TODO: Figure out the Jacobian value
// btScalar abs_impulse = abs_depth*tau_/timeStep * jacDiagABInv - damping_ * rel_vel * jacDiagABInv;
// cheat instead for now
btScalar abs_impulse = -abs_depth * 1.0;
m_rbA.applyImpulse( norm_depth*abs_impulse, pivotAInW - m_rbA.getCenterOfMassPosition());
m_rbB.applyImpulse(-norm_depth*abs_impulse, pivotBInW - m_rbB.getCenterOfMassPosition());
}