mujoco-react 9.4.0 → 9.6.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/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { withContacts, getContact } from './chunk-VDSEPZYQ.js';
2
- export { RobotActuators, RobotBodies, RobotCameras, RobotGeoms, RobotJoints, RobotKeyframes, RobotResources, RobotSensors, RobotSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, registerRobotResources, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-VDSEPZYQ.js';
1
+ import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, CAPTURE_EXCLUDE_KEY } from './chunk-4JHALVB2.js';
2
+ export { CAPTURE_EXCLUDE_KEY, RobotActuators, RobotBodies, RobotCameras, RobotGeoms, RobotJoints, RobotKeyframes, RobotResources, RobotSensors, RobotSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, registerRobotResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-4JHALVB2.js';
3
3
  import loadMujoco from '@mujoco/mujoco';
4
4
  import defaultMujocoWasmUrl from '@mujoco/mujoco/mujoco.wasm?url';
5
5
  import { createContext, forwardRef, useEffect, useContext, useState, useRef, useCallback, useMemo, useLayoutEffect } from 'react';
6
6
  import { jsx, jsxs } from 'react/jsx-runtime';
7
7
  import { Canvas, useThree, useFrame } from '@react-three/fiber';
8
- import * as THREE12 from 'three';
8
+ import * as THREE11 from 'three';
9
9
  import { PivotControls } from '@react-three/drei';
10
10
 
11
11
  var MujocoContext = createContext({
@@ -105,16 +105,16 @@ function MujocoProvider({
105
105
  }
106
106
  );
107
107
  }
108
- var CapsuleGeometry = class extends THREE12.BufferGeometry {
108
+ var CapsuleGeometry = class extends THREE11.BufferGeometry {
109
109
  parameters;
110
110
  constructor(radius = 1, length = 1, capSegments = 4, radialSegments = 8) {
111
111
  super();
112
112
  this.type = "CapsuleGeometry";
113
113
  this.parameters = { radius, length, capSegments, radialSegments };
114
- const path = new THREE12.Path();
114
+ const path = new THREE11.Path();
115
115
  path.absarc(0, -length / 2, radius, Math.PI * 1.5, 0, false);
116
116
  path.absarc(0, length / 2, radius, 0, Math.PI * 0.5, false);
117
- const latheGeometry = new THREE12.LatheGeometry(path.getPoints(capSegments), radialSegments);
117
+ const latheGeometry = new THREE11.LatheGeometry(path.getPoints(capSegments), radialSegments);
118
118
  const self = this;
119
119
  self.setIndex(latheGeometry.getIndex());
120
120
  self.setAttribute("position", latheGeometry.getAttribute("position"));
@@ -122,27 +122,27 @@ var CapsuleGeometry = class extends THREE12.BufferGeometry {
122
122
  self.setAttribute("uv", latheGeometry.getAttribute("uv"));
123
123
  }
124
124
  };
125
- var Reflector = class extends THREE12.Mesh {
125
+ var Reflector = class extends THREE11.Mesh {
126
126
  isReflector = true;
127
127
  camera;
128
- reflectorPlane = new THREE12.Plane();
129
- normal = new THREE12.Vector3();
130
- reflectorWorldPosition = new THREE12.Vector3();
131
- cameraWorldPosition = new THREE12.Vector3();
132
- rotationMatrix = new THREE12.Matrix4();
133
- lookAtPosition = new THREE12.Vector3(0, 0, -1);
134
- clipPlane = new THREE12.Vector4();
135
- view = new THREE12.Vector3();
136
- target = new THREE12.Vector3();
137
- q = new THREE12.Vector4();
138
- textureMatrix = new THREE12.Matrix4();
128
+ reflectorPlane = new THREE11.Plane();
129
+ normal = new THREE11.Vector3();
130
+ reflectorWorldPosition = new THREE11.Vector3();
131
+ cameraWorldPosition = new THREE11.Vector3();
132
+ rotationMatrix = new THREE11.Matrix4();
133
+ lookAtPosition = new THREE11.Vector3(0, 0, -1);
134
+ clipPlane = new THREE11.Vector4();
135
+ view = new THREE11.Vector3();
136
+ target = new THREE11.Vector3();
137
+ q = new THREE11.Vector4();
138
+ textureMatrix = new THREE11.Matrix4();
139
139
  virtualCamera;
140
140
  renderTarget;
141
141
  constructor(geometry, options = {}) {
142
142
  super(geometry);
143
143
  this.type = "Reflector";
144
- this.camera = new THREE12.PerspectiveCamera();
145
- const color = options.color !== void 0 ? new THREE12.Color(options.color) : new THREE12.Color(8355711);
144
+ this.camera = new THREE11.PerspectiveCamera();
145
+ const color = options.color !== void 0 ? new THREE11.Color(options.color) : new THREE11.Color(8355711);
146
146
  const textureWidth = options.textureWidth || 512;
147
147
  const textureHeight = options.textureHeight || 512;
148
148
  const clipBias = options.clipBias || 0;
@@ -150,11 +150,11 @@ var Reflector = class extends THREE12.Mesh {
150
150
  const blendTexture = options.texture || void 0;
151
151
  const mixStrength = options.mixStrength !== void 0 ? options.mixStrength : 0.25;
152
152
  this.virtualCamera = this.camera;
153
- this.renderTarget = new THREE12.WebGLRenderTarget(textureWidth, textureHeight, {
153
+ this.renderTarget = new THREE11.WebGLRenderTarget(textureWidth, textureHeight, {
154
154
  samples: multisample,
155
- type: THREE12.HalfFloatType
155
+ type: THREE11.HalfFloatType
156
156
  });
157
- this.material = new THREE12.MeshPhysicalMaterial({
157
+ this.material = new THREE11.MeshPhysicalMaterial({
158
158
  map: blendTexture,
159
159
  color,
160
160
  roughness: 0.5,
@@ -280,7 +280,7 @@ var GeomBuilder = class {
280
280
  const pos = mjModel.geom_pos.subarray(g * 3, g * 3 + 3);
281
281
  const quat = mjModel.geom_quat.subarray(g * 4, g * 4 + 4);
282
282
  const matId = mjModel.geom_matid[g];
283
- const color = new THREE12.Color(16777215);
283
+ const color = new THREE11.Color(16777215);
284
284
  let opacity = 1;
285
285
  if (matId >= 0) {
286
286
  const rgba = mjModel.mat_rgba.subarray(matId * 4, matId * 4 + 4);
@@ -295,16 +295,16 @@ var GeomBuilder = class {
295
295
  let geo = null;
296
296
  const getVal = (v) => v?.value ?? v;
297
297
  if (type === getVal(MG.mjGEOM_PLANE)) {
298
- geo = new THREE12.PlaneGeometry(size[0] * 2 || 5, size[1] * 2 || 5);
298
+ geo = new THREE11.PlaneGeometry(size[0] * 2 || 5, size[1] * 2 || 5);
299
299
  } else if (type === getVal(MG.mjGEOM_SPHERE)) {
300
- geo = new THREE12.SphereGeometry(size[0], 24, 24);
300
+ geo = new THREE11.SphereGeometry(size[0], 24, 24);
301
301
  } else if (type === getVal(MG.mjGEOM_CAPSULE)) {
302
302
  geo = new CapsuleGeometry(size[0], size[1] * 2, 24, 12);
303
303
  geo.rotateX(Math.PI / 2);
304
304
  } else if (type === getVal(MG.mjGEOM_BOX)) {
305
- geo = new THREE12.BoxGeometry(size[0] * 2, size[1] * 2, size[2] * 2);
305
+ geo = new THREE11.BoxGeometry(size[0] * 2, size[1] * 2, size[2] * 2);
306
306
  } else if (type === getVal(MG.mjGEOM_CYLINDER)) {
307
- geo = new THREE12.CylinderGeometry(size[0], size[0], size[1] * 2, 24);
307
+ geo = new THREE11.CylinderGeometry(size[0], size[0], size[1] * 2, 24);
308
308
  geo.rotateX(Math.PI / 2);
309
309
  } else if (type === getVal(MG.mjGEOM_MESH)) {
310
310
  const mId = mjModel.geom_dataid[g];
@@ -312,8 +312,8 @@ var GeomBuilder = class {
312
312
  const vNum = mjModel.mesh_vertnum[mId];
313
313
  const fAdr = mjModel.mesh_faceadr[mId];
314
314
  const fNum = mjModel.mesh_facenum[mId];
315
- geo = new THREE12.BufferGeometry();
316
- geo.setAttribute("position", new THREE12.Float32BufferAttribute(mjModel.mesh_vert.subarray(vAdr * 3, (vAdr + vNum) * 3), 3));
315
+ geo = new THREE11.BufferGeometry();
316
+ geo.setAttribute("position", new THREE11.Float32BufferAttribute(mjModel.mesh_vert.subarray(vAdr * 3, (vAdr + vNum) * 3), 3));
317
317
  geo.setIndex(Array.from(mjModel.mesh_face.subarray(fAdr * 3, (fAdr + fNum) * 3)));
318
318
  geo.computeVertexNormals();
319
319
  }
@@ -328,7 +328,7 @@ var GeomBuilder = class {
328
328
  mixStrength: 0.25
329
329
  });
330
330
  } else {
331
- mesh = new THREE12.Mesh(geo, new THREE12.MeshStandardMaterial({
331
+ mesh = new THREE11.Mesh(geo, new THREE11.MeshStandardMaterial({
332
332
  color,
333
333
  transparent: opacity < 1,
334
334
  opacity,
@@ -1142,7 +1142,7 @@ function SceneRenderer(props) {
1142
1142
  }
1143
1143
  const refs = [];
1144
1144
  for (let i = 0; i < model.nbody; i++) {
1145
- const bodyGroup = new THREE12.Group();
1145
+ const bodyGroup = new THREE11.Group();
1146
1146
  bodyGroup.userData.bodyID = i;
1147
1147
  const bodyName = getName(model, model.name_bodyadr[i]);
1148
1148
  if (!hiddenBodiesRef.current.has(bodyName)) {
@@ -1171,9 +1171,9 @@ function SceneRenderer(props) {
1171
1171
  const alpha = interpolation.alpha;
1172
1172
  const i3 = i * 3;
1173
1173
  ref.position.set(
1174
- THREE12.MathUtils.lerp(interpolation.previousXpos[i3], interpolation.currentXpos[i3], alpha),
1175
- THREE12.MathUtils.lerp(interpolation.previousXpos[i3 + 1], interpolation.currentXpos[i3 + 1], alpha),
1176
- THREE12.MathUtils.lerp(interpolation.previousXpos[i3 + 2], interpolation.currentXpos[i3 + 2], alpha)
1174
+ THREE11.MathUtils.lerp(interpolation.previousXpos[i3], interpolation.currentXpos[i3], alpha),
1175
+ THREE11.MathUtils.lerp(interpolation.previousXpos[i3 + 1], interpolation.currentXpos[i3 + 1], alpha),
1176
+ THREE11.MathUtils.lerp(interpolation.previousXpos[i3 + 2], interpolation.currentXpos[i3 + 2], alpha)
1177
1177
  );
1178
1178
  const i4 = i * 4;
1179
1179
  _previousQuat.set(
@@ -1228,8 +1228,8 @@ function SceneRenderer(props) {
1228
1228
  }
1229
1229
  );
1230
1230
  }
1231
- var _previousQuat = new THREE12.Quaternion();
1232
- var _currentQuat = new THREE12.Quaternion();
1231
+ var _previousQuat = new THREE11.Quaternion();
1232
+ var _currentQuat = new THREE11.Quaternion();
1233
1233
  function isTargetRef(target) {
1234
1234
  return Boolean(target && typeof target === "object" && "current" in target);
1235
1235
  }
@@ -1338,244 +1338,6 @@ function useFrameCapture(defaultOptions = {}) {
1338
1338
  reset
1339
1339
  };
1340
1340
  }
1341
- function toVector3(value, fallback) {
1342
- if (!value) return fallback.clone();
1343
- return value instanceof THREE12.Vector3 ? value.clone() : new THREE12.Vector3(value[0], value[1], value[2]);
1344
- }
1345
- function applyCameraPose(camera, options, fallbackCamera) {
1346
- camera.position.copy(toVector3(options.position, fallbackCamera.position));
1347
- camera.up.copy(toVector3(options.up, fallbackCamera.up));
1348
- if (options.quaternion) {
1349
- if (options.quaternion instanceof THREE12.Quaternion) {
1350
- camera.quaternion.copy(options.quaternion);
1351
- } else {
1352
- camera.quaternion.set(
1353
- options.quaternion[0],
1354
- options.quaternion[1],
1355
- options.quaternion[2],
1356
- options.quaternion[3]
1357
- );
1358
- }
1359
- } else if (options.lookAt) {
1360
- camera.lookAt(toVector3(options.lookAt, new THREE12.Vector3()));
1361
- } else {
1362
- camera.quaternion.copy(fallbackCamera.quaternion);
1363
- }
1364
- camera.updateMatrixWorld();
1365
- }
1366
- function createCaptureCamera(options, fallbackCamera, width, height) {
1367
- const camera = options.camera ? options.camera.clone() : fallbackCamera instanceof THREE12.PerspectiveCamera ? fallbackCamera.clone() : new THREE12.PerspectiveCamera(45, width / height, 0.01, 100);
1368
- if (camera instanceof THREE12.PerspectiveCamera) {
1369
- camera.aspect = width / height;
1370
- camera.fov = options.fov ?? camera.fov;
1371
- camera.near = options.near ?? camera.near;
1372
- camera.far = options.far ?? camera.far;
1373
- camera.updateProjectionMatrix();
1374
- }
1375
- applyCameraPose(camera, options, fallbackCamera);
1376
- return camera;
1377
- }
1378
- function getCaptureDimensions(renderer, options) {
1379
- const width = Math.max(
1380
- 1,
1381
- Math.floor(options.width ?? renderer.domElement.width)
1382
- );
1383
- const height = Math.max(
1384
- 1,
1385
- Math.floor(options.height ?? renderer.domElement.height)
1386
- );
1387
- return { width, height };
1388
- }
1389
- function prepareCaptureCamera(camera, options, fallbackCamera, width, height) {
1390
- if (options.camera) {
1391
- camera.copy(options.camera);
1392
- }
1393
- if (camera instanceof THREE12.PerspectiveCamera) {
1394
- camera.aspect = width / height;
1395
- camera.fov = options.fov ?? camera.fov;
1396
- camera.near = options.near ?? camera.near;
1397
- camera.far = options.far ?? camera.far;
1398
- camera.updateProjectionMatrix();
1399
- }
1400
- applyCameraPose(camera, options, fallbackCamera);
1401
- }
1402
- function readRenderTargetToCanvas(renderer, target, canvas, context, pixels, imageData, width, height) {
1403
- renderer.readRenderTargetPixels(target, 0, 0, width, height, pixels);
1404
- const rowBytes = width * 4;
1405
- for (let y = 0; y < height; y += 1) {
1406
- const sourceStart = (height - y - 1) * rowBytes;
1407
- const targetStart = y * rowBytes;
1408
- imageData.data.set(
1409
- pixels.subarray(sourceStart, sourceStart + rowBytes),
1410
- targetStart
1411
- );
1412
- }
1413
- context.putImageData(imageData, 0, 0);
1414
- return canvas;
1415
- }
1416
- function getCameraFrameCaptureSource(options) {
1417
- if (options.source) return options.source;
1418
- if (options.cameraName) {
1419
- return { kind: "mujoco-camera", cameraName: options.cameraName };
1420
- }
1421
- if (options.siteName) {
1422
- return { kind: "mujoco-site", siteName: options.siteName };
1423
- }
1424
- if (options.bodyName) {
1425
- return { kind: "mujoco-body", bodyName: options.bodyName };
1426
- }
1427
- if (options.camera) return { kind: "custom-camera" };
1428
- if (options.position || options.lookAt || options.quaternion) {
1429
- return { kind: "explicit-pose" };
1430
- }
1431
- return { kind: "fallback-camera" };
1432
- }
1433
- function createCameraFrameCaptureSession(renderer, scene, fallbackCamera, options = {}) {
1434
- const { width, height } = getCaptureDimensions(renderer, options);
1435
- const camera = createCaptureCamera(options, fallbackCamera, width, height);
1436
- const target = new THREE12.WebGLRenderTarget(width, height, {
1437
- format: THREE12.RGBAFormat,
1438
- type: THREE12.UnsignedByteType
1439
- });
1440
- const canvas = document.createElement("canvas");
1441
- canvas.width = width;
1442
- canvas.height = height;
1443
- const context = canvas.getContext("2d");
1444
- if (!context) {
1445
- target.dispose();
1446
- throw new Error("Unable to create a 2D canvas for camera frame capture.");
1447
- }
1448
- const drawContext = context;
1449
- const pixels = new Uint8Array(width * height * 4);
1450
- const imageData = drawContext.createImageData(width, height);
1451
- function capture(nextOptions = {}) {
1452
- const captureOptions = { ...options, ...nextOptions };
1453
- const nextDimensions = getCaptureDimensions(renderer, captureOptions);
1454
- if (nextDimensions.width !== width || nextDimensions.height !== height) {
1455
- throw new Error(
1456
- "Camera frame capture sessions require stable width and height."
1457
- );
1458
- }
1459
- prepareCaptureCamera(
1460
- camera,
1461
- captureOptions,
1462
- fallbackCamera,
1463
- width,
1464
- height
1465
- );
1466
- const previousTarget = renderer.getRenderTarget();
1467
- const previousXrEnabled = renderer.xr.enabled;
1468
- scene.updateMatrixWorld(true);
1469
- try {
1470
- renderer.xr.enabled = false;
1471
- renderer.setRenderTarget(target);
1472
- renderer.clear();
1473
- renderer.render(scene, camera);
1474
- readRenderTargetToCanvas(
1475
- renderer,
1476
- target,
1477
- canvas,
1478
- drawContext,
1479
- pixels,
1480
- imageData,
1481
- width,
1482
- height
1483
- );
1484
- return {
1485
- canvas,
1486
- camera,
1487
- width,
1488
- height,
1489
- source: getCameraFrameCaptureSource(captureOptions)
1490
- };
1491
- } finally {
1492
- renderer.setRenderTarget(previousTarget);
1493
- renderer.xr.enabled = previousXrEnabled;
1494
- }
1495
- }
1496
- return {
1497
- width,
1498
- height,
1499
- capture,
1500
- captureDataUrl(nextOptions = {}) {
1501
- const type = nextOptions.type ?? options.type ?? "image/png";
1502
- const result = capture(nextOptions);
1503
- return {
1504
- ...result,
1505
- dataUrl: result.canvas.toDataURL(
1506
- type,
1507
- nextOptions.quality ?? options.quality
1508
- ),
1509
- type
1510
- };
1511
- },
1512
- async captureBlob(nextOptions = {}) {
1513
- const type = nextOptions.type ?? options.type ?? "image/png";
1514
- const result = capture(nextOptions);
1515
- const blob = await new Promise((resolve, reject) => {
1516
- result.canvas.toBlob(
1517
- (nextBlob) => {
1518
- if (nextBlob) resolve(nextBlob);
1519
- else reject(new Error("Camera frame capture did not produce a Blob."));
1520
- },
1521
- type,
1522
- nextOptions.quality ?? options.quality
1523
- );
1524
- });
1525
- return { ...result, blob, type };
1526
- },
1527
- dispose() {
1528
- target.dispose();
1529
- }
1530
- };
1531
- }
1532
- function renderCameraFrameToCanvas(renderer, scene, fallbackCamera, options = {}) {
1533
- const session = createCameraFrameCaptureSession(
1534
- renderer,
1535
- scene,
1536
- fallbackCamera,
1537
- options
1538
- );
1539
- try {
1540
- return session.capture();
1541
- } finally {
1542
- session.dispose();
1543
- }
1544
- }
1545
- async function captureCameraFrame(renderer, scene, fallbackCamera, options = {}) {
1546
- const type = options.type ?? "image/png";
1547
- const result = renderCameraFrameToCanvas(
1548
- renderer,
1549
- scene,
1550
- fallbackCamera,
1551
- options
1552
- );
1553
- return {
1554
- ...result,
1555
- dataUrl: result.canvas.toDataURL(type, options.quality),
1556
- type
1557
- };
1558
- }
1559
- async function captureCameraFrameBlob(renderer, scene, fallbackCamera, options = {}) {
1560
- const type = options.type ?? "image/png";
1561
- const result = renderCameraFrameToCanvas(
1562
- renderer,
1563
- scene,
1564
- fallbackCamera,
1565
- options
1566
- );
1567
- const blob = await new Promise((resolve, reject) => {
1568
- result.canvas.toBlob(
1569
- (nextBlob) => {
1570
- if (nextBlob) resolve(nextBlob);
1571
- else reject(new Error("Camera frame capture did not produce a Blob."));
1572
- },
1573
- type,
1574
- options.quality
1575
- );
1576
- });
1577
- return { ...result, blob, type };
1578
- }
1579
1341
 
1580
1342
  // src/rendering/cameraFrameSource.ts
1581
1343
  var MountedCameraFrameSourceSuggestionMatch = {
@@ -1780,8 +1542,7 @@ function resolveMountedCameraFrameSource(key, options) {
1780
1542
  { bodyName: key }
1781
1543
  ];
1782
1544
  const aliasCandidates = normalizeAliasCandidates(options.aliases?.[key]);
1783
- const candidates = [...directCandidates, ...aliasCandidates];
1784
- for (const selector of candidates) {
1545
+ for (const selector of aliasCandidates) {
1785
1546
  if (!isSelectorMounted(selector, cameraNames, siteNames, bodyNames)) {
1786
1547
  continue;
1787
1548
  }
@@ -1804,6 +1565,14 @@ function resolveMountedCameraFrameSource(key, options) {
1804
1565
  return { key, selector, source };
1805
1566
  }
1806
1567
  }
1568
+ for (const selector of directCandidates) {
1569
+ if (!isSelectorMounted(selector, cameraNames, siteNames, bodyNames)) {
1570
+ continue;
1571
+ }
1572
+ const source = getMountedCameraFrameCaptureSource(selector);
1573
+ if (!source) continue;
1574
+ return { key, selector, source };
1575
+ }
1807
1576
  return null;
1808
1577
  }
1809
1578
  function createMountedCameraFrameSequencePlan(cameraKeys, options) {
@@ -2041,8 +1810,8 @@ var _applyPoint = new Float64Array(3);
2041
1810
  var _rayPnt = new Float64Array(3);
2042
1811
  var _rayVec = new Float64Array(3);
2043
1812
  var _rayGeomId = new Int32Array(1);
2044
- var _projRaycaster = new THREE12.Raycaster();
2045
- var _projNdc = new THREE12.Vector2();
1813
+ var _projRaycaster = new THREE11.Raycaster();
1814
+ var _projNdc = new THREE11.Vector2();
2046
1815
  function waitForNextAnimationFrame2() {
2047
1816
  return new Promise((resolve) => {
2048
1817
  requestAnimationFrame(() => resolve());
@@ -2058,16 +1827,16 @@ function throwIfCameraSequenceAborted(signal) {
2058
1827
  function vector3FromArray(values, offset) {
2059
1828
  return [values[offset], values[offset + 1], values[offset + 2]];
2060
1829
  }
2061
- function quaternionFromArray(values, offset) {
1830
+ function quaternionFromMujocoQuat(values, offset) {
2062
1831
  return [
2063
- values[offset],
2064
1832
  values[offset + 1],
2065
1833
  values[offset + 2],
2066
- values[offset + 3]
1834
+ values[offset + 3],
1835
+ values[offset]
2067
1836
  ];
2068
1837
  }
2069
1838
  function quaternionFromXmat(values, offset) {
2070
- const matrix = new THREE12.Matrix4();
1839
+ const matrix = new THREE11.Matrix4();
2071
1840
  matrix.set(
2072
1841
  values[offset],
2073
1842
  values[offset + 1],
@@ -2086,7 +1855,7 @@ function quaternionFromXmat(values, offset) {
2086
1855
  0,
2087
1856
  1
2088
1857
  );
2089
- const quaternion = new THREE12.Quaternion().setFromRotationMatrix(matrix);
1858
+ const quaternion = new THREE11.Quaternion().setFromRotationMatrix(matrix);
2090
1859
  return [quaternion.x, quaternion.y, quaternion.z, quaternion.w];
2091
1860
  }
2092
1861
  function omitResolvedCameraSelectors(options) {
@@ -2759,7 +2528,7 @@ function MujocoSimProvider({
2759
2528
  bodyId: model.cam_bodyid?.[i] ?? -1,
2760
2529
  fov: model.cam_fovy?.[i] ?? null,
2761
2530
  position: model.cam_pos ? vector3FromArray(model.cam_pos, posOffset) : null,
2762
- quaternion: model.cam_quat ? quaternionFromArray(model.cam_quat, quatOffset) : null
2531
+ quaternion: model.cam_quat ? quaternionFromMujocoQuat(model.cam_quat, quatOffset) : null
2763
2532
  });
2764
2533
  }
2765
2534
  return result;
@@ -2778,7 +2547,7 @@ function MujocoSimProvider({
2778
2547
  throw new Error(`MuJoCo camera "${options.cameraName}" was not found.`);
2779
2548
  }
2780
2549
  const position = data.cam_xpos ? vector3FromArray(data.cam_xpos, cameraId * 3) : model.cam_pos ? vector3FromArray(model.cam_pos, cameraId * 3) : void 0;
2781
- const quaternion = data.cam_xmat ? quaternionFromXmat(data.cam_xmat, cameraId * 9) : model.cam_quat ? quaternionFromArray(model.cam_quat, cameraId * 4) : void 0;
2550
+ const quaternion = data.cam_xmat ? quaternionFromXmat(data.cam_xmat, cameraId * 9) : model.cam_quat ? quaternionFromMujocoQuat(model.cam_quat, cameraId * 4) : void 0;
2782
2551
  if (!position || !quaternion) {
2783
2552
  throw new Error(
2784
2553
  `MuJoCo camera "${options.cameraName}" does not expose a capture pose.`
@@ -2864,7 +2633,7 @@ function MujocoSimProvider({
2864
2633
  const geomId = _rayGeomId[0];
2865
2634
  const bodyId = geomId >= 0 ? model.geom_bodyid[geomId] : -1;
2866
2635
  return {
2867
- point: new THREE12.Vector3(
2636
+ point: new THREE11.Vector3(
2868
2637
  origin.x + dir.x * dist,
2869
2638
  origin.y + dir.y * dist,
2870
2639
  origin.z + dir.z * dist
@@ -3144,7 +2913,7 @@ function MujocoSimProvider({
3144
2913
  const cameraFrames = {};
3145
2914
  for (const { key, captureOptions, mountedSource, session } of captureSessions) {
3146
2915
  const resolvedCaptureOptions = resolveCameraCaptureOptions(captureOptions);
3147
- const cameraFrame = session.captureDataUrl({
2916
+ const cameraFrame = await session.captureDataUrlAsync({
3148
2917
  ...resolvedCaptureOptions,
3149
2918
  source: mountedSource ?? resolvedCaptureOptions.source
3150
2919
  });
@@ -3833,7 +3602,7 @@ function solve6x6(A, b, x) {
3833
3602
  }
3834
3603
 
3835
3604
  // src/hooks/useIkController.ts
3836
- var _syncMat4 = new THREE12.Matrix4();
3605
+ var _syncMat4 = new THREE11.Matrix4();
3837
3606
  function syncGizmoToSite(data, siteId, target) {
3838
3607
  if (siteId === -1) return;
3839
3608
  const sitePos = data.site_xpos.subarray(siteId * 3, siteId * 3 + 3);
@@ -3865,7 +3634,7 @@ var useIkController = createControllerHook(
3865
3634
  const { mjModelRef, mjDataRef, mujocoRef, resetCallbacks, status } = useMujocoContext();
3866
3635
  const ikEnabledRef = useRef(false);
3867
3636
  const ikCalculatingRef = useRef(false);
3868
- const ikTargetRef = useRef(new THREE12.Group());
3637
+ const ikTargetRef = useRef(new THREE11.Group());
3869
3638
  const siteIdRef = useRef(-1);
3870
3639
  const controlGroupRef = useRef(null);
3871
3640
  const genericIkRef = useRef(new GenericIK(mujocoRef.current));
@@ -3873,10 +3642,10 @@ var useIkController = createControllerHook(
3873
3642
  const needsInitialSync = useRef(true);
3874
3643
  const gizmoAnimRef = useRef({
3875
3644
  active: false,
3876
- startPos: new THREE12.Vector3(),
3877
- endPos: new THREE12.Vector3(),
3878
- startRot: new THREE12.Quaternion(),
3879
- endRot: new THREE12.Quaternion(),
3645
+ startPos: new THREE11.Vector3(),
3646
+ endPos: new THREE11.Vector3(),
3647
+ startRot: new THREE11.Quaternion(),
3648
+ endRot: new THREE11.Quaternion(),
3880
3649
  startTime: 0,
3881
3650
  duration: 1e3
3882
3651
  });
@@ -3919,7 +3688,14 @@ var useIkController = createControllerHook(
3919
3688
  position,
3920
3689
  quaternion,
3921
3690
  currentQ,
3922
- { damping: config.damping, maxIterations: config.maxIterations }
3691
+ {
3692
+ damping: config.damping,
3693
+ epsilon: config.epsilon,
3694
+ maxIterations: config.maxIterations,
3695
+ posWeight: config.posWeight,
3696
+ rotWeight: config.rotWeight,
3697
+ tolerance: config.tolerance
3698
+ }
3923
3699
  );
3924
3700
  },
3925
3701
  [config, mjModelRef, mjDataRef]
@@ -4021,8 +3797,8 @@ var useIkController = createControllerHook(
4021
3797
  const target = ikTargetRef.current;
4022
3798
  if (!target) return;
4023
3799
  const targetPos = pos.clone();
4024
- const targetRot = new THREE12.Quaternion().setFromEuler(
4025
- new THREE12.Euler(Math.PI, 0, 0)
3800
+ const targetRot = new THREE11.Quaternion().setFromEuler(
3801
+ new THREE11.Euler(Math.PI, 0, 0)
4026
3802
  );
4027
3803
  if (duration > 0) {
4028
3804
  const ga = gizmoAnimRef.current;
@@ -4047,7 +3823,7 @@ var useIkController = createControllerHook(
4047
3823
  if (!ikCalculatingRef.current || !target) return null;
4048
3824
  return {
4049
3825
  pos: target.position.clone(),
4050
- rot: new THREE12.Euler().setFromQuaternion(target.quaternion)
3826
+ rot: new THREE11.Euler().setFromQuaternion(target.quaternion)
4051
3827
  };
4052
3828
  },
4053
3829
  []
@@ -4143,10 +3919,10 @@ function Body({
4143
3919
  if (!hasChildren) return null;
4144
3920
  return /* @__PURE__ */ jsx("group", { ref: groupRef, children });
4145
3921
  }
4146
- var _mat4 = new THREE12.Matrix4();
4147
- var _pos = new THREE12.Vector3();
4148
- var _quat = new THREE12.Quaternion();
4149
- var _scale = new THREE12.Vector3(1, 1, 1);
3922
+ var _mat4 = new THREE11.Matrix4();
3923
+ var _pos = new THREE11.Vector3();
3924
+ var _quat = new THREE11.Quaternion();
3925
+ var _scale = new THREE11.Vector3(1, 1, 1);
4150
3926
  function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
4151
3927
  const { mjModelRef, mjDataRef, status } = useMujocoContext();
4152
3928
  const { ikTargetRef, siteIdRef, ikEnabledRef, setIkEnabled } = controller;
@@ -4198,47 +3974,54 @@ function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
4198
3974
  }
4199
3975
  });
4200
3976
  if (status !== "ready") return null;
4201
- return /* @__PURE__ */ jsx("group", { ref: wrapperRef, children: /* @__PURE__ */ jsx(
4202
- PivotControls,
3977
+ return /* @__PURE__ */ jsx(
3978
+ "group",
4203
3979
  {
4204
- ref: pivotRef,
4205
- autoTransform: true,
4206
- scale,
4207
- fixed: false,
4208
- depthTest: false,
4209
- disableScaling: true,
4210
- onDragStart: () => {
4211
- draggingRef.current = true;
4212
- if (!onDrag) {
4213
- if (!ikEnabledRef.current) setIkEnabled(true);
4214
- }
4215
- if (controls) controls.enabled = false;
4216
- },
4217
- onDragEnd: () => {
4218
- draggingRef.current = false;
4219
- if (pivotRef.current) {
4220
- pivotRef.current.matrix.identity();
4221
- pivotRef.current.matrixWorldNeedsUpdate = true;
4222
- }
4223
- if (controls) controls.enabled = true;
4224
- },
4225
- onDrag: (_l, _dl, world) => {
4226
- world.decompose(_pos, _quat, _scale);
4227
- if (onDrag) {
4228
- onDrag({ position: _pos.clone(), quaternion: _quat.clone() });
4229
- } else {
4230
- const target = ikTargetRef.current;
4231
- if (target) {
4232
- target.position.copy(_pos);
4233
- target.quaternion.copy(_quat);
4234
- }
3980
+ ref: wrapperRef,
3981
+ userData: { [CAPTURE_EXCLUDE_KEY]: true },
3982
+ children: /* @__PURE__ */ jsx(
3983
+ PivotControls,
3984
+ {
3985
+ ref: pivotRef,
3986
+ autoTransform: true,
3987
+ scale,
3988
+ fixed: false,
3989
+ depthTest: false,
3990
+ disableScaling: true,
3991
+ onDragStart: () => {
3992
+ draggingRef.current = true;
3993
+ if (!onDrag) {
3994
+ if (!ikEnabledRef.current) setIkEnabled(true);
3995
+ }
3996
+ if (controls) controls.enabled = false;
3997
+ },
3998
+ onDragEnd: () => {
3999
+ draggingRef.current = false;
4000
+ if (pivotRef.current) {
4001
+ pivotRef.current.matrix.identity();
4002
+ pivotRef.current.matrixWorldNeedsUpdate = true;
4003
+ }
4004
+ if (controls) controls.enabled = true;
4005
+ },
4006
+ onDrag: (_l, _dl, world) => {
4007
+ world.decompose(_pos, _quat, _scale);
4008
+ if (onDrag) {
4009
+ onDrag({ position: _pos.clone(), quaternion: _quat.clone() });
4010
+ } else {
4011
+ const target = ikTargetRef.current;
4012
+ if (target) {
4013
+ target.position.copy(_pos);
4014
+ target.quaternion.copy(_quat);
4015
+ }
4016
+ }
4017
+ },
4018
+ children: /* @__PURE__ */ jsx("mesh", { visible: false, children: /* @__PURE__ */ jsx("sphereGeometry", { args: [1e-3] }) })
4235
4019
  }
4236
- },
4237
- children: /* @__PURE__ */ jsx("mesh", { visible: false, children: /* @__PURE__ */ jsx("sphereGeometry", { args: [1e-3] }) })
4020
+ )
4238
4021
  }
4239
- ) });
4022
+ );
4240
4023
  }
4241
- var _dummy = new THREE12.Object3D();
4024
+ var _dummy = new THREE11.Object3D();
4242
4025
  function ContactMarkers({
4243
4026
  maxContacts = 100,
4244
4027
  radius = 8e-3,
@@ -4274,19 +4057,29 @@ function ContactMarkers({
4274
4057
  mesh.instanceMatrix.needsUpdate = true;
4275
4058
  });
4276
4059
  if (status !== "ready") return null;
4277
- return /* @__PURE__ */ jsx("group", { ...groupProps, children: /* @__PURE__ */ jsxs("instancedMesh", { ref: meshRef, args: [void 0, void 0, maxContacts], frustumCulled: false, renderOrder: 999, children: [
4278
- /* @__PURE__ */ jsx("sphereGeometry", { args: [radius, 8, 8] }),
4279
- /* @__PURE__ */ jsx("meshBasicMaterial", { color, depthTest: false })
4280
- ] }) });
4060
+ return /* @__PURE__ */ jsx(
4061
+ "group",
4062
+ {
4063
+ ...groupProps,
4064
+ userData: {
4065
+ ...groupProps.userData,
4066
+ [CAPTURE_EXCLUDE_KEY]: true
4067
+ },
4068
+ children: /* @__PURE__ */ jsxs("instancedMesh", { ref: meshRef, args: [void 0, void 0, maxContacts], frustumCulled: false, renderOrder: 999, children: [
4069
+ /* @__PURE__ */ jsx("sphereGeometry", { args: [radius, 8, 8] }),
4070
+ /* @__PURE__ */ jsx("meshBasicMaterial", { color, depthTest: false })
4071
+ ] })
4072
+ }
4073
+ );
4281
4074
  }
4282
4075
  var _force = new Float64Array(3);
4283
4076
  var _torque = new Float64Array(3);
4284
4077
  var _point = new Float64Array(3);
4285
- var _bodyPos = new THREE12.Vector3();
4286
- var _bodyQuat = new THREE12.Quaternion();
4287
- var _worldHit = new THREE12.Vector3();
4288
- var _raycaster = new THREE12.Raycaster();
4289
- var _mouse = new THREE12.Vector2();
4078
+ var _bodyPos = new THREE11.Vector3();
4079
+ var _bodyQuat = new THREE11.Quaternion();
4080
+ var _worldHit = new THREE11.Vector3();
4081
+ var _raycaster = new THREE11.Raycaster();
4082
+ var _mouse = new THREE11.Vector2();
4290
4083
  function DragInteraction({
4291
4084
  stiffness = 250,
4292
4085
  showArrow = true,
@@ -4297,19 +4090,20 @@ function DragInteraction({
4297
4090
  const draggingRef = useRef(false);
4298
4091
  const bodyIdRef = useRef(-1);
4299
4092
  const grabDistanceRef = useRef(0);
4300
- const localHitRef = useRef(new THREE12.Vector3());
4301
- const grabWorldRef = useRef(new THREE12.Vector3());
4302
- const mouseWorldRef = useRef(new THREE12.Vector3());
4093
+ const localHitRef = useRef(new THREE11.Vector3());
4094
+ const grabWorldRef = useRef(new THREE11.Vector3());
4095
+ const mouseWorldRef = useRef(new THREE11.Vector3());
4303
4096
  const arrowRef = useRef(null);
4304
4097
  const groupRef = useRef(null);
4305
4098
  useEffect(() => {
4306
4099
  if (!showArrow || !groupRef.current) return;
4307
- const arrow = new THREE12.ArrowHelper(
4308
- new THREE12.Vector3(0, 1, 0),
4309
- new THREE12.Vector3(),
4100
+ const arrow = new THREE11.ArrowHelper(
4101
+ new THREE11.Vector3(0, 1, 0),
4102
+ new THREE11.Vector3(),
4310
4103
  0.1,
4311
4104
  16729156
4312
4105
  );
4106
+ arrow.userData[CAPTURE_EXCLUDE_KEY] = true;
4313
4107
  arrow.visible = false;
4314
4108
  arrow.line.material.transparent = true;
4315
4109
  arrow.line.material.opacity = 0.6;
@@ -4488,7 +4282,7 @@ function useSceneLights(intensity = 1) {
4488
4282
  const dr = lightDiffuse ? lightDiffuse[3 * i] : 1;
4489
4283
  const dg = lightDiffuse ? lightDiffuse[3 * i + 1] : 1;
4490
4284
  const db = lightDiffuse ? lightDiffuse[3 * i + 2] : 1;
4491
- const color = new THREE12.Color(dr, dg, db);
4285
+ const color = new THREE11.Color(dr, dg, db);
4492
4286
  const px = lightPos[3 * i];
4493
4287
  const py = lightPos[3 * i + 1];
4494
4288
  const pz = lightPos[3 * i + 2];
@@ -4496,7 +4290,7 @@ function useSceneLights(intensity = 1) {
4496
4290
  const dy = lightDir[3 * i + 1];
4497
4291
  const dz = lightDir[3 * i + 2];
4498
4292
  if (isDirectional) {
4499
- const light = new THREE12.DirectionalLight(color, finalIntensity);
4293
+ const light = new THREE11.DirectionalLight(color, finalIntensity);
4500
4294
  light.position.set(px, py, pz);
4501
4295
  light.target.position.set(px + dx, py + dy, pz + dz);
4502
4296
  light.castShadow = castShadow;
@@ -4519,7 +4313,7 @@ function useSceneLights(intensity = 1) {
4519
4313
  const cutoff = lightCutoff ? lightCutoff[i] : 45;
4520
4314
  const exponent = lightExponent ? lightExponent[i] : 10;
4521
4315
  const angle = cutoff * Math.PI / 180;
4522
- const light = new THREE12.SpotLight(color, finalIntensity, 0, angle, exponent / 128);
4316
+ const light = new THREE11.SpotLight(color, finalIntensity, 0, angle, exponent / 128);
4523
4317
  light.position.set(px, py, pz);
4524
4318
  light.target.position.set(px + dx, py + dy, pz + dz);
4525
4319
  light.castShadow = castShadow;
@@ -4802,16 +4596,20 @@ var JOINT_COLORS = {
4802
4596
  3: 16776960
4803
4597
  // hinge - yellow
4804
4598
  };
4805
- var _v3a = new THREE12.Vector3();
4806
- new THREE12.Vector3();
4807
- var _quat2 = new THREE12.Quaternion();
4808
- var _contactPos = new THREE12.Vector3();
4809
- var _contactNormal = new THREE12.Vector3();
4599
+ var _v3a = new THREE11.Vector3();
4600
+ new THREE11.Vector3();
4601
+ var _quat2 = new THREE11.Quaternion();
4602
+ var _cameraMatrix = new THREE11.Matrix4();
4603
+ var _contactPos = new THREE11.Vector3();
4604
+ var _contactNormal = new THREE11.Vector3();
4810
4605
  var MAX_CONTACT_ARROWS = 50;
4606
+ var CAMERA_DEBUG_LENGTH = 0.12;
4607
+ var CAMERA_DEBUG_FRUSTUM_DEPTH = 0.08;
4811
4608
  function Debug({
4812
4609
  showGeoms = false,
4813
4610
  showSites = false,
4814
4611
  showJoints = false,
4612
+ showCameras = false,
4815
4613
  showContacts = false,
4816
4614
  showCOM = false,
4817
4615
  showInertia = false,
@@ -4827,6 +4625,7 @@ function Debug({
4827
4625
  const geoms = [];
4828
4626
  const sites = [];
4829
4627
  const joints = [];
4628
+ const cameras = [];
4830
4629
  const comMarkers = [];
4831
4630
  if (showGeoms) {
4832
4631
  for (let i = 0; i < model.ngeom; i++) {
@@ -4835,21 +4634,21 @@ function Debug({
4835
4634
  let geometry = null;
4836
4635
  switch (type) {
4837
4636
  case 2:
4838
- geometry = new THREE12.SphereGeometry(s[3 * i], 12, 8);
4637
+ geometry = new THREE11.SphereGeometry(s[3 * i], 12, 8);
4839
4638
  break;
4840
4639
  case 3:
4841
- geometry = new THREE12.CapsuleGeometry(s[3 * i], s[3 * i + 1] * 2, 6, 8);
4640
+ geometry = new THREE11.CapsuleGeometry(s[3 * i], s[3 * i + 1] * 2, 6, 8);
4842
4641
  break;
4843
4642
  case 5:
4844
- geometry = new THREE12.CylinderGeometry(s[3 * i], s[3 * i], s[3 * i + 1] * 2, 12);
4643
+ geometry = new THREE11.CylinderGeometry(s[3 * i], s[3 * i], s[3 * i + 1] * 2, 12);
4845
4644
  break;
4846
4645
  case 6:
4847
- geometry = new THREE12.BoxGeometry(s[3 * i] * 2, s[3 * i + 1] * 2, s[3 * i + 2] * 2);
4646
+ geometry = new THREE11.BoxGeometry(s[3 * i] * 2, s[3 * i + 1] * 2, s[3 * i + 2] * 2);
4848
4647
  break;
4849
4648
  }
4850
4649
  if (geometry) {
4851
- const mat = new THREE12.MeshBasicMaterial({ color: 65280, wireframe: true, transparent: true, opacity: 0.3 });
4852
- const mesh = new THREE12.Mesh(geometry, mat);
4650
+ const mat = new THREE11.MeshBasicMaterial({ color: 65280, wireframe: true, transparent: true, opacity: 0.3 });
4651
+ const mesh = new THREE11.Mesh(geometry, mat);
4853
4652
  mesh.userData.geomId = i;
4854
4653
  mesh.userData.bodyId = model.geom_bodyid[i];
4855
4654
  geoms.push(mesh);
@@ -4872,9 +4671,9 @@ function Debug({
4872
4671
  }
4873
4672
  if (maxGeomSize > 0) radius = maxGeomSize * 0.15;
4874
4673
  }
4875
- const geometry = new THREE12.OctahedronGeometry(radius);
4876
- const mat = new THREE12.MeshBasicMaterial({ color: 16711935, depthTest: false });
4877
- const mesh = new THREE12.Mesh(geometry, mat);
4674
+ const geometry = new THREE11.OctahedronGeometry(radius);
4675
+ const mat = new THREE11.MeshBasicMaterial({ color: 16711935, depthTest: false });
4676
+ const mesh = new THREE11.Mesh(geometry, mat);
4878
4677
  mesh.renderOrder = 999;
4879
4678
  mesh.frustumCulled = false;
4880
4679
  mesh.userData.siteId = i;
@@ -4886,9 +4685,9 @@ function Debug({
4886
4685
  ctx.font = "bold 36px monospace";
4887
4686
  ctx.textAlign = "center";
4888
4687
  ctx.fillText(getName(model, model.name_siteadr[i]), 128, 42);
4889
- const tex = new THREE12.CanvasTexture(canvas);
4890
- const spriteMat = new THREE12.SpriteMaterial({ map: tex, depthTest: false, transparent: true });
4891
- const sprite = new THREE12.Sprite(spriteMat);
4688
+ const tex = new THREE11.CanvasTexture(canvas);
4689
+ const spriteMat = new THREE11.SpriteMaterial({ map: tex, depthTest: false, transparent: true });
4690
+ const sprite = new THREE11.Sprite(spriteMat);
4892
4691
  const labelScale = radius * 15;
4893
4692
  sprite.scale.set(labelScale, labelScale * 0.25, 1);
4894
4693
  sprite.position.y = radius * 2;
@@ -4911,9 +4710,9 @@ function Debug({
4911
4710
  }
4912
4711
  }
4913
4712
  const arrowLen = Math.max(maxGeomSize * 0.8, 0.05);
4914
- const arrow = new THREE12.ArrowHelper(
4915
- new THREE12.Vector3(0, 0, 1),
4916
- new THREE12.Vector3(),
4713
+ const arrow = new THREE11.ArrowHelper(
4714
+ new THREE11.Vector3(0, 0, 1),
4715
+ new THREE11.Vector3(),
4917
4716
  arrowLen,
4918
4717
  color,
4919
4718
  arrowLen * 0.25,
@@ -4921,7 +4720,7 @@ function Debug({
4921
4720
  );
4922
4721
  arrow.renderOrder = 999;
4923
4722
  arrow.frustumCulled = false;
4924
- arrow.line.material = new THREE12.LineBasicMaterial({ color, depthTest: false });
4723
+ arrow.line.material = new THREE11.LineBasicMaterial({ color, depthTest: false });
4925
4724
  arrow.cone.material.depthTest = false;
4926
4725
  arrow.line.renderOrder = 999;
4927
4726
  arrow.line.frustumCulled = false;
@@ -4934,17 +4733,88 @@ function Debug({
4934
4733
  joints.push(arrow);
4935
4734
  }
4936
4735
  }
4736
+ if (showCameras && model.ncam && model.name_camadr) {
4737
+ for (let i = 0; i < model.ncam; i++) {
4738
+ const group = new THREE11.Group();
4739
+ group.userData.cameraId = i;
4740
+ group.renderOrder = 999;
4741
+ group.frustumCulled = false;
4742
+ const marker = new THREE11.Mesh(
4743
+ new THREE11.BoxGeometry(0.014, 9e-3, 6e-3),
4744
+ new THREE11.MeshBasicMaterial({ color: 3718648, depthTest: false })
4745
+ );
4746
+ marker.renderOrder = 999;
4747
+ marker.frustumCulled = false;
4748
+ group.add(marker);
4749
+ const forward = new THREE11.ArrowHelper(
4750
+ new THREE11.Vector3(0, 0, -1),
4751
+ new THREE11.Vector3(),
4752
+ CAMERA_DEBUG_LENGTH,
4753
+ 3718648,
4754
+ CAMERA_DEBUG_LENGTH * 0.24,
4755
+ CAMERA_DEBUG_LENGTH * 0.11
4756
+ );
4757
+ forward.renderOrder = 999;
4758
+ forward.frustumCulled = false;
4759
+ forward.line.material = new THREE11.LineBasicMaterial({
4760
+ color: 3718648,
4761
+ depthTest: false
4762
+ });
4763
+ forward.cone.material.depthTest = false;
4764
+ group.add(forward);
4765
+ const frustumGeometry = new THREE11.BufferGeometry();
4766
+ frustumGeometry.setAttribute(
4767
+ "position",
4768
+ new THREE11.Float32BufferAttribute(new Float32Array(8 * 2 * 3), 3)
4769
+ );
4770
+ const frustum = new THREE11.LineSegments(
4771
+ frustumGeometry,
4772
+ new THREE11.LineBasicMaterial({
4773
+ color: 3718648,
4774
+ transparent: true,
4775
+ opacity: 0.8,
4776
+ depthTest: false
4777
+ })
4778
+ );
4779
+ frustum.renderOrder = 999;
4780
+ frustum.frustumCulled = false;
4781
+ group.userData.frustum = frustum;
4782
+ group.add(frustum);
4783
+ const canvas = document.createElement("canvas");
4784
+ canvas.width = 256;
4785
+ canvas.height = 64;
4786
+ const ctx = canvas.getContext("2d");
4787
+ ctx.fillStyle = "#38bdf8";
4788
+ ctx.font = "bold 32px monospace";
4789
+ ctx.textAlign = "center";
4790
+ ctx.fillText(getName(model, model.name_camadr[i]), 128, 42);
4791
+ const texture = new THREE11.CanvasTexture(canvas);
4792
+ const sprite = new THREE11.Sprite(
4793
+ new THREE11.SpriteMaterial({
4794
+ map: texture,
4795
+ depthTest: false,
4796
+ transparent: true
4797
+ })
4798
+ );
4799
+ sprite.position.set(0, 0.014, 0.01);
4800
+ sprite.scale.set(0.04, 0.01, 1);
4801
+ sprite.renderOrder = 999;
4802
+ group.userData.label = sprite;
4803
+ group.add(sprite);
4804
+ cameras.push(group);
4805
+ }
4806
+ }
4937
4807
  if (showCOM) {
4938
4808
  for (let i = 1; i < model.nbody; i++) {
4939
- const geometry = new THREE12.SphereGeometry(5e-3, 6, 6);
4940
- const mat = new THREE12.MeshBasicMaterial({ color: 16711680 });
4941
- const mesh = new THREE12.Mesh(geometry, mat);
4809
+ const geometry = new THREE11.SphereGeometry(5e-3, 6, 6);
4810
+ const mat = new THREE11.MeshBasicMaterial({ color: 16711680 });
4811
+ const mesh = new THREE11.Mesh(geometry, mat);
4942
4812
  mesh.userData.bodyId = i;
4943
4813
  comMarkers.push(mesh);
4944
4814
  }
4945
4815
  }
4946
- return { geoms, sites, joints, comMarkers };
4947
- }, [status, mjModelRef, showGeoms, showSites, showJoints, showCOM]);
4816
+ return { geoms, sites, joints, cameras, comMarkers };
4817
+ }, [status, mjModelRef, showGeoms, showSites, showJoints, showCameras, showCOM]);
4948
4818
  useEffect(() => {
4949
4819
  const group = groupRef.current;
4950
4820
  if (!group || !debugGeometry) return;
@@ -4952,6 +4822,7 @@ function Debug({
4952
4822
  ...debugGeometry.geoms,
4953
4823
  ...debugGeometry.sites,
4954
4824
  ...debugGeometry.joints,
4825
+ ...debugGeometry.cameras,
4955
4826
  ...debugGeometry.comMarkers
4956
4827
  ];
4957
4828
  for (const obj of allObjects) group.add(obj);
@@ -5014,6 +4885,68 @@ function Debug({
5014
4885
  arrow.setDirection(_v3a);
5015
4886
  }
5016
4887
  }
4888
+ const camXpos = data.cam_xpos;
4889
+ const camXmat = data.cam_xmat;
4890
+ if (camXpos && camXmat) {
4891
+ for (const group of debugGeometry.cameras) {
4892
+ const cameraId = group.userData.cameraId;
4893
+ const i3 = cameraId * 3;
4894
+ const i9 = cameraId * 9;
4895
+ group.position.set(
4896
+ camXpos[i3],
4897
+ camXpos[i3 + 1],
4898
+ camXpos[i3 + 2]
4899
+ );
4900
+ _cameraMatrix.set(
4901
+ camXmat[i9],
4902
+ camXmat[i9 + 1],
4903
+ camXmat[i9 + 2],
4904
+ 0,
4905
+ camXmat[i9 + 3],
4906
+ camXmat[i9 + 4],
4907
+ camXmat[i9 + 5],
4908
+ 0,
4909
+ camXmat[i9 + 6],
4910
+ camXmat[i9 + 7],
4911
+ camXmat[i9 + 8],
4912
+ 0,
4913
+ 0,
4914
+ 0,
4915
+ 0,
4916
+ 1
4917
+ );
4918
+ group.quaternion.setFromRotationMatrix(_cameraMatrix);
4919
+ const fovy = model.cam_fovy?.[cameraId] ?? 45;
4920
+ const halfHeight = Math.tan(THREE11.MathUtils.degToRad(fovy) / 2) * CAMERA_DEBUG_FRUSTUM_DEPTH;
4921
+ const halfWidth = halfHeight * 4 / 3;
4922
+ const positions = group.userData.frustum.geometry.attributes.position;
4923
+ const array = positions.array;
4924
+ const points = [
4925
+ [0, 0, 0],
4926
+ [-halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4927
+ [0, 0, 0],
4928
+ [halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4929
+ [0, 0, 0],
4930
+ [halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4931
+ [0, 0, 0],
4932
+ [-halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4933
+ [-halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4934
+ [halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4935
+ [halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4936
+ [halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4937
+ [halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4938
+ [-halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4939
+ [-halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4940
+ [-halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH]
4941
+ ];
4942
+ for (let i = 0; i < points.length; i += 1) {
4943
+ array[i * 3] = points[i][0];
4944
+ array[i * 3 + 1] = points[i][1];
4945
+ array[i * 3 + 2] = points[i][2];
4946
+ }
4947
+ positions.needsUpdate = true;
4948
+ }
4949
+ }
5017
4950
  for (const mesh of debugGeometry.comMarkers) {
5018
4951
  const bid = mesh.userData.bodyId;
5019
4952
  const i3 = bid * 3;
@@ -5029,9 +4962,9 @@ function Debug({
5029
4962
  contactPoolInitRef.current = true;
5030
4963
  const pool = [];
5031
4964
  for (let i = 0; i < MAX_CONTACT_ARROWS; i++) {
5032
- const arrow = new THREE12.ArrowHelper(
5033
- new THREE12.Vector3(0, 1, 0),
5034
- new THREE12.Vector3(),
4965
+ const arrow = new THREE11.ArrowHelper(
4966
+ new THREE11.Vector3(0, 1, 0),
4967
+ new THREE11.Vector3(),
5035
4968
  0.1,
5036
4969
  16729156,
5037
4970
  0.03,
@@ -5081,14 +5014,24 @@ function Debug({
5081
5014
  }
5082
5015
  });
5083
5016
  if (status !== "ready") return null;
5084
- return /* @__PURE__ */ jsxs("group", { ...groupProps, children: [
5085
- /* @__PURE__ */ jsx("group", { ref: groupRef }),
5086
- showContacts && /* @__PURE__ */ jsx("group", { ref: contactGroupRef })
5087
- ] });
5017
+ return /* @__PURE__ */ jsxs(
5018
+ "group",
5019
+ {
5020
+ ...groupProps,
5021
+ userData: {
5022
+ ...groupProps.userData,
5023
+ [CAPTURE_EXCLUDE_KEY]: true
5024
+ },
5025
+ children: [
5026
+ /* @__PURE__ */ jsx("group", { ref: groupRef }),
5027
+ showContacts && /* @__PURE__ */ jsx("group", { ref: contactGroupRef })
5028
+ ]
5029
+ }
5030
+ );
5088
5031
  }
5089
- var DEFAULT_TENDON_COLOR = new THREE12.Color(0.3, 0.3, 0.8);
5032
+ var DEFAULT_TENDON_COLOR = new THREE11.Color(0.3, 0.3, 0.8);
5090
5033
  var DEFAULT_TENDON_WIDTH = 2e-3;
5091
- new THREE12.Vector3();
5034
+ new THREE11.Vector3();
5092
5035
  function TendonRenderer(props) {
5093
5036
  const { mjModelRef, mjDataRef, status } = useMujocoContext();
5094
5037
  const groupRef = useRef(null);
@@ -5102,7 +5045,7 @@ function TendonRenderer(props) {
5102
5045
  if (!model || !data || !group) return;
5103
5046
  const ntendon = model.ntendon ?? 0;
5104
5047
  if (ntendon === 0) return;
5105
- const material = new THREE12.MeshStandardMaterial({
5048
+ const material = new THREE11.MeshStandardMaterial({
5106
5049
  color: DEFAULT_TENDON_COLOR,
5107
5050
  roughness: 0.6,
5108
5051
  metalness: 0.1
@@ -5117,11 +5060,11 @@ function TendonRenderer(props) {
5117
5060
  curves.push(null);
5118
5061
  continue;
5119
5062
  }
5120
- const points = Array.from({ length: wrapNum }, () => new THREE12.Vector3());
5121
- const curve = new THREE12.CatmullRomCurve3(points, false);
5063
+ const points = Array.from({ length: wrapNum }, () => new THREE11.Vector3());
5064
+ const curve = new THREE11.CatmullRomCurve3(points, false);
5122
5065
  const segments = Math.max(wrapNum * 2, 4);
5123
- const geometry = new THREE12.TubeGeometry(curve, segments, DEFAULT_TENDON_WIDTH, 6, false);
5124
- const mesh = new THREE12.Mesh(geometry, material);
5066
+ const geometry = new THREE11.TubeGeometry(curve, segments, DEFAULT_TENDON_WIDTH, 6, false);
5067
+ const mesh = new THREE11.Mesh(geometry, material);
5125
5068
  mesh.frustumCulled = false;
5126
5069
  group.add(mesh);
5127
5070
  meshes.push(mesh);
@@ -5176,11 +5119,11 @@ function TendonRenderer(props) {
5176
5119
  if (curve.points.length !== validCount) {
5177
5120
  curve.points.length = validCount;
5178
5121
  while (curve.points.length < validCount) {
5179
- curve.points.push(new THREE12.Vector3());
5122
+ curve.points.push(new THREE11.Vector3());
5180
5123
  }
5181
5124
  }
5182
5125
  mesh.geometry.dispose();
5183
- mesh.geometry = new THREE12.TubeGeometry(
5126
+ mesh.geometry = new THREE11.TubeGeometry(
5184
5127
  curve,
5185
5128
  Math.max(validCount * 2, 4),
5186
5129
  DEFAULT_TENDON_WIDTH,
@@ -5207,24 +5150,24 @@ function FlexRenderer(props) {
5207
5150
  const vertAdr = model.flex_vertadr[f];
5208
5151
  const vertNum = model.flex_vertnum[f];
5209
5152
  if (vertNum === 0) continue;
5210
- const geometry = new THREE12.BufferGeometry();
5153
+ const geometry = new THREE11.BufferGeometry();
5211
5154
  const positions = new Float32Array(vertNum * 3);
5212
- geometry.setAttribute("position", new THREE12.BufferAttribute(positions, 3));
5155
+ geometry.setAttribute("position", new THREE11.BufferAttribute(positions, 3));
5213
5156
  geometry.computeVertexNormals();
5214
- let color = new THREE12.Color(0.5, 0.5, 0.5);
5157
+ let color = new THREE11.Color(0.5, 0.5, 0.5);
5215
5158
  if (model.flex_rgba) {
5216
- color = new THREE12.Color(
5159
+ color = new THREE11.Color(
5217
5160
  model.flex_rgba[4 * f],
5218
5161
  model.flex_rgba[4 * f + 1],
5219
5162
  model.flex_rgba[4 * f + 2]
5220
5163
  );
5221
5164
  }
5222
- const material = new THREE12.MeshStandardMaterial({
5165
+ const material = new THREE11.MeshStandardMaterial({
5223
5166
  color,
5224
5167
  roughness: 0.7,
5225
- side: THREE12.DoubleSide
5168
+ side: THREE11.DoubleSide
5226
5169
  });
5227
- const mesh = new THREE12.Mesh(geometry, material);
5170
+ const mesh = new THREE11.Mesh(geometry, material);
5228
5171
  mesh.userData.flexId = f;
5229
5172
  mesh.userData.vertAdr = vertAdr;
5230
5173
  mesh.userData.vertNum = vertNum;
@@ -5260,7 +5203,7 @@ function FlexRenderer(props) {
5260
5203
  return /* @__PURE__ */ jsx("group", { ...props, ref: groupRef });
5261
5204
  }
5262
5205
  var GEOM_TYPE_NAMES2 = ["plane", "hfield", "sphere", "capsule", "ellipsoid", "cylinder", "box", "mesh"];
5263
- var _matrix = new THREE12.Matrix4();
5206
+ var _matrix = new THREE11.Matrix4();
5264
5207
  function getGeomInfo(model, geomId) {
5265
5208
  const size = model.geom_size.subarray(geomId * 3, geomId * 3 + 3);
5266
5209
  const type = model.geom_type[geomId];
@@ -5282,10 +5225,10 @@ function geomSignature(model, geomId) {
5282
5225
  return [type, size, mat, data, rgba].join("|");
5283
5226
  }
5284
5227
  function firstMesh(object) {
5285
- if (object instanceof THREE12.Mesh) return object;
5228
+ if (object instanceof THREE11.Mesh) return object;
5286
5229
  let mesh = null;
5287
5230
  object.traverse((child) => {
5288
- if (!mesh && child instanceof THREE12.Mesh) mesh = child;
5231
+ if (!mesh && child instanceof THREE11.Mesh) mesh = child;
5289
5232
  });
5290
5233
  return mesh;
5291
5234
  }
@@ -5714,12 +5657,12 @@ function useActuators() {
5714
5657
  return actuators;
5715
5658
  }, [status, mjModelRef]);
5716
5659
  }
5717
- var _mat42 = new THREE12.Matrix4();
5660
+ var _mat42 = new THREE11.Matrix4();
5718
5661
  function useSitePosition(siteName) {
5719
5662
  const { mjModelRef, mjDataRef, status } = useMujocoContext();
5720
5663
  const siteIdRef = useRef(-1);
5721
- const positionRef = useRef(new THREE12.Vector3());
5722
- const quaternionRef = useRef(new THREE12.Quaternion());
5664
+ const positionRef = useRef(new THREE11.Vector3());
5665
+ const quaternionRef = useRef(new THREE11.Quaternion());
5723
5666
  useEffect(() => {
5724
5667
  const model = mjModelRef.current;
5725
5668
  if (!model || status !== "ready") {
@@ -5910,10 +5853,10 @@ function useJointState(name) {
5910
5853
  function useBodyState(name) {
5911
5854
  const { mjModelRef, status } = useMujocoContext();
5912
5855
  const bodyIdRef = useRef(-1);
5913
- const position = useRef(new THREE12.Vector3());
5914
- const quaternion = useRef(new THREE12.Quaternion());
5915
- const linearVelocity = useRef(new THREE12.Vector3());
5916
- const angularVelocity = useRef(new THREE12.Vector3());
5856
+ const position = useRef(new THREE11.Vector3());
5857
+ const quaternion = useRef(new THREE11.Quaternion());
5858
+ const linearVelocity = useRef(new THREE11.Vector3());
5859
+ const angularVelocity = useRef(new THREE11.Vector3());
5917
5860
  useEffect(() => {
5918
5861
  const model = mjModelRef.current;
5919
5862
  if (!model || status !== "ready") return;
@@ -6035,6 +5978,135 @@ function useKeyboardTeleop(config) {
6035
5978
  }
6036
5979
  });
6037
5980
  }
5981
+ var DEFAULT_TRANSLATE_SPEED = 0.25;
5982
+ var DEFAULT_ROTATE_SPEED = 1;
5983
+ var _translation = new THREE11.Vector3();
5984
+ var _axis = new THREE11.Vector3();
5985
+ var _quat3 = new THREE11.Quaternion();
5986
+ function actionSign(action) {
5987
+ return action.endsWith("+") ? 1 : -1;
5988
+ }
5989
+ function actionBase(action) {
5990
+ return action.slice(0, -1);
5991
+ }
5992
+ function applyRotation(target, action, amount, frame) {
5993
+ const base = actionBase(action);
5994
+ if (base === "pitch") {
5995
+ _axis.set(1, 0, 0);
5996
+ } else if (base === "yaw") {
5997
+ _axis.set(0, 1, 0);
5998
+ } else if (base === "roll") {
5999
+ _axis.set(0, 0, 1);
6000
+ } else {
6001
+ return;
6002
+ }
6003
+ _quat3.setFromAxisAngle(_axis, amount);
6004
+ if (frame === "target") {
6005
+ target.quaternion.multiply(_quat3);
6006
+ } else {
6007
+ target.quaternion.premultiply(_quat3);
6008
+ }
6009
+ }
6010
+ function addTranslation(action, amount) {
6011
+ switch (action) {
6012
+ case "x+":
6013
+ _translation.x += amount;
6014
+ break;
6015
+ case "x-":
6016
+ _translation.x -= amount;
6017
+ break;
6018
+ case "y+":
6019
+ _translation.y += amount;
6020
+ break;
6021
+ case "y-":
6022
+ _translation.y -= amount;
6023
+ break;
6024
+ case "z+":
6025
+ _translation.z += amount;
6026
+ break;
6027
+ case "z-":
6028
+ _translation.z -= amount;
6029
+ break;
6030
+ }
6031
+ }
6032
+ function useKeyboardIkTarget(config) {
6033
+ const pressedRef = useRef(/* @__PURE__ */ new Set());
6034
+ const wasActiveRef = useRef(false);
6035
+ const configRef = useRef(config);
6036
+ configRef.current = config;
6037
+ const boundCodes = useMemo(() => {
6038
+ return new Set((config?.bindings ?? []).map((binding) => binding.code));
6039
+ }, [config?.bindings]);
6040
+ useEffect(() => {
6041
+ const onKeyDown = (event) => {
6042
+ const current = configRef.current;
6043
+ if (!current || current.enabled === false || !boundCodes.has(event.code)) return;
6044
+ if (current.preventDefault !== false) event.preventDefault();
6045
+ pressedRef.current.add(event.code);
6046
+ };
6047
+ const onKeyUp = (event) => {
6048
+ const current = configRef.current;
6049
+ if (boundCodes.has(event.code) && current?.preventDefault !== false) {
6050
+ event.preventDefault();
6051
+ }
6052
+ pressedRef.current.delete(event.code);
6053
+ };
6054
+ const onBlur = () => {
6055
+ pressedRef.current.clear();
6056
+ wasActiveRef.current = false;
6057
+ };
6058
+ window.addEventListener("keydown", onKeyDown);
6059
+ window.addEventListener("keyup", onKeyUp);
6060
+ window.addEventListener("blur", onBlur);
6061
+ return () => {
6062
+ window.removeEventListener("keydown", onKeyDown);
6063
+ window.removeEventListener("keyup", onKeyUp);
6064
+ window.removeEventListener("blur", onBlur);
6065
+ };
6066
+ }, [boundCodes]);
6067
+ useFrame((_state, delta) => {
6068
+ const current = configRef.current;
6069
+ const controller = current?.controller;
6070
+ if (!current || current.enabled === false || !controller) {
6071
+ wasActiveRef.current = false;
6072
+ return;
6073
+ }
6074
+ const activeBindings = [];
6075
+ for (const binding of current.bindings) {
6076
+ if (pressedRef.current.has(binding.code)) activeBindings.push(binding);
6077
+ }
6078
+ if (activeBindings.length === 0) {
6079
+ wasActiveRef.current = false;
6080
+ return;
6081
+ }
6082
+ if (!wasActiveRef.current) {
6083
+ if (current.syncOnStart !== false) controller.syncTargetToSite();
6084
+ if (current.autoEnableIk !== false && !controller.ikEnabledRef.current) {
6085
+ controller.setIkEnabled(true);
6086
+ }
6087
+ }
6088
+ wasActiveRef.current = true;
6089
+ const target = controller.ikTargetRef.current;
6090
+ if (!target) return;
6091
+ const frame = current.frame ?? "world";
6092
+ _translation.set(0, 0, 0);
6093
+ for (const binding of activeBindings) {
6094
+ const translateSpeed = binding.translateSpeed ?? current.translateSpeed ?? DEFAULT_TRANSLATE_SPEED;
6095
+ const rotateSpeed = binding.rotateSpeed ?? current.rotateSpeed ?? DEFAULT_ROTATE_SPEED;
6096
+ const amount = actionSign(binding.action) * delta;
6097
+ const base = actionBase(binding.action);
6098
+ if (base === "x" || base === "y" || base === "z") {
6099
+ addTranslation(binding.action, translateSpeed * delta);
6100
+ } else {
6101
+ applyRotation(target, binding.action, rotateSpeed * amount, frame);
6102
+ }
6103
+ }
6104
+ if (_translation.lengthSq() > 0) {
6105
+ if (frame === "target") _translation.applyQuaternion(target.quaternion);
6106
+ target.position.add(_translation);
6107
+ }
6108
+ });
6109
+ }
6038
6110
  function usePolicy(config) {
6039
6111
  const lastActionTimeRef = useRef(0);
6040
6112
  const lastObservationRef = useRef(null);
@@ -6501,7 +6573,7 @@ function useSelectionHighlight(bodyId, options = {}) {
6501
6573
  }
6502
6574
  }
6503
6575
  prevRef.current = [];
6504
- const highlightColor = new THREE12.Color(color);
6576
+ const highlightColor = new THREE11.Color(color);
6505
6577
  for (const mesh of meshes) {
6506
6578
  const mat = mesh.material;
6507
6579
  if (mat.emissive) {
@@ -6528,15 +6600,15 @@ function useSelectionHighlight(bodyId, options = {}) {
6528
6600
  }
6529
6601
  function useCameraAnimation() {
6530
6602
  const { camera } = useThree();
6531
- const orbitTargetRef = useRef(new THREE12.Vector3(0, 0, 0));
6603
+ const orbitTargetRef = useRef(new THREE11.Vector3(0, 0, 0));
6532
6604
  const cameraAnimRef = useRef({
6533
6605
  active: false,
6534
- startPos: new THREE12.Vector3(),
6535
- endPos: new THREE12.Vector3(),
6536
- startRot: new THREE12.Quaternion(),
6537
- endRot: new THREE12.Quaternion(),
6538
- startTarget: new THREE12.Vector3(),
6539
- endTarget: new THREE12.Vector3(),
6606
+ startPos: new THREE11.Vector3(),
6607
+ endPos: new THREE11.Vector3(),
6608
+ startRot: new THREE11.Quaternion(),
6609
+ endRot: new THREE11.Quaternion(),
6610
+ startTarget: new THREE11.Vector3(),
6611
+ endTarget: new THREE11.Vector3(),
6540
6612
  startTime: 0,
6541
6613
  duration: 0,
6542
6614
  resolve: null
@@ -6608,12 +6680,6 @@ function useCameraAnimation() {
6608
6680
  *
6609
6681
  * useFrameCapture — still-frame capture for canvas-backed MuJoCo/R3F scenes.
6610
6682
  */
6611
- /**
6612
- * @license
6613
- * SPDX-License-Identifier: Apache-2.0
6614
- *
6615
- * Offscreen camera-frame capture for R3F/MuJoCo scenes.
6616
- */
6617
6683
  /**
6618
6684
  * @license
6619
6685
  * SPDX-License-Identifier: Apache-2.0
@@ -6801,6 +6867,6 @@ function useCameraAnimation() {
6801
6867
  * useCameraAnimation — composable camera animation hook.
6802
6868
  */
6803
6869
 
6804
- export { Body, ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkGizmo, InstancedGeomRenderer, MountedCameraFrameSequenceManifestStatus, MountedCameraFrameSequenceReadinessStatus, MountedCameraFrameSourceSuggestionMatch, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, SceneLights, SplatCollisionProxyPreview, TendonRenderer, TrajectoryPlayer, buildObservation, canFetchSplatCollisionProxyXml, captureCameraFrame, captureCameraFrameBlob, captureFrame, captureFrameBlob, createCameraFrameCaptureSession, createContiguousControlGroup, createController, createControllerHook, createMountedCameraFrameSequenceManifest, createMountedCameraFrameSequencePlan, createMountedCameraFrameSequencePlanFromApi, createMountedCameraFrameSequenceReadiness, createMountedCameraFrameSourceSuggestions, fetchSplatCollisionProxyXml, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getCameraFrameCaptureSourceTarget, getControlMap, getMountedCameraFrameCaptureSource, getName, isMountedCameraFrameCaptureSource, loadScene, parseSplatCollisionProxyGeoms, recordMountedCameraFrameSequence, renderCameraFrameToCanvas, resolveControlGroup, resolveMountedCameraFrameSource, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useCameraFrameCapture, useCameraSequenceRecorder, useContactEvents, useContacts, useCtrl, useCtrlNoise, useFrameCapture, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardTeleop, useMountedCameraSequenceRecorder, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useSplatCollisionProxyGeoms, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
6870
+ export { Body, ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkGizmo, InstancedGeomRenderer, MountedCameraFrameSequenceManifestStatus, MountedCameraFrameSequenceReadinessStatus, MountedCameraFrameSourceSuggestionMatch, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, SceneLights, SplatCollisionProxyPreview, TendonRenderer, TrajectoryPlayer, buildObservation, canFetchSplatCollisionProxyXml, captureFrame, captureFrameBlob, createContiguousControlGroup, createController, createControllerHook, createMountedCameraFrameSequenceManifest, createMountedCameraFrameSequencePlan, createMountedCameraFrameSequencePlanFromApi, createMountedCameraFrameSequenceReadiness, createMountedCameraFrameSourceSuggestions, fetchSplatCollisionProxyXml, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getCameraFrameCaptureSourceTarget, getControlMap, getMountedCameraFrameCaptureSource, getName, isMountedCameraFrameCaptureSource, loadScene, parseSplatCollisionProxyGeoms, recordMountedCameraFrameSequence, resolveControlGroup, resolveMountedCameraFrameSource, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useCameraFrameCapture, useCameraSequenceRecorder, useContactEvents, useContacts, useCtrl, useCtrlNoise, useFrameCapture, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardIkTarget, useKeyboardTeleop, useMountedCameraSequenceRecorder, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useSplatCollisionProxyGeoms, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
6805
6871
  //# sourceMappingURL=index.js.map
6806
6872
  //# sourceMappingURL=index.js.map