Mesh
Mesh
今日のターゲットFBXファイルを読んで、スクリーンに置いてください!
これまで,表現の対象はハードコーディングで直接成形されたものであった.
しかし、実際の作業では、このような場合は、予め作成されたオブジェクトを読むことでほとんど使われています.
FBXファイルには、Material、Mesh、Animation、Bone、Skinなど様々なモデルに関する情報が含まれています.
FBXライブラリからFBXファイルを読み込みます.
void FBXLoader::LoadFbx(const wstring& path)
{
// 파일 데이터 로드
Import(path);
// Animation
//LoadBones(_scene->GetRootNode());
//LoadAnimationInfo();
// 로드된 데이터 파싱 (Mesh/Material/Skin)
ParseNode(_scene->GetRootNode());
// 우리 구조에 맞게 Texture / Material 생성
CreateTextures();
CreateMaterials();
}
void FBXLoader::Import(const wstring& path)
{
// FBX SDK 관리자 객체 생성
_manager = FbxManager::Create();
// IOSettings 객체 생성 및 설정
FbxIOSettings* settings = FbxIOSettings::Create(_manager, IOSROOT);
_manager->SetIOSettings(settings);
// FbxImporter 객체 생성
_scene = FbxScene::Create(_manager, "");
// 나중에 Texture 경로 계산할 때 쓸 것
_resourceDirectory = fs::path(path).parent_path().wstring() + L"\\" + fs::path(path).filename().stem().wstring() + L".fbm";
_importer = FbxImporter::Create(_manager, "");
string strPath = ws2s(path);
_importer->Initialize(strPath.c_str(), -1, _manager->GetIOSettings());
_importer->Import(_scene);
_scene->GetGlobalSettings().SetAxisSystem(FbxAxisSystem::DirectX);
// 씬 내에서 삼각형화 할 수 있는 모든 노드를 삼각형화 시킨다.
FbxGeometryConverter geometryConverter(_manager);
geometryConverter.Triangulate(_scene, true);
_importer->Destroy();
}
void FBXLoader::ParseNode(FbxNode* node)
{
FbxNodeAttribute* attribute = node->GetNodeAttribute();
if (attribute)
{
switch (attribute->GetAttributeType())
{
case FbxNodeAttribute::eMesh:
LoadMesh(node->GetMesh());
break;
}
}
// Material 로드
const uint32 materialCount = node->GetMaterialCount();
for (uint32 i = 0; i < materialCount; ++i)
{
FbxSurfaceMaterial* surfaceMaterial = node->GetMaterial(i);
LoadMaterial(surfaceMaterial);
}
// Tree 구조 재귀 호출
const int32 childCount = node->GetChildCount();
for (int32 i = 0; i < childCount; ++i)
ParseNode(node->GetChild(i));
}
void FBXLoader::LoadMesh(FbxMesh* mesh)
{
_meshes.push_back(FbxMeshInfo());
FbxMeshInfo& meshInfo = _meshes.back();
meshInfo.name = s2ws(mesh->GetName());
const int32 vertexCount = mesh->GetControlPointsCount();
meshInfo.vertices.resize(vertexCount);
meshInfo.boneWeights.resize(vertexCount);
// Position
FbxVector4* controlPoints = mesh->GetControlPoints();
for (int32 i = 0; i < vertexCount; ++i)
{
meshInfo.vertices[i].pos.x = static_cast<float>(controlPoints[i].mData[0]);
meshInfo.vertices[i].pos.y = static_cast<float>(controlPoints[i].mData[2]);
meshInfo.vertices[i].pos.z = static_cast<float>(controlPoints[i].mData[1]);
}
const int32 materialCount = mesh->GetNode()->GetMaterialCount();
meshInfo.indices.resize(materialCount);
FbxGeometryElementMaterial* geometryElementMaterial = mesh->GetElementMaterial();
const int32 polygonSize = mesh->GetPolygonSize(0);
assert(polygonSize == 3);
uint32 arrIdx[3];
uint32 vertexCounter = 0; // 정점의 개수
const int32 triCount = mesh->GetPolygonCount(); // 메쉬의 삼각형 개수를 가져온다
for (int32 i = 0; i < triCount; i++) // 삼각형의 개수
{
for (int32 j = 0; j < 3; j++) // 삼각형은 세 개의 정점으로 구성
{
int32 controlPointIndex = mesh->GetPolygonVertex(i, j); // 제어점의 인덱스 추출
arrIdx[j] = controlPointIndex;
GetNormal(mesh, &meshInfo, controlPointIndex, vertexCounter);
GetTangent(mesh, &meshInfo, controlPointIndex, vertexCounter);
GetUV(mesh, &meshInfo, controlPointIndex, mesh->GetTextureUVIndex(i, j));
vertexCounter++;
}
const uint32 subsetIdx = geometryElementMaterial->GetIndexArray().GetAt(i);
meshInfo.indices[subsetIdx].push_back(arrIdx[0]);
meshInfo.indices[subsetIdx].push_back(arrIdx[2]);
meshInfo.indices[subsetIdx].push_back(arrIdx[1]);
}
// Animation
LoadAnimationData(mesh, &meshInfo);
}
結果Reference
この問題について(Mesh), 我々は、より多くの情報をここで見つけました https://velog.io/@sansam41/Meshテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol