Queue translucent world GfxObj batches and scene particles in one stable far-to-near stream using transformed DAT sort centers, then drain it at retail's landscape and final-world boundaries. Preserve authored blend, cull, lighting, opacity, and adjacent-only batching so particles behind lifestones are composited through the crystal instead of overpainting it. Release build succeeds and all 5,914 tests pass with five intentional skips. Co-authored-by: OpenAI Codex <codex@openai.com>
40 lines
1.6 KiB
C#
40 lines
1.6 KiB
C#
using System.Numerics;
|
|
using AcDream.App.Rendering.Wb;
|
|
using Xunit;
|
|
|
|
namespace AcDream.App.Tests.Rendering.Wb;
|
|
|
|
public class InstanceGroupClearTests
|
|
{
|
|
// #193 (regression from #188, 2026-07-09): WbDrawDispatcher's InstanceGroup holds
|
|
// seven per-instance parallel lists — Matrices, LocalSortCenters, Slots,
|
|
// LightSets, IndoorFlags, Opacities, SelectionLighting — appended in lockstep
|
|
// (one entry per drawn instance) every frame. The
|
|
// per-frame reset must clear ALL of them. #188 added Opacities but left it out of
|
|
// the inline clear loop, so it grew one float per instance per frame forever; as
|
|
// List<float>'s backing array doubled it produced ~128 MB / ~512 MB LOH float[]
|
|
// arrays and leaked ~1 GB/min -> OOM after ~50 min of play. This test pins that
|
|
// every parallel list is reset, so a newly-added list can't silently drift again.
|
|
[Fact]
|
|
public void ClearPerInstanceData_ClearsEveryParallelPerInstanceList()
|
|
{
|
|
var grp = new WbDrawDispatcher.InstanceGroup();
|
|
grp.Matrices.Add(Matrix4x4.Identity);
|
|
grp.LocalSortCenters.Add(Vector3.Zero);
|
|
grp.Slots.Add(1u);
|
|
grp.LightSets.Add(-1);
|
|
grp.IndoorFlags.Add(0u);
|
|
grp.Opacities.Add(1.0f);
|
|
grp.SelectionLighting.Add(new Vector2(0f, 1f));
|
|
|
|
grp.ClearPerInstanceData();
|
|
|
|
Assert.Empty(grp.Matrices);
|
|
Assert.Empty(grp.LocalSortCenters);
|
|
Assert.Empty(grp.Slots);
|
|
Assert.Empty(grp.LightSets);
|
|
Assert.Empty(grp.IndoorFlags);
|
|
Assert.Empty(grp.Opacities); // #193 — the list that leaked
|
|
Assert.Empty(grp.SelectionLighting);
|
|
}
|
|
}
|