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/README.md +22 -6
- package/dist/{chunk-VDSEPZYQ.js → chunk-4JHALVB2.js} +397 -4
- package/dist/chunk-4JHALVB2.js.map +1 -0
- package/dist/index.d.ts +26 -4
- package/dist/index.js +497 -431
- package/dist/index.js.map +1 -1
- package/dist/spark.d.ts +27 -3
- package/dist/spark.js +156 -3
- package/dist/spark.js.map +1 -1
- package/dist/{types-BuJ4boaq.d.ts → types-C1rwH74Y.d.ts} +37 -1
- package/package.json +1 -1
- package/src/components/ContactMarkers.tsx +8 -1
- package/src/components/Debug.tsx +154 -3
- package/src/components/DragInteraction.tsx +2 -0
- package/src/components/IkGizmo.tsx +5 -1
- package/src/core/MujocoSimProvider.tsx +5 -5
- package/src/hooks/useIkController.ts +8 -1
- package/src/hooks/useKeyboardIkTarget.ts +170 -0
- package/src/index.ts +5 -0
- package/src/rendering/cameraFrameCapture.ts +259 -28
- package/src/rendering/cameraFrameSource.ts +10 -2
- package/src/spark.tsx +241 -1
- package/src/types.ts +51 -0
- package/dist/chunk-VDSEPZYQ.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { withContacts, getContact } from './chunk-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
125
|
+
var Reflector = class extends THREE11.Mesh {
|
|
126
126
|
isReflector = true;
|
|
127
127
|
camera;
|
|
128
|
-
reflectorPlane = new
|
|
129
|
-
normal = new
|
|
130
|
-
reflectorWorldPosition = new
|
|
131
|
-
cameraWorldPosition = new
|
|
132
|
-
rotationMatrix = new
|
|
133
|
-
lookAtPosition = new
|
|
134
|
-
clipPlane = new
|
|
135
|
-
view = new
|
|
136
|
-
target = new
|
|
137
|
-
q = new
|
|
138
|
-
textureMatrix = new
|
|
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
|
|
145
|
-
const color = options.color !== void 0 ? new
|
|
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
|
|
153
|
+
this.renderTarget = new THREE11.WebGLRenderTarget(textureWidth, textureHeight, {
|
|
154
154
|
samples: multisample,
|
|
155
|
-
type:
|
|
155
|
+
type: THREE11.HalfFloatType
|
|
156
156
|
});
|
|
157
|
-
this.material = new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
316
|
-
geo.setAttribute("position", new
|
|
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
|
|
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
|
|
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
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
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
|
|
1232
|
-
var _currentQuat = new
|
|
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
|
|
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
|
|
2045
|
-
var _projNdc = new
|
|
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
|
|
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
|
|
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
|
|
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 ?
|
|
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 ?
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
3877
|
-
endPos: new
|
|
3878
|
-
startRot: new
|
|
3879
|
-
endRot: new
|
|
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
|
-
{
|
|
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
|
|
4025
|
-
new
|
|
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
|
|
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
|
|
4147
|
-
var _pos = new
|
|
4148
|
-
var _quat = new
|
|
4149
|
-
var _scale = new
|
|
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(
|
|
4202
|
-
|
|
3977
|
+
return /* @__PURE__ */ jsx(
|
|
3978
|
+
"group",
|
|
4203
3979
|
{
|
|
4204
|
-
ref:
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
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
|
|
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(
|
|
4278
|
-
|
|
4279
|
-
|
|
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
|
|
4286
|
-
var _bodyQuat = new
|
|
4287
|
-
var _worldHit = new
|
|
4288
|
-
var _raycaster = new
|
|
4289
|
-
var _mouse = new
|
|
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
|
|
4301
|
-
const grabWorldRef = useRef(new
|
|
4302
|
-
const mouseWorldRef = useRef(new
|
|
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
|
|
4308
|
-
new
|
|
4309
|
-
new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
4806
|
-
new
|
|
4807
|
-
var _quat2 = new
|
|
4808
|
-
var
|
|
4809
|
-
var
|
|
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
|
|
4637
|
+
geometry = new THREE11.SphereGeometry(s[3 * i], 12, 8);
|
|
4839
4638
|
break;
|
|
4840
4639
|
case 3:
|
|
4841
|
-
geometry = new
|
|
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
|
|
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
|
|
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
|
|
4852
|
-
const mesh = new
|
|
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
|
|
4876
|
-
const mat = new
|
|
4877
|
-
const mesh = new
|
|
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
|
|
4890
|
-
const spriteMat = new
|
|
4891
|
-
const sprite = new
|
|
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
|
|
4915
|
-
new
|
|
4916
|
-
new
|
|
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
|
|
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
|
|
4940
|
-
const mat = new
|
|
4941
|
-
const mesh = new
|
|
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
|
|
5033
|
-
new
|
|
5034
|
-
new
|
|
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(
|
|
5085
|
-
|
|
5086
|
-
|
|
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
|
|
5032
|
+
var DEFAULT_TENDON_COLOR = new THREE11.Color(0.3, 0.3, 0.8);
|
|
5090
5033
|
var DEFAULT_TENDON_WIDTH = 2e-3;
|
|
5091
|
-
new
|
|
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
|
|
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
|
|
5121
|
-
const curve = new
|
|
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
|
|
5124
|
-
const mesh = new
|
|
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
|
|
5122
|
+
curve.points.push(new THREE11.Vector3());
|
|
5180
5123
|
}
|
|
5181
5124
|
}
|
|
5182
5125
|
mesh.geometry.dispose();
|
|
5183
|
-
mesh.geometry = new
|
|
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
|
|
5153
|
+
const geometry = new THREE11.BufferGeometry();
|
|
5211
5154
|
const positions = new Float32Array(vertNum * 3);
|
|
5212
|
-
geometry.setAttribute("position", new
|
|
5155
|
+
geometry.setAttribute("position", new THREE11.BufferAttribute(positions, 3));
|
|
5213
5156
|
geometry.computeVertexNormals();
|
|
5214
|
-
let color = new
|
|
5157
|
+
let color = new THREE11.Color(0.5, 0.5, 0.5);
|
|
5215
5158
|
if (model.flex_rgba) {
|
|
5216
|
-
color = new
|
|
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
|
|
5165
|
+
const material = new THREE11.MeshStandardMaterial({
|
|
5223
5166
|
color,
|
|
5224
5167
|
roughness: 0.7,
|
|
5225
|
-
side:
|
|
5168
|
+
side: THREE11.DoubleSide
|
|
5226
5169
|
});
|
|
5227
|
-
const mesh = new
|
|
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
|
|
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
|
|
5228
|
+
if (object instanceof THREE11.Mesh) return object;
|
|
5286
5229
|
let mesh = null;
|
|
5287
5230
|
object.traverse((child) => {
|
|
5288
|
-
if (!mesh && child instanceof
|
|
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
|
|
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
|
|
5722
|
-
const quaternionRef = useRef(new
|
|
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
|
|
5914
|
-
const quaternion = useRef(new
|
|
5915
|
-
const linearVelocity = useRef(new
|
|
5916
|
-
const angularVelocity = useRef(new
|
|
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
|
|
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
|
|
6603
|
+
const orbitTargetRef = useRef(new THREE11.Vector3(0, 0, 0));
|
|
6532
6604
|
const cameraAnimRef = useRef({
|
|
6533
6605
|
active: false,
|
|
6534
|
-
startPos: new
|
|
6535
|
-
endPos: new
|
|
6536
|
-
startRot: new
|
|
6537
|
-
endRot: new
|
|
6538
|
-
startTarget: new
|
|
6539
|
-
endTarget: new
|
|
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,
|
|
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
|