骨のアニメーション-行列と計算


7

プロジェクトの完了に関しては、最終段階にありますが、アニメーションシステムを実装する直前です。

クライアントは「ボーンアニメーション」を選択することにしました。つまり、このアニメーション化されたオブジェクトが持つすべてのフレームとすべてのボーンに対して、各変換マトリックス(matrix4x4 rotation + translation)をエクスポートする必要があります。

ゲーム内のオブジェクトは3DS Max Physiqueモディファイヤでアニメーション化されているため、頂点ごとにボーン/ウェイトデータがあります。しかし、この件について少し理解するために、ここでは説明を簡略化します。

この投稿を2つのポイントに分割します。

  1. すべてのフレームのボーンマトリックスのエクスポート

    • 後のアニメーションの目的でボーンの位置をエクスポートする正しい方法について扱います。この場合、このボーンの影響を受けるすべての頂点をフレームXのボーンの位置に「移動」および「回転」する必要があります。
  2. 最終的な頂点位置の計算

    • フレームXのボーン変換に従って新しい頂点位置を計算するために、適切な行列演算について扱います。

1.フレームごとにボーンマトリックスをエクスポートする

アニメーション化されたオブジェクトをエクスポートするときに、次のことを行う必要があることを正しく理解していますか?

  1. フレーム0でBONE変換行列を取得し、この行列を反転します

  2. FRAMExでBONE変換行列を取得

  3. 1 * 2を乗算して、FRAMExでのBONEの変換オフセットを取得します

[pseudocode]
// Animation export

// For each frame, export bone transformation offset
for(int iFrame = 0; iFrame < vFrames.size(); iFrame++)
{
    // For every bone in the object
    for(int iBone = 0; iBone < vBones.size(); iBone++)
    {
        // Grab transformation matrix for this bone at frame 0 and inverse it
        Matrix3 matBoneMatrixAtStart = pNode->GetObjectTMAfterWSM( 0 );
        matBoneMatrixAtStart.Inverse();

        // Grab transformation matrix for this bone at frame iFrame
        Matrix3 matBoneMatrixAtCurrentFrame = pNode->GetObjectTMAfterWSM( iFrame );

        // Multiply Inversed Transformation Matrix of this bone at frame 0 - with
        //  current frame transformation matrix
        Matrix3 matBoneTransformationOffset = matBoneMatrixAtStart
                                              * matBoneMatrixAtCurrentFrame ;

        // Save matBoneTransformationOffset - vertex will be multiplied by this
        //  matrix for animation purposes
        fwrite(.....)
    }

}
[/pseudocode]

それで十分でしょうか?または私がここで欠けているものはありますか?

2.新しい頂点の位置を計算する(フレームXでの最終的な頂点の位置)

後でレンダリングするとき、オブジェクトの頂点には、実際のアニメーションフレームのエクスポートされたボーン変換行列が乗算され、次にこのモデル全体の変換行列が乗算されて、オブジェクトがレベル内の正しい位置に配置されます。

[pseudocode]

Update()
{
    // The model transformation matrix describing the position of
    //  the model in the level
    matModelTransformationMatrix


    // Calculate new vertex position according to it's bone transformation offset
    NewVertexPosition = (OriginalVertexPosition * matBoneTransformationOffset[iFrame])
                           * matModelTransformationMatrix;

    // Increment the frame for testing purposes
    iFrame++;
}

[/pseudocode]

私はここで正しいと思いますか?したがって、フレームXのボーン変換オフセットがある場合、このボーンの影響を受けるすべての頂点にこのオフセットを掛けると、頂点はこのボーンのとおりに変換されますか?

回答:


8

いくつかのGPU Gems記事を含むnVidiaのページを読むことをお勧めします。次の疑似回答で簡単に説明する主要な式があります。ここに画像の説明を入力してください

これがあなたが完全な記事を見つける場所であり、それは今では古典的なリソースです。私は、あなたがそのプロセスの説明を、(私ができる限り)単純化された方法で行うことを望んでいると仮定します。

式とその意味:

まず、頂点のメッシュ、つまり、接続性のある頂点のセット{Pk}から始めます。トポロジーについてはそれほど気にしないので、接続性は無視してください(これはスキニングが低下してはならず、多様体を多様体のように見せる、トポロジーを維持するなど)。その式では、vBindposeはキャラクターの頂点の静止位置を示します。これはオブジェクトスペース、つまり、そのキャラクターのフレームの「ワールドスペース」にあります。これで、各ボーンには独自のフレームがあり、ボーンのbone [i]フレームに書き込まれたベクトルをオブジェクトのグローバルフレームに変換する方法は、matrixBindpose [I]。(ロボットを組み立てる必要があり、その前腕の頂点が肘の参照フレームで与えられていると想像してください。そして、肘は上腕骨/肩の骨に接続されています。それが主に頂点セットを組み立てるためにこれらの変換が必要な理由です。メッシュに)

では、INV(matrixBindpose [i])x vBindposeはどういう意味ですか?これは、そのbone [i]ボーンのローカルフレーム内のv頂点の座標を取得することを意味します。どうして?各ボーンは、影響を受ける頂点が独自の座標フレームを基準にして独自のバージョンを記憶できるためです。つまり、各ボーンは、他のボーンがそのポイントをどのように見ているかに関係なく、影響を受けるポイントがどこにあるかについての独自の相対ビューを提供できます。

ここで、新しい骨変換行列matrix [i]を乗算するとどうなりますか?最後のポイントから、v頂点のローカルバージョンができたことを思い出してください。つまり、bone [i]は、その頂点が自身のフレームに対してどのように見えるかを考えます。matrix [i]を掛けると、グローバル/オブジェクト座標フレームにあるベクトル/頂点ができあがります。

次に、その頂点にボーンのスカラー寄与/重みを掛けます。それであなたは何を持っていますか?最終的に、同じ座標フレームにあるベクトルの重み付き合計になります。そのため、それらを追加することができます。つまり、頂点に影響を与えるすべてのボーンの合計を取得できます。

コードは、手順を完全に理解したことを実際には反映していません。nVidiaの記事は、シェーダーを介してそれを行う方法に重点を置いています。そのため、初期/バインドポーズメッシュの1つの頂点に影響を与えることができるボーンは最大で4つあると仮定しています。

あなたが言ったように、あなたが最初のポーズ、バインドポーズを取るなら、matrix [i] x matrix [i] ^-1は単位行列です。合計は_sum(w_i)* vBindpose_と等しくなるため、問題ありません。以来vBindposeは、グローバル/対象フレームに書き込まれたベクトルであり、それは既に組み立てられた位置にあります。構築によるこれらの重みの合計は1です(重みの正規化プロセスから生じる凸の組み合わせ-通常、各頂点に重みが割り当てられた後にシステムによって実行されます)。そのため、この式を使用して、モデルを正しく組み立てることができるかどうかを確認できます(通常はMD5 Doom3によって行われました)私が正しく覚えていればアニメーションモデルローダー)。簡単に言えば、それだけです。つまり、各ステップで計算を少し最適化して、そこでリロル式の結果を計算する必要があるということです。幸せなコーディング:)


ああ、それは私がここ数回を読み取るために持っていることを多くのものだ-私はそれがこのように複雑になっている疑いませんでした。これは私が...動作して取得する必要があり、ご協力いただきありがとうござい
PEES

ようこそ、実際にはかなり単純なトピックです。これについてチュートリアルを行いましたが、英語ではなかったため、そのPDFを提供するのに役立ちません。私はそれをビデオ、純粋な英語で行い、YouTubeチャンネルに投稿するつもりですが、現在、時間はありません。近い将来、ここでこのトピックに関する質問をしてください。このようなトピックについて議論するのは素晴らしいことです。
teodron 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.