Importazione e visualizzazione di file .fbx


8

Ho un piccolo problema con l'importazione / visualizzazione di file .fbx.

Ho controllato gli esempi, ma quelli che mi interessano di più (animazione e trama) sono mal documentati per la comprensione da qualcuno che è nuovo in questo come me.

Questo è quello che ho provato: sono riuscito a ottenere i vertici e le normali, ma sono bloccato a ottenere i coordini delle trame per ciascun vertice.

Ecco il mio codice finora:

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

Le mie domande sono:

  1. Come ottengo i coords delle texture?
  2. Come posso esportare la texture in Blender in un formato fotografico? (come .jpg o .tga)
  3. Finora ci sono errori nella mia visualizzazione?
  4. Esiste un progetto nei campioni .fbx che mostra solo una scena (tra cui animazione e trama; non sono riuscito a trovarne uno da solo)?

Risposte:


3

Per quanto riguarda # 1 : il metodo GetTextureUV di FbxMesh dovrebbe fare il trucco.

EDIT: il seguente codice non è testato e copiato approssimativamente da qui :

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: Ho esaminato alcuni altri esempi che ho trovato: sembrano esserci due classi simili: FbxVector2 e KFbxVector2 dove quest'ultima ha l'accesso diretto ai valori doppi inclusi. Confronta quell'esempio:

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

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

Puoi usare quei tipi K *?

EDIT3: Quei tipi K * apparentemente provengono da un vecchio SDK FBX, quindi non sono rilevanti per tutti.


Un po 'più di dettaglio sarebbe davvero apprezzato, come una spiegazione o alcuni esempi. (Ho già visto questo metodo ma non ho davvero capito cosa fa o come lo fa).
Taigi,

Alcuni minuti fa, ho modificato in un piccolo esempio che ho trovato che può aiutare forse. Finora non ho mai lavorato con FBX, figuriamoci ho scritto un importatore, quindi temo di non poter essere di maggiore aiuto, scusa.
Philip Allgaier,

Hmm che sembra abbastanza buono (lo proverò un po 'più tardi) ma grazie mille dovrebbe funzionare! (Volevo votare ma non posso :( odio avere meno di 15 rep :()
Taigi

Conosco la sensazione. Volevo anche commentare alcuni altri thread prima, ma per questo sono necessari 50 rappresentanti. Ho già ottenuto un voto positivo da parte mia per questa discussione, perché fornisce un buon punto di partenza per gli altri. Buona fortuna!
Philip Allgaier,

Provato ... Non funziona poiché GetPolygonCount è una funzione bool e richiede anche 2 parametri
Taigi

2

Non sono un esperto di FBX ma ne ho una certa esperienza, ecco i miei suggerimenti

Come ottengo i coords delle texture? Esiste un progetto nei campioni .fbx che mostra solo una scena (tra cui animazione e trama; non sono riuscito a trovarne uno da solo)?

Suggerirei di esaminare l'esempio in $ (FBXSDK) \ samples \ ImportScene

Questo ti mostrerà come ottenere i raggi UV e altri dati

Come posso esportare la texture in Blender in un formato fotografico? (come .jpg o .tga)

Non lavoro con Blender che esporta FBX, mi dispiace

Finora ci sono errori nella mia visualizzazione?

Ho dato una rapida occhiata al tuo codice, quindi non posso dire al 100% se hai errori, ma ti darò alcuni suggerimenti che ho imparato lavorando con FBX SDK.

A seconda del software 3D, è necessario verificare se è necessario convertire i propri raggi UV. Ad esempio, potrebbe essere lo stesso di quello che il tuo software si aspetta o devi farlo

mine.U = fbx.U

mine.V = 1 - fbx.V

Anche FBX a seconda dell'esportatore (la mia esperienza con 3ds max) cambierà Y e Z solo per le traduzioni, la rotazione verrà invertita. Quello che voglio dire è se esporti (in 3ds max) Y-UP, lclTranslation corrisponderà a 1: 1 ma lclRotation sarà così

myRot.x = fbxRot.x

myRot.y = fbxRot.z

myRot.z = fbxRot.y

Ricorda inoltre di verificare se il sistema di coordinate è Sinistra o Destra e se corrisponde a ciò che il tuo software si aspetta, se non lo correggi.

La creazione e l'importatore personalizzato per FBX è impegnativo, non mollare!


2

Ottenere le coordinate delle trame per i modelli con un set UV Usando 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 );
     }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.