mujoco-react 9.4.0 → 9.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/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-6MOK6ZWB.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-6MOK6ZWB.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
  });
@@ -4021,8 +3790,8 @@ var useIkController = createControllerHook(
4021
3790
  const target = ikTargetRef.current;
4022
3791
  if (!target) return;
4023
3792
  const targetPos = pos.clone();
4024
- const targetRot = new THREE12.Quaternion().setFromEuler(
4025
- new THREE12.Euler(Math.PI, 0, 0)
3793
+ const targetRot = new THREE11.Quaternion().setFromEuler(
3794
+ new THREE11.Euler(Math.PI, 0, 0)
4026
3795
  );
4027
3796
  if (duration > 0) {
4028
3797
  const ga = gizmoAnimRef.current;
@@ -4047,7 +3816,7 @@ var useIkController = createControllerHook(
4047
3816
  if (!ikCalculatingRef.current || !target) return null;
4048
3817
  return {
4049
3818
  pos: target.position.clone(),
4050
- rot: new THREE12.Euler().setFromQuaternion(target.quaternion)
3819
+ rot: new THREE11.Euler().setFromQuaternion(target.quaternion)
4051
3820
  };
4052
3821
  },
4053
3822
  []
@@ -4143,10 +3912,10 @@ function Body({
4143
3912
  if (!hasChildren) return null;
4144
3913
  return /* @__PURE__ */ jsx("group", { ref: groupRef, children });
4145
3914
  }
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);
3915
+ var _mat4 = new THREE11.Matrix4();
3916
+ var _pos = new THREE11.Vector3();
3917
+ var _quat = new THREE11.Quaternion();
3918
+ var _scale = new THREE11.Vector3(1, 1, 1);
4150
3919
  function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
4151
3920
  const { mjModelRef, mjDataRef, status } = useMujocoContext();
4152
3921
  const { ikTargetRef, siteIdRef, ikEnabledRef, setIkEnabled } = controller;
@@ -4198,47 +3967,54 @@ function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
4198
3967
  }
4199
3968
  });
4200
3969
  if (status !== "ready") return null;
4201
- return /* @__PURE__ */ jsx("group", { ref: wrapperRef, children: /* @__PURE__ */ jsx(
4202
- PivotControls,
3970
+ return /* @__PURE__ */ jsx(
3971
+ "group",
4203
3972
  {
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
- }
3973
+ ref: wrapperRef,
3974
+ userData: { [CAPTURE_EXCLUDE_KEY]: true },
3975
+ children: /* @__PURE__ */ jsx(
3976
+ PivotControls,
3977
+ {
3978
+ ref: pivotRef,
3979
+ autoTransform: true,
3980
+ scale,
3981
+ fixed: false,
3982
+ depthTest: false,
3983
+ disableScaling: true,
3984
+ onDragStart: () => {
3985
+ draggingRef.current = true;
3986
+ if (!onDrag) {
3987
+ if (!ikEnabledRef.current) setIkEnabled(true);
3988
+ }
3989
+ if (controls) controls.enabled = false;
3990
+ },
3991
+ onDragEnd: () => {
3992
+ draggingRef.current = false;
3993
+ if (pivotRef.current) {
3994
+ pivotRef.current.matrix.identity();
3995
+ pivotRef.current.matrixWorldNeedsUpdate = true;
3996
+ }
3997
+ if (controls) controls.enabled = true;
3998
+ },
3999
+ onDrag: (_l, _dl, world) => {
4000
+ world.decompose(_pos, _quat, _scale);
4001
+ if (onDrag) {
4002
+ onDrag({ position: _pos.clone(), quaternion: _quat.clone() });
4003
+ } else {
4004
+ const target = ikTargetRef.current;
4005
+ if (target) {
4006
+ target.position.copy(_pos);
4007
+ target.quaternion.copy(_quat);
4008
+ }
4009
+ }
4010
+ },
4011
+ children: /* @__PURE__ */ jsx("mesh", { visible: false, children: /* @__PURE__ */ jsx("sphereGeometry", { args: [1e-3] }) })
4235
4012
  }
4236
- },
4237
- children: /* @__PURE__ */ jsx("mesh", { visible: false, children: /* @__PURE__ */ jsx("sphereGeometry", { args: [1e-3] }) })
4013
+ )
4238
4014
  }
4239
- ) });
4015
+ );
4240
4016
  }
4241
- var _dummy = new THREE12.Object3D();
4017
+ var _dummy = new THREE11.Object3D();
4242
4018
  function ContactMarkers({
4243
4019
  maxContacts = 100,
4244
4020
  radius = 8e-3,
@@ -4274,19 +4050,29 @@ function ContactMarkers({
4274
4050
  mesh.instanceMatrix.needsUpdate = true;
4275
4051
  });
4276
4052
  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
- ] }) });
4053
+ return /* @__PURE__ */ jsx(
4054
+ "group",
4055
+ {
4056
+ ...groupProps,
4057
+ userData: {
4058
+ ...groupProps.userData,
4059
+ [CAPTURE_EXCLUDE_KEY]: true
4060
+ },
4061
+ children: /* @__PURE__ */ jsxs("instancedMesh", { ref: meshRef, args: [void 0, void 0, maxContacts], frustumCulled: false, renderOrder: 999, children: [
4062
+ /* @__PURE__ */ jsx("sphereGeometry", { args: [radius, 8, 8] }),
4063
+ /* @__PURE__ */ jsx("meshBasicMaterial", { color, depthTest: false })
4064
+ ] })
4065
+ }
4066
+ );
4281
4067
  }
4282
4068
  var _force = new Float64Array(3);
4283
4069
  var _torque = new Float64Array(3);
4284
4070
  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();
4071
+ var _bodyPos = new THREE11.Vector3();
4072
+ var _bodyQuat = new THREE11.Quaternion();
4073
+ var _worldHit = new THREE11.Vector3();
4074
+ var _raycaster = new THREE11.Raycaster();
4075
+ var _mouse = new THREE11.Vector2();
4290
4076
  function DragInteraction({
4291
4077
  stiffness = 250,
4292
4078
  showArrow = true,
@@ -4297,19 +4083,20 @@ function DragInteraction({
4297
4083
  const draggingRef = useRef(false);
4298
4084
  const bodyIdRef = useRef(-1);
4299
4085
  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());
4086
+ const localHitRef = useRef(new THREE11.Vector3());
4087
+ const grabWorldRef = useRef(new THREE11.Vector3());
4088
+ const mouseWorldRef = useRef(new THREE11.Vector3());
4303
4089
  const arrowRef = useRef(null);
4304
4090
  const groupRef = useRef(null);
4305
4091
  useEffect(() => {
4306
4092
  if (!showArrow || !groupRef.current) return;
4307
- const arrow = new THREE12.ArrowHelper(
4308
- new THREE12.Vector3(0, 1, 0),
4309
- new THREE12.Vector3(),
4093
+ const arrow = new THREE11.ArrowHelper(
4094
+ new THREE11.Vector3(0, 1, 0),
4095
+ new THREE11.Vector3(),
4310
4096
  0.1,
4311
4097
  16729156
4312
4098
  );
4099
+ arrow.userData[CAPTURE_EXCLUDE_KEY] = true;
4313
4100
  arrow.visible = false;
4314
4101
  arrow.line.material.transparent = true;
4315
4102
  arrow.line.material.opacity = 0.6;
@@ -4488,7 +4275,7 @@ function useSceneLights(intensity = 1) {
4488
4275
  const dr = lightDiffuse ? lightDiffuse[3 * i] : 1;
4489
4276
  const dg = lightDiffuse ? lightDiffuse[3 * i + 1] : 1;
4490
4277
  const db = lightDiffuse ? lightDiffuse[3 * i + 2] : 1;
4491
- const color = new THREE12.Color(dr, dg, db);
4278
+ const color = new THREE11.Color(dr, dg, db);
4492
4279
  const px = lightPos[3 * i];
4493
4280
  const py = lightPos[3 * i + 1];
4494
4281
  const pz = lightPos[3 * i + 2];
@@ -4496,7 +4283,7 @@ function useSceneLights(intensity = 1) {
4496
4283
  const dy = lightDir[3 * i + 1];
4497
4284
  const dz = lightDir[3 * i + 2];
4498
4285
  if (isDirectional) {
4499
- const light = new THREE12.DirectionalLight(color, finalIntensity);
4286
+ const light = new THREE11.DirectionalLight(color, finalIntensity);
4500
4287
  light.position.set(px, py, pz);
4501
4288
  light.target.position.set(px + dx, py + dy, pz + dz);
4502
4289
  light.castShadow = castShadow;
@@ -4519,7 +4306,7 @@ function useSceneLights(intensity = 1) {
4519
4306
  const cutoff = lightCutoff ? lightCutoff[i] : 45;
4520
4307
  const exponent = lightExponent ? lightExponent[i] : 10;
4521
4308
  const angle = cutoff * Math.PI / 180;
4522
- const light = new THREE12.SpotLight(color, finalIntensity, 0, angle, exponent / 128);
4309
+ const light = new THREE11.SpotLight(color, finalIntensity, 0, angle, exponent / 128);
4523
4310
  light.position.set(px, py, pz);
4524
4311
  light.target.position.set(px + dx, py + dy, pz + dz);
4525
4312
  light.castShadow = castShadow;
@@ -4802,16 +4589,20 @@ var JOINT_COLORS = {
4802
4589
  3: 16776960
4803
4590
  // hinge - yellow
4804
4591
  };
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();
4592
+ var _v3a = new THREE11.Vector3();
4593
+ new THREE11.Vector3();
4594
+ var _quat2 = new THREE11.Quaternion();
4595
+ var _cameraMatrix = new THREE11.Matrix4();
4596
+ var _contactPos = new THREE11.Vector3();
4597
+ var _contactNormal = new THREE11.Vector3();
4810
4598
  var MAX_CONTACT_ARROWS = 50;
4599
+ var CAMERA_DEBUG_LENGTH = 0.12;
4600
+ var CAMERA_DEBUG_FRUSTUM_DEPTH = 0.08;
4811
4601
  function Debug({
4812
4602
  showGeoms = false,
4813
4603
  showSites = false,
4814
4604
  showJoints = false,
4605
+ showCameras = false,
4815
4606
  showContacts = false,
4816
4607
  showCOM = false,
4817
4608
  showInertia = false,
@@ -4827,6 +4618,7 @@ function Debug({
4827
4618
  const geoms = [];
4828
4619
  const sites = [];
4829
4620
  const joints = [];
4621
+ const cameras = [];
4830
4622
  const comMarkers = [];
4831
4623
  if (showGeoms) {
4832
4624
  for (let i = 0; i < model.ngeom; i++) {
@@ -4835,21 +4627,21 @@ function Debug({
4835
4627
  let geometry = null;
4836
4628
  switch (type) {
4837
4629
  case 2:
4838
- geometry = new THREE12.SphereGeometry(s[3 * i], 12, 8);
4630
+ geometry = new THREE11.SphereGeometry(s[3 * i], 12, 8);
4839
4631
  break;
4840
4632
  case 3:
4841
- geometry = new THREE12.CapsuleGeometry(s[3 * i], s[3 * i + 1] * 2, 6, 8);
4633
+ geometry = new THREE11.CapsuleGeometry(s[3 * i], s[3 * i + 1] * 2, 6, 8);
4842
4634
  break;
4843
4635
  case 5:
4844
- geometry = new THREE12.CylinderGeometry(s[3 * i], s[3 * i], s[3 * i + 1] * 2, 12);
4636
+ geometry = new THREE11.CylinderGeometry(s[3 * i], s[3 * i], s[3 * i + 1] * 2, 12);
4845
4637
  break;
4846
4638
  case 6:
4847
- geometry = new THREE12.BoxGeometry(s[3 * i] * 2, s[3 * i + 1] * 2, s[3 * i + 2] * 2);
4639
+ geometry = new THREE11.BoxGeometry(s[3 * i] * 2, s[3 * i + 1] * 2, s[3 * i + 2] * 2);
4848
4640
  break;
4849
4641
  }
4850
4642
  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);
4643
+ const mat = new THREE11.MeshBasicMaterial({ color: 65280, wireframe: true, transparent: true, opacity: 0.3 });
4644
+ const mesh = new THREE11.Mesh(geometry, mat);
4853
4645
  mesh.userData.geomId = i;
4854
4646
  mesh.userData.bodyId = model.geom_bodyid[i];
4855
4647
  geoms.push(mesh);
@@ -4872,9 +4664,9 @@ function Debug({
4872
4664
  }
4873
4665
  if (maxGeomSize > 0) radius = maxGeomSize * 0.15;
4874
4666
  }
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);
4667
+ const geometry = new THREE11.OctahedronGeometry(radius);
4668
+ const mat = new THREE11.MeshBasicMaterial({ color: 16711935, depthTest: false });
4669
+ const mesh = new THREE11.Mesh(geometry, mat);
4878
4670
  mesh.renderOrder = 999;
4879
4671
  mesh.frustumCulled = false;
4880
4672
  mesh.userData.siteId = i;
@@ -4886,9 +4678,9 @@ function Debug({
4886
4678
  ctx.font = "bold 36px monospace";
4887
4679
  ctx.textAlign = "center";
4888
4680
  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);
4681
+ const tex = new THREE11.CanvasTexture(canvas);
4682
+ const spriteMat = new THREE11.SpriteMaterial({ map: tex, depthTest: false, transparent: true });
4683
+ const sprite = new THREE11.Sprite(spriteMat);
4892
4684
  const labelScale = radius * 15;
4893
4685
  sprite.scale.set(labelScale, labelScale * 0.25, 1);
4894
4686
  sprite.position.y = radius * 2;
@@ -4911,9 +4703,9 @@ function Debug({
4911
4703
  }
4912
4704
  }
4913
4705
  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(),
4706
+ const arrow = new THREE11.ArrowHelper(
4707
+ new THREE11.Vector3(0, 0, 1),
4708
+ new THREE11.Vector3(),
4917
4709
  arrowLen,
4918
4710
  color,
4919
4711
  arrowLen * 0.25,
@@ -4921,7 +4713,7 @@ function Debug({
4921
4713
  );
4922
4714
  arrow.renderOrder = 999;
4923
4715
  arrow.frustumCulled = false;
4924
- arrow.line.material = new THREE12.LineBasicMaterial({ color, depthTest: false });
4716
+ arrow.line.material = new THREE11.LineBasicMaterial({ color, depthTest: false });
4925
4717
  arrow.cone.material.depthTest = false;
4926
4718
  arrow.line.renderOrder = 999;
4927
4719
  arrow.line.frustumCulled = false;
@@ -4934,17 +4726,88 @@ function Debug({
4934
4726
  joints.push(arrow);
4935
4727
  }
4936
4728
  }
4729
+ if (showCameras && model.ncam && model.name_camadr) {
4730
+ for (let i = 0; i < model.ncam; i++) {
4731
+ const group = new THREE11.Group();
4732
+ group.userData.cameraId = i;
4733
+ group.renderOrder = 999;
4734
+ group.frustumCulled = false;
4735
+ const marker = new THREE11.Mesh(
4736
+ new THREE11.BoxGeometry(0.014, 9e-3, 6e-3),
4737
+ new THREE11.MeshBasicMaterial({ color: 3718648, depthTest: false })
4738
+ );
4739
+ marker.renderOrder = 999;
4740
+ marker.frustumCulled = false;
4741
+ group.add(marker);
4742
+ const forward = new THREE11.ArrowHelper(
4743
+ new THREE11.Vector3(0, 0, -1),
4744
+ new THREE11.Vector3(),
4745
+ CAMERA_DEBUG_LENGTH,
4746
+ 3718648,
4747
+ CAMERA_DEBUG_LENGTH * 0.24,
4748
+ CAMERA_DEBUG_LENGTH * 0.11
4749
+ );
4750
+ forward.renderOrder = 999;
4751
+ forward.frustumCulled = false;
4752
+ forward.line.material = new THREE11.LineBasicMaterial({
4753
+ color: 3718648,
4754
+ depthTest: false
4755
+ });
4756
+ forward.cone.material.depthTest = false;
4757
+ group.add(forward);
4758
+ const frustumGeometry = new THREE11.BufferGeometry();
4759
+ frustumGeometry.setAttribute(
4760
+ "position",
4761
+ new THREE11.Float32BufferAttribute(new Float32Array(8 * 2 * 3), 3)
4762
+ );
4763
+ const frustum = new THREE11.LineSegments(
4764
+ frustumGeometry,
4765
+ new THREE11.LineBasicMaterial({
4766
+ color: 3718648,
4767
+ transparent: true,
4768
+ opacity: 0.8,
4769
+ depthTest: false
4770
+ })
4771
+ );
4772
+ frustum.renderOrder = 999;
4773
+ frustum.frustumCulled = false;
4774
+ group.userData.frustum = frustum;
4775
+ group.add(frustum);
4776
+ const canvas = document.createElement("canvas");
4777
+ canvas.width = 256;
4778
+ canvas.height = 64;
4779
+ const ctx = canvas.getContext("2d");
4780
+ ctx.fillStyle = "#38bdf8";
4781
+ ctx.font = "bold 32px monospace";
4782
+ ctx.textAlign = "center";
4783
+ ctx.fillText(getName(model, model.name_camadr[i]), 128, 42);
4784
+ const texture = new THREE11.CanvasTexture(canvas);
4785
+ const sprite = new THREE11.Sprite(
4786
+ new THREE11.SpriteMaterial({
4787
+ map: texture,
4788
+ depthTest: false,
4789
+ transparent: true
4790
+ })
4791
+ );
4792
+ sprite.position.set(0, 0.014, 0.01);
4793
+ sprite.scale.set(0.04, 0.01, 1);
4794
+ sprite.renderOrder = 999;
4795
+ group.userData.label = sprite;
4796
+ group.add(sprite);
4797
+ cameras.push(group);
4798
+ }
4799
+ }
4937
4800
  if (showCOM) {
4938
4801
  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);
4802
+ const geometry = new THREE11.SphereGeometry(5e-3, 6, 6);
4803
+ const mat = new THREE11.MeshBasicMaterial({ color: 16711680 });
4804
+ const mesh = new THREE11.Mesh(geometry, mat);
4942
4805
  mesh.userData.bodyId = i;
4943
4806
  comMarkers.push(mesh);
4944
4807
  }
4945
4808
  }
4946
- return { geoms, sites, joints, comMarkers };
4947
- }, [status, mjModelRef, showGeoms, showSites, showJoints, showCOM]);
4809
+ return { geoms, sites, joints, cameras, comMarkers };
4810
+ }, [status, mjModelRef, showGeoms, showSites, showJoints, showCameras, showCOM]);
4948
4811
  useEffect(() => {
4949
4812
  const group = groupRef.current;
4950
4813
  if (!group || !debugGeometry) return;
@@ -4952,6 +4815,7 @@ function Debug({
4952
4815
  ...debugGeometry.geoms,
4953
4816
  ...debugGeometry.sites,
4954
4817
  ...debugGeometry.joints,
4818
+ ...debugGeometry.cameras,
4955
4819
  ...debugGeometry.comMarkers
4956
4820
  ];
4957
4821
  for (const obj of allObjects) group.add(obj);
@@ -5014,6 +4878,68 @@ function Debug({
5014
4878
  arrow.setDirection(_v3a);
5015
4879
  }
5016
4880
  }
4881
+ const camXpos = data.cam_xpos;
4882
+ const camXmat = data.cam_xmat;
4883
+ if (camXpos && camXmat) {
4884
+ for (const group of debugGeometry.cameras) {
4885
+ const cameraId = group.userData.cameraId;
4886
+ const i3 = cameraId * 3;
4887
+ const i9 = cameraId * 9;
4888
+ group.position.set(
4889
+ camXpos[i3],
4890
+ camXpos[i3 + 1],
4891
+ camXpos[i3 + 2]
4892
+ );
4893
+ _cameraMatrix.set(
4894
+ camXmat[i9],
4895
+ camXmat[i9 + 1],
4896
+ camXmat[i9 + 2],
4897
+ 0,
4898
+ camXmat[i9 + 3],
4899
+ camXmat[i9 + 4],
4900
+ camXmat[i9 + 5],
4901
+ 0,
4902
+ camXmat[i9 + 6],
4903
+ camXmat[i9 + 7],
4904
+ camXmat[i9 + 8],
4905
+ 0,
4906
+ 0,
4907
+ 0,
4908
+ 0,
4909
+ 1
4910
+ );
4911
+ group.quaternion.setFromRotationMatrix(_cameraMatrix);
4912
+ const fovy = model.cam_fovy?.[cameraId] ?? 45;
4913
+ const halfHeight = Math.tan(THREE11.MathUtils.degToRad(fovy) / 2) * CAMERA_DEBUG_FRUSTUM_DEPTH;
4914
+ const halfWidth = halfHeight * 4 / 3;
4915
+ const positions = group.userData.frustum.geometry.attributes.position;
4916
+ const array = positions.array;
4917
+ const points = [
4918
+ [0, 0, 0],
4919
+ [-halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4920
+ [0, 0, 0],
4921
+ [halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4922
+ [0, 0, 0],
4923
+ [halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4924
+ [0, 0, 0],
4925
+ [-halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4926
+ [-halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4927
+ [halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4928
+ [halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4929
+ [halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4930
+ [halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4931
+ [-halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4932
+ [-halfWidth, -halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH],
4933
+ [-halfWidth, halfHeight, -CAMERA_DEBUG_FRUSTUM_DEPTH]
4934
+ ];
4935
+ for (let i = 0; i < points.length; i += 1) {
4936
+ array[i * 3] = points[i][0];
4937
+ array[i * 3 + 1] = points[i][1];
4938
+ array[i * 3 + 2] = points[i][2];
4939
+ }
4940
+ positions.needsUpdate = true;
4941
+ }
4942
+ }
5017
4943
  for (const mesh of debugGeometry.comMarkers) {
5018
4944
  const bid = mesh.userData.bodyId;
5019
4945
  const i3 = bid * 3;
@@ -5029,9 +4955,9 @@ function Debug({
5029
4955
  contactPoolInitRef.current = true;
5030
4956
  const pool = [];
5031
4957
  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(),
4958
+ const arrow = new THREE11.ArrowHelper(
4959
+ new THREE11.Vector3(0, 1, 0),
4960
+ new THREE11.Vector3(),
5035
4961
  0.1,
5036
4962
  16729156,
5037
4963
  0.03,
@@ -5081,14 +5007,24 @@ function Debug({
5081
5007
  }
5082
5008
  });
5083
5009
  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
- ] });
5010
+ return /* @__PURE__ */ jsxs(
5011
+ "group",
5012
+ {
5013
+ ...groupProps,
5014
+ userData: {
5015
+ ...groupProps.userData,
5016
+ [CAPTURE_EXCLUDE_KEY]: true
5017
+ },
5018
+ children: [
5019
+ /* @__PURE__ */ jsx("group", { ref: groupRef }),
5020
+ showContacts && /* @__PURE__ */ jsx("group", { ref: contactGroupRef })
5021
+ ]
5022
+ }
5023
+ );
5088
5024
  }
5089
- var DEFAULT_TENDON_COLOR = new THREE12.Color(0.3, 0.3, 0.8);
5025
+ var DEFAULT_TENDON_COLOR = new THREE11.Color(0.3, 0.3, 0.8);
5090
5026
  var DEFAULT_TENDON_WIDTH = 2e-3;
5091
- new THREE12.Vector3();
5027
+ new THREE11.Vector3();
5092
5028
  function TendonRenderer(props) {
5093
5029
  const { mjModelRef, mjDataRef, status } = useMujocoContext();
5094
5030
  const groupRef = useRef(null);
@@ -5102,7 +5038,7 @@ function TendonRenderer(props) {
5102
5038
  if (!model || !data || !group) return;
5103
5039
  const ntendon = model.ntendon ?? 0;
5104
5040
  if (ntendon === 0) return;
5105
- const material = new THREE12.MeshStandardMaterial({
5041
+ const material = new THREE11.MeshStandardMaterial({
5106
5042
  color: DEFAULT_TENDON_COLOR,
5107
5043
  roughness: 0.6,
5108
5044
  metalness: 0.1
@@ -5117,11 +5053,11 @@ function TendonRenderer(props) {
5117
5053
  curves.push(null);
5118
5054
  continue;
5119
5055
  }
5120
- const points = Array.from({ length: wrapNum }, () => new THREE12.Vector3());
5121
- const curve = new THREE12.CatmullRomCurve3(points, false);
5056
+ const points = Array.from({ length: wrapNum }, () => new THREE11.Vector3());
5057
+ const curve = new THREE11.CatmullRomCurve3(points, false);
5122
5058
  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);
5059
+ const geometry = new THREE11.TubeGeometry(curve, segments, DEFAULT_TENDON_WIDTH, 6, false);
5060
+ const mesh = new THREE11.Mesh(geometry, material);
5125
5061
  mesh.frustumCulled = false;
5126
5062
  group.add(mesh);
5127
5063
  meshes.push(mesh);
@@ -5176,11 +5112,11 @@ function TendonRenderer(props) {
5176
5112
  if (curve.points.length !== validCount) {
5177
5113
  curve.points.length = validCount;
5178
5114
  while (curve.points.length < validCount) {
5179
- curve.points.push(new THREE12.Vector3());
5115
+ curve.points.push(new THREE11.Vector3());
5180
5116
  }
5181
5117
  }
5182
5118
  mesh.geometry.dispose();
5183
- mesh.geometry = new THREE12.TubeGeometry(
5119
+ mesh.geometry = new THREE11.TubeGeometry(
5184
5120
  curve,
5185
5121
  Math.max(validCount * 2, 4),
5186
5122
  DEFAULT_TENDON_WIDTH,
@@ -5207,24 +5143,24 @@ function FlexRenderer(props) {
5207
5143
  const vertAdr = model.flex_vertadr[f];
5208
5144
  const vertNum = model.flex_vertnum[f];
5209
5145
  if (vertNum === 0) continue;
5210
- const geometry = new THREE12.BufferGeometry();
5146
+ const geometry = new THREE11.BufferGeometry();
5211
5147
  const positions = new Float32Array(vertNum * 3);
5212
- geometry.setAttribute("position", new THREE12.BufferAttribute(positions, 3));
5148
+ geometry.setAttribute("position", new THREE11.BufferAttribute(positions, 3));
5213
5149
  geometry.computeVertexNormals();
5214
- let color = new THREE12.Color(0.5, 0.5, 0.5);
5150
+ let color = new THREE11.Color(0.5, 0.5, 0.5);
5215
5151
  if (model.flex_rgba) {
5216
- color = new THREE12.Color(
5152
+ color = new THREE11.Color(
5217
5153
  model.flex_rgba[4 * f],
5218
5154
  model.flex_rgba[4 * f + 1],
5219
5155
  model.flex_rgba[4 * f + 2]
5220
5156
  );
5221
5157
  }
5222
- const material = new THREE12.MeshStandardMaterial({
5158
+ const material = new THREE11.MeshStandardMaterial({
5223
5159
  color,
5224
5160
  roughness: 0.7,
5225
- side: THREE12.DoubleSide
5161
+ side: THREE11.DoubleSide
5226
5162
  });
5227
- const mesh = new THREE12.Mesh(geometry, material);
5163
+ const mesh = new THREE11.Mesh(geometry, material);
5228
5164
  mesh.userData.flexId = f;
5229
5165
  mesh.userData.vertAdr = vertAdr;
5230
5166
  mesh.userData.vertNum = vertNum;
@@ -5260,7 +5196,7 @@ function FlexRenderer(props) {
5260
5196
  return /* @__PURE__ */ jsx("group", { ...props, ref: groupRef });
5261
5197
  }
5262
5198
  var GEOM_TYPE_NAMES2 = ["plane", "hfield", "sphere", "capsule", "ellipsoid", "cylinder", "box", "mesh"];
5263
- var _matrix = new THREE12.Matrix4();
5199
+ var _matrix = new THREE11.Matrix4();
5264
5200
  function getGeomInfo(model, geomId) {
5265
5201
  const size = model.geom_size.subarray(geomId * 3, geomId * 3 + 3);
5266
5202
  const type = model.geom_type[geomId];
@@ -5282,10 +5218,10 @@ function geomSignature(model, geomId) {
5282
5218
  return [type, size, mat, data, rgba].join("|");
5283
5219
  }
5284
5220
  function firstMesh(object) {
5285
- if (object instanceof THREE12.Mesh) return object;
5221
+ if (object instanceof THREE11.Mesh) return object;
5286
5222
  let mesh = null;
5287
5223
  object.traverse((child) => {
5288
- if (!mesh && child instanceof THREE12.Mesh) mesh = child;
5224
+ if (!mesh && child instanceof THREE11.Mesh) mesh = child;
5289
5225
  });
5290
5226
  return mesh;
5291
5227
  }
@@ -5714,12 +5650,12 @@ function useActuators() {
5714
5650
  return actuators;
5715
5651
  }, [status, mjModelRef]);
5716
5652
  }
5717
- var _mat42 = new THREE12.Matrix4();
5653
+ var _mat42 = new THREE11.Matrix4();
5718
5654
  function useSitePosition(siteName) {
5719
5655
  const { mjModelRef, mjDataRef, status } = useMujocoContext();
5720
5656
  const siteIdRef = useRef(-1);
5721
- const positionRef = useRef(new THREE12.Vector3());
5722
- const quaternionRef = useRef(new THREE12.Quaternion());
5657
+ const positionRef = useRef(new THREE11.Vector3());
5658
+ const quaternionRef = useRef(new THREE11.Quaternion());
5723
5659
  useEffect(() => {
5724
5660
  const model = mjModelRef.current;
5725
5661
  if (!model || status !== "ready") {
@@ -5910,10 +5846,10 @@ function useJointState(name) {
5910
5846
  function useBodyState(name) {
5911
5847
  const { mjModelRef, status } = useMujocoContext();
5912
5848
  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());
5849
+ const position = useRef(new THREE11.Vector3());
5850
+ const quaternion = useRef(new THREE11.Quaternion());
5851
+ const linearVelocity = useRef(new THREE11.Vector3());
5852
+ const angularVelocity = useRef(new THREE11.Vector3());
5917
5853
  useEffect(() => {
5918
5854
  const model = mjModelRef.current;
5919
5855
  if (!model || status !== "ready") return;
@@ -6501,7 +6437,7 @@ function useSelectionHighlight(bodyId, options = {}) {
6501
6437
  }
6502
6438
  }
6503
6439
  prevRef.current = [];
6504
- const highlightColor = new THREE12.Color(color);
6440
+ const highlightColor = new THREE11.Color(color);
6505
6441
  for (const mesh of meshes) {
6506
6442
  const mat = mesh.material;
6507
6443
  if (mat.emissive) {
@@ -6528,15 +6464,15 @@ function useSelectionHighlight(bodyId, options = {}) {
6528
6464
  }
6529
6465
  function useCameraAnimation() {
6530
6466
  const { camera } = useThree();
6531
- const orbitTargetRef = useRef(new THREE12.Vector3(0, 0, 0));
6467
+ const orbitTargetRef = useRef(new THREE11.Vector3(0, 0, 0));
6532
6468
  const cameraAnimRef = useRef({
6533
6469
  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(),
6470
+ startPos: new THREE11.Vector3(),
6471
+ endPos: new THREE11.Vector3(),
6472
+ startRot: new THREE11.Quaternion(),
6473
+ endRot: new THREE11.Quaternion(),
6474
+ startTarget: new THREE11.Vector3(),
6475
+ endTarget: new THREE11.Vector3(),
6540
6476
  startTime: 0,
6541
6477
  duration: 0,
6542
6478
  resolve: null
@@ -6608,12 +6544,6 @@ function useCameraAnimation() {
6608
6544
  *
6609
6545
  * useFrameCapture — still-frame capture for canvas-backed MuJoCo/R3F scenes.
6610
6546
  */
6611
- /**
6612
- * @license
6613
- * SPDX-License-Identifier: Apache-2.0
6614
- *
6615
- * Offscreen camera-frame capture for R3F/MuJoCo scenes.
6616
- */
6617
6547
  /**
6618
6548
  * @license
6619
6549
  * SPDX-License-Identifier: Apache-2.0
@@ -6801,6 +6731,6 @@ function useCameraAnimation() {
6801
6731
  * useCameraAnimation — composable camera animation hook.
6802
6732
  */
6803
6733
 
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 };
6734
+ 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, useKeyboardTeleop, useMountedCameraSequenceRecorder, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useSplatCollisionProxyGeoms, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
6805
6735
  //# sourceMappingURL=index.js.map
6806
6736
  //# sourceMappingURL=index.js.map