-1

I am trying to make a skeletal animation using OpenGL using my own FBX SDK binary files.

What I've done is that I'm reading values from an FBX file and writing out the values I need to an binary file for another program. The info I get for the animation is the Inverse Bind pose, which vertices the joints are controlling and how much weight/influence the vertex has for each joint. I also baked the animation so that the set keyframes are on each frame in Maya, to keep it simple for now. I then read the translation,rotation and scale for each join every frame. I write out all these values in binary and read them in another program, and the values that I read are correct when I compare it to the program that reads the values.

To update the animation I've done a simple for loop that goes through all the joints and updates the weight values and makes the new transform pose like so:

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

the struct skelShader is a struct I send to the GPU, it has the values that should be needed for the animation to work:

struct skelShader {

int indexPos[4];
float indexInfluence[4];
glm::mat4 currentJointTrans[100];


};

This is my vertex shader:

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

If I'm not using any animation techniques, the mesh is correct.

However, when I apply this code to the render function, together with the code that increases and resets the current keyframe, the mesh looks like this:

Animation update

The mesh is moving slightly so it does have some movement. I've tried changing around the matrix multiplication for the currentJointTrans, so that the bindPose goes first, but it only makes the mesh disappear. Does anyone know what the problem could be?

If needed, I can send more code and/or debugging values of the matrices that's needed.

This is how the model looks without the animation from the update function and vertex shader (Ignore the texture and the tiny cube under the model):

Complete mesh without animation applied

genpfault
  • 51,148
  • 11
  • 85
  • 139
Haplue
  • 70
  • 9
  • http://imgur.com/a/UXR8S Here are some values from debugging in visual studio where I get the inversed bind pose matrix and a picture of the bind pose values within Maya. – Haplue May 15 '17 at 12:48

1 Answers1

0

Best guess?

It looks like one of your matrices are transposed. OpenGL is column-major order and so is FBX, so when using glUniformMatrix4fv make sure to pass GL_FALSE.

In situations like these, I will use gDebugger (hard to find) or a similar OpenGL debugger (nVidia NSight, AMD bought gDebugger and replaced it twice) to grab a frame or stop on a glDrawElements call to make sure that the GL state is correct and to check the uniform values.

Another approach is to force identity matrices for the bones and one by one add each bone into the hierarchy from the root until you get an error, fix the error and continue.

James Poag
  • 2,320
  • 1
  • 13
  • 20
  • I've used GL_FALSE but it seems it is still incorrect. I've also heard from people that since Maya is using OpenGL, the FBX SDK does not need any transposing since it's the same API. I also noticed that the bindpose and transposes for each frame were incorrect before, since when you put the data from an FbxAMatrix in to an FbxVector4, the data on [3] from the matrix (the w value) became 1. So I fixed those with 2 simple for loops. I will try to get some graphical debuggers fixed so that I can see what's going on in the GPU soon. Thank you for your answer, I will test the methods you mentioned – Haplue May 15 '17 at 14:43
  • I am beginning to believe that it is the weights that are incorrect. I noticed I only go through the first 4 vertices every time I loop through the bones to update the translations on every frame. I'll write an update if I find out I come up with something – Haplue May 15 '17 at 15:02