2012-05-09 4 views
0

皮のメッシュでロスト)!は</p> <p>私は最終的にGPU上でMD5と皮メッシュ上で動作する時間を持って、私は一種の迷ってしまいました

だからここに私が何をすべきかです: -

    • はMD5MESHファイルをロードし

    • ビルドメッシュ(ジオメトリが正しいか、この一歩が正しく行われている)バインドポーズこのようなバインドと逆バインドを作成します(ジョイントは読み込まれたものとして使用されますが、親によって変換されるのではありません)。

      for(unsigned int i = 0; i < this->mMatricesCount; i++) 
      { 
          mat4 mBoneTranslation = mat4(
            1, 0, 0, mModel->mJoints[i].mPosition.x, 
            0, 1, 0, mModel->mJoints[i].mPosition.y, 
            0, 0, 1, mModel->mJoints[i].mPosition.z, 
            0, 0, 0, 1); 
          mat4 mBoneRotation = mat4(mModel->mJoints[i].mOrientation); 
      
          mat4 mBoneMatrix = mBoneTranslation * mBoneRotation; 
      
          this->mMatrices[i] = mBoneMatrix; 
          this->mInverseMatrices[i] = inverse(mBoneMatrix); 
      } 
      
    • ロードMD5ANIMファイル(各フレームジョイントは以下のように計算される):

         if(mAnimation->mJoints[i].mParent < 0) 
             { 
              mAnimation->mFrames[mFrameID][i].mPosition = _position; 
              mAnimation->mFrames[mFrameID][i].mOrientation = _orientation; 
             } 
             else 
             { 
              MD5FrameJoint *mParent = &mAnimation->mFrames[mFrameID][mAnimation->mJoints[i].mParent]; 
      
              float4 rpos = rotate(mParent->mOrientation, _position); 
      
              mAnimation->mFrames[mFrameID][i].mPosition = rpos + mParent->mPosition; 
              mAnimation->mFrames[mFrameID][i].mOrientation = mParent->mOrientation * _orientation;       
             } 
      
    • 各フレームは、(今4点の重みの最大は、現在I、トラブルの原因とされていないような骨マトリックスを構築シンプルなモザイク状のクワッド上のシーンでわずか3骨がある - 誤って回転):

      for(unsigned int i = 0; i < this->mJoints; i++) 
      { 
          const mat4 mTranslate = mat4(
           1, 0, 0, this->mFramePositions[mFrame][i].x, 
           0, 1, 0, this->mFramePositions[mFrame][i].y, 
           0, 0, 1, this->mFramePositions[mFrame][i].z, 
           0, 0, 0, 1); 
          const mat4 mRotate = mat4(this->mFrameOrientations[mFrame][i]); 
      
          this->mOutput[i] = mTranslate * mRotate; 
      } 
      
    • をそして(今、CPU上でやって、GPUに移動したい)などの頂点を計算:

       for(unsigned int j = 0; j < mSkinnedModel->mVertexCount[i]; j++) 
           { 
            float4 mResult = float4(0, 0, 0, 0); 
      
            float4 mPosition = float4(mSkinnedModel->mVertices[i][j].mPosition[0], 
                   mSkinnedModel->mVertices[i][j].mPosition[1], 
                   mSkinnedModel->mVertices[i][j].mPosition[2], 
                   1.0f); 
      
            for(unsigned int k = 0; k < 4; k++) 
            { 
             mResult += (mAnimatedBones[mSkinnedModel->mVertices[i][j].mBoneIndices[k]] * mPosition) * mSkinnedModel->mVertices[i][j].mBoneWeights[k]; 
            } 
      
            mBuffer[j].mPosition[0] = mResult.x; 
            mBuffer[j].mPosition[1] = mResult.y; 
            mBuffer[j].mPosition[2] = mResult.z; 
            mBuffer[j].mPosition[3] = 1.0f; 
           } 
      

    (+のアニメーションファイルが正しいメッシュは、(それらをエクスポートし、3Dモデリングソフトウェアにインポート、作品!)

    今、私は私の数学ライブラリは大丈夫であるかどうかをテストすることだし、これまでのところ、それは良いようです行列逆行列は良いですが、四元数の乗算も四元数からの行列です...)

    そして私には何かを指摘しないでください。行列+ソースコード付きのGPUでMD5スキニングをしている人)が開いて何が間違っているのか分かりませんが、これまでのコードはほぼ私のようです。それはいくつかの小さなちっさいな細部になります。

    誰でもグルがどこですか?

  • +0

    MD5は、最も一般的なハッシュアルゴリズムです。私はそのタグを削除しました。 – rekire

    答えて

    3

    (これは間違っています)!

    1つの画像は数千語分の価値があります。あなたは写真を投稿しませんでした。それで、あなたは何を期待しましたか?

    mat4 mBoneTranslation = mat4(
         1, 0, 0, mModel->mJoints[i].mPosition.x, 
         0, 1, 0, mModel->mJoints[i].mPosition.y, 
         0, 0, 1, mModel->mJoints[i].mPosition.z, 
         0, 0, 0, 1); 
    

    これはOpenGLマトリックスですか? OpenGLマトリクスは異なる向きを持ち、そのレイアウトはDirectXで使用されるD3DXMATRIX/D3DMATRIXと完全に同じです。転置されたすべてのマトリクスを保存する必要がある場合を除きます。

    非転置変換行列:

    mat4 translation = mat4(
         1, 0, 0, 0, 
         0, 1, 0, 0, 
         0, 0, 1, 0, 
         x, y, z, 1); 
    

    そしてもちろん、非転置行列が逆の乗算の順序を使用します。

    mat4 combined = rotation * translation; 
    

    はまた、代わりに掛けるのは、単純に(最後の行をコピーすることができます非転置):

    mat4 combined = rotation; 
    combined.rows[3] = translation.rows[3]; 
    

    または列(転置)。

    はまた、この部分で:

    this->mOutput[i] = mTranslate * mRotate; 
    

    あなたは計算に逆変換の骨を含めるのを忘れていました。 Inotot逆骨変換スキンメッシュは "爆発"します。

    それは(転置行列)

    this->mOutput[i] = mTranslate * mRotate * mInverseMatrices[i]; 
    

    または(非転置用)でなければなりません。

    this->mOutput[i] = mInverseMatrices[i] * mRotate * mTranslate; 
    

    --EDIT--

    あなたが間違って共同階層変換を計算していることも可能です。

    { 
        MD5FrameJoint *mParent = &mAnimation->mFrames[mFrameID][mAnimation->mJoints[i].mParent]; 
    
        float4 rpos = rotate(mParent->mOrientation, _position); 
    
        mAnimation->mFrames[mFrameID][i].mPosition = rpos + mParent->mPosition; 
        mAnimation->mFrames[mFrameID][i].mOrientation = mParent->mOrientation * _orientation;       
    } 
    

    これは正常に行われていない方法です。

    ジョイントごとにローカル変換を計算します。

    this->localTransform = positionMatrix * rotationMatrix 
    

    計算の世界はオブジェクトの行列の掛け算がある親変換変換と子がルートノードの世界について

    this->worldTransform = parent->worldTransform * this->localTransform; 
    

    変換乗じて、すべての関節のために変換し、地元の変換(つまりは、周りのメッシュ変換します)。階層内のマトリックス(ANY行列は)コンポーネントをスケーリングしている場合

    root->worldTransform = worldMatrix * root->localTransform; 
    

    あなたスキームが正しく動作しません。

    これで問題が解決しない場合は、誰かがコードをデバッグする必要があります。私は無料でデバッグをしませんが、SOの "フリーランス"サービスを提供することは許可されていません(AFAIK)。だからあなたは他の誰かを見つけなければならないでしょう。

    もう一つは、 "白い点を使用して\"を指定する代わりに、アニメーションmd5形式を表示できるアプリケーションを使用し、正しく動作することが保証されている必要があります。あなたの白い点が正しい位置にあるという保証はありません。

    +0

    さて、私は逆行列を他の場所に乗算しています:) - とにかく行列の一部が転置され、他の転置されていない - ほとんどの問題を解決しました(まだいくつかの非正規化クォータニオンが関わっていると思います私はそれらを見つけることができると思う) – ZarakiKenpachi

    +0

    そう...私はそれを持っていると思う:)(それは今働いている... hooray!)。ありがとう!ありがとう!ポスト、それは私に多くの事をより明確に見せた:P。 – ZarakiKenpachi

    関連する問題

     関連する問題