Files
workinf_Blender_Wasm/docs/web/mesh-buffer-layout.md
2026-08-12 04:47:48 -04:00

67 lines
3.2 KiB
Markdown

# MeshIR Buffer Layout
This document is the versioned boundary between the Blender reader and the
Three.js renderer. The compatibility C ABI returns a JSON snapshot. The
preferred ABI separates JSON metadata from a native WBG1 geometry stream, and
the Worker transfers each typed mesh buffer without reconstructing large JSON
arrays. JSON arrays remain a fallback for older engine binaries.
## Coordinate and topology contract
- Blender source coordinates are right-handed, Z-up, with forward `-Y`.
- Positions and normals use packed little-endian IEEE-754 `float32` values.
- `indices` are packed little-endian unsigned 32-bit integers and reference
`positions` vertices.
- `topology` is `triangles`; every three indices form one triangle.
- `triangleCornerIndices` maps every index entry to the original Blender mesh
corner. It is required when UV or color attributes are present because a
single position can have multiple corner values.
- `triangleMaterialIndices` has one non-negative integer per triangle and
indexes `materialSlotIds`.
## SceneIR fields
| Field | Element count | Type | Domain |
| --- | ---: | --- | --- |
| `positions` | `vertexCount * 3` | `float32` | Point |
| `normals` | `vertexCount * 3` | `float32` | Point, normalized |
| `indices` | `triangleCount * 3` | `uint32` | Triangle corners |
| `triangleCornerIndices` | `triangleCount * 3` | `uint32` | Blender Corner |
| `uvs` | `cornerCount * 2` | `float32` | Corner, optional |
| `colors` | `cornerCount * 4` | `float32` RGBA | Corner, optional |
| `triangleMaterialIndices` | `triangleCount` | `uint32` | Face expanded to triangles |
| `triangleFaceIndices` | `triangleCount` | `uint32` | Source face for edit selection |
| `edgeVertexIndices` | `edgeCount * 2` | `uint32` | Edge endpoints |
| `tangents` | `cornerCount * 4` | `float32` | Corner tangent/sign, optional |
| `splitNormals` | `cornerCount * 3` | `float32` | Corner normal, optional |
`bounds.min` and `bounds.max` are three finite JSON numbers in source object
space. `materialSlotIds` are stable SceneIR IDs and never contain embedded
material data.
## Native WBG1 stream
The stream starts with `WBG1`, a little-endian schema version and mesh count.
Each mesh contains an ID length, eleven element counts, UTF-8 ID bytes, then
the following arrays in order:
```text
positions:f32, indices:u32, normals:f32, triangleCornerIndices:u32,
uvs:f32, colors:f32, triangleMaterialIndices:u32,
triangleFaceIndices:u32, edgeVertexIndices:u32, tangents:f32,
splitNormals:f32
```
Every count is element-based and every scalar is 4 bytes, so array starts stay
4-byte aligned. The decoder rejects truncation/trailing bytes, unknown mesh
IDs, count/summary mismatches and indices outside `vertexCount`. Topology
changes must regenerate triangle-face and edge mappings; stale source arrays
are never accepted.
`geometryStatus: "binary"` means metadata references a transferred per-mesh
buffer through `geometryBufferId`. `geometryStatus: "available"` is the JSON
fallback. After the initial WBG1 generation, `MeshGeometryDelta` carries
`meshId`, field, byte offset and transferable replacement bytes for stable-size
changes; topology or attribute-layout changes replace only that mesh envelope.
Network-style progressive sub-mesh streaming is not implied by WBG1.