javaandroidopengl-esopengl-es-2.0skeletal-animation

OpenGL skeletal animation logic


I am tryin to implement skeletal animation in OpenGL ES2 in Android, I have a JSON model exported from Blender using io_three , I can read from this file Bones array each one has Position as 3 floats array, quaternion rotation as 4 floats array and scale and an integer which is parent, also I has animation which has hierarchy list as I understand which handles each bone matrix every frame, each hierarchy has a parent and list of keys each key has same components as the bone, so I read many tutorials and made many tries but unfortunately I did not success, I need the logic explained simply. so I have a bone class each one has vectors and I can get the relative matrix for each bone then multiply it with the parent absolute matrix to get the absolute matrix of the bone then inverse it to get the inversed matrix, I can make same calculations for each key but I can not bind them together, I need to understand the relation between the bone and each frame. my problem is not with the code but with logic.


Solution

  • I will try to explain how to compute the animated skeleton at some t of your animation where t is between the start and end times of your entire animation.

    I can read from this file Bones array each one has Position as 3 floats array, quaternion rotation as 4 floats array and scale

    You must also be having the timing data for the above i.e. if you have say 17 frames in your animation, the time information for each frame. Assuming you have this or can obtain this data from io_three, you can compute the animation matrix. The more granular steps are:

    1. Find the position data for time t i.e. you find the 2 frames with times t1 and t2 such that: t1 < t < t2. Now you can compute the interpolated translation matrix.
    2. Similar to 1, compute the interpolated rotation and scale matrices.
    3. Now find the local animation matrix: A from the T, R, S matrices you just computed.
    4. Next multiply the local animation matrix with your bone inverse bind transform.
    5. Now multiply with the parent matrix, so that you have a cumulative animation matrix.

    You can see a sample of this kind of computation here: note that it is in ObjectiveC, using Assimp.

    You will do the steps 1 to 4 for each bone in your skeleton and you traverse from the root of the skeleton all the way down, which ensures that for each bone you have a cumulative animation matrix. You start with the IdentityMatrix as the parent matrix.

    As you have to start with the root of the skeleton, you have to also know that root. Either your data provides the root of the skeleton or else you have to derive the skeleton root. If you have a tree of bone nodes, then the node with the lowest depth will be root!

    Once you have the animation matrix for each bone, you also need to know the number of bones that influence each vertex and the weighting of that influence. Then you can compute the deformed vertex, either on the CPU or the GPU. Note that both have their pros and cons.

    A much better explanation of skeletal animation but with Assimp library is described in this post's top answer.

    Overall, while the overall logic of skeletal animation is simple; the hard part is in navigation of your data structure which contains all that data and building the correct animation matrices, identification of the root node of the skeleton and the mapping from vertices to bone/animation data.