67 lines
3.2 KiB
Markdown
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.
|