BindingBuilder
A design-time helper component for authoring objectBindings and sceneConfig in the browser. Load a GLB, GLTF, OBJ, FBX, or USDZ asset, inspect its mesh nodes, edit binding fields, configure the scene, preview the result live, and export as JSON or TypeScript.
Try the public editor at react-immersive.liveroom.dev/editor .
Usage
import { BindingBuilder } from "@liveroom-tech/react-immersive";
export default function App() {
return <BindingBuilder licenseKey="your_license_key" />;
}Props
type BindingBuilderProps = {
licenseKey: string;
};licenseKey is required and is validated the same way as ModelViewer’s, see Licensing & plan tiers below. While the key is being checked, BindingBuilder renders a “Verifying license…” placeholder; if the key is invalid, it renders an error message instead of the editor.
Capabilities
Object tab
- Upload a
.glb, standalone/data-URI.gltf,.obj,.fbx,.usdz, or.zipbundle. ZIP bundles may contain GLTF dependencies, OBJ + MTL/textures, or FBX external textures; USDZ is uploaded directly - Traverse renderable mesh nodes and generate starter bindings automatically
- Edit binding fields: identity, label, type, status, booleans, style, actions, metrics, metadata, and saved camera state
- Move and rotate the selected object with a geometry-centered pivot, World or Local axes, numeric position/rotation fields, and restore-to-authored-transform support
- Author a full per-object material in the Material panel, a one-click
preset gallery (wood, metal, chrome, glass, plastic, fabric, ceramic,
concrete, etc.) plus collapsible sub-panels for PBR maps, roughness,
emission, opacity, normal & bump, displacement, ambient occlusion,
clearcoat, sheen, anisotropy, transmission & volume, and faces rendering.
Each sub-panel has an enable toggle, and every field maps to a
style.materialoverride (seeObjectBindingMaterial) - Undo/redo the current bindings (toolbar buttons, or
Cmd/Ctrl+Z/Cmd/Ctrl+Shift+Zwhile the Object tab is active), rapid edits like slider drags coalesce into a single undo step - Import a previously exported
objectBindings.jsonand merge it back onto the current model (matched bymodelObjectId, so re-imports survive hand edits or partial files) - Export the current bindings as JSON or TypeScript
Scene tab
- Configure scene-wide settings (lighting, environment, background, ground
shadows, wireframe, post-processing, annotations, per-clip animation options,
and a cinematic camera path), the same
SceneConfigshape consumed byModelViewer’ssceneConfigprop - Switch the model renderer between PBR, Matcap, and UV Checker. UV Checker overlays a numbered directional chart to diagnose stretching, seams, rotation, texel-density differences, and missing UV0 coordinates
- Author a cinematic camera path visually in the Cinematic sub-tab:
frame the model in the preview, click Add waypoint from current view to
capture the camera pose, then reorder, fly-to-preview (📍), or delete
waypoints. Toggle Enable / Loop / Auto-play and the glide Duration. The path
is stored on
sceneConfig.cinematicand replayed byModelViewer’scinematicprop - Undo/redo the scene config independently of the Object tab’s bindings history
- Import a previously exported
sceneConfig.json, merged by top-level section so a partial file doesn’t wipe sections it doesn’t include - Export the current scene config as JSON or TypeScript
Preview
- Live preview of the selected node in an embedded
ModelViewer
Moving and rotating objects
Open the Move & Rotate panel in the Object tab, then:
- Turn on Transform gizmo. Camera controls pause while editing is enabled.
- Select a bound mesh in the preview or object list.
- Drag an arrow to move on one axis, a plane handle to move on two axes, or a colored ring to rotate. Move and rotate handles are always shown together.
- Choose World to keep the handles aligned with the scene, or Local to align them with the selected object’s current orientation.
- Use the horizontal X, Y, and Z fields for precise values. Rotation fields display degrees; the exported binding stores radians.
The pivot is placed at the center of the selected object’s renderable geometry, so rotation happens around the object itself even when the source node’s authored origin is elsewhere. This authoring pivot does not rewrite the GLB/GLTF origin.
Both gizmo and numeric edits are saved to the selected binding’s local-space
transform.position and transform.rotation. Changing World/Local axis space
only changes the direction of the gizmo handles; it does not change the saved
position. Use Restore original position & rotation to remove those
overrides and return to the model-authored transform.
Exporting and Reusing Files
BindingBuilder has separate toolbars for bindings and scene settings, so export the data from the tab that owns it:
- Load your model first. The import and export controls become available once BindingBuilder has inspected its nodes.
- Open the Object tab to work with
objectBindings. In that tab’s toolbar, use Export → JSON or Export → TypeScript. - Open the Scene tab to work with
sceneConfig. Its toolbar has the same Export menu, producingsceneConfig.jsonorsceneConfig.ts. - Choose TypeScript for a file you will import into your application. Choose JSON for a portable snapshot that you want to bring back into BindingBuilder later.
We recommend keeping TypeScript exports alongside the viewer route, for example:
src/immersive/objectBindings.ts
src/immersive/sceneConfig.ts
public/model.glb
public/materials/... (when the export includes uploaded textures)The TypeScript bindings export already wraps the record in defineObjectBindings, so TypeScript validates the complete file without widening its keys or literal IDs. Import the named exports directly and pass them to ModelViewer:
import { useState } from "react";
import { ModelViewer } from "@liveroom-tech/react-immersive";
import { objectBindings as initialObjectBindings } from "./objectBindings";
import { sceneConfig } from "./sceneConfig";
export default function ProductViewer() {
const [objectBindings, setObjectBindings] = useState(initialObjectBindings);
return (
<ModelViewer
modelUrl="/model.glb"
licenseKey="your-license-key"
objectBindings={objectBindings}
sceneConfig={sceneConfig}
onObjectBindingsChange={setObjectBindings}
/>
);
}Importing Back into BindingBuilder
Use the Import button in the same toolbar as the matching export:
- Object tab → Import accepts an
objectBindings.jsonfile. Load the model first; incoming records are matched bymodelObjectId, so bindings for nodes absent from the current model are safely skipped. - Scene tab → Import accepts a
sceneConfig.jsonfile. Included top-level sections are merged into the current scene config, which lets you restore a partial scene preset without resetting the other settings.
TypeScript exports are deliberately for your application source code, not for the editor’s import button. Keep a JSON export whenever you expect to reopen or share the configuration in BindingBuilder.
Picking a texture map stores the durable path materials/<filename> in
the binding (this is what’s exported), and shows the image immediately in
the live preview via an in-memory blob: URL, so you can author without
first copying files into public/.
Exporting bundles the files automatically: if any material field was
filled by uploading a file, clicking Export
downloads a .zip instead of a single .json/.ts, containing the
export file plus a materials/ folder with every uploaded image. Unzip it
into your app’s public/ folder and the exported bindings resolve as-is.
Two different uploads that happen to share a filename are kept distinct
(materials/wood.jpg, materials/wood-2.jpg, …) rather than one
overwriting the other. If nothing was uploaded, Export downloads a plain
.json/.ts file exactly as before.
Licensing & plan tiers
BindingBuilder validates licenseKey the same way ModelViewer does, and additionally gates some editor features by the license’s plan tier:
| Tier | Unlocks |
|---|---|
free | Base color, metalness/roughness sliders, basic scene settings |
starter | + Texture maps, the specular workflow, reflectivity, environment lighting, environment backgrounds, wireframe preview, animation configuration, annotations, cinematic camera paths |
growth | + Post-processing effects |
A locked feature is shown in place (not hidden) with a message naming the required plan, so the feature stays discoverable while editing. Get a license key at the React Immersive Console .
Typical Workflow
- Mount
<BindingBuilder />in a dev-only route (e.g./dev/bindings) - Upload your
.glb,.gltf, or.zip - Select mesh nodes in the sidebar, edit their binding fields, move or rotate them as needed, or apply a material preset
- Configure scene-wide settings in the Scene tab
- Preview the interactive result in the embedded viewer
- Click Export → JSON or Export → TypeScript to download the bindings (and, if you uploaded any textures, a
.zipwith them included) - Drop the exported file (and any
materials/folder) into your app as the initialobjectBindings/sceneConfigstate