fix(app): interior stabs are landblock-local, not cell-local
Phase 2d's initial composition was cellOrigin + cellRot*stabLocal, assuming EnvCell.StaticObjects carried cell-local frames and that EnvCell.Position was the cell-to-landblock transform. User reported all interior objects "far up in the air" after the initial Phase 2d. Diagnostic confirmed the real shape: EnvCell 0xA9B40100.Position.Origin = (84.1, 131.5, 66.0) and the first Stab inside it had Frame.Origin = (92.1, 131.5, 68.0). Both are in landblock-local X/Y/Z space — the stab is 8 units east and 2 units up from the cell's registered origin but expressed in the SAME coordinate space, not as an offset. Adding the cell origin on top double-counted ~155 units in Z and put the statue at worldPos Y=263 Z=233+, completely out of range. EnvCell.Position appears to tell the physics engine which landblock region owns the cell (for collision/portal lookups) rather than acting as a cell-to-landblock transform for contained objects. The stabs are already in the same coordinate system as LandBlockInfo.Objects stabs. Fix: drop the cell origin + cell rotation from the composition. World position is now just stab.Frame.Origin + lbOffset, mirroring the regular Stab handling exactly. Smoke verified: 475 interior objects still hydrate, process runs clean. Visual verification pending. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
abcfb55418
commit
82e857cf21
1 changed files with 8 additions and 10 deletions
|
|
@ -381,16 +381,14 @@ public sealed class GameWindow : IDisposable
|
|||
|
||||
if (meshRefs.Count == 0) continue;
|
||||
|
||||
// Compose: the stab's position is cell-local, and the cell's Position
|
||||
// is landblock-local. Rotate the stab-local position by the cell's
|
||||
// orientation before adding the cell origin.
|
||||
var stabLocalPos = stab.Frame.Origin;
|
||||
var cellOrigin = envCell.Position.Origin;
|
||||
var cellRot = envCell.Position.Orientation;
|
||||
var rotatedStab = System.Numerics.Vector3.Transform(stabLocalPos, cellRot);
|
||||
var landblockLocalPos = cellOrigin + rotatedStab;
|
||||
var worldPos = landblockLocalPos + lbOffset;
|
||||
var worldRot = cellRot * stab.Frame.Orientation;
|
||||
// Stabs inside EnvCells are already in landblock-local coordinates
|
||||
// (same coordinate space as LandBlockInfo.Objects stabs) — NOT
|
||||
// cell-local. The EnvCell.Position field tells the physics engine
|
||||
// which cell owns the object, but it doesn't translate coordinates.
|
||||
// Adding cellOrigin was a wrong assumption that left interior objects
|
||||
// floating ~150 units in the air.
|
||||
var worldPos = stab.Frame.Origin + lbOffset;
|
||||
var worldRot = stab.Frame.Orientation;
|
||||
|
||||
var hydrated = new AcDream.Core.World.WorldEntity
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue