mujoco-react 10.4.0 → 10.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -136
- package/dist/{chunk-FBXXXPLQ.js → chunk-KHZ5U36J.js} +157 -16
- package/dist/chunk-KHZ5U36J.js.map +1 -0
- package/dist/index.d.ts +179 -48
- package/dist/index.js +470 -17
- package/dist/index.js.map +1 -1
- package/dist/onnx.d.ts +65 -0
- package/dist/onnx.js +58 -0
- package/dist/onnx.js.map +1 -0
- package/dist/spark.d.ts +1 -1
- package/dist/spark.js +1 -1
- package/dist/{types-CdFZCYmy.d.ts → types-CViUme8D.d.ts} +141 -1
- package/package.json +14 -3
- package/src/components/CameraView.tsx +245 -0
- package/src/core/GenericIK.ts +16 -4
- package/src/core/MujocoSimProvider.tsx +37 -1
- package/src/core/SceneLoader.ts +3 -2
- package/src/hooks/useCameraStream.ts +115 -0
- package/src/hooks/useControlGroup.ts +0 -0
- package/src/hooks/useIkController.ts +3 -0
- package/src/hooks/usePolicyCameraTensors.ts +215 -0
- package/src/index.ts +44 -0
- package/src/onnx.ts +126 -0
- package/src/policyImageTensors.ts +150 -0
- package/src/rendering/cameraFrameCapture.ts +112 -15
- package/src/types.ts +28 -0
- package/dist/chunk-FBXXXPLQ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/policyImageTensors.ts","../src/rendering/cameraFrameCapture.ts","../src/components/VisualScenario.tsx"],"names":["THREE2"],"mappings":"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","file":"chunk-KHZ5U36J.js","sourcesContent":["/**\n * @license\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type React from 'react';\nimport type { ReactNode } from 'react';\nimport type { CanvasProps, ThreeElements } from '@react-three/fiber';\nimport * as THREE from 'three';\nimport type {\n CameraFrameCaptureSession,\n CameraFrameCaptureTensorOptions,\n CameraFrameTensorResult,\n} from './rendering/cameraFrameCapture';\n\n// ---- Register (type-safe named resources) ----\n\n/**\n * Module augmentation interface for type-safe resource names.\n *\n * Declare your model's resource names via module augmentation:\n * ```ts\n * declare module 'mujoco-react' {\n * interface Register {\n * models: {\n * panda: {\n * actuators: 'joint1' | 'joint2' | 'gripper';\n * sensors: 'force_sensor' | 'torque_sensor';\n * bodies: 'link0' | 'link1' | 'hand';\n * };\n * };\n * actuators: 'joint1' | 'joint2' | 'gripper';\n * sensors: 'force_sensor' | 'torque_sensor';\n * bodies: 'link0' | 'link1' | 'hand';\n * }\n * }\n * ```\n *\n * When no augmentation is declared, all names fall back to `string`.\n */\nexport interface Register {}\n\nexport type RegisteredModelMap = Register extends { models: infer T extends Record<string, Record<string, string>> }\n ? T\n : never;\nexport type Models = [RegisteredModelMap] extends [never] ? string : Extract<keyof RegisteredModelMap, string>;\nexport type ModelResource<TModel extends string, TKey extends string> =\n [RegisteredModelMap] extends [never]\n ? string\n : TModel extends keyof RegisteredModelMap\n ? TKey extends keyof RegisteredModelMap[TModel]\n ? RegisteredModelMap[TModel][TKey]\n : string\n : never;\nexport type ModelActuators<TModel extends string> = ModelResource<TModel, 'actuators'>;\nexport type ModelSensors<TModel extends string> = ModelResource<TModel, 'sensors'>;\nexport type ModelBodies<TModel extends string> = ModelResource<TModel, 'bodies'>;\nexport type ModelJoints<TModel extends string> = ModelResource<TModel, 'joints'>;\nexport type ModelSites<TModel extends string> = ModelResource<TModel, 'sites'>;\nexport type ModelGeoms<TModel extends string> = ModelResource<TModel, 'geoms'>;\nexport type ModelKeyframes<TModel extends string> = ModelResource<TModel, 'keyframes'>;\nexport type ModelCameras<TModel extends string> = ModelResource<TModel, 'cameras'>;\n\nexport type RegisterResourceKey = 'actuators' | 'sensors' | 'bodies' | 'joints' | 'sites' | 'geoms' | 'keyframes' | 'cameras';\nexport type ModelResourceObject<TModel extends string, TKey extends RegisterResourceKey> =\n string extends ModelResource<TModel, TKey>\n ? Record<string, string>\n : { readonly [K in ModelResource<TModel, TKey>]: K };\nexport type ModelResourceCategory<TKey extends RegisterResourceKey> =\n string extends Models\n ? Record<string, Record<string, string>>\n : { readonly [TModel in Models]: ModelResourceObject<TModel, TKey> };\nexport type ModelResourceRegistry =\n string extends Models\n ? Record<string, Record<RegisterResourceKey, Record<string, string>>>\n : { readonly [TModel in Models]: { readonly [TKey in RegisterResourceKey]: ModelResourceObject<TModel, TKey> } };\n\ntype RuntimeModelResources = Record<string, Record<RegisterResourceKey, Record<string, string>>>;\ntype RuntimeModelResourceRegistration = Readonly<Record<string, Readonly<Record<RegisterResourceKey, Readonly<Record<string, string>>>>>>;\n\nconst runtimeModelResources: RuntimeModelResources = {};\nconst REGISTER_RESOURCE_KEYS: RegisterResourceKey[] = ['actuators', 'sensors', 'bodies', 'joints', 'sites', 'geoms', 'keyframes', 'cameras'];\n\nfunction createEmptyRuntimeResources(): Record<RegisterResourceKey, Record<string, string>> {\n return {\n actuators: {},\n sensors: {},\n bodies: {},\n joints: {},\n sites: {},\n geoms: {},\n keyframes: {},\n cameras: {},\n };\n}\n\nexport function registerModelResources(resources: RuntimeModelResourceRegistration): void {\n for (const [model, modelResources] of Object.entries(resources)) {\n const existing = runtimeModelResources[model] ?? createEmptyRuntimeResources();\n for (const key of REGISTER_RESOURCE_KEYS) {\n existing[key] = { ...existing[key], ...(modelResources[key] ?? {}) };\n }\n runtimeModelResources[model] = existing;\n }\n}\n\nfunction createResourceCategory<TKey extends RegisterResourceKey>(key: TKey): ModelResourceCategory<TKey> {\n return new Proxy({}, {\n get(_target, model) {\n if (typeof model !== 'string') return undefined;\n return runtimeModelResources[model]?.[key] ?? {};\n },\n ownKeys() {\n return Reflect.ownKeys(runtimeModelResources);\n },\n getOwnPropertyDescriptor(_target, model) {\n if (typeof model !== 'string' || !(model in runtimeModelResources)) return undefined;\n return { enumerable: true, configurable: true };\n },\n }) as ModelResourceCategory<TKey>;\n}\n\nexport const ModelResources: ModelResourceRegistry = new Proxy(runtimeModelResources, {\n get(target, model) {\n if (typeof model !== 'string') return undefined;\n return target[model] ?? createEmptyRuntimeResources();\n },\n ownKeys(target) {\n return Reflect.ownKeys(target);\n },\n getOwnPropertyDescriptor(target, model) {\n if (typeof model !== 'string' || !(model in target)) return undefined;\n return { enumerable: true, configurable: true };\n },\n}) as ModelResourceRegistry;\n\nexport const ModelActuators: ModelResourceCategory<'actuators'> = createResourceCategory('actuators');\nexport const ModelSensors: ModelResourceCategory<'sensors'> = createResourceCategory('sensors');\nexport const ModelBodies: ModelResourceCategory<'bodies'> = createResourceCategory('bodies');\nexport const ModelJoints: ModelResourceCategory<'joints'> = createResourceCategory('joints');\nexport const ModelSites: ModelResourceCategory<'sites'> = createResourceCategory('sites');\nexport const ModelGeoms: ModelResourceCategory<'geoms'> = createResourceCategory('geoms');\nexport const ModelKeyframes: ModelResourceCategory<'keyframes'> = createResourceCategory('keyframes');\nexport const ModelCameras: ModelResourceCategory<'cameras'> = createResourceCategory('cameras');\n\nexport type Actuators = Register extends { actuators: infer T extends string } ? T : string;\nexport type Sensors = Register extends { sensors: infer T extends string } ? T : string;\nexport type Bodies = Register extends { bodies: infer T extends string } ? T : string;\nexport type Joints = Register extends { joints: infer T extends string } ? T : string;\nexport type Sites = Register extends { sites: infer T extends string } ? T : string;\nexport type Geoms = Register extends { geoms: infer T extends string } ? T : string;\nexport type Keyframes = Register extends { keyframes: infer T extends string } ? T : string;\nexport type Cameras = Register extends { cameras: infer T extends string } ? T : string;\n\n// ---- MuJoCo WASM Types ----\n\n/**\n * A single MuJoCo contact from the WASM module.\n * Accessed via `data.contact.get(i)`.\n */\nexport interface MujocoContact {\n geom1: number;\n geom2: number;\n pos: Float64Array;\n frame: Float64Array;\n dist: number;\n}\n\n/**\n * WASM contact array — supports indexed access via `.get(i)`.\n */\nexport interface MujocoContactArray {\n get(i: number): MujocoContact | undefined;\n delete?: () => void;\n}\n\n/**\n * Read a single contact from an already-acquired WASM contact array.\n * Returns undefined if the access fails (WASM heap issue, bad index, etc.).\n */\nexport function getContact(contacts: MujocoContactArray, i: number): MujocoContact | undefined {\n try {\n return contacts.get(i);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Access the current contact vector and release the copied WASM handle afterwards.\n */\nexport function withContacts<T>(data: MujocoData, read: (contacts: MujocoContactArray) => T): T {\n const contacts = data.contact;\n try {\n return read(contacts);\n } finally {\n contacts.delete?.();\n }\n}\n\n/**\n * Minimal interface for MuJoCo Model to avoid 'any'.\n */\nexport interface MujocoModel {\n // Counts\n nbody: number;\n ngeom: number;\n nsite: number;\n nu: number;\n njnt: number;\n nq: number;\n nv: number;\n nkey: number;\n nsensor: number;\n nsensordata: number;\n nlight: number;\n ntendon: number;\n nflex: number;\n nmesh: number;\n nmat: number;\n ncam?: number;\n\n // Name tables\n names: Int8Array;\n name_bodyadr: Int32Array;\n name_jntadr: Int32Array;\n name_geomadr: Int32Array;\n name_siteadr: Int32Array;\n name_actuatoradr: Int32Array;\n name_keyadr: Int32Array;\n name_sensoradr: Int32Array;\n name_tendonadr: Int32Array;\n name_camadr?: Int32Array;\n\n // Body\n body_mass: Float64Array;\n body_parentid: Int32Array;\n body_jntnum: Int32Array;\n body_jntadr: Int32Array;\n body_pos: Float64Array;\n body_quat: Float64Array;\n body_geomnum: Int32Array;\n body_geomadr: Int32Array;\n body_inertia: Float64Array;\n\n // Default configuration\n qpos0: Float64Array;\n\n // Joint\n jnt_qposadr: Int32Array;\n jnt_dofadr: Int32Array;\n jnt_type: Int32Array;\n jnt_range: Float64Array;\n jnt_bodyid: Int32Array;\n jnt_pos: Float64Array;\n jnt_axis: Float64Array;\n jnt_limited: Uint8Array;\n\n // Geom\n geom_group: Int32Array;\n geom_type: Int32Array;\n geom_size: Float64Array;\n geom_pos: Float64Array;\n geom_quat: Float64Array;\n geom_matid: Int32Array;\n geom_rgba: Float32Array;\n geom_dataid: Int32Array;\n geom_bodyid: Int32Array;\n geom_contype: Int32Array;\n geom_conaffinity: Int32Array;\n geom_friction: Float64Array;\n\n // Material\n mat_texid: Int32Array;\n mat_texrepeat: Float32Array;\n mat_texuniform: Uint8Array;\n mat_rgba: Float32Array;\n\n // Texture\n tex_adr: Int32Array;\n tex_data: Uint8Array;\n tex_height: Int32Array;\n tex_nchannel: Int32Array;\n tex_width: Int32Array;\n\n // Mesh\n mesh_vertadr: Int32Array;\n mesh_vertnum: Int32Array;\n mesh_faceadr: Int32Array;\n mesh_facenum: Int32Array;\n mesh_vert: Float32Array;\n mesh_face: Int32Array;\n mesh_normal: Float32Array;\n\n // Site\n site_bodyid: Int32Array;\n\n // Actuator\n actuator_trnid: Int32Array;\n actuator_ctrlrange: Float64Array;\n actuator_trntype: Int32Array;\n actuator_gainprm: Float64Array;\n actuator_biasprm: Float64Array;\n\n // Sensor\n sensor_type: Int32Array;\n sensor_dim: Int32Array;\n sensor_adr: Int32Array;\n sensor_objtype: Int32Array;\n sensor_objid: Int32Array;\n\n // Keyframe\n key_qpos: Float64Array;\n key_ctrl: Float64Array;\n key_time: Float64Array;\n key_qvel: Float64Array;\n\n // Light\n light_pos: Float64Array;\n light_dir: Float64Array;\n light_diffuse: Float32Array;\n light_specular: Float32Array;\n light_type: Int32Array;\n light_active: Uint8Array;\n light_castshadow: Uint8Array;\n light_attenuation: Float32Array;\n light_cutoff: Float32Array;\n light_exponent: Float32Array;\n light_intensity: Float32Array;\n\n // Camera\n cam_bodyid?: Int32Array;\n cam_pos?: Float64Array;\n cam_quat?: Float64Array;\n cam_fovy?: Float64Array;\n cam_intrinsic?: Float64Array;\n cam_resolution?: Int32Array;\n cam_sensorsize?: Float64Array;\n\n // Tendon\n ten_wrapadr: Int32Array;\n ten_wrapnum: Int32Array;\n ten_range: Float64Array;\n ten_rgba: Float32Array;\n ten_width: Float64Array;\n\n // Flex\n flex_vertadr: Int32Array;\n flex_vertnum: Int32Array;\n flex_faceadr: Int32Array;\n flex_facenum: Int32Array;\n flex_face: Int32Array;\n flex_rgba: Float32Array;\n\n // Model options\n opt: {\n timestep: number;\n gravity: Float64Array;\n integrator: number;\n [key: string]: unknown;\n };\n\n delete: () => void;\n [key: string]: unknown;\n}\n\n/**\n * Minimal interface for MuJoCo Data to avoid 'any'.\n */\nexport interface MujocoData {\n time: number;\n qpos: Float64Array;\n qvel: Float64Array;\n ctrl: Float64Array;\n act: Float64Array;\n xpos: Float64Array;\n xquat: Float64Array;\n xfrc_applied: Float64Array;\n qfrc_applied: Float64Array;\n qfrc_bias: Float64Array;\n site_xpos: Float64Array;\n site_xmat: Float64Array;\n cam_xpos?: Float64Array;\n cam_xmat?: Float64Array;\n xmat?: Float64Array;\n sensordata: Float64Array;\n ncon: number;\n contact: MujocoContactArray;\n cvel: Float64Array;\n cfrc_ext: Float64Array;\n ten_length: Float64Array;\n wrap_xpos: Float64Array;\n ten_wrapadr: Int32Array;\n flexvert_xpos: Float64Array;\n geom_xpos: Float64Array;\n geom_xmat: Float64Array;\n delete: () => void;\n [key: string]: unknown;\n}\n\n/**\n * Minimal interface for the MuJoCo WASM Module.\n */\nexport interface MujocoModule {\n MjModel: {\n from_xml_path?: (path: string) => MujocoModel;\n from_xml_string?: (xml: string, vfs?: unknown) => MujocoModel;\n loadFromXML?: (path: string) => MujocoModel;\n [key: string]: unknown;\n };\n MjData: new (model: MujocoModel) => MujocoData;\n MjvOption: new () => { delete: () => void; [key: string]: unknown };\n mj_forward: (m: MujocoModel, d: MujocoData) => void;\n mj_step: (m: MujocoModel, d: MujocoData) => void;\n mj_resetData: (m: MujocoModel, d: MujocoData) => void;\n mj_step1: (m: MujocoModel, d: MujocoData) => void;\n mj_step2: (m: MujocoModel, d: MujocoData) => void;\n mj_applyFT: (\n model: MujocoModel,\n data: MujocoData,\n force: Float64Array,\n torque: Float64Array,\n point: Float64Array,\n bodyId: number,\n qfrc_target: Float64Array\n ) => void;\n mj_ray: (\n model: MujocoModel,\n data: MujocoData,\n pnt: Float64Array,\n vec: Float64Array,\n geomgroup: Uint8Array | null,\n flg_static: number,\n bodyexclude: number,\n geomid: Int32Array\n ) => number;\n mj_name2id: (model: MujocoModel, type: number, name: string) => number;\n mjtObj: Record<string, number>;\n mjtGeom: Record<string, number | {value: number}>;\n mjtJoint: Record<string, number | {value: number}>;\n mjtSensor: Record<string, number | {value: number}>;\n FS: {\n writeFile: (path: string, content: string | Uint8Array) => void;\n readFile: (path: string, opts?: { encoding: string }) => string | Uint8Array;\n mkdir: (path: string) => void;\n unmount: (path: string) => void;\n };\n [key: string]: unknown;\n}\n\n// ---- Scene Configuration ----\n\nexport interface SceneObject {\n name: string;\n /** MuJoCo geom name. Defaults to `${name}_geom` for generated objects. */\n geomName?: string;\n type: 'box' | 'sphere' | 'cylinder';\n size: [number, number, number];\n position: [number, number, number];\n rgba: [number, number, number, number];\n mass?: number;\n freejoint?: boolean;\n friction?: string;\n solref?: string;\n solimp?: string;\n condim?: number;\n /** MuJoCo geom contact type bitmask. Defaults to 1 for generated objects. */\n contype?: number;\n /** MuJoCo geom contact affinity bitmask. Defaults to 1 for generated objects. */\n conaffinity?: number;\n /** MuJoCo geom group. Group 3 is conventionally used for collision-only helper geoms. */\n group?: number;\n}\n\nexport interface XmlPatch {\n target: string;\n inject?: string;\n injectAfter?: string;\n replace?: [string, string];\n}\n\nexport type LocalMujocoFile = File;\n\nexport interface LoadFromFilesOptions {\n /** Entry MJCF/URDF file. Inferred from scene.xml, model.xml, robot.xml, or the first XML/URDF file when omitted. */\n sceneFile?: string;\n /** Additional MJCF environment XML files merged into the entry scene before MuJoCo compilation. */\n environmentFiles?: string[];\n homeJoints?: number[];\n xmlPatches?: XmlPatch[];\n sceneObjects?: SceneObject[];\n onReset?: (input: ResetCallbackInput) => void;\n}\n\nexport interface SceneConfig {\n /** Base URL for fetching model files. The loader fetches `src + sceneFile` and follows dependencies. */\n src: string;\n /** Entry MJCF XML or URDF file name, e.g. 'scene.xml' or 'robot.urdf'. */\n sceneFile: string;\n /** Browser-selected files for local MJCF/URDF loading. Preserves webkitRelativePath when available. */\n files?: readonly LocalMujocoFile[];\n /**\n * Additional MJCF environment XML files merged into the entry scene before compilation.\n *\n * Use this for static collision/physics layers such as a Gaussian-splat\n * environment's proxy `scene.xml`; render the splat itself as a separate\n * visual layer.\n */\n environmentFiles?: string[];\n sceneObjects?: SceneObject[];\n homeJoints?: number[];\n xmlPatches?: XmlPatch[];\n onReset?: (input: ResetCallbackInput) => void;\n}\n\n// ---- IK Controller Config ----\n\nexport type ResourceSelector<TInfo, TName extends string = string> =\n | TName\n | readonly TName[]\n | RegExp\n | ((info: TInfo) => boolean);\n\nexport interface IkConfig {\n /** MuJoCo site name for IK target. */\n siteName: Sites;\n /**\n * Explicit joints for IK. When omitted, the controller infers scalar hinge/slide\n * joints by walking from the site body to the model root.\n */\n joints?: ResourceSelector<JointInfo, Joints>;\n /** Explicit actuators for IK control output. */\n actuators?: ResourceSelector<ActuatorInfo, Actuators>;\n /**\n * Number of joints to solve for, assuming legacy contiguous qpos/ctrl layout\n * starting at index 0. Prefer inferred IK or `joints`/`actuators`.\n */\n numJoints?: number;\n /**\n * Optional solve-space joint limits in the same order as the resolved joints.\n * Use this when MJCF limits are intentionally broad or when a setup/calibration\n * tool should stay within a narrower envelope.\n */\n jointLimits?: ReadonlyArray<readonly [number, number] | null | undefined>;\n /** Custom IK solver. When omitted, uses built-in Damped Least-Squares solver. */\n ikSolveFn?: IKSolveFn;\n /** DLS damping. Default: 0.01. */\n damping?: number;\n /** Position error weight for the built-in DLS solver. Default: 1. */\n posWeight?: number;\n /** Orientation error weight for the built-in DLS solver. Default: 0.3. */\n rotWeight?: number;\n /** Solver convergence tolerance. Default: 1e-3. */\n tolerance?: number;\n /** Finite-difference step used by the built-in DLS solver. Default: 1e-6. */\n epsilon?: number;\n /** Max solver iterations. Default: 50. */\n maxIterations?: number;\n}\n\nexport interface IkContextValue {\n ikEnabledRef: React.RefObject<boolean>;\n ikCalculatingRef: React.RefObject<boolean>;\n ikTargetRef: React.RefObject<THREE.Group>;\n siteIdRef: React.RefObject<number>;\n setIkEnabled: (enabled: boolean) => void;\n moveTarget: (pos: THREE.Vector3, duration?: number) => void;\n syncTargetToSite: () => void;\n solveIK: (input: IkSolveInput) => number[] | null;\n getGizmoStats: () => { pos: THREE.Vector3; rot: THREE.Euler } | null;\n}\n\nexport interface SceneMarker {\n id: number;\n position: THREE.Vector3;\n label: string;\n}\n\n// ---- Physics Config (spec 1.1) ----\n\nexport interface PhysicsConfig {\n gravity?: [number, number, number];\n timestep?: number;\n substeps?: number;\n paused?: boolean;\n speed?: number;\n}\n\n// ---- IK ----\n\nexport type IKSolveFn = (\n input: IkSolveInput\n) => number[] | null;\n\nexport interface IkSolveInput {\n position: THREE.Vector3;\n quaternion: THREE.Quaternion;\n currentQ: number[];\n context?: IKSolveContext;\n}\n\nexport interface IKSolveContext {\n model: MujocoModel;\n data: MujocoData;\n siteId: number;\n controlGroup: ControlGroupInfo;\n}\n\n// ---- Callbacks ----\n\nexport interface PhysicsStepInput {\n model: MujocoModel;\n data: MujocoData;\n}\n\nexport interface ResetCallbackInput extends PhysicsStepInput {}\n\nexport interface ReadyCallbackInput {\n api: MujocoSimAPI;\n}\n\nexport interface StepCallbackInput {\n time: number;\n model: MujocoModel;\n data: MujocoData;\n}\n\nexport interface SelectionCallbackInput {\n bodyId: number;\n name: string;\n}\n\nexport type PhysicsStepCallback = (input: PhysicsStepInput) => void;\n\n// ---- State Management (spec 4.1) ----\n\nexport interface StateSnapshot {\n time: number;\n qpos: Float64Array;\n qvel: Float64Array;\n ctrl: Float64Array;\n act: Float64Array;\n qfrc_applied: Float64Array;\n}\n\n// ---- Model Introspection (spec 5.1) ----\n\nexport interface BodyInfo {\n id: number;\n name: string;\n mass: number;\n parentId: number;\n}\n\nexport interface JointInfo {\n id: number;\n name: string;\n type: number;\n typeName: string;\n range: [number, number];\n limited: boolean;\n bodyId: number;\n qposAdr: number;\n dofAdr: number;\n}\n\nexport interface GeomInfo {\n id: number;\n name: string;\n type: number;\n typeName: string;\n size: [number, number, number];\n bodyId: number;\n}\n\nexport interface SiteInfo {\n id: number;\n name: string;\n bodyId: number;\n}\n\nexport interface ActuatorInfo {\n id: number;\n name: string;\n range: [number, number];\n}\n\nexport interface ActuatedJointInfo extends JointInfo {\n actuatorId: number;\n actuatorName: string;\n ctrlAdr: number;\n ctrlRange: [number, number];\n}\n\nexport interface ControlJointInfo extends JointInfo {\n actuatorId: number | null;\n actuatorName: string | null;\n ctrlAdr: number | null;\n ctrlRange: [number, number] | null;\n}\n\nexport interface ControlGroupSelector {\n /** Infer a kinematic chain from a MuJoCo site. */\n siteName?: Sites;\n /** Infer a kinematic chain from a body. */\n bodyName?: Bodies;\n /** Select joints by name, names, regex, or predicate. */\n joints?: ResourceSelector<JointInfo, Joints>;\n /** Select actuators by name, names, regex, or predicate. */\n actuators?: ResourceSelector<ActuatorInfo, Actuators>;\n}\n\nexport interface ControlGroupInfo {\n /** Joints in solve/control order. */\n joints: ControlJointInfo[];\n /** Actuators in control output order. */\n actuators: ActuatorInfo[];\n /** qpos addresses for scalar hinge/slide joints. */\n qposAdr: number[];\n /** dof addresses for scalar hinge/slide joints. */\n dofAdr: number[];\n /** ctrl addresses matching writable actuators. */\n ctrlAdr: number[];\n readQpos(data: MujocoData): Float64Array;\n readCtrl(data: MujocoData): Float64Array;\n writeQpos(data: MujocoData, values: ArrayLike<number>): void;\n writeCtrl(data: MujocoData, values: ArrayLike<number>): void;\n}\n\nexport interface SensorInfo {\n id: number;\n name: string;\n type: number;\n typeName: string;\n dim: number;\n adr: number;\n}\n\nexport interface CameraInfo {\n id: number;\n name: string;\n bodyId: number;\n fov: number | null;\n resolution: [number, number] | null;\n sensorSize: [number, number] | null;\n intrinsic: [number, number, number, number] | null;\n position: [number, number, number] | null;\n quaternion: [number, number, number, number] | null;\n}\n\n// ---- Contacts (spec 2.4, 2.5) ----\n\nexport interface ContactInfo {\n geom1: number;\n geom1Name: string;\n geom2: number;\n geom2Name: string;\n pos: [number, number, number];\n depth: number;\n}\n\n// ---- Raycast (spec 7.1) ----\n\nexport interface RayHit {\n point: THREE.Vector3;\n bodyId: number;\n geomId: number;\n distance: number;\n}\n\nexport type ImagePointCoordinateSpace =\n | 'normalized'\n | 'normalized-1000'\n | 'pixel'\n | 'ndc';\n\nexport interface ImagePointProjectionOptions extends CameraFrameCaptureOptions {\n /** X coordinate in the selected coordinate space. Defaults to normalized 0..1. */\n x: number;\n /** Y coordinate in the selected coordinate space. Defaults to normalized 0..1 with origin at top-left. */\n y: number;\n /**\n * Coordinate convention for x/y:\n * - normalized: 0..1 image coordinates, top-left origin\n * - normalized-1000: 0..1000 detector coordinates, top-left origin\n * - pixel: pixel coordinates, top-left origin\n * - ndc: Three.js normalized device coordinates, -1..1\n */\n coordinateSpace?: ImagePointCoordinateSpace;\n /** Image width for pixel coordinates. Falls back to `width` or renderer canvas width. */\n imageWidth?: number;\n /** Image height for pixel coordinates. Falls back to `height` or renderer canvas height. */\n imageHeight?: number;\n /** Ignore hits farther than this distance from the camera ray origin. */\n maxDistance?: number;\n}\n\nexport interface ImagePointProjectionResult extends RayHit {\n /** NDC coordinates used for raycasting. */\n ndc: [number, number];\n /** Image dimensions used when interpreting pixel coordinates. */\n imageSize: [number, number];\n /** Camera pose provenance, matching camera-frame capture results. */\n source: CameraFrameCaptureSource;\n}\n\n// ---- Model Options (spec 5.3) ----\n\nexport interface ModelOptions {\n timestep: number;\n gravity: [number, number, number];\n integrator: number;\n}\n\n// ---- Trajectory (spec 13.1, 13.2) ----\n\nexport interface TrajectoryFrame {\n time: number;\n qpos: Float64Array;\n qvel?: Float64Array;\n ctrl?: Float64Array;\n sensordata?: Float64Array;\n}\n\nexport interface TrajectoryData {\n frames: TrajectoryFrame[];\n fps: number;\n}\n\nexport type PlaybackState = 'idle' | 'playing' | 'paused' | 'completed';\n\n// ---- Keyboard Teleop (spec 12.1) ----\n\nexport interface KeyBinding {\n actuator: Actuators;\n delta?: number;\n toggle?: [number, number];\n set?: number;\n}\n\nexport interface KeyboardTeleopConfig {\n bindings: Record<string, KeyBinding>;\n enabled?: boolean;\n}\n\n// ---- Policy (spec 10.1) ----\n\nexport type PolicyVector = Float32Array | Float64Array | number[];\n\nexport interface PolicyObservationInput {\n model: MujocoModel;\n data: MujocoData;\n}\n\nexport interface PolicyInferenceInput extends PolicyObservationInput {\n observation: PolicyVector;\n /** Number of actions still queued locally when inference is requested. */\n queuedActions?: number;\n}\n\nexport type PolicyActionChunk = readonly PolicyVector[];\nexport type PolicyInferenceOutput = PolicyVector | PolicyActionChunk;\nexport type PolicyInferenceResult = PolicyInferenceOutput | Promise<PolicyInferenceOutput>;\n\nexport interface PolicyActionInput extends PolicyInferenceInput {\n action: PolicyVector;\n}\n\nexport interface PolicyAPI {\n readonly isRunning: boolean;\n start: () => void;\n stop: () => void;\n clearQueue: () => void;\n reset: () => void;\n readonly inFlight: boolean;\n readonly queuedActions: number;\n readonly lastObservation: PolicyVector | null;\n readonly lastAction: PolicyVector | null;\n readonly lastError: unknown;\n}\n\nexport interface PolicyConfig {\n frequency: number;\n enabled?: boolean;\n /** Start async inference while this many queued actions remain. Defaults to 0. */\n prefetchThreshold?: number;\n /**\n * How async action chunks update the queue.\n * - append preserves legacy FIFO behavior.\n * - replace is useful for receding-horizon policies where a fresh chunk should supersede stale queued actions.\n */\n queueStrategy?: 'append' | 'replace';\n /**\n * Clear queued actions and ignore in-flight async results when `stop()` is called.\n * Defaults to false so callers can choose pause/resume behavior explicitly.\n */\n clearQueueOnStop?: boolean;\n onObservation: (input: PolicyObservationInput) => PolicyVector;\n /** Run policy inference. Omit to pass observations directly to `onAction` for custom inline controllers. */\n infer?: (input: PolicyInferenceInput) => PolicyInferenceResult;\n onAction: (input: PolicyActionInput) => void;\n /** Called when async inference rejects. */\n onError?: (error: unknown) => void;\n}\n\nexport interface RemotePolicyRequestInput extends PolicyInferenceInput {\n /** True for the first request after hook construction or `reset()`. */\n reset: boolean;\n /** Zero-based request index since construction or `reset()`. */\n requestIndex: number;\n /** Aborts when the request is no longer needed, e.g. after pause/reset. */\n signal: AbortSignal;\n}\n\nexport interface RemotePolicyRequestInfo extends RemotePolicyRequestInput {\n body: unknown;\n requestStartedAt: number;\n}\n\nexport interface RemotePolicyResponseInfo extends RemotePolicyRequestInfo {\n response: Response;\n responseBody: unknown;\n responseFinishedAt: number;\n requestMs: number;\n}\n\nexport type RemotePolicyStatus = 'idle' | 'requesting' | 'ready' | 'error' | 'aborted';\n\nexport interface RemotePolicyConfig extends Omit<PolicyConfig, 'infer'> {\n endpoint: string | URL;\n method?: string;\n headers?: HeadersInit;\n credentials?: RequestCredentials;\n /** Additional external cancellation signal for remote inference requests. */\n signal?: AbortSignal;\n /**\n * Abort the active HTTP request when `stop()` or `reset()` is called.\n * Defaults to true so paused policies stop consuming server work.\n */\n abortOnStop?: boolean;\n fetcher?: typeof fetch;\n requestInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'credentials' | 'signal'>;\n buildRequest?: (input: RemotePolicyRequestInput) => unknown | Promise<unknown>;\n readResponse?: (response: Response) => unknown | Promise<unknown>;\n parseResponse?: (\n responseBody: unknown,\n info: RemotePolicyResponseInfo\n ) => PolicyInferenceResult;\n onRequest?: (info: RemotePolicyRequestInfo) => void;\n onResponse?: (info: RemotePolicyResponseInfo) => void;\n}\n\nexport interface RemotePolicyAPI extends PolicyAPI {\n abort: (reason?: unknown) => void;\n readonly remoteStatus: RemotePolicyStatus;\n readonly requestCount: number;\n readonly responseCount: number;\n readonly lastRequestBody: unknown;\n readonly lastResponseBody: unknown;\n readonly lastHttpStatus: number | null;\n readonly lastRequestMs: number | null;\n}\n\nexport interface PolicyCameraFrameStream extends CameraFrameCaptureOptions {\n /** Image key used in policy payloads, e.g. `image`, `front`, or `wrist_cam`. */\n key: string;\n /** Additional payload keys that should receive the same data URL. */\n aliases?: readonly string[];\n}\n\nexport interface PolicyCameraFrameCaptureOptions {\n streams: readonly PolicyCameraFrameStream[];\n /**\n * Include `observation.images.${key}` for every captured stream.\n * Defaults to true because LeRobot-style policies usually use these names.\n */\n includeObservationImageAliases?: boolean;\n}\n\nexport interface PolicyCameraFrameCaptureResult {\n frames: Record<string, CameraFrameCaptureResult>;\n images: Record<string, string>;\n /** Human-readable source summary for UI/debug telemetry. */\n sourceSummary: string;\n capturedAt: number;\n}\n\nexport interface PolicyCameraFrameCaptureAPI {\n status: FrameCaptureStatus;\n error: Error | null;\n isCapturing: boolean;\n capture: (\n options?: Partial<PolicyCameraFrameCaptureOptions>\n ) => Promise<PolicyCameraFrameCaptureResult>;\n reset: () => void;\n}\n\n// ---- Observation Builder ----\n\nexport type ObservationOutput = 'float32' | 'float64';\n\nexport interface ObservationConfig {\n /** Include scalar simulation time. */\n time?: boolean;\n /** Include all qpos values. */\n qpos?: boolean;\n /** Include all qvel values. */\n qvel?: boolean;\n /** Include all ctrl values. */\n ctrl?: boolean;\n /** Include all actuator activation values. */\n act?: boolean;\n /** Include all raw sensordata values. */\n sensordata?: boolean;\n /** Include named sensor values in the configured order. */\n sensors?: readonly Sensors[];\n /** Include named site world positions in the configured order. */\n sites?: readonly Sites[];\n /** Include world gravity projected into each named body's local frame. */\n projectedGravity?: Bodies | readonly Bodies[];\n /** Output array type. Defaults to Float32Array. */\n output?: ObservationOutput;\n}\n\nexport interface ObservationLayoutItem {\n name: string;\n start: number;\n size: number;\n}\n\nexport interface ObservationResult {\n values: Float32Array | Float64Array;\n layout: ObservationLayoutItem[];\n}\n\nexport interface ObservationHandle {\n /** Read a fresh observation from the current live MuJoCo model/data refs. */\n read(): ObservationResult;\n /** Read just the vector values for policy inference. */\n readValues(): Float32Array | Float64Array;\n}\n\n// ---- Debug Component (spec 6.1) ----\n\nexport interface DebugVirtualCamera {\n name?: string;\n position?: CameraFrameCaptureVector3;\n lookAt?: CameraFrameCaptureVector3;\n up?: CameraFrameCaptureVector3;\n quaternion?: THREE.Quaternion | readonly [number, number, number, number];\n fov?: number;\n width?: number;\n height?: number;\n frustumDepth?: number;\n markerScale?: number;\n color?: THREE.ColorRepresentation;\n aimColor?: THREE.ColorRepresentation;\n}\n\nexport interface DebugProps {\n showGeoms?: boolean;\n showSites?: boolean;\n showJoints?: boolean;\n showCameras?: boolean;\n /** Additional explicit virtual camera poses to visualize alongside MuJoCo XML cameras. */\n virtualCameras?: readonly DebugVirtualCamera[];\n showContacts?: boolean;\n showCOM?: boolean;\n showInertia?: boolean;\n showTendons?: boolean;\n}\n\n// ---- Component Props ----\n\nexport interface IkGizmoProps {\n controller: IkContextValue;\n siteName?: string;\n scale?: number;\n onDrag?: (input: IkGizmoDragInput) => void;\n}\n\nexport interface IkGizmoDragInput {\n position: THREE.Vector3;\n quaternion: THREE.Quaternion;\n}\n\nexport type KeyboardIkTargetAction =\n | 'x+'\n | 'x-'\n | 'y+'\n | 'y-'\n | 'z+'\n | 'z-'\n | 'pitch+'\n | 'pitch-'\n | 'yaw+'\n | 'yaw-'\n | 'roll+'\n | 'roll-';\n\nexport interface KeyboardIkTargetBinding {\n /** KeyboardEvent.code, e.g. `KeyW`, `ArrowUp`, `Space`. */\n code: string;\n action: KeyboardIkTargetAction;\n /** Override translation speed in meters/second for this binding. */\n translateSpeed?: number;\n /** Override rotation speed in radians/second for this binding. */\n rotateSpeed?: number;\n}\n\nexport interface KeyboardIkTargetConfig {\n controller: IkContextValue | null;\n bindings: KeyboardIkTargetBinding[];\n enabled?: boolean;\n /** Default translation speed in meters/second. Default: 0.25. */\n translateSpeed?: number;\n /** Default rotation speed in radians/second. Default: 1.0. */\n rotateSpeed?: number;\n /** Apply translation and rotation axes in world or current target space. Default: `world`. */\n frame?: 'world' | 'target';\n /** Enable IK while keys are active. Default: true. */\n autoEnableIk?: boolean;\n /** Sync target to current site when keyboard control starts. Default: true. */\n syncOnStart?: boolean;\n /** Prevent browser default behavior for bound keys. Default: true. */\n preventDefault?: boolean;\n}\n\nexport interface DragInteractionProps {\n stiffness?: number;\n showArrow?: boolean;\n}\n\nexport interface SceneLightsProps {\n /** Override intensity for all MJCF lights. Default: 1.0. */\n intensity?: number;\n}\n\n// ---- Visual scenarios / 3DGS composition ----\n\nexport type ScenarioLightingPreset = 'studio' | 'warehouse' | 'low-light' | 'splat';\nexport type SplatFormat = 'spz' | 'ply' | 'splat';\nexport type SplatRendererKind = 'spark' | 'custom';\nexport type SplatCollisionPrimitive = 'plane' | 'box' | 'sphere' | 'capsule' | 'mesh';\n\nexport interface ScenarioCameraConfig {\n jitter?: number;\n exposure?: number;\n noise?: number;\n blur?: number;\n}\n\nexport interface ScenarioMaterialConfig {\n randomizeObjectColors?: boolean;\n randomizeTableMaterial?: boolean;\n roughness?: number;\n metalness?: number;\n}\n\nexport interface SplatAssetConfig {\n src: string;\n /** Common browser-friendly splat format. Renderer-specific loaders may accept more. */\n format?: SplatFormat;\n /** Optional renderer hint. The library does not import renderer-specific code. */\n renderer?: SplatRendererKind;\n}\n\nexport interface SplatScenarioConfig {\n enabled: boolean;\n /** Common browser-friendly splat format. Renderer-specific loaders may accept more. */\n format?: SplatFormat;\n src?: string;\n requiresCollisionProxy?: boolean;\n collisionProxy?: SplatCollisionProxyConfig | null;\n}\n\nexport interface SplatCollisionProxyConfig {\n /** MJCF/XML file or artifact path that provides physics collision for the visual splat. */\n xmlPath?: string;\n /** Human-readable status for authoring and validation flows. */\n status?: 'missing' | 'planned' | 'generated' | 'validated';\n /** Primitive proxy shapes expected in the MJCF collision proxy. */\n primitives?: SplatCollisionPrimitive[];\n /** Optional notes that should travel with scene variants and rollout metadata. */\n notes?: string[];\n}\n\nexport interface PairedSplatEnvironmentConfig {\n id: string;\n label: string;\n description?: string;\n /** Visual-only Gaussian splat asset. */\n splat: SplatAssetConfig;\n /** Optional MJCF/XML contact geometry paired with the visual splat. */\n collisionProxy?: SplatCollisionProxyConfig & { xmlPath: string };\n}\n\nexport const SplatEnvironmentReadinessStatus = {\n Disabled: 'disabled',\n MissingSplat: 'missing-splat',\n MissingCollisionProxy: 'missing-collision-proxy',\n UnsupportedFormat: 'unsupported-format',\n Ready: 'ready',\n} as const;\n\nexport type SplatEnvironmentReadinessStatus =\n (typeof SplatEnvironmentReadinessStatus)[keyof typeof SplatEnvironmentReadinessStatus];\n\nexport interface SplatEnvironmentReadiness {\n status: SplatEnvironmentReadinessStatus;\n ready: boolean;\n requiresCollisionProxy: boolean;\n missing: Array<'splat' | 'collisionProxy'>;\n format?: SplatFormat;\n renderer?: SplatRendererKind;\n message: string;\n}\n\nexport interface SplatEnvironmentMetadataInput {\n environment?: PairedSplatEnvironmentConfig;\n scenario?: VisualScenarioConfig;\n renderer?: SplatRendererKind;\n src?: string;\n format?: SplatFormat;\n collisionProxy?: SplatCollisionProxyConfig;\n}\n\nexport interface SplatEnvironmentMetadata {\n src?: string;\n format: SplatFormat;\n collisionProxy?: SplatCollisionProxyConfig;\n readiness: SplatEnvironmentReadiness;\n userData: Record<string, unknown>;\n}\n\nexport interface ResolvedScenarioCameraConfig {\n jitter: number;\n exposure: number;\n noise: number;\n blur: number;\n}\n\nexport interface ResolvedScenarioMaterialConfig {\n randomizeObjectColors: boolean;\n randomizeTableMaterial: boolean;\n roughness?: number;\n metalness?: number;\n}\n\nexport interface VisualScenarioExecutionContext {\n scenarioId: string;\n scenarioLabel: string;\n variantId?: string;\n seed: number;\n lighting: ScenarioLightingPreset;\n environment?: string;\n camera: ResolvedScenarioCameraConfig;\n materials: ResolvedScenarioMaterialConfig;\n splatEnabled: boolean;\n splatSrc?: string;\n splatFormat: SplatFormat;\n splatRenderer?: SplatRendererKind;\n collisionProxyXmlPath?: string;\n collisionProxyStatus?: SplatCollisionProxyConfig['status'];\n collisionProxyPrimitives: SplatCollisionPrimitive[];\n readiness: SplatEnvironmentReadiness;\n transformSource: 'visualScenario.camera';\n}\n\nexport interface VisualScenarioExecutionContextInput {\n scenario?: VisualScenarioConfig;\n environment?: PairedSplatEnvironmentConfig;\n renderer?: SplatRendererKind;\n variantId?: string;\n enabled?: boolean;\n}\n\nexport type SplatSceneInput =\n | PairedSplatEnvironmentConfig\n | VisualScenarioConfig\n | undefined\n | null;\n\nexport interface SplatSceneConfigInput {\n sceneConfig: SceneConfig;\n scenario?: VisualScenarioConfig;\n environment?: PairedSplatEnvironmentConfig;\n enabled?: boolean;\n renderer?: SplatRendererKind;\n}\n\nexport interface SplatSceneConfigState {\n environment: PairedSplatEnvironmentConfig | undefined;\n sceneConfig: SceneConfig;\n enabled: boolean;\n readiness: SplatEnvironmentReadiness;\n}\n\nexport interface VisualScenarioConfig {\n id?: string;\n label?: string;\n seed?: number;\n lighting?: ScenarioLightingPreset;\n environment?: string;\n camera?: ScenarioCameraConfig;\n materials?: ScenarioMaterialConfig;\n splat?: SplatScenarioConfig | null;\n}\n\nexport interface ScenarioLightingProps {\n preset?: ScenarioLightingPreset;\n intensity?: number;\n castShadow?: boolean;\n}\n\nexport interface SplatEnvironmentProps extends Omit<ThreeElements['group'], 'ref'> {\n environment?: PairedSplatEnvironmentConfig;\n scenario?: VisualScenarioConfig;\n renderer?: SplatRendererKind;\n src?: string;\n format?: SplatFormat;\n collisionProxy?: ReactNode;\n collisionProxyMetadata?: SplatCollisionProxyConfig;\n showPlaceholder?: boolean;\n}\n\nexport interface VisualScenarioEffectsProps {\n scenario?: VisualScenarioConfig;\n enabled?: boolean;\n applyBackground?: boolean;\n applyFog?: boolean;\n applyRenderer?: boolean;\n applyMaterials?: boolean;\n background?: THREE.ColorRepresentation;\n fogNear?: number;\n fogFar?: number;\n materialFilter?: (input: VisualScenarioMaterialFilterInput) => boolean;\n}\n\nexport interface VisualScenarioMaterialFilterInput {\n object: THREE.Object3D;\n material: THREE.Material;\n}\n\nexport type TrajectoryInput = TrajectoryFrame[] | number[][];\n\nexport interface TrajectoryPlayerProps {\n trajectory: TrajectoryInput;\n fps?: number;\n speed?: number;\n loop?: boolean;\n playing?: boolean;\n mode?: 'kinematic' | 'physics';\n onFrame?: (input: TrajectoryFrameCallbackInput) => void;\n onComplete?: () => void;\n onStateChange?: (input: TrajectoryStateChangeInput) => void;\n}\n\nexport interface TrajectoryFrameCallbackInput {\n frameIndex: number;\n frame: TrajectoryFrame | number[] | undefined;\n}\n\nexport interface TrajectoryStateChangeInput {\n state: PlaybackState;\n}\n\nexport interface SelectionHighlightProps {\n bodyId: number | null;\n color?: string;\n emissiveIntensity?: number;\n}\n\nexport interface ContactListenerProps {\n body: Bodies;\n onContactEnter?: (info: ContactInfo) => void;\n onContactExit?: (info: ContactInfo) => void;\n}\n\nexport interface BodyProps {\n name: Bodies;\n type: 'box' | 'sphere' | 'cylinder';\n size: [number, number, number];\n position?: [number, number, number];\n rgba?: [number, number, number, number];\n mass?: number;\n freejoint?: boolean;\n friction?: string;\n solref?: string;\n solimp?: string;\n condim?: number;\n /** MuJoCo geom group. Group 3 is conventionally used for collision-only helper geoms. */\n group?: number;\n children?: ReactNode;\n}\n\n// ---- Public API (spec: full surface) ----\n\nexport interface MujocoSimAPI {\n // State\n readonly status: 'loading' | 'ready' | 'error';\n readonly config: SceneConfig;\n\n // Simulation control (spec 1.1, 1.2, 1.3)\n reset(): void;\n setSpeed(multiplier: number): void;\n togglePause(): boolean;\n setPaused(paused: boolean): void;\n step(n?: number): void;\n getTime(): number;\n getTimestep(): number;\n applyKeyframe(nameOrIndex: Keyframes | number): void;\n\n // State management (spec 4.1, 4.2, 4.3)\n saveState(): StateSnapshot;\n restoreState(snapshot: StateSnapshot): void;\n setQpos(values: Float64Array | number[]): void;\n setQvel(values: Float64Array | number[]): void;\n getQpos(): Float64Array;\n getQvel(): Float64Array;\n\n // Actuator / control (spec 3.1)\n setCtrl(nameOrValues: Actuators | Record<Actuators, number>, value?: number): void;\n getCtrl(): Float64Array;\n getControlMap(): ControlGroupInfo;\n getActuatedJoints(): ActuatedJointInfo[];\n resolveControlGroup(selector: ControlGroupSelector): ControlGroupInfo | null;\n\n // Force application (spec 8.1)\n applyForce(bodyName: Bodies, force: THREE.Vector3, point?: THREE.Vector3): void;\n applyTorque(bodyName: Bodies, torque: THREE.Vector3): void;\n setExternalForce(bodyName: Bodies, force: THREE.Vector3, torque: THREE.Vector3): void;\n applyGeneralizedForce(values: Float64Array | number[]): void;\n\n // Sensors (spec 2.1)\n getSensorData(name: Sensors): Float64Array | null;\n\n // Contacts (spec 2.4)\n getContacts(): ContactInfo[];\n\n // Model introspection (spec 5.1, 5.2)\n getBodies(): BodyInfo[];\n getJoints(): JointInfo[];\n getGeoms(): GeomInfo[];\n getSites(): SiteInfo[];\n getActuators(): ActuatorInfo[];\n getSensors(): SensorInfo[];\n getCameras(): CameraInfo[];\n\n // Model parameters (spec 5.3)\n getModelOption(): ModelOptions;\n setGravity(g: [number, number, number]): void;\n setTimestep(dt: number): void;\n\n // Raycasting (spec 7.1)\n raycast(origin: THREE.Vector3, direction: THREE.Vector3, maxDist?: number): RayHit | null;\n\n // Keyframes (spec 4.2)\n getKeyframeNames(): string[];\n getKeyframeCount(): number;\n\n // Model loading (spec 9.1)\n loadScene(newConfig: SceneConfig): Promise<void>;\n loadFromFiles(files: FileList | readonly LocalMujocoFile[], options?: LoadFromFilesOptions): Promise<void>;\n addBody(body: SceneObject): Promise<void>;\n removeBody(name: Bodies): Promise<void>;\n recompile(patches?: XmlPatch[]): Promise<void>;\n\n // Canvas\n getCanvas(): HTMLCanvasElement | null;\n getCanvasSnapshot(width?: number, height?: number, mimeType?: string): string;\n captureFrame(options?: MujocoFrameCaptureOptions): Promise<FrameCaptureResult>;\n captureFrameBlob(options?: MujocoFrameCaptureOptions): Promise<FrameCaptureBlobResult>;\n captureCameraFrame(options?: CameraFrameCaptureOptions): Promise<CameraFrameCaptureResult>;\n captureCameraFrameBlob(options?: CameraFrameCaptureOptions): Promise<CameraFrameCaptureBlobResult>;\n /** Capture a camera frame straight into a policy image tensor (no canvas/PNG encode). */\n captureCameraFrameTensor(options?: CameraFrameCaptureTensorOptions): CameraFrameTensorResult;\n /**\n * Create a reusable offscreen capture session bound to this scene. Reuse it\n * for live inference/recording so the render target and buffers persist\n * across frames; call `session.captureTensor()` / `capturePixels()` each step.\n */\n createCameraFrameCaptureSession(options?: CameraFrameCaptureOptions): CameraFrameCaptureSession;\n /**\n * Resolve a named MuJoCo camera/site/body into concrete capture options with\n * the current world pose. Useful for re-aiming a persistent session each step.\n */\n resolveCameraCaptureOptions(options?: CameraFrameCaptureOptions): CameraFrameCaptureOptions;\n recordCameraSequence(options: CameraFrameSequenceOptions): Promise<CameraFrameSequenceResult>;\n project2DTo3D(\n x: number,\n y: number,\n cameraPos: THREE.Vector3,\n lookAt: THREE.Vector3\n ): { point: THREE.Vector3; bodyId: number; geomId: number } | null;\n projectImagePointTo3D(options: ImagePointProjectionOptions): ImagePointProjectionResult | null;\n\n // Domain randomization (spec 10.3)\n setBodyMass(name: Bodies, mass: number): void;\n setGeomFriction(name: Geoms, friction: [number, number, number]): void;\n setGeomSize(name: Geoms, size: [number, number, number]): void;\n\n // Internal refs for advanced use\n readonly mjModelRef: React.RefObject<MujocoModel | null>;\n readonly mjDataRef: React.RefObject<MujocoData | null>;\n}\n\nexport type FrameCaptureStatus = 'idle' | 'capturing' | 'captured' | 'error';\n\nexport type FrameCaptureTarget =\n | HTMLCanvasElement\n | HTMLElement\n | null\n | undefined;\n\nexport type FrameCaptureTargetRef =\n React.RefObject<HTMLCanvasElement | HTMLElement | null>;\n\nexport interface FrameCaptureOptions {\n target?: FrameCaptureTarget | FrameCaptureTargetRef;\n type?: string;\n quality?: number;\n waitForAnimationFrame?: boolean;\n}\n\nexport type MujocoFrameCaptureOptions = Omit<FrameCaptureOptions, 'target'>;\n\nexport interface FrameCaptureResult {\n canvas: HTMLCanvasElement;\n dataUrl: string;\n type: string;\n}\n\nexport interface FrameCaptureBlobResult {\n canvas: HTMLCanvasElement;\n blob: Blob;\n type: string;\n}\n\nexport interface FrameCaptureAPI {\n status: FrameCaptureStatus;\n error: Error | null;\n isCapturing: boolean;\n capture: (options?: FrameCaptureOptions) => Promise<FrameCaptureResult>;\n captureBlob: (\n options?: FrameCaptureOptions\n ) => Promise<FrameCaptureBlobResult>;\n reset: () => void;\n}\n\nexport type CameraFrameCaptureVector3 =\n | THREE.Vector3\n | readonly [number, number, number];\n\nexport type CameraFrameCaptureQuaternion =\n | THREE.Quaternion\n | readonly [number, number, number, number];\n\nexport interface CameraFrameVisualOverrides {\n /**\n * Override `scene.background` for this capture only.\n * Use `null` or `false` to render without the viewer scene background.\n */\n sceneBackground?: THREE.Scene['background'] | THREE.ColorRepresentation | null | false;\n /**\n * Override `scene.environment` for this capture only.\n * Use `null` or `false` to remove viewer environment lighting/maps.\n */\n sceneEnvironment?: THREE.Scene['environment'] | null | false;\n /**\n * Override `scene.fog` for this capture only.\n * Use `null` or `false` to remove viewer fog.\n */\n sceneFog?: THREE.Scene['fog'] | null | false;\n /** Override `renderer.shadowMap.enabled` while capturing. */\n shadows?: boolean;\n /** Override renderer tone mapping while capturing. */\n toneMapping?: THREE.WebGLRenderer['toneMapping'];\n /** Override renderer output color space while capturing. */\n outputColorSpace?: THREE.WebGLRenderer['outputColorSpace'];\n}\n\nexport interface CameraFrameRenderIsolationOptions {\n /**\n * Use an independent offscreen WebGLRenderer for this capture.\n *\n * This prevents viewer renderer settings such as antialiasing, shadow-map\n * configuration, tone mapping, and environment setup from leaking into\n * policy/training images. Leave unset for the historical shared-renderer path.\n */\n enabled?: boolean;\n /** Offscreen renderer antialiasing. Defaults to false for deterministic policy captures. */\n antialias?: boolean;\n /** Offscreen renderer alpha buffer. Defaults to false, matching Three.js WebGLRenderer. */\n alpha?: boolean;\n /** Offscreen renderer preserveDrawingBuffer flag. Defaults to false. */\n preserveDrawingBuffer?: boolean;\n /** Offscreen renderer power preference. Defaults to the browser's renderer default. */\n powerPreference?: WebGLPowerPreference;\n /** Reuse an offscreen renderer for matching capture dimensions/options. Defaults to true. */\n cache?: boolean;\n}\n\nexport interface CameraFrameCaptureOptions {\n /** Existing Three camera to clone before applying pose overrides. */\n camera?: THREE.Camera;\n /** Named MuJoCo `<camera>` to render from when available in the loaded model. */\n cameraName?: Cameras;\n /** Named MuJoCo site to use as the rendered camera pose. Useful for robot-mounted optical frames. */\n siteName?: Sites;\n /** Named MuJoCo body to use as the rendered camera pose. */\n bodyName?: Bodies;\n position?: CameraFrameCaptureVector3;\n lookAt?: CameraFrameCaptureVector3;\n quaternion?: CameraFrameCaptureQuaternion;\n up?: CameraFrameCaptureVector3;\n /** Local-space offset applied after resolving a mounted MuJoCo camera/site/body pose. */\n positionOffset?: CameraFrameCaptureVector3;\n /** Local-space rotation applied after resolving a mounted MuJoCo camera/site/body pose. Array values use Three.js order: [x, y, z, w]. */\n quaternionOffset?: CameraFrameCaptureQuaternion;\n width?: number;\n height?: number;\n type?: string;\n quality?: number;\n fov?: number;\n near?: number;\n far?: number;\n /**\n * Explicit projection matrix for offscreen capture. This is useful when a\n * MuJoCo camera has calibrated intrinsics that cannot be represented by a\n * symmetric Three.js PerspectiveCamera fov alone.\n */\n projectionMatrix?: THREE.Matrix4 | readonly number[];\n /** Provenance for the camera pose used by the capture. Usually set by the MuJoCo provider. */\n source?: CameraFrameCaptureSource;\n /**\n * When resolving a named MuJoCo camera, derive Three capture settings from\n * MuJoCo camera metadata where available: cam_resolution, cam_fovy,\n * cam_intrinsic/cam_sensorsize, and visual map near/far clipping.\n */\n mujocoCameraCompatibility?: boolean | {\n useResolution?: boolean;\n useIntrinsics?: boolean;\n useClipping?: boolean;\n /**\n * When a MuJoCo camera has `resolution` metadata and the caller supplies\n * only width or only height, derive the missing dimension from the MuJoCo\n * camera aspect ratio.\n */\n preserveAspect?: boolean;\n /**\n * Prefer the MuJoCo camera's configured resolution over width/height\n * provided by the caller. Leave false when a policy wants fixed-size\n * payloads while still preserving the camera aspect ratio.\n */\n preferResolution?: boolean;\n };\n /** Hide rendered Three objects whose MuJoCo geom group is in this list. */\n hiddenGeomGroups?: readonly number[];\n /** When provided, only rendered Three objects whose MuJoCo geom group is in this list are visible. */\n visibleGeomGroups?: readonly number[];\n /** Hide rendered Three objects whose MuJoCo geom name is in this list. */\n hiddenGeomNames?: readonly string[];\n /** Optional clear color for this capture only. Defaults to the renderer's current clear color. */\n background?: THREE.ColorRepresentation;\n /** Optional clear alpha for this capture only. Defaults to the renderer's current clear alpha. */\n backgroundAlpha?: number;\n /** Temporary scene/renderer visual overrides applied only for this offscreen capture. */\n visualOverrides?: CameraFrameVisualOverrides;\n /**\n * Render this capture with a separate offscreen WebGLRenderer.\n *\n * This is useful for policy or training captures that should remain canonical\n * while the interactive viewer uses richer visual effects.\n */\n renderIsolation?: boolean | CameraFrameRenderIsolationOptions;\n /** Mirror the captured image horizontally after rendering. Useful when matching policy datasets with mirrored camera frames. */\n flipX?: boolean;\n}\n\nexport type CameraFrameCaptureSource =\n | { kind: 'mujoco-camera'; cameraName: Cameras }\n | { kind: 'mujoco-site'; siteName: Sites }\n | { kind: 'mujoco-body'; bodyName: Bodies }\n | { kind: 'custom-camera' }\n | { kind: 'explicit-pose' }\n | { kind: 'fallback-camera' };\n\nexport interface CameraFrameCaptureResult {\n canvas: HTMLCanvasElement;\n camera: THREE.Camera;\n dataUrl: string;\n type: string;\n width: number;\n height: number;\n source: CameraFrameCaptureSource;\n}\n\nexport interface CameraFrameCaptureBlobResult {\n canvas: HTMLCanvasElement;\n camera: THREE.Camera;\n blob: Blob;\n type: string;\n width: number;\n height: number;\n source: CameraFrameCaptureSource;\n}\n\nexport interface CameraFrameCaptureAPI {\n status: FrameCaptureStatus;\n error: Error | null;\n isCapturing: boolean;\n capture: (\n options?: CameraFrameCaptureOptions\n ) => Promise<CameraFrameCaptureResult>;\n captureBlob: (\n options?: CameraFrameCaptureOptions\n ) => Promise<CameraFrameCaptureBlobResult>;\n reset: () => void;\n}\n\nexport interface CameraFrameSequenceCamera extends CameraFrameCaptureOptions {\n key: string;\n}\n\nexport interface CameraFrameSequenceFrame {\n frameIndex: number;\n time: number;\n cameras: Record<string, CameraFrameCaptureResult>;\n}\n\nexport interface CameraFrameSequenceCameraSummary {\n key: string;\n width: number;\n height: number;\n source: CameraFrameCaptureSource;\n frameCount: number;\n firstFrameIndex: number | null;\n lastFrameIndex: number | null;\n firstTimestamp: number | null;\n lastTimestamp: number | null;\n}\n\nexport interface CameraFrameSequenceSampleInput extends PhysicsStepInput {\n frameIndex: number;\n time: number;\n}\n\nexport interface CameraFrameSequenceStepInput extends PhysicsStepInput {\n frameIndex: number;\n stepIndex: number;\n time: number;\n}\n\nexport interface CameraFrameSequenceOptions {\n cameras: readonly CameraFrameSequenceCamera[];\n frames: number;\n /** Number of MuJoCo steps between captured frames. Use 0 for static camera provenance captures. */\n stepsPerFrame?: number;\n reset?: boolean;\n captureInitialFrame?: boolean;\n retainFrames?: boolean;\n /**\n * Require each recorded stream to resolve from exactly one mounted MuJoCo\n * camera/site/body selector. Defaults to true because sequence recording is\n * intended for dataset/policy camera streams.\n */\n requireMountedSources?: boolean;\n signal?: AbortSignal;\n /** Called after stepping and before image capture for this frame. Use this to record synchronized state/action rows. */\n onSample?: (input: CameraFrameSequenceSampleInput) => void | Promise<void>;\n /** Called before each MuJoCo step inside sequence recording. Use this to apply policy/control actions. */\n onBeforeStep?: (input: CameraFrameSequenceStepInput) => void | Promise<void>;\n /** Called after each MuJoCo step inside sequence recording. Use this for step-level telemetry. */\n onAfterStep?: (input: CameraFrameSequenceStepInput) => void | Promise<void>;\n onFrame?: (frame: CameraFrameSequenceFrame) => void | Promise<void>;\n}\n\nexport interface CameraFrameSequenceResult {\n frames: CameraFrameSequenceFrame[];\n cameraKeys: string[];\n cameraSummaries: Record<string, CameraFrameSequenceCameraSummary>;\n frameCount: number;\n}\n\nexport interface CameraFrameSequenceRecorderAPI {\n status: FrameCaptureStatus;\n error: Error | null;\n isRecording: boolean;\n record: (options: CameraFrameSequenceOptions) => Promise<CameraFrameSequenceResult>;\n reset: () => void;\n}\n\nexport type MujocoMeshNormalSmoothing =\n | boolean\n | {\n /** Vertex merge tolerance used before recomputing mesh normals. Defaults to `1e-4`. */\n tolerance?: number;\n };\n\nexport interface MujocoRenderOptions {\n /**\n * Smooth mesh normals by welding duplicate vertices before recomputing normals.\n * Useful for faceted STL visuals; keep off for exact policy-render parity.\n */\n meshNormalSmoothing?: MujocoMeshNormalSmoothing;\n}\n\n// ---- Canvas Props ----\n\nexport type MujocoCanvasProps = Omit<CanvasProps, 'onError'> & {\n config: SceneConfig;\n /** R3F content rendered while the MuJoCo WASM module is still loading. */\n loadingFallback?: ReactNode;\n onReady?: (input: ReadyCallbackInput) => void;\n onError?: (error: Error) => void;\n onStep?: (input: StepCallbackInput) => void;\n onSelection?: (input: SelectionCallbackInput) => void;\n // Declarative physics config (spec 1.1)\n gravity?: [number, number, number];\n timestep?: number;\n substeps?: number;\n paused?: boolean;\n speed?: number;\n interpolate?: boolean;\n renderOptions?: MujocoRenderOptions;\n};\n\n// ---- Hook Return Types ----\n\nexport interface SitePositionResult {\n position: React.RefObject<THREE.Vector3>;\n quaternion: React.RefObject<THREE.Quaternion>;\n}\n\nexport interface MujocoContextValue {\n mujoco: MujocoModule | null;\n status: 'loading' | 'ready' | 'error';\n error: string | null;\n}\n\n/** @deprecated Use `SensorHandle` instead. */\nexport interface SensorResult {\n value: React.RefObject<Float64Array>;\n size: number;\n}\n\nexport interface CtrlHandle {\n /** Read the current ctrl value. */\n read(): number;\n /** Write a ctrl value (goes directly to data.ctrl). */\n write(value: number): void;\n /** Actuator name. */\n name: Actuators;\n /** Actuator control range [min, max]. */\n range: [number, number];\n}\n\nexport interface SensorHandle {\n /** Read the current sensor data. */\n read(): Float64Array;\n /** Sensor dimensionality. */\n dim: number;\n /** Sensor name. */\n name: Sensors;\n}\n\nexport interface BodyStateResult {\n position: React.RefObject<THREE.Vector3>;\n quaternion: React.RefObject<THREE.Quaternion>;\n linearVelocity: React.RefObject<THREE.Vector3>;\n angularVelocity: React.RefObject<THREE.Vector3>;\n}\n\nexport type JointStateKind = 'auto' | 'scalar' | 'array';\n\nexport interface JointStateOptions {\n /**\n * Expected joint value shape.\n *\n * - `auto`: scalar joints return numbers, ball/free joints return Float64Array.\n * - `scalar`: return numeric refs for hinge/slide joints.\n * - `array`: return Float64Array refs for ball/free joints.\n */\n kind?: JointStateKind;\n}\n\nexport interface JointStateResult {\n position: React.RefObject<number | Float64Array>;\n velocity: React.RefObject<number | Float64Array>;\n}\n\nexport interface ScalarJointStateResult {\n position: React.RefObject<number>;\n velocity: React.RefObject<number>;\n}\n\nexport interface ArrayJointStateResult {\n position: React.RefObject<Float64Array>;\n velocity: React.RefObject<Float64Array>;\n}\n","/**\n * @license\n * SPDX-License-Identifier: Apache-2.0\n *\n * Helpers for turning browser camera captures into policy image tensors.\n */\n\nexport type PolicyImageTensorLayout = 'CHW' | 'HWC';\nexport type PolicyImageTensorRange = readonly [number, number];\n/**\n * Row order of a raw pixel buffer. WebGL `readRenderTargetPixels` returns rows\n * bottom-to-top (`'bottom-left'`); `ImageData` is top-to-bottom (`'top-left'`).\n */\nexport type PolicyImageTensorSourceOrigin = 'top-left' | 'bottom-left';\n\nexport interface PolicyImageTensorOptions {\n width: number;\n height: number;\n channels?: 3 | 4;\n layout?: PolicyImageTensorLayout;\n range?: PolicyImageTensorRange;\n}\n\nexport interface PolicyImageTensorPixelOptions extends PolicyImageTensorOptions {\n /** Row order of the source buffer. Defaults to `'top-left'`. */\n sourceOrigin?: PolicyImageTensorSourceOrigin;\n /** Mirror horizontally while reading. */\n flipX?: boolean;\n}\n\nexport interface PolicyImageTensorResult {\n data: Float32Array;\n shape: [number, number, number];\n width: number;\n height: number;\n channels: 3 | 4;\n layout: PolicyImageTensorLayout;\n range: PolicyImageTensorRange;\n}\n\nfunction resolveTensorOptions(options: PolicyImageTensorOptions): Required<PolicyImageTensorOptions> {\n return {\n channels: 3,\n layout: 'CHW',\n range: [0, 1],\n ...options,\n };\n}\n\nfunction normalizeChannel(value: number, range: PolicyImageTensorRange) {\n const [min, max] = range;\n if (min === 0 && max === 255) return value;\n return min + (value / 255) * (max - min);\n}\n\n/**\n * Convert a raw RGBA pixel buffer (4 bytes per pixel) directly into a policy\n * image tensor. This is the fast path that skips canvas encoding entirely —\n * feed it the `Uint8Array` returned by `readRenderTargetPixels` (which is\n * bottom-left origin, so pass `sourceOrigin: 'bottom-left'`).\n */\nexport function pixelsToPolicyImageTensor(\n pixels: Uint8Array | Uint8ClampedArray,\n options: PolicyImageTensorPixelOptions\n): PolicyImageTensorResult {\n const resolved = resolveTensorOptions(options);\n const { width, height, channels, layout, range } = resolved;\n const expected = width * height * 4;\n if (pixels.length < expected) {\n throw new Error(\n `Pixel buffer of length ${pixels.length} is too small for ${width}x${height} RGBA data (${expected} bytes).`\n );\n }\n\n const flipY = options.sourceOrigin === 'bottom-left';\n const flipX = options.flipX ?? false;\n const pixelCount = width * height;\n const data = new Float32Array(pixelCount * channels);\n\n for (let y = 0; y < height; y += 1) {\n const sourceY = flipY ? height - y - 1 : y;\n for (let x = 0; x < width; x += 1) {\n const sourceX = flipX ? width - x - 1 : x;\n const source = (sourceY * width + sourceX) * 4;\n const target = y * width + x;\n for (let channel = 0; channel < channels; channel += 1) {\n const value = normalizeChannel(pixels[source + channel], range);\n if (layout === 'CHW') {\n data[channel * pixelCount + target] = value;\n } else {\n data[target * channels + channel] = value;\n }\n }\n }\n }\n\n return {\n data,\n shape: layout === 'CHW' ? [channels, height, width] : [height, width, channels],\n width,\n height,\n channels,\n layout,\n range,\n };\n}\n\nexport function imageDataToPolicyImageTensor(\n imageData: ImageData,\n options: PolicyImageTensorOptions\n): PolicyImageTensorResult {\n const resolved = resolveTensorOptions(options);\n if (imageData.width !== resolved.width || imageData.height !== resolved.height) {\n throw new Error(\n `ImageData size ${imageData.width}x${imageData.height} does not match tensor size ${resolved.width}x${resolved.height}.`\n );\n }\n return pixelsToPolicyImageTensor(imageData.data, {\n ...resolved,\n sourceOrigin: 'top-left',\n });\n}\n\nasync function decodeImageSource(dataUrl: string) {\n const image = new Image();\n image.decoding = 'async';\n image.src = dataUrl;\n await image.decode();\n return image;\n}\n\nexport async function dataUrlToPolicyImageTensor(\n dataUrl: string,\n options: PolicyImageTensorOptions\n): Promise<PolicyImageTensorResult> {\n const resolved = resolveTensorOptions(options);\n const image = await decodeImageSource(dataUrl);\n const canvas = document.createElement('canvas');\n canvas.width = resolved.width;\n canvas.height = resolved.height;\n const context = canvas.getContext('2d', { willReadFrequently: true });\n if (!context) {\n throw new Error('Unable to create a 2D canvas context for policy image tensor conversion.');\n }\n context.drawImage(image, 0, 0, resolved.width, resolved.height);\n return imageDataToPolicyImageTensor(\n context.getImageData(0, 0, resolved.width, resolved.height),\n resolved\n );\n}\n","/**\n * @license\n * SPDX-License-Identifier: Apache-2.0\n *\n * Offscreen camera-frame capture for R3F/MuJoCo scenes.\n */\n\nimport * as THREE from 'three';\nimport type {\n CameraFrameCaptureBlobResult,\n CameraFrameCaptureOptions,\n CameraFrameCaptureResult,\n CameraFrameCaptureSource,\n CameraFrameCaptureVector3,\n} from '../types';\nimport {\n pixelsToPolicyImageTensor,\n type PolicyImageTensorOptions,\n type PolicyImageTensorResult,\n} from '../policyImageTensors';\n\n/** Options for capturing a camera frame straight into a policy image tensor. */\nexport type CameraFrameCaptureTensorOptions = CameraFrameCaptureOptions &\n Pick<PolicyImageTensorOptions, 'channels' | 'layout' | 'range'>;\n\nexport interface CameraFramePixelsResult {\n /** Raw RGBA pixels, bottom-left origin (reused buffer — consume before the next capture). */\n pixels: Uint8Array;\n camera: THREE.Camera;\n width: number;\n height: number;\n source: CameraFrameCaptureSource;\n}\n\nexport interface CameraFrameTensorResult extends PolicyImageTensorResult {\n camera: THREE.Camera;\n source: CameraFrameCaptureSource;\n}\n\nexport interface CameraFrameCaptureSession {\n readonly width: number;\n readonly height: number;\n capture(options?: CameraFrameCaptureOptions): {\n canvas: HTMLCanvasElement;\n camera: THREE.Camera;\n width: number;\n height: number;\n source: CameraFrameCaptureSource;\n };\n captureAsync(options?: CameraFrameCaptureOptions): Promise<{\n canvas: HTMLCanvasElement;\n camera: THREE.Camera;\n width: number;\n height: number;\n source: CameraFrameCaptureSource;\n }>;\n captureDataUrl(options?: CameraFrameCaptureOptions): CameraFrameCaptureResult;\n captureDataUrlAsync(\n options?: CameraFrameCaptureOptions\n ): Promise<CameraFrameCaptureResult>;\n captureBlob(options?: CameraFrameCaptureOptions): Promise<CameraFrameCaptureBlobResult>;\n /**\n * Render and read raw RGBA pixels without any canvas/PNG round-trip. The\n * returned buffer is reused between calls — copy or convert it before the\n * next capture.\n */\n capturePixels(options?: CameraFrameCaptureOptions): CameraFramePixelsResult;\n /** Render straight into a normalized policy image tensor (no canvas/PNG encode). */\n captureTensor(options?: CameraFrameCaptureTensorOptions): CameraFrameTensorResult;\n dispose(): void;\n}\n\nexport const CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY =\n 'mujocoReactCameraFrameCaptureRender';\nexport const CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY =\n 'mujocoReactCameraFrameCapturePreRender';\nexport const CAPTURE_EXCLUDE_KEY =\n 'mujoco.capture.exclude';\n\nexport type CameraFrameCaptureRenderInput = {\n renderer: THREE.WebGLRenderer;\n scene: THREE.Scene;\n camera: THREE.Camera;\n target: THREE.WebGLRenderTarget;\n width: number;\n height: number;\n};\n\nexport type CameraFrameCaptureRenderResult = {\n pixels: Uint8Array;\n width?: number;\n height?: number;\n flipY?: boolean;\n flipX?: boolean;\n};\n\ntype CameraFrameCaptureRender = (\n input: CameraFrameCaptureRenderInput\n) =>\n | CameraFrameCaptureRenderResult\n | null\n | undefined\n | Promise<CameraFrameCaptureRenderResult | null | undefined>;\n\ntype RendererState = {\n target: THREE.WebGLRenderTarget | null;\n xrEnabled: boolean;\n viewport: THREE.Vector4;\n scissor: THREE.Vector4;\n scissorTest: boolean;\n clearColor: THREE.Color;\n clearAlpha: number;\n autoClear: boolean;\n shadowMapEnabled: boolean;\n toneMapping: THREE.WebGLRenderer['toneMapping'];\n outputColorSpace: THREE.WebGLRenderer['outputColorSpace'];\n};\n\ntype SceneVisualState = {\n background: THREE.Scene['background'];\n environment: THREE.Scene['environment'];\n fog: THREE.Scene['fog'];\n};\n\ntype VisibilityState = {\n object: THREE.Object3D;\n visible: boolean;\n};\n\ntype CameraFrameCapturePreRender = () => void;\n\nconst isolatedRendererCache = new WeakMap<\n THREE.WebGLRenderer,\n Map<string, THREE.WebGLRenderer>\n>();\n\nfunction shouldUseRenderIsolation(\n options: CameraFrameCaptureOptions\n): boolean {\n return options.renderIsolation === true || (\n typeof options.renderIsolation === 'object' &&\n options.renderIsolation.enabled !== false\n );\n}\n\nfunction getRenderIsolationOptions(\n options: CameraFrameCaptureOptions\n) {\n return typeof options.renderIsolation === 'object'\n ? options.renderIsolation\n : {};\n}\n\nfunction getRenderIsolationCacheKey(\n width: number,\n height: number,\n options: CameraFrameCaptureOptions\n) {\n const isolation = getRenderIsolationOptions(options);\n return JSON.stringify({\n width,\n height,\n antialias: isolation.antialias ?? false,\n alpha: isolation.alpha ?? false,\n preserveDrawingBuffer: isolation.preserveDrawingBuffer ?? false,\n powerPreference: isolation.powerPreference ?? null,\n });\n}\n\nfunction createIsolatedRenderer(\n sourceRenderer: THREE.WebGLRenderer,\n width: number,\n height: number,\n options: CameraFrameCaptureOptions\n): { renderer: THREE.WebGLRenderer; cached: boolean } | null {\n if (!shouldUseRenderIsolation(options)) return null;\n\n const isolation = getRenderIsolationOptions(options);\n if (isolation.cache !== false) {\n const cacheKey = getRenderIsolationCacheKey(width, height, options);\n let rendererCache = isolatedRendererCache.get(sourceRenderer);\n if (!rendererCache) {\n rendererCache = new Map();\n isolatedRendererCache.set(sourceRenderer, rendererCache);\n }\n const cachedRenderer = rendererCache.get(cacheKey);\n if (cachedRenderer) {\n cachedRenderer.outputColorSpace = sourceRenderer.outputColorSpace;\n cachedRenderer.toneMapping = sourceRenderer.toneMapping;\n cachedRenderer.shadowMap.enabled = false;\n return { renderer: cachedRenderer, cached: true };\n }\n const createdRenderer = createUncachedIsolatedRenderer(\n sourceRenderer,\n width,\n height,\n options\n );\n rendererCache.set(cacheKey, createdRenderer);\n return { renderer: createdRenderer, cached: true };\n }\n\n return {\n renderer: createUncachedIsolatedRenderer(sourceRenderer, width, height, options),\n cached: false,\n };\n}\n\nfunction createUncachedIsolatedRenderer(\n sourceRenderer: THREE.WebGLRenderer,\n width: number,\n height: number,\n options: CameraFrameCaptureOptions\n) {\n const isolation = getRenderIsolationOptions(options);\n const canvas = document.createElement('canvas');\n const renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: isolation.antialias ?? false,\n alpha: isolation.alpha ?? false,\n preserveDrawingBuffer: isolation.preserveDrawingBuffer ?? false,\n powerPreference: isolation.powerPreference,\n });\n\n renderer.setPixelRatio(1);\n renderer.setSize(width, height, false);\n renderer.outputColorSpace = sourceRenderer.outputColorSpace;\n renderer.toneMapping = sourceRenderer.toneMapping;\n renderer.shadowMap.enabled = false;\n return renderer;\n}\n\nfunction toVector3(\n value: CameraFrameCaptureVector3 | undefined,\n fallback: THREE.Vector3\n): THREE.Vector3 {\n if (!value) return fallback.clone();\n return value instanceof THREE.Vector3\n ? value.clone()\n : new THREE.Vector3(value[0], value[1], value[2]);\n}\n\nfunction applyCameraPose(\n camera: THREE.Camera,\n options: CameraFrameCaptureOptions,\n fallbackCamera: THREE.Camera\n) {\n camera.position.copy(toVector3(options.position, fallbackCamera.position));\n camera.up.copy(toVector3(options.up, fallbackCamera.up));\n\n if (options.quaternion) {\n if (options.quaternion instanceof THREE.Quaternion) {\n camera.quaternion.copy(options.quaternion);\n } else {\n camera.quaternion.set(\n options.quaternion[0],\n options.quaternion[1],\n options.quaternion[2],\n options.quaternion[3]\n );\n }\n } else if (options.lookAt) {\n camera.lookAt(toVector3(options.lookAt, new THREE.Vector3()));\n } else {\n camera.quaternion.copy(fallbackCamera.quaternion);\n }\n\n camera.updateMatrixWorld();\n}\n\nfunction applyProjectionMatrix(\n camera: THREE.Camera,\n projectionMatrix: CameraFrameCaptureOptions['projectionMatrix'] | undefined\n) {\n if (!projectionMatrix) return;\n if (projectionMatrix instanceof THREE.Matrix4) {\n camera.projectionMatrix.copy(projectionMatrix);\n } else {\n camera.projectionMatrix.fromArray(projectionMatrix);\n }\n camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\n}\n\nexport function createCaptureCamera(\n options: CameraFrameCaptureOptions,\n fallbackCamera: THREE.Camera,\n width: number,\n height: number\n): THREE.Camera {\n const camera = options.camera\n ? options.camera.clone()\n : fallbackCamera instanceof THREE.PerspectiveCamera\n ? fallbackCamera.clone()\n : new THREE.PerspectiveCamera(45, width / height, 0.01, 100);\n\n if (camera instanceof THREE.PerspectiveCamera) {\n camera.aspect = width / height;\n camera.fov = options.fov ?? camera.fov;\n camera.near = options.near ?? camera.near;\n camera.far = options.far ?? camera.far;\n camera.updateProjectionMatrix();\n }\n applyProjectionMatrix(camera, options.projectionMatrix);\n\n applyCameraPose(camera, options, fallbackCamera);\n return camera;\n}\n\nfunction getCaptureDimensions(\n renderer: THREE.WebGLRenderer,\n options: CameraFrameCaptureOptions\n) {\n const width = Math.max(\n 1,\n Math.floor(options.width ?? renderer.domElement.width)\n );\n const height = Math.max(\n 1,\n Math.floor(options.height ?? renderer.domElement.height)\n );\n return { width, height };\n}\n\nexport function prepareCaptureCamera(\n camera: THREE.Camera,\n options: CameraFrameCaptureOptions,\n fallbackCamera: THREE.Camera,\n width: number,\n height: number\n) {\n if (options.camera) {\n camera.copy(options.camera);\n }\n\n if (camera instanceof THREE.PerspectiveCamera) {\n camera.aspect = width / height;\n camera.fov = options.fov ?? camera.fov;\n camera.near = options.near ?? camera.near;\n camera.far = options.far ?? camera.far;\n camera.updateProjectionMatrix();\n }\n applyProjectionMatrix(camera, options.projectionMatrix);\n\n applyCameraPose(camera, options, fallbackCamera);\n}\n\nfunction readRenderTargetToCanvas(\n renderer: THREE.WebGLRenderer,\n target: THREE.WebGLRenderTarget,\n canvas: HTMLCanvasElement,\n context: CanvasRenderingContext2D,\n pixels: Uint8Array,\n imageData: ImageData,\n width: number,\n height: number,\n outputColorSpace: string,\n flipX = false\n) {\n renderer.readRenderTargetPixels(target, 0, 0, width, height, pixels);\n\n const rowBytes = width * 4;\n const encodeSrgb = outputColorSpace === THREE.SRGBColorSpace;\n for (let y = 0; y < height; y += 1) {\n const sourceStart = (height - y - 1) * rowBytes;\n const targetStart = y * rowBytes;\n const row = pixels.subarray(sourceStart, sourceStart + rowBytes);\n if (!encodeSrgb && !flipX) {\n imageData.data.set(row, targetStart);\n continue;\n }\n\n for (let x = 0; x < width; x += 1) {\n const sourceX = flipX ? width - x - 1 : x;\n const sourceOffset = sourceX * 4;\n const targetOffset = targetStart + x * 4;\n imageData.data[targetOffset] = encodeSrgb\n ? linearByteToSrgbByte(row[sourceOffset])\n : row[sourceOffset];\n imageData.data[targetOffset + 1] = encodeSrgb\n ? linearByteToSrgbByte(row[sourceOffset + 1])\n : row[sourceOffset + 1];\n imageData.data[targetOffset + 2] = encodeSrgb\n ? linearByteToSrgbByte(row[sourceOffset + 2])\n : row[sourceOffset + 2];\n imageData.data[targetOffset + 3] = row[sourceOffset + 3];\n }\n }\n context.putImageData(imageData, 0, 0);\n return canvas;\n}\n\nfunction linearByteToSrgbByte(value: number) {\n const normalized = value / 255;\n const encoded =\n normalized <= 0.0031308\n ? normalized * 12.92\n : 1.055 * Math.pow(normalized, 1 / 2.4) - 0.055;\n return Math.min(255, Math.max(0, Math.round(encoded * 255)));\n}\n\nfunction readPixelsToCanvas(\n pixels: Uint8Array,\n context: CanvasRenderingContext2D,\n imageData: ImageData,\n width: number,\n height: number,\n flipY = true,\n flipX = false\n) {\n const rowBytes = width * 4;\n for (let y = 0; y < height; y += 1) {\n const sourceY = flipY ? height - y - 1 : y;\n const sourceStart = sourceY * rowBytes;\n const targetStart = y * rowBytes;\n if (!flipX) {\n imageData.data.set(\n pixels.subarray(sourceStart, sourceStart + rowBytes),\n targetStart\n );\n continue;\n }\n for (let x = 0; x < width; x += 1) {\n const sourceX = width - x - 1;\n const sourceOffset = sourceStart + sourceX * 4;\n const targetOffset = targetStart + x * 4;\n imageData.data[targetOffset] = pixels[sourceOffset];\n imageData.data[targetOffset + 1] = pixels[sourceOffset + 1];\n imageData.data[targetOffset + 2] = pixels[sourceOffset + 2];\n imageData.data[targetOffset + 3] = pixels[sourceOffset + 3];\n }\n }\n context.putImageData(imageData, 0, 0);\n}\n\nfunction hideExcludedCaptureObjects(scene: THREE.Scene): VisibilityState[] {\n const hidden: VisibilityState[] = [];\n scene.traverse((object) => {\n if (!object.visible) return;\n if (!object.userData[CAPTURE_EXCLUDE_KEY]) return;\n hidden.push({ object, visible: object.visible });\n object.visible = false;\n });\n return hidden;\n}\n\nfunction hideCaptureGeomGroups(\n scene: THREE.Scene,\n options: CameraFrameCaptureOptions\n): VisibilityState[] {\n const hidden: VisibilityState[] = [];\n const hiddenGroups = options.hiddenGeomGroups\n ? new Set(options.hiddenGeomGroups)\n : null;\n const visibleGroups = options.visibleGeomGroups\n ? new Set(options.visibleGeomGroups)\n : null;\n const hiddenNames = options.hiddenGeomNames\n ? new Set(options.hiddenGeomNames)\n : null;\n if (!hiddenGroups && !visibleGroups && !hiddenNames) return hidden;\n\n scene.traverse((object) => {\n if (!object.visible) return;\n const geomGroup = object.userData.geomGroup;\n const geomName = object.userData.geomName;\n if (typeof geomGroup !== 'number' && typeof geomName !== 'string') return;\n if (\n hiddenNames?.has(geomName) ||\n hiddenGroups?.has(geomGroup) ||\n (typeof geomGroup === 'number' && visibleGroups && !visibleGroups.has(geomGroup))\n ) {\n hidden.push({ object, visible: object.visible });\n object.visible = false;\n }\n });\n return hidden;\n}\n\nfunction restoreObjectVisibility(hidden: VisibilityState[]) {\n for (const { object, visible } of hidden) {\n object.visible = visible;\n }\n}\n\nfunction getCameraFrameCaptureSource(\n options: CameraFrameCaptureOptions\n): CameraFrameCaptureSource {\n if (options.source) return options.source;\n if (options.cameraName) {\n return { kind: 'mujoco-camera', cameraName: options.cameraName };\n }\n if (options.siteName) {\n return { kind: 'mujoco-site', siteName: options.siteName };\n }\n if (options.bodyName) {\n return { kind: 'mujoco-body', bodyName: options.bodyName };\n }\n if (options.camera) return { kind: 'custom-camera' };\n if (options.position || options.lookAt || options.quaternion) {\n return { kind: 'explicit-pose' };\n }\n return { kind: 'fallback-camera' };\n}\n\nfunction saveRendererState(renderer: THREE.WebGLRenderer): RendererState {\n const viewport = new THREE.Vector4();\n const scissor = new THREE.Vector4();\n const clearColor = new THREE.Color();\n renderer.getViewport(viewport);\n renderer.getScissor(scissor);\n renderer.getClearColor(clearColor);\n return {\n target: renderer.getRenderTarget(),\n xrEnabled: renderer.xr.enabled,\n viewport,\n scissor,\n scissorTest: renderer.getScissorTest(),\n clearColor,\n clearAlpha: renderer.getClearAlpha(),\n autoClear: renderer.autoClear,\n shadowMapEnabled: renderer.shadowMap.enabled,\n toneMapping: renderer.toneMapping,\n outputColorSpace: renderer.outputColorSpace,\n };\n}\n\nfunction restoreRendererState(\n renderer: THREE.WebGLRenderer,\n state: RendererState\n) {\n renderer.setRenderTarget(state.target);\n renderer.xr.enabled = state.xrEnabled;\n renderer.setViewport(state.viewport);\n renderer.setScissor(state.scissor);\n renderer.setScissorTest(state.scissorTest);\n renderer.setClearColor(state.clearColor, state.clearAlpha);\n renderer.autoClear = state.autoClear;\n renderer.shadowMap.enabled = state.shadowMapEnabled;\n renderer.toneMapping = state.toneMapping;\n renderer.outputColorSpace = state.outputColorSpace;\n}\n\nfunction saveSceneVisualState(scene: THREE.Scene): SceneVisualState {\n return {\n background: scene.background,\n environment: scene.environment,\n fog: scene.fog,\n };\n}\n\nfunction restoreSceneVisualState(scene: THREE.Scene, state: SceneVisualState) {\n scene.background = state.background;\n scene.environment = state.environment;\n scene.fog = state.fog;\n}\n\nfunction hasOwn<T extends object>(object: T, key: keyof T) {\n return Object.prototype.hasOwnProperty.call(object, key);\n}\n\nfunction applyCaptureVisualOverrides(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n options: CameraFrameCaptureOptions\n): SceneVisualState | null {\n const overrides = options.visualOverrides;\n if (!overrides) return null;\n\n const previousSceneState = saveSceneVisualState(scene);\n if (hasOwn(overrides, 'sceneBackground')) {\n const background = overrides.sceneBackground;\n scene.background = background === false ? null : (\n typeof background === 'string' || typeof background === 'number'\n ? new THREE.Color(background)\n : background ?? null\n );\n }\n if (hasOwn(overrides, 'sceneEnvironment')) {\n const environment = overrides.sceneEnvironment;\n scene.environment = environment === false ? null : environment ?? null;\n }\n if (hasOwn(overrides, 'sceneFog')) {\n const fog = overrides.sceneFog;\n scene.fog = fog === false ? null : fog ?? null;\n }\n if (overrides.shadows !== undefined) {\n renderer.shadowMap.enabled = overrides.shadows;\n }\n if (overrides.toneMapping !== undefined) {\n renderer.toneMapping = overrides.toneMapping;\n }\n if (overrides.outputColorSpace !== undefined) {\n renderer.outputColorSpace = overrides.outputColorSpace;\n }\n return previousSceneState;\n}\n\nfunction getCaptureRenderer(\n scene: THREE.Scene\n): CameraFrameCaptureRender | null {\n const renderers: CameraFrameCaptureRender[] = [];\n scene.traverse((object) => {\n if (renderers.length) return;\n const render = object.userData[\n CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY\n ] as CameraFrameCaptureRender | undefined;\n if (typeof render === 'function') renderers.push(render);\n });\n return renderers[0] ?? null;\n}\n\nfunction runCapturePreRenderHooks(scene: THREE.Scene) {\n const callbacks: CameraFrameCapturePreRender[] = [];\n scene.traverse((object) => {\n const callback = object.userData[\n CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY\n ] as CameraFrameCapturePreRender | undefined;\n if (typeof callback === 'function') callbacks.push(callback);\n });\n for (const callback of callbacks) callback();\n}\n\nexport function createCameraFrameCaptureSession(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n fallbackCamera: THREE.Camera,\n options: CameraFrameCaptureOptions = {}\n): CameraFrameCaptureSession {\n const { width, height } = getCaptureDimensions(renderer, options);\n const isolatedRenderer = createIsolatedRenderer(renderer, width, height, options);\n const sessionRenderer = isolatedRenderer?.renderer ?? renderer;\n const camera = createCaptureCamera(options, fallbackCamera, width, height);\n const target = new THREE.WebGLRenderTarget(width, height, {\n format: THREE.RGBAFormat,\n type: THREE.UnsignedByteType,\n });\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext('2d');\n if (!context) {\n target.dispose();\n throw new Error('Unable to create a 2D canvas for camera frame capture.');\n }\n const drawContext = context;\n\n const pixels = new Uint8Array(width * height * 4);\n const imageData = drawContext.createImageData(width, height);\n\n function resolveCaptureOptions(nextOptions: CameraFrameCaptureOptions = {}) {\n const captureOptions = { ...options, ...nextOptions };\n if (\n shouldUseRenderIsolation(captureOptions) !== shouldUseRenderIsolation(options)\n ) {\n throw new Error(\n 'Camera frame capture sessions require stable renderIsolation settings.'\n );\n }\n const nextDimensions = getCaptureDimensions(renderer, captureOptions);\n if (\n nextDimensions.width !== width ||\n nextDimensions.height !== height\n ) {\n throw new Error(\n 'Camera frame capture sessions require stable width and height.'\n );\n }\n\n prepareCaptureCamera(\n camera,\n captureOptions,\n fallbackCamera,\n width,\n height\n );\n\n return captureOptions;\n }\n\n function renderCaptureToTarget(\n captureOptions: CameraFrameCaptureOptions,\n readback: () => void\n ) {\n const previousState = saveRendererState(sessionRenderer);\n const previousSceneState = applyCaptureVisualOverrides(\n sessionRenderer,\n scene,\n captureOptions\n );\n const hidden = [\n ...hideExcludedCaptureObjects(scene),\n ...hideCaptureGeomGroups(scene, captureOptions),\n ];\n\n runCapturePreRenderHooks(scene);\n scene.updateMatrixWorld(true);\n try {\n sessionRenderer.xr.enabled = false;\n sessionRenderer.setRenderTarget(target);\n sessionRenderer.setViewport(0, 0, width, height);\n sessionRenderer.setScissor(0, 0, width, height);\n sessionRenderer.setScissorTest(false);\n if (captureOptions.background !== undefined) {\n sessionRenderer.setClearColor(\n new THREE.Color(captureOptions.background),\n captureOptions.backgroundAlpha ?? previousState.clearAlpha\n );\n } else if (captureOptions.backgroundAlpha !== undefined) {\n sessionRenderer.setClearColor(previousState.clearColor, captureOptions.backgroundAlpha);\n }\n sessionRenderer.clear();\n sessionRenderer.render(scene, camera);\n readback();\n } finally {\n restoreObjectVisibility(hidden);\n if (previousSceneState) restoreSceneVisualState(scene, previousSceneState);\n restoreRendererState(sessionRenderer, previousState);\n }\n }\n\n function renderPreparedCapture(captureOptions: CameraFrameCaptureOptions) {\n renderCaptureToTarget(captureOptions, () => {\n readRenderTargetToCanvas(\n sessionRenderer,\n target,\n canvas,\n drawContext,\n pixels,\n imageData,\n width,\n height,\n sessionRenderer.outputColorSpace,\n captureOptions.flipX ?? false\n );\n });\n return {\n canvas,\n camera,\n width,\n height,\n source: getCameraFrameCaptureSource(captureOptions),\n };\n }\n\n function capture(nextOptions: CameraFrameCaptureOptions = {}) {\n return renderPreparedCapture(resolveCaptureOptions(nextOptions));\n }\n\n function capturePixels(nextOptions: CameraFrameCaptureOptions = {}): CameraFramePixelsResult {\n const captureOptions = resolveCaptureOptions(nextOptions);\n renderCaptureToTarget(captureOptions, () => {\n sessionRenderer.readRenderTargetPixels(target, 0, 0, width, height, pixels);\n });\n return {\n pixels,\n camera,\n width,\n height,\n source: getCameraFrameCaptureSource(captureOptions),\n };\n }\n\n function captureTensor(\n nextOptions: CameraFrameCaptureTensorOptions = {}\n ): CameraFrameTensorResult {\n const result = capturePixels(nextOptions);\n const tensor = pixelsToPolicyImageTensor(pixels, {\n width,\n height,\n channels: nextOptions.channels,\n layout: nextOptions.layout,\n range: nextOptions.range,\n sourceOrigin: 'bottom-left',\n flipX: nextOptions.flipX,\n });\n return { ...tensor, camera, source: result.source };\n }\n\n async function captureAsync(nextOptions: CameraFrameCaptureOptions = {}) {\n const captureOptions = resolveCaptureOptions(nextOptions);\n runCapturePreRenderHooks(scene);\n scene.updateMatrixWorld(true);\n const captureRenderer = getCaptureRenderer(scene);\n if (captureRenderer) {\n const previousState = saveRendererState(sessionRenderer);\n const previousSceneState = applyCaptureVisualOverrides(\n sessionRenderer,\n scene,\n captureOptions\n );\n const hidden = [\n ...hideExcludedCaptureObjects(scene),\n ...hideCaptureGeomGroups(scene, captureOptions),\n ];\n try {\n sessionRenderer.xr.enabled = false;\n if (captureOptions.background !== undefined) {\n sessionRenderer.setClearColor(\n new THREE.Color(captureOptions.background),\n captureOptions.backgroundAlpha ?? previousState.clearAlpha\n );\n } else if (captureOptions.backgroundAlpha !== undefined) {\n sessionRenderer.setClearColor(previousState.clearColor, captureOptions.backgroundAlpha);\n }\n const captureResult = await captureRenderer({\n renderer: sessionRenderer,\n scene,\n camera,\n target,\n width,\n height,\n });\n if (captureResult) {\n const captureWidth = captureResult.width ?? width;\n const captureHeight = captureResult.height ?? height;\n if (captureWidth !== width || captureHeight !== height) {\n throw new Error(\n 'Camera frame capture renderer returned unexpected dimensions.'\n );\n }\n readPixelsToCanvas(\n captureResult.pixels,\n drawContext,\n imageData,\n width,\n height,\n captureResult.flipY ?? true,\n captureResult.flipX ?? captureOptions.flipX ?? false\n );\n return {\n canvas,\n camera,\n width,\n height,\n source: getCameraFrameCaptureSource(captureOptions),\n };\n }\n } finally {\n restoreObjectVisibility(hidden);\n if (previousSceneState) restoreSceneVisualState(scene, previousSceneState);\n restoreRendererState(sessionRenderer, previousState);\n }\n }\n return renderPreparedCapture(captureOptions);\n }\n\n return {\n width,\n height,\n capture,\n captureAsync,\n capturePixels,\n captureTensor,\n captureDataUrl(nextOptions = {}) {\n const type = nextOptions.type ?? options.type ?? 'image/png';\n const result = capture(nextOptions);\n return {\n ...result,\n dataUrl: result.canvas.toDataURL(\n type,\n nextOptions.quality ?? options.quality\n ),\n type,\n };\n },\n async captureDataUrlAsync(nextOptions = {}) {\n const type = nextOptions.type ?? options.type ?? 'image/png';\n const result = await captureAsync(nextOptions);\n return {\n ...result,\n dataUrl: result.canvas.toDataURL(\n type,\n nextOptions.quality ?? options.quality\n ),\n type,\n };\n },\n async captureBlob(nextOptions = {}) {\n const type = nextOptions.type ?? options.type ?? 'image/png';\n const result = await captureAsync(nextOptions);\n const blob = await new Promise<Blob>((resolve, reject) => {\n result.canvas.toBlob(\n (nextBlob) => {\n if (nextBlob) resolve(nextBlob);\n else reject(new Error('Camera frame capture did not produce a Blob.'));\n },\n type,\n nextOptions.quality ?? options.quality\n );\n });\n return { ...result, blob, type };\n },\n dispose() {\n target.dispose();\n if (isolatedRenderer && !isolatedRenderer.cached) {\n isolatedRenderer.renderer.dispose();\n }\n },\n };\n}\n\nexport function renderCameraFrameToCanvas(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n fallbackCamera: THREE.Camera,\n options: CameraFrameCaptureOptions = {}\n) {\n const session = createCameraFrameCaptureSession(\n renderer,\n scene,\n fallbackCamera,\n options\n );\n try {\n return session.capture();\n } finally {\n session.dispose();\n }\n}\n\nexport async function captureCameraFrame(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n fallbackCamera: THREE.Camera,\n options: CameraFrameCaptureOptions = {}\n): Promise<CameraFrameCaptureResult> {\n const type = options.type ?? 'image/png';\n const session = createCameraFrameCaptureSession(\n renderer,\n scene,\n fallbackCamera,\n options\n );\n try {\n const result = await session.captureAsync();\n return {\n ...result,\n dataUrl: result.canvas.toDataURL(type, options.quality),\n type,\n };\n } finally {\n session.dispose();\n }\n}\n\nexport async function captureCameraFrameBlob(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n fallbackCamera: THREE.Camera,\n options: CameraFrameCaptureOptions = {}\n): Promise<CameraFrameCaptureBlobResult> {\n const session = createCameraFrameCaptureSession(\n renderer,\n scene,\n fallbackCamera,\n options\n );\n try {\n return await session.captureBlob();\n } finally {\n session.dispose();\n }\n}\n\n/**\n * One-shot camera frame capture straight into a policy image tensor, skipping\n * the canvas/PNG round-trip. For repeated captures (live inference, recording),\n * create a session once with {@link createCameraFrameCaptureSession} and call\n * `session.captureTensor()` so the render target and buffers are reused.\n */\nexport function captureCameraFrameTensor(\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n fallbackCamera: THREE.Camera,\n options: CameraFrameCaptureTensorOptions = {}\n): CameraFrameTensorResult {\n const session = createCameraFrameCaptureSession(\n renderer,\n scene,\n fallbackCamera,\n options\n );\n try {\n return session.captureTensor(options);\n } finally {\n session.dispose();\n }\n}\n","/**\n * @license\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { useThree } from '@react-three/fiber';\nimport type { ThreeElements } from '@react-three/fiber';\nimport type { ReactNode } from 'react';\nimport { useEffect, useMemo } from 'react';\nimport * as THREE from 'three';\nimport { SplatEnvironmentReadinessStatus } from '../types';\nimport type {\n PairedSplatEnvironmentConfig,\n ScenarioMaterialConfig,\n SceneConfig,\n SplatCollisionProxyConfig,\n SplatEnvironmentReadiness,\n SplatEnvironmentMetadata,\n SplatEnvironmentMetadataInput,\n SplatFormat,\n SplatRendererKind,\n SplatSceneConfigInput,\n SplatSceneConfigState,\n SplatSceneInput,\n ScenarioLightingPreset,\n ScenarioLightingProps,\n SplatEnvironmentProps,\n VisualScenarioConfig,\n VisualScenarioExecutionContext,\n VisualScenarioExecutionContextInput,\n VisualScenarioEffectsProps,\n} from '../types';\n\nconst DEFAULT_BACKGROUND = '#181a1f';\n\nexport function ScenarioLighting({\n preset = 'studio',\n castShadow = true,\n intensity = 1,\n}: ScenarioLightingProps) {\n if (preset === 'warehouse') {\n return (\n <>\n <ambientLight intensity={0.18 * intensity} />\n <directionalLight\n position={[3.5, -2, 5]}\n intensity={2.2 * intensity}\n castShadow={castShadow}\n />\n <directionalLight position={[-2, 1.5, 2.5]} intensity={0.25 * intensity} />\n </>\n );\n }\n\n if (preset === 'low-light') {\n return (\n <>\n <ambientLight intensity={0.08 * intensity} />\n <directionalLight\n position={[2, -2, 3]}\n intensity={0.75 * intensity}\n castShadow={castShadow}\n />\n <pointLight position={[-0.5, -0.8, 1.3]} intensity={0.6 * intensity} />\n </>\n );\n }\n\n if (preset === 'splat') {\n return (\n <>\n <ambientLight intensity={0.42 * intensity} />\n <directionalLight\n position={[1.8, -2.4, 3.5]}\n intensity={1.2 * intensity}\n castShadow={castShadow}\n />\n <pointLight position={[0.4, 0.2, 1.4]} intensity={0.35 * intensity} />\n </>\n );\n }\n\n return (\n <>\n <ambientLight intensity={0.35 * intensity} />\n <directionalLight\n position={[2.5, -3, 4]}\n intensity={1.6 * intensity}\n castShadow={castShadow}\n />\n </>\n );\n}\n\nexport function getScenarioBackground(\n preset: ScenarioLightingPreset | undefined,\n fallback = DEFAULT_BACKGROUND\n) {\n if (preset === 'warehouse') return '#20242b';\n if (preset === 'low-light') return '#0f1115';\n if (preset === 'splat') return '#1b1f24';\n return fallback;\n}\n\nexport function getScenarioCameraPosition(\n basePosition: readonly [number, number, number],\n scenario?: Pick<VisualScenarioConfig, 'camera'>\n): [number, number, number] {\n const [x, y, z] = basePosition;\n const jitter = scenario?.camera?.jitter ?? 0;\n\n return [\n Number((x + jitter * 0.6).toFixed(3)),\n Number((y - jitter * 0.4).toFixed(3)),\n Number((z + jitter * 0.25).toFixed(3)),\n ];\n}\n\nexport function useVisualScenarioExecutionContext({\n scenario,\n environment,\n renderer,\n variantId,\n enabled,\n}: VisualScenarioExecutionContextInput): VisualScenarioExecutionContext {\n return useMemo(\n () =>\n createVisualScenarioExecutionContext({\n scenario,\n environment,\n renderer,\n variantId,\n enabled,\n }),\n [enabled, environment, renderer, scenario, variantId]\n );\n}\n\nexport function createVisualScenarioExecutionContext({\n scenario,\n environment,\n renderer,\n variantId,\n enabled = true,\n}: VisualScenarioExecutionContextInput): VisualScenarioExecutionContext {\n const pairedEnvironment =\n environment ??\n (scenario ? createPairedSplatEnvironment(scenario, { renderer }) : undefined);\n const splat = scenario?.splat;\n const collisionProxy =\n pairedEnvironment?.collisionProxy ?? splat?.collisionProxy ?? undefined;\n const readiness = getSplatEnvironmentReadiness({\n environment: pairedEnvironment,\n scenario,\n renderer,\n enabled,\n });\n const format =\n pairedEnvironment?.splat.format ?? splat?.format ?? readiness.format ?? 'spz';\n\n return {\n scenarioId: scenario?.id ?? pairedEnvironment?.id ?? 'visual-scenario',\n scenarioLabel:\n scenario?.label ?? pairedEnvironment?.label ?? 'Visual scenario',\n variantId,\n seed: scenario?.seed ?? 0,\n lighting: scenario?.lighting ?? 'studio',\n environment: scenario?.environment,\n camera: {\n jitter: scenario?.camera?.jitter ?? 0,\n exposure: scenario?.camera?.exposure ?? 1,\n noise: scenario?.camera?.noise ?? 0,\n blur: scenario?.camera?.blur ?? 0,\n },\n materials: {\n randomizeObjectColors: Boolean(\n scenario?.materials?.randomizeObjectColors\n ),\n randomizeTableMaterial: Boolean(\n scenario?.materials?.randomizeTableMaterial\n ),\n roughness: scenario?.materials?.roughness,\n metalness: scenario?.materials?.metalness,\n },\n splatEnabled: Boolean(splat?.enabled || pairedEnvironment),\n splatSrc: pairedEnvironment?.splat.src ?? splat?.src,\n splatFormat: format,\n splatRenderer: renderer ?? pairedEnvironment?.splat.renderer,\n collisionProxyXmlPath: collisionProxy?.xmlPath,\n collisionProxyStatus: collisionProxy?.status,\n collisionProxyPrimitives: collisionProxy?.primitives ?? [],\n readiness,\n transformSource: 'visualScenario.camera',\n };\n}\n\nexport function VisualScenarioEffects(props: VisualScenarioEffectsProps) {\n useVisualScenarioEffects(props);\n return null;\n}\n\nexport function useVisualScenarioEffects({\n scenario,\n enabled = true,\n applyBackground = true,\n applyFog = true,\n applyRenderer = true,\n applyMaterials = true,\n background,\n fogNear,\n fogFar,\n materialFilter,\n}: VisualScenarioEffectsProps) {\n const { gl, scene, invalidate } = useThree();\n\n useEffect(() => {\n if (!enabled || !scenario) {\n return undefined;\n }\n\n const previousExposure = gl.toneMappingExposure;\n const previousBackground = scene.background;\n const previousFog = scene.fog;\n const materialSnapshots = new Map<\n THREE.Material,\n {\n color?: THREE.Color;\n roughness?: number;\n metalness?: number;\n }\n >();\n\n if (applyRenderer) {\n gl.toneMappingExposure = scenario.camera?.exposure ?? 1;\n }\n\n if (applyBackground) {\n scene.background = new THREE.Color(\n background ?? getScenarioBackground(scenario.lighting)\n );\n }\n\n if (applyFog) {\n scene.fog = createScenarioFog(scenario, background, fogNear, fogFar);\n }\n\n if (applyMaterials && scenario.materials) {\n applyScenarioMaterials(scene, scenario, materialSnapshots, materialFilter);\n }\n\n invalidate();\n\n return () => {\n gl.toneMappingExposure = previousExposure;\n scene.background = previousBackground;\n scene.fog = previousFog;\n\n for (const [material, snapshot] of materialSnapshots) {\n const mutable = getMutableScenarioMaterial(material);\n if (!mutable) continue;\n if (snapshot.color) mutable.color.copy(snapshot.color);\n if (typeof snapshot.roughness === 'number') {\n mutable.roughness = snapshot.roughness;\n }\n if (typeof snapshot.metalness === 'number') {\n mutable.metalness = snapshot.metalness;\n }\n mutable.needsUpdate = true;\n }\n\n invalidate();\n };\n }, [\n applyBackground,\n applyFog,\n applyMaterials,\n applyRenderer,\n background,\n enabled,\n fogFar,\n fogNear,\n gl,\n invalidate,\n materialFilter,\n scenario,\n scene,\n ]);\n}\n\n/**\n * Renderer-agnostic Gaussian splat environment boundary.\n *\n * This component intentionally does not import a specific 3DGS renderer. Pass a\n * Spark/GaussianSplats3D object as `children` once the app chooses a renderer,\n * and pass MuJoCo/MJCF collision proxy visuals via `collisionProxy`.\n */\nexport function SplatEnvironment({\n environment,\n scenario,\n renderer,\n src,\n format,\n collisionProxy,\n collisionProxyMetadata,\n children,\n showPlaceholder = true,\n ...groupProps\n}: SplatEnvironmentProps) {\n const metadata = useSplatEnvironment({\n environment,\n scenario,\n renderer,\n src,\n format,\n collisionProxy: collisionProxyMetadata,\n });\n const existingUserData =\n typeof groupProps.userData === 'object' && groupProps.userData !== null\n ? groupProps.userData\n : {};\n\n return (\n <group\n {...groupProps}\n userData={{\n ...existingUserData,\n ...metadata.userData,\n }}\n >\n {children}\n {children || !showPlaceholder ? null : <SplatPlaceholder />}\n {collisionProxy}\n </group>\n );\n}\n\nexport function useSplatEnvironment({\n environment,\n scenario,\n renderer,\n src,\n format,\n collisionProxy,\n}: SplatEnvironmentMetadataInput): SplatEnvironmentMetadata {\n const scenarioEnvironment = useMemo(\n () =>\n environment ??\n (scenario\n ? createPairedSplatEnvironment(scenario, { renderer })\n : undefined),\n [environment, renderer, scenario]\n );\n const resolvedSrc = src ?? scenarioEnvironment?.splat.src ?? scenario?.splat?.src;\n const resolvedFormat =\n format ??\n scenarioEnvironment?.splat.format ??\n scenario?.splat?.format ??\n 'spz';\n const resolvedCollisionProxy =\n collisionProxy ??\n scenarioEnvironment?.collisionProxy ??\n scenario?.splat?.collisionProxy ??\n undefined;\n const readiness = useMemo(\n () =>\n getSplatEnvironmentReadiness({\n environment: scenarioEnvironment,\n scenario,\n renderer,\n src: resolvedSrc,\n format: resolvedFormat,\n collisionProxy: resolvedCollisionProxy,\n }),\n [\n collisionProxy,\n renderer,\n resolvedCollisionProxy,\n resolvedFormat,\n resolvedSrc,\n scenario,\n scenarioEnvironment,\n ]\n );\n\n return useMemo(\n () => ({\n src: resolvedSrc,\n format: resolvedFormat,\n collisionProxy: resolvedCollisionProxy,\n readiness,\n userData: createSplatEnvironmentUserData({\n environment: scenarioEnvironment,\n src: resolvedSrc,\n format: resolvedFormat,\n collisionProxy: resolvedCollisionProxy,\n readiness,\n }),\n }),\n [\n scenarioEnvironment,\n resolvedSrc,\n resolvedFormat,\n resolvedCollisionProxy,\n readiness,\n ]\n );\n}\n\n/**\n * Resolve a visual scenario's paired splat environment and compose its MJCF\n * collision proxy into a MuJoCo scene config.\n *\n * This hook is renderer-agnostic: apps can use it with Spark, another 3DGS\n * renderer, or their own Three scene objects while keeping physics collision\n * files paired with the visual splat metadata.\n */\nexport function useSplatSceneConfig({\n sceneConfig,\n scenario,\n environment,\n enabled = true,\n renderer,\n}: SplatSceneConfigInput): SplatSceneConfigState {\n return useMemo(\n () =>\n createSplatSceneConfig({\n sceneConfig,\n scenario,\n environment,\n enabled,\n renderer,\n }),\n [enabled, environment, renderer, scenario, sceneConfig]\n );\n}\n\n/**\n * Resolve a visual scenario's paired splat environment without requiring React.\n *\n * Use this in codegen, import validators, backend handoff metadata, or app code\n * that needs the same behavior as `useSplatSceneConfig` outside a component.\n */\nexport function createSplatSceneConfig({\n sceneConfig,\n scenario,\n environment,\n enabled = true,\n renderer,\n}: SplatSceneConfigInput): SplatSceneConfigState {\n const resolvedEnvironment = enabled\n ? environment ??\n (scenario\n ? createPairedSplatEnvironment(scenario, { renderer })\n : undefined)\n : undefined;\n const readiness = getSplatEnvironmentReadiness({\n environment: resolvedEnvironment,\n scenario,\n renderer,\n enabled,\n });\n const resolvedSceneConfig = resolvedEnvironment\n ? withSplatEnvironment(sceneConfig, resolvedEnvironment, { renderer })\n : sceneConfig;\n\n return {\n environment: resolvedEnvironment,\n sceneConfig: resolvedSceneConfig,\n enabled:\n enabled && readiness.status !== SplatEnvironmentReadinessStatus.Disabled,\n readiness,\n };\n}\n\nexport function getSplatEnvironmentReadiness({\n environment,\n scenario,\n renderer,\n src,\n format,\n collisionProxy,\n enabled = true,\n}: {\n environment?: PairedSplatEnvironmentConfig;\n scenario?: Pick<VisualScenarioConfig, 'splat'>;\n renderer?: SplatRendererKind;\n src?: string;\n format?: SplatFormat;\n collisionProxy?: SplatCollisionProxyConfig;\n enabled?: boolean;\n}): SplatEnvironmentReadiness {\n const splat = scenario?.splat;\n const resolvedSrc = src ?? environment?.splat.src ?? splat?.src;\n const resolvedFormat =\n format ?? environment?.splat.format ?? splat?.format ?? 'spz';\n const resolvedRenderer = renderer ?? environment?.splat.renderer;\n const resolvedCollisionProxy =\n collisionProxy ?? environment?.collisionProxy ?? splat?.collisionProxy ?? undefined;\n const requiresCollisionProxy = splat?.requiresCollisionProxy ?? true;\n\n if (!enabled || (splat && splat.enabled === false && !environment)) {\n return {\n status: SplatEnvironmentReadinessStatus.Disabled,\n ready: false,\n requiresCollisionProxy,\n missing: [],\n format: resolvedFormat,\n renderer: resolvedRenderer,\n message: 'Splat environment is disabled.',\n };\n }\n\n if (!resolvedSrc) {\n return {\n status: SplatEnvironmentReadinessStatus.MissingSplat,\n ready: false,\n requiresCollisionProxy,\n missing: ['splat'],\n format: resolvedFormat,\n renderer: resolvedRenderer,\n message: 'Splat environment is missing a visual asset source.',\n };\n }\n\n if (resolvedRenderer === 'spark' && resolvedFormat !== 'spz') {\n return {\n status: SplatEnvironmentReadinessStatus.UnsupportedFormat,\n ready: false,\n requiresCollisionProxy,\n missing: [],\n format: resolvedFormat,\n renderer: resolvedRenderer,\n message: `Spark splat rendering requires .spz assets; received ${resolvedFormat}.`,\n };\n }\n\n if (requiresCollisionProxy && !resolvedCollisionProxy?.xmlPath) {\n return {\n status: SplatEnvironmentReadinessStatus.MissingCollisionProxy,\n ready: false,\n requiresCollisionProxy,\n missing: ['collisionProxy'],\n format: resolvedFormat,\n renderer: resolvedRenderer,\n message: 'Splat environment is missing paired MJCF collision proxy XML.',\n };\n }\n\n return {\n status: SplatEnvironmentReadinessStatus.Ready,\n ready: true,\n requiresCollisionProxy,\n missing: [],\n format: resolvedFormat,\n renderer: resolvedRenderer,\n message: requiresCollisionProxy\n ? 'Splat environment has visual asset and collision proxy metadata.'\n : 'Splat environment has a visual asset and does not require collision proxy metadata.',\n };\n}\n\n/**\n * Convert a generic visual scenario splat block into a composable splat\n * environment config. Visual-only splats are valid; readiness reports whether\n * a paired MJCF collision proxy is required before training/physics handoff.\n */\nexport function createPairedSplatEnvironment(\n scenario: Pick<VisualScenarioConfig, 'id' | 'label' | 'environment' | 'splat'>,\n options: {\n id?: string;\n label?: string;\n description?: string;\n renderer?: SplatRendererKind;\n } = {}\n): PairedSplatEnvironmentConfig | undefined {\n const splat = scenario.splat;\n const collisionProxy = splat?.collisionProxy;\n\n if (!splat?.enabled || !splat.src) {\n return undefined;\n }\n\n return {\n id: options.id ?? scenario.id ?? 'splat-environment',\n label: options.label ?? scenario.label ?? 'Gaussian splat environment',\n description:\n options.description ??\n (scenario.environment\n ? `Visual ${scenario.environment} splat paired with MJCF collision proxy.`\n : undefined),\n splat: {\n src: splat.src,\n format: splat.format ?? 'spz',\n renderer: options.renderer,\n },\n collisionProxy: collisionProxy?.xmlPath\n ? {\n ...collisionProxy,\n xmlPath: collisionProxy.xmlPath,\n }\n : undefined,\n };\n}\n\nfunction isPairedSplatEnvironment(input: SplatSceneInput): input is PairedSplatEnvironmentConfig {\n return (\n !!input &&\n 'splat' in input &&\n !!input.splat &&\n !('enabled' in input.splat)\n );\n}\n\nfunction sceneRelativePath(sceneConfig: SceneConfig, path: string): string {\n const src = sceneConfig.src;\n if (!src) return path;\n\n const base = src.endsWith('/') ? src : src + '/';\n if (path.startsWith(base)) return path.slice(base.length);\n return path;\n}\n\nfunction uniquePaths(paths: readonly string[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const path of paths) {\n if (seen.has(path)) continue;\n seen.add(path);\n result.push(path);\n }\n return result;\n}\n\n/**\n * Compose a MuJoCo scene config with a paired splat collision proxy.\n *\n * This keeps the common hybrid setup declarative:\n * robot XML remains `sceneFile`, the `.spz` remains a visual-only layer, and\n * the paired MJCF collision proxy is added to `environmentFiles`.\n */\nexport function withSplatEnvironment(\n sceneConfig: SceneConfig,\n input: SplatSceneInput,\n options: { renderer?: SplatRendererKind } = {}\n): SceneConfig {\n const environment = isPairedSplatEnvironment(input)\n ? input\n : input\n ? createPairedSplatEnvironment(input, options)\n : undefined;\n const xmlPath = environment?.collisionProxy?.xmlPath;\n if (!xmlPath) return sceneConfig;\n\n return {\n ...sceneConfig,\n environmentFiles: uniquePaths([\n ...(sceneConfig.environmentFiles ?? []),\n sceneRelativePath(sceneConfig, xmlPath),\n ]),\n };\n}\n\nexport function createSplatEnvironmentUserData({\n environment,\n src,\n format = 'spz',\n collisionProxy,\n readiness,\n}: {\n environment?: PairedSplatEnvironmentConfig;\n src?: string;\n format?: SplatFormat;\n collisionProxy?: SplatCollisionProxyConfig;\n readiness?: SplatEnvironmentReadiness;\n}) {\n return {\n role: 'splat-environment',\n environmentId: environment?.id,\n environmentLabel: environment?.label,\n splatSrc: src,\n splatFormat: format,\n splatRenderer: environment?.splat.renderer,\n collisionProxyStatus: collisionProxy?.status ?? 'missing',\n collisionProxyXmlPath: collisionProxy?.xmlPath,\n collisionProxyPrimitives: collisionProxy?.primitives ?? [],\n readinessStatus: readiness?.status,\n readinessMessage: readiness?.message,\n };\n}\n\nexport function createSparkSplatViewerUrl({\n viewerUrl,\n splatSrc,\n}: {\n viewerUrl: string;\n splatSrc: string;\n}) {\n const url = new URL(viewerUrl, 'http://mujoco-react.local');\n url.searchParams.set('splat', splatSrc);\n return viewerUrl.startsWith('http') ? url.toString() : `${url.pathname}${url.search}`;\n}\n\nfunction SplatPlaceholder() {\n return (\n <group>\n <mesh position={[0, 0, 1.2]}>\n <boxGeometry args={[2.4, 2.4, 2.4]} />\n <meshBasicMaterial\n color=\"#8b8b8b\"\n transparent\n opacity={0.06}\n wireframe\n side={THREE.DoubleSide}\n />\n </mesh>\n </group>\n );\n}\n\nfunction createScenarioFog(\n scenario: VisualScenarioConfig,\n background: THREE.ColorRepresentation | undefined,\n fogNear: number | undefined,\n fogFar: number | undefined\n) {\n if (scenario.lighting === 'low-light') {\n return new THREE.Fog(\n background ?? getScenarioBackground(scenario.lighting),\n fogNear ?? 2.5,\n fogFar ?? 9\n );\n }\n\n if (scenario.lighting === 'warehouse') {\n return new THREE.Fog(\n background ?? getScenarioBackground(scenario.lighting),\n fogNear ?? 5,\n fogFar ?? 16\n );\n }\n\n return null;\n}\n\nfunction applyScenarioMaterials(\n scene: THREE.Scene,\n scenario: VisualScenarioConfig,\n snapshots: Map<\n THREE.Material,\n {\n color?: THREE.Color;\n roughness?: number;\n metalness?: number;\n }\n >,\n materialFilter: VisualScenarioEffectsProps['materialFilter']\n) {\n const materials = scenario.materials;\n if (!materials) return;\n\n scene.traverse((object) => {\n if (!(object instanceof THREE.Mesh)) {\n return;\n }\n\n for (const material of normalizeMaterials(object.material)) {\n const mutable = getMutableScenarioMaterial(material);\n if (!mutable) continue;\n if (materialFilter && !materialFilter({ object, material })) continue;\n\n if (!snapshots.has(material)) {\n snapshots.set(material, {\n color: mutable.color.clone(),\n roughness: mutable.roughness,\n metalness: mutable.metalness,\n });\n }\n\n applyScenarioMaterial(mutable, object, scenario, materials);\n }\n });\n}\n\nfunction applyScenarioMaterial(\n material: THREE.MeshStandardMaterial | THREE.MeshPhysicalMaterial,\n object: THREE.Object3D,\n scenario: VisualScenarioConfig,\n materials: ScenarioMaterialConfig\n) {\n const seed = scenario.seed ?? 0;\n const objectKey = `${scenario.id ?? 'scenario'}:${object.name}:${material.name}:${seed}`;\n const variation = hashToUnitInterval(objectKey);\n\n if (materials.randomizeObjectColors) {\n material.color.setHSL(variation, 0.38, 0.42);\n }\n\n if (materials.randomizeTableMaterial) {\n material.roughness = clamp01(\n materials.roughness ?? 0.35 + variation * 0.45\n );\n material.metalness = clamp01(\n materials.metalness ?? variation * 0.12\n );\n }\n\n material.needsUpdate = true;\n}\n\nfunction normalizeMaterials(\n material: THREE.Material | THREE.Material[]\n): THREE.Material[] {\n return Array.isArray(material) ? material : [material];\n}\n\nfunction getMutableScenarioMaterial(\n material: THREE.Material\n): THREE.MeshStandardMaterial | THREE.MeshPhysicalMaterial | null {\n if (\n material instanceof THREE.MeshStandardMaterial ||\n material instanceof THREE.MeshPhysicalMaterial\n ) {\n return material;\n }\n\n return null;\n}\n\nfunction hashToUnitInterval(value: string) {\n let hash = 2166136261;\n for (let index = 0; index < value.length; index += 1) {\n hash ^= value.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return (hash >>> 0) / 4294967295;\n}\n\nfunction clamp01(value: number) {\n return Math.max(0, Math.min(1, value));\n}\n\nexport type SplatCollisionProxy = ReactNode | ThreeElements['group'];\n"]}
|