diff --git a/KeepersCompound.Lightmapper/MathUtils.cs b/KeepersCompound.Lightmapper/MathUtils.cs index 769fc72..64dbb85 100644 --- a/KeepersCompound.Lightmapper/MathUtils.cs +++ b/KeepersCompound.Lightmapper/MathUtils.cs @@ -51,4 +51,65 @@ public static class MathUtils { return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length(); } + + /// + /// Expects poly to be convex. Given a point + /// + public static Vector3 ClipPointToPoly3d(Vector3 point, Vector3[] vertices, Plane projectionPlane) + { + // Shouldn't need to pass 3d. We can just pass the luxel coord, and then we only need the + + var (p2d, v2ds) = LocalPlaneCoords(point, vertices, projectionPlane); + + // !HACK: Replace this shit + var origin = vertices[0]; + var locX = vertices[1] - origin; + var locY = Vector3.Cross(projectionPlane.Normal, locX); + locX = Vector3.Normalize(locX); + locY = Vector3.Normalize(locY); + + var inside = true; + for (var i = 0; i < v2ds.Length; i++) + { + var a = v2ds[i]; + var b = v2ds[(i + 1) % v2ds.Length]; + var segment = b - a; + var offset = p2d - a; + var norm = Vector2.Normalize(new Vector2(-segment.Y, segment.X)); + var side = Vector2.Dot(norm, offset); + if (side >= -0.001) + { + p2d -= norm * (side + 0.0015f); + inside = false; + } + } + + // return p2d; + + return origin + p2d.X * locX + p2d.Y * locY; + + // return Vector3.One; + } + + // TODO: Only do this once per poly + public static (Vector2, Vector2[]) LocalPlaneCoords(Vector3 point, Vector3[] ps, Plane plane) + { + var origin = ps[0]; + var locX = ps[1] - origin; + var locY = Vector3.Cross(plane.Normal, locX); + + locX = Vector3.Normalize(locX); + locY = Vector3.Normalize(locY); + + var offset = point - origin; + var p2d = new Vector2(Vector3.Dot(offset, locX), Vector3.Dot(offset, locY)); + var p2ds = new Vector2[ps.Length]; + for (var i = 0; i < ps.Length; i++) + { + var p = ps[i] - origin; + p2ds[i] = new Vector2(Vector3.Dot(p, locX), Vector3.Dot(p, locY)); + } + + return (p2d, p2ds); + } } \ No newline at end of file diff --git a/KeepersCompound.Lightmapper/Program.cs b/KeepersCompound.Lightmapper/Program.cs index 4e81016..02090e8 100644 --- a/KeepersCompound.Lightmapper/Program.cs +++ b/KeepersCompound.Lightmapper/Program.cs @@ -259,6 +259,13 @@ class Program topLeft + xDir + yDir, ]); + // Used for clipping points to poly + var vs = new Vector3[poly.VertexCount]; + for (var i = 0; i < poly.VertexCount; i++) + { + vs[i] = cell.Vertices[cell.Indices[cellIdxOffset + i]]; + } + foreach (var light in lights) { // Check if plane normal is facing towards the light @@ -294,6 +301,8 @@ class Program pos += x * 0.25f * renderPoly.TextureVectors.Item1; pos += y * 0.25f * renderPoly.TextureVectors.Item2; + pos = MathUtils.ClipPointToPoly3d(pos, vs, plane); + // If we're out of range there's no point casting a ray // There's probably a better way to discard the entire lightmap // if we're massively out of range