頂点座標と頂点インデックスを取得しよう

連載一覧 : FBX SDKを使ってファイルからデータを取得しよう

    いつも見てくださってありがとうございます。

    見に来てくださる人がいるので、記事を更新するモチベーションが今のところ干上がらずに済んでいるyosiです。

    第3回は前回取得したノードから頂点座標と頂点インデックスを取得していきます。

    メッシュを取得する

    ノードからメッシュを取得します。

    そのメッシュを用いて、頂点情報を取得していきます。

    DisplayIndex(mesh)とDisplayPosition(mesh)は頂点インデックスと頂点座標を取得するための関数で、この後に定義していきます。

    #include "stdafx.h"
    #include "fbxsdk.h"
    #include "iostream"
    
    void DisplayContent(FbxScene* pScene);
    void DisplayContent(FbxNode* pNode);
    void DisplayMesh(FbxNode* pNode);
    void DisplayIndex(FbxMesh* mesh);
    void DisplayPosition(FbxMesh* mesh);
    
    int main()
    {
        //省略 前回までの内容をご覧ください
    
        DisplayContent(scene);
    
        manager->Destroy();
        return 0;
    }
    
    
    void DisplayContent(FbxScene* scene)
    {
        //省略 前回までの内容をご覧ください
    }
    
    
    void DisplayContent(FbxNode* node)
    {
        FbxNodeAttribute::EType lAttributeType;
    
        if (node->GetNodeAttribute() == NULL)
        {
            std::cout << "NULL Node Attribute\n\n";
        }
        else
        {
            lAttributeType = (node->GetNodeAttribute()->GetAttributeType());
    
            switch (lAttributeType)
            {
            default:
                break;
    
            case FbxNodeAttribute::eMesh:
                DisplayMesh(node);
                break;
            }
        }
    
    
        for (int i = 0; i < node->GetChildCount(); i++)
        {
            DisplayContent(node->GetChild(i));
        }
    }
    
    
    void DisplayMesh(FbxNode* node)
    {
        FbxMesh* mesh = (FbxMesh*)node->GetNodeAttribute();
    
        std::cout << "\n\nMesh Name: " << (char *)node->GetName() << std::endl;
    
        DisplayIndex(mesh);
        DisplayPosition(mesh);
    
    }

    頂点インデックスと頂点座標を取得する

    取得していくデータについて簡単に説明しますと、3Dデータは複数の頂点(Vertex)から成るポリゴンによって表現されます。

    その頂点には頂点座標、法線、テクスチャ座標などがあります。

    複数のポリゴン間には重複している頂点があります(下の図の頂点0と2)。

    その重複によるメモリの無駄を避けるために、頂点インデックスがあります。

    795c73385807522705c42ff4c863564b

    その頂点インデックスを取得していきます。

    ここでは基本的に表示のみをしています。

    後はこのindexを集めて配列にするなり、ファイルに書き出すなりしてください。

    void DisplayIndex(FbxMesh* mesh)
    {
        //総ポリゴン数
        int polygonNum = mesh->GetPolygonCount();
    
        //p個目のポリゴンへの処理
        for (int p = 0; p < polygonNum; ++p)
        {
            //p個目のポリゴンのn個目の頂点への処理
            for (int n = 0; n < 3; ++n)
            {
                int index = mesh->GetPolygonVertex(p, n);
                std::cout << "index[" << p+n <<"] : " << index << std::endl;
            }
        }
    }

    次に頂点座標を取得していきます。

    得られたpositionは大きさ4のベクトルなのですが、実行してみると分かるのですが、多くの場合4つ目の要素(position[i])に0が入っています。

    ただ、OpenGLで実行するときには4つ目の要素は0だと描画されないのでたいていは1を指定することになると思います。

    void DisplayPosition(FbxMesh* mesh)
    {
        int positionNum = mesh->GetControlPointsCount();	// 頂点数
        FbxVector4* position = mesh->GetControlPoints();	// 頂点座標配列
    
        for (int i = 0; i < positionNum; ++i)
        {
            std::cout << "position[" << i << "] : ("
                << position[i][0] << "," 
                << position[i][1] << "," 
                << position[i][2] << "," 
                << position[i][3] << ")" << std::endl;
        }
    }

    実行してみると、メッシュ名、頂点インデックス、頂点座標が表示されると思います。

    余談ですが、コンソールアプリケーションは実行し終わるとすぐに終了してしまいます。

    そんな時は、止めたい行を選択して、カーソルの前まで実行を使うと、その部分で実行が止まるので便利です。

    SnapCrab NoName 2017 12 28 23 32 24 No 00

    連載一覧 : FBX SDKを使ってファイルからデータを取得しよう