Як відключити рух по осі Y в двигуні фізики Bullet


11

Я хочу створити об'єкт, ніж рухатися тільки по осях X і Z, при цьому утримуючи вісь Y відключена (це як рух у 2D, і об'єкт не впаде вниз).

Наразі я використовую обмеження 6 dof для обмеження руху по осі Y, але воно не працює:

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

Дякую!


Можливо, це допоможе: bulletphysics.org/Bullet/phpBB3/… , можливо, також встановіть нижню / верхню межу для осі Y на 0, замість 1.
уповільнивсякавіарій

Відповіді:


20

Кращим способом досягти цього в Кулі є встановлення лінійного коефіцієнта і, можливо, кутового коефіцієнта для тіла. Цей метод представлений у вигляді фрагмента коду на сторінці Bullet Wiki.

Щоб дозволити рух по осі Y, ви використовуєте щось подібне:

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

Якщо ви додатково бажаєте відключити обертання навколо будь-якої конкретної осі, ви використовуєте ту саму процедуру, але setAngularFactorзамість цього використовуєте функцію.

У цьому простому прикладі відео я використав наступні два виклики, щоб вимкнути рух по осі Y і дозволити обертання навколо лише осі Y. Це ефективно змушує організм залишатися в площині XZ, в якій він був створений спочатку.

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

2

Один із способів зробити це - створити зворотний виклик фізики. Це буде називатися щоразу, коли куля тикне всередину. У цьому зворотному зворотному звороті ви можете встановити швидкість Y на 0, ефективно вимикаючи рух Y. Це виглядатиме приблизно так:

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

Детальніше про зворотні дзвінки з імітацією ви можете прочитати тут .


Дякую! Це чудова відповідь, оскільки це стосується і java-порта JBullet (на відміну від іншої відповіді).
joehot200
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.