mujoco-react 5.0.0 → 6.0.1

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 CHANGED
@@ -365,10 +365,6 @@ Component wrapper for contact events:
365
365
  />
366
366
  ```
367
367
 
368
- ### `<SelectionHighlight />`
369
-
370
- Emissive highlight on selected body meshes. Also available as `useSelectionHighlight(bodyId, options?)` hook.
371
-
372
368
  ### `<TrajectoryPlayer />`
373
369
 
374
370
  Plays back recorded qpos trajectories with scrubbing.
@@ -555,9 +551,19 @@ Returns actuator metadata for building control UIs.
555
551
 
556
552
  Ref-based site position/quaternion tracking.
557
553
 
554
+ ### `useBodyMeshes(bodyId)`
555
+
556
+ Returns the Three.js meshes belonging to a MuJoCo body. Use for custom selection visuals, outlines, postprocessing, or any per-body mesh manipulation:
557
+
558
+ ```tsx
559
+ const meshes = useBodyMeshes(selectedBodyId);
560
+
561
+ // Use with drei Outline, or manipulate materials directly
562
+ ```
563
+
558
564
  ### `useSelectionHighlight(bodyId, options?)`
559
565
 
560
- Hook form of `<SelectionHighlight>`. Apply emissive highlights imperatively:
566
+ Convenience wrapper around `useBodyMeshes` that applies an emissive highlight:
561
567
 
562
568
  ```tsx
563
569
  useSelectionHighlight(selectedBodyId, { color: '#00ff00', emissiveIntensity: 0.5 });
@@ -659,12 +665,13 @@ Objects that need stable contact (grasping, stacking, etc.) require tuned MuJoCo
659
665
 
660
666
  ### Click-to-Select
661
667
 
662
- Combine R3F raycasting with `<SelectionHighlight />` for body selection:
668
+ Combine R3F raycasting with `useSelectionHighlight` for body selection:
663
669
 
664
670
  ```tsx
665
671
  function ClickSelectOverlay() {
666
672
  const selectedBodyId = useClickSelect(); // your raycasting hook
667
- return <SelectionHighlight bodyId={selectedBodyId} />;
673
+ useSelectionHighlight(selectedBodyId);
674
+ return null;
668
675
  }
669
676
  ```
670
677
 
package/dist/index.d.ts CHANGED
@@ -393,11 +393,6 @@ interface TrajectoryPlayerProps {
393
393
  playing?: boolean;
394
394
  onFrame?: (frameIdx: number) => void;
395
395
  }
396
- interface SelectionHighlightProps {
397
- bodyId: number | null;
398
- color?: string;
399
- emissiveIntensity?: number;
400
- }
401
396
  interface ContactListenerProps {
402
397
  body: string;
403
398
  onContactEnter?: (info: ContactInfo) => void;
@@ -816,19 +811,6 @@ declare function ContactListener({ body, onContactEnter, onContactExit, }: Conta
816
811
  */
817
812
  declare function TrajectoryPlayer({ trajectory, fps, loop, playing, onFrame, }: TrajectoryPlayerProps): null;
818
813
 
819
- /**
820
- * @license
821
- * SPDX-License-Identifier: Apache-2.0
822
- *
823
- * SelectionHighlight — highlight a selected body with emissive color (spec 6.5)
824
- */
825
-
826
- /**
827
- * Applies emissive highlight to all meshes belonging to a body.
828
- * Restores original emissive when bodyId changes or component unmounts.
829
- */
830
- declare function SelectionHighlight({ bodyId, color, emissiveIntensity, }: SelectionHighlightProps): null;
831
-
832
814
  /**
833
815
  * @license
834
816
  * SPDX-License-Identifier: Apache-2.0
@@ -1114,10 +1096,37 @@ declare function useCtrlNoise(config?: CtrlNoiseConfig): void;
1114
1096
  * @license
1115
1097
  * SPDX-License-Identifier: Apache-2.0
1116
1098
  *
1117
- * useSelectionHighlighthook form of SelectionHighlight (spec 6.5)
1099
+ * useBodyMeshesreturns Three.js meshes belonging to a MuJoCo body.
1100
+ *
1101
+ * Low-level primitive for custom selection visuals, outlines,
1102
+ * postprocessing effects, or any per-body mesh manipulation.
1103
+ */
1104
+
1105
+ /**
1106
+ * Returns all Three.js meshes belonging to the given MuJoCo body ID.
1107
+ *
1108
+ * @example
1109
+ * ```tsx
1110
+ * const meshes = useBodyMeshes(selectedBodyId);
1111
+ *
1112
+ * // Use with drei Outline
1113
+ * <Outline selection={meshes} />
1114
+ *
1115
+ * // Or manipulate directly
1116
+ * useFrame(() => {
1117
+ * meshes.forEach(m => { m.scale.setScalar(1.05); });
1118
+ * });
1119
+ * ```
1120
+ */
1121
+ declare function useBodyMeshes(bodyId: number | null): THREE.Mesh[];
1122
+
1123
+ /**
1124
+ * @license
1125
+ * SPDX-License-Identifier: Apache-2.0
1126
+ *
1127
+ * useSelectionHighlight — convenience hook for emissive body highlights.
1118
1128
  *
1119
- * Applies emissive highlight to all meshes belonging to a body.
1120
- * Restores original emissive when bodyId changes or hook unmounts.
1129
+ * Built on useBodyMeshes. For custom visuals, use useBodyMeshes directly.
1121
1130
  */
1122
1131
  declare function useSelectionHighlight(bodyId: number | null, options?: {
1123
1132
  color?: string;
@@ -1155,4 +1164,4 @@ interface CameraAnimationAPI {
1155
1164
  */
1156
1165
  declare function useCameraAnimation(): CameraAnimationAPI;
1157
1166
 
1158
- export { type ActuatorInfo, type BodyInfo, type BodyStateResult, type CameraAnimationAPI, type ContactInfo, ContactListener, type ContactListenerProps, ContactMarkers, type ControllerComponent, type ControllerOptions, Debug, type DebugProps, DragInteraction, type DragInteractionProps, FlexRenderer, type GeomInfo, type IKSolveFn, type IkConfig, type IkContextValue, IkController, IkGizmo, type IkGizmoProps, type JointInfo, type JointStateResult, type KeyBinding, type KeyboardTeleopConfig, type ModelOptions, MujocoCanvas, type MujocoCanvasProps, type MujocoContact, type MujocoContactArray, type MujocoContextValue, type MujocoData, type MujocoModel, type MujocoModule, MujocoPhysics, type MujocoPhysicsProps, MujocoProvider, type MujocoSimAPI, MujocoSimProvider, type PhysicsConfig, type PhysicsStepCallback, type PolicyConfig, type RayHit, type SceneConfig, SceneLights, type SceneLightsProps, type SceneMarker, type SceneObject, SelectionHighlight, type SelectionHighlightProps, type SensorInfo, type SensorResult, type SiteInfo, type SitePositionResult, type StateSnapshot, TendonRenderer, type TrajectoryData, type TrajectoryFrame, TrajectoryPlayer, type TrajectoryPlayerProps, type XmlPatch, createController, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getContact, getName, loadScene, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIk, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
1167
+ export { type ActuatorInfo, type BodyInfo, type BodyStateResult, type CameraAnimationAPI, type ContactInfo, ContactListener, type ContactListenerProps, ContactMarkers, type ControllerComponent, type ControllerOptions, Debug, type DebugProps, DragInteraction, type DragInteractionProps, FlexRenderer, type GeomInfo, type IKSolveFn, type IkConfig, type IkContextValue, IkController, IkGizmo, type IkGizmoProps, type JointInfo, type JointStateResult, type KeyBinding, type KeyboardTeleopConfig, type ModelOptions, MujocoCanvas, type MujocoCanvasProps, type MujocoContact, type MujocoContactArray, type MujocoContextValue, type MujocoData, type MujocoModel, type MujocoModule, MujocoPhysics, type MujocoPhysicsProps, MujocoProvider, type MujocoSimAPI, MujocoSimProvider, type PhysicsConfig, type PhysicsStepCallback, type PolicyConfig, type RayHit, type SceneConfig, SceneLights, type SceneLightsProps, type SceneMarker, type SceneObject, type SensorInfo, type SensorResult, type SiteInfo, type SitePositionResult, type StateSnapshot, TendonRenderer, type TrajectoryData, type TrajectoryFrame, TrajectoryPlayer, type TrajectoryPlayerProps, type XmlPatch, createController, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getContact, getName, loadScene, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIk, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
package/dist/index.js CHANGED
@@ -3053,58 +3053,6 @@ function TrajectoryPlayer({
3053
3053
  });
3054
3054
  return null;
3055
3055
  }
3056
- function useSelectionHighlight(bodyId, options = {}) {
3057
- const { color = "#ff4444", emissiveIntensity = 0.3 } = options;
3058
- const { scene } = useThree();
3059
- const prevMeshesRef = useRef([]);
3060
- useEffect(() => {
3061
- for (const entry of prevMeshesRef.current) {
3062
- const mat = entry.mesh.material;
3063
- if (mat.emissive) {
3064
- mat.emissive.copy(entry.originalEmissive);
3065
- mat.emissiveIntensity = entry.originalIntensity;
3066
- }
3067
- }
3068
- prevMeshesRef.current = [];
3069
- if (bodyId === null || bodyId < 0) return;
3070
- const highlightColor = new THREE11.Color(color);
3071
- scene.traverse((obj) => {
3072
- if (obj.userData.bodyID === bodyId && obj.isMesh) {
3073
- const mesh = obj;
3074
- const mat = mesh.material;
3075
- if (mat.emissive) {
3076
- prevMeshesRef.current.push({
3077
- mesh,
3078
- originalEmissive: mat.emissive.clone(),
3079
- originalIntensity: mat.emissiveIntensity ?? 0
3080
- });
3081
- mat.emissive.copy(highlightColor);
3082
- mat.emissiveIntensity = emissiveIntensity;
3083
- }
3084
- }
3085
- });
3086
- return () => {
3087
- for (const entry of prevMeshesRef.current) {
3088
- const mat = entry.mesh.material;
3089
- if (mat.emissive) {
3090
- mat.emissive.copy(entry.originalEmissive);
3091
- mat.emissiveIntensity = entry.originalIntensity;
3092
- }
3093
- }
3094
- prevMeshesRef.current = [];
3095
- };
3096
- }, [bodyId, color, emissiveIntensity, scene]);
3097
- }
3098
-
3099
- // src/components/SelectionHighlight.tsx
3100
- function SelectionHighlight({
3101
- bodyId,
3102
- color = "#ff4444",
3103
- emissiveIntensity = 0.3
3104
- }) {
3105
- useSelectionHighlight(bodyId, { color, emissiveIntensity });
3106
- return null;
3107
- }
3108
3056
  function useActuators() {
3109
3057
  const { mjModelRef, status } = useMujoco();
3110
3058
  return useMemo(() => {
@@ -3651,6 +3599,57 @@ function useCtrlNoise(config = {}) {
3651
3599
  }
3652
3600
  });
3653
3601
  }
3602
+ function useBodyMeshes(bodyId) {
3603
+ const { scene } = useThree();
3604
+ return useMemo(() => {
3605
+ if (bodyId === null || bodyId < 0) return [];
3606
+ const meshes = [];
3607
+ scene.traverse((obj) => {
3608
+ if (obj.userData.bodyID === bodyId && obj.isMesh) {
3609
+ meshes.push(obj);
3610
+ }
3611
+ });
3612
+ return meshes;
3613
+ }, [bodyId, scene]);
3614
+ }
3615
+ function useSelectionHighlight(bodyId, options = {}) {
3616
+ const { color = "#ff4444", emissiveIntensity = 0.3 } = options;
3617
+ const meshes = useBodyMeshes(bodyId);
3618
+ const prevRef = useRef([]);
3619
+ useEffect(() => {
3620
+ for (const entry of prevRef.current) {
3621
+ const mat = entry.mesh.material;
3622
+ if (mat.emissive) {
3623
+ mat.emissive.copy(entry.originalEmissive);
3624
+ mat.emissiveIntensity = entry.originalIntensity;
3625
+ }
3626
+ }
3627
+ prevRef.current = [];
3628
+ const highlightColor = new THREE11.Color(color);
3629
+ for (const mesh of meshes) {
3630
+ const mat = mesh.material;
3631
+ if (mat.emissive) {
3632
+ prevRef.current.push({
3633
+ mesh,
3634
+ originalEmissive: mat.emissive.clone(),
3635
+ originalIntensity: mat.emissiveIntensity ?? 0
3636
+ });
3637
+ mat.emissive.copy(highlightColor);
3638
+ mat.emissiveIntensity = emissiveIntensity;
3639
+ }
3640
+ }
3641
+ return () => {
3642
+ for (const entry of prevRef.current) {
3643
+ const mat = entry.mesh.material;
3644
+ if (mat.emissive) {
3645
+ mat.emissive.copy(entry.originalEmissive);
3646
+ mat.emissiveIntensity = entry.originalIntensity;
3647
+ }
3648
+ }
3649
+ prevRef.current = [];
3650
+ };
3651
+ }, [meshes, color, emissiveIntensity]);
3652
+ }
3654
3653
  function useCameraAnimation() {
3655
3654
  const { camera } = useThree();
3656
3655
  const orbitTargetRef = useRef(new THREE11.Vector3(0, 0, 0));
@@ -3825,21 +3824,6 @@ function useCameraAnimation() {
3825
3824
  *
3826
3825
  * TrajectoryPlayer — component form of trajectory playback (spec 13.2)
3827
3826
  */
3828
- /**
3829
- * @license
3830
- * SPDX-License-Identifier: Apache-2.0
3831
- *
3832
- * useSelectionHighlight — hook form of SelectionHighlight (spec 6.5)
3833
- *
3834
- * Applies emissive highlight to all meshes belonging to a body.
3835
- * Restores original emissive when bodyId changes or hook unmounts.
3836
- */
3837
- /**
3838
- * @license
3839
- * SPDX-License-Identifier: Apache-2.0
3840
- *
3841
- * SelectionHighlight — highlight a selected body with emissive color (spec 6.5)
3842
- */
3843
3827
  /**
3844
3828
  * @license
3845
3829
  * SPDX-License-Identifier: Apache-2.0
@@ -3900,6 +3884,23 @@ function useCameraAnimation() {
3900
3884
  *
3901
3885
  * useCtrlNoise — control noise / perturbation hook (spec 3.2)
3902
3886
  */
3887
+ /**
3888
+ * @license
3889
+ * SPDX-License-Identifier: Apache-2.0
3890
+ *
3891
+ * useBodyMeshes — returns Three.js meshes belonging to a MuJoCo body.
3892
+ *
3893
+ * Low-level primitive for custom selection visuals, outlines,
3894
+ * postprocessing effects, or any per-body mesh manipulation.
3895
+ */
3896
+ /**
3897
+ * @license
3898
+ * SPDX-License-Identifier: Apache-2.0
3899
+ *
3900
+ * useSelectionHighlight — convenience hook for emissive body highlights.
3901
+ *
3902
+ * Built on useBodyMeshes. For custom visuals, use useBodyMeshes directly.
3903
+ */
3903
3904
  /**
3904
3905
  * @license
3905
3906
  * SPDX-License-Identifier: Apache-2.0
@@ -3907,6 +3908,6 @@ function useCameraAnimation() {
3907
3908
  * useCameraAnimation — composable camera animation hook.
3908
3909
  */
3909
3910
 
3910
- export { ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkController, IkGizmo, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, SceneLights, SelectionHighlight, TendonRenderer, TrajectoryPlayer, createController, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getContact, getName, loadScene, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIk, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
3911
+ export { ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkController, IkGizmo, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, SceneLights, TendonRenderer, TrajectoryPlayer, createController, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getContact, getName, loadScene, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIk, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
3911
3912
  //# sourceMappingURL=index.js.map
3912
3913
  //# sourceMappingURL=index.js.map