using System.Numerics; namespace AcDream.Core.Physics; /// /// Retail Frame (acclient.h:30647) — named CellFrame here to avoid /// colliding with DatReaderWriter.Types.Frame (the dat placement/animation /// frame, used in physics-adjacent code such as ShadowShapeBuilder). /// is LOCAL to the owning cell: outdoor → X/Y ∈ [0,192) within /// the landblock, Z = height; indoor → the EnvCell-relative placement. /// replaces retail's m_fl2gv 3×3 local→global /// matrix (equivalent rotation). /// public readonly record struct CellFrame(Vector3 Origin, Quaternion Orientation); /// /// Retail Position (acclient.h:30658): the (which-cell, where-inside) pair. /// One type for indoor and outdoor. The full 32-bit cell id (high 16 = landblock /// prefix, low 16 = cell index) plus the cell-local . Neither /// half is ever reconstructed from a streaming center — see #145 design spec. The /// Frame member keeps retail's name. /// public readonly record struct Position(uint ObjCellId, CellFrame Frame) { public Position(uint objCellId, Vector3 origin, Quaternion orientation) : this(objCellId, new CellFrame(origin, orientation)) { } }