mujoco-react 9.0.0 → 9.2.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 +45 -10
- package/dist/index.d.ts +43 -33
- package/dist/index.js +547 -195
- package/dist/index.js.map +1 -1
- package/dist/spark.d.ts +1 -1
- package/dist/{types-izZlUweI.d.ts → types-S8ggQY2n.d.ts} +103 -1
- package/package.json +1 -1
- package/src/core/MujocoSimProvider.tsx +146 -2
- package/src/core/createController.tsx +6 -2
- package/src/hooks/useCameraFrameCapture.ts +94 -0
- package/src/hooks/useCameraSequenceRecorder.ts +59 -0
- package/src/hooks/useFrameCapture.ts +8 -42
- package/src/index.ts +26 -9
- package/src/rendering/cameraFrameCapture.ts +184 -0
- package/src/types.ts +136 -0
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import defaultMujocoWasmUrl from '@mujoco/mujoco/mujoco.wasm?url';
|
|
|
4
4
|
import { createContext, forwardRef, useEffect, useContext, useState, useRef, useCallback, useMemo, useLayoutEffect } from 'react';
|
|
5
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
import { Canvas, useThree, useFrame } from '@react-three/fiber';
|
|
7
|
-
import * as
|
|
7
|
+
import * as THREE12 from 'three';
|
|
8
8
|
import { PivotControls } from '@react-three/drei';
|
|
9
9
|
|
|
10
10
|
var MujocoContext = createContext({
|
|
@@ -178,16 +178,16 @@ function withContacts(data, read) {
|
|
|
178
178
|
contacts.delete?.();
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
-
var CapsuleGeometry = class extends
|
|
181
|
+
var CapsuleGeometry = class extends THREE12.BufferGeometry {
|
|
182
182
|
parameters;
|
|
183
183
|
constructor(radius = 1, length = 1, capSegments = 4, radialSegments = 8) {
|
|
184
184
|
super();
|
|
185
185
|
this.type = "CapsuleGeometry";
|
|
186
186
|
this.parameters = { radius, length, capSegments, radialSegments };
|
|
187
|
-
const path = new
|
|
187
|
+
const path = new THREE12.Path();
|
|
188
188
|
path.absarc(0, -length / 2, radius, Math.PI * 1.5, 0, false);
|
|
189
189
|
path.absarc(0, length / 2, radius, 0, Math.PI * 0.5, false);
|
|
190
|
-
const latheGeometry = new
|
|
190
|
+
const latheGeometry = new THREE12.LatheGeometry(path.getPoints(capSegments), radialSegments);
|
|
191
191
|
const self = this;
|
|
192
192
|
self.setIndex(latheGeometry.getIndex());
|
|
193
193
|
self.setAttribute("position", latheGeometry.getAttribute("position"));
|
|
@@ -195,27 +195,27 @@ var CapsuleGeometry = class extends THREE11.BufferGeometry {
|
|
|
195
195
|
self.setAttribute("uv", latheGeometry.getAttribute("uv"));
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
|
-
var Reflector = class extends
|
|
198
|
+
var Reflector = class extends THREE12.Mesh {
|
|
199
199
|
isReflector = true;
|
|
200
200
|
camera;
|
|
201
|
-
reflectorPlane = new
|
|
202
|
-
normal = new
|
|
203
|
-
reflectorWorldPosition = new
|
|
204
|
-
cameraWorldPosition = new
|
|
205
|
-
rotationMatrix = new
|
|
206
|
-
lookAtPosition = new
|
|
207
|
-
clipPlane = new
|
|
208
|
-
view = new
|
|
209
|
-
target = new
|
|
210
|
-
q = new
|
|
211
|
-
textureMatrix = new
|
|
201
|
+
reflectorPlane = new THREE12.Plane();
|
|
202
|
+
normal = new THREE12.Vector3();
|
|
203
|
+
reflectorWorldPosition = new THREE12.Vector3();
|
|
204
|
+
cameraWorldPosition = new THREE12.Vector3();
|
|
205
|
+
rotationMatrix = new THREE12.Matrix4();
|
|
206
|
+
lookAtPosition = new THREE12.Vector3(0, 0, -1);
|
|
207
|
+
clipPlane = new THREE12.Vector4();
|
|
208
|
+
view = new THREE12.Vector3();
|
|
209
|
+
target = new THREE12.Vector3();
|
|
210
|
+
q = new THREE12.Vector4();
|
|
211
|
+
textureMatrix = new THREE12.Matrix4();
|
|
212
212
|
virtualCamera;
|
|
213
213
|
renderTarget;
|
|
214
214
|
constructor(geometry, options = {}) {
|
|
215
215
|
super(geometry);
|
|
216
216
|
this.type = "Reflector";
|
|
217
|
-
this.camera = new
|
|
218
|
-
const color = options.color !== void 0 ? new
|
|
217
|
+
this.camera = new THREE12.PerspectiveCamera();
|
|
218
|
+
const color = options.color !== void 0 ? new THREE12.Color(options.color) : new THREE12.Color(8355711);
|
|
219
219
|
const textureWidth = options.textureWidth || 512;
|
|
220
220
|
const textureHeight = options.textureHeight || 512;
|
|
221
221
|
const clipBias = options.clipBias || 0;
|
|
@@ -223,11 +223,11 @@ var Reflector = class extends THREE11.Mesh {
|
|
|
223
223
|
const blendTexture = options.texture || void 0;
|
|
224
224
|
const mixStrength = options.mixStrength !== void 0 ? options.mixStrength : 0.25;
|
|
225
225
|
this.virtualCamera = this.camera;
|
|
226
|
-
this.renderTarget = new
|
|
226
|
+
this.renderTarget = new THREE12.WebGLRenderTarget(textureWidth, textureHeight, {
|
|
227
227
|
samples: multisample,
|
|
228
|
-
type:
|
|
228
|
+
type: THREE12.HalfFloatType
|
|
229
229
|
});
|
|
230
|
-
this.material = new
|
|
230
|
+
this.material = new THREE12.MeshPhysicalMaterial({
|
|
231
231
|
map: blendTexture,
|
|
232
232
|
color,
|
|
233
233
|
roughness: 0.5,
|
|
@@ -353,7 +353,7 @@ var GeomBuilder = class {
|
|
|
353
353
|
const pos = mjModel.geom_pos.subarray(g * 3, g * 3 + 3);
|
|
354
354
|
const quat = mjModel.geom_quat.subarray(g * 4, g * 4 + 4);
|
|
355
355
|
const matId = mjModel.geom_matid[g];
|
|
356
|
-
const color = new
|
|
356
|
+
const color = new THREE12.Color(16777215);
|
|
357
357
|
let opacity = 1;
|
|
358
358
|
if (matId >= 0) {
|
|
359
359
|
const rgba = mjModel.mat_rgba.subarray(matId * 4, matId * 4 + 4);
|
|
@@ -368,16 +368,16 @@ var GeomBuilder = class {
|
|
|
368
368
|
let geo = null;
|
|
369
369
|
const getVal = (v) => v?.value ?? v;
|
|
370
370
|
if (type === getVal(MG.mjGEOM_PLANE)) {
|
|
371
|
-
geo = new
|
|
371
|
+
geo = new THREE12.PlaneGeometry(size[0] * 2 || 5, size[1] * 2 || 5);
|
|
372
372
|
} else if (type === getVal(MG.mjGEOM_SPHERE)) {
|
|
373
|
-
geo = new
|
|
373
|
+
geo = new THREE12.SphereGeometry(size[0], 24, 24);
|
|
374
374
|
} else if (type === getVal(MG.mjGEOM_CAPSULE)) {
|
|
375
375
|
geo = new CapsuleGeometry(size[0], size[1] * 2, 24, 12);
|
|
376
376
|
geo.rotateX(Math.PI / 2);
|
|
377
377
|
} else if (type === getVal(MG.mjGEOM_BOX)) {
|
|
378
|
-
geo = new
|
|
378
|
+
geo = new THREE12.BoxGeometry(size[0] * 2, size[1] * 2, size[2] * 2);
|
|
379
379
|
} else if (type === getVal(MG.mjGEOM_CYLINDER)) {
|
|
380
|
-
geo = new
|
|
380
|
+
geo = new THREE12.CylinderGeometry(size[0], size[0], size[1] * 2, 24);
|
|
381
381
|
geo.rotateX(Math.PI / 2);
|
|
382
382
|
} else if (type === getVal(MG.mjGEOM_MESH)) {
|
|
383
383
|
const mId = mjModel.geom_dataid[g];
|
|
@@ -385,8 +385,8 @@ var GeomBuilder = class {
|
|
|
385
385
|
const vNum = mjModel.mesh_vertnum[mId];
|
|
386
386
|
const fAdr = mjModel.mesh_faceadr[mId];
|
|
387
387
|
const fNum = mjModel.mesh_facenum[mId];
|
|
388
|
-
geo = new
|
|
389
|
-
geo.setAttribute("position", new
|
|
388
|
+
geo = new THREE12.BufferGeometry();
|
|
389
|
+
geo.setAttribute("position", new THREE12.Float32BufferAttribute(mjModel.mesh_vert.subarray(vAdr * 3, (vAdr + vNum) * 3), 3));
|
|
390
390
|
geo.setIndex(Array.from(mjModel.mesh_face.subarray(fAdr * 3, (fAdr + fNum) * 3)));
|
|
391
391
|
geo.computeVertexNormals();
|
|
392
392
|
}
|
|
@@ -401,7 +401,7 @@ var GeomBuilder = class {
|
|
|
401
401
|
mixStrength: 0.25
|
|
402
402
|
});
|
|
403
403
|
} else {
|
|
404
|
-
mesh = new
|
|
404
|
+
mesh = new THREE12.Mesh(geo, new THREE12.MeshStandardMaterial({
|
|
405
405
|
color,
|
|
406
406
|
transparent: opacity < 1,
|
|
407
407
|
opacity,
|
|
@@ -1206,7 +1206,7 @@ function SceneRenderer(props) {
|
|
|
1206
1206
|
}
|
|
1207
1207
|
const refs = [];
|
|
1208
1208
|
for (let i = 0; i < model.nbody; i++) {
|
|
1209
|
-
const bodyGroup = new
|
|
1209
|
+
const bodyGroup = new THREE12.Group();
|
|
1210
1210
|
bodyGroup.userData.bodyID = i;
|
|
1211
1211
|
const bodyName = getName(model, model.name_bodyadr[i]);
|
|
1212
1212
|
if (!hiddenBodiesRef.current.has(bodyName)) {
|
|
@@ -1235,9 +1235,9 @@ function SceneRenderer(props) {
|
|
|
1235
1235
|
const alpha = interpolation.alpha;
|
|
1236
1236
|
const i3 = i * 3;
|
|
1237
1237
|
ref.position.set(
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1238
|
+
THREE12.MathUtils.lerp(interpolation.previousXpos[i3], interpolation.currentXpos[i3], alpha),
|
|
1239
|
+
THREE12.MathUtils.lerp(interpolation.previousXpos[i3 + 1], interpolation.currentXpos[i3 + 1], alpha),
|
|
1240
|
+
THREE12.MathUtils.lerp(interpolation.previousXpos[i3 + 2], interpolation.currentXpos[i3 + 2], alpha)
|
|
1241
1241
|
);
|
|
1242
1242
|
const i4 = i * 4;
|
|
1243
1243
|
_previousQuat.set(
|
|
@@ -1292,8 +1292,234 @@ function SceneRenderer(props) {
|
|
|
1292
1292
|
}
|
|
1293
1293
|
);
|
|
1294
1294
|
}
|
|
1295
|
-
var _previousQuat = new
|
|
1296
|
-
var _currentQuat = new
|
|
1295
|
+
var _previousQuat = new THREE12.Quaternion();
|
|
1296
|
+
var _currentQuat = new THREE12.Quaternion();
|
|
1297
|
+
function isTargetRef(target) {
|
|
1298
|
+
return Boolean(target && typeof target === "object" && "current" in target);
|
|
1299
|
+
}
|
|
1300
|
+
function resolveCanvasTarget(target) {
|
|
1301
|
+
const resolvedTarget = isTargetRef(target) ? target.current : target;
|
|
1302
|
+
if (!resolvedTarget) {
|
|
1303
|
+
throw new Error("No frame capture target is available.");
|
|
1304
|
+
}
|
|
1305
|
+
if (resolvedTarget instanceof HTMLCanvasElement) {
|
|
1306
|
+
return resolvedTarget;
|
|
1307
|
+
}
|
|
1308
|
+
const canvas = resolvedTarget.querySelector("canvas");
|
|
1309
|
+
if (!canvas) {
|
|
1310
|
+
throw new Error("Frame capture target does not contain a canvas.");
|
|
1311
|
+
}
|
|
1312
|
+
return canvas;
|
|
1313
|
+
}
|
|
1314
|
+
function waitForNextAnimationFrame() {
|
|
1315
|
+
return new Promise((resolve) => {
|
|
1316
|
+
requestAnimationFrame(() => resolve());
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
async function captureFrame(options) {
|
|
1320
|
+
const type = options.type ?? "image/png";
|
|
1321
|
+
const canvas = resolveCanvasTarget(options.target);
|
|
1322
|
+
if (options.waitForAnimationFrame ?? true) {
|
|
1323
|
+
await waitForNextAnimationFrame();
|
|
1324
|
+
}
|
|
1325
|
+
return {
|
|
1326
|
+
canvas,
|
|
1327
|
+
dataUrl: canvas.toDataURL(type, options.quality),
|
|
1328
|
+
type
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
async function captureFrameBlob(options) {
|
|
1332
|
+
const type = options.type ?? "image/png";
|
|
1333
|
+
const canvas = resolveCanvasTarget(options.target);
|
|
1334
|
+
if (options.waitForAnimationFrame ?? true) {
|
|
1335
|
+
await waitForNextAnimationFrame();
|
|
1336
|
+
}
|
|
1337
|
+
const blob = await new Promise((resolve, reject) => {
|
|
1338
|
+
canvas.toBlob(
|
|
1339
|
+
(nextBlob) => {
|
|
1340
|
+
if (nextBlob) {
|
|
1341
|
+
resolve(nextBlob);
|
|
1342
|
+
} else {
|
|
1343
|
+
reject(new Error("Canvas frame capture did not produce a Blob."));
|
|
1344
|
+
}
|
|
1345
|
+
},
|
|
1346
|
+
type,
|
|
1347
|
+
options.quality
|
|
1348
|
+
);
|
|
1349
|
+
});
|
|
1350
|
+
return { canvas, blob, type };
|
|
1351
|
+
}
|
|
1352
|
+
function useFrameCapture(defaultOptions = {}) {
|
|
1353
|
+
const [status, setStatus] = useState("idle");
|
|
1354
|
+
const [error, setError] = useState(null);
|
|
1355
|
+
const reset = useCallback(() => {
|
|
1356
|
+
setStatus("idle");
|
|
1357
|
+
setError(null);
|
|
1358
|
+
}, []);
|
|
1359
|
+
const capture = useCallback(
|
|
1360
|
+
async (options = {}) => {
|
|
1361
|
+
setStatus("capturing");
|
|
1362
|
+
setError(null);
|
|
1363
|
+
try {
|
|
1364
|
+
const result = await captureFrame({ ...defaultOptions, ...options });
|
|
1365
|
+
setStatus("captured");
|
|
1366
|
+
return result;
|
|
1367
|
+
} catch (nextError) {
|
|
1368
|
+
const error2 = nextError instanceof Error ? nextError : new Error("Unable to capture the current canvas frame.");
|
|
1369
|
+
setError(error2);
|
|
1370
|
+
setStatus("error");
|
|
1371
|
+
throw error2;
|
|
1372
|
+
}
|
|
1373
|
+
},
|
|
1374
|
+
[defaultOptions]
|
|
1375
|
+
);
|
|
1376
|
+
const captureBlob = useCallback(
|
|
1377
|
+
async (options = {}) => {
|
|
1378
|
+
setStatus("capturing");
|
|
1379
|
+
setError(null);
|
|
1380
|
+
try {
|
|
1381
|
+
const result = await captureFrameBlob({
|
|
1382
|
+
...defaultOptions,
|
|
1383
|
+
...options
|
|
1384
|
+
});
|
|
1385
|
+
setStatus("captured");
|
|
1386
|
+
return result;
|
|
1387
|
+
} catch (nextError) {
|
|
1388
|
+
const error2 = nextError instanceof Error ? nextError : new Error("Unable to capture the current canvas frame.");
|
|
1389
|
+
setError(error2);
|
|
1390
|
+
setStatus("error");
|
|
1391
|
+
throw error2;
|
|
1392
|
+
}
|
|
1393
|
+
},
|
|
1394
|
+
[defaultOptions]
|
|
1395
|
+
);
|
|
1396
|
+
return {
|
|
1397
|
+
status,
|
|
1398
|
+
error,
|
|
1399
|
+
isCapturing: status === "capturing",
|
|
1400
|
+
capture,
|
|
1401
|
+
captureBlob,
|
|
1402
|
+
reset
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
function toVector3(value, fallback) {
|
|
1406
|
+
if (!value) return fallback.clone();
|
|
1407
|
+
return value instanceof THREE12.Vector3 ? value.clone() : new THREE12.Vector3(value[0], value[1], value[2]);
|
|
1408
|
+
}
|
|
1409
|
+
function applyCameraPose(camera, options, fallbackCamera) {
|
|
1410
|
+
camera.position.copy(toVector3(options.position, fallbackCamera.position));
|
|
1411
|
+
camera.up.copy(toVector3(options.up, fallbackCamera.up));
|
|
1412
|
+
if (options.quaternion) {
|
|
1413
|
+
if (options.quaternion instanceof THREE12.Quaternion) {
|
|
1414
|
+
camera.quaternion.copy(options.quaternion);
|
|
1415
|
+
} else {
|
|
1416
|
+
camera.quaternion.set(
|
|
1417
|
+
options.quaternion[0],
|
|
1418
|
+
options.quaternion[1],
|
|
1419
|
+
options.quaternion[2],
|
|
1420
|
+
options.quaternion[3]
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
} else if (options.lookAt) {
|
|
1424
|
+
camera.lookAt(toVector3(options.lookAt, new THREE12.Vector3()));
|
|
1425
|
+
} else {
|
|
1426
|
+
camera.quaternion.copy(fallbackCamera.quaternion);
|
|
1427
|
+
}
|
|
1428
|
+
camera.updateMatrixWorld();
|
|
1429
|
+
}
|
|
1430
|
+
function createCaptureCamera(options, fallbackCamera, width, height) {
|
|
1431
|
+
const camera = options.camera ? options.camera.clone() : fallbackCamera instanceof THREE12.PerspectiveCamera ? fallbackCamera.clone() : new THREE12.PerspectiveCamera(45, width / height, 0.01, 100);
|
|
1432
|
+
if (camera instanceof THREE12.PerspectiveCamera) {
|
|
1433
|
+
camera.aspect = width / height;
|
|
1434
|
+
camera.fov = options.fov ?? camera.fov;
|
|
1435
|
+
camera.near = options.near ?? camera.near;
|
|
1436
|
+
camera.far = options.far ?? camera.far;
|
|
1437
|
+
camera.updateProjectionMatrix();
|
|
1438
|
+
}
|
|
1439
|
+
applyCameraPose(camera, options, fallbackCamera);
|
|
1440
|
+
return camera;
|
|
1441
|
+
}
|
|
1442
|
+
function readRenderTargetToCanvas(renderer, target, width, height) {
|
|
1443
|
+
const pixels = new Uint8Array(width * height * 4);
|
|
1444
|
+
renderer.readRenderTargetPixels(target, 0, 0, width, height, pixels);
|
|
1445
|
+
const canvas = document.createElement("canvas");
|
|
1446
|
+
canvas.width = width;
|
|
1447
|
+
canvas.height = height;
|
|
1448
|
+
const context = canvas.getContext("2d");
|
|
1449
|
+
if (!context) {
|
|
1450
|
+
throw new Error("Unable to create a 2D canvas for camera frame capture.");
|
|
1451
|
+
}
|
|
1452
|
+
const imageData = context.createImageData(width, height);
|
|
1453
|
+
const rowBytes = width * 4;
|
|
1454
|
+
for (let y = 0; y < height; y += 1) {
|
|
1455
|
+
const sourceStart = (height - y - 1) * rowBytes;
|
|
1456
|
+
const targetStart = y * rowBytes;
|
|
1457
|
+
imageData.data.set(
|
|
1458
|
+
pixels.subarray(sourceStart, sourceStart + rowBytes),
|
|
1459
|
+
targetStart
|
|
1460
|
+
);
|
|
1461
|
+
}
|
|
1462
|
+
context.putImageData(imageData, 0, 0);
|
|
1463
|
+
return canvas;
|
|
1464
|
+
}
|
|
1465
|
+
function renderCameraFrameToCanvas(renderer, scene, fallbackCamera, options = {}) {
|
|
1466
|
+
const width = Math.max(1, Math.floor(options.width ?? renderer.domElement.width));
|
|
1467
|
+
const height = Math.max(1, Math.floor(options.height ?? renderer.domElement.height));
|
|
1468
|
+
const camera = createCaptureCamera(options, fallbackCamera, width, height);
|
|
1469
|
+
const target = new THREE12.WebGLRenderTarget(width, height, {
|
|
1470
|
+
format: THREE12.RGBAFormat,
|
|
1471
|
+
type: THREE12.UnsignedByteType
|
|
1472
|
+
});
|
|
1473
|
+
const previousTarget = renderer.getRenderTarget();
|
|
1474
|
+
const previousXrEnabled = renderer.xr.enabled;
|
|
1475
|
+
scene.updateMatrixWorld(true);
|
|
1476
|
+
try {
|
|
1477
|
+
renderer.xr.enabled = false;
|
|
1478
|
+
renderer.setRenderTarget(target);
|
|
1479
|
+
renderer.clear();
|
|
1480
|
+
renderer.render(scene, camera);
|
|
1481
|
+
const canvas = readRenderTargetToCanvas(renderer, target, width, height);
|
|
1482
|
+
return { canvas, camera, width, height };
|
|
1483
|
+
} finally {
|
|
1484
|
+
renderer.setRenderTarget(previousTarget);
|
|
1485
|
+
renderer.xr.enabled = previousXrEnabled;
|
|
1486
|
+
target.dispose();
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
async function captureCameraFrame(renderer, scene, fallbackCamera, options = {}) {
|
|
1490
|
+
const type = options.type ?? "image/png";
|
|
1491
|
+
const result = renderCameraFrameToCanvas(
|
|
1492
|
+
renderer,
|
|
1493
|
+
scene,
|
|
1494
|
+
fallbackCamera,
|
|
1495
|
+
options
|
|
1496
|
+
);
|
|
1497
|
+
return {
|
|
1498
|
+
...result,
|
|
1499
|
+
dataUrl: result.canvas.toDataURL(type, options.quality),
|
|
1500
|
+
type
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
async function captureCameraFrameBlob(renderer, scene, fallbackCamera, options = {}) {
|
|
1504
|
+
const type = options.type ?? "image/png";
|
|
1505
|
+
const result = renderCameraFrameToCanvas(
|
|
1506
|
+
renderer,
|
|
1507
|
+
scene,
|
|
1508
|
+
fallbackCamera,
|
|
1509
|
+
options
|
|
1510
|
+
);
|
|
1511
|
+
const blob = await new Promise((resolve, reject) => {
|
|
1512
|
+
result.canvas.toBlob(
|
|
1513
|
+
(nextBlob) => {
|
|
1514
|
+
if (nextBlob) resolve(nextBlob);
|
|
1515
|
+
else reject(new Error("Camera frame capture did not produce a Blob."));
|
|
1516
|
+
},
|
|
1517
|
+
type,
|
|
1518
|
+
options.quality
|
|
1519
|
+
);
|
|
1520
|
+
});
|
|
1521
|
+
return { ...result, blob, type };
|
|
1522
|
+
}
|
|
1297
1523
|
var JOINT_TYPE_NAMES2 = ["free", "ball", "slide", "hinge"];
|
|
1298
1524
|
var GEOM_TYPE_NAMES = ["plane", "hfield", "sphere", "capsule", "ellipsoid", "cylinder", "box", "mesh"];
|
|
1299
1525
|
var SENSOR_TYPE_NAMES = {
|
|
@@ -1369,8 +1595,13 @@ var _applyPoint = new Float64Array(3);
|
|
|
1369
1595
|
var _rayPnt = new Float64Array(3);
|
|
1370
1596
|
var _rayVec = new Float64Array(3);
|
|
1371
1597
|
var _rayGeomId = new Int32Array(1);
|
|
1372
|
-
var _projRaycaster = new
|
|
1373
|
-
var _projNdc = new
|
|
1598
|
+
var _projRaycaster = new THREE12.Raycaster();
|
|
1599
|
+
var _projNdc = new THREE12.Vector2();
|
|
1600
|
+
function waitForNextAnimationFrame2() {
|
|
1601
|
+
return new Promise((resolve) => {
|
|
1602
|
+
requestAnimationFrame(() => resolve());
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1374
1605
|
var MujocoSimContext = createContext(null);
|
|
1375
1606
|
function useMujocoContext() {
|
|
1376
1607
|
const ctx = useContext(MujocoSimContext);
|
|
@@ -1455,7 +1686,7 @@ function MujocoSimProvider({
|
|
|
1455
1686
|
interpolate,
|
|
1456
1687
|
children
|
|
1457
1688
|
}) {
|
|
1458
|
-
const { gl, camera } = useThree();
|
|
1689
|
+
const { gl, camera, scene } = useThree();
|
|
1459
1690
|
const [status, setStatus] = useState("loading");
|
|
1460
1691
|
const mjModelRef = useRef(null);
|
|
1461
1692
|
const mjDataRef = useRef(null);
|
|
@@ -1704,6 +1935,27 @@ function MujocoSimProvider({
|
|
|
1704
1935
|
const step = useCallback((n = 1) => {
|
|
1705
1936
|
stepsToRunRef.current = n;
|
|
1706
1937
|
}, []);
|
|
1938
|
+
const stepImmediately = useCallback((steps = 1) => {
|
|
1939
|
+
const model = mjModelRef.current;
|
|
1940
|
+
const data = mjDataRef.current;
|
|
1941
|
+
if (!model || !data) return false;
|
|
1942
|
+
for (let stepIndex = 0; stepIndex < steps; stepIndex += 1) {
|
|
1943
|
+
for (let i = 0; i < model.nv; i += 1) {
|
|
1944
|
+
data.qfrc_applied[i] = 0;
|
|
1945
|
+
}
|
|
1946
|
+
for (const cb of beforeStepCallbacks.current) {
|
|
1947
|
+
cb({ model, data });
|
|
1948
|
+
}
|
|
1949
|
+
mujoco.mj_step(model, data);
|
|
1950
|
+
for (const cb of afterStepCallbacks.current) {
|
|
1951
|
+
cb({ model, data });
|
|
1952
|
+
}
|
|
1953
|
+
onStepRef.current?.({ time: data.time, model, data });
|
|
1954
|
+
}
|
|
1955
|
+
physicsAccumulatorRef.current = 0;
|
|
1956
|
+
interpolationStateRef.current.valid = false;
|
|
1957
|
+
return true;
|
|
1958
|
+
}, [mujoco]);
|
|
1707
1959
|
const getTime = useCallback(() => {
|
|
1708
1960
|
return mjDataRef.current?.time ?? 0;
|
|
1709
1961
|
}, []);
|
|
@@ -2014,7 +2266,7 @@ function MujocoSimProvider({
|
|
|
2014
2266
|
const geomId = _rayGeomId[0];
|
|
2015
2267
|
const bodyId = geomId >= 0 ? model.geom_bodyid[geomId] : -1;
|
|
2016
2268
|
return {
|
|
2017
|
-
point: new
|
|
2269
|
+
point: new THREE12.Vector3(
|
|
2018
2270
|
origin.x + dir.x * dist,
|
|
2019
2271
|
origin.y + dir.y * dist,
|
|
2020
2272
|
origin.z + dir.z * dist
|
|
@@ -2145,6 +2397,85 @@ function MujocoSimProvider({
|
|
|
2145
2397
|
},
|
|
2146
2398
|
[gl]
|
|
2147
2399
|
);
|
|
2400
|
+
const getCanvas = useCallback(() => {
|
|
2401
|
+
return gl.domElement ?? null;
|
|
2402
|
+
}, [gl]);
|
|
2403
|
+
const captureFrameApi = useCallback(
|
|
2404
|
+
(options = {}) => {
|
|
2405
|
+
return captureFrame({ ...options, target: gl.domElement });
|
|
2406
|
+
},
|
|
2407
|
+
[gl]
|
|
2408
|
+
);
|
|
2409
|
+
const captureFrameBlobApi = useCallback(
|
|
2410
|
+
(options = {}) => {
|
|
2411
|
+
return captureFrameBlob({ ...options, target: gl.domElement });
|
|
2412
|
+
},
|
|
2413
|
+
[gl]
|
|
2414
|
+
);
|
|
2415
|
+
const captureCameraFrameApi = useCallback(
|
|
2416
|
+
(options = {}) => {
|
|
2417
|
+
return captureCameraFrame(gl, scene, camera, options);
|
|
2418
|
+
},
|
|
2419
|
+
[camera, gl, scene]
|
|
2420
|
+
);
|
|
2421
|
+
const captureCameraFrameBlobApi = useCallback(
|
|
2422
|
+
(options = {}) => {
|
|
2423
|
+
return captureCameraFrameBlob(gl, scene, camera, options);
|
|
2424
|
+
},
|
|
2425
|
+
[camera, gl, scene]
|
|
2426
|
+
);
|
|
2427
|
+
const recordCameraSequenceApi = useCallback(
|
|
2428
|
+
async (options) => {
|
|
2429
|
+
const frameCount = Math.max(0, Math.floor(options.frames));
|
|
2430
|
+
const stepsPerFrame = Math.max(1, Math.floor(options.stepsPerFrame ?? 1));
|
|
2431
|
+
const cameras = options.cameras;
|
|
2432
|
+
const frames = [];
|
|
2433
|
+
const wasPaused = pausedRef.current;
|
|
2434
|
+
if (frameCount === 0 || cameras.length === 0) {
|
|
2435
|
+
return {
|
|
2436
|
+
frames,
|
|
2437
|
+
cameraKeys: cameras.map((sequenceCamera) => sequenceCamera.key),
|
|
2438
|
+
frameCount: 0
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
try {
|
|
2442
|
+
pausedRef.current = true;
|
|
2443
|
+
stepsToRunRef.current = 0;
|
|
2444
|
+
if (options.reset) reset();
|
|
2445
|
+
for (let frameIndex = 0; frameIndex < frameCount; frameIndex += 1) {
|
|
2446
|
+
if (frameIndex > 0 || options.captureInitialFrame === false) {
|
|
2447
|
+
stepImmediately(stepsPerFrame);
|
|
2448
|
+
}
|
|
2449
|
+
await waitForNextAnimationFrame2();
|
|
2450
|
+
const cameraFrames = {};
|
|
2451
|
+
for (const sequenceCamera of cameras) {
|
|
2452
|
+
const { key, ...captureOptions } = sequenceCamera;
|
|
2453
|
+
cameraFrames[key] = await captureCameraFrame(
|
|
2454
|
+
gl,
|
|
2455
|
+
scene,
|
|
2456
|
+
camera,
|
|
2457
|
+
captureOptions
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
const frame = {
|
|
2461
|
+
frameIndex,
|
|
2462
|
+
time: getTime(),
|
|
2463
|
+
cameras: cameraFrames
|
|
2464
|
+
};
|
|
2465
|
+
frames.push(frame);
|
|
2466
|
+
await options.onFrame?.(frame);
|
|
2467
|
+
}
|
|
2468
|
+
} finally {
|
|
2469
|
+
pausedRef.current = wasPaused;
|
|
2470
|
+
}
|
|
2471
|
+
return {
|
|
2472
|
+
frames,
|
|
2473
|
+
cameraKeys: cameras.map((sequenceCamera) => sequenceCamera.key),
|
|
2474
|
+
frameCount: frames.length
|
|
2475
|
+
};
|
|
2476
|
+
},
|
|
2477
|
+
[camera, getTime, gl, reset, scene, stepImmediately]
|
|
2478
|
+
);
|
|
2148
2479
|
const project2DTo3D = useCallback(
|
|
2149
2480
|
(x, y, cameraPos, lookAt) => {
|
|
2150
2481
|
const virtCam = camera.clone();
|
|
@@ -2155,9 +2486,9 @@ function MujocoSimProvider({
|
|
|
2155
2486
|
_projNdc.set(x * 2 - 1, -(y * 2 - 1));
|
|
2156
2487
|
_projRaycaster.setFromCamera(_projNdc, virtCam);
|
|
2157
2488
|
const objects = [];
|
|
2158
|
-
const
|
|
2159
|
-
if (
|
|
2160
|
-
|
|
2489
|
+
const scene2 = camera.parent;
|
|
2490
|
+
if (scene2) {
|
|
2491
|
+
scene2.traverse((c) => {
|
|
2161
2492
|
if (c.isMesh) objects.push(c);
|
|
2162
2493
|
});
|
|
2163
2494
|
}
|
|
@@ -2251,7 +2582,13 @@ function MujocoSimProvider({
|
|
|
2251
2582
|
addBody: addBodyApi,
|
|
2252
2583
|
removeBody: removeBodyApi,
|
|
2253
2584
|
recompile: recompileApi,
|
|
2585
|
+
getCanvas,
|
|
2254
2586
|
getCanvasSnapshot,
|
|
2587
|
+
captureFrame: captureFrameApi,
|
|
2588
|
+
captureFrameBlob: captureFrameBlobApi,
|
|
2589
|
+
captureCameraFrame: captureCameraFrameApi,
|
|
2590
|
+
captureCameraFrameBlob: captureCameraFrameBlobApi,
|
|
2591
|
+
recordCameraSequence: recordCameraSequenceApi,
|
|
2255
2592
|
project2DTo3D,
|
|
2256
2593
|
setBodyMass,
|
|
2257
2594
|
setGeomFriction,
|
|
@@ -2303,7 +2640,13 @@ function MujocoSimProvider({
|
|
|
2303
2640
|
addBodyApi,
|
|
2304
2641
|
removeBodyApi,
|
|
2305
2642
|
recompileApi,
|
|
2643
|
+
getCanvas,
|
|
2306
2644
|
getCanvasSnapshot,
|
|
2645
|
+
captureFrameApi,
|
|
2646
|
+
captureFrameBlobApi,
|
|
2647
|
+
captureCameraFrameApi,
|
|
2648
|
+
captureCameraFrameBlobApi,
|
|
2649
|
+
recordCameraSequenceApi,
|
|
2307
2650
|
project2DTo3D,
|
|
2308
2651
|
setBodyMass,
|
|
2309
2652
|
setGeomFriction,
|
|
@@ -2770,7 +3113,7 @@ function solve6x6(A, b, x) {
|
|
|
2770
3113
|
}
|
|
2771
3114
|
|
|
2772
3115
|
// src/hooks/useIkController.ts
|
|
2773
|
-
var _syncMat4 = new
|
|
3116
|
+
var _syncMat4 = new THREE12.Matrix4();
|
|
2774
3117
|
function syncGizmoToSite(data, siteId, target) {
|
|
2775
3118
|
if (siteId === -1) return;
|
|
2776
3119
|
const sitePos = data.site_xpos.subarray(siteId * 3, siteId * 3 + 3);
|
|
@@ -2802,7 +3145,7 @@ var useIkController = createControllerHook(
|
|
|
2802
3145
|
const { mjModelRef, mjDataRef, mujocoRef, resetCallbacks, status } = useMujocoContext();
|
|
2803
3146
|
const ikEnabledRef = useRef(false);
|
|
2804
3147
|
const ikCalculatingRef = useRef(false);
|
|
2805
|
-
const ikTargetRef = useRef(new
|
|
3148
|
+
const ikTargetRef = useRef(new THREE12.Group());
|
|
2806
3149
|
const siteIdRef = useRef(-1);
|
|
2807
3150
|
const controlGroupRef = useRef(null);
|
|
2808
3151
|
const genericIkRef = useRef(new GenericIK(mujocoRef.current));
|
|
@@ -2810,10 +3153,10 @@ var useIkController = createControllerHook(
|
|
|
2810
3153
|
const needsInitialSync = useRef(true);
|
|
2811
3154
|
const gizmoAnimRef = useRef({
|
|
2812
3155
|
active: false,
|
|
2813
|
-
startPos: new
|
|
2814
|
-
endPos: new
|
|
2815
|
-
startRot: new
|
|
2816
|
-
endRot: new
|
|
3156
|
+
startPos: new THREE12.Vector3(),
|
|
3157
|
+
endPos: new THREE12.Vector3(),
|
|
3158
|
+
startRot: new THREE12.Quaternion(),
|
|
3159
|
+
endRot: new THREE12.Quaternion(),
|
|
2817
3160
|
startTime: 0,
|
|
2818
3161
|
duration: 1e3
|
|
2819
3162
|
});
|
|
@@ -2958,8 +3301,8 @@ var useIkController = createControllerHook(
|
|
|
2958
3301
|
const target = ikTargetRef.current;
|
|
2959
3302
|
if (!target) return;
|
|
2960
3303
|
const targetPos = pos.clone();
|
|
2961
|
-
const targetRot = new
|
|
2962
|
-
new
|
|
3304
|
+
const targetRot = new THREE12.Quaternion().setFromEuler(
|
|
3305
|
+
new THREE12.Euler(Math.PI, 0, 0)
|
|
2963
3306
|
);
|
|
2964
3307
|
if (duration > 0) {
|
|
2965
3308
|
const ga = gizmoAnimRef.current;
|
|
@@ -2984,7 +3327,7 @@ var useIkController = createControllerHook(
|
|
|
2984
3327
|
if (!ikCalculatingRef.current || !target) return null;
|
|
2985
3328
|
return {
|
|
2986
3329
|
pos: target.position.clone(),
|
|
2987
|
-
rot: new
|
|
3330
|
+
rot: new THREE12.Euler().setFromQuaternion(target.quaternion)
|
|
2988
3331
|
};
|
|
2989
3332
|
},
|
|
2990
3333
|
[]
|
|
@@ -3080,10 +3423,10 @@ function Body({
|
|
|
3080
3423
|
if (!hasChildren) return null;
|
|
3081
3424
|
return /* @__PURE__ */ jsx("group", { ref: groupRef, children });
|
|
3082
3425
|
}
|
|
3083
|
-
var _mat4 = new
|
|
3084
|
-
var _pos = new
|
|
3085
|
-
var _quat = new
|
|
3086
|
-
var _scale = new
|
|
3426
|
+
var _mat4 = new THREE12.Matrix4();
|
|
3427
|
+
var _pos = new THREE12.Vector3();
|
|
3428
|
+
var _quat = new THREE12.Quaternion();
|
|
3429
|
+
var _scale = new THREE12.Vector3(1, 1, 1);
|
|
3087
3430
|
function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
|
|
3088
3431
|
const { mjModelRef, mjDataRef, status } = useMujocoContext();
|
|
3089
3432
|
const { ikTargetRef, siteIdRef, ikEnabledRef, setIkEnabled } = controller;
|
|
@@ -3175,7 +3518,7 @@ function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
|
|
|
3175
3518
|
}
|
|
3176
3519
|
) });
|
|
3177
3520
|
}
|
|
3178
|
-
var _dummy = new
|
|
3521
|
+
var _dummy = new THREE12.Object3D();
|
|
3179
3522
|
function ContactMarkers({
|
|
3180
3523
|
maxContacts = 100,
|
|
3181
3524
|
radius = 8e-3,
|
|
@@ -3219,11 +3562,11 @@ function ContactMarkers({
|
|
|
3219
3562
|
var _force = new Float64Array(3);
|
|
3220
3563
|
var _torque = new Float64Array(3);
|
|
3221
3564
|
var _point = new Float64Array(3);
|
|
3222
|
-
var _bodyPos = new
|
|
3223
|
-
var _bodyQuat = new
|
|
3224
|
-
var _worldHit = new
|
|
3225
|
-
var _raycaster = new
|
|
3226
|
-
var _mouse = new
|
|
3565
|
+
var _bodyPos = new THREE12.Vector3();
|
|
3566
|
+
var _bodyQuat = new THREE12.Quaternion();
|
|
3567
|
+
var _worldHit = new THREE12.Vector3();
|
|
3568
|
+
var _raycaster = new THREE12.Raycaster();
|
|
3569
|
+
var _mouse = new THREE12.Vector2();
|
|
3227
3570
|
function DragInteraction({
|
|
3228
3571
|
stiffness = 250,
|
|
3229
3572
|
showArrow = true,
|
|
@@ -3234,16 +3577,16 @@ function DragInteraction({
|
|
|
3234
3577
|
const draggingRef = useRef(false);
|
|
3235
3578
|
const bodyIdRef = useRef(-1);
|
|
3236
3579
|
const grabDistanceRef = useRef(0);
|
|
3237
|
-
const localHitRef = useRef(new
|
|
3238
|
-
const grabWorldRef = useRef(new
|
|
3239
|
-
const mouseWorldRef = useRef(new
|
|
3580
|
+
const localHitRef = useRef(new THREE12.Vector3());
|
|
3581
|
+
const grabWorldRef = useRef(new THREE12.Vector3());
|
|
3582
|
+
const mouseWorldRef = useRef(new THREE12.Vector3());
|
|
3240
3583
|
const arrowRef = useRef(null);
|
|
3241
3584
|
const groupRef = useRef(null);
|
|
3242
3585
|
useEffect(() => {
|
|
3243
3586
|
if (!showArrow || !groupRef.current) return;
|
|
3244
|
-
const arrow = new
|
|
3245
|
-
new
|
|
3246
|
-
new
|
|
3587
|
+
const arrow = new THREE12.ArrowHelper(
|
|
3588
|
+
new THREE12.Vector3(0, 1, 0),
|
|
3589
|
+
new THREE12.Vector3(),
|
|
3247
3590
|
0.1,
|
|
3248
3591
|
16729156
|
|
3249
3592
|
);
|
|
@@ -3425,7 +3768,7 @@ function useSceneLights(intensity = 1) {
|
|
|
3425
3768
|
const dr = lightDiffuse ? lightDiffuse[3 * i] : 1;
|
|
3426
3769
|
const dg = lightDiffuse ? lightDiffuse[3 * i + 1] : 1;
|
|
3427
3770
|
const db = lightDiffuse ? lightDiffuse[3 * i + 2] : 1;
|
|
3428
|
-
const color = new
|
|
3771
|
+
const color = new THREE12.Color(dr, dg, db);
|
|
3429
3772
|
const px = lightPos[3 * i];
|
|
3430
3773
|
const py = lightPos[3 * i + 1];
|
|
3431
3774
|
const pz = lightPos[3 * i + 2];
|
|
@@ -3433,7 +3776,7 @@ function useSceneLights(intensity = 1) {
|
|
|
3433
3776
|
const dy = lightDir[3 * i + 1];
|
|
3434
3777
|
const dz = lightDir[3 * i + 2];
|
|
3435
3778
|
if (isDirectional) {
|
|
3436
|
-
const light = new
|
|
3779
|
+
const light = new THREE12.DirectionalLight(color, finalIntensity);
|
|
3437
3780
|
light.position.set(px, py, pz);
|
|
3438
3781
|
light.target.position.set(px + dx, py + dy, pz + dz);
|
|
3439
3782
|
light.castShadow = castShadow;
|
|
@@ -3456,7 +3799,7 @@ function useSceneLights(intensity = 1) {
|
|
|
3456
3799
|
const cutoff = lightCutoff ? lightCutoff[i] : 45;
|
|
3457
3800
|
const exponent = lightExponent ? lightExponent[i] : 10;
|
|
3458
3801
|
const angle = cutoff * Math.PI / 180;
|
|
3459
|
-
const light = new
|
|
3802
|
+
const light = new THREE12.SpotLight(color, finalIntensity, 0, angle, exponent / 128);
|
|
3460
3803
|
light.position.set(px, py, pz);
|
|
3461
3804
|
light.target.position.set(px + dx, py + dy, pz + dz);
|
|
3462
3805
|
light.castShadow = castShadow;
|
|
@@ -3514,11 +3857,11 @@ var JOINT_COLORS = {
|
|
|
3514
3857
|
3: 16776960
|
|
3515
3858
|
// hinge - yellow
|
|
3516
3859
|
};
|
|
3517
|
-
var _v3a = new
|
|
3518
|
-
new
|
|
3519
|
-
var _quat2 = new
|
|
3520
|
-
var _contactPos = new
|
|
3521
|
-
var _contactNormal = new
|
|
3860
|
+
var _v3a = new THREE12.Vector3();
|
|
3861
|
+
new THREE12.Vector3();
|
|
3862
|
+
var _quat2 = new THREE12.Quaternion();
|
|
3863
|
+
var _contactPos = new THREE12.Vector3();
|
|
3864
|
+
var _contactNormal = new THREE12.Vector3();
|
|
3522
3865
|
var MAX_CONTACT_ARROWS = 50;
|
|
3523
3866
|
function Debug({
|
|
3524
3867
|
showGeoms = false,
|
|
@@ -3547,21 +3890,21 @@ function Debug({
|
|
|
3547
3890
|
let geometry = null;
|
|
3548
3891
|
switch (type) {
|
|
3549
3892
|
case 2:
|
|
3550
|
-
geometry = new
|
|
3893
|
+
geometry = new THREE12.SphereGeometry(s[3 * i], 12, 8);
|
|
3551
3894
|
break;
|
|
3552
3895
|
case 3:
|
|
3553
|
-
geometry = new
|
|
3896
|
+
geometry = new THREE12.CapsuleGeometry(s[3 * i], s[3 * i + 1] * 2, 6, 8);
|
|
3554
3897
|
break;
|
|
3555
3898
|
case 5:
|
|
3556
|
-
geometry = new
|
|
3899
|
+
geometry = new THREE12.CylinderGeometry(s[3 * i], s[3 * i], s[3 * i + 1] * 2, 12);
|
|
3557
3900
|
break;
|
|
3558
3901
|
case 6:
|
|
3559
|
-
geometry = new
|
|
3902
|
+
geometry = new THREE12.BoxGeometry(s[3 * i] * 2, s[3 * i + 1] * 2, s[3 * i + 2] * 2);
|
|
3560
3903
|
break;
|
|
3561
3904
|
}
|
|
3562
3905
|
if (geometry) {
|
|
3563
|
-
const mat = new
|
|
3564
|
-
const mesh = new
|
|
3906
|
+
const mat = new THREE12.MeshBasicMaterial({ color: 65280, wireframe: true, transparent: true, opacity: 0.3 });
|
|
3907
|
+
const mesh = new THREE12.Mesh(geometry, mat);
|
|
3565
3908
|
mesh.userData.geomId = i;
|
|
3566
3909
|
mesh.userData.bodyId = model.geom_bodyid[i];
|
|
3567
3910
|
geoms.push(mesh);
|
|
@@ -3584,9 +3927,9 @@ function Debug({
|
|
|
3584
3927
|
}
|
|
3585
3928
|
if (maxGeomSize > 0) radius = maxGeomSize * 0.15;
|
|
3586
3929
|
}
|
|
3587
|
-
const geometry = new
|
|
3588
|
-
const mat = new
|
|
3589
|
-
const mesh = new
|
|
3930
|
+
const geometry = new THREE12.OctahedronGeometry(radius);
|
|
3931
|
+
const mat = new THREE12.MeshBasicMaterial({ color: 16711935, depthTest: false });
|
|
3932
|
+
const mesh = new THREE12.Mesh(geometry, mat);
|
|
3590
3933
|
mesh.renderOrder = 999;
|
|
3591
3934
|
mesh.frustumCulled = false;
|
|
3592
3935
|
mesh.userData.siteId = i;
|
|
@@ -3598,9 +3941,9 @@ function Debug({
|
|
|
3598
3941
|
ctx.font = "bold 36px monospace";
|
|
3599
3942
|
ctx.textAlign = "center";
|
|
3600
3943
|
ctx.fillText(getName(model, model.name_siteadr[i]), 128, 42);
|
|
3601
|
-
const tex = new
|
|
3602
|
-
const spriteMat = new
|
|
3603
|
-
const sprite = new
|
|
3944
|
+
const tex = new THREE12.CanvasTexture(canvas);
|
|
3945
|
+
const spriteMat = new THREE12.SpriteMaterial({ map: tex, depthTest: false, transparent: true });
|
|
3946
|
+
const sprite = new THREE12.Sprite(spriteMat);
|
|
3604
3947
|
const labelScale = radius * 15;
|
|
3605
3948
|
sprite.scale.set(labelScale, labelScale * 0.25, 1);
|
|
3606
3949
|
sprite.position.y = radius * 2;
|
|
@@ -3623,9 +3966,9 @@ function Debug({
|
|
|
3623
3966
|
}
|
|
3624
3967
|
}
|
|
3625
3968
|
const arrowLen = Math.max(maxGeomSize * 0.8, 0.05);
|
|
3626
|
-
const arrow = new
|
|
3627
|
-
new
|
|
3628
|
-
new
|
|
3969
|
+
const arrow = new THREE12.ArrowHelper(
|
|
3970
|
+
new THREE12.Vector3(0, 0, 1),
|
|
3971
|
+
new THREE12.Vector3(),
|
|
3629
3972
|
arrowLen,
|
|
3630
3973
|
color,
|
|
3631
3974
|
arrowLen * 0.25,
|
|
@@ -3633,7 +3976,7 @@ function Debug({
|
|
|
3633
3976
|
);
|
|
3634
3977
|
arrow.renderOrder = 999;
|
|
3635
3978
|
arrow.frustumCulled = false;
|
|
3636
|
-
arrow.line.material = new
|
|
3979
|
+
arrow.line.material = new THREE12.LineBasicMaterial({ color, depthTest: false });
|
|
3637
3980
|
arrow.cone.material.depthTest = false;
|
|
3638
3981
|
arrow.line.renderOrder = 999;
|
|
3639
3982
|
arrow.line.frustumCulled = false;
|
|
@@ -3648,9 +3991,9 @@ function Debug({
|
|
|
3648
3991
|
}
|
|
3649
3992
|
if (showCOM) {
|
|
3650
3993
|
for (let i = 1; i < model.nbody; i++) {
|
|
3651
|
-
const geometry = new
|
|
3652
|
-
const mat = new
|
|
3653
|
-
const mesh = new
|
|
3994
|
+
const geometry = new THREE12.SphereGeometry(5e-3, 6, 6);
|
|
3995
|
+
const mat = new THREE12.MeshBasicMaterial({ color: 16711680 });
|
|
3996
|
+
const mesh = new THREE12.Mesh(geometry, mat);
|
|
3654
3997
|
mesh.userData.bodyId = i;
|
|
3655
3998
|
comMarkers.push(mesh);
|
|
3656
3999
|
}
|
|
@@ -3741,9 +4084,9 @@ function Debug({
|
|
|
3741
4084
|
contactPoolInitRef.current = true;
|
|
3742
4085
|
const pool = [];
|
|
3743
4086
|
for (let i = 0; i < MAX_CONTACT_ARROWS; i++) {
|
|
3744
|
-
const arrow = new
|
|
3745
|
-
new
|
|
3746
|
-
new
|
|
4087
|
+
const arrow = new THREE12.ArrowHelper(
|
|
4088
|
+
new THREE12.Vector3(0, 1, 0),
|
|
4089
|
+
new THREE12.Vector3(),
|
|
3747
4090
|
0.1,
|
|
3748
4091
|
16729156,
|
|
3749
4092
|
0.03,
|
|
@@ -3798,9 +4141,9 @@ function Debug({
|
|
|
3798
4141
|
showContacts && /* @__PURE__ */ jsx("group", { ref: contactGroupRef })
|
|
3799
4142
|
] });
|
|
3800
4143
|
}
|
|
3801
|
-
var DEFAULT_TENDON_COLOR = new
|
|
4144
|
+
var DEFAULT_TENDON_COLOR = new THREE12.Color(0.3, 0.3, 0.8);
|
|
3802
4145
|
var DEFAULT_TENDON_WIDTH = 2e-3;
|
|
3803
|
-
new
|
|
4146
|
+
new THREE12.Vector3();
|
|
3804
4147
|
function TendonRenderer(props) {
|
|
3805
4148
|
const { mjModelRef, mjDataRef, status } = useMujocoContext();
|
|
3806
4149
|
const groupRef = useRef(null);
|
|
@@ -3814,7 +4157,7 @@ function TendonRenderer(props) {
|
|
|
3814
4157
|
if (!model || !data || !group) return;
|
|
3815
4158
|
const ntendon = model.ntendon ?? 0;
|
|
3816
4159
|
if (ntendon === 0) return;
|
|
3817
|
-
const material = new
|
|
4160
|
+
const material = new THREE12.MeshStandardMaterial({
|
|
3818
4161
|
color: DEFAULT_TENDON_COLOR,
|
|
3819
4162
|
roughness: 0.6,
|
|
3820
4163
|
metalness: 0.1
|
|
@@ -3829,11 +4172,11 @@ function TendonRenderer(props) {
|
|
|
3829
4172
|
curves.push(null);
|
|
3830
4173
|
continue;
|
|
3831
4174
|
}
|
|
3832
|
-
const points = Array.from({ length: wrapNum }, () => new
|
|
3833
|
-
const curve = new
|
|
4175
|
+
const points = Array.from({ length: wrapNum }, () => new THREE12.Vector3());
|
|
4176
|
+
const curve = new THREE12.CatmullRomCurve3(points, false);
|
|
3834
4177
|
const segments = Math.max(wrapNum * 2, 4);
|
|
3835
|
-
const geometry = new
|
|
3836
|
-
const mesh = new
|
|
4178
|
+
const geometry = new THREE12.TubeGeometry(curve, segments, DEFAULT_TENDON_WIDTH, 6, false);
|
|
4179
|
+
const mesh = new THREE12.Mesh(geometry, material);
|
|
3837
4180
|
mesh.frustumCulled = false;
|
|
3838
4181
|
group.add(mesh);
|
|
3839
4182
|
meshes.push(mesh);
|
|
@@ -3888,11 +4231,11 @@ function TendonRenderer(props) {
|
|
|
3888
4231
|
if (curve.points.length !== validCount) {
|
|
3889
4232
|
curve.points.length = validCount;
|
|
3890
4233
|
while (curve.points.length < validCount) {
|
|
3891
|
-
curve.points.push(new
|
|
4234
|
+
curve.points.push(new THREE12.Vector3());
|
|
3892
4235
|
}
|
|
3893
4236
|
}
|
|
3894
4237
|
mesh.geometry.dispose();
|
|
3895
|
-
mesh.geometry = new
|
|
4238
|
+
mesh.geometry = new THREE12.TubeGeometry(
|
|
3896
4239
|
curve,
|
|
3897
4240
|
Math.max(validCount * 2, 4),
|
|
3898
4241
|
DEFAULT_TENDON_WIDTH,
|
|
@@ -3919,24 +4262,24 @@ function FlexRenderer(props) {
|
|
|
3919
4262
|
const vertAdr = model.flex_vertadr[f];
|
|
3920
4263
|
const vertNum = model.flex_vertnum[f];
|
|
3921
4264
|
if (vertNum === 0) continue;
|
|
3922
|
-
const geometry = new
|
|
4265
|
+
const geometry = new THREE12.BufferGeometry();
|
|
3923
4266
|
const positions = new Float32Array(vertNum * 3);
|
|
3924
|
-
geometry.setAttribute("position", new
|
|
4267
|
+
geometry.setAttribute("position", new THREE12.BufferAttribute(positions, 3));
|
|
3925
4268
|
geometry.computeVertexNormals();
|
|
3926
|
-
let color = new
|
|
4269
|
+
let color = new THREE12.Color(0.5, 0.5, 0.5);
|
|
3927
4270
|
if (model.flex_rgba) {
|
|
3928
|
-
color = new
|
|
4271
|
+
color = new THREE12.Color(
|
|
3929
4272
|
model.flex_rgba[4 * f],
|
|
3930
4273
|
model.flex_rgba[4 * f + 1],
|
|
3931
4274
|
model.flex_rgba[4 * f + 2]
|
|
3932
4275
|
);
|
|
3933
4276
|
}
|
|
3934
|
-
const material = new
|
|
4277
|
+
const material = new THREE12.MeshStandardMaterial({
|
|
3935
4278
|
color,
|
|
3936
4279
|
roughness: 0.7,
|
|
3937
|
-
side:
|
|
4280
|
+
side: THREE12.DoubleSide
|
|
3938
4281
|
});
|
|
3939
|
-
const mesh = new
|
|
4282
|
+
const mesh = new THREE12.Mesh(geometry, material);
|
|
3940
4283
|
mesh.userData.flexId = f;
|
|
3941
4284
|
mesh.userData.vertAdr = vertAdr;
|
|
3942
4285
|
mesh.userData.vertNum = vertNum;
|
|
@@ -3972,7 +4315,7 @@ function FlexRenderer(props) {
|
|
|
3972
4315
|
return /* @__PURE__ */ jsx("group", { ...props, ref: groupRef });
|
|
3973
4316
|
}
|
|
3974
4317
|
var GEOM_TYPE_NAMES2 = ["plane", "hfield", "sphere", "capsule", "ellipsoid", "cylinder", "box", "mesh"];
|
|
3975
|
-
var _matrix = new
|
|
4318
|
+
var _matrix = new THREE12.Matrix4();
|
|
3976
4319
|
function getGeomInfo(model, geomId) {
|
|
3977
4320
|
const size = model.geom_size.subarray(geomId * 3, geomId * 3 + 3);
|
|
3978
4321
|
const type = model.geom_type[geomId];
|
|
@@ -3994,10 +4337,10 @@ function geomSignature(model, geomId) {
|
|
|
3994
4337
|
return [type, size, mat, data, rgba].join("|");
|
|
3995
4338
|
}
|
|
3996
4339
|
function firstMesh(object) {
|
|
3997
|
-
if (object instanceof
|
|
4340
|
+
if (object instanceof THREE12.Mesh) return object;
|
|
3998
4341
|
let mesh = null;
|
|
3999
4342
|
object.traverse((child) => {
|
|
4000
|
-
if (!mesh && child instanceof
|
|
4343
|
+
if (!mesh && child instanceof THREE12.Mesh) mesh = child;
|
|
4001
4344
|
});
|
|
4002
4345
|
return mesh;
|
|
4003
4346
|
}
|
|
@@ -4426,12 +4769,12 @@ function useActuators() {
|
|
|
4426
4769
|
return actuators;
|
|
4427
4770
|
}, [status, mjModelRef]);
|
|
4428
4771
|
}
|
|
4429
|
-
var _mat42 = new
|
|
4772
|
+
var _mat42 = new THREE12.Matrix4();
|
|
4430
4773
|
function useSitePosition(siteName) {
|
|
4431
4774
|
const { mjModelRef, mjDataRef, status } = useMujocoContext();
|
|
4432
4775
|
const siteIdRef = useRef(-1);
|
|
4433
|
-
const positionRef = useRef(new
|
|
4434
|
-
const quaternionRef = useRef(new
|
|
4776
|
+
const positionRef = useRef(new THREE12.Vector3());
|
|
4777
|
+
const quaternionRef = useRef(new THREE12.Quaternion());
|
|
4435
4778
|
useEffect(() => {
|
|
4436
4779
|
const model = mjModelRef.current;
|
|
4437
4780
|
if (!model || status !== "ready") {
|
|
@@ -4622,10 +4965,10 @@ function useJointState(name) {
|
|
|
4622
4965
|
function useBodyState(name) {
|
|
4623
4966
|
const { mjModelRef, status } = useMujocoContext();
|
|
4624
4967
|
const bodyIdRef = useRef(-1);
|
|
4625
|
-
const position = useRef(new
|
|
4626
|
-
const quaternion = useRef(new
|
|
4627
|
-
const linearVelocity = useRef(new
|
|
4628
|
-
const angularVelocity = useRef(new
|
|
4968
|
+
const position = useRef(new THREE12.Vector3());
|
|
4969
|
+
const quaternion = useRef(new THREE12.Quaternion());
|
|
4970
|
+
const linearVelocity = useRef(new THREE12.Vector3());
|
|
4971
|
+
const angularVelocity = useRef(new THREE12.Vector3());
|
|
4629
4972
|
useEffect(() => {
|
|
4630
4973
|
const model = mjModelRef.current;
|
|
4631
4974
|
if (!model || status !== "ready") return;
|
|
@@ -4979,62 +5322,8 @@ function useVideoRecorder(options = {}) {
|
|
|
4979
5322
|
}
|
|
4980
5323
|
};
|
|
4981
5324
|
}
|
|
4982
|
-
function
|
|
4983
|
-
|
|
4984
|
-
}
|
|
4985
|
-
function resolveCanvasTarget(target) {
|
|
4986
|
-
const resolvedTarget = isTargetRef(target) ? target.current : target;
|
|
4987
|
-
if (!resolvedTarget) {
|
|
4988
|
-
throw new Error("No frame capture target is available.");
|
|
4989
|
-
}
|
|
4990
|
-
if (resolvedTarget instanceof HTMLCanvasElement) {
|
|
4991
|
-
return resolvedTarget;
|
|
4992
|
-
}
|
|
4993
|
-
const canvas = resolvedTarget.querySelector("canvas");
|
|
4994
|
-
if (!canvas) {
|
|
4995
|
-
throw new Error("Frame capture target does not contain a canvas.");
|
|
4996
|
-
}
|
|
4997
|
-
return canvas;
|
|
4998
|
-
}
|
|
4999
|
-
function waitForNextAnimationFrame() {
|
|
5000
|
-
return new Promise((resolve) => {
|
|
5001
|
-
requestAnimationFrame(() => resolve());
|
|
5002
|
-
});
|
|
5003
|
-
}
|
|
5004
|
-
async function captureFrame(options) {
|
|
5005
|
-
const type = options.type ?? "image/png";
|
|
5006
|
-
const canvas = resolveCanvasTarget(options.target);
|
|
5007
|
-
if (options.waitForAnimationFrame ?? true) {
|
|
5008
|
-
await waitForNextAnimationFrame();
|
|
5009
|
-
}
|
|
5010
|
-
return {
|
|
5011
|
-
canvas,
|
|
5012
|
-
dataUrl: canvas.toDataURL(type, options.quality),
|
|
5013
|
-
type
|
|
5014
|
-
};
|
|
5015
|
-
}
|
|
5016
|
-
async function captureFrameBlob(options) {
|
|
5017
|
-
const type = options.type ?? "image/png";
|
|
5018
|
-
const canvas = resolveCanvasTarget(options.target);
|
|
5019
|
-
if (options.waitForAnimationFrame ?? true) {
|
|
5020
|
-
await waitForNextAnimationFrame();
|
|
5021
|
-
}
|
|
5022
|
-
const blob = await new Promise((resolve, reject) => {
|
|
5023
|
-
canvas.toBlob(
|
|
5024
|
-
(nextBlob) => {
|
|
5025
|
-
if (nextBlob) {
|
|
5026
|
-
resolve(nextBlob);
|
|
5027
|
-
} else {
|
|
5028
|
-
reject(new Error("Canvas frame capture did not produce a Blob."));
|
|
5029
|
-
}
|
|
5030
|
-
},
|
|
5031
|
-
type,
|
|
5032
|
-
options.quality
|
|
5033
|
-
);
|
|
5034
|
-
});
|
|
5035
|
-
return { canvas, blob, type };
|
|
5036
|
-
}
|
|
5037
|
-
function useFrameCapture(defaultOptions = {}) {
|
|
5325
|
+
function useCameraFrameCapture(defaultOptions = {}) {
|
|
5326
|
+
const mujoco = useMujoco();
|
|
5038
5327
|
const [status, setStatus] = useState("idle");
|
|
5039
5328
|
const [error, setError] = useState(null);
|
|
5040
5329
|
const reset = useCallback(() => {
|
|
@@ -5043,40 +5332,49 @@ function useFrameCapture(defaultOptions = {}) {
|
|
|
5043
5332
|
}, []);
|
|
5044
5333
|
const capture = useCallback(
|
|
5045
5334
|
async (options = {}) => {
|
|
5335
|
+
if (!mujoco.api) {
|
|
5336
|
+
throw new Error("MuJoCo scene is not ready for camera frame capture.");
|
|
5337
|
+
}
|
|
5046
5338
|
setStatus("capturing");
|
|
5047
5339
|
setError(null);
|
|
5048
5340
|
try {
|
|
5049
|
-
const result = await
|
|
5341
|
+
const result = await mujoco.api.captureCameraFrame({
|
|
5342
|
+
...defaultOptions,
|
|
5343
|
+
...options
|
|
5344
|
+
});
|
|
5050
5345
|
setStatus("captured");
|
|
5051
5346
|
return result;
|
|
5052
5347
|
} catch (nextError) {
|
|
5053
|
-
const error2 = nextError instanceof Error ? nextError : new Error("Unable to capture the
|
|
5348
|
+
const error2 = nextError instanceof Error ? nextError : new Error("Unable to capture the requested camera frame.");
|
|
5054
5349
|
setError(error2);
|
|
5055
5350
|
setStatus("error");
|
|
5056
5351
|
throw error2;
|
|
5057
5352
|
}
|
|
5058
5353
|
},
|
|
5059
|
-
[defaultOptions]
|
|
5354
|
+
[defaultOptions, mujoco.api]
|
|
5060
5355
|
);
|
|
5061
5356
|
const captureBlob = useCallback(
|
|
5062
5357
|
async (options = {}) => {
|
|
5358
|
+
if (!mujoco.api) {
|
|
5359
|
+
throw new Error("MuJoCo scene is not ready for camera frame capture.");
|
|
5360
|
+
}
|
|
5063
5361
|
setStatus("capturing");
|
|
5064
5362
|
setError(null);
|
|
5065
5363
|
try {
|
|
5066
|
-
const result = await
|
|
5364
|
+
const result = await mujoco.api.captureCameraFrameBlob({
|
|
5067
5365
|
...defaultOptions,
|
|
5068
5366
|
...options
|
|
5069
5367
|
});
|
|
5070
5368
|
setStatus("captured");
|
|
5071
5369
|
return result;
|
|
5072
5370
|
} catch (nextError) {
|
|
5073
|
-
const error2 = nextError instanceof Error ? nextError : new Error("Unable to capture the
|
|
5371
|
+
const error2 = nextError instanceof Error ? nextError : new Error("Unable to capture the requested camera frame.");
|
|
5074
5372
|
setError(error2);
|
|
5075
5373
|
setStatus("error");
|
|
5076
5374
|
throw error2;
|
|
5077
5375
|
}
|
|
5078
5376
|
},
|
|
5079
|
-
[defaultOptions]
|
|
5377
|
+
[defaultOptions, mujoco.api]
|
|
5080
5378
|
);
|
|
5081
5379
|
return {
|
|
5082
5380
|
status,
|
|
@@ -5087,6 +5385,42 @@ function useFrameCapture(defaultOptions = {}) {
|
|
|
5087
5385
|
reset
|
|
5088
5386
|
};
|
|
5089
5387
|
}
|
|
5388
|
+
function useCameraSequenceRecorder() {
|
|
5389
|
+
const mujoco = useMujoco();
|
|
5390
|
+
const [status, setStatus] = useState("idle");
|
|
5391
|
+
const [error, setError] = useState(null);
|
|
5392
|
+
const reset = useCallback(() => {
|
|
5393
|
+
setStatus("idle");
|
|
5394
|
+
setError(null);
|
|
5395
|
+
}, []);
|
|
5396
|
+
const record = useCallback(
|
|
5397
|
+
async (options) => {
|
|
5398
|
+
if (!mujoco.api) {
|
|
5399
|
+
throw new Error("MuJoCo scene is not ready for camera sequence recording.");
|
|
5400
|
+
}
|
|
5401
|
+
setStatus("capturing");
|
|
5402
|
+
setError(null);
|
|
5403
|
+
try {
|
|
5404
|
+
const result = await mujoco.api.recordCameraSequence(options);
|
|
5405
|
+
setStatus("captured");
|
|
5406
|
+
return result;
|
|
5407
|
+
} catch (nextError) {
|
|
5408
|
+
const error2 = nextError instanceof Error ? nextError : new Error("Unable to record the requested camera sequence.");
|
|
5409
|
+
setError(error2);
|
|
5410
|
+
setStatus("error");
|
|
5411
|
+
throw error2;
|
|
5412
|
+
}
|
|
5413
|
+
},
|
|
5414
|
+
[mujoco.api]
|
|
5415
|
+
);
|
|
5416
|
+
return {
|
|
5417
|
+
status,
|
|
5418
|
+
error,
|
|
5419
|
+
isRecording: status === "capturing",
|
|
5420
|
+
record,
|
|
5421
|
+
reset
|
|
5422
|
+
};
|
|
5423
|
+
}
|
|
5090
5424
|
function useCtrlNoise(config = {}) {
|
|
5091
5425
|
const { mjModelRef } = useMujocoContext();
|
|
5092
5426
|
const configRef = useRef(config);
|
|
@@ -5138,7 +5472,7 @@ function useSelectionHighlight(bodyId, options = {}) {
|
|
|
5138
5472
|
}
|
|
5139
5473
|
}
|
|
5140
5474
|
prevRef.current = [];
|
|
5141
|
-
const highlightColor = new
|
|
5475
|
+
const highlightColor = new THREE12.Color(color);
|
|
5142
5476
|
for (const mesh of meshes) {
|
|
5143
5477
|
const mat = mesh.material;
|
|
5144
5478
|
if (mat.emissive) {
|
|
@@ -5165,15 +5499,15 @@ function useSelectionHighlight(bodyId, options = {}) {
|
|
|
5165
5499
|
}
|
|
5166
5500
|
function useCameraAnimation() {
|
|
5167
5501
|
const { camera } = useThree();
|
|
5168
|
-
const orbitTargetRef = useRef(new
|
|
5502
|
+
const orbitTargetRef = useRef(new THREE12.Vector3(0, 0, 0));
|
|
5169
5503
|
const cameraAnimRef = useRef({
|
|
5170
5504
|
active: false,
|
|
5171
|
-
startPos: new
|
|
5172
|
-
endPos: new
|
|
5173
|
-
startRot: new
|
|
5174
|
-
endRot: new
|
|
5175
|
-
startTarget: new
|
|
5176
|
-
endTarget: new
|
|
5505
|
+
startPos: new THREE12.Vector3(),
|
|
5506
|
+
endPos: new THREE12.Vector3(),
|
|
5507
|
+
startRot: new THREE12.Quaternion(),
|
|
5508
|
+
endRot: new THREE12.Quaternion(),
|
|
5509
|
+
startTarget: new THREE12.Vector3(),
|
|
5510
|
+
endTarget: new THREE12.Vector3(),
|
|
5177
5511
|
startTime: 0,
|
|
5178
5512
|
duration: 0,
|
|
5179
5513
|
resolve: null
|
|
@@ -5239,6 +5573,18 @@ function useCameraAnimation() {
|
|
|
5239
5573
|
* @license
|
|
5240
5574
|
* SPDX-License-Identifier: Apache-2.0
|
|
5241
5575
|
*/
|
|
5576
|
+
/**
|
|
5577
|
+
* @license
|
|
5578
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5579
|
+
*
|
|
5580
|
+
* useFrameCapture — still-frame capture for canvas-backed MuJoCo/R3F scenes.
|
|
5581
|
+
*/
|
|
5582
|
+
/**
|
|
5583
|
+
* @license
|
|
5584
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5585
|
+
*
|
|
5586
|
+
* Offscreen camera-frame capture for R3F/MuJoCo scenes.
|
|
5587
|
+
*/
|
|
5242
5588
|
/**
|
|
5243
5589
|
* @license
|
|
5244
5590
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -5376,7 +5722,13 @@ function useCameraAnimation() {
|
|
|
5376
5722
|
* @license
|
|
5377
5723
|
* SPDX-License-Identifier: Apache-2.0
|
|
5378
5724
|
*
|
|
5379
|
-
*
|
|
5725
|
+
* React state wrapper around MuJoCo/R3F offscreen camera-frame capture.
|
|
5726
|
+
*/
|
|
5727
|
+
/**
|
|
5728
|
+
* @license
|
|
5729
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5730
|
+
*
|
|
5731
|
+
* React state wrapper around fixed-camera simulation sequence recording.
|
|
5380
5732
|
*/
|
|
5381
5733
|
/**
|
|
5382
5734
|
* @license
|
|
@@ -5408,6 +5760,6 @@ function useCameraAnimation() {
|
|
|
5408
5760
|
* useCameraAnimation — composable camera animation hook.
|
|
5409
5761
|
*/
|
|
5410
5762
|
|
|
5411
|
-
export { Body, ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkGizmo, InstancedGeomRenderer, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, RobotActuators, RobotBodies, RobotGeoms, RobotJoints, RobotKeyframes, RobotResources, RobotSensors, RobotSites, SceneLights, TendonRenderer, TrajectoryPlayer, buildObservation, captureFrame, captureFrameBlob, createContiguousControlGroup, createController, createControllerHook, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getContact, getControlMap, getName, loadScene, registerRobotResources, resolveControlGroup, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useFrameCapture, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
|
|
5763
|
+
export { Body, ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkGizmo, InstancedGeomRenderer, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, RobotActuators, RobotBodies, RobotGeoms, RobotJoints, RobotKeyframes, RobotResources, RobotSensors, RobotSites, SceneLights, TendonRenderer, TrajectoryPlayer, buildObservation, captureCameraFrame, captureCameraFrameBlob, captureFrame, captureFrameBlob, createContiguousControlGroup, createController, createControllerHook, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getContact, getControlMap, getName, loadScene, registerRobotResources, renderCameraFrameToCanvas, resolveControlGroup, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useCameraFrameCapture, useCameraSequenceRecorder, useContactEvents, useContacts, useCtrl, useCtrlNoise, useFrameCapture, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
|
|
5412
5764
|
//# sourceMappingURL=index.js.map
|
|
5413
5765
|
//# sourceMappingURL=index.js.map
|