Add Sphere AABB intersection test

This commit is contained in:
Jarrod Doyle 2024-09-24 08:55:05 +01:00
parent edd01952e7
commit d144bdb6e9
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
2 changed files with 61 additions and 1 deletions

View File

@ -4,6 +4,49 @@ namespace KeepersCompound.Lightmapper;
public static class MathUtils public static class MathUtils
{ {
public readonly struct Aabb
{
public readonly Vector3 Min;
public readonly Vector3 Max;
public Aabb(Vector3[] points)
{
Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
foreach (var p in points)
{
Min = Vector3.Min(Min, p);
Max = Vector3.Max(Max, p);
}
}
}
public readonly struct Sphere
{
public readonly Vector3 Position;
public readonly float Radius;
public Sphere(Vector3 position, float radius)
{
Position = position;
Radius = radius;
}
}
public static Vector3 ClosestPoint(Aabb aabb, Vector3 point)
{
return Vector3.Min(aabb.Max, Vector3.Max(aabb.Min, point));
}
public static bool Intersects(Sphere sphere, Aabb aabb)
{
var closestPoint = ClosestPoint(aabb, sphere.Position);
var d2 = (sphere.Position - closestPoint).LengthSquared();
var r2 = sphere.Radius * sphere.Radius;
return d2 < r2;
}
public static float DistanceFromPlane(Plane plane, Vector3 point) public static float DistanceFromPlane(Plane plane, Vector3 point)
{ {
return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length(); return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length();

View File

@ -1,4 +1,4 @@
using System.Numerics; using System.Numerics;
using KeepersCompound.LGS.Database; using KeepersCompound.LGS.Database;
using KeepersCompound.LGS.Database.Chunks; using KeepersCompound.LGS.Database.Chunks;
using TinyEmbree; using TinyEmbree;
@ -22,6 +22,7 @@ class Program
var misPath = "/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/FMs/JAYRUDE_Tests/lm_test.cow"; var misPath = "/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/FMs/JAYRUDE_Tests/lm_test.cow";
misPath = "/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/FMs/AtdV/miss20.mis"; misPath = "/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/FMs/AtdV/miss20.mis";
misPath = "/stuff/Games/thief/drive_c/GOG Games/TG ND 1.27 (MAPPING)/FMs/TDP20AC_a_burrick_in_a_room/miss20.mis";
Timing.TimeStage("Total", () => LightmapMission(misPath)); Timing.TimeStage("Total", () => LightmapMission(misPath));
Timing.LogAll(); Timing.LogAll();
@ -246,6 +247,15 @@ class Program
topLeft -= renderPoly.TextureVectors.Item1 * (renderPoly.TextureBases.Item1 - info.Bases.Item1 * 0.25f); topLeft -= renderPoly.TextureVectors.Item1 * (renderPoly.TextureBases.Item1 - info.Bases.Item1 * 0.25f);
topLeft -= renderPoly.TextureVectors.Item2 * (renderPoly.TextureBases.Item2 - info.Bases.Item2 * 0.25f); topLeft -= renderPoly.TextureVectors.Item2 * (renderPoly.TextureBases.Item2 - info.Bases.Item2 * 0.25f);
var xDir = 0.25f * lightmap.Width * renderPoly.TextureVectors.Item1;
var yDir = 0.25f * lightmap.Height * renderPoly.TextureVectors.Item2;
var aabb = new MathUtils.Aabb([
topLeft,
topLeft + xDir,
topLeft + yDir,
topLeft + xDir + yDir,
]);
foreach (var light in lights) foreach (var light in lights)
{ {
// Check if plane normal is facing towards the light // Check if plane normal is facing towards the light
@ -266,6 +276,13 @@ class Program
continue; continue;
} }
// If the poly of the lightmap doesn't intersect the light radius then
// none of the lightmap points will so we can discard.
if (!MathUtils.Intersects(new MathUtils.Sphere(light.position, light.radius), aabb))
{
continue;
}
for (var y = 0; y < lightmap.Height; y++) for (var y = 0; y < lightmap.Height; y++)
{ {
for (var x = 0; x < lightmap.Width; x++) for (var x = 0; x < lightmap.Width; x++)