Compare commits
No commits in common. "317b17ab02a1890f5762a68e569c83be7ed31c86" and "ceb86c0a979f85376d4b0a98270bb997c8788f9f" have entirely different histories.
317b17ab02
...
ceb86c0a97
|
@ -371,79 +371,11 @@ public class LightMapper
|
|||
if (!_mission.TryGetChunk<WorldRep>("WREXT", out var worldRep))
|
||||
return;
|
||||
|
||||
|
||||
var lightVisibleCells = Timing.TimeStage("Light PVS", () =>
|
||||
{
|
||||
var cellCount = worldRep.Cells.Length;
|
||||
var aabbs = new MathUtils.Aabb[worldRep.Cells.Length];
|
||||
Parallel.For(0, cellCount, i => aabbs[i] = new MathUtils.Aabb(worldRep.Cells[i].Vertices));
|
||||
|
||||
var lightCellMap = new int[_lights.Count];
|
||||
Parallel.For(0, _lights.Count, i =>
|
||||
{
|
||||
lightCellMap[i] = -1;
|
||||
var light = _lights[i];
|
||||
for (var j = 0; j < cellCount; j++)
|
||||
{
|
||||
if (!MathUtils.Intersects(aabbs[j], light.Position))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Half-space contained
|
||||
var cell = worldRep.Cells[j];
|
||||
var contained = true;
|
||||
for (var k = 0; k < cell.PlaneCount; k++)
|
||||
{
|
||||
var plane = cell.Planes[k];
|
||||
if (MathUtils.DistanceFromPlane(plane, light.Position) < -MathUtils.Epsilon)
|
||||
{
|
||||
contained = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (contained)
|
||||
{
|
||||
lightCellMap[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var lightVisibleCells = new List<int[]>(_lights.Count);
|
||||
var pvs = new PotentiallyVisibleSet(worldRep.Cells);
|
||||
for (var i = 0; i < _lights.Count; i++)
|
||||
{
|
||||
var cellIdx = lightCellMap[i];
|
||||
if (cellIdx == -1)
|
||||
{
|
||||
lightVisibleCells.Add([]);
|
||||
continue;
|
||||
}
|
||||
var visibleSet = pvs.GetVisible(lightCellMap[i]);
|
||||
lightVisibleCells.Add(visibleSet);
|
||||
}
|
||||
|
||||
return lightVisibleCells;
|
||||
|
||||
// TODO: This isn't actually thread safe :)
|
||||
// Parallel.For(0, worldRep.Cells.Length, i => pvs.GetVisible(i));
|
||||
// for (var i = 0; i < worldRep.Cells.Length; i++)
|
||||
// {
|
||||
// pvs.GetVisible(i);
|
||||
// // var visible = pvs.GetVisible(i);
|
||||
// // Console.WriteLine($"Cell {i}: Count({visible.Length}), Visible[{string.Join(" ", visible)}]");
|
||||
// }
|
||||
});
|
||||
|
||||
// TODO: Move this functionality to the LGS library
|
||||
// We set up light indices in separately from lighting because the actual
|
||||
// lighting phase takes a lot of shortcuts that we don't want
|
||||
// Parallel.ForEach(worldRep.Cells, cell =>
|
||||
Parallel.For(0, worldRep.Cells.Length, i =>
|
||||
Parallel.ForEach(worldRep.Cells, cell =>
|
||||
{
|
||||
var cell = worldRep.Cells[i];
|
||||
cell.LightIndexCount = 0;
|
||||
cell.LightIndices.Clear();
|
||||
|
||||
|
@ -471,22 +403,14 @@ public class LightMapper
|
|||
// cache, so we want this to be as minimal as possible. Additionally large
|
||||
// lists actually cause performance issues!
|
||||
var cellAabb = new MathUtils.Aabb(cell.Vertices);
|
||||
for (var j = 0; j < _lights.Count; j++)
|
||||
foreach (var light in _lights)
|
||||
{
|
||||
var light = _lights[j];
|
||||
if (!MathUtils.Intersects(new MathUtils.Sphere(light.Position, light.Radius), cellAabb))
|
||||
if (MathUtils.Intersects(new MathUtils.Sphere(light.Position, light.Radius), cellAabb))
|
||||
{
|
||||
continue;
|
||||
cell.LightIndexCount++;
|
||||
cell.LightIndices.Add((ushort)light.LightTableIndex);
|
||||
cell.LightIndices[0]++;
|
||||
}
|
||||
|
||||
if (!lightVisibleCells[j].Contains(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cell.LightIndexCount++;
|
||||
cell.LightIndices.Add((ushort)light.LightTableIndex);
|
||||
cell.LightIndices[0]++;
|
||||
}
|
||||
|
||||
if (cell.LightIndexCount > 97)
|
||||
|
@ -513,10 +437,8 @@ public class LightMapper
|
|||
|
||||
if (overLit > 0)
|
||||
{
|
||||
Console.WriteLine($"WARNING: Overlit cells detected: {overLit}/{worldRep.Cells.Length}");
|
||||
Console.WriteLine($"WARNING: Overlit cells detected: {overLit}/{worldRep.Cells.Length}, MaxLights: {maxLights} / 96");
|
||||
}
|
||||
|
||||
Console.WriteLine($"MaxLights: {maxLights} / 96");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -641,13 +563,9 @@ public class LightMapper
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var lightIdx in cell.LightIndices)
|
||||
foreach (var light in _lights)
|
||||
{
|
||||
if (lightIdx == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var light = _lights[lightIdx - 1];
|
||||
var layer = 0;
|
||||
|
||||
// Check if plane normal is facing towards the light
|
||||
// If it's not then we're never going to be (directly) lit by this
|
||||
|
@ -697,13 +615,10 @@ public class LightMapper
|
|||
|
||||
if (strength != 0f)
|
||||
{
|
||||
var layer = 0;
|
||||
|
||||
// If we're an anim light there's a lot of stuff we need to update
|
||||
// Firstly we need to add the light to the cells anim light palette
|
||||
// Secondly we need to set the appropriate bit of the lightmap's
|
||||
// bitmask. Finally we need to check if the lightmap needs another layer
|
||||
// TODO: Handle too many lights for a layer
|
||||
if (light.Anim)
|
||||
{
|
||||
// TODO: Don't recalculate this for every point lol
|
||||
|
|
|
@ -80,14 +80,6 @@ public static class MathUtils
|
|||
return (sphere.Position - other.Position).Length() <= rsum;
|
||||
}
|
||||
|
||||
public static bool Intersects(Aabb aabb, Vector3 point)
|
||||
{
|
||||
var min = aabb.Min;
|
||||
var max = aabb.Max;
|
||||
return point.X >= min.X && point.Y >= min.Y && point.Z >= min.Z &&
|
||||
point.X <= max.X && point.Y <= max.Y && point.Z <= max.Z;
|
||||
}
|
||||
|
||||
public static float DistanceFromPlane(Plane plane, Vector3 point)
|
||||
{
|
||||
return Math.Abs(Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length();
|
||||
|
|
Loading…
Reference in New Issue