Box采用OBB定义:
enum AxisDefine
{
X ,
Y ,
Z
};
// data member
Vector3f Center;
Vector3f Axis[3];
float extent[3]; // 边长的一半
Ray采用参数式 Point=Origin+t∗Direction,0≤t≤∞
// data
Vector3f Origin;
Vector3f Direction;
Ray.Origin⇒O
Ray.Direction⇒Dir−→−
Box.Center⇒C
Box.Extent[i]⇒ei
Box.Axis[i]⇒Axis[i]−→−−−
采用分离轴方法来进行碰撞检测:
一:首先我们使用Box的面法线(即坐标轴) Aixs[i]−→−−− 作为分离轴
在这种情况下Box在分离轴上的投影即为该轴向的边
计算光线起点在分离轴上的投影:
delta−→−−=O−C=CO−→−
ProRay=delta−→−−⋅Axis[i]−→−−−
Box在分离轴上的投影为:
−ei≤ProBox≤ei
当满足如下两种情况:
- ProRay>ei 且 Dir−→−⋅Axis[i]−→−−−≥0 (即光线方向与分离轴的方向范围为 (−90。,90。)
- ProRay<−ei 且 Dir−→−⋅Axis[i]−→−−−≤0
将二者结合: |ProRay|>ei and (Dir−→−⋅Axis[i]−→−−−)∗ProRay≥0
二:射线方向向量与面法线的叉乘作为分离轴
为了使得计算简单,我们可以将OBB转换为AABB
Dir−→−⇒Dir−→− ′=(Dir−→−⋅Axis[X]−→−−−−,Dir−→−⋅Axis[Y]−→−−−−,Dir−→−⋅Axis[Z]−→−−−−)
O⇒O ′=(delta−→−−⋅Axis[X]−→−−−−,delta−→−−⋅Axis[Y]−→−−−−,delta−→−−⋅Axis[Z]−→−−−−)
则Box的三个轴为:
Axis[X]−→−−−−⇒Axis[X]−→−−−− ′=(1,0,0)