2차원 공간에서의 충돌은 일반적으로 점과 면, 면과 면의 충돌이다. 면은 사각형과 원으로 나뉘며, 사각형은 회전값 변화 여부에 따라 AABB와 OBB로 나뉜다.
https://eunsikk.tistory.com/22
[Game] 충돌
특정 오브젝트가 다른 오브젝트와 충돌을 했을 때, 이를 어떻게 확인하면 좋을까? 우선 단순하게는 해당 객체의 좌표가 다른 객체의 좌표와 겹쳐졌을 때 반응을 일으키면 된다. 충돌을 판정하는
eunsikk.tistory.com
https://eunsikk.tistory.com/23
[Game] 충돌 (2)
객체의 축이 평행한 경우의 충돌은 단순하게 구현할 수 있다. 만약, 회전을 통해 객체의 축이 평행하지 않은 경우에는 어떻게 구현을 해야 할까? OBB 회전을 하게 되면 두 객체의 축이 평행하지
eunsikk.tistory.com
2차원의 충돌은 이렇게 쉽게 설명이 가능하지만 3차원 공간에서의 충돌은 좀 더 복잡하다.
단순히 생각하여 3차원에는 깊이값이 존재하여 우리에게 원근감을 선사한다. 이 깊이값이 가지는 의미는 해당 오브젝트가 3차원 공간의 원점을 기준으로 앞뒤 방향으로 얼마나 움직였냐를 의미한다.
만약, 이 오브젝트와 마우스의 충돌을 구현하고 싶을 경우에는 어떤 식으로 해야 할까.
이 문제의 해답은 바로 레이 캐스팅, 혹은 레이 트레이싱이라는 기법에 있다.
원래는 3D 렌더링 기법의 일종으로 나온 것이나 우리는 이 기법을 통해 점과 오브젝트의 충돌을 확인할 수 있다.
우선 레이는 광선, 즉 일직선으로 뻗은 빛의 선을 의미한다. 2차원에서는 단순히 점이었지만 3차원에 와서는 깊이값을 가지므로 1차원의 점을 2차원의 선으로 변경해야 한다.
레이 캐스팅은, 가상 공간에 보이지 않는 빛(Ray)를 투사해 빛에 닿는 표면을 파악하는 기술이다. 이때 광선의 길이는 무한하고, 가상의 빛이기 때문에 마우스 포인터가 이 점에 대응할 수 있다.
D3D에는 Ray라는 클래스가 정의되어 있다. 내부 값은 위치를 갖는 벡터와 방향을 갖는 벡터가 있다.
한 마디로, 광선의 시작점과 해당 광선이 뻗어가는 방향을 가지는 클래스이다.
우리는 클래스 Ray와 오브젝트만 있으면 빛에 닿은, 마우스 포인터로 해석하면 마우스 포인터와 닿은 부분을 찾을 수 있다.
정말 다행스럽게도 D3D 내부에 정의된 Ray의 안에는 충돌을 확인하는 함수가 있다.
해당 함수의 매개변수는 BoundingBox와 float의 레퍼런스이며, 함수를 호출한 Ray가 해당 박스와 충돌하였다면 거리를 float 변수에 담는다.
또한 우리는 여기에 Ray의 시작 위치와 방향을 알고 있기 때문에 추가된 거리(Distance, dis)를 이용해 충돌한 지점을 알 수 있게 된다.
bool Collider::Intersect(Ray Ray, Vector3& Hit)
{
Ray.direction.Normalize();
float Dis;
bool result = false;
if (type == ColliderType::BOX)
}
BoundingBox box1;
box1.Center = GetWorldPos();
box1.Extents = Vector3(S._11, S._22, S._33);
result = Ray.Intersects(box1, Dis);
Hit = Ray.position + Ray.direction * Dis;
}
return result;
}
'프로그래밍 > 공부' 카테고리의 다른 글
[Graphcis] 스키닝 애니메이션 (0) | 2023.06.22 |
---|---|
[DirectX3D] 광원 효과 - (1) (1) | 2023.06.08 |
[C++] std::Function (0) | 2023.05.25 |
[Graphics] 3D 환경에서 회전 (1) | 2023.05.16 |
[Graphics] 정점, 폴리곤, 메시 (0) | 2023.05.08 |
댓글