AABB 和平面的相交性检测
AABB : pmin 和 pmax
平面 :p⋅n=dis ,其中 n 为单位向量。
1. 静态检测
计算 AABB 顶点和 n 的点积,通过比较点积结果与 dis ,来检测 AABB 的顶点是否完全在平面的一边,或是在另一边。
- 如果所有点积都大于 dis ,那么整个 AABB 就在平面的正面所指的一侧;
- 如果所有点积都小于 dis ,那么整个 AABB 就在平面的反面所指的一侧。
实际上,不需要检测全部的 8 个顶点。
- 若 nx>0 ,点积最小的顶点是 x=xmin ,点积最大的顶点是 x=xmax ;
- 若 nx<0 ,点积最小的顶点是 x=xmax ,点积最大的顶点是 x=xmin 。
- 对于 ny , nz 同理。
计算最小点积 minD
和最大点积 maxD
的值:
- minD⩾dis :AABB 在平面的正面;
- maxD⩽dis :AABB 在平面的背面;
- minD⩽dis⩽maxD :AABB 与平面相交。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
int AABB3::classifyPlane(const Vector3& n, float d) const {
float minD, maxD;
if (n.x > 0.0f) { minD = n.x * min.x; maxD = n.x * max.x; } else { minD = n.x * max.x; maxD = n.x * min.x; }
if (n.y > 0.0f) { minD += n.y * min.y; maxD += n.y * max.y; } else { minD += n.y * max.y; maxD += n.y * min.y; }
if (n.z > 0.0f) { minD += n.z * min.z; maxD += n.z * max.z; } else { minD += n.z * max.z; maxD += n.z * min.z; }
if (minD >= d) { return +1; }
if (maxD <= d) { return -1; }
return 0; }
|
2. 动态检测
// TODO