StaticMesh를 렌더할 수 있도록 엔진을 만들었다.
해당 엔진에 FBX 파일을 임포트하여, StaticMesh로 변환한 뒤 렌더하는 기능을 구현한다.
서브 메시 개념은 생각하지 못해 이후에 도입했습니다.
Assimp에서 제공하는 플래그를 통해 내가 만든 엔진 구조에 맞게 읽음
aiScene
Assimp::Importer::ReadFile()의 결과는 aiScene*이며, 이 객체가 임포트된 모델의 루트 컨테이너다.
주요 멤버
scene->mRootNode : 노드 트리의 루트scene->mMeshes[] : 메시 배열(실제 geometry 데이터)scene->mMaterials[] : 머티리얼 배열scene->mNumTextures / mTextures[] : embedded texture(내장 텍스처) 배열이걸 봤을 때 Mesh와 Material이 배열인걸 보고 뭔가 잘못됐다 생각함. 내 엔진은 StaticMeshComp 1--1 MeshData 1--1 Material 1대1구조임
aiNode
Assimp 구조에서 노드(aiNode)는 트랜스폼을 가진다.
반면, 메시 데이터는 scene->mMeshes[idx]에 있다.
node->mMeshes[]로 참조하는 mesh index를 보유scene->mMeshes[meshIndex]에 존재최종 코드에서는 DFS로 노드를 순회하며 누적 트랜스폼을 만든다:
global = parent * node->mTransformationscene->mMeshes[meshIndex]를 처리p' = global * pinverse-transpose(upper3x3(global)) 적용 후 normalize이를 통해 노드 트랜스폼(특히 스케일/회전)이 포함된 올바른 월드 공간 지오메트리를 얻는다.
기존 엔진 구조로 임포트 하기 위해 하나의 aiMesh만 사용해 임포트 하였더니 특정 부위가 정상적으로 구성되지 않은 것을 확인했다.
aiNode가 N개 이고, 다른 meshIndex를 사용하는 경우였다. 이를 고려해 ChildNode를 순회하며 버텍스를 생성해줘야한다.
ChildNode의 버텍스 정보는 캐싱해둬야 한다. 자세한 내용은 Material에서 다룬다.

텍스쳐 경로에 따라 처리 로직을 나눈다
텍스쳐가 FBX에 포함되어 있는 경우
if (const aiTexture* at = scene->GetEmbeddedTexture(t8.c_str()))를 통해 가져오기 시도CreateSRVFromEmbeddedRawBGRA8를 통해 SRV 변환scene->mTextures를 레퍼런스 하는 경우
"*index" 형태인지 검사scene->mTextures접근하여 CreateSRVFromEmbeddedRawBGRA8를 통해 SRV 변환외부 경로인지 확인
DirectX::CreateWICTextureFromFile위에서 봤듯이 scene->mMaterials[]은 배열이다.
각각의 메시가 참조하는 머티리얼이 다르다.
따라서 엔진에서도 메시를 작은 단위 (굳이 노드가 아니여도 됨)로 나누고 작은 단위의 메시 마다 머티리얼 참조를 할 수 있는 구조를 만들어야한다.
나는 하나의 머티리얼만 사용하는 줄 알고 0번을 레퍼런스 하도록 구현했었는데 아래와 같이 0번 머티리얼을 사용하지 않는 메시의 머티리얼이 비정상적인 것을 볼 수 있다

이를 해결하기 위해 아래와 같이 대응했다



