Assets: weld vertices / index-dedup imported meshes (large-mesh memory + import time)

Current State

The FBX cook emits geometry fully de-indexed — one vertex per triangle corner, indices[i] == i (engine/vendor/fbx_wrap.c, indices[vi] = vi). The Bistro exterior mesh is therefore 8,496,360 vertices for 2,832,120 triangles (zero vertex sharing) → a ~272 MB vertex buffer.

Goal

Weld shared vertices during the cook so imported meshes use a real index buffer, cutting VBO size and upload/import time (typically 3–6× fewer vertices).

Scope

  • Add a vertex-weld / index-dedup pass in the mesh cook: hash (pos, normal, uv) → reuse existing index. Shared between the FBX and glTF cook paths where possible (engine/assets/FbxLoader.zig, GltfLoader.zig).
  • Weld per submesh (preserve submesh index ranges) so it composes with the material-slot submesh table.
  • Consider 16-bit indices where a submesh's vertex count fits in u16.
  • Bump AssetImporter.VERSION_MODEL to force a one-time re-cook.

Notes

Interacts with the synchronous-import perf issue tracked for the Bistro milestone — cooking 2.8 M triangles is where first-open wall-clock time goes. Welding reduces both memory and cook cost.

Acceptance

  • Bistro exterior cooks to a substantially smaller vertex buffer with identical rendered output.
  • Import time for the Bistro sample measurably drops.
Edited by Bruno Massa