'In FBX file, I cannot understand difference between Transform and TransformLink

I am very new to FBX and not familiar in this area since I just started to study it

In the FBX SDK reference guide, It says :

Transform refers to the global initial position of the node containing the link

TransformLink refers to global initial position of the link node

But I cannot understand the definition.

Also what's the difference between "node containing the link" and "link node"

The document is too unfriendly to study FBX... Can I get some help?

In advance Thanks :)



Solution 1:[1]

An FBX mesh can be expected to have only one skin deformer object for animation purposes. Think of this as a deformable version of the mesh.

The deformer contains clusters, and each cluster in turn contains a link (or joint).

These objects are extracted from the mesh as follows:

VOID FbxLoader::LoadMeshBoneWeightsIndices(FbxMesh* pMesh, Mesh& mesh)
{
    // A deformer is a FBX thing, which contains some clusters
    // A cluster contains a link, which is basically a joint
    // Normally, there is only one deformer in a mesh
    // There are many types of deformers in Maya,
    // We are using only skins, so we see if this is a skin
    FbxSkin* currSkin = (FbxSkin*)(pMesh->GetDeformer(0u, FbxDeformer::eSkin));

    UINT numberOfClusters = UINT(currSkin->GetClusterCount());
    for (UINT clusterIndex = 0u; clusterIndex < numberOfClusters; ++clusterIndex)
    {
        FbxCluster* clusterPtr = currSkin->GetCluster(clusterIndex);
        UINT numOfIndices = UINT(clusterPtr->GetControlPointIndicesCount());
        DOUBLE* weightPtr = clusterPtr->GetControlPointWeights();
        INT* indicePtr = clusterPtr->GetControlPointIndices();
        std::string currJointName = clusterPtr->GetLink()->GetName();
        std::string secondName = clusterPtr->GetName();
        UINT boneIndex = BoneNameToIndex(currJointName);
        FbxAMatrix transformMatrix;
        FbxAMatrix transformLinkMatrix;
        FbxAMatrix globalBindposeInverseMatrix;

        // Now that we have the clusterPtr, let's calculate the inverse bind pose matrix.

        // The transformation of the cluster(joint) at binding time from joint space to world space
        clusterPtr->GetTransformLinkMatrix(transformLinkMatrix);
        clusterPtr->GetTransformMatrix(transformMatrix); // The transformation of the mesh at binding time
        // find out if we need geometryTransform
        globalBindposeInverseMatrix = transformLinkMatrix.Inverse() * transformMatrix; // * geometryTransform;

...

Back to your question, the code sample also extracts the transform matrix, and the transform link matrix:

  • The transform matrix is a local-to-world space transform of the mesh vertices
  • The transform link matrix is a local-to-world space transform of the joint

Each is used to arrive at the global bind pose inverse matrix as shown.

globalBindposeInverseMatrix = transformLinkMatrix.Inverse() * transformMatrix;

For each new frame of a skeletal animation, a bone offset matrix must be generated for each bone in the skinned model... and that offset matrix is globalBindposeInverseMatrix. Just load it into each bone's offset matrix member for every new frame of animation, for example:

LoadOffsetMatrix(globalBindposeInverseMatrix, mBoneVector[boneIndex].offset);

The offset matrices are packed together into an array, usually referred to as the bone matrix palette. And it's this bone matrix palette which is sent to the vertex skinning shader to update the skeletal model animation each frame.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1