Intersection with a ray and an AABB

광선과 AABB가 교차하는지를 평가하는 함수이다. 이 함수는 Stefan Zerbst의 책 “3D Game Engine Programming”의 138~140쪽에 나오는 ZFXRay::Intersects 함수를 VB.NET으로 변환한 것이다. 이 함수의 원천적인 알고리즘은 Andrew Woo의 알고리즘에서 비롯한 것이다.

[vbnet]Function IntersectionAABBonText(ByVal RayDirection As Vector3D, ByVal RayOrigin As Vector3D) As Boolean
Dim RayInsideAABB As Boolean = True
Dim HitPoint As Vector3D
Dim MaxT As New Vector3D(-1.0F, -1.0F, -1.0F)
Dim Epsilon As Single = 0.00001F

‘Find the x component
If (RayOrigin.X < Me.m_Min.X) Then HitPoint.X = Me.m_Min.X RayInsideAABB = False If RayDirection.X <> 0.0F Then
MaxT.X = (Me.m_Min.X – RayOrigin.X) / RayDirection.X
End If
ElseIf (RayOrigin.X < Me.m_Max.X) Then HitPoint.X = Me.m_Max.X RayInsideAABB = False If RayDirection.X <> 0.0F Then
MaxT.X = (Me.m_Max.X – RayOrigin.X) / RayDirection.X
End If
End If
‘Find the y component
If (RayOrigin.Y < Me.m_Min.Y) Then HitPoint.Y = Me.m_Min.Y RayInsideAABB = False If RayDirection.Y <> 0.0F Then
MaxT.Y = (Me.m_Min.Y – RayOrigin.Y) / RayDirection.Y
End If
ElseIf (RayOrigin.Y > Me.m_Max.Y) Then
HitPoint.Y = Me.m_Max.Y
RayInsideAABB = False
If RayDirection.Y <> 0.0F Then
MaxT.Y = (Me.m_Max.Y – RayOrigin.Y) / RayDirection.Y
End If
End If
‘Find the z component
If (RayOrigin.Z < Me.m_Min.Z) Then HitPoint.Z = Me.m_Min.Z RayInsideAABB = False If RayDirection.Z <> 0.0F Then
MaxT.Z = (Me.m_Min.Z – RayOrigin.Z) / RayDirection.Z
End If
ElseIf (RayOrigin.Z > Me.m_Max.Z) Then
HitPoint.Z = Me.m_Max.Z
RayInsideAABB = False
If RayDirection.Z <> 0.0F Then
MaxT.Z = (Me.m_Max.Z – RayOrigin.Z) / RayDirection.Z
End If
End If

‘—- Ray origin inside bounding box
‘광선의 시점이 박스 안에 있다. 이 판단이 내 프로그램에서 유용할 것인가?
‘내 프로그램은 기본적으로 3D Face이기 때문에 정확한 판단이 아닐 수도 있다.
If RayInsideAABB Then
HitPoint = RayOrigin
Return True
End If

‘—- Get largest of the maxT’s for final choice of intersection
‘최대값 구하기
Dim nPlane As Integer = 0
If (MaxT.Y > MaxT(nPlane)) Then nPlane = 1
If (MaxT.Z > MaxT(nPlane)) Then nPlane = 2

‘—- Check final candidate actually inside box
If (MaxT(nPlane) < 0.0F) Then Return False If nPlane <> 0 Then
HitPoint.X = RayOrigin.X + MaxT.X * RayDirection.X
If (HitPoint.X < Me.m_Min.X - Epsilon) OrElse (HitPoint.X > Me.m_Max.X + Epsilon) Then
Return False
End If
End If
If nPlane <> 1 Then
HitPoint.Y = RayOrigin.Y + MaxT.Y * RayDirection.Y
If (HitPoint.Y < Me.m_Min.Y - Epsilon) OrElse (HitPoint.Y > Me.m_Max.Y + Epsilon) Then
Return False
End If
End If
If nPlane <> 2 Then
HitPoint.Z = RayOrigin.Z + MaxT.Z * RayDirection.Z
If (HitPoint.Z < Me.m_Min.Z - Epsilon) OrElse (HitPoint.Z > Me.m_Max.Z + Epsilon) Then
Return False
End If
End If
Return True
End Function[/vbnet]

Print Friendly, PDF & Email