본문 바로가기

DirectX11 3D/기본 문법

<DirectX11 3D> 34. ModelEditor - Converter(Assimp)

프로젝트 구조


Framework (모델 불러오기, 렌더링)
<- UnitTest
<- ModelEditor(우리가 원하는 형태로 파일 저장)

 

 

 

필요한 개념


<3D Model file format>

FBX
3DS
OBJ
MD5
...

 

-> 여러가지 포맷을 불러들일 수 있도록 Assimp라는 라이브러리가 있다.(오픈소스)
Assimp는 여러가지 포맷을 불러들여서 Assimp라는 포맷(공통적인)으로 바꾼다.

 

* Tip
- 3D 파일 포맷은 게임을 위해서만 제작된 것이 아니므로 게임에서는 필요 없는 데이터도 많이 들어있다.
- ex) Assimp로 불러들였는데, 우리가 이미 만들어논 카메라 데이터, 라이트 데이터가 들어옴(불필요한 것들)
-> Assimp는 여러많은 포맷들을 공통구조로 불러주므로 우리가 필요한 데이터만 꺼내서 우리가 원하는 변수로 추출한
다음 우리가 원하는 형태의 파일로 저장해서 사용할 것이다.

 

- 편집 프로그램
3DSMax(압도적으로 많이씀), Maya -> AutoDesk(Fbx포멧을 만들어냄)
Blender -> OpenSource

fbx 포맷은 표준에 가까워서 모든 게임엔진이 기본으로 지원한다.

Assimp의 구조만 알면 된다.(Assimp는 여러 포맷들을 불러 들일때 Assimp구조로 불러들인다.)

- Assimp 구조

Assimp 내부 구조

 


Importer로 3D 파일을 불러온 후 Scene 객체를 리턴, Scene에 모델 정보가 있다.
(Importer->Scene)

Scene은 Materials라는 배열, Meshes 배열을 가지고 있다.
Scene  - Materials(재질 : 색상과 텍스쳐를 가지고 있다.)
- Meshes(실제 렌더링 될 데이터가 들어가 있다.)
- SceneRoot(부모, 자식관계로 된 트렌스폼 정보를 가지고 있다.)
| body               -> Material(Materials 배열의 번호만 가지고 있다.)
-> Mesh(Meshes 배열의 번호만 가지고 있다.) -Vertices, Indices
-> Transformation(Matrix) : 부모와 자식간의 연관관계 유지를 위해(머리가 이동하면 몸전체를 이동..)
| 바퀴
| 바퀴
| 포탑
   | 포신

 

 

 

 


Transformation 추가 설명 : A가 30 이동하면(자식 B도 30이동됨), 그 후 B가 20이동하면 B만 이동됨(B의 Local(Relative : 관계(부모에서 얼마나 이동했나)) 20 이동한것이 되고)
30이동은 world로 이동한 것이다.

 

 


우리는 Model을 구성할 것이다.
Model  -  ModelBone(Transformation 정보를 가짐) ->즉 Bone은 Mesh가 그려질 위치의 트랜스폼을 가지고 있다.
-  ModelMesh(Meshes 정보가짐(vertices, indices))
-  Material



ModelEditor 프로젝트 생성후(Framework 빌드 후 이벤트 세팅)

class Converter -> Assimp에서 불러온것을 우리가 원하는 형태로 변환하는 클래스 작성

assimp라이브러리는 구글에 검색해서 github 혹은 공식사이트에서 다운로드후 빌드후에 라이브러리로 사용하면 된다.

 

 

 

 

 

 

.h


더보기
더보기
#pragma once

class Converter
{
public:
	Converter();
	~Converter();

	void ReadFile();

private:
	// 모델 파일 주소
	wstring file;

	// Scene 로드를 위해
	Assimp::Importer* importer;
	// Model 관련된 정보가 있다.
	const aiScene* scene;
};

 

 

 

 

 

 

 

.Cpp


더보기
더보기
#include "stdafx.h"
#include "Converter.h"

Converter::Converter()
{
	importer = new Assimp::Importer();
}

Converter::~Converter()
{
	SafeDelete(importer);
}

void Converter::ReadFile()
{
	this->file = L"../;../_Assets/" + file;

	// aiProcess_ConvertToLeftHanded : 왼손좌표계로 수정, 우리는 왼손좌표계, 행우선(가로)를 사용한다. 우리는 행우선으로
	// x,y,z하는데
	// 일반 3D 그래픽은 오른손좌표계, 열우선(세로)을 사용한다. 열우선은 세로 축 방향으로 x,y,z한다.
	
	// 우리가 아는 삼각형으로 모델을 디자인 하는 방식 외에도 스컬팅, 넙스 등 여러가지 포맷이 있다.
	// 그리는 방식이 많다.
	// 그러나 우리는 삼각형으로 그린다.
	// aiProcess_Triangulate : 삼각형으로 변환해서 데이터를 달라
	// aiProcess_GenUVCoords : 우리가 위에 삼각형으로 바꿨으니까 UV도 변환해서 달라는 얘기
	// aiProcess_GenNormals : 삼각형 단위로 바뀌었으니까, 노멀도 다시 계산해달라
	// aiProcess_CalcTangentSpace : 나중에 NormalMap할때 설명해주심

	scene = importer->ReadFile(String::ToString(this->file),
		aiProcess_ConvertToLeftHanded | aiProcess_Triangulate | aiProcess_GenUVCoords |
		aiProcess_GenNormals | aiProcess_CalcTangentSpace);

	// 부를 수 없다면 scene이 null이 나온다.
	assert(scene != nullptr);
}

 

 

 

 

 

 

 

 

.fx


 

 

 

 

 

 

 

 

 

 

 

결과