2009-11-04 28 views
18

私は現在、C++とOgre3Dを使って書いている3D空間ゲームのためにBullet Physics Libraryを評価しています。私はOgre3DとBulletをbtMotionStateから引き出し、自分のSceneNodeをプラグインしてうまく統合しましたが、今はbtRigidBody :: applyCentralImpulseメソッドとbtRigidBody :: applyTorqueImpulseメソッドに渡すべき値を計算するのに苦労しています私が探している結果Bullet Physics - ボディのローカルスペースにトルクインパルスを適用する

キーボードの左または右のキーを押すと、宇宙船がローカルのZ軸上を回転します。 UPまたはDOWNを押すと、ローカルのX軸でピッチを調整します。 AまたはZを押すと、ローカルZ軸の方向に加減速します。私はいくつかの四元数学を使ってこれをOgreで完璧に達成でき、SceneNodeに直接平行移動/回転を適用することができますが、力/トルク法を使ってBulletエンジンでこれらの値を適用したいのですが、ユーザーがキーを押すのをやめた後でも、オブジェクトに摩擦が作用して必要に応じて減速します。

インパルスがワールドの軸を使用するのではなく、身体の現在の向きに基づいて動作するように、これら2つのインパルス法に必要な値を計算するにはどうすればよいですか?

おかげで、 マルク

更新:

私が進退するために必要な衝動をうまくすることができましたが、私はまだヨー/ピッチ/ロール値を再配向する方法に苦しんでいますトルクインパルス法でそれらを使用する。私は前進/後退をした方法をここにあります:

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

+0

APIからわかるように、線形インパルス法は、ワールド座標の方向のx、y、zベクトルのみを受け取り、角度インパルス法はヨーのy、p、rベクトルのみを受け取り、ピッチ、ロールをワールド座標系に変換します。数学は私の頭を少し上回っているかもしれませんが(私はドットとクロスのようなものを視覚化するのに苦労します)、実際のBullet API自体は私の頭を越えて全く新しいものです...これらの2つの組み合わせは私現時点では不可能な人生。 – Lusid

答えて

3

は、だから私は、次のコード気づくbtRigidBody.h

を見て:

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

を今、私はそれを理解して、あなたのトルクをしたいですあなたの宇宙船に関連付けられているx(またはz)軸周りの回転ベクトルの一定の倍に等しくなるようにします。

我々は次のように一般化された回転行列を決定することができる知っているように:

  1. 回転ステップ1

  • 回転
  • 正規軸周りに逆この手段軸プリフォームを配置します軸合わせトルク(私が頭の上からわからない)を特定できれば、あなたはそれをあなたと変えることができます:

    mBody->getWorldTransform()*axisAlignedXTorque 
    

    http://www.bulletphysics.com/Bullet/BulletFull/classbtTransform.html によれば、*演算子はトルクベクトル上でワールド変換を実行するために上書きされます。

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

    は欲求不満の長い期間の後、私は最終的にapplyTorqueImpulse(又はapplyTorque)への入力として、上記を使用して動作するように本体ローカルトルクを得ました。私はこの時点でなぜそれが働くのか理解していないのですが、そうしています。bulletから

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

    は多分これがtzenesが軸整列トルクを発生について言及されたものです。しかし、私は、他の誰かがこのようにしているという例は見つけられないということに困惑しています。確かに他の誰かが身体のローカルスペースにトルクを加えたかったのですか?しかし、私はオンラインで見つけられたものは、まるでそれがそうであるように見えたにもかかわらず、全く働かなかった。

    変換*トルクのみを適用すると、あなたが世界の起源から遠ざかるまで、最初は動作するように見えます。だから、それ以上回転させるのが難しい場合は、原点から離れているか、身体の場所によって物が逆回転し始める場合は、おそらくこれが問題です。

    EDIT: ああ、ここで私は私の翻訳を持っている方法は次のとおりです。

    btVector3メートル= body-> getWorldTransform()getBasis()* btVector3(機銃掃射、移動、上昇)。

    関連する問題