子弹物理 - 在身体的局部空间中施加扭矩冲击

Lus*_*sid 18 c++ physics ogre3d bullet

我正在评估Bullet物理库中我正在使用C++和Ogre3D编写的3D空间游戏.通过从btMotionState派生并插入我的SceneNodes,我已经很好地集成了Ogre3D和Bullet,但是现在我在计算我应该传递给btRigidBody :: applyCentralImpulse和btRigidBody :: applyTorqueImpulse方法的值时遇到很多麻烦才能实现我正在寻找的结果.

当我按下键盘上的左或右键时,我希望太空飞船在本地Z轴上滚动.当我按UP或DOWN时,我希望它在本地X轴上倾斜.当我按A或Z时,我希望它在局部Z轴的方向上加速/减速.我可以在Ogre中使用一些四元数学并直接在SceneNode上应用translate/rotation来实现这一点,但我真的想使用force/torque方法在Bullet引擎中应用这些值,这样它将继续移动/俯仰/滚动即使在用户停止按键之后,摩擦也会作用在物体上以根据需要减慢速度.

那么,我如何计算为这两种脉冲方法提供的必要值,以确保脉冲基于身体的当前方向而不是使用世界的轴?

谢谢,马克

更新:

我能够计算出向前和向后运动所需的冲动,但我仍在努力解决如何重新定向偏航/俯仰/滚转值以便将它们与扭矩脉冲方法一起使用.这是我进行前进/后退运动的方式:

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);
Run Code Online (Sandbox Code Playgroud)

tze*_*nes 3

所以看看 btRigidBody.h

我注意到以下代码:

     void applyTorqueImpulse(const btVector3& torque)
     {
                     m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
     }
Run Code Online (Sandbox Code Playgroud)

现在,据我了解,您希望扭矩等于某个常数乘以与飞船相关的 x(或 z)轴的旋转矢量。

众所周知,广义旋转矩阵可以确定如下:

  1. 旋转以对齐轴预成型件
  2. 绕规范轴旋转
  3. 步骤 1 的逆过程

这意味着,如果您可以确定轴对齐扭矩(我不知道),您可以用以下方法对其进行转换:

mBody->getWorldTransform()*axisAlignedXTorque
Run Code Online (Sandbox Code Playgroud)

根据http://www.bulletphysicals.com/Bullet/BulletFull/classbtTransform.html ,此处的 * 运算符被重写以对扭矩矢量执行世界变换。