Come disabilitare il movimento dell'asse Y nel motore di fisica Bullet


11

Voglio creare un oggetto che si sposta solo lungo gli assi X e Z, mantenendo disabilitato l'asse Y (è come il movimento in 2D e l'oggetto non cadrà).

Attualmente sto usando un vincolo 6 dof per limitare il movimento sull'asse Y, ma non funziona:

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

Grazie!


Forse questo aiuterà: bulletphysics.org/Bullet/phpBB3/… , forse anche impostare i limiti inferiore / superiore per l'asse Y su 0, anziché su 1.
deceleratedcaviar

Risposte:


20

Il modo preferito per raggiungere questo obiettivo in Bullet è impostare il fattore lineare e possibilmente il fattore angolare per il corpo in questione. Questo metodo è presentato come frammento di codice nella pagina Bullet Wiki.

Per consentire il movimento lungo solo l'asse Y, dovresti usare qualcosa del genere:

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

Se si desidera inoltre disabilitare la rotazione attorno a un determinato asse, utilizzare la stessa procedura, ma utilizzando setAngularFactorinvece la funzione.

In questo semplice video di esempio ho usato le due chiamate seguenti per disabilitare il movimento lungo l'asse Y e consentire la rotazione solo attorno all'asse Y. Questo costringe effettivamente il corpo a rimanere sul piano XZ in cui è stato inizialmente creato.

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

2

Un modo per farlo è quello di creare un callback tick di fisica. Questo verrà chiamato ogni volta che il proiettile spunta internamente. In questa richiamata è possibile impostare la velocità Y su 0, disabilitando efficacemente il movimento Y. Sarebbe simile a questo:

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

Puoi leggere di più sui callback tick di simulazione qui .


Grazie! Questa è un'ottima risposta, poiché si applica anche alla porta java di JBullet (a differenza dell'altra risposta).
joehot200,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.