在身体局部空间施加扭矩脉冲
我目前正在评估使用C ++和Ogre3D编写的3D空间游戏的子弹物理库。 我已经通过派生自btMotionState并插入SceneNodes来很好地集成了Ogre3D和Bullet,但是现在我在计算应该传递给btRigidBody :: applyCentralImpulse和btRigidBody :: applyTorqueImpulse方法的值时遇到了很多麻烦,以便实现我正在寻找的结果。
当我按下键盘上的LEFT或RIGHT键时,我希望飞船在本地Z轴上滚动。 当我按UP或DOWN时,我想让它在当地的X轴上投球。 当我按A或Z时,我希望它在本地Z轴的方向上加速/减速。 我可以在Ogre中使用一些四元数学并在SceneNode上直接应用平移/旋转来完美实现这一点,但我真的希望使用力/力矩方法在Bullet引擎中应用这些值,以便它继续移动/俯仰/滚动即使在用户停止按下按键之后,摩擦也会在物体上起作用,以便在必要时减慢它。
那么,如何计算提供给这两种冲动方法的必要值,以确保脉冲基于身体的当前方向而不是使用世界坐标轴?
谢谢,Marc
更新:
我能够计算出向前和向后运动所需的冲动,但我仍在努力改变偏航/俯仰/滚转值的方向,以便使用扭矩冲击方法。 以下是我如何做前进/后退运动:
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);
所以看着btRigidBody.h
我注意到下面的代码:
void applyTorqueImpulse(const btVector3& torque)
{
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}
现在据我所知,你希望你的转矩等于某个常数乘以围绕与你的飞船相关的x(或z)轴的旋转矢量。
正如我们所知,广义旋转矩阵可以如下确定:
这意味着如果你能够识别一个轴对齐的扭矩(我不知道我的头顶部),你可以用你的:
mBody->getWorldTransform()*axisAlignedXTorque
根据http://www.bulletphysics.com/Bullet/BulletFull/classbtTransform.html中的*运算符,这将被覆盖,以对Torque矢量进行世界变换。
body->getInvInertiaTensorWorld().inverse()*(body->getWorldTransform().getBasis()*torque)
经过长时间的挫折之后,我最终得到了身体局部扭矩,以上述为输入来施加扭矩脉冲(或应用扭矩)。 我不假装为什么在这一点上起作用,但它确实如此。
从子弹:
void applyTorqueImpulse(const btVector3& torque)
{
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}
也许这就是tzenes提到的产生轴对齐扭矩的原因。 但我感到困惑的是,我找不到任何其他人这样做的例子。 当然其他人已经想要在人体局部空间施加扭矩? 但是,尽管它看起来应该如此,但我在网上找到的任何东西都无法工作。
如果你只应用变换扭矩,它会看起来像它的工作,直到你开始离开你的世界的起源。 所以,如果感觉越难旋转越远离原点,或者如果事情根据身体的位置开始反向旋转,这可能是您的问题。
编辑:哦,这是我的翻译方式:
btVector3 m = body-> getWorldTransform()。getBasis()* btVector3(strafe,move,rise);
链接地址: http://www.djcxy.com/p/17101.html