Como desativar o movimento do eixo Y no mecanismo de física Bullet

11

Eu quero criar um objeto que apenas se mova ao longo dos eixos X e Z, mantendo o eixo Y desativado (é como o movimento em 2D, e o objeto não cai).

Atualmente, estou usando uma restrição de 6 dof para restringir o movimento no eixo Y, mas não está funcionando:

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

Obrigado!

azer
fonte
Talvez isto ajude: bulletphysics.org/Bullet/phpBB3/... , talvez também definir os limites inferior / superior para o eixo Y a 0, em vez de 1.
deceleratedcaviar

Respostas:

20

A maneira preferida de conseguir isso no Bullet é definir o fator linear e possivelmente o fator angular para o corpo em questão. Este método é apresentado como um trecho de código na página Bullet Wiki.

Para permitir o movimento apenas ao longo do eixo Y, você usaria algo como isto:

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

Se você deseja desativar adicionalmente a rotação em torno de qualquer eixo específico, use o mesmo procedimento, mas usando a setAngularFactorfunção.

Neste vídeo de exemplo simples , usei as duas chamadas a seguir para desativar o movimento ao longo do eixo Y e permitir a rotação apenas ao redor do eixo Y. Isso efetivamente força o corpo a permanecer no plano XZ no qual foi criado inicialmente.

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

Uma maneira de fazer isso é criar um retorno de chamada físico. Isso será chamado toda vez que o marcador for marcado internamente. Nesta chamada de retorno, você pode definir a velocidade Y como 0, desativando efetivamente o movimento Y. Seria algo como isto:

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

Você pode ler mais sobre retornos de chamada de simulação aqui .

MichaelHouse
fonte
Obrigado! Essa é uma ótima resposta, pois também se aplica à porta java do JBullet (diferente da outra resposta).
Joehot200 14/05