Compare commits
No commits in common. "196e97a8fdfed3c3bfbeefcd7573c3a651b1efdb" and "ce7002477e94451bda3434984a4ab87a4beebbc7" have entirely different histories.
196e97a8fd
...
ce7002477e
|
@ -4,8 +4,6 @@ namespace KeepersCompound.Lightmapper;
|
|||
|
||||
public static class MathUtils
|
||||
{
|
||||
public const float Epsilon = 0.001f;
|
||||
|
||||
public readonly struct Aabb
|
||||
{
|
||||
public readonly Vector3 Min;
|
||||
|
@ -54,76 +52,64 @@ public static class MathUtils
|
|||
return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length();
|
||||
}
|
||||
|
||||
public record PlanePointMapper
|
||||
/// <summary>
|
||||
/// Expects poly to be convex. Given a point
|
||||
/// </summary>
|
||||
public static Vector3 ClipPointToPoly3d(Vector3 point, Vector3[] vertices, Plane projectionPlane)
|
||||
{
|
||||
Vector3 _origin;
|
||||
Vector3 _xAxis;
|
||||
Vector3 _yAxis;
|
||||
// Shouldn't need to pass 3d. We can just pass the luxel coord, and then we only need the
|
||||
|
||||
public PlanePointMapper(Vector3 normal, Vector3 p0, Vector3 p1)
|
||||
{
|
||||
_origin = p0;
|
||||
_xAxis = p1 - _origin;
|
||||
_yAxis = Vector3.Cross(normal, _xAxis);
|
||||
var (p2d, v2ds) = LocalPlaneCoords(point, vertices, projectionPlane);
|
||||
|
||||
_xAxis = Vector3.Normalize(_xAxis);
|
||||
_yAxis = Vector3.Normalize(_yAxis);
|
||||
}
|
||||
// !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);
|
||||
|
||||
public Vector2 MapTo2d(Vector3 point)
|
||||
var inside = true;
|
||||
for (var i = 0; i < v2ds.Length; i++)
|
||||
{
|
||||
var offset = point - _origin;
|
||||
var x = Vector3.Dot(offset, _xAxis);
|
||||
var y = Vector3.Dot(offset, _yAxis);
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
public Vector2[] MapTo2d(Vector3[] points)
|
||||
{
|
||||
var points2d = new Vector2[points.Length];
|
||||
for (var i = 0; i < points.Length; i++)
|
||||
{
|
||||
points2d[i] = MapTo2d(points[i]);
|
||||
}
|
||||
return points2d;
|
||||
}
|
||||
|
||||
public Vector3 MapTo3d(Vector2 point)
|
||||
{
|
||||
return _origin + point.X * _xAxis + point.Y * _yAxis;
|
||||
}
|
||||
|
||||
public Vector3[] MapTo3d(Vector2[] points)
|
||||
{
|
||||
var points3d = new Vector3[points.Length];
|
||||
for (var i = 0; i < points.Length; i++)
|
||||
{
|
||||
points3d[i] = MapTo3d(points[i]);
|
||||
}
|
||||
return points3d;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 ClipPointToPoly2d(Vector2 point, Vector2[] vertices)
|
||||
{
|
||||
var vertexCount = vertices.Length;
|
||||
for (var i = 0; i < vertexCount; i++)
|
||||
{
|
||||
var a = vertices[i];
|
||||
var b = vertices[(i + 1) % vertexCount];
|
||||
var a = v2ds[i];
|
||||
var b = v2ds[(i + 1) % v2ds.Length];
|
||||
var segment = b - a;
|
||||
var offset = point - a;
|
||||
var offset = p2d - a;
|
||||
var norm = Vector2.Normalize(new Vector2(-segment.Y, segment.X));
|
||||
var side = Vector2.Dot(norm, offset);
|
||||
if (side >= -Epsilon)
|
||||
if (side >= -0.001)
|
||||
{
|
||||
// We apply epsilon so that we push slightly into the poly. If we only
|
||||
// push to the edge then Embree sometimes misses casts. The reason
|
||||
// it's 2 epsilon is so Side == -Epsilon still gets pushed in properly
|
||||
point -= norm * (side + 2 * Epsilon);
|
||||
p2d -= norm * (side + 0.0015f);
|
||||
inside = false;
|
||||
}
|
||||
}
|
||||
|
||||
return point;
|
||||
// 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);
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ class Program
|
|||
Timing.Reset();
|
||||
|
||||
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));
|
||||
|
||||
|
@ -117,11 +117,9 @@ class Program
|
|||
{
|
||||
propLightColor ??= new PropLightColor { Hue = 0, Saturation = 0 };
|
||||
|
||||
// TODO: There's still some lights that aren't positioned right such as Streetlamp.
|
||||
// Perhaps there's a light point specified in model files?
|
||||
var light = new Light
|
||||
{
|
||||
position = brush.position + propLight.Offset,
|
||||
position = brush.position,
|
||||
color = HsbToRgb(propLightColor.Hue, propLightColor.Saturation, propLight.Brightness),
|
||||
radius = propLight.Radius,
|
||||
r2 = propLight.Radius * propLight.Radius,
|
||||
|
@ -245,7 +243,7 @@ class Program
|
|||
var info = cell.LightList[polyIdx];
|
||||
var lightmap = cell.Lightmaps[polyIdx];
|
||||
|
||||
ResetLightmap(ambientLight, lightmap, hdr);
|
||||
ResetLightmap(ambientLight, lightmap);
|
||||
|
||||
// Get world position of lightmap (0, 0) (+0.5 so we cast from the center of a pixel)
|
||||
var topLeft = cell.Vertices[cell.Indices[cellIdxOffset]];
|
||||
|
@ -267,8 +265,6 @@ class Program
|
|||
{
|
||||
vs[i] = cell.Vertices[cell.Indices[cellIdxOffset + i]];
|
||||
}
|
||||
var planeMapper = new MathUtils.PlanePointMapper(plane.Normal, vs[0], vs[1]);
|
||||
var v2ds = planeMapper.MapTo2d(vs);
|
||||
|
||||
foreach (var light in lights)
|
||||
{
|
||||
|
@ -305,17 +301,7 @@ class Program
|
|||
pos += x * 0.25f * renderPoly.TextureVectors.Item1;
|
||||
pos += y * 0.25f * renderPoly.TextureVectors.Item2;
|
||||
|
||||
// We need to clip the point to slightly inside of the poly
|
||||
// to avoid three problems:
|
||||
// 1. Darkened spots from lightmap pixels who's center is outside
|
||||
// of the polygon but is partially contained in the polygon
|
||||
// 2. Darkened spots from linear filtering of points outside of the
|
||||
// polygon which have missed
|
||||
// 3. Darkened spots where centers are on the exact edge of a poly
|
||||
// which can sometimes cause Embree to miss casts
|
||||
var p2d = planeMapper.MapTo2d(pos);
|
||||
p2d = MathUtils.ClipPointToPoly2d(p2d, v2ds);
|
||||
pos = planeMapper.MapTo3d(p2d);
|
||||
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
|
||||
|
@ -336,7 +322,7 @@ class Program
|
|||
|
||||
// cheeky epsilon
|
||||
// TODO: Some pixels aren't hitting and I'm not sure why
|
||||
var hit = hitResult && Math.Abs(hitResult.Distance - direction.Length()) < MathUtils.Epsilon;
|
||||
var hit = hitResult && Math.Abs(hitResult.Distance - direction.Length()) < 0.001;
|
||||
if (hit)
|
||||
{
|
||||
// Calculate light strength at a given point. As far as I can tell
|
||||
|
@ -381,24 +367,18 @@ class Program
|
|||
Console.Write("\n");
|
||||
}
|
||||
|
||||
private static void ResetLightmap(Vector3 ambientLight, WorldRep.Cell.Lightmap lightmap, bool hdr)
|
||||
private static void ResetLightmap(Vector3 ambientLight, WorldRep.Cell.Lightmap lightmap)
|
||||
{
|
||||
for (var i = 0; i < lightmap.Pixels.Length; i++)
|
||||
{
|
||||
lightmap.Pixels[i] = 0;
|
||||
}
|
||||
|
||||
var c = ambientLight;
|
||||
if (hdr)
|
||||
{
|
||||
c /= 2.0f;
|
||||
}
|
||||
|
||||
for (var y = 0; y < lightmap.Height; y++)
|
||||
{
|
||||
for (var x = 0; x < lightmap.Width; x++)
|
||||
{
|
||||
lightmap.AddLight(0, x, y, (byte)c.X, (byte)c.Y, (byte)c.Z);
|
||||
lightmap.AddLight(0, x, y, (byte)ambientLight.X, (byte)ambientLight.Y, (byte)ambientLight.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue