refactor(M03): extract M2 placement grouper

This commit is contained in:
2026-07-17 00:05:49 +04:00
parent 9c9020e60f
commit 9df32d38ef
12 changed files with 633 additions and 59 deletions
+21 -18
View File
@@ -13,7 +13,7 @@
## Purpose
Resolve the unscaled Godot-space orientation and optional local origin offset
used by ADT M2 worker grouping, placeholder rendering and instance creation.
used by the pure placement grouper, placeholder rendering and instance creation.
## Non-goals
@@ -30,7 +30,7 @@ flowchart LR
ADT[ADT placement rotation/path/scale] --> Resolver[M2PlacementTransformResolver]
Resolver --> Basis[Unscaled Basis]
Resolver --> Offset[Local origin offset]
Basis --> Group[Worker grouping]
Basis --> Group[M2PlacementGrouper]
Basis --> Placeholder[Placeholder MultiMesh path]
Basis --> Instance[Instance path]
Offset --> Group
@@ -57,8 +57,8 @@ files, gameplay, network and editor UI are forbidden.
| Input | Godot Euler rotation in radians | ADT loader placement record | Resolver | Scalar copy | One call |
| Input | Relative M2 path | ADT MMDX/name table | Resolver allowlist | Caller string | One call |
| Input | Raw placement scale | ADT placement record | Offset compensation | Scalar copy | One call |
| Output | Unscaled `Basis` | Resolver | Group/placeholder/instance adapter | Value copy | One call |
| Output | Local `Vector3` offset | Resolver | Transform origin adapter | Value copy | One call |
| Output | Unscaled `Basis` | Resolver | Grouper/placeholder/instance adapter | Value copy | One call |
| Output | Local `Vector3` offset | Resolver | Grouper/placeholder/instance adapter | Value copy | One call |
Callers preserve their historical basis scale minima: grouping/instance use
`0.0001`, while placeholders use `0.01`.
@@ -88,22 +88,22 @@ world reset and shutdown require no clear, cancellation or resource release.
```mermaid
sequenceDiagram
participant Loader as StreamingWorldLoader
participant Caller as Grouper or StreamingWorldLoader
participant Resolver as M2PlacementTransformResolver
participant Consumer as Group/placeholder/instance path
Loader->>Resolver: resolve_basis(rotation, path)
Resolver-->>Loader: unscaled Basis
Loader->>Resolver: resolve_origin_offset(rotation, path, scale)
Resolver-->>Loader: local offset
Loader->>Consumer: compose historical scaled Transform3D
participant Consumer as Grouper/placeholder/instance path
Caller->>Resolver: resolve_basis(rotation, path)
Resolver-->>Caller: unscaled Basis
Caller->>Resolver: resolve_origin_offset(rotation, path, scale)
Resolver-->>Caller: local offset
Caller->>Consumer: compose historical scaled Transform3D
```
## Ownership, threading and resources
- The resolver retains no mutable state or engine resources.
- The loader owns placement records, final transforms, tasks, queues, caches,
MultiMesh/Node/Mesh/material/RID creation and cleanup.
- Pure methods are safe for current worker grouping and main-thread consumers.
- The grouper owns worker-path final transforms; the loader owns placement records,
tasks, queues, caches and MultiMesh/Node/Mesh/material/RID creation and cleanup.
- Pure methods are safe for grouper worker use and main-thread consumers.
- Returned `Basis`/`Vector3` values have no lifetime coupling to the resolver.
## Errors, cancellation and recovery
@@ -134,14 +134,15 @@ versions and rebuild instructions remain unchanged.
## Diagnostics and observability
The resolver emits no logs. The contract verifier compares formulas/constants,
checks all three loader consumers and records bounded synthetic timing. Visual
checks two direct loader consumers plus the grouper consumer and records bounded
synthetic timing. Visual
and asset-backed evidence remains in the renderer checkpoint workflow.
## Verification
- `verify_m2_placement_transform_resolver.gd`: regular fallback, path
normalization, both cliff rocks, both waterfalls, twist anchor, negative-scale
compensation, three loader adapters, source boundary and 10,000-pair timing.
compensation, three consumers, source boundary and 10,000-pair timing.
- M2 unique/dedupe, terrain, facade, internal-access, manifest, shutdown,
scheduler, streaming and coordinate regressions remain required.
- Fidelity evidence is exact extraction of existing calibrated formulas. The
@@ -149,7 +150,7 @@ and asset-backed evidence remains in the renderer checkpoint workflow.
## Extension points
- The next package may compose this resolver into a pure placement grouper.
- `M2PlacementGrouper` composes this resolver for the worker grouping path.
- New model corrections require separate measured fidelity evidence; this module
is not a generic override registry.
@@ -173,11 +174,13 @@ and asset-backed evidence remains in the renderer checkpoint workflow.
| Path | Responsibility |
|---|---|
| `src/render/m2/m2_placement_transform_resolver.gd` | Pure basis/offset rules and calibrated allowlists |
| `src/scenes/streaming/streaming_world_loader.gd` | Three adapters and final Transform3D/resource ownership |
| `src/render/m2/m2_placement_grouper.gd` | Grouping adapter and local Transform3D ownership |
| `src/scenes/streaming/streaming_world_loader.gd` | Two direct adapters and renderer resource ownership |
| `src/tools/verify_m2_placement_transform_resolver.gd` | Formula, source and performance regression |
## Related decisions and references
- [`m2-placement-grouper.md`](m2-placement-grouper.md)
- [`m2-unique-placement-registry.md`](m2-unique-placement-registry.md)
- [`world-renderer.md`](world-renderer.md)
- [`../../RENDER.md`](../../RENDER.md)