.fbxファイルのインポートと表示


8

.fbxファイルのインポート/表示に少し問題があります。

私は例をチェックしましたが、私が最も興味を持っているもの(アニメーションとテクスチャー)は、私のようにこれに慣れていない誰かが理解するためにひどく文書化されています。

これは私が試したことです:頂点と法線を取得することができましたが、各頂点のテクスチャ座標を取得することに行き詰まっています。

これまでのところ私のコードです:

3dModelBasicStructs.h

struct vertex
{
float x,y,z;
};

struct texturecoords
{
float a,b;
};

struct poligon
{
int a,b,c;
};

Model.h

#ifndef MODEL_H
#define MODEL_H
#define FBXSDK_NEW_API

#define MAX_VERTICES 80000

#include "3dModelBasicStructs.h"

#include <fbxsdk.h>
#include <iostream>
#include <GL/glut.h>
using namespace std;

class Model
{

     public:

         Model(char*);
         ~Model();

         void ShowDetails();

         char* GetModelName();
         void  SetModelName( char* );
         void  GetFbxInfo( FbxNode* );
         void  RenderModel();


      private:

          char Name[25];

          vertex vertices[MAX_VERTICES];
          texturecoords txt[MAX_VERTICES];

          float *normals;
          int numNormals;

          int *indices;
          int numIndices;

          int numVertices;


};
#endif

Model.cpp

#include "Model.h"

Model::Model(char *filename)
{
cout<<"\nA model has been built!";

numVertices=0;
numIndices=0;

FbxManager *manager = FbxManager::Create();

FbxIOSettings *ioSettings = FbxIOSettings::Create(manager, IOSROOT);
manager->SetIOSettings(ioSettings);

FbxImporter *importer=FbxImporter::Create(manager,"");
importer->Initialize(filename,-1,manager->GetIOSettings());

FbxScene *scene = FbxScene::Create(manager,"tempName");

importer->Import(scene);
importer->Destroy();

FbxNode* rootNode = scene->GetRootNode();
this->SetModelName(filename);
if(rootNode) { this->GetFbxInfo(rootNode); }

}

Model::~Model()
{
cout<<"\nA model has been destroyed!";
glDisableClientState(GL_VERTEX_ARRAY);
}


void Model::ShowDetails()
{
cout<<"\nName:"<<Name;
cout<<"\nVertices Number:"<<numVertices;
cout<<"\nIndices Number:"<<numIndices;

}

char* Model::GetModelName()
{
return Name;
}

void Model::SetModelName(char *x)
{
strcpy(Name,x);
}

void Model::GetFbxInfo( FbxNode* Node )
{

int numKids = Node->GetChildCount();
FbxNode *childNode = 0;

for ( int i=0 ; i<numKids ; i++)
{
    childNode = Node->GetChild(i);
    FbxMesh *mesh = childNode->GetMesh();

    if ( mesh != NULL)
    {
//================= Get Vertices ====================================
        int numVerts = mesh->GetControlPointsCount();

        for ( int j=0; j<numVerts; j++)
        {
            FbxVector4 vert = mesh->GetControlPointAt(j);
            vertices[numVertices].x=(float)vert.mData[0];
            vertices[numVertices].y=(float)vert.mData[1];
            vertices[numVertices++].z=(float)vert.mData[2];
    //      cout<<"\n"<<vertices[numVertices-1].x<<" "<<vertices[numVertices-1].y<<" "<<vertices[numVertices-1].z;
        }
//================= Get Indices ====================================
        numIndices=mesh->GetPolygonVertexCount();
        indices = new int[numIndices];
        indices = mesh->GetPolygonVertices();
        cout<<numIndices;
//================= Get Normals ====================================


        FbxGeometryElementNormal* normalEl = mesh->GetElementNormal();
        if( normalEl)
        {
            numNormals = mesh->GetPolygonCount()*3;
            normals = new float[numNormals*3];
            int vertexCounter=0;
            for(int polyCounter = 0 ; polyCounter<mesh->GetPolygonCount(); polyCounter++)
            {
                for(int i=0;i<3;i++)
                {
                    FbxVector4 normal = normalEl->GetDirectArray().GetAt(vertexCounter);
                    normals[vertexCounter*3+0] = normal[0];
                    normals[vertexCounter*3+1] = normal[1];
                    normals[vertexCounter*3+2] = normal[2];
                    cout<<"\n"<<normals[vertexCounter*3+0]<<" "<<normals[vertexCounter*3+1]<<" "<<normals[vertexCounter*3+2];
                    vertexCounter++;
                }
            }
        }


    }
    this->GetFbxInfo(childNode);
}
}

void Model::RenderModel()
{
int i,j;
for(i=0;i<numIndices-3;i++)
{
    glBegin(GL_TRIANGLES);
    glNormal3f(normals[i*3+0],normals[i*3+1],normals[i*3+2]); 
    for(j=i;j<=i+2;j++)
            glVertex3f(vertices[indices[j]].x,vertices[indices[j]].y,vertices[indices[j]].z);
    glEnd();
}
}

私の質問は:

  1. テクスチャコードを取得するにはどうすればよいですか?
  2. ブレンダーでテクスチャを写真形式でエクスポートするにはどうすればよいですか?(.jpgや.tgaなど)
  3. これまでの表示方法に間違いはありませんか?
  4. .fbxサンプルに、シーンのみを表示するプロジェクト(アニメーションとテクスチャを含む、自分では見つからなかった)はありますか?

回答:


3

#1についてFbxMeshのメソッドGetTextureUVは、トリックを実行する必要があります。

編集:次のコードはテストされておらず、ここから不正にコピーされています

int polygonCount = mesh->GetPolygonCount();
for (int i = 0; i < polygonCount; ++i) {

  FbxLayerElementArrayTemplate<KFbxVector2>* uvVertices= 0;
  mesh->GetTextureUV(&uvVertices, KFbxLayerElement::eTextureDiffuse);

  for (int j = 0; j < mesh>GetPolygonSize(i); ++j) {

     FbxVector2 uv = uvVertices[mesh->GetTextureUVIndex(i, j)];

     texturecoords.a = uv[0];
     texturecoords.b = uv[1];

  }
}

編集2: 私が見つけた他のいくつかの例を調べました:2つの同様のクラスがあるようです:FbxVector2とKFbxVector2、後者は含まれているdouble値に直接アクセスできます。その例を比較してください:

KFbxLayerElementArrayTemplate<KFbxVector2>* lUVArray = NULL;    
pMesh->GetTextureUV(&lUVArray, KFbxLayerElement::eDIFFUSE_TEXTURES); 

lUVArray->GetAt(mesh->GetTextureUVIndex(i, j)).mData[0];

それらのK *タイプを使用できますか?

EDIT3:これらのK *タイプは明らかに古いFBX SDKからのものであるため、すべての人に関連しているわけではありません。


説明やいくつかの例のように、もう少し詳細をいただければ幸いです。(私はすでにこの方法を見ましたが、それが何をするか、どのように行うかを本当に理解していませんでした)。
Taigi

数分前、私は小さな例で編集しました。私はこれまでFBXを使用したことがなく、インポーターを作成したことは言うまでもありません。申し訳ありませんが、これ以上の力はありません。
フィリップアルガイエ2013年

うーん、見た目はかなり良いです(少しテストします)が、これでうまくいくはずです!(投票したかったのですが、できません:( 15 repを下回るのが嫌いです:()
Taigi

気持ちがわかります。以前にも他のスレッドについてコメントしたかったのですが、そのためには50人の担当者が必要です。このスレッドは、他の人に良い出発点を提供するので、あなたはすでに私からこのスレッドへの賛成票を得ています。がんばって!
フィリップアルガイエ2013年

試してみました... GetPolygonCountはブール関数であり、2つのパラメーターが必要であるため機能しません
Taigi

2

私はFBXの専門家ではありませんが、ある程度の経験があります。これが私の提案です。

テクスチャコードを取得するにはどうすればよいですか?.fbxサンプルに、シーンのみを表示するプロジェクト(アニメーションとテクスチャを含む、自分では見つからなかった)はありますか?

$(FBXSDK)\ samples \ ImportSceneの例を検討することをお勧めします

これは、UV座標やその他のデータを取得する方法を示します。

ブレンダーでテクスチャを写真形式でエクスポートするにはどうすればよいですか?(.jpgや.tgaなど)

FBXをエクスポートするブレンダーを使用していません。

これまでの表示方法に間違いはありませんか?

コードをざっと見てみたので、間違いがあっても100%とは言えませんが、FBX SDKでの作業で学んだいくつかの提案をします。

3Dソフトウェアによっては、UV座標を変換する必要があるかどうかを確認する必要があります。たとえば、ソフトウェアが期待するものと同じであるか、これを行う必要があります

mine.U = fbx.U

mine.V = 1-fbx.V

また、FBXはエクスポーター(3ds maxでの私の経験)によって異なりますが、YとZは移動のみで変更され、回転が反転します。(3ds maxで)Y-UPをエクスポートすると、lclTranslationは1:1に一致しますが、lclRotationは次のようになります。

myRot.x = fbxRot.x

myRot.y = fbxRot.z

myRot.z = fbxRot.y

また、座標系が左か右かを確認し、ソフトウェアが期待するものと一致しているかどうかを確認してください。

FBX用のカスタムインポーターの作成と作成は、あきらめないでください。


2

FBX SDK 2013を使用して1つのUVセットを持つモデルのテクスチャ座標を取得する:

// UV Container
std::vector<float[2]> UVList;

// Loop for each poly
for ( int Poly(0); Poly < fbxMesh->GetPolygonCount(); Poly++ )
{
    // Get number of verts in this poly
    const int NumVertices = fbxMesh->GetPolygonSize( Poly );

    // Loop for each vert in poly
    for( int Vertex(0); Vertex < NumVertices; Vertex++ )
    {
         FbxVector2 fbxTexCoord;
         FbxStringList UVSetNameList;

         // Get the name of each set of UV coords
         fbxMesh->GetUVSetNames( UVSetNameList );

         // Get the UV coords for this vertex in this poly which belong to the first UV set
         // Note: Using 0 as index into UV set list as this example supports only one UV set
         fbxMesh->GetPolygonVertexUV( Poly, Vertex, UVSetNameList.GetStringAt(0), fbxTexCoord );

         // Convert to floats
         float UVCoord[2];
         UVCoord[0] = static_cast<float>( fbxTexCoord[0] );
         UVCoord[1] = static_cast<float>( fbxTexCoord[1] );

         // Store UV
         UVList.push_back( UVCoord );
     }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.