Mengimpor dan Menampilkan file .fbx

8

Saya punya sedikit masalah dengan mengimpor / menampilkan file .fbx.

Saya memeriksa contoh-contohnya tetapi yang paling saya sukai (animasi dan tekstur) tidak terdokumentasi dengan baik untuk dipahami oleh seseorang yang baru dengan ini seperti saya.

Inilah yang saya coba: Saya berhasil mendapatkan simpul dan normalnya tapi saya terjebak pada mendapatkan tekstur tekstur untuk setiap simpul.

Ini kode saya sejauh ini:

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

Pertanyaan saya adalah:

  1. Bagaimana saya mendapatkan tekstur coords?
  2. Bagaimana cara membuat blender mengekspor tekstur dalam format foto? (seperti .jpg atau .tga)
  3. Apakah ada kesalahan dalam tampilan saya sejauh ini?
  4. Apakah ada proyek dalam sampel .fbx yang hanya menampilkan adegan (termasuk animasi dan tekstur; saya tidak dapat menemukannya sendiri)?
Taigi
sumber

Jawaban:

3

Mengenai # 1 : Metode GetTextureUV dari FbxMesh harus menyelesaikan masalahnya.

EDIT: Kode berikut ini belum diuji dan secara kasar disalin dari sini :

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];

  }
}

EDIT 2: Saya melihat beberapa contoh lain yang saya temukan: Tampaknya ada dua kelas yang serupa: FbxVector2 dan KFbxVector2 di mana yang terakhir memiliki akses langsung ke nilai ganda yang disertakan. Bandingkan contoh itu:

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

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

Bisakah Anda menggunakan tipe K * itu?

EDIT3: Jenis-jenis K * itu tampaknya berasal dari FBX SDK yang lebih lama, jadi tidak relevan untuk semua orang.

Philip Allgaier
sumber
Sedikit lebih detail akan sangat dihargai, seperti penjelasan atau beberapa contoh. (Saya sudah melihat metode ini tetapi tidak benar-benar mengerti apa yang dilakukannya atau bagaimana melakukannya).
Taigi
Beberapa menit yang lalu, saya mengedit dalam sedikit contoh yang saya temukan yang mungkin bisa membantu. Saya tidak pernah bekerja dengan FBX sejauh ini, apalagi menulis importir, jadi saya khawatir saya tidak bisa membantu, maaf.
Philip Allgaier
Hmm itu terlihat cukup bagus (saya akan mengujinya sedikit), tapi terima kasih banyak ini harus bekerja! (Ingin memilih tetapi saya tidak bisa :( Aku benci memiliki di bawah 15 rep :()
Taigi
Saya tahu perasaan itu. Saya juga ingin mengomentari beberapa utas lain sebelumnya, tetapi Anda perlu 50 rep untuk itu. Anda telah menerima suara dari saya untuk utas ini, karena ini memberikan titik awal yang baik untuk orang lain. Semoga berhasil!
Philip Allgaier
Sudah mencobanya ... Ini tidak berfungsi karena GetPolygonCount adalah fungsi bool dan juga membutuhkan 2 parameter
Taigi
2

Saya bukan ahli dalam FBX tetapi saya memiliki pengalaman dengan itu, berikut adalah saran saya

Bagaimana saya mendapatkan tekstur coords? Apakah ada proyek dalam sampel .fbx yang hanya menampilkan adegan (termasuk animasi dan tekstur; saya tidak dapat menemukannya sendiri)?

Saya sarankan memeriksa contoh dalam $ (FBXSDK) \ samples \ ImportScene

Ini akan menunjukkan kepada Anda bagaimana cara mendapatkan UV Coords dan data lainnya

Bagaimana cara membuat blender mengekspor tekstur dalam format foto? (seperti .jpg atau .tga)

Saya belum bekerja dengan blender yang mengekspor FBX, maaf

Apakah ada kesalahan dalam tampilan saya sejauh ini?

Saya sudah melihat sekilas kode Anda, jadi tidak bisa mengatakan 100% jika Anda memiliki kesalahan, tetapi saya akan memberikan beberapa saran agar saya belajar bekerja dengan FBX SDK.

Bergantung pada Perangkat Lunak 3D Anda harus memeriksa apakah Anda perlu mengkonversi Coords UV Anda. Misalnya itu bisa sama dengan yang diharapkan oleh perangkat lunak Anda atau Anda perlu melakukan ini

mine.U = fbx.U

mine.V = 1 - fbx.V

Juga FBX tergantung pada eksportir (pengalaman saya dengan 3ds maks) itu akan mengubah Y & Z hanya untuk terjemahan, rotasi akan terbalik. Yang ingin saya katakan adalah jika Anda mengekspor (dalam 3ds maks) Y-UP, lclTranslation akan cocok dengan 1: 1 tetapi lclRotasi akan seperti ini

myRot.x = fbxRot.x

myRot.y = fbxRot.z

myRot.z = fbxRot.y

Juga ingat untuk memeriksa untuk memeriksa apakah sistem koordinat Kiri atau Kanan dan apakah itu sesuai dengan apa yang diharapkan perangkat lunak Anda, jika tidak memperbaikinya.

Membuat dan importir khusus untuk FBX itu menantang jangan menyerah!

Carlos Ch
sumber
2

Mendapatkan koordinat tekstur untuk model dengan satu set UV Menggunakan FBX SDK 2013:

// 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 );
     }
}
Syntac_
sumber