Как отключить движение по оси Y в движке Bullet Physics

11

Я хочу создать объект, который двигается только вдоль осей X и Z, при этом ось Y остается отключенной (это похоже на движение в 2D, и объект не упадет).

В настоящее время я использую ограничение 6 степеней свободы, чтобы ограничить движение по оси 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

Предпочтительный способ для достижения этой цели в пулях , чтобы установить линейный множитель и , возможно, угловой коэффициент для рассматриваемого тела. Этот метод представлен как фрагмент кода на странице Wiki Пули.

Чтобы разрешить движение только по оси Y, вы должны использовать что-то вроде этого:

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

Если вы дополнительно хотите отключить вращение вокруг какой - либо конкретной оси, можно использовать ту же процедуру, но с использованием setAngularFactorфункции вместо.

В этом простом примере видео я использовал следующие два вызов для того , чтобы отключить движение вдоль оси Y. и обеспечить вращение вокруг только Y-ось. Это фактически заставляет тело оставаться в XZ-плоскости , в которой он был первоначально создан.

body->setLinearFactor(btVector3(1,0,1));
body->setAngularFactor(btVector3(0,1,0));
Jiddo
источник
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);
} 

Вы можете прочитать больше о моделировании клеща обратных вызовов здесь .

MichaelHouse
источник
Спасибо! Это отличный ответ, так как это также относится и к Java порту JBullet , а также ( в отличие от другого ответа).
joehot200