헛둘이 2023. 9. 12. 13:48

Mesh Collider란?

- 현재 우리 엔진은 모든 충돌 처리를 PhysX를 통해 처리하고 있는데, 한 가지 문제점은 구부러진 펜스같은 것들은 표현하기 어렵다는 것이다.

- 현재 내가 구현해놓은 Geometry는 박스, 구, 캡슐인데, 플레이어의 접근을 막기 위해서는 펜스의 모양을 흉내낸 여러개의 박스 콜라이더를 잔뜩 붙여야 했다.  

- 팀원과 회의를 통해 유니티에서 메쉬 콜라이더라는 충돌체를 지원한다는 얘기를 들었고 이 충돌체는 메쉬가 가진 정점과 인덱스를 이용해서 충돌체를 만들어낸다.

이와 비슷한 것을 PhysX에서 TriangleMeshGeometry라는 이름으로 지원한다는 것을 어렴풋이 알고 있었기 때문에 PhysX Docs를 참고해서 기능을 구현할 수 있었다.

- 우리 엔진에서 메쉬란 MeshContainer라는 이름으로 여러 개의 하위 메쉬를 소유하고 있고, 그려줄 때 이 하위 메쉬를 순회하며 그려주는 원리인데 콜라이더를 만들려면 이 하위 메쉬들을 하나의 메쉬로 뭉쳐야할 필요성이 있었다.

- FBX로드할 때 정점 데이터와 인덱스 데이터를 소유하고 있던게 신의 한수였던 것 같다.

- 이 데이터를 다시 순회하며 모든 정점과 인덱스를 하나의 정점배열과 하나의 인덱스배열로 뭉친 후, 이 데이터를 이용해서 메쉬 형태의 콜라이더를 만들어낼 수 있었다.

 

TriangleMeshInfo Mesh::GetTriangleMeshInfo()
{
	TriangleMeshInfo info = {};

	UINT32 totalVertices = 0;
	UINT32 totalIndices = 0;
		
	int vtxAccCount = 0;
	int idxAccCount = 0;

	for (int i = 0; i < mMeshContainerVec.size(); ++i)
	{
		totalVertices += mMeshContainerVec[i]->vertexBufferInfo.count;
		totalIndices += mMeshContainerVec[i]->indexBufferGroup[0].count;
	}

	info.vertices.resize(totalVertices);
	info.indices.resize(totalIndices);

	for (int i = 0; i < mMeshContainerVec.size(); ++i)
	{
		UINT32 verticeCount = mMeshContainerVec[i]->vertexBufferInfo.count;
		int vertexSize = sizeof(Vertex);
		int vertexOffset = 0;
		for (UINT32 j = 0; j < verticeCount; ++j)
		{
			Vertex* v = new Vertex;
			memcpy(v, (char*)mMeshContainerVec[i]->vertexBufferInfo.pData + vertexOffset, vertexSize);
			info.vertices[vtxAccCount + j] = (*v).pos;
			vertexOffset += vertexSize;
			SAFE_DELETE(v);
		}

		UINT32 indicesCount = mMeshContainerVec[i]->indexBufferGroup[0].count;
		int indexSize = sizeof(int);
		int indexOffset = 0;

		for (UINT32 j = 0; j < indicesCount; ++j)
		{
			int* idx = new int;
			memcpy(idx, (char*)mMeshContainerVec[i]->indexBufferGroup[0].pData + indexOffset, indexSize);
			info.indices[idxAccCount + j] = vtxAccCount + *idx;
			indexOffset += indexSize;
			SAFE_DELETE(idx);
		}

		vtxAccCount += verticeCount;
		idxAccCount += indicesCount;
	}

	return info;
}

 - TriangleMeshInfo는 TriangleMesh를 만들어주기 위한 구조체이며, 여기에 넣고 반환한 리턴값을 PhysX에 넘겨줘서 메쉬 모양의 충돌체를 만들 수 있다.