본문 바로가기
프로그래밍/공부

[Game] 충돌 (2)

by Sik.K 2023. 1. 16.

객체의 축이 평행한 경우의 충돌은 단순하게 구현할 수 있다.

만약, 회전을 통해 객체의 축이 평행하지 않은 경우에는 어떻게 구현을 해야 할까?

OBB 충돌

 

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

댓글