You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.8 KiB
133 lines
4.8 KiB
namespace UnityEngine.Rendering
|
|
{
|
|
internal static class ProbeVolumePositioning
|
|
{
|
|
internal static Vector3[] m_Axes = new Vector3[6];
|
|
internal static Vector3[] m_AABBCorners = new Vector3[8];
|
|
|
|
public static bool OBBIntersect(in ProbeReferenceVolume.Volume a, in ProbeReferenceVolume.Volume b)
|
|
{
|
|
// First we test if the bounding spheres intersects, in which case we case do the more complex OBB test
|
|
a.CalculateCenterAndSize(out var aCenter, out var aSize);
|
|
b.CalculateCenterAndSize(out var bCenter, out var bSize);
|
|
|
|
var aRadius = aSize.sqrMagnitude / 2.0f;
|
|
var bRadius = bSize.sqrMagnitude / 2.0f;
|
|
if (Vector3.SqrMagnitude(aCenter - bCenter) > aRadius + bRadius)
|
|
return false;
|
|
|
|
m_Axes[0] = a.X.normalized;
|
|
m_Axes[1] = a.Y.normalized;
|
|
m_Axes[2] = a.Z.normalized;
|
|
m_Axes[3] = b.X.normalized;
|
|
m_Axes[4] = b.Y.normalized;
|
|
m_Axes[5] = b.Z.normalized;
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
Vector2 aProj = ProjectOBB(in a, m_Axes[i]);
|
|
Vector2 bProj = ProjectOBB(in b, m_Axes[i]);
|
|
|
|
if (aProj.y < bProj.x || bProj.y < aProj.x)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static bool OBBContains(in ProbeReferenceVolume.Volume obb, Vector3 point)
|
|
{
|
|
float lenX2 = obb.X.sqrMagnitude;
|
|
float lenY2 = obb.Y.sqrMagnitude;
|
|
float lenZ2 = obb.Z.sqrMagnitude;
|
|
|
|
// Project in OBB space
|
|
point -= obb.corner;
|
|
point = new Vector3(Vector3.Dot(point, obb.X), Vector3.Dot(point, obb.Y), Vector3.Dot(point, obb.Z));
|
|
|
|
return (0.0f < point.x && point.x < lenX2) && (0.0f < point.y && point.y < lenY2) && (0.0f < point.z && point.z < lenZ2);
|
|
}
|
|
|
|
// Test between a OBB and an AABB. The AABB of the OBB is requested to avoid recalculating it
|
|
public static bool OBBAABBIntersect(in ProbeReferenceVolume.Volume a, in Bounds b, in Bounds aAABB)
|
|
{
|
|
// First perform fast AABB test
|
|
if (!aAABB.Intersects(b))
|
|
return false;
|
|
|
|
// Perform complex OBB test
|
|
Vector3 boundsMin = b.min, boundsMax = b.max;
|
|
m_AABBCorners[0] = new Vector3(boundsMin.x, boundsMin.y, boundsMin.z);
|
|
m_AABBCorners[1] = new Vector3(boundsMax.x, boundsMin.y, boundsMin.z);
|
|
m_AABBCorners[2] = new Vector3(boundsMax.x, boundsMax.y, boundsMin.z);
|
|
m_AABBCorners[3] = new Vector3(boundsMin.x, boundsMax.y, boundsMin.z);
|
|
m_AABBCorners[4] = new Vector3(boundsMin.x, boundsMin.y, boundsMax.z);
|
|
m_AABBCorners[5] = new Vector3(boundsMax.x, boundsMin.y, boundsMax.z);
|
|
m_AABBCorners[6] = new Vector3(boundsMax.x, boundsMax.y, boundsMax.z);
|
|
m_AABBCorners[7] = new Vector3(boundsMin.x, boundsMax.y, boundsMax.z);
|
|
|
|
m_Axes[0] = a.X.normalized;
|
|
m_Axes[1] = a.Y.normalized;
|
|
m_Axes[2] = a.Z.normalized;
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
Vector2 aProj = ProjectOBB(in a, m_Axes[i]);
|
|
Vector2 bProj = ProjectAABB(m_AABBCorners, m_Axes[i]);
|
|
|
|
if (aProj.y < bProj.x || bProj.y < aProj.x)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static Vector2 ProjectOBB(in ProbeReferenceVolume.Volume a, Vector3 axis)
|
|
{
|
|
float min = Vector3.Dot(axis, a.corner);
|
|
float max = min;
|
|
|
|
for (int x = 0; x < 2; x++)
|
|
{
|
|
for (int y = 0; y < 2; y++)
|
|
{
|
|
for (int z = 0; z < 2; z++)
|
|
{
|
|
Vector3 vert = a.corner + a.X * x + a.Y * y + a.Z * z;
|
|
|
|
float proj = Vector3.Dot(axis, vert);
|
|
|
|
if (proj < min)
|
|
{
|
|
min = proj;
|
|
}
|
|
else if (proj > max)
|
|
{
|
|
max = proj;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return new Vector2(min, max);
|
|
}
|
|
|
|
static Vector2 ProjectAABB(in Vector3[] corners, Vector3 axis)
|
|
{
|
|
float min = Vector3.Dot(axis, corners[0]);
|
|
float max = min;
|
|
for (int i = 1; i < 8; i++)
|
|
{
|
|
float proj = Vector3.Dot(axis, corners[i]);
|
|
if (proj < min) min = proj;
|
|
else if (proj > max) max = proj;
|
|
}
|
|
|
|
return new Vector2(min, max);
|
|
}
|
|
}
|
|
}
|