hi everyone,

i'd like to know how to setup a skeletal animation, how to structure the necessary data practically. first, assimp gives me the data like this:

Code :struct Bone { mat4 offset; vector<pair<int, float>> vertexweights; }; struct Mesh { vector<vec3> vertices; vector<vec3> normals; ... vector<Bone> Bones; }; struct Scene { vector<Mesh> meshes; vector<Animation> animations; ... };

i know how to extract the geometry so that i can draw the model without bones, for each mesh i create a "drawarrays" call. but there are several things to keep in mind:

1. a "joint" (or "bone") has a offset matrix, it transforms from mesh space to "bind pose"

2. the order in which the joint matrices are multiplied is crucial

how i plan to do it: (vertex shader)

Code glsl:#version 450 core /* uniform */ /****************************************************/ layout (std140, binding = 1) uniform StreamBuffer { mat4 View; mat4 Projection; }; layout (std140, binding = 2) uniform BoneBuffer { mat4 Bones[256]; }; layout (location = 0) uniform mat4 Model = mat4(1); /****************************************************/ /* input */ /****************************************************/ layout (location = 0) in vec3 in_position; layout (location = 1) in vec2 in_texcoord; layout (location = 2) in vec3 in_normal; layout (location = 3) in vec3 in_tangent; layout (location = 4) in vec3 in_bitangent; layout (location = 5) in uvec4 in_boneindices; layout (location = 6) in vec4 in_boneweights; /****************************************************/ /* output */ /****************************************************/ out VS_FS { smooth vec3 position; smooth vec2 texcoord; smooth vec3 normal; } vs_out; /****************************************************/ mat4 Animation() { mat4 animation = mat4(0); vec4 weights = normalize(in_boneweights); for (uint i = 0; i < 4; i++) animation += Bones[in_boneindices[i]] * weights[i]; return animation; } void main() { mat4 Transformation = Model;// * Animation(); mat4 MVP = Projection * View * Transformation; gl_Position = MVP * vec4(in_position, 1); vs_out.position = (Transformation * vec4(in_position, 1)).xyz; vs_out.texcoord = in_texcoord; vs_out.normal = (Transformation * vec4(in_normal, 0)).xyz; }

so i need to send up to 4 references to joint matrices up to the vertexshader.

if a vertex need less than 4 joint matrices, then i'll fill the rest with a reference to the very first joint matrix which is by default mat4(1) --> to eliminate undesired effects (as a fallback). i a vertex needs more then 4 joint matrix references, then ... what ?

how to build these attribute data ?

vector<vector<unsigned int> indices_lists(vertexcount);

vector<vector<float>> weights_lists(vertexcount);

for (each bone of this mesh)

--> fill both arrays:

each array element belongs to e certain vertex, and is an array of needed joint references (index to uniform joint matrix + weight)

is this the "usual way" to do this or am i thinking a little too simple/complicated/weird ?

assuming thats rihgt, the next thing is to KEEP THE JOINT MATRIX ORDER, that means i have to rebuild these 2 arrays (of arrays of references to joints): how ?

i guess that i just have to sort the indices (to uniform joint matrices) ascending, and BEFORE that i recursively go through the scene node tree and add needed "bones" BEFORE i add their needed children (if any) ... correct, or wrong ?

-----------------------------------------------------

when done, and assuming thats correct (?), what data to i need on the cpu-side?

-- joint offset matrix array

-- array of the same size of type mat4, containing computed joint matrices (i have to send as uniform block)

-- animations

when computing animations, how to compute the mat4s ?

for each animation

-- for each "channel" (affecting exact 1 joint)

---- uniformJoints[..certain.index..] = jointOffsetMatrix[..certain.index..] * interpolatedKeys

.. where "interpolatedKeys" are pairs of vec3 location / quat rotation / vec3 scale

is this how its done ?

(i've searched for simple examples, could find anything [including model file] that is understandable .. this one is simply not transpaerent enough for me )

i appreciate every advice !!