Remove PVS lighting stage

This commit is contained in:
Jarrod Doyle 2025-02-23 10:21:06 +00:00
parent db0a70607d
commit ccd1c6ef82
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
1 changed files with 63 additions and 71 deletions

View File

@ -477,96 +477,88 @@ public class LightMapper
private void SetCellLightIndices(Settings settings) private void SetCellLightIndices(Settings settings)
{ {
// TODO: Doors aren't blocking lights. Need to do some cell traversal to remove light indices :(
if (!_mission.TryGetChunk<WorldRep>("WREXT", out var worldRep)) if (!_mission.TryGetChunk<WorldRep>("WREXT", out var worldRep))
return; 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 =>
{ {
var cellCount = worldRep.Cells.Length; lightCellMap[i] = -1;
var aabbs = new MathUtils.Aabb[worldRep.Cells.Length]; var light = _lights[i];
Parallel.For(0, cellCount, i => aabbs[i] = new MathUtils.Aabb(worldRep.Cells[i].Vertices)); for (var j = 0; j < cellCount; j++)
var lightCellMap = new int[_lights.Count];
Parallel.For(0, _lights.Count, i =>
{ {
lightCellMap[i] = -1; if (!MathUtils.Intersects(aabbs[j], light.Position))
var light = _lights[i];
for (var j = 0; j < cellCount; j++)
{ {
if (!MathUtils.Intersects(aabbs[j], light.Position)) continue;
{ }
continue;
}
// Half-space contained // Half-space contained
var cell = worldRep.Cells[j]; var cell = worldRep.Cells[j];
var contained = true; var contained = true;
for (var k = 0; k < cell.PlaneCount; k++) for (var k = 0; k < cell.PlaneCount; k++)
{
var plane = cell.Planes[k];
if (MathUtils.DistanceFromPlane(plane, light.Position) < -MathUtils.Epsilon)
{ {
var plane = cell.Planes[k]; contained = false;
if (MathUtils.DistanceFromPlane(plane, light.Position) < -MathUtils.Epsilon)
{
contained = false;
break;
}
}
if (contained)
{
lightCellMap[i] = j;
break; break;
} }
} }
if (lightCellMap[i] == -1) if (contained)
{ {
if (light.ObjId != -1) lightCellMap[i] = j;
{ break;
Log.Warning("Object {Id}: Light is inside solid terrain.", light.ObjId);
}
else
{
Log.Warning("Brush at {Position}: Light is inside solid terrain.", light.Position);
}
} }
});
Log.Information("Mission has {c} lights", _lights.Count);
var pvs = new PotentiallyVisibleSet(worldRep.Cells);
var visibleCellMap = new HashSet<int>[_lights.Count];
// Exact visibility doesn't use MightSee (yet?) so we only bother computing it if we're doing fast vis
if (settings.FastPvs)
{
Parallel.ForEach(lightCellMap, i =>
{
if (i != -1) pvs.ComputeCellMightSee(i);
});
} }
Parallel.For(0, _lights.Count, i => if (lightCellMap[i] == -1)
{ {
var cellIdx = lightCellMap[i]; if (light.ObjId != -1)
if (cellIdx == -1)
{ {
visibleCellMap[i] = []; Log.Warning("Object {Id}: Light is inside solid terrain.", light.ObjId);
return;
} }
else
var visibleSet = settings.FastPvs switch { {
true => pvs.ComputeVisibilityFast(lightCellMap[i]), Log.Warning("Brush at {Position}: Light is inside solid terrain.", light.Position);
false => pvs.ComputeVisibilityExact(_lights[i].Position, lightCellMap[i], _lights[i].Radius) }
}; }
// Log.Information("Light {i} sees {c} cells", i, visibleSet.Count);
visibleCellMap[i] = visibleSet;
});
return visibleCellMap;
}); });
Log.Information("Mission has {c} lights", _lights.Count);
var pvs = new PotentiallyVisibleSet(worldRep.Cells);
var visibleCellMap = new HashSet<int>[_lights.Count];
// Exact visibility doesn't use MightSee (yet?) so we only bother computing it if we're doing fast vis
if (settings.FastPvs)
{
Parallel.ForEach(lightCellMap, i =>
{
if (i != -1) pvs.ComputeCellMightSee(i);
});
}
Parallel.For(0, _lights.Count, i =>
{
var cellIdx = lightCellMap[i];
if (cellIdx == -1)
{
visibleCellMap[i] = [];
return;
}
var visibleSet = settings.FastPvs switch {
true => pvs.ComputeVisibilityFast(lightCellMap[i]),
false => pvs.ComputeVisibilityExact(_lights[i].Position, lightCellMap[i], _lights[i].Radius)
};
// Log.Information("Light {i} sees {c} cells", i, visibleSet.Count);
visibleCellMap[i] = visibleSet;
});
// TODO: Move this functionality to the LGS library // TODO: Move this functionality to the LGS library
// We set up light indices in separately from lighting because the actual // We set up light indices in separately from lighting because the actual
@ -610,7 +602,7 @@ public class LightMapper
continue; continue;
} }
if (!lightVisibleCells[j].Contains(i)) if (!visibleCellMap[j].Contains(i))
{ {
continue; continue;
} }