Skip to Content
API ReferenceTypes Reference

Types Reference

ObjectBinding

The core data record for each interactive mesh in the viewer.

type ObjectBinding = { id: string; type: ObjectBindingType; modelObjectId: string; label?: string; group?: string; tags?: string[]; visible?: boolean; selectable?: boolean; hoverable?: boolean; transform?: ObjectBindingTransform; style?: ObjectBindingStyle; actions?: ObjectBindingAction[]; metrics?: Record<string, number>; metadata?: Record<string, unknown>; cameraState?: ObjectBindingCameraState; };

Key Notes

  • The objectBindings record is keyed by node name, not by id
  • group assigns a binding to one named set, while tags can assign it to several queryable sets
  • transform stores persistent local-space position, rotation, and scale overrides; rotation values use radians
  • visible is live render state, not just an initial default
  • selectable: false and hoverable: false make the mesh inert to viewport picking; clicks resolve the front-most surface under the pointer, so a non-selectable mesh does not pass the click through to meshes behind it
  • style.material.baseColor is the committed source of truth for color picks
  • style.material.texture.path is the committed source of truth for texture uploads
  • If no texture.path and no style.material.baseColor are set, the viewer falls back to the original GLB/GLTF material
  • See ObjectBindingMaterial for the full set of per-object material overrides
  • metrics and metadata are displayed in the side panel as nested key/value fields (objects expand into indented child labels)
  • cameraState stores a saved camera view for the object; when both position and target are set, the viewer uses that view when the object is focused or selected instead of falling back to fitToBox

defineObjectBindings

A runtime identity helper that validates binding literals while preserving their exact inferred TypeScript types.

import { defineObjectBindings, type ObjectBindingActionId, type ObjectBindingKey, } from "@liveroom-tech/react-immersive"; const bindings = defineObjectBindings({ body: { id: "vehicle-body", modelObjectId: "body", type: "body", actions: [{ id: "repaint", label: "Repaint", type: "command" }], }, }); type BindingKeys = ObjectBindingKey<typeof bindings>; // "body" type BodyActions = ObjectBindingActionId<typeof bindings, "body">; // "repaint"

ObjectBindingKey<T> extracts the binding-map key union. ObjectBindingActionId<T, K> extracts the declared action-id union for binding K.

ObjectBindingTransform

type ObjectBindingTransform = { position?: [number, number, number]; // local model units rotation?: [number, number, number]; // local Euler angles in radians scale?: [number, number, number]; };

Missing fields retain their model-authored local values. Removing the complete transform restores the model-authored position, rotation, and scale.

ModelViewer and BindingBuilder convert World/Local gizmo interactions back into this local-space data before saving. BindingBuilder displays rotation in degrees for authoring, but exports radians. Its transform gizmo is positioned at the center of the object’s renderable geometry so an object can rotate around itself even when its source node origin is offset; that temporary authoring pivot does not modify the model file’s origin.


ObjectBindingType

A large union covering vehicles, rooms, furniture, characters, weapons, environment, and more.

type ObjectBindingType = | "body" | "light" | "wheel" | "glass" | "interior" | "floor" | "wall" | "door" | "furniture" | "decor" | "electronics" | "other"; // ... and more

ObjectBindingStyle

Controls the visual appearance of a mesh. All visual overrides live under material (an ObjectBindingMaterial); there are no style-level color / metalness / roughness fields.

type ObjectBindingStyle = { material?: ObjectBindingMaterial; };

ObjectBindingMaterial

Per-object overrides applied on top of the mesh’s original GLB/GLTF material as a MeshPhysicalMaterial. Every field is optional, only the fields you set are overridden; everything else falls back to the model-authored value. Texture slots are { path: string } objects.

type TextureSlot = { path: string }; type ObjectBindingMaterial = { // ── Base / PBR ────────────────────────────────────────────── texture?: TextureSlot; // base color (albedo) map baseColor?: string; // hex, e.g. "#ff0000" metalness?: number; // 0–1 metalnessMap?: TextureSlot; roughness?: number; // 0–1 roughnessMap?: TextureSlot; reflectivity?: number; // 0–1 (specular F0) specularIntensity?: number; // 0–1 specularIntensityMap?: TextureSlot; specularColor?: string; // hex specularColorMap?: TextureSlot; // ── Emission ──────────────────────────────────────────────── emissive?: string; // hex emissiveIntensity?: number; // 0–10 emissiveMap?: TextureSlot; // ── Opacity / blending ────────────────────────────────────── opacity?: number; // 0–1 alphaMap?: TextureSlot; alphaTest?: number; // 0–1 alphaHash?: boolean; dithering?: boolean; // banding reduction on gradients blendingMode?: "normal" | "additive"; // ── Normal / bump ─────────────────────────────────────────── normalMap?: TextureSlot; normalScale?: number; flipNormalY?: boolean; bumpMap?: TextureSlot; bumpScale?: number; // ── Displacement ──────────────────────────────────────────── displacementMap?: TextureSlot; displacementScale?: number; displacementBias?: number; // ── Ambient occlusion ─────────────────────────────────────── aoMap?: TextureSlot; aoMapIntensity?: number; // ── Clearcoat ─────────────────────────────────────────────── clearcoat?: number; // 0–1 clearcoatMap?: TextureSlot; clearcoatRoughness?: number; // 0–1 clearcoatRoughnessMap?: TextureSlot; clearcoatNormalMap?: TextureSlot; clearcoatNormalScale?: number; flipClearcoatNormalY?: boolean; // ── Sheen ─────────────────────────────────────────────────── sheen?: number; // 0–1 sheenColor?: string; // hex sheenColorMap?: TextureSlot; sheenRoughness?: number; // 0–1 sheenRoughnessMap?: TextureSlot; // ── Anisotropy ────────────────────────────────────────────── anisotropy?: number; // 0–1 anisotropyRotation?: number; // radians anisotropyMap?: TextureSlot; // ── Transmission / volume ─────────────────────────────────── transmission?: number; // 0–1 transmissionMap?: TextureSlot; thickness?: number; thicknessMap?: TextureSlot; attenuationColor?: string; // hex (volume tint) attenuationDistance?: number; // ── Faces ─────────────────────────────────────────────────── side?: "front" | "back" | "double"; };

Texture color space

Texture slots are decoded with the correct color space automatically, so maps render at the right brightness:

  • sRGB (color) maps: texture (base color/albedo), emissiveMap, sheenColorMap, specularColorMap
  • Linear (data) maps: everything else, normalMap, roughnessMap, metalnessMap, aoMap, displacementMap, bumpMap, alphaMap, clearcoat*Map, anisotropyMap, transmissionMap, thicknessMap, sheenRoughnessMap, specularIntensityMap

The shared texture cache is keyed by URL and color space, so the same image URL can be used safely as both a color map and a data map.


ObjectBindingAction

Defines an action button shown in the side panel.

type ObjectBindingAction = { id: string; label: string; type: "command"; effects?: ObjectActionEffect[]; };

effects are executed in declaration order by useViewerActions. Each effect updates one concern through the corresponding library controller:

type ObjectActionEffect = | { target: ObjectBindingTarget; objectBindings: ObjectBindingPatch; } | { sceneConfig: SceneConfigPatch } | { target: ObjectBindingTarget; visibility: "show" | "hide" | "toggle"; } | { camera: CameraAction } | { animation: AnimationAction }; type CameraAction = | { type: "focus-object"; objectId?: string } | { type: "fit-scene" } | { type: "reset" } | { type: "set-target"; target: [number, number, number]; transition?: boolean } | { type: "set-state"; state: ViewerCameraState; transition?: boolean }; type AnimationAction = | { type: "play"; clip: string } | { type: "pause" } | { type: "stop" } | { type: "set-speed"; speed: number } | { type: "seek"; time: number };

ObjectBindingTarget supports an object id, an array of ids, { group }, { tag }, or { type }.

Built-in action IDs:

IDBehavior
toggle-visibilityToggle mesh visibility
change-colorOpen color picker
change-materialOpen texture upload

ObjectBindingCameraState

Saved camera state for zooming to an object.

type ObjectBindingCameraState = { position?: [number, number, number]; target?: [number, number, number]; fov?: number; zoom?: number; };

When both position and target are set on a binding’s cameraState, the viewer uses that saved view when the object is focused or selected instead of falling back to fitToBox.


ObjectActionEvent

The event shape emitted by onAction and useViewerActions.runAction.

type ObjectActionEvent = { objectId: string; action: ObjectBindingAction; binding?: ObjectBinding; screenX?: number; screenY?: number; };

AnimationControls

Provided via onAnimationsReady.

type AnimationPlaybackState = { currentClip: string | null; isPlaying: boolean; speed: number; time: number; // live position of the current clip, in seconds duration: number; // length of the current clip, in seconds }; type AnimationControls = { clips: string[]; clipDetails?: { sourceName: string; duration: number }[]; play: (clipName: string) => void; pause: () => void; stop: () => void; setSpeed: (speed: number) => void; seek?: (time: number) => void; // scrub the current clip to an absolute time (seconds) getState?: () => AnimationPlaybackState; subscribe?: (listener: (state: AnimationPlaybackState) => void) => () => void; };

SceneLight

type SceneLightAttachment = { objectId: string; offset: [number, number, number]; }; type SceneLight = { id: string; type: "none" | "directional" | "point" | "hemisphere"; color: string; intensity: number; position: [number, number, number]; distance?: number; decay?: number; attachedToCamera: boolean; attachment?: SceneLightAttachment; castShadow: boolean; shadowBias: number; visible: boolean; };

position is world-space unless the light is attached. An attachment resolves binding keys, binding ids, modelObjectId values, and raw model node names. Its offset uses the target object’s local space.


SceneModelRenderer

Selects the whole-model material renderer used by SceneConfig.model.renderer.

type SceneModelRenderer = "pbr" | "matcap" | "uv-checker";
  • "pbr" renders the model-authored and binding-overridden physical materials.
  • "matcap" renders a lighting-independent studio material.
  • "uv-checker" renders a numbered directional UV0 test chart. Meshes without UV0 coordinates appear magenta.

CinematicConfig

Configures the cinematic auto-camera on ModelViewer.

type CinematicConfig = { waypoints?: CinematicWaypoint[]; // camera keyframes to glide through duration?: number; // seconds for one full pass (auto-scales when omitted) loop?: boolean; // default true autoPlay?: boolean; // start once the model has loaded and framed (default false) }; type CinematicWaypoint = { position: [number, number, number]; target: [number, number, number]; // world-space look-at point azimuthAngle?: number; // preserves orbit rotation at vertical poles polarAngle?: number; };

With fewer than two waypoints the camera falls back to an auto-generated orbit around the model’s bounding sphere.


SceneCinematicConfig

The persisted form of the cinematic path carried on SceneConfig.cinematic, authored visually in BindingBuilder’s Cinematic tab.

type SceneCinematicConfig = { enabled: boolean; // turns the auto-camera on at runtime waypoints: SceneCinematicWaypoint[]; duration?: number; loop: boolean; autoPlay: boolean; }; type SceneCinematicWaypoint = { position: [number, number, number]; target: [number, number, number]; azimuthAngle?: number; polarAngle?: number; };

ModelViewer activates a sceneConfig-authored path when enabled is true and there are at least two waypoints. The cinematic prop overrides it field-by-field.


CustomObjectBindingDataPanelProps

Props passed to a customObjectBindingDataPanel render prop.

type CustomObjectBindingDataPanelProps = { isOpen: boolean; selectedObject: ObjectBinding | null; currentAction: ObjectActionEvent | null; onClose: () => void; onAction: (event: ObjectActionEvent) => void; };

CustomSceneObjectsPanelProps

Props passed to a customSceneObjectsPanel render prop.

type CustomSceneObjectsPanelProps = { objectBindings: Record<string, ObjectBinding>; onAction?: (event: ObjectActionEvent) => void; onFocus?: (binding: ObjectBinding) => void; onHover?: (binding: ObjectBinding | null) => void; };