본문 바로가기

Programming/물리엔진/게임엔진

구와 박스(OBB 또는 AABB)의 충돌체크

기본적으로 구와 구의 충돌 체크, AABB와 AABB의 충돌체크, OBB와 OBB의 충돌 체크는 인터넷 검색으로 찾을 수 있지만 캡슐과 캡슐, 구와 캡슐, 구와 OBB, 캡슐과 OBB는 찾기가 쉽지 않다. 그래서 대강 요약을 해보게 되었다.(캡슐과 캡슐, 구와 캡슐은 이전의 포스트에 있다.)


기본적으로 구와 AABB의 충돌 체크는 간단하다.

구의 중심벡터와 AABB의 각 길이, 깊이, 높이를 안다면 이들의 x,y,z값을 비교해 구에서 박스내부의 가장 가까운 점을 구하여 이 길이가 구의 반지름보다 작거나 같으면 충돌/겹칩 이 일어난 것이다.


기본적인 코드는 이런식으로 될 수 있다.


if (sphere.center().x < box.center().x - box.Length()/2.0f)

    boxPoint.x = box.center().x - box.Length() /2.0f;

else if ( sphere.center().x > box.center().x + box.Length()/2.0f )

    boxPoint.x = box.center().x + box.Length() /2.0f;

else

    boxPoint.x =  sphere.center().x ;


위의 과정을 y, z에 대해서도 해주면 박스위의 점 중 구와 가장 가까운 점(boxPoint)을 구할 수 있다.


그 뒤 이들의 거리가 구의 반지름보다 큰지 작은지를 알아 내면 되는것이다.

vector3 dist =  sphere.center()  - boxPoint;

float collisionDistance = Length(dist) - sphere.radius();


그렇다면 구와 OBB의 충돌 체크는 어떻게 할까......


가장 간단한 방법은 구의 중심 좌표를 OBB의 중심좌표계로 변환하여 OBB의 중심좌표를 원점으로 갖는 AABB형식으로 계산을 하면 간단하다.


OBB와 AABB의 차이는 AABB가 오브젝트가 회전을 할때 같이 회전을 하여 OBB가 되는것이다. 이 회전 행렬을 구하여 구의 중심에 곱해주어 구를 OBB의 좌표계로 변환하면 위의 AABB의 코드를 그 뒤에 그대로 가져다 쓰기만 하면 되는것이다.



더 이상의 자세한 설명은 생략한다.