Specification - Field Entity Extraction Rules (Godot -> SceneSnapshot)¶
Charter section: Sec4 Module Map (GodotAdapter), Sec7.1 Field Entity Representation
Status: Implemented
Key source files: GodotAdapter/SnapshotBuilder.cs, FieldSource3D.cs
1) Purpose¶
Defines how FieldSource3D nodes in the Godot scene tree are extracted into
renderer-native FieldEntitySOA entries within SceneSnapshot.
2) Extraction Pipeline (Implemented)¶
SnapshotBuilder.BuildFromGodotScene(root) performs:
- Collect: Recursively find all
FieldSource3Dnodes in scene tree. - Sort: Sort by
NodePathusingstring.CompareOrdinal(deterministic ordering). - Filter: Retain only nodes with
Enabled = true. - Extract per field:
- Resolve effective canonical params via
field.ResolveEffectiveParams(out reason) - Read
MetricModel - Read resolved
ShapeType,CurveType, andModeFlags - Get world transform (
GlobalTransform) and computeAffineInverse - Pack resolved
rInner,rOuter,amp,a,b,c,r0,r1 - Append 8-float block to
PackedParamBuffer - Compute conservative world AABB via
field.GetWorldInfluenceAabbConservative() - Emit into
FieldEntitySOAarrays - Build TLAS:
FieldTLAS.Build(fields)over the extracted entities.
3) Ordering Rules (Implemented)¶
Primary sort key: NodePath.ToString() via string.CompareOrdinal.
This ensures:
- Stable entity index assignment across frames (given stable scene structure)
- Deterministic accumulation order in
FieldSystem.AccelAt - Reproducible snapshot content for validation
No secondary sort key is needed; full path ordinal comparison is sufficient.
4) Parameter Packing (Implemented)¶
All fields pack into uniform 8-float blocks via PackedParamBuffer.AppendBlock8:
[+0] rInner [+1] rOuter [+2] amp
[+3] a [+4] b [+5] c
[+6] r0 (reserved) [+7] r1 (reserved)
Field entity stores paramOffset (index into buffer) and paramLength (always 8).
Values are canonical resolved values, not raw legacy inspector values.
5) Bounds Extraction (Implemented)¶
World bounds come from FieldSource3D.GetWorldInfluenceAabbConservative().
This must return a world-space AABB that fully contains the field's influence
region (rOuter sphere or box bounds transformed to world).
Conservatism requirement: bounds must never underestimate. Underestimation can cause missed field contributions; overestimation is safe and only increases candidate counts.
6) Geometry Extraction (Implemented)¶
Parallel to field extraction, SnapshotBuilder also extracts geometry:
- Collect
CollisionObject3Dnodes (sorted by NodePath) - Collect
VisualInstance3Dnodes (sorted by NodePath) - Prefer collision objects; skip visuals that have collision ancestors or descendants
- Filter collision objects by
CollisionLayer != 0(raycast targets only) - Compute world AABB per node (from collision shapes or visual AABB)
- Inflate bounds by
GeometryInflateconstant (0.02) - Store as
GeometryEntitySOAwith Godot instance IDs
Shape AABB extraction handles: BoxShape3D, SphereShape3D, CapsuleShape3D,
CylinderShape3D. Unknown shapes fall back to node position +/- 0.05.
7) Transform Handling (Implemented)¶
Transforms are stored as System.Numerics.Matrix4x4.
Conversion: SnapshotBuilder.ToMatrix4x4(Transform3D t) extracts basis columns
and origin into a matrix compatible with Vector3.Transform and
Vector3.TransformNormal.
Both WorldFromLocal and LocalFromWorld are stored to avoid per-query inverse.
8) Defaults and Compatibility¶
Canonical default values (before legacy migration):
rInner = 0,rOuter = 0,amp = 0curveType = Linear,a = 0,b = 0,c = 0shapeType = SphereRadial,metricModel = GRINmodeFlags = 0
Compatibility behavior:
- If canonical appears unset but legacy fields are meaningful,
FieldSource3Dmigrates legacy values into canonical fields on_Ready(). - If canonical and legacy are both materially set and differ, canonical wins and legacy is ignored (warning logged once).
9) Validation¶
SnapshotBuilder emits periodic [SNAPSHOT] log lines reporting:
- Total geometry count (collision vs visual breakdown)
- Collision objects skipped (non-raycast)
- Visual objects skipped (collision preference)
- Bounds samples for first 3 geometry entities
Log is controlled by DebugLogConfig.EnableSnapshotLog and
SnapshotLogIntervalSec.