Compare commits

..

No commits in common. "ec9c20423d3e59d32b9987ef93cc771abfa1a0db" and "e48393b856c58e0259b0ce302f1b04e9f8ab9200" have entirely different histories.

2 changed files with 9 additions and 55 deletions

View File

@ -1,4 +1,3 @@
using System.Collections;
using System.Numerics; using System.Numerics;
using KeepersCompound.LGS.Database.Chunks; using KeepersCompound.LGS.Database.Chunks;
@ -13,9 +12,9 @@ public class PotentiallyVisibleSet
public readonly List<int> EdgeIndices = edgeIndices; public readonly List<int> EdgeIndices = edgeIndices;
} }
private readonly struct Edge(int mightSeeLength, int destination, Poly poly) private readonly struct Edge(int destination, Poly poly)
{ {
public readonly BitArray MightSee = new(mightSeeLength); public readonly HashSet<int> MightSee = [];
public readonly int Destination = destination; public readonly int Destination = destination;
public readonly Poly Poly = poly; public readonly Poly Poly = poly;
@ -27,8 +26,6 @@ public class PotentiallyVisibleSet
private struct Poly private struct Poly
{ {
public readonly Vector3 Center;
public readonly float Radius;
public List<Vector3> Vertices; public List<Vector3> Vertices;
public readonly Plane Plane; public readonly Plane Plane;
@ -36,25 +33,6 @@ public class PotentiallyVisibleSet
{ {
Vertices = vertices; Vertices = vertices;
Plane = plane; Plane = plane;
// Center is just taken to be the "average" of the vertices
Center = Vector3.Zero;
foreach (var v in vertices)
{
Center += v;
}
Center /= vertices.Count;
// Radius is the max vertex distance from the center
// We're actually calculating radius squared to begin with because it's faster :)
Radius = 0;
foreach (var v in vertices)
{
Radius = float.Max(Radius, (v - Center).LengthSquared());
}
Radius = MathF.Sqrt(Radius);
} }
public Poly(Poly other) public Poly(Poly other)
@ -100,12 +78,6 @@ public class PotentiallyVisibleSet
_graph = new Node[cells.Length]; _graph = new Node[cells.Length];
_edges = []; _edges = [];
var portalCount = 0;
foreach (var cell in cells)
{
portalCount += cell.PortalPolyCount;
}
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 +111,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(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;
@ -176,32 +148,22 @@ public class PotentiallyVisibleSet
while (unexploredCells.Count > 0) while (unexploredCells.Count > 0)
{ {
var cellIdx = unexploredCells.Pop(); var cellIdx = unexploredCells.Pop();
if (source.MightSee[cellIdx])
if (!source.MightSee.Add(cellIdx))
{ {
continue; // target is already explored continue; // target is already explored
} }
source.MightSee[cellIdx] = true;
// Target must be partly behind source, source must be partly in front of target, and source and target cannot face each other // Target must be partly behind source, source must be partly in front of target, and source and target cannot face each other
foreach (var targetEdgeIdx in _graph[cellIdx].EdgeIndices) foreach (var targetEdgeIdx in _graph[cellIdx].EdgeIndices)
{ {
var target = _edges[targetEdgeIdx]; var target = _edges[targetEdgeIdx];
var targetPlane = target.Poly.Plane; var targetPlane = target.Poly.Plane;
// If we're already visited the target, target is fully behind source, or source is fully behind target
// then we can quickly discard this portal
if (source.MightSee[target.Destination] ||
MathUtils.DistanceFromNormalizedPlane(sourcePlane, target.Poly.Center) > target.Poly.Radius ||
MathUtils.DistanceFromNormalizedPlane(targetPlane, source.Poly.Center) < -source.Poly.Radius)
{
continue;
}
var validTarget = false; var validTarget = false;
foreach (var v in target.Poly.Vertices) foreach (var v in target.Poly.Vertices)
{ {
if (MathUtils.DistanceFromNormalizedPlane(sourcePlane, v) < -MathUtils.Epsilon) if (MathUtils.DistanceFromPlane(sourcePlane, v) < -MathUtils.Epsilon)
{ {
validTarget = true; validTarget = true;
break; break;
@ -216,7 +178,7 @@ public class PotentiallyVisibleSet
validTarget = false; validTarget = false;
foreach (var v in source.Poly.Vertices) foreach (var v in source.Poly.Vertices)
{ {
if (MathUtils.DistanceFromNormalizedPlane(targetPlane, v) > MathUtils.Epsilon) if (MathUtils.DistanceFromPlane(targetPlane, v) > MathUtils.Epsilon)
{ {
validTarget = true; validTarget = true;
break; break;
@ -250,12 +212,9 @@ public class PotentiallyVisibleSet
foreach (var edgeIdx in _graph[cellIdx].EdgeIndices) foreach (var edgeIdx in _graph[cellIdx].EdgeIndices)
{ {
var edge = _edges[edgeIdx]; var edge = _edges[edgeIdx];
for (var i = 0; i < edge.MightSee.Length; i++) foreach (var mightSee in edge.MightSee)
{ {
if (edge.MightSee[i]) visible.Add(mightSee);
{
visible.Add(i);
}
} }
} }

View File

@ -93,11 +93,6 @@ public static class MathUtils
return (Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length(); return (Vector3.Dot(plane.Normal, point) + plane.D) / plane.Normal.Length();
} }
public static float DistanceFromNormalizedPlane(Plane plane, Vector3 point)
{
return Vector3.Dot(plane.Normal, point) + plane.D;
}
public static bool IsCoplanar(Plane p0, Plane p1) public static bool IsCoplanar(Plane p0, Plane p1)
{ {
var m = p0.D / p1.D; var m = p0.D / p1.D;