using System.Numerics; using AcDream.Core.Physics; using Xunit; namespace AcDream.Core.Tests.Physics; public class PhysicsBodyCellSyncTests { [Fact] public void SnapToCell_SeedsCellPosition_AndWorldPosition() { var body = new PhysicsBody(); body.SnapToCell(0xC95B0001u, worldPos: new Vector3(1000f, 2000f, 12f), cellLocal: new Vector3(14.8f, 0.3f, 12f)); Assert.Equal(0xC95B0001u, body.CellPosition.ObjCellId); Assert.Equal(new Vector3(14.8f, 0.3f, 12f), body.CellPosition.Frame.Origin); Assert.Equal(new Vector3(1000f, 2000f, 12f), body.Position); } [Fact] public void PositionDelta_MirrorsIntoCellPosition_WithinLandblock() { var body = new PhysicsBody(); body.SnapToCell(0xC95B0001u, new Vector3(1000f, 2000f, 12f), new Vector3(100f, 50f, 12f)); body.Position += new Vector3(5f, 3f, 0f); // move within the landblock Assert.Equal(new Vector3(105f, 53f, 12f), body.CellPosition.Frame.Origin); Assert.Equal(0xC95B0001u, body.CellPosition.ObjCellId); // no [0,192) crossing → same cell Assert.Equal(new Vector3(1005f, 2003f, 12f), body.Position); // world still authoritative + moved } [Fact] public void PositionDelta_AcrossSouthLandblockEdge_BumpsCellAndRewraps() { var body = new PhysicsBody(); // local Y just above 0 in 0xC95B (lbY=0x5B); move south past 0 → south neighbour 0xC95A, local Y near 192. body.SnapToCell(0xC95B0001u, new Vector3(1000f, 2000f, 12f), new Vector3(100f, 0.3f, 12f)); body.Position += new Vector3(0f, -1f, 0f); int lbY = (int)((body.CellPosition.ObjCellId >> 16) & 0xFFu); Assert.Equal(0x5A, lbY); // bumped to south neighbour Assert.InRange(body.CellPosition.Frame.Origin.Y, 190f, 192f); // re-wrapped near top of southern block } [Fact] public void PositionDelta_WithoutSeed_LeavesCellPositionDefault() { // A body that was never SnapToCell'd (e.g. a remote entity) must NOT get // a synthesized cell — CellPosition stays default, no AdjustToOutside. var body = new PhysicsBody(); body.Position += new Vector3(10f, 10f, 0f); Assert.Equal(0u, body.CellPosition.ObjCellId); } }