   hierarchy animation
  I'm having trouble animating the joints.Given the following:struct bindpose_joint{   int parent, sibling, child; // //   vec4 world_rotation;   //   vec4 world_position;   // //   vec4 local_rotation;   // <--- all of these were given from source file   vec4 local_position;   //   vec4 local_scale; //    mat4x4 final_transform;   // <--- I added this};struct animation_joint{   vec4 local_rotation;   //   vec4 local_position;   // <--- all of these were given from source file   vec4 local_scale; //};animation_joint frames[numframes][numjoints];I create a chain of matrices from the bindpose_joints::local_position :mat4x4 transl = mat4x4(childjoint.local_position);childjoint.final_transform = parentjoint.final_transform * transl;and that looks fine when I render it (skeleton standing with arms out to the side with all of the joints in the right place in object space).However, when I try to do the exact same thing with the joints in frame X (creating a chain of matrices out of animation_joint::local_position), all of frame X's joints are around the origin.Is this the correct way to animate joints/bones? Do I need to multiply bindpose_joint's data with the animation_joint's? Or is the frame data just incorrect (all the animation_joint::local_position components are near zero)? Or am I just interpreting the frame joint data incorrectly?   
  I think your snipped is missing the rotation part, can you post that too?Something else that stands out is that the hierarchy (parent-child relation) is redefined for every frame. Can you check that these are still valid for all frames > 0?What is in the world_rotation/position fields? Can you dump them into the final_transform and check if things improve?   ;Quote:Original post by Ohforf sakeI think your snipped is missing the rotation part, can you post that too?So, I'm not all that familiar with animating. I only used the bindpose_joints::local_position when creating the chain and it looked fine. Why and where do I need the rotation part? http://www.cyberkreations.com/kreationsedge/?page_id=29 didn't mention anything about rotations(in the paragraph right after the bone struct/class definition)Quote:Original post by Ohforf sakeWhat is in the world_rotation/position fields? Can you dump them into the final_transform and check if things improve?Same as the above question. Some of the sites I looked at didn't mention using the world_rotation and position when animating the joints (they did when talking about skinning). Why and where do I need to incorporate the world_rotation/position?Quote:Original post by Ohforf sakeSomething else that stands out is that the hierarchy (parent-child relation) is redefined for every frame. Can you check that these are still valid for all frames > 0?You mean if they're still indexed/positioned correctly in every frame? I believe so.   ;  I'll check the link when I get home, but usually the rotation is the most interesting part. Imagine a simple walking animation. The displacement of the feet is not achieved by variations of the translation, but by changing the rotation of the bones. E.g. your upper leg rotates forward, your lower leg rotates backward, and as a result your foot rises into the air.Not using the rotation will most likely be the problem in your case.The initial pose might be unaffected because in some animations the initial rotation for all bones is zero.About the world_location/rotation, I suspect them to contain what you are trying to compute, so it might be worth checking them out to see, if you are having the same trouble with them. But try to get the rotation stuff (the thing I mentioned above) working first.   ;Quote:Original post by 16bit_portWhy and where do I need the rotation part? http://www.cyberkreations.com/kreationsedge/?page_id=29 didn't mention anything about rotations(in the paragraph right after the bone struct/class definition)The paragraph right after the bone structure is somewhat misleading. However if you read on, you will notice that he uses quaternions for his rotations and that he also shows how to use them. That is, he posts the code but doesn't touch the topic in his text (at least in the parts I read).   ;  I think it would help me out a lot if I understood what those different rotations/scales/translations mean. Like when would I use the bindpose::world rotation/position as opposed to the bindpose::local position/rotation. Do I used both of them to build the initial pose?"The initial pose might be unaffected because in some animations the initial rotation for all bones is zero."The bindpose::world_rotation and bindpose::local_rotation that I've looked at have values in them. I guess when I rendered them (the joints), it seemed like they were in the right position but are actually inaccurate/incorrect (since I'm not using the rotations).   ;  What part is giving you trouble the skeletal animation or the skinning using the skeleton? Are you sure you have all the the skeleton/animation data needed from the file?   ;Quote:Original post by NumberXaeroWhat part is giving you trouble the skeletal animation or the skinning using the skeleton? Are you sure you have all the the skeleton/animation data needed from the file?Skeletal animation. I'm pretty sure I have all of the data. I'm just not really sure what I should be doing with some of the data (as addressed in the previous posts)   ;  This may be different here or there, you may use matrices, or store things different, sometimes the words joints and bones are used interchangably, I call it joints, bone to me would be the part between two joints, I use joints because the bone idea confuses me. The main parts are- Final Skeleton (used the generate the skinning matrix)- Animation Skeleton (base skeleton pose for the specific animation)- Animation Data (channel data sometimes called track data)The general idea (not actual code)...You have a Skeleton, this is a heirarchy of parent child joints. If it were a snake, you would have a head joint, it would have a child joint, and the child would have a child, the tail, etc. This would look like two bones (3 joints)So, SkeletonSkeleton {SkeletonJoint joints[kMaxSkeletonJoints];// update this from the active animation data// these joints are the characters "rig", properly parented, indexable by the weight/joint index, // with root at index [0], and all children  at some index > 0}Each of these joints hasSkeletonJoint {SkeletonJoint* parent;// parent == NULL, root joint, begin updating from thereSkeletonJoint* children[kMaxChildJoints]// animation creates these from animating the skeleton, generating interpolated versions of thesevec3 local_pos;vec3 local_scale;quat local_rot;// this.world_ = parent.world_ combined with  this.local_ vec3 world_pos;vec3 world_scale;quat world_rot;Mat4 finalWorldMatrix;// computed by combining world_ partsMat4 invBindPoseMatrix;// from file, usually part of skinning infoMat4 skinMatrix;// updated each frame, skinMatrix = finalWorldMatrix * invBindMatrixUpdate()// make sure this is called from root joint down, parent == NULL{if(parent)// should be updated first{vec3 parentWorldPos = parent->world_pos;vec3 parentWorldScale = parent->world_scale;vec3 parentWorldRot = parent->world_rot;this->world_rot = parentWorldRot * this->local_rot;this->world_pos = (parentWorldRot * (this->local_pos * parentWorldScale)) + parentWorldPosthis->world_scale = parentWorldScale * this->local_scale}else{world_pos = local_pos;world_scale = local_scale;world_rot = local_rot;}mat3 rm = world_rot.ToRotationMatrix();mat3 sm = FromScale(world_scale)finalWorld = Mat4FromMat3AndT(rm * sm, world_pos)skinMatrix = finalWorld * invBindPoseMatrix}}You would use skeleton joints skinMatrix applied to the vertices, either on cpu or gpu to do the skinning using the weights/jointIndex pair.Given a time along the animation generate an interpolated version of the animations base skeleton.JointPose {vec3 pos;vec3 scale;quat rot;}SkeletonPose {Array<JointPose> joints;// frozen animation start pose, from animation file, variable length, animations dont always change every joint}Animation {float currentTime// add deltaTime to this to advance the animationSkeletonPose basePose;// animate all or some of these to where it should be based on "currentTime"AnimationChannel channels[?];// sometimes called tracks}So an animation has a base pose for the animation, for a duck idle animation, the character might havetheir knees bent, and hands near the floor. This will be the starting point of the animation, think of it asframe 0, depending on the current animation time, you generate a new result pose for this time. Dependingon the anmation channel data all or some of these joints have their pos, scale, or rot replaced by the interpolation result. Animating to a result pose allows different animations to generate SkeletonResultPose's which can then be blended or layered togetherSkeletonResultPose {JointPose jointPose[kMaxSkeletonJoints];// result of animating}Skeleton::Update(float dt){SkeletonResultPose result;// the skeleton for this frame time of the active animationactiveAnimation->Update(dt, result){result = basePose;// copy base, start with the base pose, all or some of it is replaced by channel datacurrentTime += dt;// advance the animationactiveAnimation->ComputeFromChannels(currentTime, result)// change parts of the result (base) or all{FOR EACH CHANNEL// could be as much as num skeleton joints * 3 (rot, tran, scale) i supposeChannel* ch = this->channels;index = ch->targetIndex;// channels data targets some joint// change thesevec3& t = result.jointPose[index].pos;quat& r = result.jointPose[index].rot;vec3& s = result.jointPose[index].scale;ch->Update(currentTime, r, t, s){// channel generates interpoalted rotation, translation or scale, channel knows, we dont// pass all 3, it modifies which ever it targets// Example: determine interpolated "t" at "currentTime (0.5)"{// find previous key frame number// from sample channel time dataFOR EACH TIME SAMPLE (i = 0; i < numKeyTime - 1; ++i)if(time >= keyTime && time < keyTime)<br><span class="cpp-keyword">return</span> i;<span class="cpp-comment">// prevFrame</span><br><br><span class="cpp-comment">// nextFrame index = prevFrame index + 1</span><br><br><span class="cpp-comment">// got frame before and after time (0.5), now interpolate</span><br><br>t =  <span class="cpp-comment">// interpolated value between data[prevFrame] and data[nextFrame]</span><br><span class="cpp-comment">// channel may just change t.x or s.z, usually all of r, but replaces something</span><br>}<br><span class="cpp-comment">// or r</span><br><span class="cpp-comment">// or s</span><br>}<br>}<br>}<br><br><span class="cpp-comment">// now we have an resulting skeleton pose created by animation in "result"</span><br><br><span class="cpp-comment">// optional: gen another skeleton pose from another animation, blend them, creating a third pose</span><br><br><span class="cpp-comment">// update the local of the final skeleton using "result" from active animation</span><br><span class="cpp-keyword">FOR</span> EACH JOINT <span class="cpp-comment">// simply copy result to final skeleton local</span><br><span class="cpp-keyword">this</span>-&gt;joints<span style="font-weight:bold;">.local_pos = result.jointPose<span style="font-weight:bold;">.pos;<br><span class="cpp-keyword">this</span>-&gt;joints<span style="font-weight:bold;">.local_scale = result.jointPose<span style="font-weight:bold;">.scale;<br><span class="cpp-keyword">this</span>-&gt;joints<span style="font-weight:bold;">.local_rot = result.jointPose<span style="font-weight:bold;">.rot;<br><br><span class="cpp-comment">// compute the matrices from the resulting pieces</span><br><span class="cpp-keyword">FOR</span> EACH JOINT  <span class="cpp-comment">// see above</span><br><span class="cpp-keyword">this</span>-&gt;joints<span style="font-weight:bold;">.Update()<span class="cpp-comment">// gen finalWorld, build new skinMatrix from it</span><br><br><span class="cpp-comment">// do skinning with joints<span style="font-weight:bold;">.skinMatrix and wight</span><br>}<br><br></pre></div><!–ENDSCRIPT–><br><br>thats the general idea/order of things, maybe it will help you organize what youve got.<br>;  I think what confused me was the fact that when I render the bindpose_world and bindpose_local data, they came out to be exactly the same, so I wasn't sure which one was used for what and why there was a need for the other. And that I thought that I need both the bindpose_world and bindpose_local to do skeletal animation (not skinning).But it seems that the bindpose_world is for skinning only, while the bindpose_local is used as a base and when combined with the offset data in the frames, it produces a joint in world position.Any corrections to what I've concluded is greatly appreciated!Thanks, NumberXaero and Ohforf sake. Rate +.   