projectileman is quite correct. Using the X axis as the "upright" axis does indeed work, but you need to change the reference frames so that the X axis becomes the world Y axis. Here is the code in our engine that uses this solution:
Code:
_bt_balancer_body = new btRigidBody(
btRigidBody::btRigidBodyConstructionInfo(
0, 0, 0, bt_vector_zero ) );
// must use X axis as Y axis because 6dof wont spin freely on Y
btTransform frameina( btTransform::getIdentity() );
btTransform frameinb( btTransform::getIdentity() );
frameina.getBasis().setEulerZYX( 0, 0, SIMD_HALF_PI );
_bt_balancer_body->getWorldTransform()
.getBasis().setEulerZYX( 0, 0, SIMD_HALF_PI );
btGeneric6DofConstraint * sixdof = new btGeneric6DofConstraint(
*_bt_rigid_body, *_bt_balancer_body,
frameina, frameinb, true ); // use linear reference frame a
sixdof->setLimit( 0, -SIMD_INFINITY, SIMD_INFINITY );
sixdof->setLimit( 1, -SIMD_INFINITY, SIMD_INFINITY );
sixdof->setLimit( 2, -SIMD_INFINITY, SIMD_INFINITY );
sixdof->setLimit( 3, -SIMD_PI, SIMD_PI ); // only x axis can turn freely
sixdof->setLimit( 4, 0, 0 );
sixdof->setLimit( 5, 0, 0 );
_bt_balancer_constraint = sixdof;
Also, Erwin posted
viewtopic.php?f=9&t=3369&p=19436#p19436a far simpler solution using btRigidBody::setAngularFactor.
Code:
btVector3 angularfactor( 0, 1, 0 );
_bt_rigid_body->setAngularFactor( angularfactor );
Nevertheless, the btGeneric6DofConstraint solution is the best for us because our worlds are spherical planets, so the "upright" axis changes as bodies move rather than being fixed to the universal Y axis.
--Christopher
