게임 개발/[D3D_Portfolio] DirectX3D 팀 포트폴리오 작업일지
17. PhysX를 이용한 Mesh Collider 구현
헛둘이
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에 넘겨줘서 메쉬 모양의 충돌체를 만들 수 있다.