BRZ: Bruce Archive Format
A .brz file is a Nextspace archive format that packages an Assembly. It is a hierarchy of Entities at a single root Entity node for export, import, and interchange between systems. It carries the Entity attribute values, parent-child hierarchy with transforms, and embedded 3D geometry (GLB).
BRZ files are produced by an Export BRZ job and consumed by the Import Assembly endpoint.
Container format
A BRZ file is a standard ZIP archive containing exactly one entry: a SQLite database named model.db. A ".db" file renamed to ".brz" is not considered valid.
Complete schema
The following is the exact creation script and schema explanation to use for new BRZ files. Copy-paste this to initialise a valid v7 database before inserting any data.
Inserting geometry correctly
The most common mistake when generating BRZ files is populating the Geometry.filepath column. When that column is non-empty the importer tries to read a file from disk instead of reading the embedded blob, which silently drops all geometry. Always set filepath to NULL.
GLB requirements
Each GLB embedded in the Geometry table must satisfy the following rules. Missing any of these will cause import failures, Tileset generation crashes, or models rendering incorrectly.
| Requirement | Description |
|---|---|
| At least one material | Every GLB must define at least one material using pbrMetallicRoughness. A simple default is fine (e.g. baseColorFactor [0.8, 0.8, 0.8, 1.0]). GLBs with zero materials will crash the Tileset generator. |
| Material reference on every primitive | The material index on each mesh primitive must be set. Omitting it produces undefined behaviour in downstream processing tools. |
Vertex normals (NORMAL) | Every mesh primitive must include a NORMAL accessor alongside POSITION. Without normals, lighting is broken and some processing tools may crash. |
| Indexed triangles (mode 4) | Primitives must use indexed triangle mode. Non-indexed geometry or other modes (lines, points) are not reliably supported. |
| Y-up orientation | Geometry must be authored in Y-up space per the glTF specification. +X = right, +Y = up, −Z = forward. The Nextspace viewer (CesiumJS) expects Y-up and automatically converts to its internal Z-up scene coordinate system. Geometry authored in Z-up will appear sideways. |
| Single-node structure | A single scene containing one root node with one child mesh node is the recommended GLB structure. Multi-node GLBs work but single-node is preferred for stable importer and Tileset generation behaviour. |
Minimal valid material example
Positioning and placement
The ParentRelationship transform (px/py/pz, quaternion, scale) is relative to the parent Entity, not world-absolute. The importer converts each row into a 4×4 matrix stored on the child Entity. At render time the viewer computes the world matrix by chaining transforms up the hierarchy: world = parent.world × child.local.
No collision detection, gravity, or snap-to-surface logic is applied. Objects will float, intersect, or sink if their translations are not computed from their actual geometry bounds.
Flat vs. nested hierarchies
In a flat hierarchy (every Entity is a direct child of the root), the root typically has an identity transform, so each child's px/py/pz values are effectively world-space coordinates.
In a nested hierarchy (e.g. monitor is a child of desk), each child is positioned relative to its parent. A monitor at py = 0.76 under a desk means "0.76 m above the desk's local origin", not 0.76 m above the world floor.
Recommended mesh origin convention
For generated assets, place each mesh origin at the centre of its base contact surface so that miny = 0 for floor-standing objects. This simplifies placement: in a flat hierarchy, py is the world-space Y of the surface the object rests on.
Placement from bounds
To place a child so its base sits on a surface, use the Geometry bounding box:
In a flat hierarchy, surface_y is the world-space Y of the support surface. In a nested hierarchy it is the parent-local Y of the support surface (e.g. the parent's maxy). If meshes follow the miny = 0 convention, the formula simplifies to py = surface_y.
Worked example (flat hierarchy)
All Entities below are children of the root Entity (1). Because the root has an identity transform, px/py/pz are world positions.