tag:blogger.com,1999:blog-3759630438511440621.post2063998184018059828..comments2018-09-27T01:38:30.724-07:00Comments on AnimMotion: What Is a Binding Pose in Character Animation?Peyman Massoudihttp://www.blogger.com/profile/03391039797831648545noreply@blogger.comBlogger17125tag:blogger.com,1999:blog-3759630438511440621.post-66968760504055217312016-01-14T10:02:57.703-08:002016-01-14T10:02:57.703-08:00For screen shots, you can upload them on any third...For screen shots, you can upload them on any third party website like DropBox or your Google Drive and share the link here.<br /><br />Regarding the codes, from what I saw so far, the issue is in the way you are calculating the final matrix. It should be something like this:<br /><br /><br />FinalTransformation = Inv(M1) * T1 * Inv(M2)*T2 * Inv(M3) * T3Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-51214305006683580362016-01-05T08:09:46.908-08:002016-01-05T08:09:46.908-08:00Explanation of the code above:
To visualize the ...Explanation of the code above:<br /> To visualize the pose correctly I Need two matrices for each bone: 1. WorldMatrix, 2. OffSetMatrix<br /><br /> 1. World Matrix for each bone is the Transformation Matrix of the bone (using XYZ degree) influenced by the matrices parents in hierarchy. Say if we have Transformation matrices of upperPart, middlePart and lowerPart a finger as T1, T2, T3, then Tranfromation of the upperPart after applying hierarchy: T = T1*T2*T3<br /><br />2. OffSetMatrix is calculated using the inverse of the bindpose Matrices as following: say we have M1, M2, M3 as the Bindpose Matrix of upper, middle and lower part of a finger, then OffSetMatrix of UpperPart of the finger: M = Inv(M3)*Inv(M2)*Inv(M1) <br /><br />Then the tranfromation Matrix which should be applied to a vertex has the following Format: TrV=T*M<br /><br />Regarding the Screen shot, I dont knwo how can I include this Screen shot here. Can you please Show me the way?Amin Dadgarhttps://www.blogger.com/profile/14820731648634073099noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-52166068669711909562016-01-05T07:57:25.616-08:002016-01-05T07:57:25.616-08:00Dear Peyman;
Thanks for the post.
I should say I...Dear Peyman;<br />Thanks for the post. <br /><br />I should say I have no Animation in blender. I think this is one part of my Software which makes confusion.<br /><br />What I have is just a still mesh (at ist rest pose), together with rigged Information which means: weights, indices of weights and bind pose Matrix. <br /><br />Regarding the way I calculate my bone Transformation Matrices I can write it as follow:<br /><br />lets consider one pose only for now. But considering number of poses for Animation has the similar principle:<br /><br />1. I assign a Rotation to each limb: XYZ degrees <br /><br />2. Then I calculate Transformation matrices of each limb (in world space)<br /><br />3. Then I return the Bindpose Matrices for each limb<br /><br />4. within a method called HierarchyApplied(), I apply These Transformation to all childeren of the limbs, as following:<br /><br />vector Posture1Hand::HierarchyApplied(HandSkltn HNDSKs, vector BindPoseMatrices, string test){<br /> vector WorldMatrices; WorldMatrices.resize(HNDSKs.GetLimbNum());<br /> vector OffSetMatrices; OffSetMatrices.resize(HNDSKs.GetLimbNum());<br /> vector Matrices; Matrices.resize(HNDSKs.GetLimbNum());<br /><br /> //non Hierarchical Matrices<br /> for (unsigned int i = 0; i < Matrices.size(); i++){<br /> WorldMatrices[i] = newPose[i].getModelMatSkltn(HNDSKs.GetLimb(i).getLwCenter());<br /> OffSetMatrices[i] = glm::inverse(BindPoseMatrices[i]);<br /> }<br /> for (unsigned int i = 0; i < Matrices.size(); i++){<br /> vectorchilderen = HNDSKs.GetLimb(i).getChildren();<br /> for (unsigned int j = 0; j < childeren.size(); j++){<br /> WorldMatrices[childeren[j]->getId()] = WorldMatrices[i] * WorldMatrices[childeren[j]->getId()];<br /> OffSetMatrices[childeren[j]->getId()] =(BindPoseMatrices[childeren[j]->getId()])*OffSetMatrices[i] * glm::inverse(BindPoseMatrices[childeren[j]->getId()]);<br /> }<br /> }<br /> for (unsigned int i = 0; i < Matrices.size(); i++){<br /> Matrices[i] = OffSetMatrices[i]*WorldMatrices[i];<br /> }<br /><br /> return Matrices;<br />}<br /><br /><br /><br />Amin Dadgarhttps://www.blogger.com/profile/14820731648634073099noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-81616856012089754622015-12-22T09:18:17.377-08:002015-12-22T09:18:17.377-08:00Hi Amin,
The way you are calculating the bone tra...Hi Amin,<br /><br />The way you are calculating the bone transformation can cause plenty of issues specially on interpolations and I'm not sure how you are calculating the matrices and how the transformation key frames are stored in the keyframes. Are they store in their parent space? Are they stored in their corresponding binding pose space or you are using the keyframed bone transformation in the modelling space. All can lead you to calculate the bones transformation in the hierarchy differently.<br /><br />You can send me some part of your hierarchy matrix calculation codes and a screen shots from the correct animation in blender, corrupted animation in your own app and the character in binding pose. I can help you more this way.<br /><br />Also try to find out that in what space the animation transformation data is stored. That can help you much.Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-78989239871161568202015-12-22T06:29:40.014-08:002015-12-22T06:29:40.014-08:00Dear Peyman,
Thanks for your reply.
Yes you wer...Dear Peyman,<br /><br />Thanks for your reply. <br /><br />Yes you were right. Actually after detailed Investigation of the Loader data struture, I could return the binding pose data of the skeleton.<br /><br />However, I applied the inverse of the matrices to the bone Transformation. But I did not get what I wanted. Actually this time when I apply the bind pose matrices to the rest pose, then I will not get a correct mesh!<br /><br />This makes me believe that, what I said from the first is more correct in my case. That is, I do not Need bind pose matrices, since the functionaliy of These matrices implicitly is there (e.g. in the steps I have already stated). because for Animation I use my own set up of Skeleton (e.g. not the blender one). so for each bone Transformation i already transform the bone to the origin, calculate Tr Mat, and apply the hierarchy and Skin the correspounding Vertices.<br /><br />Please tell me your say.<br />Amin Dadgarhttps://www.blogger.com/profile/14820731648634073099noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-280438176333624452015-12-21T08:59:00.688-08:002015-12-21T08:59:00.688-08:00Hi Amin,
Unfortunately I haven't worked with ...Hi Amin,<br /><br />Unfortunately I haven't worked with FBXSDK before but every skeletal animation exporter have to export the binding pose in their respective file. So there should be a method which can load the binding pose data. From the names of the methods above, I think non of them are responsible to obtain the binding pose transforms.<br /><br />If the class you're working with is an abstract one then you should implement it yourself or find another class in the SDK which is implementing it.<br /><br />At the worst case, if you don't find any method to load the binding pose, you can export a one frame animation from the DCC tool (blender here) with the binding pose enabled and use this animation data as the binding pose in your application. BTW this technique is not recommended since the binding pose is surely stored in the skeleton data structure you are already using.Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-49397943886756090672015-12-19T09:31:37.080-08:002015-12-19T09:31:37.080-08:00The point is that, with the loader I have, I can n...The point is that, with the loader I have, I can not instantiate its abstract class related to the above methods (the class seems to be incomplete). I would be glad if you could show the way I can use FBX sdk.<br />Amin Dadgarhttps://www.blogger.com/profile/14820731648634073099noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-43894677601932274602015-12-19T08:49:39.729-08:002015-12-19T08:49:39.729-08:00Hi Peyman,
Thank you for the informative response...Hi Peyman,<br /><br />Thank you for the informative response. I now understand why I need such a matrix.<br /><br />Do you know how should I access that matrix from FBXSDK. I also have a FBXleader which imports the FBX data to c++, I am abit confused which one of them could be the Bind Pose matrix of the bone:<br /><br />const Math::V3View& globPos() const;<br />const Math::RotMat& globOrient() const;<br />const Math::RigidTransform& globTransf() const;<br />const Math::RigidTransform& parentToProximal() const;<br />const Math::RigidTransform& proximalToDistal() const;<br />Math::RigidTransform distalToProximal() const;<br />Amin Dadgarhttps://www.blogger.com/profile/14820731648634073099noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-88075295762427761942015-12-18T08:37:48.845-08:002015-12-18T08:37:48.845-08:00Hi Amin,
So it seems that you have skinned a mesh...Hi Amin,<br /><br />So it seems that you have skinned a mesh in blender and imported it in a custom 3D real time application based on D3D or OpenGL?! if it's true then you need to consider the binding pose to obtain the final transformation of the vertices in modelling space. The hand squash pose is likely because of the binding pose. The rigger might have scaled the bone to put it in the right place in the mesh.<br /><br />When you create a bone in a DCC tool like Blender, it has a default direction and size. The rigger changes its direction and size to put it in the right position in the mesh body. This extra transformation is called binding pose and should not be applied to final vertices positions while skinning. You need binding pose to find the exact world transformation of the bones but it should not be applied to the vertices final transformations.<br /><br />So after you calculated the bones matrices in the mesh modelling space, you need to deduct the binding pose from each bone matrix, like this:<br /><br />Final_Bone_Matrix_For_Skinning = BindingPose.Inverse * BoneMatrix<br /><br />Each bone has a binding pose. You have to multiply the inverse binding pose of each bone by the bone transformation matrix. Note that the BoneMatrix and BindingPose matrices here are considered to be in mesh's modelling space.Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-72737334273098597822015-12-18T06:36:48.075-08:002015-12-18T06:36:48.075-08:00Hi, I have a question regarding animation:
1.I h...Hi, I have a question regarding animation:<br /><br /><br />1.I have a Hand mesh which I want to animate.<br /><br /><br />2.I have the Skeleton which can be hierarchically animated.<br /><br /><br />3.My mesh is also weighted in Blender. So each vertex has 4 associated bones to be affected by.<br /><br /><br />4.When I apply the Animation of my Skeleton to the mesh, the hierarchy is applied. (so the hierarchy of the mesh, matches the hierarchy of the Skeleton).<br /><br /><br />So far so good, now question: the fingers look to be stretched (its like the fingers smashed by a heavy door). Why? <br /><br />Note: (I didn't apply the bind pose bone Transformation Matrix explicitly, but I read about it and I believe its functionality is there, in the hierarchical Transformation I have for my Skeleton).<br /><br />If you need more clarification of the steps, please ask.<br />Amin Dadgarhttps://www.blogger.com/profile/14820731648634073099noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-18749801253731660562015-10-10T12:09:53.561-07:002015-10-10T12:09:53.561-07:00Thanks :)Thanks :)Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-75581678587607076672015-10-07T19:49:43.309-07:002015-10-07T19:49:43.309-07:00Hey, Nice blog...and Really helpful...
Thank you
h...Hey, Nice blog...and Really helpful...<br />Thank you<br />http://www.gameyan.com/3d-character-animation.html<br />GameYan Studiohttps://www.blogger.com/profile/09055692607000365230noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-48363559437006695252015-02-11T05:33:40.433-08:002015-02-11T05:33:40.433-08:00Hi, sorry I forgot to reply to your help. Thanks f...Hi, sorry I forgot to reply to your help. Thanks for your help. If I may I want to ask another question which is if there's a keyframe at 0:02, I should interpolate the joint matrix(the matrix used for animation using the weight equation) during these two secends? If so how can I interpolate the matrix?0 zerohttps://www.blogger.com/profile/16184356824571986061noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-33823410951656706932014-11-07T07:39:43.020-08:002014-11-07T07:39:43.020-08:00Hello again,
Actually I haven't used collada ...Hello again,<br /><br />Actually I haven't used collada before but usually all the exporters produce same data with different arrangement and size. However I exported a sample file with collada and had a short look at it, So here are the answers:<br /><br />1- The matrix in the library_visual_scene is not the inverse binding pose matrix. I think it shows the current transformation of the bones in the scene but i'm not sure. As I said I haven't worked with collada before.<br /><br />2- You need the absolute matrix for the skinning process. Since vertices positions are being calculated in modeling space or world space you need the absolute matrices.<br /><br />3- If you open the file and search for "INV_BIND_MATRIX", it shows that it refers to the controller section. So the matrices in the controller section might be the inverse bind pose transformation.<br /><br />4- Relative transformations are used for animation. If you use the absolute matrices you will get unnatural results for character animation during keyframe interpolation. It can tear the skeleton because of having translation data in it and also interpolating the joints in parent space (or better with respect to each joint binding pose) can result a better and more natural result. <br /><br />The absolute matrix is just computed based on the relative matrices and it's used for being used for skinning process or any other operation that needs the absolute transformation of bones like physical calculation or inverse kinematics. You don't need to save absolute, you can always acquire it from relative matrices. In some cases you may save absolute matrices for caching purposes to be used for low detailed NPCs.<br /><br />The inverse bind matrix is used for ignoring the initial transformation of the bones. When you start rigging a character, you move and rotate the bones and also you might scale them and place them in the right position in the mesh. This transformation is called binding pose. After this you start skinning process. If you apply the binding pose to the mesh, the mesh's initial shape should be messed up. So you always should multiply each bone's inverse bind pose to the absolute matrix to have the initial pose of the mesh.<br /><br />5- The equation is correct but the joint matrix here is the absolute matrix that you have calculated in modeling space (not world).<br /><br />6- Keyframes are just transformations which are coming with local time . When you start the animation you should count the time. Then based on the current time you can find the two active keyframes. Then you should interpolate between these two active keyframes. Don't forget to first interpolate the bones in the parent space for each bone and then calculate the absolute transformation for each bone and use it for the skinning process.<br /><br />7- Each vertex has some weights to bones. So its final transformation should be the weighted sum of the the equation you wrote in your 4th question:<br /><br />((weight1 of vertex * JointMatrix1 * inverse bind matrix1) + (weight2 of vertex * JointMatrix2 * inverse bind matrix2) +..+(weight n of vertex * JointMatrix n * inverse bind matrix n)) * vertex.<br /><br />The number 'n' is not going beyond 4 at the most times for performance reasons, but it depends on your exporter to export how many bones influencing vertices.<br /><br />There are many approaches that can help you to optimize your skinning process, like GPU skinning, using SIMD operations on CPU or applying dirty flags to the bones, but the overall process is just about averaging the vertices based on the weights of their corresponding bones.<br /><br />Hope this would help :)<br />Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-76963075283834014992014-11-05T18:30:26.459-08:002014-11-05T18:30:26.459-08:00Thanks. Sorry I replied late, and sorry this post ...Thanks. Sorry I replied late, and sorry this post is a little long.<br /><br />The 3d model format I use is collada. From what I have searched, to calculate the skinning matrix, I need each joint's relative matrix, absolute matrix, animation matrix and the inverse bind matrix. In my opinion, if I'm correct, the relative matrix is stored as in .the absolute matrix needs to be calculated by multiplying the joint's relative matrix<br />by its parent's absolution matrix. And for the skinning equation, I need the inverse bind matrix, which is, if I guess correctly,<br />located under the library_controllers. My questions are<br /><br />1) Are the matrix in library_visual_scene the local transform matrix of the bone, and are they bind pose matrix?<br /><br />2) Why do I need the absolute matrix ( the one that is acquired through multiplying the relative/local transform matrix by its parent's absolute matrix) It doesn't appear in the skinning equation.<br /><br />3) Are the matrix in library_controller the Inverse Bind Matrix?<br /><br />4) What do absolute, relative and inverse bind matrix do?<br /><br />5) I found the skinning equation on this website : http://http.developer.nvidia.com/GPUGems/gpugems_ch04.html . It is the weight of vertex * JointMatrix ( I suppose ) * inverse bind matrix * vertex.<br /> I don't know what is the jointMatrix in that equation?<br /><br />6) When I export animation from blender, I see a series of matrices for each bone in library_animation. I think they correspond to the keyframe time.<br /> But how do I use these matrices ( i call them animation matrix).<br /><br />7) What approach can I take to calculate the skinning matrix ?<br /><br />Hobbyisthttps://www.blogger.com/profile/07105403081093700566noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-87901316132692396302014-11-02T13:11:55.366-08:002014-11-02T13:11:55.366-08:00Hi,
Yes of course, why not :)Hi,<br /><br />Yes of course, why not :)Peyman Massoudihttps://www.blogger.com/profile/03391039797831648545noreply@blogger.comtag:blogger.com,1999:blog-3759630438511440621.post-89522171267506359712014-11-01T14:11:40.897-07:002014-11-01T14:11:40.897-07:00Hi, if you don't mind could I ask animation-re...Hi, if you don't mind could I ask animation-related questions? I'm learning to do animation using opengl and collada.Hobbyisthttps://www.blogger.com/profile/07105403081093700566noreply@blogger.com