feat(core): UCG Stage 1 — EnvCell + PointInCell (AABB/BSP)

Adds `EnvCell` (sealed, extends `ObjCell`) with a primitive constructor
and `PointInCell` that uses the cell-containment BSP when present, else
falls back to an AABB test. Retail anchor: CEnvCell (acclient.h:32072).
BSP branch delegates to `BSPQuery.PointInsideCellBsp` (BSPQuery.cs:1034);
the AABB branch is the genuinely new logic. No `FromDat` factory — that is
a separate later task. Consumed by nobody yet (Stage 1 scaffold).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-02 08:59:52 +02:00
parent 9cb15710be
commit 76c9e2f07d
2 changed files with 66 additions and 0 deletions

View file

@ -0,0 +1,33 @@
using System.Numerics;
using AcDream.Core.World.Cells;
using Xunit;
namespace AcDream.Core.Tests.World.Cells;
public class EnvCellTests
{
private static EnvCell Make(Vector3 min, Vector3 max, Matrix4x4? transform = null)
{
var t = transform ?? Matrix4x4.Identity;
Matrix4x4.Invert(t, out var inv);
return new EnvCell(0xA9B40174u, t, inv, min, max,
System.Array.Empty<CellPortal>(), System.Array.Empty<uint>(),
seenOutside: false, containmentBsp: null);
}
[Fact]
public void PointInCell_NullBsp_Aabb_InsideIsTrue()
=> Assert.True(Make(new Vector3(0,0,0), new Vector3(10,10,10)).PointInCell(new Vector3(5,5,5)));
[Fact]
public void PointInCell_NullBsp_Aabb_OutsideIsFalse()
=> Assert.False(Make(new Vector3(0,0,0), new Vector3(10,10,10)).PointInCell(new Vector3(20,5,5)));
[Fact]
public void PointInCell_TransformsWorldToLocalBeforeTesting()
{
var c = Make(new Vector3(0,0,0), new Vector3(10,10,10), Matrix4x4.CreateTranslation(100,0,0));
Assert.True(c.PointInCell(new Vector3(105,5,5)));
Assert.False(c.PointInCell(new Vector3(5,5,5)));
}
}