<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Manually building bindpose matrices in FBX SDK in FBX Forum</title>
    <link>https://forums.autodesk.com/t5/fbx-forum/manually-building-bindpose-matrices-in-fbx-sdk/m-p/7440504#M1606</link>
    <description>&lt;P&gt;Hi everyone, I've been running into a strange issue where my bindpose matrices are getting&amp;nbsp;incorrect values compared to what I'm expecting from Maya. I'm using a different approach compared to the more common GetTransformLinkMatrix on the current cluster to receive its bindpose matrix. This strategy worked in FBX SDK 2015 and its based on the EvaluateLocalTransform function which I use to store each joint's local transformation at the specified time. The specified time is&amp;nbsp;FBXSDK_TIME_INFINITE, which should give me the bindpose the mesh was bound to without any&amp;nbsp;animation curves evaluation. I&amp;nbsp;want to do this to create the inversed bind pose matrix for the current joint so I can use this for my skeletal animation calculations.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I start by initializng the root joint in order to be able to iterate through the joint hierarchy using the parent index I've received from a depth-first search algorithm I used when reading the contents from the FBX file. By doing so, I should be able to manually create a joint's bindpose by multiplying the current joint's local transform with the parent joint's local transform. The motivation for this&amp;nbsp;was to detach as much of the logic as possible from FBX so that the same approach can (hopefully) be used for other formats.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now suddenly, when upgrading to FBX SDK 2017.0.1, this no longer works. It might also be worth to mention that I'm using animation layers and that I've experienced issues in which they modify the bindpose matrices depending on if I mute them or not before exporting. Are there any options with animation layers I should take extra notice on when working with layers? Is there a unique bindpose under every layer? I haven't bound more than one mesh to the same skeleton, so I've unchecked in my skin bind settings to not allow more than one bind pose. On the base animation layer, I only have the mesh in bindpose and no keyframes applied. I've only used this strategy without animation layers, but they shouldn't affect the transform values since I've specified&amp;nbsp;&lt;SPAN&gt;FBXSDK_TIME_INFINITE. So to my question, is this actually a valid way of manually building your bindpose matrices or is there a better way? By using TransformLinkMatrix, I receive the same invalid values so I get the feeling that something else is messing up my bindpose. Any help would be appreciated, I feel rather lost at the moment since this used to work for me back in 2015.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;I'm going to attach my bind settings, the structs I'm using to gather data and the algorithm I use with comments for each step. I'm also going to include a log file where I display&amp;nbsp;the raw values from the matrices, column major from the FbxAMatrix type.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Mesh&lt;/STRONG&gt; is a wrapper to the skin node&lt;/U&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;struct Mesh {&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&lt;/STRONG&gt;string name&lt;/P&gt;&lt;P&gt;&amp;nbsp; FbxMesh* meshNode;&lt;BR /&gt;&amp;nbsp; FbxSkin* skinNode;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;}&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Joint&lt;/STRONG&gt; is a wrapper to the matrices&lt;/U&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;struct Joint {&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp; &lt;/STRONG&gt;string Name;&lt;BR /&gt;&amp;nbsp; int ParentIndex;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; FbxAMatrix GlobalBindposeInverse;&lt;BR /&gt;&amp;nbsp; FbxAMatrix LocalTransform;&lt;BR /&gt;&amp;nbsp; FbxAMatrix GlobalTransform;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; FbxNode* Node;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;}&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;// Get the root joint node which is the first cluster in the skin.&lt;/STRONG&gt;&lt;BR /&gt;FbxCluster* currentCluster = pMesh.skinNode-&amp;gt;GetCluster(0);&lt;/P&gt;&lt;P&gt;currentCluster-&amp;gt;GetName();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;// Initialize the root joint first. By doing so, we make sure no children is evaluated before its parent&lt;/STRONG&gt;&lt;BR /&gt;pMesh.skeleton.hierarchy[0].LocalTransform = currentCluster-&amp;gt;GetLink()-&amp;gt;EvaluateLocalTransform(FBXSDK_TIME_INFINITE);&lt;BR /&gt;pMesh.skeleton.hierarchy[0].GlobalTransform = pMesh.skeleton.hierarchy[0].LocalTransform;&lt;BR /&gt;pMesh.skeleton.hierarchy[0].GlobalBindposeInverse = pMesh.skeleton.hierarchy[0].GlobalTransform.Inverse();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;// Loop through all the joints in the hierarchy&lt;/STRONG&gt;&lt;BR /&gt;for (int i = 1; i &amp;lt; NUM_BONES; i++) {&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &lt;STRONG&gt;// Receive the current joint cluster&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; currentCluster = pMesh.skinNode-&amp;gt;GetCluster(i);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// Create a reference to the currenct joint in the hierarchy to be processed&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;Joint &amp;amp;b = pMesh.skeleton.hierarchy[i];&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// Get the current joint LOCAL transformation&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;b.LocalTransform = currentCluster-&amp;gt;GetLink()-&amp;gt;EvaluateLocalTransform(FBXSDK_TIME_INFINITE);&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// Calculate the current joint GLOBAL transformation by taking the global transformation of the parent&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;multiplied by this joint LOCAL transformation&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;b.GlobalTransform = pMesh.skeleton.hierarchy[b.ParentIndex].GlobalTransform * b.LocalTransform;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// The inverse bind pose is calculated by taking the inverse of the joint GLOBAL transformation matrix&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;b.GlobalBindposeInverse = b.GlobalTransform.Inverse();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;</description>
    <pubDate>Fri, 06 Oct 2017 16:10:46 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2017-10-06T16:10:46Z</dc:date>
    <item>
      <title>Manually building bindpose matrices in FBX SDK</title>
      <link>https://forums.autodesk.com/t5/fbx-forum/manually-building-bindpose-matrices-in-fbx-sdk/m-p/7440504#M1606</link>
      <description>&lt;P&gt;Hi everyone, I've been running into a strange issue where my bindpose matrices are getting&amp;nbsp;incorrect values compared to what I'm expecting from Maya. I'm using a different approach compared to the more common GetTransformLinkMatrix on the current cluster to receive its bindpose matrix. This strategy worked in FBX SDK 2015 and its based on the EvaluateLocalTransform function which I use to store each joint's local transformation at the specified time. The specified time is&amp;nbsp;FBXSDK_TIME_INFINITE, which should give me the bindpose the mesh was bound to without any&amp;nbsp;animation curves evaluation. I&amp;nbsp;want to do this to create the inversed bind pose matrix for the current joint so I can use this for my skeletal animation calculations.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I start by initializng the root joint in order to be able to iterate through the joint hierarchy using the parent index I've received from a depth-first search algorithm I used when reading the contents from the FBX file. By doing so, I should be able to manually create a joint's bindpose by multiplying the current joint's local transform with the parent joint's local transform. The motivation for this&amp;nbsp;was to detach as much of the logic as possible from FBX so that the same approach can (hopefully) be used for other formats.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now suddenly, when upgrading to FBX SDK 2017.0.1, this no longer works. It might also be worth to mention that I'm using animation layers and that I've experienced issues in which they modify the bindpose matrices depending on if I mute them or not before exporting. Are there any options with animation layers I should take extra notice on when working with layers? Is there a unique bindpose under every layer? I haven't bound more than one mesh to the same skeleton, so I've unchecked in my skin bind settings to not allow more than one bind pose. On the base animation layer, I only have the mesh in bindpose and no keyframes applied. I've only used this strategy without animation layers, but they shouldn't affect the transform values since I've specified&amp;nbsp;&lt;SPAN&gt;FBXSDK_TIME_INFINITE. So to my question, is this actually a valid way of manually building your bindpose matrices or is there a better way? By using TransformLinkMatrix, I receive the same invalid values so I get the feeling that something else is messing up my bindpose. Any help would be appreciated, I feel rather lost at the moment since this used to work for me back in 2015.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;I'm going to attach my bind settings, the structs I'm using to gather data and the algorithm I use with comments for each step. I'm also going to include a log file where I display&amp;nbsp;the raw values from the matrices, column major from the FbxAMatrix type.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Mesh&lt;/STRONG&gt; is a wrapper to the skin node&lt;/U&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;struct Mesh {&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&lt;/STRONG&gt;string name&lt;/P&gt;&lt;P&gt;&amp;nbsp; FbxMesh* meshNode;&lt;BR /&gt;&amp;nbsp; FbxSkin* skinNode;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;}&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Joint&lt;/STRONG&gt; is a wrapper to the matrices&lt;/U&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;struct Joint {&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp; &lt;/STRONG&gt;string Name;&lt;BR /&gt;&amp;nbsp; int ParentIndex;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; FbxAMatrix GlobalBindposeInverse;&lt;BR /&gt;&amp;nbsp; FbxAMatrix LocalTransform;&lt;BR /&gt;&amp;nbsp; FbxAMatrix GlobalTransform;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; FbxNode* Node;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;}&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;// Get the root joint node which is the first cluster in the skin.&lt;/STRONG&gt;&lt;BR /&gt;FbxCluster* currentCluster = pMesh.skinNode-&amp;gt;GetCluster(0);&lt;/P&gt;&lt;P&gt;currentCluster-&amp;gt;GetName();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;// Initialize the root joint first. By doing so, we make sure no children is evaluated before its parent&lt;/STRONG&gt;&lt;BR /&gt;pMesh.skeleton.hierarchy[0].LocalTransform = currentCluster-&amp;gt;GetLink()-&amp;gt;EvaluateLocalTransform(FBXSDK_TIME_INFINITE);&lt;BR /&gt;pMesh.skeleton.hierarchy[0].GlobalTransform = pMesh.skeleton.hierarchy[0].LocalTransform;&lt;BR /&gt;pMesh.skeleton.hierarchy[0].GlobalBindposeInverse = pMesh.skeleton.hierarchy[0].GlobalTransform.Inverse();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;// Loop through all the joints in the hierarchy&lt;/STRONG&gt;&lt;BR /&gt;for (int i = 1; i &amp;lt; NUM_BONES; i++) {&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &lt;STRONG&gt;// Receive the current joint cluster&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; currentCluster = pMesh.skinNode-&amp;gt;GetCluster(i);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// Create a reference to the currenct joint in the hierarchy to be processed&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;Joint &amp;amp;b = pMesh.skeleton.hierarchy[i];&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// Get the current joint LOCAL transformation&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;b.LocalTransform = currentCluster-&amp;gt;GetLink()-&amp;gt;EvaluateLocalTransform(FBXSDK_TIME_INFINITE);&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// Calculate the current joint GLOBAL transformation by taking the global transformation of the parent&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;multiplied by this joint LOCAL transformation&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;b.GlobalTransform = pMesh.skeleton.hierarchy[b.ParentIndex].GlobalTransform * b.LocalTransform;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;&lt;STRONG&gt;// The inverse bind pose is calculated by taking the inverse of the joint GLOBAL transformation matrix&lt;/STRONG&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;b.GlobalBindposeInverse = b.GlobalTransform.Inverse();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;</description>
      <pubDate>Fri, 06 Oct 2017 16:10:46 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fbx-forum/manually-building-bindpose-matrices-in-fbx-sdk/m-p/7440504#M1606</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-10-06T16:10:46Z</dc:date>
    </item>
    <item>
      <title>Re: Manually building bindpose matrices in FBX SDK</title>
      <link>https://forums.autodesk.com/t5/fbx-forum/manually-building-bindpose-matrices-in-fbx-sdk/m-p/7444646#M1607</link>
      <description>&lt;P&gt;Problem solved, there was a faulty in my joint tool settings. I had to&amp;nbsp;check&amp;nbsp;"Orient joint to World" to receive the correct values. Now both methods work, the manual method and the TransformLinkMatrix approach. I hope this can help anyone out there experiencing the same problem.&lt;/P&gt;</description>
      <pubDate>Mon, 09 Oct 2017 12:00:17 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fbx-forum/manually-building-bindpose-matrices-in-fbx-sdk/m-p/7444646#M1607</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2017-10-09T12:00:17Z</dc:date>
    </item>
  </channel>
</rss>

