Bullet Physics - 在身体的局部空间中应用扭矩脉冲

Posted

技术标签:

【中文标题】Bullet Physics - 在身体的局部空间中应用扭矩脉冲【英文标题】:Bullet Physics - Apply Torque Impulse in Body's Local Space 【发布时间】:2010-12-13 05:16:49 【问题描述】:

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

当我按下键盘上的 LEFT 或 RIGHT 键时,我希望飞船在本地 Z 轴上滚动。当我按下 UP 或 DOWN 时,我希望它在本地 X 轴上倾斜。当我按下 A 或 Z 时,我希望它在局部 Z 轴的方向上加速/减速。我可以使用一些四元数数学在 Ogre 中完美地实现这一点,并直接在 SceneNode 上应用平移/旋转,但我真的想使用力/扭矩方法在子弹引擎中应用这些值,以便它继续移动/俯仰/滚动即使在用户停止按键之后,摩擦力也会作用在对象上,使其在必要时减慢速度。

那么,我如何计算提供给这两种脉冲方法的必要值,以确保脉冲根据身体当前的方向而不是使用世界坐标轴起作用?

谢谢, 马克

更新:

我能够计算出向前和向后运动所需的脉冲,但我仍在努力调整偏航/俯仰/滚动值的方向,以便将它们与扭矩脉冲法一起使用。以下是我进行向前/向后移动的方式:

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

【问题讨论】:

您能否将四元数传递给脉冲 API 或以某种方式将四元数转换为您可以传递的东西? 从我在 API 中可以看到,似乎线性脉冲方法只接受世界坐标方向的 x,y,z 向量,而角度脉冲方法只接受 y,p ,r 世界坐标中偏航、俯仰和滚动的向量。虽然数学可能有点超出我的想象(我很难想象像点积和叉积之类的东西),但实际的 Bullet API 本身就超出了我的想象,对我来说是全新的……这两者的结合使我此刻的生活是不可能的。 【参考方案1】:

所以看看 btRigidBody.h

我注意到以下代码:

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

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

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

    旋转以对齐轴预制件 围绕标准轴旋转 步骤 1 的逆操作

这意味着,如果您可以识别轴对齐扭矩(我不知道在我的头顶上),您可以使用您的:

mBody->getWorldTransform()*axisAlignedXTorque

根据http://www.bulletphysics.com/Bullet/BulletFull/classbtTransform.html 此处的 * 运算符被覆盖以对 Torque 向量进行世界变换。

【讨论】:

【参考方案2】:
body->getInvInertiaTensorWorld().inverse()*(body->getWorldTransform().getBasis()*torque)

经过长时间的挫折,我终于得到了身体局部扭矩,使用上述作为 applyTorqueImpulse(或 applyTorque)的输入。我不假装理解它为什么在这一点上起作用,但确实如此。

来自子弹:

    void applyTorqueImpulse(const btVector3& torque)

        m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;

也许这就是 tzenes 提到的关于产生轴对齐扭矩的内容。但我很困惑,我找不到其他人这样做的例子。肯定有人想要在身体的局部空间中施加扭矩吗?但我在网上发现的任何东西都不起作用,尽管看起来应该如此。

如果您只应用 transform*torque,它一开始会看起来像它一样有效,直到您开始远离世界的起源。因此,如果您离原点越远感觉旋转越困难,或者如果根据身体所在的位置开始反向旋转,这可能是您的问题。

编辑: 哦,我的翻译是这样的:

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

【讨论】:

以上是关于Bullet Physics - 在身体的局部空间中应用扭矩脉冲的主要内容,如果未能解决你的问题,请参考以下文章

无法编译简单的 Bullet Physics 应用程序

有没有人有关于如何使用 Bullet Physics/jBullet 进行 voronoi 粉碎的示例/教程?

[原][osg][osgEarth]关于在OE中使用物理引擎的调研

Computational physics 计算物理 exact diagonalization 精确对角化1

physx是啥

Havok Physics 2012