feat(A.5 T8): WorldEntity AABB cache + dirty flag
Adds AabbMin/AabbMax (per-entity world-space bounding box) and AabbDirty flag to WorldEntity. RefreshAabb() recomputes the box from Position ±5 m (DefaultAabbRadius). SetPosition() writes Position and marks the cache dirty so the dispatcher calls RefreshAabb on first read rather than carrying stale bounds. AabbDirty defaults to true on construction — freshly-built entities have zero AabbMin/AabbMax until RefreshAabb is called. Two new conformance tests verify the ±5 m geometry and the dirty/clean state machine. Per Phase A.5 spec §4.6 Change #2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
295bce9bb2
commit
a0741bd13a
2 changed files with 71 additions and 0 deletions
|
|
@ -71,6 +71,30 @@ public sealed class WorldEntity
|
|||
/// present. Zero (no parts hidden) is the default.
|
||||
/// </summary>
|
||||
public ulong HiddenPartsMask { get; init; }
|
||||
|
||||
// Per Phase A.5 spec §4.6 Change #2 — cache per-entity AABB so the
|
||||
// dispatcher's frustum cull is a memory read, not a per-frame recompute.
|
||||
// AabbDirty starts true so the dispatcher calls RefreshAabb on first read
|
||||
// (AabbMin/AabbMax are Vector3.Zero until refreshed).
|
||||
public Vector3 AabbMin { get; private set; }
|
||||
public Vector3 AabbMax { get; private set; }
|
||||
public bool AabbDirty { get; private set; } = true;
|
||||
|
||||
private const float DefaultAabbRadius = 5.0f;
|
||||
|
||||
public void RefreshAabb()
|
||||
{
|
||||
var p = Position;
|
||||
AabbMin = new Vector3(p.X - DefaultAabbRadius, p.Y - DefaultAabbRadius, p.Z - DefaultAabbRadius);
|
||||
AabbMax = new Vector3(p.X + DefaultAabbRadius, p.Y + DefaultAabbRadius, p.Z + DefaultAabbRadius);
|
||||
AabbDirty = false;
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 pos)
|
||||
{
|
||||
Position = pos;
|
||||
AabbDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue