[DirectX11] Ray와 물체의 충돌 판정 (Intersection)
Ray와 물체의 Intersection
Ray- Mesh
ray를 이용해서 picking을 하기 위해서는 일단 ray가 mesh를 지나는지를 알아야 할 것이다.
mesh를 이루는 각 삼각형들에 대해서 충돌 판정을 하고,
삼각형과 충돌이 확인되면 그 삼각형이 속한 mesh가 선택될 수 있다.
그러나 매 프레임마다 mesh를 이루는 수많은 삼각형에 대해서 충돌 체크를 한다면 부담이 될 것이다.
연산량을 줄이기 위해 bounding box와 같은 단순한 collider와 먼저 충돌 체크를 하고, 충돌했을 때 삼각형들을 체크한다.
bounding box와 충돌하지 않았으면 삼각형과도 충돌하지 않은 것이므로 연산을 할 필요가 없다.
picking, 충돌 감지 목적의 단순한 mesh가 따로 저장되어있는 경우도 있다.
uint32 pickedTriangle = -1;
float minDistance = 0.0f;
if(boundingBox.Intersects(rayOrigin, rayDir, OUT distance)
{
uint32 dMin = UINT32_MAX;
const auto& indices = _mesh->GetGeometry()->GetIndices();
for(int32 i = 0; i < indices.size(); i++)
{
uint32 index[3];
index[0] = indices[i*3+0];
index[1] = indices[i*3+1];
index[2] = indices[i*3+2];
Vector3 vertex[3];
for(int32 j = 0; j < 3; v++)
vertex[j] = vertices[index[j]].position;
float& d = 0.0f;
if(ray.Intersects(vertex[0], vertex[1], vertex[2], OUT d))
{
if(d < dMin)
{
dMiin = d;
pickedTriangle = i;
}
}
}
distance = dMin;
}
Ray - Bounding Box
위에서 설명한 것처럼 mesh의 삼각형마다 충돌 판정을 하는 것은 부담이 되므로 bounding box와 같이 단순한 도형의 collider를 두는 것을 고려할 수 있다.
Box collider에는 크게 AABB와 OBB의 두 종류가 있다.
AABB(Axis-Aligned Bounding Box)
AABB는 축이 좌표계의 축과 일치하는 상자이다.
DirectXMath 에서 BoundingBox 로 제공되며, Intersects 함수를 이용하여 충돌 판정을 할 수 있다.
BoundingBox aabb;
aabb.Center = Vec3(0.0f);
aabb.Extents = Vec3(0.5f);
aabb.Intersects(ray.position, ray.direction, OUT distance);
OBB(Oriented Bounding Box)
OBB는 축이 좌표계의 축과 일치하지 않는 상자이다.
물체가 축에 나란하게 정렬되어 있지 않거나 회전하는 경우에 사용할 수 있다.
DirectXMath 에서 BoundingOrientedBox 로 제공되며 Orientation 으로 회전값을 설정할 수 있다.
마찬가지로 Intersects 함수를 사용하여 충돌 판정을 할 수 있다.
BoundingOrientedBox obb;
obb.Center = Vec3(0.0f);
obb.Extents = Vec3(0.5f);
obb.Orientation = Quaternion::CreateFromYawPitchRoll(45, 0, 0);
obb.Intersects(ray.position, ray.direction, OUT distance);
Ray - Sphere
구체는 BoundingSphere로 제공되며, Cender와 Radius 값을 가진다. 마찬가지로 Intersects 함수를 이용한다.
BoundingSphere sphere;
sphere.Center = Vec3(0.0f);
sphere.Radius = Vec3(0.5f);
sphere.Intersects(ray.position, ray.direction, OUT distance);
참고 자료
Introduction to 3D Game Programming with DirectX11 - Frank D. Luna
Rookiss님 인프런 멘토링 강의