gpt4 book ai didi

c++ - 丢失蒙皮网格

转载 作者:行者123 更新时间:2023-11-28 00:57:01 24 4
gpt4 key购买 nike

我有点迷路了

我终于有时间在 GPU 上使用 MD5 处理蒙皮网格 - 通过矩阵,但我绝望地无法得到正确的结果(这太他妈的错了)!

我的做法是:

  • 载入MD5MESH文件

  • 构建 bind-pose 网格(这一步正确完成 - 几何形状正确)

  • 像这样创建 bindpose 和 inverse 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;
    }

Mesh + anim 文件是正确的(将它们导出并导入到 3d 建模软件,有效!)

现在我正在测试我的数学库是否正常,到目前为止它看起来不错(矩阵求逆很好,四元数乘法也很好,四元数矩阵经过测试,...)

请不要指点我任何文章,我已经打开其中一些(包括那些在 GPU 上使用矩阵 + 源代码进行 MD5 蒙皮的文章)并找出问题所在,到目前为止,代码看起来几乎完全一样像我的。这将是一些微小的细节。

有人看到大师在哪里吗?

最佳答案

(it is so damn wrong)!

一图胜千言。你没有发图片。那么,您期待什么?

 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;

--编辑--

您可能错误地计算了 union 层次结构变换。

{
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;

对于根节点,世界变换是对象矩阵(在周围平移网格)和局部变换的乘积。

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

如果层次结构中的矩阵(任何矩阵)具有缩放组件,您的方案将无法正常工作。

如果这没有帮助,那么您需要找人来调试您的代码。我不免费调试,但不允许(AFAIK)在 SO 上提供“自由职业”服务。所以你必须找到其他人。

另一件事是,您必须使用可以显示动画 md5 格式并保证正确执行的应用程序,而不是使用“白点来指示“它应该在哪里””。否则无法保证您的白点位于正确位置。

关于c++ - 丢失蒙皮网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10520901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com