mujoco-react 10.3.0 → 10.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY } from './chunk-6AZEFI6A.js';
2
- export { CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, ModelActuators, ModelBodies, ModelCameras, ModelGeoms, ModelJoints, ModelKeyframes, ModelResources, ModelSensors, ModelSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, registerModelResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-6AZEFI6A.js';
1
+ import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY } from './chunk-FBXXXPLQ.js';
2
+ export { CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, ModelActuators, ModelBodies, ModelCameras, ModelGeoms, ModelJoints, ModelKeyframes, ModelResources, ModelSensors, ModelSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, registerModelResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-FBXXXPLQ.js';
3
3
  import loadMujoco from '@mujoco/mujoco';
4
4
  import defaultMujocoWasmUrl from '@mujoco/mujoco/mujoco.wasm?url';
5
5
  import { createContext, forwardRef, useRef, useEffect, useContext, useState, useCallback, useMemo, useLayoutEffect } from 'react';
@@ -4867,11 +4867,161 @@ var _contactNormal = new THREE11.Vector3();
4867
4867
  var MAX_CONTACT_ARROWS = 50;
4868
4868
  var CAMERA_DEBUG_LENGTH = 0.12;
4869
4869
  var CAMERA_DEBUG_FRUSTUM_DEPTH = 0.08;
4870
+ function toVector32(value, fallback) {
4871
+ if (!value) return fallback.clone();
4872
+ return value instanceof THREE11.Vector3 ? value.clone() : new THREE11.Vector3(value[0], value[1], value[2]);
4873
+ }
4874
+ function createCameraLabel(text, color) {
4875
+ const canvas = document.createElement("canvas");
4876
+ canvas.width = 256;
4877
+ canvas.height = 64;
4878
+ const ctx = canvas.getContext("2d");
4879
+ ctx.fillStyle = new THREE11.Color(color).getStyle();
4880
+ ctx.font = "bold 32px monospace";
4881
+ ctx.textAlign = "center";
4882
+ ctx.fillText(text, 128, 42);
4883
+ const texture = new THREE11.CanvasTexture(canvas);
4884
+ const sprite = new THREE11.Sprite(
4885
+ new THREE11.SpriteMaterial({
4886
+ map: texture,
4887
+ depthTest: false,
4888
+ transparent: true
4889
+ })
4890
+ );
4891
+ sprite.position.set(0, 0.014, 0.01);
4892
+ sprite.scale.set(0.05, 0.012, 1);
4893
+ sprite.renderOrder = 999;
4894
+ return sprite;
4895
+ }
4896
+ function createVirtualCameraDebugObject(camera, index) {
4897
+ const color = camera.color ?? "#ff3d71";
4898
+ const aimColor = camera.aimColor ?? "#38bdf8";
4899
+ const markerScale = camera.markerScale ?? 1;
4900
+ const cameraPosition = toVector32(camera.position, new THREE11.Vector3());
4901
+ const configuredUp = toVector32(camera.up, new THREE11.Vector3(0, 0, 1)).normalize();
4902
+ const cameraQuaternion = new THREE11.Quaternion();
4903
+ const forward = new THREE11.Vector3();
4904
+ if (camera.quaternion) {
4905
+ if (camera.quaternion instanceof THREE11.Quaternion) {
4906
+ cameraQuaternion.copy(camera.quaternion);
4907
+ } else {
4908
+ cameraQuaternion.set(
4909
+ camera.quaternion[0],
4910
+ camera.quaternion[1],
4911
+ camera.quaternion[2],
4912
+ camera.quaternion[3]
4913
+ );
4914
+ }
4915
+ forward.set(0, 0, -1).applyQuaternion(cameraQuaternion).normalize();
4916
+ } else {
4917
+ const target2 = toVector32(
4918
+ camera.lookAt,
4919
+ cameraPosition.clone().add(new THREE11.Vector3(0, 0, -1))
4920
+ );
4921
+ forward.copy(target2).sub(cameraPosition);
4922
+ if (forward.lengthSq() < 1e-8) forward.set(0, 0, -1);
4923
+ forward.normalize();
4924
+ cameraQuaternion.setFromRotationMatrix(
4925
+ new THREE11.Matrix4().lookAt(cameraPosition, target2, configuredUp)
4926
+ );
4927
+ }
4928
+ const target = camera.lookAt ? toVector32(camera.lookAt, cameraPosition.clone().add(forward)) : cameraPosition.clone().addScaledVector(forward, 0.4);
4929
+ const distanceToTarget = Math.max(target.distanceTo(cameraPosition), 1e-3);
4930
+ const depth = camera.frustumDepth ?? Math.min(Math.max(distanceToTarget * 0.42, 0.16), 0.45);
4931
+ const fov = camera.fov ?? 50;
4932
+ const aspect = (camera.width ?? 640) / (camera.height ?? 480);
4933
+ const right = forward.clone().cross(configuredUp);
4934
+ if (right.lengthSq() < 1e-8) right.set(1, 0, 0);
4935
+ right.normalize();
4936
+ const orthogonalUp = right.clone().cross(forward).normalize();
4937
+ const frustumHeight = 2 * Math.tan(THREE11.MathUtils.degToRad(fov) / 2) * depth;
4938
+ const frustumWidth = frustumHeight * aspect;
4939
+ const center = cameraPosition.clone().addScaledVector(forward, depth);
4940
+ const halfRight = right.clone().multiplyScalar(frustumWidth / 2);
4941
+ const halfUp = orthogonalUp.clone().multiplyScalar(frustumHeight / 2);
4942
+ const topLeft = center.clone().sub(halfRight).add(halfUp);
4943
+ const topRight = center.clone().add(halfRight).add(halfUp);
4944
+ const bottomRight = center.clone().add(halfRight).sub(halfUp);
4945
+ const bottomLeft = center.clone().sub(halfRight).sub(halfUp);
4946
+ const frustumPoints = [
4947
+ cameraPosition,
4948
+ topLeft,
4949
+ cameraPosition,
4950
+ topRight,
4951
+ cameraPosition,
4952
+ bottomRight,
4953
+ cameraPosition,
4954
+ bottomLeft,
4955
+ topLeft,
4956
+ topRight,
4957
+ topRight,
4958
+ bottomRight,
4959
+ bottomRight,
4960
+ bottomLeft,
4961
+ bottomLeft,
4962
+ topLeft
4963
+ ];
4964
+ const group = new THREE11.Group();
4965
+ group.name = camera.name ?? `virtual-camera-${index}`;
4966
+ group.renderOrder = 999;
4967
+ group.frustumCulled = false;
4968
+ const frustum = new THREE11.LineSegments(
4969
+ new THREE11.BufferGeometry().setFromPoints(frustumPoints),
4970
+ new THREE11.LineBasicMaterial({
4971
+ color,
4972
+ transparent: true,
4973
+ opacity: 0.9,
4974
+ depthTest: false
4975
+ })
4976
+ );
4977
+ frustum.renderOrder = 999;
4978
+ frustum.frustumCulled = false;
4979
+ group.add(frustum);
4980
+ const aim = new THREE11.LineSegments(
4981
+ new THREE11.BufferGeometry().setFromPoints([cameraPosition, target]),
4982
+ new THREE11.LineBasicMaterial({
4983
+ color: aimColor,
4984
+ transparent: true,
4985
+ opacity: 0.95,
4986
+ depthTest: false
4987
+ })
4988
+ );
4989
+ aim.renderOrder = 999;
4990
+ aim.frustumCulled = false;
4991
+ group.add(aim);
4992
+ const markerGroup = new THREE11.Group();
4993
+ markerGroup.position.copy(cameraPosition);
4994
+ markerGroup.quaternion.copy(cameraQuaternion);
4995
+ markerGroup.renderOrder = 999;
4996
+ markerGroup.frustumCulled = false;
4997
+ markerGroup.add(new THREE11.Mesh(
4998
+ new THREE11.BoxGeometry(0.045 * markerScale, 0.028 * markerScale, 0.022 * markerScale),
4999
+ new THREE11.MeshBasicMaterial({ color, depthTest: false })
5000
+ ));
5001
+ const lens = new THREE11.Mesh(
5002
+ new THREE11.BoxGeometry(0.025 * markerScale, 0.018 * markerScale, 0.014 * markerScale),
5003
+ new THREE11.MeshBasicMaterial({ color: aimColor, depthTest: false })
5004
+ );
5005
+ lens.position.set(0, 0, -0.021 * markerScale);
5006
+ markerGroup.add(lens);
5007
+ if (camera.name) markerGroup.add(createCameraLabel(camera.name, color));
5008
+ group.add(markerGroup);
5009
+ const targetMarker = new THREE11.Mesh(
5010
+ new THREE11.SphereGeometry(0.018 * markerScale, 16, 10),
5011
+ new THREE11.MeshBasicMaterial({ color: aimColor, depthTest: false })
5012
+ );
5013
+ targetMarker.position.copy(target);
5014
+ targetMarker.renderOrder = 999;
5015
+ targetMarker.frustumCulled = false;
5016
+ group.add(targetMarker);
5017
+ return group;
5018
+ }
4870
5019
  function Debug({
4871
5020
  showGeoms = false,
4872
5021
  showSites = false,
4873
5022
  showJoints = false,
4874
5023
  showCameras = false,
5024
+ virtualCameras = [],
4875
5025
  showContacts = false,
4876
5026
  showCOM = false,
4877
5027
  showInertia = false,
@@ -4888,6 +5038,7 @@ function Debug({
4888
5038
  const sites = [];
4889
5039
  const joints = [];
4890
5040
  const cameras = [];
5041
+ const virtualCameraObjects = [];
4891
5042
  const comMarkers = [];
4892
5043
  if (showGeoms) {
4893
5044
  for (let i = 0; i < model.ngeom; i++) {
@@ -5066,6 +5217,9 @@ function Debug({
5066
5217
  cameras.push(group);
5067
5218
  }
5068
5219
  }
5220
+ for (let i = 0; i < virtualCameras.length; i += 1) {
5221
+ virtualCameraObjects.push(createVirtualCameraDebugObject(virtualCameras[i], i));
5222
+ }
5069
5223
  if (showCOM) {
5070
5224
  for (let i = 1; i < model.nbody; i++) {
5071
5225
  const geometry = new THREE11.SphereGeometry(5e-3, 6, 6);
@@ -5075,8 +5229,8 @@ function Debug({
5075
5229
  comMarkers.push(mesh);
5076
5230
  }
5077
5231
  }
5078
- return { geoms, sites, joints, cameras, comMarkers };
5079
- }, [status, mjModelRef, showGeoms, showSites, showJoints, showCameras, showCOM]);
5232
+ return { geoms, sites, joints, cameras, virtualCameraObjects, comMarkers };
5233
+ }, [status, mjModelRef, showGeoms, showSites, showJoints, showCameras, virtualCameras, showCOM]);
5080
5234
  useEffect(() => {
5081
5235
  const group = groupRef.current;
5082
5236
  if (!group || !debugGeometry) return;
@@ -5085,6 +5239,7 @@ function Debug({
5085
5239
  ...debugGeometry.sites,
5086
5240
  ...debugGeometry.joints,
5087
5241
  ...debugGeometry.cameras,
5242
+ ...debugGeometry.virtualCameraObjects,
5088
5243
  ...debugGeometry.comMarkers
5089
5244
  ];
5090
5245
  for (const obj of allObjects) group.add(obj);