Nhập và hiển thị tệp .fbx


8

Tôi có một chút vấn đề với việc nhập / hiển thị tệp .fbx.

Tôi đã kiểm tra các ví dụ nhưng những cái mà tôi quan tâm nhất (hoạt hình và kết cấu) được ghi lại một cách tồi tệ để hiểu bởi một người mới biết điều này giống như tôi.

Đây là những gì tôi đã cố gắng: Tôi đã xoay sở để có được các đỉnh và các quy tắc nhưng tôi bị mắc kẹt trong việc lấy các kết cấu cho mỗi đỉnh.

Đây là mã của tôi cho đến nay:

3dModelBasicStructs.h

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

struct texturecoords
{
float a,b;
};

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

Người mẫu

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

Câu hỏi của tôi là:

  1. Làm thế nào để tôi có được các kết cấu coords?
  2. Làm cách nào để tạo máy xay xuất kết cấu ở định dạng ảnh? (như .jpg hoặc .tga)
  3. Có bất kỳ sai lầm trong cách hiển thị của tôi cho đến nay?
  4. Có một dự án nào trong các mẫu .fbx chỉ hiển thị một cảnh (bao gồm cả hoạt hình và kết cấu; tôi không thể tự tìm thấy một cảnh nào)?

Câu trả lời:


3

Về # 1 : Phương thức GetTextureUV của FbxMesh sẽ hoàn thành thủ thuật.

EDIT: Đoạn mã sau chưa được kiểm tra và sao chép khó khăn từ đây :

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: Tôi đã xem qua một số ví dụ khác mà tôi tìm thấy: Dường như có hai lớp tương tự: FbxVector2 và KFbxVector2 trong đó lớp sau có quyền truy cập trực tiếp vào các giá trị kép được bao gồm. So sánh ví dụ đó:

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

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

Bạn có thể sử dụng các loại K *?

EDIT3: Các loại K * đó rõ ràng là từ SDK FBX cũ hơn, do đó không phù hợp với tất cả mọi người.


Một chút chi tiết sẽ thực sự được đánh giá cao, như một lời giải thích hoặc một số ví dụ. (Tôi đã thấy phương pháp này nhưng không thực sự hiểu nó làm gì hoặc làm như thế nào).
Taigi

Vài phút trước, tôi đã chỉnh sửa trong một ví dụ nhỏ mà tôi thấy có thể giúp ích. Tôi chưa bao giờ làm việc với FBX, nói gì đến việc viết một nhà nhập khẩu, vì vậy tôi sợ rằng tôi thực sự không thể giúp đỡ nhiều hơn, xin lỗi.
Philip Allgaier

Hmm có vẻ khá tốt (tôi sẽ kiểm tra nó một chút sau) nhưng thnx rất nhiều điều này sẽ hoạt động! (Muốn bỏ phiếu nhưng tôi không thể :( tôi ghét có dưới 15 đại diện :()
Taigi

Tôi biết cảm giác. Tôi cũng muốn bình luận về một số chủ đề khác trước đó, nhưng bạn cần 50 đại diện cho điều đó. Bạn đã nhận được một phiếu bầu từ tôi cho chủ đề này, bởi vì nó cung cấp một điểm khởi đầu tốt cho những người khác. May mắn nhất!
Philip Allgaier

Đã thử nó ... Nó không hoạt động vì GetPolygonCount là một hàm bool và nó cũng yêu cầu 2 tham số
Taigi

2

Tôi không phải là chuyên gia về FBX nhưng tôi có một số kinh nghiệm với nó, đây là những gợi ý của tôi

Làm thế nào để tôi có được các kết cấu coords? Có một dự án nào trong các mẫu .fbx chỉ hiển thị một cảnh (bao gồm cả hoạt hình và kết cấu; tôi không thể tự tìm thấy một cảnh nào)?

Tôi sẽ đề xuất đi qua ví dụ trong $ (FBXSDK) \ samples \ ImportScene

Điều này sẽ chỉ cho bạn cách lấy UV Coords và các dữ liệu khác

Làm cách nào để tạo máy xay xuất kết cấu ở định dạng ảnh? (như .jpg hoặc .tga)

Tôi không làm việc với máy xay sinh tố xuất FBX, xin lỗi

Có bất kỳ sai lầm trong cách hiển thị của tôi cho đến nay?

Tôi đã xem nhanh mã của bạn, vì vậy không thể nói 100% nếu bạn có lỗi, nhưng tôi sẽ cung cấp cho bạn một số đề xuất mà tôi học được khi làm việc với FBX SDK.

Tùy thuộc vào Phần mềm 3D, bạn phải kiểm tra xem bạn có cần chuyển đổi UV Coords không. Ví dụ, nó có thể giống như những gì phần mềm của bạn mong đợi hoặc bạn cần làm điều này

của tôi.U = fbx.U

của tôi.V = 1 - fbx.V

Ngoài ra FBX tùy thuộc vào nhà xuất khẩu (kinh nghiệm của tôi với 3ds max), nó sẽ thay đổi Y & Z chỉ cho các bản dịch, xoay sẽ được đảo ngược. Điều tôi muốn nói là nếu bạn xuất (tối đa 3ds) Y-UP, lclTranslation sẽ khớp với 1: 1 nhưng lclRotation sẽ như thế này

myRot.x = fbxRot.x

myRot.y = fbxRot.z

myRot.z = fbxRot.y

Ngoài ra, hãy nhớ kiểm tra xem hệ thống tọa độ là Trái hay Phải và nếu nó phù hợp với những gì phần mềm của bạn mong đợi, nếu không sửa nó.

Tạo và nhập tùy chỉnh cho FBX là một thách thức không bỏ cuộc!


2

Nhận tọa độ kết cấu cho các mô hình với một bộ UV Sử dụng 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 );
     }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.