Compare commits

...

6 Commits

2 changed files with 30 additions and 23 deletions

View File

@ -481,9 +481,14 @@ public class LightMapper
} }
} }
}); });
var pvs = new PotentiallyVisibleSet(worldRep.Cells);
Parallel.ForEach(lightCellMap, i =>
{
if (i != -1) pvs.ComputeVisibility(i);
});
var visibleCellMap = new List<int[]>(_lights.Count); var visibleCellMap = new List<int[]>(_lights.Count);
var pvs = new PotentiallyVisibleSet(worldRep.Cells);
for (var i = 0; i < _lights.Count; i++) for (var i = 0; i < _lights.Count; i++)
{ {
var cellIdx = lightCellMap[i]; var cellIdx = lightCellMap[i];

View File

@ -1,15 +1,15 @@
using System.Collections; using System.Collections;
using System.Numerics; using System.Numerics;
using KeepersCompound.LGS.Database.Chunks; using KeepersCompound.LGS.Database.Chunks;
using Serilog;
namespace KeepersCompound.Lightmapper; namespace KeepersCompound.Lightmapper;
public class PotentiallyVisibleSet public class PotentiallyVisibleSet
{ {
private struct Node(List<int> edgeIndices) private readonly struct Node(List<int> edgeIndices)
{ {
public bool VisibilityComputed = false; public readonly HashSet<int> VisibleNodes = [];
public HashSet<int> VisibleNodes = [];
public readonly List<int> EdgeIndices = edgeIndices; public readonly List<int> EdgeIndices = edgeIndices;
} }
@ -75,6 +75,7 @@ public class PotentiallyVisibleSet
} }
private readonly Node[] _graph; private readonly Node[] _graph;
private readonly bool[] _computedMap;
private readonly List<Edge> _edges; private readonly List<Edge> _edges;
private const float Epsilon = 0.1f; private const float Epsilon = 0.1f;
@ -98,14 +99,18 @@ public class PotentiallyVisibleSet
public PotentiallyVisibleSet(WorldRep.Cell[] cells) public PotentiallyVisibleSet(WorldRep.Cell[] cells)
{ {
_graph = new Node[cells.Length]; _graph = new Node[cells.Length];
_edges = []; _computedMap = new bool[cells.Length];
var portalCount = 0; var portalCount = 0;
foreach (var cell in cells) for (var i = 0; i < cells.Length; i++)
{ {
portalCount += cell.PortalPolyCount; _computedMap[i] = false;
portalCount += cells[i].PortalPolyCount;
} }
_edges = new List<Edge>(portalCount);
Log.Information("Mission contains {PortalCount} portals.", portalCount);
for (var i = 0; i < cells.Length; i++) for (var i = 0; i < cells.Length; i++)
{ {
var cell = cells[i]; var cell = cells[i];
@ -139,7 +144,7 @@ public class PotentiallyVisibleSet
vs.Add(cell.Vertices[cell.Indices[indicesOffset + vIdx]]); vs.Add(cell.Vertices[cell.Indices[indicesOffset + vIdx]]);
} }
var edge = new Edge(portalCount, poly.Destination, new Poly(vs, cell.Planes[poly.PlaneId])); var edge = new Edge(cells.Length, poly.Destination, new Poly(vs, cell.Planes[poly.PlaneId]));
edgeIndices.Add(_edges.Count); edgeIndices.Add(_edges.Count);
_edges.Add(edge); _edges.Add(edge);
indicesOffset += poly.VertexCount; indicesOffset += poly.VertexCount;
@ -148,23 +153,21 @@ public class PotentiallyVisibleSet
_graph[i] = new Node(edgeIndices); _graph[i] = new Node(edgeIndices);
} }
Parallel.ForEach(_edges, ComputeEdgeMightSee); // Parallel.ForEach(_edges, ComputeEdgeMightSee);
} }
public int[] GetVisible(int cellIdx) public int[] GetVisible(int cellIdx)
{ {
// TODO: Handle out of range indices // TODO: Handle out of range indices
var node = _graph[cellIdx]; var node = _graph[cellIdx];
if (node.VisibilityComputed) if (_computedMap[cellIdx])
{ {
return [..node.VisibleNodes]; return [..node.VisibleNodes];
} }
var visibleCells = ComputeVisibility(cellIdx); ComputeVisibility(cellIdx);
node.VisibilityComputed = true;
node.VisibleNodes = visibleCells;
_graph[cellIdx] = node; _graph[cellIdx] = node;
return [..visibleCells]; return [.._graph[cellIdx].VisibleNodes];
} }
private void ComputeEdgeMightSee(Edge source) private void ComputeEdgeMightSee(Edge source)
@ -236,31 +239,30 @@ public class PotentiallyVisibleSet
} }
} }
private HashSet<int> ComputeVisibility(int cellIdx) public void ComputeVisibility(int cellIdx)
{ {
if (cellIdx >= _graph.Length) if (cellIdx >= _graph.Length)
{ {
return []; return;
} }
// A cell can always see itself, so we'll add that now // A cell can always see itself, so we'll add that now
var visible = new HashSet<int>(); _graph[cellIdx].VisibleNodes.Add(cellIdx);
visible.Add(cellIdx);
foreach (var edgeIdx in _graph[cellIdx].EdgeIndices) foreach (var edgeIdx in _graph[cellIdx].EdgeIndices)
{ {
var edge = _edges[edgeIdx]; var edge = _edges[edgeIdx];
ComputeEdgeMightSee(edge);
for (var i = 0; i < edge.MightSee.Length; i++) for (var i = 0; i < edge.MightSee.Length; i++)
{ {
if (edge.MightSee[i]) if (edge.MightSee[i])
{ {
visible.Add(i); _graph[cellIdx].VisibleNodes.Add(i);
} }
} }
} }
return visible; _computedMap[cellIdx] = true;
// if (cellIdx >= _portalGraph.Length) // if (cellIdx >= _portalGraph.Length)
// { // {
// return []; // return [];