using System.Numerics; using AcDream.Core.World; using Xunit; namespace AcDream.Core.Tests.World; public class WorldEntityAabbTests { [Fact] public void Aabb_DefaultRadius_PositionPlusMinus5() { var entity = new WorldEntity { Id = 1, SourceGfxObjOrSetupId = 0, Position = new Vector3(10, 20, 30), Rotation = System.Numerics.Quaternion.Identity, MeshRefs = System.Array.Empty(), }; entity.RefreshAabb(); Assert.Equal(new Vector3(5, 15, 25), entity.AabbMin); Assert.Equal(new Vector3(15, 25, 35), entity.AabbMax); } [Fact] public void Aabb_MultiPartOffsets_CoverTheParts() { // #119 follow-up: the AAB3 tower staircase — 43 parts spiralling to // (3, 3, 15.15) root-relative. The box (and the viewcone sphere derived // from it) must cover the parts, not just the ±5 m anchor neighborhood; // the anchor-only box made the staircase vanish whenever the gaze left // the base (visible climbing down, gone climbing up). var entity = new WorldEntity { Id = 1, SourceGfxObjOrSetupId = 0x020003F2, Position = new Vector3(300, -132, 112), Rotation = System.Numerics.Quaternion.Identity, MeshRefs = new[] { new MeshRef(0x01000E2A, Matrix4x4.CreateTranslation(0f, 3f, 1.55f)), new MeshRef(0x01000E2D, Matrix4x4.CreateTranslation(-1.75f, 3f, 15.15f)), }, }; entity.RefreshAabb(); // Top part sits at z = 112 + 15.15 = 127.15 — must be inside the box. Assert.True(entity.AabbMax.Z >= 127.15f, $"box top {entity.AabbMax.Z} must cover the highest part (z=127.15)"); // Conservative symmetric expansion still contains the old ±5 box. Assert.True(entity.AabbMin.Z <= 107f && entity.AabbMax.X >= 305f); } [Fact] public void Aabb_DirtyFlag_SetByMutator_ClearedByRefresh() { var entity = new WorldEntity { Id = 1, SourceGfxObjOrSetupId = 0, Position = new Vector3(10, 20, 30), Rotation = System.Numerics.Quaternion.Identity, MeshRefs = System.Array.Empty(), }; entity.RefreshAabb(); Assert.False(entity.AabbDirty); entity.SetPosition(new Vector3(100, 200, 300)); Assert.True(entity.AabbDirty); entity.RefreshAabb(); Assert.False(entity.AabbDirty); Assert.Equal(new Vector3(95, 195, 295), entity.AabbMin); } }