丢失了皮肤网格
Lost with skinned meshes
我有点迷茫,
我终于有时间在 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 个权重不会造成麻烦,因为目前我在简单的镶嵌四边形上只有 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 皮肤(并找出问题所在,到目前为止,代码看起来几乎和我的一模一样。这将是一些微小的蹩脚细节。
有人看到上师在哪里吗?
(这太该死的错误了(!
一张图片胜过千言万语。你没有发布图片。那么,你期待什么?
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;
对于根节点,世界变换是对象矩阵(围绕网格转换(和局部变换的乘法。
root->worldTransform = worldMatrix * root->localTransform;
如果层次结构中的矩阵(任何矩阵(具有缩放组件,则您的方案将无法正常工作。
如果这没有帮助,那么你需要找人来调试你的代码。我不免费进行调试,但不允许 SO 上的 (AFAIK( 提供"自由职业"服务。所以你必须找其他人。
另一件事是,您必须使用可以显示动画 md5 格式并保证正确执行的应用程序,而不是使用"白点来指示它应该在哪里"。否则,无法保证您的白点位于正确的位置。
- 使用对象文件读取三角形数据网格
- 如何从 Skia 路径几何体中获取网格?
- CGAL:如何创建填充边界曲线的曲面网格?
- 检查 2D 网格的某个元素是否与另一个元素共享对角线、水平线或垂直线
- 创建具有两个视口的Qt3D C++场景,其中显示适当的不同网格
- 如何从 3D 曲面网格中删除自相交三角形?
- 在均匀网格中处理碰撞
- 更改高度贴图,使其在 4x4 网格上显示 16 个 hieghtmap
- 用于查找网格中最短路径的算法
- 循环通过网格获取温度,但不知道如何告诉程序停止循环
- 使用 glvertex4i 传递网格面索引时的顶点着色器错误
- 如何使用 sdl2 快速绘制像素网格?
- 如何使用条件计算 3D 网格中从一个点到另一个点的所有路径
- 使用 MFC 的表/网格
- 是否可以制作没有内部分割的cgal 3d多多马因网格?
- 获取网格中心的屏幕位置
- ASIMP 模型加载不会加载所有网格
- C++中的多维数据集:从 std::vector 的 2D 数据到 std::vector 的 2D 网格的最干净方法?
- 如何从C++而不是虚幻编辑器中添加静态网格体组件的值?
- 从 CGAL 3D 网格生成中获取顶点坐标的 -6.27744e+66:mesh_implicit_sphere示例