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

View file

@ -1,3 +1,4 @@
using AcDream.Content;
using DatReaderWriter;
using DatReaderWriter.Enums;
using DatReaderWriter.Lib.IO;

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,11 @@
using System.Numerics;
using DatReaderWriter.Types;
namespace AcDream.App.Rendering.Wb {
// MP1a (2026-07-05, Task 4): moved to AcDream.Content, namespace only —
// consumed by MeshExtractor.PrepareCellStructEdgeLineData, which must be
// GL-free.
namespace AcDream.Content {
public static class EdgeLineBuilder {
public static List<Vector3> BuildEdgeLines(CellStruct cellStruct) {
var edgeMap = new Dictionary<EdgeKey, List<Edge>>();

View file

@ -9,8 +9,13 @@ using System.Diagnostics.CodeAnalysis;
// WorldBuilder.Shared project reference can be dropped.
// The only consumer of IDatReaderWriter in acdream is DatCollectionAdapter +
// ObjectMeshManager, both already in this namespace.
//
// MP1a (2026-07-05, Task 4): moved to AcDream.Content, namespace only —
// MeshExtractor's constructor takes IDatReaderWriter and must be GL-free.
// DatCollectionAdapter (the concrete DatCollection-backed implementation)
// stays in AcDream.App; it now implements this Content-namespaced interface.
namespace AcDream.App.Rendering.Wb;
namespace AcDream.Content;
/// <summary>
/// Interface for the dat reader/writer

File diff suppressed because it is too large Load diff