5. 交差判定・Rayと三角形
Ray
P
交差判定はメッシュのローカル座標系で行う
プログラミング上の注意点
• Transform.InverseTransformDirecHon()
• Ray.direcHon
これらは、Ray
の方向ベクトルを正規化してしまうため使えない
以下のようにローカル座標の非正規化
Ray
を求める:
Vector3
rayOrigin
=
transform.InverseTransformPoint(ray.origin);
Vector3
rayDirecHon
=
transform.worldToLocalMatrix
*
(Vector4)
ray.direcHon;
6. 交差判定・Rayと三角形(cont’d)
計算には
“Fast
,
Minimum
Storage
Ray/Triangle
IntersecHon”
[Tomas
Möller
1997]
のアルゴリズムを使用。以下その説明
始点
O、方向
D
の
Ray
が
距離
t
で位置 P
に当たると
P = O + tD
三角形上の位置
P
は
バリセントリック座標(u,v)で
P = (1− u − v)V0 + uV1 + vV2
V1
O
D
u
t
P
V0
v
V2
7. 交差判定・Rayと三角形(cont’d)
三角形上の位置
P
は
バリセントリック座標(u,v)で
P = (1− u − v)V0 + uV1 + vV2
始点
O、方向
D
の
Ray
が
長さ t
で位置 P
に当たると
P = O + tD
(1− u − v)V0 + uV1 + vV2 = O + tD
行列で表せば
! t $
#
&
[−D,V1 − V0 ,V2 − V0 ]# u & = O − V0
# v &
"
%
8. 交差判定・Rayと三角形(cont’d)
! t $
#
&
[−D,V1 − V0 ,V2 − V0 ]# u & = O − V0
# v &
"
%
クラメールの公式を使って
! t $
#
&
1
# u & = −D, E , E
1
2
# v &
"
%
! T, E , E
1
2
#
# −D,T, E2
#
# −D, E1,T
"
$
&
&
&
&
%
• t
:
Rayの長さ
• (u,
v)
:
バリセントリック座標
9. 交差判定・Rayと三角形(cont’d)
! t $
#
&
1
# u & = −D, E , E
1
2
# v &
"
%
! T, E , E
1
2
#
# −D,T, E2
#
# −D, E1,T
"
$
&
&
&
&
%
A, B, C = −(A × C)⋅ B = −(C × B)⋅ A
! Q⋅E $
! t $
2
#
&
#
&
1
# u & = P ⋅ E # P ⋅T &
1 # Q⋅D &
# v &
"
%
"
%
{P = (D × E2 ),Q = T × E1 }
• t
:
Rayの長さ
• (u,
v)
:
バリセントリック座標
10. 交差判定・Rayと三角形(cont’d)
! Q⋅E $
! t $
2
#
&
#
&
1
# u & = P ⋅ E # P ⋅ T &
1 # Q⋅D &
# v &
"
%
"
%
ここが 0
だと、Ray
と三角形が平行
(交差しないので処理をスキップ)
交差するのは以下の時だけ(それ以外はスキップ)
0 ≤ u ≤ 1, 0 ≤ v ≤ 1, 0 ≤ u + v ≤ 1,
候補を絞りこんで
距離 t
を求めて、最近メッシュを保持
• データベースからその部位の情報を取得
• その部位のマテリアル変更
•
•
•
•
t
:
Rayの長さ
(u,
v)
:
バリセントリック座標
P
=
D
x
E2
Q
=
T
x
E1