refactor(pipeline): MP1a - MeshExtractor extracted to AcDream.Content (verbatim move)

This commit is contained in:
Erik 2026-07-05 20:19:52 +02:00
parent e3376d4734
commit 30cc1e282e
6 changed files with 1260 additions and 1113 deletions

View file

@ -30,6 +30,50 @@ our tree (see CLAUDE.md for the full breakdown):
interface WB's internals expect (O-D7 fallback; `ObjectMeshManager` has 26
internal `_dats.*` call sites — above the 20-site inline-swap threshold).
**MP1a (2026-07-05): CPU mesh-extraction half moved to `AcDream.Content`.**
The GL-free portion of the former `ObjectMeshManager` — dat read → polygon
walk → vertex/index build → inline BCn/palette texture decode →
`ObjectMeshData` — is now `MeshExtractor` in a new `src/AcDream.Content/`
assembly (no Silk.NET dependency), so the MP1b bake tool can run the exact
same extraction code offline without an OpenGL context. This was a
mechanical, verbatim move (namespace + visibility only) per
`docs/superpowers/plans/2026-07-05-mp1a-content-extraction.md` — no
behavior change, no divergence-register row.
- `src/AcDream.Content/MeshExtractor.cs` — the `Prepare*` family
(`PrepareMeshData`, `PrepareSetupMeshData`, `PrepareGfxObjMeshData`,
`PrepareEnvCellMeshData`, `PrepareCellStructMeshData`,
`PrepareCellStructEdgeLineData`) + private helpers (`CollectParts`,
`CollectEmittersFromScript`, `ComputeBounds`, `BuildPolygonIndices`,
`BuildCellStructPolygonIndices`) and the decoded-texture cache /
`ThreadLocal<BcDecoder>` that back them.
- `src/AcDream.Content/ObjectMeshData.cs` — the CPU-side boundary records:
`VertexPositionNormalTexture`, `StagedEmitter`, `ObjectMeshData`,
`MeshBatchData`, `TextureBatchData`.
- `src/AcDream.Content/TextureKey.cs` — the atlas dedup key, lifted out of
the GL-owning `TextureAtlasManager` (which stays in App and now
references the lifted struct).
- `src/AcDream.Content/IDatReaderWriter.cs`, `EdgeLineBuilder.cs` — GL-free
dependencies of the extractor, moved (namespace-only) alongside it.
- **Stays in `src/AcDream.App/Rendering/Wb/`:** `ObjectMeshManager` (now a
thin wrapper owning the staged-queue/worker-pool/Dispose-quiesce lifecycle
and all GL upload — constructs one `MeshExtractor` and delegates every
former `Prepare*` call site to it), `ObjectRenderData`/`ObjectRenderBatch`
(hold a GL `TextureAtlasManager` field), `TextureAtlasManager`,
`DatCollectionAdapter` (concrete `DatCollection`-backed implementation of
the now-Content-namespaced `IDatReaderWriter`), `GeometryUtils` (used only
by App-side raycasting, not by extraction), `AcSurfaceMetadata`/
`AcSurfaceMetadataTable` (not on the extraction path), `Building.cs`
(explicitly out of scope).
- `AcDream.Core` is untouched; `AcDream.Content` references `AcDream.Core`
(for `TextureHelpers`, `Sphere`/`BoundingBox` via `Chorizite.Core.Lib`);
`AcDream.App` references `AcDream.Content`. `AcDream.Core` does NOT
reference `AcDream.Content` (one-way dependency, per Code Structure Rule 2).
- Reason: MP1 (`docs/superpowers/specs/2026-07-05-modern-pipeline-design.md`
§6.1) — the bake tool needs the identical mesh/texture extraction code
running with no GL context, so baked pak output and live-client output stay
byte-identical.
**Workflow:** Before re-implementing any AC-specific rendering or dat-handling
algorithm, **check this inventory first**. If we already extracted it (🟢
sections), it's in `src/AcDream.App/Rendering/Wb/` — use our copy. If WB has