我正在统一编程体素化算法。 现在事实证明,我需要在立方体和多边形之间进行一些狂热的交叉检查。
实际上我在这里有一个代码。
public static bool Intersects(Triangle tri, Bounds aabb)
{
float p0, p1, p2, r;
Vector3 extents = aabb.max - aabb.center;
Vector3 v0 = tri.a - aabb.center,
v1 = tri.b - aabb.center,
v2 = tri.c - aabb.center;
Vector3 f0 = v1 - v0,
f1 = v2 - v1,
f2 = v0 - v2;
Vector3 a00 = new Vector3(0, -f0.z, f0.y),
a01 = new Vector3(0, -f1.z, f1.y),
a02 = new Vector3(0, -f2.z, f2.y),
a10 = new Vector3(f0.z, 0, -f0.x),
a11 = new Vector3(f1.z, 0, -f1.x),
a12 = new Vector3(f2.z, 0, -f2.x),
a20 = new Vector3(-f0.y, f0.x, 0),
a21 = new Vector3(-f1.y, f1.x, 0),
a22 = new Vector3(-f2.y, f2.x, 0);
// Test axis a00
p0 = Vector3.Dot(v0, a00);
p1 = Vector3.Dot(v1, a00);
p2 = Vector3.Dot(v2, a00);
r = extents.y * Mathf.Abs(f0.z) + extents.z * Mathf.Abs(f0.y);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a01
p0 = Vector3.Dot(v0, a01);
p1 = Vector3.Dot(v1, a01);
p2 = Vector3.Dot(v2, a01);
r = extents.y * Mathf.Abs(f1.z) + extents.z * Mathf.Abs(f1.y);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a02
p0 = Vector3.Dot(v0, a02);
p1 = Vector3.Dot(v1, a02);
p2 = Vector3.Dot(v2, a02);
r = extents.y * Mathf.Abs(f2.z) + extents.z * Mathf.Abs(f2.y);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a10
p0 = Vector3.Dot(v0, a10);
p1 = Vector3.Dot(v1, a10);
p2 = Vector3.Dot(v2, a10);
r = extents.x * Mathf.Abs(f0.z) + extents.z * Mathf.Abs(f0.x);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a11
p0 = Vector3.Dot(v0, a11);
p1 = Vector3.Dot(v1, a11);
p2 = Vector3.Dot(v2, a11);
r = extents.x * Mathf.Abs(f1.z) + extents.z * Mathf.Abs(f1.x);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a12
p0 = Vector3.Dot(v0, a12);
p1 = Vector3.Dot(v1, a12);
p2 = Vector3.Dot(v2, a12);
r = extents.x * Mathf.Abs(f2.z) + extents.z * Mathf.Abs(f2.x);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a20
p0 = Vector3.Dot(v0, a20);
p1 = Vector3.Dot(v1, a20);
p2 = Vector3.Dot(v2, a20);
r = extents.x * Mathf.Abs(f0.y) + extents.y * Mathf.Abs(f0.x);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a21
p0 = Vector3.Dot(v0, a21);
p1 = Vector3.Dot(v1, a21);
p2 = Vector3.Dot(v2, a21);
r = extents.x * Mathf.Abs(f1.y) + extents.y * Mathf.Abs(f1.x);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
// Test axis a22
p0 = Vector3.Dot(v0, a22);
p1 = Vector3.Dot(v1, a22);
p2 = Vector3.Dot(v2, a22);
r = extents.x * Mathf.Abs(f2.y) + extents.y * Mathf.Abs(f2.x);
if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
{
return false;
}
if (Mathf.Max(v0.x, v1.x, v2.x) < -extents.x || Mathf.Min(v0.x, v1.x, v2.x) > extents.x)
{
return false;
}
if (Mathf.Max(v0.y, v1.y, v2.y) < -extents.y || Mathf.Min(v0.y, v1.y, v2.y) > extents.y)
{
return false;
}
if (Mathf.Max(v0.z, v1.z, v2.z) < -extents.z || Mathf.Min(v0.z, v1.z, v2.z) > extents.z)
{
return false;
}
var normal = Vector3.Cross(f1, f0).normalized;
var pl = new Plane(normal, Vector3.Dot(normal, tri.a));
return Intersects(pl, aabb);
}
public static bool Intersects(Plane pl, Bounds aabb)
{
Vector3 center = aabb.center;
var extents = aabb.max - center;
var r = extents.x * Mathf.Abs(pl.normal.x) + extents.y * Mathf.Abs(pl.normal.y) + extents.z * Mathf.Abs(pl.normal.z);
var s = Vector3.Dot(pl.normal, center) - pl.distance;
return Mathf.Abs(s) <= r;
}
但是很难理解这个过程及其工作原理...... 如果对此代码或其他简短算法进行简短解释,我们将非常感激。 欢呼声