mujoco-react 10.3.0 → 10.4.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/dist/spark.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _sparkjsdev_spark from '@sparkjsdev/spark';
3
- import { o as SplatEnvironmentProps, r as PairedSplatEnvironmentConfig, S as SceneConfig, u as SplatEnvironmentReadiness, p as VisualScenarioConfig } from './types-BOhNDICK.js';
3
+ import { o as SplatEnvironmentProps, r as PairedSplatEnvironmentConfig, S as SceneConfig, u as SplatEnvironmentReadiness, p as VisualScenarioConfig } from './types-CdFZCYmy.js';
4
4
  import 'react';
5
5
  import '@react-three/fiber';
6
6
  import 'three';
package/dist/spark.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useSplatSceneConfig, useSplatEnvironment, SplatEnvironment, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY } from './chunk-6AZEFI6A.js';
1
+ import { useSplatSceneConfig, useSplatEnvironment, SplatEnvironment, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY } from './chunk-FBXXXPLQ.js';
2
2
  import { useThree } from '@react-three/fiber';
3
3
  import { useMemo, useState, useEffect, useCallback, useRef } from 'react';
4
4
  import * as THREE from 'three';
@@ -801,11 +801,27 @@ interface ObservationHandle {
801
801
  /** Read just the vector values for policy inference. */
802
802
  readValues(): Float32Array | Float64Array;
803
803
  }
804
+ interface DebugVirtualCamera {
805
+ name?: string;
806
+ position?: CameraFrameCaptureVector3;
807
+ lookAt?: CameraFrameCaptureVector3;
808
+ up?: CameraFrameCaptureVector3;
809
+ quaternion?: THREE.Quaternion | readonly [number, number, number, number];
810
+ fov?: number;
811
+ width?: number;
812
+ height?: number;
813
+ frustumDepth?: number;
814
+ markerScale?: number;
815
+ color?: THREE.ColorRepresentation;
816
+ aimColor?: THREE.ColorRepresentation;
817
+ }
804
818
  interface DebugProps {
805
819
  showGeoms?: boolean;
806
820
  showSites?: boolean;
807
821
  showJoints?: boolean;
808
822
  showCameras?: boolean;
823
+ /** Additional explicit virtual camera poses to visualize alongside MuJoCo XML cameras. */
824
+ virtualCameras?: readonly DebugVirtualCamera[];
809
825
  showContacts?: boolean;
810
826
  showCOM?: boolean;
811
827
  showInertia?: boolean;
@@ -1482,4 +1498,4 @@ interface ArrayJointStateResult {
1482
1498
  velocity: React__default.RefObject<Float64Array>;
1483
1499
  }
1484
1500
 
1485
- export { type ScalarJointStateResult as $, type ActuatedJointInfo as A, type BodyProps as B, type ControlGroupInfo as C, type DragInteractionProps as D, type VisualScenarioExecutionContext as E, type ScenarioLightingPreset as F, type SplatEnvironmentMetadataInput as G, type SplatEnvironmentMetadata as H, type IkConfig as I, type SplatSceneInput as J, type DebugProps as K, type GeomInfo as L, type MujocoContextValue as M, type ContactListenerProps as N, type ObservationConfig as O, type PhysicsStepCallback as P, type ActuatorInfo as Q, type ReadyCallbackInput as R, type SceneConfig as S, type TrajectoryPlayerProps as T, type Sites as U, type VisualScenarioEffectsProps as V, type SitePositionResult as W, type Sensors as X, type SensorHandle as Y, type SensorInfo as Z, type Joints as _, type MujocoCanvasProps as a, type Keyframes as a$, type ArrayJointStateResult as a0, type JointStateOptions as a1, type JointStateResult as a2, type Bodies as a3, type BodyStateResult as a4, type Geoms as a5, type Actuators as a6, type CtrlHandle as a7, type ContactInfo as a8, type KeyboardTeleopConfig as a9, type PolicyCameraFrameCaptureAPI as aA, type CameraFrameSequenceRecorderAPI as aB, type CameraFrameCaptureResult as aC, type CameraFrameCaptureBlobResult as aD, type ImagePointCoordinateSpace as aE, type ImagePointProjectionOptions as aF, type ImagePointProjectionResult as aG, type PolicyVector as aH, type BodyInfo as aI, type CameraFrameCaptureQuaternion as aJ, type CameraFrameCaptureVector3 as aK, type CameraFrameSequenceCameraSummary as aL, type CameraFrameSequenceFrame as aM, type CameraFrameSequenceSampleInput as aN, type CameraFrameSequenceStepInput as aO, type CameraInfo as aP, type ControlJointInfo as aQ, type FrameCaptureTarget as aR, type FrameCaptureTargetRef as aS, type IKSolveFn as aT, type IkGizmoDragInput as aU, type IkSolveInput as aV, type JointInfo as aW, type JointStateKind as aX, type KeyBinding as aY, type KeyboardIkTargetAction as aZ, type KeyboardIkTargetBinding as a_, type KeyboardIkTargetConfig as aa, type PolicyConfig as ab, type PolicyAPI as ac, type RemotePolicyConfig as ad, type RemotePolicyAPI as ae, type ObservationHandle as af, type ObservationOutput as ag, type TrajectoryInput as ah, type TrajectoryStateChangeInput as ai, type PlaybackState as aj, type TrajectoryFrame as ak, type FrameCaptureOptions as al, type FrameCaptureResult as am, type FrameCaptureBlobResult as an, type FrameCaptureAPI as ao, type CameraFrameCaptureOptions as ap, type CameraFrameCaptureAPI as aq, type Cameras as ar, type CameraFrameSequenceCamera as as, type CameraFrameCaptureSource as at, type CameraFrameSequenceOptions as au, type CameraFrameSequenceResult as av, type PolicyCameraFrameStream as aw, type PolicyCameraFrameCaptureOptions as ax, type PolicyCameraFrameCaptureResult as ay, type FrameCaptureStatus as az, type MujocoSimAPI as b, ModelActuators as b0, ModelBodies as b1, ModelCameras as b2, ModelGeoms as b3, ModelJoints as b4, ModelKeyframes as b5, type ModelOptions as b6, type ModelResource as b7, ModelResources as b8, ModelSensors as b9, type ScenarioMaterialConfig as bA, type SceneMarker as bB, type SceneObject as bC, type SensorResult as bD, type SiteInfo as bE, type SplatAssetConfig as bF, type SplatScenarioConfig as bG, type StateSnapshot as bH, type TrajectoryData as bI, type TrajectoryFrameCallbackInput as bJ, type VisualScenarioMaterialFilterInput as bK, type XmlPatch as bL, getContact as bM, registerModelResources as bN, ModelSites as ba, type Models as bb, type MujocoContact as bc, type MujocoContactArray as bd, type MujocoFrameCaptureOptions as be, type ObservationLayoutItem as bf, type PhysicsConfig as bg, type PhysicsStepInput as bh, type PolicyActionChunk as bi, type PolicyActionInput as bj, type PolicyInferenceInput as bk, type PolicyInferenceOutput as bl, type PolicyInferenceResult as bm, type PolicyObservationInput as bn, type RayHit as bo, type Register as bp, type RegisteredModelMap as bq, type RemotePolicyRequestInfo as br, type RemotePolicyRequestInput as bs, type RemotePolicyResponseInfo as bt, type RemotePolicyStatus as bu, type ResetCallbackInput as bv, type ResolvedScenarioCameraConfig as bw, type ResolvedScenarioMaterialConfig as bx, type ResourceSelector as by, type ScenarioCameraConfig as bz, type StepCallbackInput as c, type SelectionCallbackInput as d, type MujocoModule as e, type MujocoRenderOptions as f, type MujocoModel as g, type MujocoData as h, type ControlGroupSelector as i, type ObservationResult as j, type IkContextValue as k, type IkGizmoProps as l, type SceneLightsProps as m, type ScenarioLightingProps as n, type SplatEnvironmentProps as o, type VisualScenarioConfig as p, type SplatRendererKind as q, type PairedSplatEnvironmentConfig as r, type SplatFormat as s, type SplatCollisionProxyConfig as t, type SplatEnvironmentReadiness as u, type SplatCollisionPrimitive as v, SplatEnvironmentReadinessStatus as w, type SplatSceneConfigInput as x, type SplatSceneConfigState as y, type VisualScenarioExecutionContextInput as z };
1501
+ export { type ScalarJointStateResult as $, type ActuatedJointInfo as A, type BodyProps as B, type ControlGroupInfo as C, type DragInteractionProps as D, type VisualScenarioExecutionContext as E, type ScenarioLightingPreset as F, type SplatEnvironmentMetadataInput as G, type SplatEnvironmentMetadata as H, type IkConfig as I, type SplatSceneInput as J, type DebugProps as K, type GeomInfo as L, type MujocoContextValue as M, type ContactListenerProps as N, type ObservationConfig as O, type PhysicsStepCallback as P, type ActuatorInfo as Q, type ReadyCallbackInput as R, type SceneConfig as S, type TrajectoryPlayerProps as T, type Sites as U, type VisualScenarioEffectsProps as V, type SitePositionResult as W, type Sensors as X, type SensorHandle as Y, type SensorInfo as Z, type Joints as _, type MujocoCanvasProps as a, type KeyboardIkTargetBinding as a$, type ArrayJointStateResult as a0, type JointStateOptions as a1, type JointStateResult as a2, type Bodies as a3, type BodyStateResult as a4, type Geoms as a5, type Actuators as a6, type CtrlHandle as a7, type ContactInfo as a8, type KeyboardTeleopConfig as a9, type PolicyCameraFrameCaptureAPI as aA, type CameraFrameSequenceRecorderAPI as aB, type CameraFrameCaptureResult as aC, type CameraFrameCaptureBlobResult as aD, type ImagePointCoordinateSpace as aE, type ImagePointProjectionOptions as aF, type ImagePointProjectionResult as aG, type PolicyVector as aH, type BodyInfo as aI, type CameraFrameCaptureQuaternion as aJ, type CameraFrameCaptureVector3 as aK, type CameraFrameSequenceCameraSummary as aL, type CameraFrameSequenceFrame as aM, type CameraFrameSequenceSampleInput as aN, type CameraFrameSequenceStepInput as aO, type CameraInfo as aP, type ControlJointInfo as aQ, type DebugVirtualCamera as aR, type FrameCaptureTarget as aS, type FrameCaptureTargetRef as aT, type IKSolveFn as aU, type IkGizmoDragInput as aV, type IkSolveInput as aW, type JointInfo as aX, type JointStateKind as aY, type KeyBinding as aZ, type KeyboardIkTargetAction as a_, type KeyboardIkTargetConfig as aa, type PolicyConfig as ab, type PolicyAPI as ac, type RemotePolicyConfig as ad, type RemotePolicyAPI as ae, type ObservationHandle as af, type ObservationOutput as ag, type TrajectoryInput as ah, type TrajectoryStateChangeInput as ai, type PlaybackState as aj, type TrajectoryFrame as ak, type FrameCaptureOptions as al, type FrameCaptureResult as am, type FrameCaptureBlobResult as an, type FrameCaptureAPI as ao, type CameraFrameCaptureOptions as ap, type CameraFrameCaptureAPI as aq, type Cameras as ar, type CameraFrameSequenceCamera as as, type CameraFrameCaptureSource as at, type CameraFrameSequenceOptions as au, type CameraFrameSequenceResult as av, type PolicyCameraFrameStream as aw, type PolicyCameraFrameCaptureOptions as ax, type PolicyCameraFrameCaptureResult as ay, type FrameCaptureStatus as az, type MujocoSimAPI as b, type Keyframes as b0, ModelActuators as b1, ModelBodies as b2, ModelCameras as b3, ModelGeoms as b4, ModelJoints as b5, ModelKeyframes as b6, type ModelOptions as b7, type ModelResource as b8, ModelResources as b9, type ScenarioCameraConfig as bA, type ScenarioMaterialConfig as bB, type SceneMarker as bC, type SceneObject as bD, type SensorResult as bE, type SiteInfo as bF, type SplatAssetConfig as bG, type SplatScenarioConfig as bH, type StateSnapshot as bI, type TrajectoryData as bJ, type TrajectoryFrameCallbackInput as bK, type VisualScenarioMaterialFilterInput as bL, type XmlPatch as bM, getContact as bN, registerModelResources as bO, ModelSensors as ba, ModelSites as bb, type Models as bc, type MujocoContact as bd, type MujocoContactArray as be, type MujocoFrameCaptureOptions as bf, type ObservationLayoutItem as bg, type PhysicsConfig as bh, type PhysicsStepInput as bi, type PolicyActionChunk as bj, type PolicyActionInput as bk, type PolicyInferenceInput as bl, type PolicyInferenceOutput as bm, type PolicyInferenceResult as bn, type PolicyObservationInput as bo, type RayHit as bp, type Register as bq, type RegisteredModelMap as br, type RemotePolicyRequestInfo as bs, type RemotePolicyRequestInput as bt, type RemotePolicyResponseInfo as bu, type RemotePolicyStatus as bv, type ResetCallbackInput as bw, type ResolvedScenarioCameraConfig as bx, type ResolvedScenarioMaterialConfig as by, type ResourceSelector as bz, type StepCallbackInput as c, type SelectionCallbackInput as d, type MujocoModule as e, type MujocoRenderOptions as f, type MujocoModel as g, type MujocoData as h, type ControlGroupSelector as i, type ObservationResult as j, type IkContextValue as k, type IkGizmoProps as l, type SceneLightsProps as m, type ScenarioLightingProps as n, type SplatEnvironmentProps as o, type VisualScenarioConfig as p, type SplatRendererKind as q, type PairedSplatEnvironmentConfig as r, type SplatFormat as s, type SplatCollisionProxyConfig as t, type SplatEnvironmentReadiness as u, type SplatCollisionPrimitive as v, SplatEnvironmentReadinessStatus as w, type SplatSceneConfigInput as x, type SplatSceneConfigState as y, type VisualScenarioExecutionContextInput as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mujoco-react",
3
- "version": "10.3.0",
3
+ "version": "10.4.0",
4
4
  "description": "Composable React Three Fiber building blocks for MuJoCo WASM simulations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,7 +13,7 @@ import { useMujocoContext } from '../core/MujocoSimProvider';
13
13
  import { getName } from '../core/SceneLoader';
14
14
  import { CAPTURE_EXCLUDE_KEY } from '../rendering/cameraFrameCapture';
15
15
  import { getContact, withContacts } from '../types';
16
- import type { DebugProps } from '../types';
16
+ import type { CameraFrameCaptureVector3, DebugProps, DebugVirtualCamera } from '../types';
17
17
 
18
18
  const JOINT_COLORS: Record<number, number> = {
19
19
  0: 0xff0000, // free - red
@@ -41,6 +41,170 @@ type CameraDebugObject = THREE.Group & {
41
41
  };
42
42
  };
43
43
 
44
+ function toVector3(
45
+ value: CameraFrameCaptureVector3 | undefined,
46
+ fallback: THREE.Vector3
47
+ ) {
48
+ if (!value) return fallback.clone();
49
+ return value instanceof THREE.Vector3
50
+ ? value.clone()
51
+ : new THREE.Vector3(value[0], value[1], value[2]);
52
+ }
53
+
54
+ function createCameraLabel(text: string, color: THREE.ColorRepresentation) {
55
+ const canvas = document.createElement('canvas');
56
+ canvas.width = 256;
57
+ canvas.height = 64;
58
+ const ctx = canvas.getContext('2d')!;
59
+ ctx.fillStyle = new THREE.Color(color).getStyle();
60
+ ctx.font = 'bold 32px monospace';
61
+ ctx.textAlign = 'center';
62
+ ctx.fillText(text, 128, 42);
63
+ const texture = new THREE.CanvasTexture(canvas);
64
+ const sprite = new THREE.Sprite(
65
+ new THREE.SpriteMaterial({
66
+ map: texture,
67
+ depthTest: false,
68
+ transparent: true,
69
+ })
70
+ );
71
+ sprite.position.set(0, 0.014, 0.01);
72
+ sprite.scale.set(0.05, 0.012, 1);
73
+ sprite.renderOrder = 999;
74
+ return sprite;
75
+ }
76
+
77
+ function createVirtualCameraDebugObject(
78
+ camera: DebugVirtualCamera,
79
+ index: number
80
+ ) {
81
+ const color = camera.color ?? '#ff3d71';
82
+ const aimColor = camera.aimColor ?? '#38bdf8';
83
+ const markerScale = camera.markerScale ?? 1;
84
+ const cameraPosition = toVector3(camera.position, new THREE.Vector3());
85
+ const configuredUp = toVector3(camera.up, new THREE.Vector3(0, 0, 1)).normalize();
86
+ const cameraQuaternion = new THREE.Quaternion();
87
+ const forward = new THREE.Vector3();
88
+
89
+ if (camera.quaternion) {
90
+ if (camera.quaternion instanceof THREE.Quaternion) {
91
+ cameraQuaternion.copy(camera.quaternion);
92
+ } else {
93
+ cameraQuaternion.set(
94
+ camera.quaternion[0],
95
+ camera.quaternion[1],
96
+ camera.quaternion[2],
97
+ camera.quaternion[3]
98
+ );
99
+ }
100
+ forward.set(0, 0, -1).applyQuaternion(cameraQuaternion).normalize();
101
+ } else {
102
+ const target = toVector3(
103
+ camera.lookAt,
104
+ cameraPosition.clone().add(new THREE.Vector3(0, 0, -1))
105
+ );
106
+ forward.copy(target).sub(cameraPosition);
107
+ if (forward.lengthSq() < 1e-8) forward.set(0, 0, -1);
108
+ forward.normalize();
109
+ cameraQuaternion.setFromRotationMatrix(
110
+ new THREE.Matrix4().lookAt(cameraPosition, target, configuredUp)
111
+ );
112
+ }
113
+
114
+ const target = camera.lookAt
115
+ ? toVector3(camera.lookAt, cameraPosition.clone().add(forward))
116
+ : cameraPosition.clone().addScaledVector(forward, 0.4);
117
+ const distanceToTarget = Math.max(target.distanceTo(cameraPosition), 0.001);
118
+ const depth = camera.frustumDepth ?? Math.min(Math.max(distanceToTarget * 0.42, 0.16), 0.45);
119
+ const fov = camera.fov ?? 50;
120
+ const aspect = (camera.width ?? 640) / (camera.height ?? 480);
121
+
122
+ const right = forward.clone().cross(configuredUp);
123
+ if (right.lengthSq() < 1e-8) right.set(1, 0, 0);
124
+ right.normalize();
125
+ const orthogonalUp = right.clone().cross(forward).normalize();
126
+ const frustumHeight = 2 * Math.tan(THREE.MathUtils.degToRad(fov) / 2) * depth;
127
+ const frustumWidth = frustumHeight * aspect;
128
+ const center = cameraPosition.clone().addScaledVector(forward, depth);
129
+ const halfRight = right.clone().multiplyScalar(frustumWidth / 2);
130
+ const halfUp = orthogonalUp.clone().multiplyScalar(frustumHeight / 2);
131
+
132
+ const topLeft = center.clone().sub(halfRight).add(halfUp);
133
+ const topRight = center.clone().add(halfRight).add(halfUp);
134
+ const bottomRight = center.clone().add(halfRight).sub(halfUp);
135
+ const bottomLeft = center.clone().sub(halfRight).sub(halfUp);
136
+ const frustumPoints = [
137
+ cameraPosition, topLeft,
138
+ cameraPosition, topRight,
139
+ cameraPosition, bottomRight,
140
+ cameraPosition, bottomLeft,
141
+ topLeft, topRight,
142
+ topRight, bottomRight,
143
+ bottomRight, bottomLeft,
144
+ bottomLeft, topLeft,
145
+ ];
146
+
147
+ const group = new THREE.Group();
148
+ group.name = camera.name ?? `virtual-camera-${index}`;
149
+ group.renderOrder = 999;
150
+ group.frustumCulled = false;
151
+
152
+ const frustum = new THREE.LineSegments(
153
+ new THREE.BufferGeometry().setFromPoints(frustumPoints),
154
+ new THREE.LineBasicMaterial({
155
+ color,
156
+ transparent: true,
157
+ opacity: 0.9,
158
+ depthTest: false,
159
+ })
160
+ );
161
+ frustum.renderOrder = 999;
162
+ frustum.frustumCulled = false;
163
+ group.add(frustum);
164
+
165
+ const aim = new THREE.LineSegments(
166
+ new THREE.BufferGeometry().setFromPoints([cameraPosition, target]),
167
+ new THREE.LineBasicMaterial({
168
+ color: aimColor,
169
+ transparent: true,
170
+ opacity: 0.95,
171
+ depthTest: false,
172
+ })
173
+ );
174
+ aim.renderOrder = 999;
175
+ aim.frustumCulled = false;
176
+ group.add(aim);
177
+
178
+ const markerGroup = new THREE.Group();
179
+ markerGroup.position.copy(cameraPosition);
180
+ markerGroup.quaternion.copy(cameraQuaternion);
181
+ markerGroup.renderOrder = 999;
182
+ markerGroup.frustumCulled = false;
183
+ markerGroup.add(new THREE.Mesh(
184
+ new THREE.BoxGeometry(0.045 * markerScale, 0.028 * markerScale, 0.022 * markerScale),
185
+ new THREE.MeshBasicMaterial({ color, depthTest: false })
186
+ ));
187
+ const lens = new THREE.Mesh(
188
+ new THREE.BoxGeometry(0.025 * markerScale, 0.018 * markerScale, 0.014 * markerScale),
189
+ new THREE.MeshBasicMaterial({ color: aimColor, depthTest: false })
190
+ );
191
+ lens.position.set(0, 0, -0.021 * markerScale);
192
+ markerGroup.add(lens);
193
+ if (camera.name) markerGroup.add(createCameraLabel(camera.name, color));
194
+ group.add(markerGroup);
195
+
196
+ const targetMarker = new THREE.Mesh(
197
+ new THREE.SphereGeometry(0.018 * markerScale, 16, 10),
198
+ new THREE.MeshBasicMaterial({ color: aimColor, depthTest: false })
199
+ );
200
+ targetMarker.position.copy(target);
201
+ targetMarker.renderOrder = 999;
202
+ targetMarker.frustumCulled = false;
203
+ group.add(targetMarker);
204
+
205
+ return group;
206
+ }
207
+
44
208
  /**
45
209
  * Declarative debug visualization component.
46
210
  * Renders wireframe geoms, site markers, joint axes, contact forces, COM markers, etc.
@@ -50,6 +214,7 @@ export function Debug({
50
214
  showSites = false,
51
215
  showJoints = false,
52
216
  showCameras = false,
217
+ virtualCameras = [],
53
218
  showContacts = false,
54
219
  showCOM = false,
55
220
  showInertia = false,
@@ -69,6 +234,7 @@ export function Debug({
69
234
  const sites: THREE.Object3D[] = [];
70
235
  const joints: THREE.Object3D[] = [];
71
236
  const cameras: CameraDebugObject[] = [];
237
+ const virtualCameraObjects: THREE.Object3D[] = [];
72
238
  const comMarkers: THREE.Object3D[] = [];
73
239
 
74
240
  // Wireframe geoms
@@ -270,6 +436,10 @@ export function Debug({
270
436
  }
271
437
  }
272
438
 
439
+ for (let i = 0; i < virtualCameras.length; i += 1) {
440
+ virtualCameraObjects.push(createVirtualCameraDebugObject(virtualCameras[i], i));
441
+ }
442
+
273
443
  // COM markers
274
444
  if (showCOM) {
275
445
  for (let i = 1; i < model.nbody; i++) {
@@ -281,8 +451,8 @@ export function Debug({
281
451
  }
282
452
  }
283
453
 
284
- return { geoms, sites, joints, cameras, comMarkers };
285
- }, [status, mjModelRef, showGeoms, showSites, showJoints, showCameras, showCOM]);
454
+ return { geoms, sites, joints, cameras, virtualCameraObjects, comMarkers };
455
+ }, [status, mjModelRef, showGeoms, showSites, showJoints, showCameras, virtualCameras, showCOM]);
286
456
 
287
457
  // Add/remove debug objects from scene
288
458
  useEffect(() => {
@@ -294,6 +464,7 @@ export function Debug({
294
464
  ...debugGeometry.sites,
295
465
  ...debugGeometry.joints,
296
466
  ...debugGeometry.cameras,
467
+ ...debugGeometry.virtualCameraObjects,
297
468
  ...debugGeometry.comMarkers,
298
469
  ];
299
470
  for (const obj of allObjects) group.add(obj);
package/src/index.ts CHANGED
@@ -320,6 +320,7 @@ export type {
320
320
  IkGizmoProps,
321
321
  IkGizmoDragInput,
322
322
  DragInteractionProps,
323
+ DebugVirtualCamera,
323
324
  DebugProps,
324
325
  SceneLightsProps,
325
326
  ScenarioLightingPreset,
package/src/types.ts CHANGED
@@ -1027,11 +1027,28 @@ export interface ObservationHandle {
1027
1027
 
1028
1028
  // ---- Debug Component (spec 6.1) ----
1029
1029
 
1030
+ export interface DebugVirtualCamera {
1031
+ name?: string;
1032
+ position?: CameraFrameCaptureVector3;
1033
+ lookAt?: CameraFrameCaptureVector3;
1034
+ up?: CameraFrameCaptureVector3;
1035
+ quaternion?: THREE.Quaternion | readonly [number, number, number, number];
1036
+ fov?: number;
1037
+ width?: number;
1038
+ height?: number;
1039
+ frustumDepth?: number;
1040
+ markerScale?: number;
1041
+ color?: THREE.ColorRepresentation;
1042
+ aimColor?: THREE.ColorRepresentation;
1043
+ }
1044
+
1030
1045
  export interface DebugProps {
1031
1046
  showGeoms?: boolean;
1032
1047
  showSites?: boolean;
1033
1048
  showJoints?: boolean;
1034
1049
  showCameras?: boolean;
1050
+ /** Additional explicit virtual camera poses to visualize alongside MuJoCo XML cameras. */
1051
+ virtualCameras?: readonly DebugVirtualCamera[];
1035
1052
  showContacts?: boolean;
1036
1053
  showCOM?: boolean;
1037
1054
  showInertia?: boolean;