객체의 축이 평행한 경우의 충돌은 단순하게 구현할 수 있다.
만약, 회전을 통해 객체의 축이 평행하지 않은 경우에는 어떻게 구현을 해야 할까?
OBB
회전을 하게 되면 두 객체의 축이 평행하지 않게 된다. 이 경우에는 다음과 같은 과정이 이어진다.
1. 두 객체의 중점을 잇는 차이 벡터를 구한다.
2. 네 개의 축 중 하나의 축의 단위벡터와 차이 벡터를 내적하여 절댓값을 찾는다. (a)
3. a와 같은 방향을 가지는 단위벡터와, 객체의 중점에서부터 스케일값만큼 뻗어진 가로 벡터, 세로 벡터를 찾는다. (b)
4. a와 b 과정에서 나온 4개의 절댓값을 더한 값을 비교하여 a가 더 크다면 충돌하지 않은 것, b가 더 크다면 충돌한 것으로 판정한다.
5. 단, 이 과정을 총 네 번 반복하고 모두 만족해야 완전히 충돌한 것이라고 할 수 있다.
bool InterSectOBB(Object rect1, Object rect2)
{
Vector2 dis = rect1->GetWorldPos() - rect2->GetWorldPos();
Vector2 axis[4] = {};
axis[0] = Vector2(rect1->GetRight().x * (rect1->scale.x * 0.5f), rect1->GetRight().y * (rect1->scale.y * 0.5f));
axis[1] = Vector2(rect1->GetUp().x * (rect1->scale.x * 0.5f), rect1->GetUp().y * (rect1->scale.y * 0.5f));
axis[2] = Vector2(rect2->GetRight().x * (rect2->scale.x * 0.5f), rect2->GetRight().y * (rect2->scale.y * 0.5f));
axis[3] = Vector2(rect2->GetUp().x * (rect2->scale.x * 0.5f), rect2->GetUp().y * (rect2->scale.y * 0.5f));
Vector2 unit[4] = { rect1->GetRight(), rect1->GetUp(), rect2->GetRight(), rect2->GetUp() };
float sum[4] = {};
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
sum[i] += fabs(axis[j].Dot(unit[i]));
}
if (fabs(dis.Dot(unit[i])) < sum[i])
{
return false;
}
}
return true;
}
'프로그래밍 > 공부' 카테고리의 다른 글
[Game] Uv 좌표 (0) | 2023.01.22 |
---|---|
[Game] 객체 가두기 (0) | 2023.01.17 |
[Game] 충돌 (0) | 2023.01.13 |
[DirectX] 렌더링 파이프라인 - (2) (0) | 2023.01.06 |
[DirectX] 셰이더(Shader) (0) | 2023.01.04 |
댓글