Подтвердить что ты не робот

Физика пули - применение импульсного импульса в локальном пространстве тела

В настоящее время я оцениваю Bullet Physics Library для игры в 3D-пространстве, которую я пишу, используя С++ и Ogre3D. У меня есть Ogre3D и Bullet, которые прекрасно сочетаются с выходом из btMotionState и подключением моих SceneNodes, но теперь у меня много проблем с вычислением значений, которые я должен передать в btRigidBody:: applyCentralImpulse и btRigidBody:: applyTorqueImpulse, чтобы достичь результаты, которые я ищу.

Когда я нажимаю клавиши LEFT или RIGHT на клавиатуре, я хочу, чтобы космический корабль катился по локальной оси Z. Когда я нажимаю UP или DOWN, я хочу, чтобы он шаг на локальной оси X. Когда я нажимаю A или Z, я хочу, чтобы он ускорялся/замедлялся в направлении локальной оси Z. Я могу достичь этого отлично в Огре, используя некоторую математику кватернионов и применяя перевод/вращение непосредственно на SceneNode, но я действительно хочу применить эти значения в двигателе Bullet, используя методы силы/крутящего момента, чтобы он продолжал двигаться/шаг/рулон даже после того, как пользователь перестанет нажимать клавиши, и поэтому трение будет действовать на объект, чтобы замедлить его при необходимости.

Итак, как мне рассчитать необходимые значения для обеспечения этих двух импульсных методов, чтобы гарантировать, что импульс действует на основе ориентации тока тела вместо использования мировых осей?

Спасибо, Марк

Update:

Я смог выработать импульсы, необходимые для движения вперед и назад, но я все еще борется с тем, как переориентировать значения рыскания/шага/валка, чтобы использовать их с импульсным методом крутящего момента. Здесь, как я сделал движение вперед/назад:

if (mKeyboard->isKeyDown(OIS::KC_A))
    mBody->applyCentralImpulse(mBody->getWorldTransform().getBasis().getColumn(2) * 20 * time);
if (mKeyboard->isKeyDown(OIS::KC_Z))
    mBody->applyCentralImpulse(mBody->getWorldTransform().getBasis().getColumn(2) * -20 * time);
4b9b3361

Ответ 1

Итак, посмотрим на btRigidBody.h

Я замечаю следующий код:

     void applyTorqueImpulse(const btVector3& torque)
     {
                     m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
     }

Теперь, когда я это понимаю, вы хотите, чтобы ваш Torque был равен некоторому постоянному временному вектору вращения вокруг оси x (или z), связанной с вашим космическим кораблем.

Как известно, обобщенная матрица вращения может быть определена следующим образом:

  • Поворот в выровненную заготовку осей
  • Вращение вокруг канонической оси
  • Обратный шаг 1

Это означает, что если вы можете определить крутящий момент, ориентированный по оси (который я не знаю с головы), вы можете преобразовать его с помощью:

mBody->getWorldTransform()*axisAlignedXTorque

Что соответствует http://www.bulletphysics.com/Bullet/BulletFull/classbtTransform.html оператор * здесь переопределяется, чтобы преформировать преобразование мира на вектор крутящего момента.

Ответ 2

body->getInvInertiaTensorWorld().inverse()*(body->getWorldTransform().getBasis()*torque)

После долгого периода разочарования я, наконец, получил крутящий момент для тела, используя вышеприведенное в качестве входного сигнала для применения TorqueImpulse (или applyTorque). Я не претендую на то, чтобы понять, почему он работает на данный момент, но он это делает.

От пули:

    void applyTorqueImpulse(const btVector3& torque)
{
        m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}

Возможно, это то, о чем говорили цени, о том, как производить крутящий момент, ориентированный по оси. Но я озадачен тем, что не могу найти никого, кто бы делал это так. Неужели кто-то еще хотел, чтобы крутящий момент применялся в местном пространстве? Но ничто из того, что я нашел в Интернете, не работало вообще, несмотря на то, что оно выглядело так, как должно.

Если вы примените крутящий момент трансформирования *, это будет выглядеть так, как будто это работает сначала, пока вы не начнете отходить от происхождения вашего мира. Поэтому, если вам будет тяжелее вращаться дальше, вы находитесь далеко от начала координат, или если вещи начинают вращаться в обратном направлении в зависимости от того, где находится тело, это, вероятно, ваша проблема.

EDIT: О, и вот, как мои переводы:

btVector3 m = body- > getWorldTransform(). getBasis() * btVector3 (strafe, move, rise);