Jak wyłączyć ruch w osi Y w silniku fizyki Bullet

11

Chcę utworzyć obiekt, a nie tylko poruszać się wzdłuż osi X i Z, przy jednoczesnym wyłączeniu osi Y (to jest jak ruch w 2D, a obiekt nie spadnie).

Obecnie używam ograniczenia 6 dof, aby ograniczyć ruch na osi Y, ale to nie działa:

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

Dzięki!

azer
źródło
Może to pomoże: bulletphysics.org/Bullet/phpBB3/… , być może również ustawisz dolne / górne limity dla osi Y na 0, zamiast 1
spowolniono, a

Odpowiedzi:

20

Preferowanym sposobem osiągnięcia tego w Bullet jest ustawienie współczynnika liniowego i ewentualnie kątowego dla danego ciała. Ta metoda jest prezentowana jako fragment kodu na stronie Wiki Bullet.

Aby umożliwić ruch tylko wzdłuż osi Y, użyłbyś czegoś takiego:

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

Jeśli dodatkowo chcesz wyłączyć obrót wokół określonej osi, zastosuj tę samą procedurę, ale setAngularFactorzamiast tego użyj funkcji.

W tym prostym przykładowym filmie użyłem następujących dwóch wywołań, aby wyłączyć ruch wzdłuż osi Y i umożliwić obrót tylko wokół osi Y. To skutecznie zmusza ciało do pozostania w płaszczyźnie XZ, w której zostało pierwotnie utworzone.

body->setLinearFactor(btVector3(1,0,1));
body->setAngularFactor(btVector3(0,1,0));
Jiddo
źródło
2

Jednym ze sposobów jest utworzenie wywołania zwrotnego zaznaczenia fizyki. Będzie to wywoływane za każdym razem, gdy pocisk wewnętrznie tyka. W tym wywołaniu zwrotnym możesz ustawić prędkość Y na 0, skutecznie blokując ruch Y. Wyglądałoby to tak:

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

Możesz przeczytać więcej o wywołaniach zwrotnych symulacji zaznacz tutaj .

MichaelHouse
źródło
Dziękuję Ci! To świetna odpowiedź, ponieważ dotyczy również portu Java JBulleta (w przeciwieństwie do innych odpowiedzi).
joehot200