Tengo un pequeño problema con la importación / visualización de archivos .fbx.
Revisé los ejemplos, pero los que más me interesan (animación y textura) están mal documentados para que alguien que es nuevo en esto los entienda como yo.
Esto es lo que he intentado: logré obtener los vértices y las normales, pero estoy atascado en obtener las coordenadas de textura para cada vértice.
Aquí está mi código hasta ahora:
3dModelBasicStructs.h
struct vertex
{
float x,y,z;
};
struct texturecoords
{
float a,b;
};
struct poligon
{
int a,b,c;
};
Modelo.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();
}
}
Mis preguntas son:
- ¿Cómo obtengo los cordones de textura?
- ¿Cómo hago para que Blender exporte la textura en formato de foto? (como .jpg o .tga)
- ¿Hay algún error en mi forma de mostrar hasta ahora?
- ¿Hay un proyecto en las muestras .fbx que solo muestre una escena (incluyendo animación y textura; no pude encontrar una yo mismo)?
No soy un experto en FBX pero tengo algo de experiencia, aquí están mis sugerencias
Sugeriría revisar el ejemplo en $ (FBXSDK) \ samples \ ImportScene
Esto le mostrará cómo obtener los códigos UV y otros datos.
No he trabajado con Blender exportando FBX, lo siento
Eché un vistazo rápido a su código, así que no puedo decir 100% si tiene errores, pero le daré algunas sugerencias que aprendo trabajando con FBX SDK.
Dependiendo del software 3D, debe verificar si necesita convertir sus UV Coords. Por ejemplo, podría ser lo mismo que su software espera o necesita hacer esto
mine.U = fbx.U
mine.V = 1 - fbx.V
También FBX dependiendo del exportador (mi experiencia con 3ds max) cambiará Y y Z solo para traducciones, la rotación se invertirá. Lo que quiero decir es que si exportas (en 3ds max) Y-UP, lclTranslation coincidirá con 1: 1 pero lclRotation será así
myRot.x = fbxRot.x
myRot.y = fbxRot.z
myRot.z = fbxRot.y
También recuerde verificar para verificar si el sistema de coordenadas es Izquierdo o Derecho y si coincide con lo que su software espera, si no lo corrige.
La creación y el importador personalizado para FBX es un desafío, ¡no te rindas!
fuente
Obtención de coordenadas de textura para modelos con un conjunto UV con FBX SDK 2013:
fuente