C++ 使用自己的FBX二进制格式的骨骼动画

C++ 使用自己的FBX二进制格式的骨骼动画,c++,animation,opengl,fbx,C++,Animation,Opengl,Fbx,我正在尝试使用OpenGL和我自己的FBX SDK二进制文件制作骨骼动画 我所做的是从FBX文件中读取值,然后将需要的值写入另一个程序的二进制文件中。我为动画获得的信息是反向绑定姿势,关节控制哪些顶点,以及顶点对每个关节的权重/影响有多大。我还烘焙了动画,以便设置的关键帧位于Maya中的每一帧上,从而暂时保持简单。然后我阅读每一帧的平移、旋转和缩放。我用二进制写下所有这些值,然后在另一个程序中读取它们,当我将它与读取这些值的程序进行比较时,我读取的值是正确的 为了更新动画,我做了一个简单的for

我正在尝试使用OpenGL和我自己的FBX SDK二进制文件制作骨骼动画

我所做的是从FBX文件中读取值,然后将需要的值写入另一个程序的二进制文件中。我为动画获得的信息是反向绑定姿势,关节控制哪些顶点,以及顶点对每个关节的权重/影响有多大。我还烘焙了动画,以便设置的关键帧位于Maya中的每一帧上,从而暂时保持简单。然后我阅读每一帧的平移、旋转和缩放。我用二进制写下所有这些值,然后在另一个程序中读取它们,当我将它与读取这些值的程序进行比较时,我读取的值是正确的

为了更新动画,我做了一个简单的for循环,该循环遍历所有关节并更新权重值,并使新的变换姿势如下所示:

for (int i = 0; i < skeleton.size(); i++) {

    for (int k = 0; k < 4; k++) {
        globalSkelInfo.indexPos[k] = skeleton[i]->indexPos[k];
        globalSkelInfo.indexInfluence[k] = skeleton[i]->indexInfluence[k];
    }
globalSkelInfo.currentJointTrans[i] = skeleton[i]->transformMat[currentFrame] * skeleton[i]->globalBindPosMat; 
  }
这是我的顶点着色器:

void main() {

vec4 finalModelPos = vec4(0.0);
vec4 finalNormal = vec4(0.0);

for (int i = 0; i < 4; i++) {

    mat4 jointTrans = currentJointTrans[indexPos[i]];
    vec4 posePos = jointTrans * vec4(vertex_position, 1.0);
    finalModelPos += posePos * indexInfluence[i];

    vec4 worldNormal = jointTrans * vec4(vertex_normal, 0.0);
    finalNormal += worldNormal * indexInfluence[i];

}

gl_Position = MVP * finalModelPos;
outNorm = finalNormal.xyz;
outUVs = vertex_UV;
}
void main(){
vec4最终模型=vec4(0.0);
vec4最终正常值=vec4(0.0);
对于(int i=0;i<4;i++){
mat4 jointTrans=currentJointTrans[indexPos[i]];
vec4 posePos=jointTrans*vec4(顶点位置,1.0);
最终模型+=posePos*指数影响[i];
vec4 worldNormal=jointTrans*vec4(顶点_法线,0.0);
最终正常值+=世界正常值*指数影响[i];
}
gl_位置=MVP*最终模型;
outNorm=最终正常值.xyz;
outUVs=顶点_UV;
}
如果我未使用任何动画技术,则网格是正确的

但是,当我将此代码应用于渲染函数时,以及增加和重置当前关键帧的代码,网格如下所示:

网格正在轻微移动,因此它确实有一些移动。我尝试过改变currentJointTrans的矩阵乘法,这样bindPose会先进行,但它只会使网格消失。有人知道问题出在哪里吗

如果需要,我可以发送更多需要的代码和/或调试矩阵值

这是在没有来自更新函数和顶点着色器的动画的情况下模型的外观(忽略模型下的纹理和小立方体):

最佳猜测

看起来你的一个矩阵被转置了。OpenGL是列主顺序,FBX也是,因此使用
glUniformMatrix4fv
时,确保传递GL\u FALSE

在这种情况下,我将使用gDebugger(很难找到)或类似的OpenGL调试器(nVidia NSight,AMD购买了gDebugger并替换了两次)获取一个帧或停止一个GLDrainElements调用,以确保GL状态正确并检查统一值


另一种方法是强制骨骼的标识矩阵,并逐个将每个骨骼从根添加到层次结构中,直到出现错误,修复错误并继续。

以下是在visual studio中调试的一些值,我在其中获得了反转的绑定姿势矩阵和Maya中绑定姿势值的图片。我使用了GL_FALSE,但它似乎仍然不正确。我还听说,由于Maya使用OpenGL,FBX SDK不需要任何转换,因为它是相同的API。我还注意到,以前每帧的bindpose和Transpose都是不正确的,因为当您将FbxAMatrix中的数据放入FbxVector4时,矩阵[3]上的数据(w值)变为1。所以我用2个简单的for循环修复了这些问题。我将尝试修复一些图形调试器,以便很快看到GPU中发生了什么。谢谢你的回答,我将测试你提到的方法。我开始相信重量是不正确的。我注意到,每次循环遍历骨骼时,我只遍历前4个顶点,以更新每个帧上的平移。如果我发现我有什么想法,我会写一个更新
void main() {

vec4 finalModelPos = vec4(0.0);
vec4 finalNormal = vec4(0.0);

for (int i = 0; i < 4; i++) {

    mat4 jointTrans = currentJointTrans[indexPos[i]];
    vec4 posePos = jointTrans * vec4(vertex_position, 1.0);
    finalModelPos += posePos * indexInfluence[i];

    vec4 worldNormal = jointTrans * vec4(vertex_normal, 0.0);
    finalNormal += worldNormal * indexInfluence[i];

}

gl_Position = MVP * finalModelPos;
outNorm = finalNormal.xyz;
outUVs = vertex_UV;
}