# M03-RND-M2-PLACEMENT-TRANSFORM-001 — M2 placement transform resolver ## Ownership - Target: M03 - Program: RND - Owner/Agent ID: sindo-main-codex - Branch: `work/sindo-main-codex/m03-m2-placement-transform` - Lease expires UTC: 2026-07-19 - Integrator: M03 milestone integrator ## Outcome Extract pure ADT M2 placement basis/origin-offset calculation, including the existing waterfall and Elwynn cliff-rock calibrations, into a scene-free service. ## Non-goals - Change coordinate conversion, placement positions, rotations or scale clamps. - Generalize model-specific corrections or add new allowlisted models. - Move grouping/tasks, MultiMesh/Node/Mesh/material/RID creation or caches. - Change M2 animation/material behavior, cache versions or renderer profiles. - Claim build-12340 placement parity beyond existing fixtures. ## Paths - Exclusive: `src/render/m2/m2_placement_transform_resolver.gd`, `src/tools/verify_m2_placement_transform_resolver.gd`, `docs/modules/m2-placement-transform-resolver.md`, this claim - Shared/hotspots: `src/scenes/streaming/streaming_world_loader.gd`, `docs/modules/world-renderer.md`, `docs/modules/README.md`, `RENDER.md`, `targets/03-renderer-facade.md` - Generated/ignored: `.godot`, native DLL, generated ADT resources, caches and proprietary renderer corpus ## Contracts and data - Input: ADT-loader Godot Euler rotation, normalized/original M2 relative path, and raw placement scale where origin compensation is requested - Output: `Basis` and local origin-offset `Vector3`; no retained state - Regular models use `Basis.from_euler`; two cliff rocks retain narrow YZX-style shell correction; two waterfall sheets retain yaw/twist/anchor compensation - Scale clamps remain caller-owned for final basis and resolver-owned at `0.0001` only for historical waterfall anchor compensation - Cache/schema/coordinate versions: unchanged ## Dependencies - Requires: current master `1b6c468` - Blocks: pure M2 grouping extraction and broader M2 service decomposition - External state: none; tests use synthetic rotations/paths and pinned constants ## Verification - Commands: dedicated regular/path-normalization/cliffrock/waterfall/twist-anchor/ scale and bounded timing verifier; three loader call-site/source boundaries; M2 unique/dedupe plus facade/terrain/internal-access/manifest/shutdown gates - Fidelity evidence: exact formulas/constants and model allowlists moved unchanged - Performance budget: allocation-free scalar/Basis math per placement aside from path normalization; no Node, Resource, RID, task, cache or file access ## Documentation deliverables - Inline resolver API documentation - New module spec with inputs/outputs, data-flow, lifecycle, ownership, failure, performance, fidelity limitations and source map - World renderer/module registry/`RENDER.md` updates ## Simplicity and naming - Important name: `M2PlacementTransformResolver` - Simplest solution: stateless service with basis and origin-offset queries - Rejected complexity: transform strategy hierarchy, generic correction registry, Resources, data-driven override format or callback injection - Unavoidable complexity: four measured model-specific exceptions remain explicit - Measured optimization evidence: bounded synthetic transform loop ## Status - State: claimed - Done: scope, formulas, allowlists and ownership published - Next: implement resolver, migrate three call sites, tests and docs - Blocked by: ## Handoff - Commit: - Results: - Remaining risks: - Documentation updated: