diff --git a/KeepersCompound.Lightmapper/MathUtils.cs b/KeepersCompound.Lightmapper/MathUtils.cs index 853167b..769fc72 100644 --- a/KeepersCompound.Lightmapper/MathUtils.cs +++ b/KeepersCompound.Lightmapper/MathUtils.cs @@ -4,6 +4,49 @@ namespace KeepersCompound.Lightmapper; 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) { return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length(); diff --git a/KeepersCompound.Lightmapper/Program.cs b/KeepersCompound.Lightmapper/Program.cs index 13d3136..b8c8164 100644 --- a/KeepersCompound.Lightmapper/Program.cs +++ b/KeepersCompound.Lightmapper/Program.cs @@ -1,4 +1,4 @@ -using System.Numerics; +using System.Numerics; using KeepersCompound.LGS.Database; using KeepersCompound.LGS.Database.Chunks; 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"; 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.LogAll(); @@ -246,6 +247,15 @@ class Program topLeft -= renderPoly.TextureVectors.Item1 * (renderPoly.TextureBases.Item1 - info.Bases.Item1 * 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) { // Check if plane normal is facing towards the light @@ -266,6 +276,13 @@ class Program 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 x = 0; x < lightmap.Width; x++)