2009-11-04 72 views
18

我目前正在评估我用C++编写的3D空间游戏Bullet Physics LibraryOgre3D。我已经通过派生自btMotionState并插入SceneNodes来很好地集成了Ogre3D和Bullet,但是现在我在计算应该传递给btRigidBody :: applyCentralImpulse和btRigidBody :: applyTorqueImpulse方法的值时遇到了很多麻烦,以便实现我正在寻找的结果。Bullet Physics - 在人体局部空间中应用转矩脉冲

当我按下键盘上的LEFT或RIGHT键时,我想宇宙飞船在本地Z轴上滚动。当我按UP或DOWN时,我想让它在当地的X轴上投球。当我按A或Z时,我希望它在本地Z轴的方向上加速/减速。我可以在Ogre中使用一些四元数学并在SceneNode上直接应用平移/旋转来完美实现这一点,但我真的希望使用力/力矩方法在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); 
+0

你可以通过四元数的冲动API或以某种方式四元数转换的东西,你可以通过? – fbrereto 2009-11-04 22:24:04

+0

从我可以在API中看到的,它出现在线性脉冲法仅在世界坐标接受一个x,y,z中的方向的矢量,和角脉冲法只接受一个Y,P,R矢量偏航,俯仰和滚动世界坐标。虽然数学可以在我的头上略(我有一个很难形象化的东西像点和跨产品),实际子弹API本身是远远超过我的头,完全新的给我...这两者的结合使我的现在的生活是不可能的。 – Lusid 2009-11-05 00:06:11

回答

3

所以看着btRigidBody.h

我发现下面的代码:

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

现在,据我所知,你希望你的扭力等于与你的飞船相关的x(或z)轴周围的旋转矢量的某些常数倍。

正如我们所知道的广义旋转矩阵可以如下确定:

  1. 旋转以对准轴瓶坯
  2. 旋转有关规范轴
  3. 逆步骤1

此装置的如果你可以识别一个轴对齐的扭矩(我不知道我的头顶部),你可以用它来转换:

mBody->getWorldTransform()*axisAlignedXTorque 

其中根据http://www.bulletphysics.com/Bullet/BulletFull/classbtTransform.html 这里的*运算符被覆盖以预制转矩矢量的世界变换。

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

后挫折长时间的,我终于体本地扭矩使用上述作为输入到applyTorqueImpulse(或applyTorque)工作。我不假装为什么在这一点上起作用,但它确实如此。

从子弹:

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

也许这就是tzenes刚提过关于生产对准扭矩轴。但我感到困惑的是,我找不到任何其他人这样做的例子。当然其他人已经想要在人体局部空间施加扭矩?但是,尽管它看起来应该如此,但我在网上找到的任何东西都无法工作。

如果仅应用变换*扭矩,它会像它工作在第一,直到你开始从你的世界的起源移开。所以,如果感觉难以进一步您远离原点,或者如果事情开始依赖于在身体转动相反,这可能是你的问题旋转。

编辑: 哦,这里就是我有我的翻译:

btVector3 M =身体 - > getWorldTransform()getBasis()* btVector3(扫射,移动,上升);