2012-05-09 54 views
0

我有點失去了,失去了與蒙皮網格

我終於有時間上的蒙皮網格與MD5對GPU的工作 - 通過矩陣,我desparately不能得到正確的結果(它是如此該死的錯)!

因此,這裏是我做的:

  • 裝入MD5MESH文件

  • 構建收口姿勢網(這一步是正確完成 - 幾何是正確的)

  • 像這樣創建bindpose和反向綁定(注意關節用作加載,未由父級轉換,它們是否需要?):

    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個權重現在不能引起麻煩,因爲目前我在簡單的鑲嵌的四現場只需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建模軟件,工程!)

現在我測試我的數學函數庫是否是好的,到目前爲止,它似乎不錯(矩陣求逆,四元數乘法,四元數矩陣測試,...)

請不要指向我的任何文章,我已經有一些(含。那些MD5皮膚與矩陣+源代碼的GPU)打開並找出什麼是錯的,到目前爲止代碼似乎幾乎完全一樣。這將是一些微小的蹩腳細節。

任何人都可以看到古茹在哪裏?

+0

MD5是最常見的哈希算法。我刪除了該標籤。 – rekire

回答

3

(這是該死的錯誤)!

一張照片勝過千言萬語。你沒有發佈圖片。那麼,你期望什麼?

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; 

你忘了包括反骨轉換成計算。 Withotu逆骨轉換皮網將「炸燬」。

應當(轉置矩陣)

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

或(對於非轉置)。

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

- 編輯 -

這可能是你沒有正確地計算關節層次轉變。

{ 
    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提供「自由職業者」的服務。所以你必須找到其他人。

另一件事是,而不是使用「白點,表示\」它應該是\「」,你必須使用的應用程序,可以顯示動畫MD5格式,保證了正確的做到這一點。不保證你的白點在正確的位置。

+0

好的,我在其他地方得到了逆矩陣乘法:) - 無論如何一些矩陣被轉置,而其他非轉置 - 它解決了大部分問題(仍然有小的問題(我認爲涉及一些非標準化的四元數),但我想我可以設法找到他們) – ZarakiKenpachi

+0

所以...我想我知道了:)(它現在正在工作......萬歲!)。感謝!非常好!後,它讓很多事情看起來更加清晰:P。 – ZarakiKenpachi