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

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

見に来てくださる人がいるので、記事を更新するモチベーションが今のところ干上がらずに済んでいる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