Comment désactiver le mouvement de l'axe Y dans le moteur physique Bullet

11

Je veux créer un objet qui ne se déplace que le long des axes X et Z, tout en gardant l'axe Y désactivé (c'est comme un mouvement en 2D, et l'objet ne tombera pas).

J'utilise actuellement une contrainte de 6 ddl pour restreindre le mouvement dans l'axe Y, mais cela ne fonctionne pas:

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);

Merci!

azer
la source
Peut-être que cela aidera: bulletphysics.org/Bullet/phpBB3/… , peut-être aussi définir les limites inférieure / supérieure de l'axe Y à 0, au lieu de 1.
deceleratedcaviar

Réponses:

20

Le moyen préféré pour y parvenir dans Bullet est de définir le facteur linéaire et éventuellement le facteur angulaire pour le corps en question. Cette méthode est présentée sous forme d' extrait de code sur la page Bullet Wiki.

Afin de permettre le mouvement uniquement le long de l'axe Y, vous utiliseriez quelque chose comme ceci:

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

Si vous souhaitez également désactiver la rotation autour d'un axe particulier, vous utilisez la même procédure, mais en utilisant la setAngularFactorfonction à la place.

Dans cet exemple vidéo simple, j'ai utilisé les deux appels suivants afin de désactiver le mouvement le long de l'axe Y et de permettre la rotation autour de l'axe Y uniquement. Cela oblige effectivement le corps à rester dans le plan XZ dans lequel il a été initialement créé.

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

Une façon de le faire est de créer un rappel de tick physique. Cela sera appelé à chaque fois que la puce se déclenche en interne. Dans ce rappel, vous pouvez régler la vitesse Y sur 0, désactivant efficacement le mouvement Y. Cela ressemblerait à quelque chose comme ceci:

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);
} 

Vous pouvez en savoir plus sur les rappels de tick de simulation ici .

MichaelHouse
la source
Je vous remercie! C'est une excellente réponse, car elle s'applique également au port java de JBullet (contrairement à l'autre réponse).
joehot200