feat(render): Phase A8.F — ViewPolygon + CellView clip-region data model
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
bb903bc157
commit
406307e8ee
2 changed files with 123 additions and 0 deletions
71
src/AcDream.App/Rendering/PortalView.cs
Normal file
71
src/AcDream.App/Rendering/PortalView.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// PortalView.cs
|
||||
//
|
||||
// Phase A8.F: GL-free 2D screen-space (NDC) clip-region data model.
|
||||
// Mirrors retail view_poly (acclient.h:32465) and view_type (acclient.h:32338):
|
||||
// a cell's clip region is a SET of convex polygons in normalized device coords.
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
|
||||
namespace AcDream.App.Rendering;
|
||||
|
||||
/// <summary>One convex polygon in NDC screen space (xy in [-1,1]), plus its bounding rect.</summary>
|
||||
public readonly struct ViewPolygon
|
||||
{
|
||||
public readonly Vector2[] Vertices;
|
||||
public readonly float MinX, MinY, MaxX, MaxY;
|
||||
|
||||
public ViewPolygon(Vector2[] vertices)
|
||||
{
|
||||
Vertices = vertices;
|
||||
if (vertices is null || vertices.Length < 3)
|
||||
{
|
||||
MinX = MinY = MaxX = MaxY = 0f;
|
||||
return;
|
||||
}
|
||||
float minX = float.MaxValue, minY = float.MaxValue, maxX = float.MinValue, maxY = float.MinValue;
|
||||
foreach (var v in vertices)
|
||||
{
|
||||
if (v.X < minX) minX = v.X;
|
||||
if (v.X > maxX) maxX = v.X;
|
||||
if (v.Y < minY) minY = v.Y;
|
||||
if (v.Y > maxY) maxY = v.Y;
|
||||
}
|
||||
MinX = minX; MinY = minY; MaxX = maxX; MaxY = maxY;
|
||||
}
|
||||
|
||||
public bool IsEmpty => Vertices is null || Vertices.Length < 3;
|
||||
}
|
||||
|
||||
/// <summary>A cell's accumulated clip region: a set of convex view polygons + the union bounding rect.</summary>
|
||||
public sealed class CellView
|
||||
{
|
||||
public readonly List<ViewPolygon> Polygons = new();
|
||||
public float MinX { get; private set; } = float.MaxValue;
|
||||
public float MinY { get; private set; } = float.MaxValue;
|
||||
public float MaxX { get; private set; } = float.MinValue;
|
||||
public float MaxY { get; private set; } = float.MinValue;
|
||||
|
||||
public bool IsEmpty => Polygons.Count == 0;
|
||||
|
||||
/// <summary>A region covering the entire NDC viewport — the camera cell's seed region
|
||||
/// (mirrors retail PView::DrawInside copy_view(..., 4) at decomp:433814).</summary>
|
||||
public static CellView FullScreen()
|
||||
{
|
||||
var v = new CellView();
|
||||
v.Add(new ViewPolygon(new[]
|
||||
{
|
||||
new Vector2(-1f, -1f), new Vector2(1f, -1f), new Vector2(1f, 1f), new Vector2(-1f, 1f),
|
||||
}));
|
||||
return v;
|
||||
}
|
||||
|
||||
public void Add(ViewPolygon p)
|
||||
{
|
||||
if (p.IsEmpty) return;
|
||||
Polygons.Add(p);
|
||||
if (p.MinX < MinX) MinX = p.MinX;
|
||||
if (p.MinY < MinY) MinY = p.MinY;
|
||||
if (p.MaxX > MaxX) MaxX = p.MaxX;
|
||||
if (p.MaxY > MaxY) MaxY = p.MaxY;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue