You can set two components of the the local inertia tensor to zero, instead of using the angular factor. This will give you a 'fixed' hinge axis in local space, so you just orient the body accordinaly (and use a btCompoundShape if necessary). I plan on adding a btTransformShape to avoid the cost of btCompoundShape when the only purpose is just to shift the center of mass.I'd still like a solution that works in the non-axis aligned case though.
You still need to set the linear factor to zero.
Code: Select all
box->calculateLocalInertia(mass,localInertia); localInertia = 0; localInertia = 0; body = new btRigidBody(..., localInertia); body->setLinearFactor(btVector3(0,0,0)); //don't call body->setAngularFactor, because we already lock the angular motion using the inertia tensor //don't need to create a btHingeConstraint either.
With btMultiBody you can attach two free moving bodies in a way so that the hinge axis will never be violated.
Yet another alternative would be to use the btDanztigSolver or btLemkeSolver (see Bullet/Demos/ForkLiftDemo). Right now, the solver is used for all objects, so performance would drop.
It is possible to use the btDantzigSolver or btLemkeSolver only for specific constraints, as a 'block' solver, in combination with regular iterative constraints (sequential impulse/projected gauss seidel).
I am working on a demo in the github repository to show the various options.
Please let us know if that inertia tensor workaround does the trick for you.