Cómo deshabilitar el movimiento del eje Y en el motor de física Bullet

11

Quiero crear un objeto que solo se mueva a lo largo de los ejes X y Z, manteniendo el eje Y deshabilitado (es como el movimiento en 2D, y el objeto no se caerá).

Actualmente estoy usando una restricción de 6 dof para restringir el movimiento en el eje Y, pero no funciona:

btRigidBody* zeroBody = new btRigidBody(0, NULL, NULL); // Create the body that we attach things to
btRigidBody* robot = mCarChassis->getBulletRigidBody();

btGeneric6DofConstraint* constrict = new btGeneric6DofConstraint(*robot, *zeroBody, btTransform::getIdentity(), btTransform::getIdentity(), false);

constrict->setLinearLowerLimit( btVector3( 1, 1, 1));
constrict->setLinearUpperLimit( btVector3(-1, 1,-1));

constrict->setAngularLowerLimit( btVector3( 1,  1,  1) );
constrict->setAngularUpperLimit( btVector3(-1, -1, -1) );

mBulletWorld->getBulletDynamicsWorld()->addConstraint(constrict);

¡Gracias!

azer
fuente
Tal vez esto ayude: bulletphysics.org/Bullet/phpBB3/… , quizás también establezca los límites inferior / superior para el eje Y en 0, en lugar de 1.
caviar desacelerado

Respuestas:

20

La forma preferida de lograr esto en Bullet es establecer el factor lineal y posiblemente el factor angular para el cuerpo en cuestión. Este método se presenta como un fragmento de código en la página Bullet Wiki.

Para permitir el movimiento solo a lo largo del eje Y, usaría algo como esto:

body->setLinearFactor(btVector3(0,1,0));

Si además desea deshabilitar la rotación alrededor de cualquier eje en particular, utilice el mismo procedimiento, pero en su lugar utilice la setAngularFactorfunción.

En este simple video de ejemplo , he usado las siguientes dos llamadas para deshabilitar el movimiento a lo largo del eje Y y permitir la rotación solo alrededor del eje Y. Esto efectivamente obliga al cuerpo a permanecer en el plano XZ en el que fue creado inicialmente.

body->setLinearFactor(btVector3(1,0,1));
body->setAngularFactor(btVector3(0,1,0));
Jiddo
fuente
2

Una forma de hacer esto es crear una devolución de llamada de tics de física. Esto se llamará cada vez que la bala haga tictac internamente. En esta devolución de llamada, puede establecer la velocidad Y en 0, deshabilitando efectivamente el movimiento Y. Se vería algo así:

void myTickCallback(const btDynamicsWorld *world, btScalar timeStep) {
    //robotBody is the btRigidBody you want to constrain the movement of
    btVector3 velocity = robotBody->getLinearVelocity();
    robotBody->setLinearVelocity(velocity.x, 0, velocity.z);
} 

Puede leer más sobre las devoluciones de llamada de marca de simulación aquí .

MichaelHouse
fuente
¡Gracias! Esta es una gran respuesta, ya que también se aplica al puerto Java de JBullet (a diferencia de la otra respuesta).
joehot200