2012-05-09 24 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