トップ | puarts.com
ロゴ
「FBX SDK」に関連する記事一覧
0  

昔作っていたモデル描画プログラムで fbx ファイルからアニメーション読み込み対応しようと、FBXSDK のアニメーション機能を使ってみたところ、以下のリンクエラーが発生しました。


error LNK2001: 外部シンボル ""public: static class fbxsdk::FbxClassId fbxsdk::FbxAnimStack::ClassId" (?ClassId@FbxAnimStack@fbxsdk@@2VFbxClassId@2@A)" は未解決です。
error LNK2001: 外部シンボル ""class fbxsdk::FbxDataType fbxsdk::FbxColor3DT" (?FbxColor3DT@fbxsdk@@3VFbxDataType@1@A)" は未解決です。
error LNK2001: 外部シンボル ""class fbxsdk::FbxDataType fbxsdk::FbxColor4DT" (?FbxColor4DT@fbxsdk@@3VFbxDataType@1@A)" は未解決です。
error LNK2001: 外部シンボル ""private: static void (__cdecl* fbxsdk::FbxAnimCurveKey::mDeallocatorFct)(class fbxsdk::FbxAnimCurveKey_Impl *)" (?mDeallocatorFct@FbxAnimCurveKey@fbxsdk@@0P6AXPEAVFbxAnimCurveKey_Impl@2@@ZEA)" は未解決です。
error LNK2001: 外部シンボル ""public: static class fbxsdk::FbxClassId fbxsdk::FbxAnimLayer::ClassId" (?ClassId@FbxAnimLayer@fbxsdk@@2VFbxClassId@2@A)" は未解決です。

これまで頂点データの読み込み等は問題なく行えていたので、なぜアニメーション関連の機能だけリンクエラーになるんだろうと思って、ネットで調べたところ、Autodesk のフォーラムで同じ問題にはまっている人がいました。

https://forums.autodesk.com/t5/fbx-forum/cannot-find-static-symbol/td-p/5816698

こちらのフォーラムにあるように私も libfbxsdk.lib をリンクしていたのですが、これではなく libfbxsdk-md.lib の方をリンクしたらビルドが通るようになりました。FBXSDK のライブラリディレクトリには fbxsdk.lib、fbxsdk-mt.lib、fbxsdk-md.lib の3つがありますが、mt と md は意味はわかるのですが、無印のは何用なんでしょうか。アニメーション機能を利用するまでは libfbxsdk.lib でもちゃんとビルド通るし、この lib の役割がよくわからないですね。

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);
        }
    }
}

0  

0.0243 sec
にほんブログ村 ゲームブログ ファイアーエムブレムへ にほんブログ村 デザインブログ コンピュータグラフィックスへ

Copyright(C)2006-2018 wsp All Rights Reserved