FBX SDK スキニングしているジョイントのローカル座標、変換行列取得 | puarts.com
映像・CG・画像処理関連の技術情報、個人作品の創作記録、メモなど
Category

FBX SDK スキニングしているジョイントのローカル座標、変換行列取得

公開日: 2017/04/16 | カテゴリ: C/C++ | タグ: C++, FBX SDK

FBX SDK を使って fbx からスキニングしているジョイントのローカル座標を取得する方法がヘルプ読まずにわからなかったので、メモ代わりにスキニングしているジョイントのローカル座標と変換行列をコンソール出力する関数を載せておきます。

ソースコード

void PrintLocalSrtAndTransformMatrixOfJoints(FbxNode* root_node)
{
    FbxMesh* mesh = root_node->GetMesh();
    int skin_count = mesh->GetDeformerCount(FbxDeformer::eSkin);
    for (int skin_index = 0; skin_index < skin_count; ++skin_index)
    {
        FbxSkin* skin = static_cast<FbxSkin*>(mesh->GetDeformer(skin_index, FbxDeformer::eSkin));
        int cluster_count = skin->GetClusterCount();
        for (int cluster_index = 0; cluster_index < cluster_count; ++cluster_index)
        {
            FbxCluster* cluster = skin->GetCluster(cluster_index);
            FbxNode* linked_node = cluster->GetLink();
            printf("%s:\n", linked_node->GetName());

            // ジョイントのローカル SRT を表示
            fbxsdk::FbxDouble3 local_translate = linked_node->LclTranslation.Get();
            fbxsdk::FbxDouble3 local_rotate = linked_node->LclRotation.Get();
            fbxsdk::FbxDouble3 local_scale = linked_node->LclScaling.Get();
            printf("    t = (%8.3f, %8.3f, %8.3f)\n    r = (%8.3f, %8.3f, %8.3f)\n    s = (%8.3f, %8.3f, %8.3f)\n",
                local_translate[0],
                local_translate[1],
                local_translate[2],
                local_rotate[0],
                local_rotate[1],
                local_rotate[2],
                local_scale[0],
                local_scale[1],
                local_scale[2]);

            // ジョイントの変換行列を表示
            fbxsdk::FbxAMatrix init_matrix;
            cluster->GetTransformLinkMatrix(init_matrix);
            printf("    matrix =\n");
            for (int row = 0; row < 4; ++row)
            {
                printf("        ");
                for (int col = 0; col < 4; ++col)
                {
                    printf("%8.3f, ", init_matrix.Get(row, col));
                }
                printf("\n");
            }
        }
    }
}

コンソール出力結果例

joint1:
    t = (   0.000,    0.000,    0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           0.000,    0.000,    0.000,    1.000,
joint2:
    t = (   0.000,    1.000,    0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           0.000,    1.000,    0.000,    1.000,
joint3:
    t = (   0.000,    1.000,   -0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           0.000,    2.000,   -0.000,    1.000,
joint4:
    t = (   1.000,    1.000,   -0.000)
    r = (   0.000,    0.000,    0.000)
    s = (   1.000,    1.000,    1.000)
    matrix =
           1.000,    0.000,    0.000,    0.000,
          -0.000,    1.000,    0.000,    0.000,
           0.000,   -0.000,    1.000,    0.000,
           1.000,    3.000,   -0.000,    1.000,

ついでにサンプルにあったバインドポーズのトンラスフォームの取得方法もメモ代わりに載せておきます。

バインドポーズのトランスフォームと行列(サンプルより)

void DisplayPose(FbxScene* pScene)
{
    int      i, j, k, lPoseCount;
    FbxString  lName;

    lPoseCount = pScene->GetPoseCount();

    for (i = 0; i < lPoseCount; i++)
    {
        FbxPose* lPose = pScene->GetPose(i);

        lName = lPose->GetName();
        printf("Pose Name: %s\n", lName.Buffer());

        printf("    Is a bind pose: %s\n", lPose->IsBindPose()?"true":"false");

        printf("    Number of items in the pose: %d\n", lPose->GetCount());

        printf("\n");

        for (j = 0; j<lPose->GetCount(); j++)
        {
            lName = lPose->GetNodeName(j).GetCurrentName();
            printf("    Item name: %s\n", lName.Buffer());

            if (!lPose->IsBindPose())
            {
                // Rest pose can have local matrix
                printf("    Is local space matrix: %s\n", lPose->IsLocalMatrix(j)?"true":"false");
            }

            printf("    Matrix value: \n");

            FbxString lMatrixValue;

            FbxNode* node = lPose->GetNode(j);

            for (k = 0; k<4; k++)
            {
                FbxMatrix  lMatrix = lPose->GetMatrix(j);
                FbxVector4 lRow = lMatrix.GetRow(k);
                char        lRowValue[1024];

                FBXSDK_sprintf(lRowValue, 1024, "%9.4f %9.4f %9.4f %9.4f\n", lRow[0], lRow[1], lRow[2], lRow[3]);
                lMatrixValue += FbxString("        ") + FbxString(lRowValue);
            }

            printf("%s\n", lMatrixValue.Buffer());
        }
    }

    lPoseCount = pScene->GetCharacterPoseCount();

    for (i = 0; i < lPoseCount; i++)
    {
        FbxCharacterPose* lPose = pScene->GetCharacterPose(i);
        FbxCharacter*     lCharacter = lPose->GetCharacter();

        if (!lCharacter) break;

        printf("Character Pose Name: %s\n", lCharacter->GetName());

        FbxCharacterLink lCharacterLink;
        FbxCharacter::ENodeId  lNodeId = FbxCharacter::eHips;

        while (lCharacter->GetCharacterLink(lNodeId, &lCharacterLink))
        {
            FbxAMatrix& lGlobalPosition = lCharacterLink.mNode->EvaluateGlobalTransform(FBXSDK_TIME_ZERO);

            printf("    Matrix value: %s\n", "");

            FbxString lMatrixValue;

            for (k = 0; k<4; k++)
            {
                FbxVector4 lRow = lGlobalPosition.GetRow(k);
                char        lRowValue[1024];

                FBXSDK_sprintf(lRowValue, 1024, "%9.4f %9.4f %9.4f %9.4f\n", lRow[0], lRow[1], lRow[2], lRow[3]);
                lMatrixValue += FbxString("        ") + FbxString(lRowValue);
            }

            printf("%s\n", lMatrixValue.Buffer());

            lNodeId = FbxCharacter::ENodeId(int(lNodeId) + 1);
        }
    }
}


  このエントリーをはてなブックマークに追加  

にほんブログ村 デザインブログ グラフィックアートへ
Links

参考になりそうなブログやサイトを見つけたら勝手にリンクを貼らせてもらっています。
リンク削除を希望の場合はお手数ですがメールにてご一報下さい。
Ke-Sen Huang's Home Page        Disney Research        VIDEO COPILOT        AbandonedArt.org
ryoji ikeda        チームラボ        トルク with AR三兄弟        DAITO MANABE

Copyright(C)2006-2017 wsp All Rights Reserved