3.2 KiB
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
float32values. indicesare packed little-endian unsigned 32-bit integers and referencepositionsvertices.topologyistriangles; every three indices form one triangle.triangleCornerIndicesmaps 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.triangleMaterialIndiceshas one non-negative integer per triangle and indexesmaterialSlotIds.
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:
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.