feat(render): IndoorDrawPlan.ShellPass — every visible cell, no drawable filter (R1)
Pure port of retail DrawCells membership: reverse cell_draw_list, per-slice. Pins the grey regression — a cell in OrderedVisibleCells is never dropped from the shell pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2ec8f41200
commit
bff1955066
2 changed files with 76 additions and 0 deletions
30
src/AcDream.App/Rendering/IndoorDrawPlan.cs
Normal file
30
src/AcDream.App/Rendering/IndoorDrawPlan.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// IndoorDrawPlan.cs
|
||||||
|
//
|
||||||
|
// Pure (GL-free) port of the membership half of retail PView::DrawCells (0x5a4840):
|
||||||
|
// the reverse cell_draw_list iterated per portal_view slice. EVERY visible cell with a
|
||||||
|
// non-empty view is included — there is NO "drawable" filter. Dropping cells without a
|
||||||
|
// clip-slot was the grey-walls bug (the cell's sealed shell never drew → clear color showed).
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AcDream.App.Rendering;
|
||||||
|
|
||||||
|
public readonly record struct CellDrawEntry(uint CellId, IReadOnlyList<ViewPolygon> Slices);
|
||||||
|
|
||||||
|
public static class IndoorDrawPlan
|
||||||
|
{
|
||||||
|
/// <summary>Reverse OrderedVisibleCells (far→near), each visible cell with its view
|
||||||
|
/// slices. Mirrors DrawCells' shell/object loops. Cells whose view is empty are skipped
|
||||||
|
/// (they are not actually visible); no other cell is ever dropped.</summary>
|
||||||
|
public static List<CellDrawEntry> ShellPass(PortalVisibilityFrame frame)
|
||||||
|
{
|
||||||
|
var result = new List<CellDrawEntry>(frame.OrderedVisibleCells.Count);
|
||||||
|
for (int i = frame.OrderedVisibleCells.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
uint cellId = frame.OrderedVisibleCells[i];
|
||||||
|
if (!frame.CellViews.TryGetValue(cellId, out var view) || view.IsEmpty)
|
||||||
|
continue;
|
||||||
|
result.Add(new CellDrawEntry(cellId, view.Polygons));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
46
tests/AcDream.App.Tests/Rendering/IndoorDrawPlanTests.cs
Normal file
46
tests/AcDream.App.Tests/Rendering/IndoorDrawPlanTests.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using AcDream.App.Rendering;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AcDream.App.Tests.Rendering;
|
||||||
|
|
||||||
|
public class IndoorDrawPlanTests
|
||||||
|
{
|
||||||
|
private static ViewPolygon Quad() => new(new[]
|
||||||
|
{ new Vector2(-1, -1), new Vector2(1, -1), new Vector2(1, 1), new Vector2(-1, 1) });
|
||||||
|
|
||||||
|
private static PortalVisibilityFrame FrameWith(params uint[] orderedCells)
|
||||||
|
{
|
||||||
|
var f = new PortalVisibilityFrame();
|
||||||
|
foreach (var id in orderedCells)
|
||||||
|
{
|
||||||
|
f.OrderedVisibleCells.Add(id);
|
||||||
|
var v = new CellView(); v.Add(Quad());
|
||||||
|
f.CellViews[id] = v;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ShellPass_IncludesEveryVisibleCell_NoFilter()
|
||||||
|
{
|
||||||
|
// The grey bug: a cell in OrderedVisibleCells must NEVER be dropped from the
|
||||||
|
// shell pass. (Old code dropped cells lacking a ClipFrameAssembler slot.)
|
||||||
|
var f = FrameWith(0x01, 0x02, 0x03);
|
||||||
|
var plan = IndoorDrawPlan.ShellPass(f);
|
||||||
|
Assert.Equal(new uint[] { 0x03, 0x02, 0x01 }, plan.Select(e => e.CellId).ToArray()); // reverse = far→near
|
||||||
|
Assert.All(plan, e => Assert.NotEmpty(e.Slices));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ShellPass_ExcludesEmptyViewCells()
|
||||||
|
{
|
||||||
|
var f = FrameWith(0x01);
|
||||||
|
f.OrderedVisibleCells.Add(0x02); // present in the list…
|
||||||
|
f.CellViews[0x02] = new CellView(); // …but empty view → not drawable
|
||||||
|
var plan = IndoorDrawPlan.ShellPass(f);
|
||||||
|
Assert.Equal(new uint[] { 0x01 }, plan.Select(e => e.CellId).ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue