@relu-interactives/spatial-ecs 0.3.6 → 0.3.8

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.
Files changed (47) hide show
  1. package/dist/{System-TmC2EijF.d.cts → System-31wk-A0g.d.cts} +1 -1
  2. package/dist/{System-TmC2EijF.d.ts → System-31wk-A0g.d.ts} +1 -1
  3. package/dist/{XRInteractor-CCUzSqg9.d.ts → XRHandPose-CxPz8VBp.d.ts} +139 -20
  4. package/dist/{XRInteractor-I2q6TKtF.d.cts → XRHandPose-VuSbe4iz.d.cts} +139 -20
  5. package/dist/{chunk-FQTOC7HK.js → chunk-KIKIWCEB.js} +14 -5
  6. package/dist/chunk-KIKIWCEB.js.map +1 -0
  7. package/dist/{chunk-N4GKZ7IV.js → chunk-KVGGAL5V.js} +227 -3
  8. package/dist/chunk-KVGGAL5V.js.map +1 -0
  9. package/dist/{chunk-JRJ3CL5H.js → chunk-L5BP727H.js} +3 -3
  10. package/dist/{chunk-JRJ3CL5H.js.map → chunk-L5BP727H.js.map} +1 -1
  11. package/dist/{chunk-WRJ2K3LZ.js → chunk-LMTB4KQ4.js} +1011 -56
  12. package/dist/chunk-LMTB4KQ4.js.map +1 -0
  13. package/dist/components/index.cjs +98 -0
  14. package/dist/components/index.cjs.map +1 -1
  15. package/dist/components/index.d.cts +4 -3
  16. package/dist/components/index.d.ts +4 -3
  17. package/dist/components/index.js +1 -1
  18. package/dist/docs/guide/vr-and-hand-poses.md +111 -0
  19. package/dist/factories/index.cjs +58 -0
  20. package/dist/factories/index.cjs.map +1 -1
  21. package/dist/factories/index.d.cts +6 -3
  22. package/dist/factories/index.d.ts +6 -3
  23. package/dist/factories/index.js +3 -3
  24. package/dist/handPose-dFxqbFFY.d.cts +240 -0
  25. package/dist/handPose-dFxqbFFY.d.ts +240 -0
  26. package/dist/{index-W8pUajCW.d.ts → index-BIQoaKAA.d.cts} +9 -3
  27. package/dist/{index-BltjPEhg.d.cts → index-BxdXgqiI.d.ts} +9 -3
  28. package/dist/{index-BpbmZuOz.d.ts → index-C7XQyrgE.d.ts} +101 -7
  29. package/dist/{index-C5FrDt3z.d.cts → index-DyN50JZo.d.cts} +101 -7
  30. package/dist/index.cjs +1269 -51
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +104 -9
  33. package/dist/index.d.ts +104 -9
  34. package/dist/index.js +8 -8
  35. package/dist/systems/index.cjs +1226 -51
  36. package/dist/systems/index.cjs.map +1 -1
  37. package/dist/systems/index.d.cts +3 -2
  38. package/dist/systems/index.d.ts +3 -2
  39. package/dist/systems/index.js +3 -3
  40. package/dist/types.d.cts +1 -1
  41. package/dist/types.d.ts +1 -1
  42. package/dist/worldSnapshotUtils.d.cts +1 -1
  43. package/dist/worldSnapshotUtils.d.ts +1 -1
  44. package/package.json +1 -1
  45. package/dist/chunk-FQTOC7HK.js.map +0 -1
  46. package/dist/chunk-N4GKZ7IV.js.map +0 -1
  47. package/dist/chunk-WRJ2K3LZ.js.map +0 -1
@@ -1,5 +1,6 @@
1
- export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, C as CameraComponent, c as CameraComponentOptions, d as CameraProjection, e as CameraRuntimeType, f as ColliderShape, g as ColliderState, h as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, i as DEFAULT_INSTANCED_MESH_PARAMETERS, j as DEFAULT_INSTANCE_TRANSFORM, k as DEFAULT_MESH_GEOMETRY_PARAMETERS, l as DEFAULT_PHYSICS_STATE, m as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, n as EntityType, I as ImageComponent, o as ImageTarget, p as ImageTargetAnchor, q as ImageTargetAnchorOptions, r as ImageTargetReference, s as InstanceSlotComponent, t as InstanceTransform, u as InstancedMeshComponent, v as InstancedMeshKind, L as LightComponent, w as LightValueState, M as MaterialComponent, x as MaterialTypeValue, y as MaterialValueState, z as MeshComponent, B as MeshGeometryComponent, F as MeshGeometryParameters, G as MeshGeometryParametersByKind, H as ModelComponent, N as Name, O as Object3DRef, P as PhysicsComponent, J as PhysicsState, K as PlaneMeshParameters, R as RadiusHeightMeshParameters, Q as RadiusMeshParameters, S as RigidbodyState, T as RigidbodyType, U as ScriptComponent, V as ScriptEntry, W as ScriptObjectComponent, X as ScriptObjectComponentInput, Y as ScriptObjectRuntimeState, Z as Selectable, _ as SelectionTransformState, $ as SpriteComponent, a0 as TextureFilteringValue, a1 as TransformModeValue, a2 as TransformSpaceValue, a3 as VRTeleportAreaComponent, a4 as VRTeleportAreaOptions, a5 as VideoComponent, a6 as VrTeleportShape, a7 as XRInteractableComponent, a8 as XRInteractableOptions, a9 as XRInteractorComponent, aa as XRInteractorOptions, ab as XRInteractorSideComponent, ac as XRRigComponent, ad as XRRigOptions, ae as XrGrabMode, af as XrHandPreset, ag as XrInteractorSide, ah as XrInteractorType, ai as XrLocomotionMode, aj as XrTrackingOrigin, ak as defaultMaterialValue, al as normalizePhysicsState, am as setPhysicsLiveRef } from '../XRInteractor-I2q6TKtF.cjs';
2
- export { D as DEFAULT_ENVIRONMENT_STATE, a as DEFAULT_POSTPROCESSING_STATE, E as Environment, b as EnvironmentFogState, c as EnvironmentFogType, d as EnvironmentGradientEffect, e as EnvironmentSkyboxState, f as EnvironmentSkyboxType, g as EnvironmentState, P as ParentId, h as Postprocessing, i as PostprocessingState, T as TransformComponent, j as TransformData, V as Vec3 } from '../System-TmC2EijF.cjs';
3
- export { P as PrefabInstance, a as PrefabNode } from '../index-BltjPEhg.cjs';
1
+ export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, C as CameraComponent, c as CameraComponentOptions, d as CameraProjection, e as CameraRuntimeType, f as ColliderShape, g as ColliderState, h as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, i as DEFAULT_INSTANCED_MESH_PARAMETERS, j as DEFAULT_INSTANCE_TRANSFORM, k as DEFAULT_MESH_GEOMETRY_PARAMETERS, l as DEFAULT_PHYSICS_STATE, m as DEFAULT_POSE_CURLS, n as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, o as EntityType, I as ImageComponent, p as ImageTarget, q as ImageTargetAnchor, r as ImageTargetAnchorOptions, s as ImageTargetReference, t as InstanceSlotComponent, u as InstanceTransform, v as InstancedMeshComponent, w as InstancedMeshKind, L as LightComponent, x as LightValueState, M as MaterialComponent, y as MaterialTypeValue, z as MaterialValueState, B as MeshComponent, F as MeshGeometryComponent, G as MeshGeometryParameters, H as MeshGeometryParametersByKind, J as ModelComponent, N as Name, O as Object3DRef, P as PhysicsComponent, K as PhysicsState, Q as PlaneMeshParameters, R as RadiusHeightMeshParameters, S as RadiusMeshParameters, T as RigidbodyState, U as RigidbodyType, V as ScriptComponent, W as ScriptEntry, X as ScriptObjectComponent, Y as ScriptObjectComponentInput, Z as ScriptObjectRuntimeState, _ as Selectable, $ as SelectionTransformState, a0 as SpriteComponent, a1 as TextureFilteringValue, a2 as TransformModeValue, a3 as TransformSpaceValue, a4 as VRTeleportAreaComponent, a5 as VRTeleportAreaOptions, a6 as VideoComponent, a7 as VrTeleportShape, a8 as XRHandPoseComponent, a9 as XRHandPoseOptions, aa as XRInteractableComponent, ab as XRInteractableOptions, ac as XRInteractorComponent, ad as XRInteractorOptions, ae as XRInteractorSideComponent, af as XRRigComponent, ag as XRRigOptions, ah as XrGrabMode, ai as XrHandPoseEntry, aj as XrHandPreset, ak as XrInteractorSide, al as XrInteractorType, am as XrLocomotionMode, an as XrTrackingOrigin, ao as createHandPoseEntry, ap as defaultMaterialValue, aq as handPoseDefinitionFor, ar as normalizePhysicsState, as as setPhysicsLiveRef } from '../XRHandPose-VuSbe4iz.cjs';
2
+ export { D as DEFAULT_ENVIRONMENT_STATE, a as DEFAULT_POSTPROCESSING_STATE, E as Environment, b as EnvironmentFogState, c as EnvironmentFogType, d as EnvironmentGradientEffect, e as EnvironmentSkyboxState, f as EnvironmentSkyboxType, g as EnvironmentState, P as ParentId, h as Postprocessing, i as PostprocessingState, T as TransformComponent, j as TransformData, V as Vec3 } from '../System-31wk-A0g.cjs';
3
+ export { P as PrefabInstance, a as PrefabNode } from '../index-BIQoaKAA.cjs';
4
4
  import 'three';
5
5
  import '@dimforge/rapier3d-compat';
6
+ import '../handPose-dFxqbFFY.cjs';
@@ -1,5 +1,6 @@
1
- export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, C as CameraComponent, c as CameraComponentOptions, d as CameraProjection, e as CameraRuntimeType, f as ColliderShape, g as ColliderState, h as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, i as DEFAULT_INSTANCED_MESH_PARAMETERS, j as DEFAULT_INSTANCE_TRANSFORM, k as DEFAULT_MESH_GEOMETRY_PARAMETERS, l as DEFAULT_PHYSICS_STATE, m as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, n as EntityType, I as ImageComponent, o as ImageTarget, p as ImageTargetAnchor, q as ImageTargetAnchorOptions, r as ImageTargetReference, s as InstanceSlotComponent, t as InstanceTransform, u as InstancedMeshComponent, v as InstancedMeshKind, L as LightComponent, w as LightValueState, M as MaterialComponent, x as MaterialTypeValue, y as MaterialValueState, z as MeshComponent, B as MeshGeometryComponent, F as MeshGeometryParameters, G as MeshGeometryParametersByKind, H as ModelComponent, N as Name, O as Object3DRef, P as PhysicsComponent, J as PhysicsState, K as PlaneMeshParameters, R as RadiusHeightMeshParameters, Q as RadiusMeshParameters, S as RigidbodyState, T as RigidbodyType, U as ScriptComponent, V as ScriptEntry, W as ScriptObjectComponent, X as ScriptObjectComponentInput, Y as ScriptObjectRuntimeState, Z as Selectable, _ as SelectionTransformState, $ as SpriteComponent, a0 as TextureFilteringValue, a1 as TransformModeValue, a2 as TransformSpaceValue, a3 as VRTeleportAreaComponent, a4 as VRTeleportAreaOptions, a5 as VideoComponent, a6 as VrTeleportShape, a7 as XRInteractableComponent, a8 as XRInteractableOptions, a9 as XRInteractorComponent, aa as XRInteractorOptions, ab as XRInteractorSideComponent, ac as XRRigComponent, ad as XRRigOptions, ae as XrGrabMode, af as XrHandPreset, ag as XrInteractorSide, ah as XrInteractorType, ai as XrLocomotionMode, aj as XrTrackingOrigin, ak as defaultMaterialValue, al as normalizePhysicsState, am as setPhysicsLiveRef } from '../XRInteractor-CCUzSqg9.js';
2
- export { D as DEFAULT_ENVIRONMENT_STATE, a as DEFAULT_POSTPROCESSING_STATE, E as Environment, b as EnvironmentFogState, c as EnvironmentFogType, d as EnvironmentGradientEffect, e as EnvironmentSkyboxState, f as EnvironmentSkyboxType, g as EnvironmentState, P as ParentId, h as Postprocessing, i as PostprocessingState, T as TransformComponent, j as TransformData, V as Vec3 } from '../System-TmC2EijF.js';
3
- export { P as PrefabInstance, a as PrefabNode } from '../index-W8pUajCW.js';
1
+ export { A as AnimationComponent, a as AnimationComponentOptions, b as AudioComponent, C as CameraComponent, c as CameraComponentOptions, d as CameraProjection, e as CameraRuntimeType, f as ColliderShape, g as ColliderState, h as CubeMeshParameters, D as DEFAULT_COLLIDER_STATE, i as DEFAULT_INSTANCED_MESH_PARAMETERS, j as DEFAULT_INSTANCE_TRANSFORM, k as DEFAULT_MESH_GEOMETRY_PARAMETERS, l as DEFAULT_PHYSICS_STATE, m as DEFAULT_POSE_CURLS, n as DEFAULT_RIGIDBODY_STATE, E as EditableMeshObjectKind, o as EntityType, I as ImageComponent, p as ImageTarget, q as ImageTargetAnchor, r as ImageTargetAnchorOptions, s as ImageTargetReference, t as InstanceSlotComponent, u as InstanceTransform, v as InstancedMeshComponent, w as InstancedMeshKind, L as LightComponent, x as LightValueState, M as MaterialComponent, y as MaterialTypeValue, z as MaterialValueState, B as MeshComponent, F as MeshGeometryComponent, G as MeshGeometryParameters, H as MeshGeometryParametersByKind, J as ModelComponent, N as Name, O as Object3DRef, P as PhysicsComponent, K as PhysicsState, Q as PlaneMeshParameters, R as RadiusHeightMeshParameters, S as RadiusMeshParameters, T as RigidbodyState, U as RigidbodyType, V as ScriptComponent, W as ScriptEntry, X as ScriptObjectComponent, Y as ScriptObjectComponentInput, Z as ScriptObjectRuntimeState, _ as Selectable, $ as SelectionTransformState, a0 as SpriteComponent, a1 as TextureFilteringValue, a2 as TransformModeValue, a3 as TransformSpaceValue, a4 as VRTeleportAreaComponent, a5 as VRTeleportAreaOptions, a6 as VideoComponent, a7 as VrTeleportShape, a8 as XRHandPoseComponent, a9 as XRHandPoseOptions, aa as XRInteractableComponent, ab as XRInteractableOptions, ac as XRInteractorComponent, ad as XRInteractorOptions, ae as XRInteractorSideComponent, af as XRRigComponent, ag as XRRigOptions, ah as XrGrabMode, ai as XrHandPoseEntry, aj as XrHandPreset, ak as XrInteractorSide, al as XrInteractorType, am as XrLocomotionMode, an as XrTrackingOrigin, ao as createHandPoseEntry, ap as defaultMaterialValue, aq as handPoseDefinitionFor, ar as normalizePhysicsState, as as setPhysicsLiveRef } from '../XRHandPose-CxPz8VBp.js';
2
+ export { D as DEFAULT_ENVIRONMENT_STATE, a as DEFAULT_POSTPROCESSING_STATE, E as Environment, b as EnvironmentFogState, c as EnvironmentFogType, d as EnvironmentGradientEffect, e as EnvironmentSkyboxState, f as EnvironmentSkyboxType, g as EnvironmentState, P as ParentId, h as Postprocessing, i as PostprocessingState, T as TransformComponent, j as TransformData, V as Vec3 } from '../System-31wk-A0g.js';
3
+ export { P as PrefabInstance, a as PrefabNode } from '../index-BxdXgqiI.js';
4
4
  import 'three';
5
5
  import '@dimforge/rapier3d-compat';
6
+ import '../handPose-dFxqbFFY.js';
@@ -1,4 +1,4 @@
1
- export { AnimationComponent, AudioComponent, CameraComponent, DEFAULT_COLLIDER_STATE, DEFAULT_ENVIRONMENT_STATE, DEFAULT_INSTANCED_MESH_PARAMETERS, DEFAULT_INSTANCE_TRANSFORM, DEFAULT_MESH_GEOMETRY_PARAMETERS, DEFAULT_PHYSICS_STATE, DEFAULT_POSTPROCESSING_STATE, DEFAULT_RIGIDBODY_STATE, EntityType, Environment, ImageComponent, ImageTarget, ImageTargetAnchor, InstanceSlotComponent, InstancedMeshComponent, LightComponent, MaterialComponent, MeshComponent, MeshGeometryComponent, ModelComponent, Name, Object3DRef, ParentId, PhysicsComponent, Postprocessing, PrefabInstance, PrefabNode, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, VRTeleportAreaComponent, VideoComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, XRRigComponent, defaultMaterialValue, normalizePhysicsState, setPhysicsLiveRef } from '../chunk-N4GKZ7IV.js';
1
+ export { AnimationComponent, AudioComponent, CameraComponent, DEFAULT_COLLIDER_STATE, DEFAULT_ENVIRONMENT_STATE, DEFAULT_INSTANCED_MESH_PARAMETERS, DEFAULT_INSTANCE_TRANSFORM, DEFAULT_MESH_GEOMETRY_PARAMETERS, DEFAULT_PHYSICS_STATE, DEFAULT_POSE_CURLS, DEFAULT_POSTPROCESSING_STATE, DEFAULT_RIGIDBODY_STATE, EntityType, Environment, ImageComponent, ImageTarget, ImageTargetAnchor, InstanceSlotComponent, InstancedMeshComponent, LightComponent, MaterialComponent, MeshComponent, MeshGeometryComponent, ModelComponent, Name, Object3DRef, ParentId, PhysicsComponent, Postprocessing, PrefabInstance, PrefabNode, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, VRTeleportAreaComponent, VideoComponent, XRHandPoseComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, XRRigComponent, createHandPoseEntry, defaultMaterialValue, handPoseDefinitionFor, normalizePhysicsState, setPhysicsLiveRef } from '../chunk-KVGGAL5V.js';
2
2
  import '../chunk-OY7ZODZP.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,111 @@
1
+ # VR, Grabbing and Hand Poses
2
+
3
+ VR projects run on raw WebXR. Behaviours receive XR events through hooks, exactly like `onUpdate` or `onTargetFound` — there is no separate XR API to import.
4
+
5
+ ## Session hooks
6
+
7
+ ```ts
8
+ import { Behaviour, type XrCapabilities } from "@relu-interactives/spatial-ecs";
9
+
10
+ export default class Greeter extends Behaviour {
11
+ onXRSessionStart(capabilities: XrCapabilities) {
12
+ // What the headset actually granted — never guess from the user agent.
13
+ if (capabilities.handTracking) { /* … */ }
14
+ }
15
+
16
+ onXRSessionEnd() { /* … */ }
17
+ }
18
+ ```
19
+
20
+ `XrCapabilities` carries `mode`, `handTracking`, `planeDetection`, `meshDetection`, `depthSensing`, `anchors`, `hitTest` and the raw `enabledFeatures` array.
21
+
22
+ ## Pointer and grab hooks
23
+
24
+ | Hook | Fires when |
25
+ | --- | --- |
26
+ | `onSelectStart(input)` | Trigger pressed / finger pinched. |
27
+ | `onSelectEnd(input)` | Released. |
28
+ | `onGrab(input)` | This entity was picked up. |
29
+ | `onRelease(input)` | This entity was let go. |
30
+ | `onHandPoseStart(event)` | A hand pose declared on this entity began. |
31
+ | `onHandPoseEnd(event)` | That pose ended. |
32
+
33
+ `input` is an `XrInputState`: `handedness`, `kind` (`controller` / `hand` / `transient-pointer` / `gaze`), `rayOrigin`, `rayDirection`, `gripPosition`, `gripQuaternion`, `select`, `squeeze`, `axes`, `buttons`, and `joints` for tracked hands.
34
+
35
+ ### Grabbing and throwing
36
+
37
+ Add an **XR Interactable** component in the inspector. The useful fields:
38
+
39
+ - **Reach** — `physical` (hand must touch it), `distance` (grab along the pointer ray), or `both`.
40
+ - **At Distance** — `snap` brings it to the hand, `remote` manipulates it where it stands.
41
+ - **Gesture** — `pinch`, `full` grip, or `any`.
42
+ - **Grab Mode** — `kinematic` follows the hand exactly; `physics` keeps the body simulated.
43
+ - **Hold Offset** — where the object sits in the hand once held.
44
+ - **Throw on Release** — carries hand momentum into the body.
45
+
46
+ For a throwable ball, the object needs a **dynamic rigidbody**, Grab Mode `physics`, and Throw on Release enabled. Release velocity is taken from the peak of a short window of hand motion, so throws match the motion the user made rather than the frame they opened their hand.
47
+
48
+ ```ts
49
+ import { Behaviour } from "@relu-interactives/spatial-ecs";
50
+
51
+ export default class Basketball extends Behaviour {
52
+ onGrab() {
53
+ console.log("picked up");
54
+ }
55
+
56
+ onRelease() {
57
+ // The throw itself is applied by the engine — react to it here.
58
+ console.log("thrown");
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Hand poses
64
+
65
+ Add an **XR Hand Pose** component and list the poses to watch for. Each is either a built-in preset or a custom set of finger curls.
66
+
67
+ ```ts
68
+ import {
69
+ Behaviour,
70
+ Object3DRef,
71
+ type XrHandPoseEventDetail,
72
+ } from "@relu-interactives/spatial-ecs";
73
+
74
+ export default class Portal extends Behaviour {
75
+ onHandPoseStart(event: XrHandPoseEventDetail) {
76
+ if (event.poseId === "open-portal") this.show(true);
77
+ }
78
+
79
+ onHandPoseEnd(event: XrHandPoseEventDetail) {
80
+ if (event.poseId === "open-portal") this.show(false);
81
+ }
82
+
83
+ private show(visible: boolean) {
84
+ const ref = this.getComponent(Object3DRef);
85
+ if (ref) ref.visibility = visible;
86
+ }
87
+ }
88
+ ```
89
+
90
+ `XrHandPoseEventDetail` is `{ poseId, poseName, handedness, confidence }`. Match on `poseId` — it is the id set in the inspector, not the preset name.
91
+
92
+ ### Presets
93
+
94
+ `fist`, `open-palm`, `point`, `thumbs-up`, `thumbs-down`, `peace`, `pinch`, `ok`, `gun`, `rock`, `shaka`, `palm-up`.
95
+
96
+ ### Custom poses
97
+
98
+ A custom pose is five curl values, `0` (finger straight) to `1` (fully closed), plus a tolerance. Poses are matched on normalized finger curl rather than raw joint positions, and every distance is scaled by the user's palm width — so a pose authored once matches hands of any size.
99
+
100
+ Optionally add a **direction** requirement: which way the palm, fingers, or thumb must point (`up`, `down`, `forward`, `back`, `left`, `right`, `toward-head`, `away-from-head`) within an angle tolerance. This is what separates thumbs-up from thumbs-down, which are the same hand shape.
101
+
102
+ ### Tuning
103
+
104
+ - **Tolerance** — raise it if a pose is hard to trigger, lower it if it fires by accident.
105
+ - **Hold Time** — seconds the pose must be sustained before firing. Fingers pass through many shapes on the way to the intended one; a hold time stops those firing.
106
+
107
+ A pose does not re-fire while held, and survives a brief hand-tracking dropout rather than flickering.
108
+
109
+ ## Locomotion
110
+
111
+ Movement is a property of the **XR Rig**, not of scripts: tracking origin (floor or eye level), locomotion mode, move speed, and snap turn. Teleport destinations are **Teleport Area** entities. Scripts should move the rig, never the camera — while a session is presenting, the headset owns the camera and writes its pose every frame.
@@ -2286,6 +2286,46 @@ function createVRTeleportAreaComponent(world, entityId, ...args) {
2286
2286
  }
2287
2287
  __name(createVRTeleportAreaComponent, "createVRTeleportAreaComponent");
2288
2288
 
2289
+ // core/components/XRHandPose.ts
2290
+ var DEFAULT_POSE_CURLS = {
2291
+ thumb: 0,
2292
+ index: 0,
2293
+ middle: 0,
2294
+ ring: 0,
2295
+ pinky: 0
2296
+ };
2297
+ function createHandPoseEntry(partial) {
2298
+ return {
2299
+ id: partial.id,
2300
+ name: partial.name ?? partial.id,
2301
+ preset: partial.preset ?? null,
2302
+ curls: { ...DEFAULT_POSE_CURLS, ...partial.curls },
2303
+ tolerance: partial.tolerance ?? 0.25,
2304
+ hand: partial.hand ?? null,
2305
+ orientation: partial.orientation ?? null,
2306
+ minHoldSeconds: partial.minHoldSeconds ?? 0.15,
2307
+ enabled: partial.enabled ?? true
2308
+ };
2309
+ }
2310
+ __name(createHandPoseEntry, "createHandPoseEntry");
2311
+ var _XRHandPoseComponent = class _XRHandPoseComponent extends Component {
2312
+ constructor(options) {
2313
+ super();
2314
+ this.enabled = options?.enabled ?? true;
2315
+ this.poses = (options?.poses ?? []).map((pose) => createHandPoseEntry(pose));
2316
+ }
2317
+ };
2318
+ __name(_XRHandPoseComponent, "XRHandPoseComponent");
2319
+ var XRHandPoseComponent = _XRHandPoseComponent;
2320
+
2321
+ // core/factories/components/XRHandPoseFactory.ts
2322
+ function createXRHandPoseComponent(world, entityId, ...args) {
2323
+ const component = new XRHandPoseComponent(...args);
2324
+ world.addComponent(entityId, component);
2325
+ return component;
2326
+ }
2327
+ __name(createXRHandPoseComponent, "createXRHandPoseComponent");
2328
+
2289
2329
  // core/components/XRInteractable.ts
2290
2330
  var _XRInteractableComponent = class _XRInteractableComponent extends Component {
2291
2331
  constructor(options) {
@@ -2294,6 +2334,22 @@ var _XRInteractableComponent = class _XRInteractableComponent extends Component
2294
2334
  this.grabbable = options?.grabbable ?? true;
2295
2335
  this.pointable = options?.pointable ?? true;
2296
2336
  this.grabMode = options?.grabMode ?? "kinematic";
2337
+ this.grabReach = options?.grabReach ?? "both";
2338
+ this.distanceBehavior = options?.distanceBehavior ?? "snap";
2339
+ this.grabGesture = options?.grabGesture ?? "any";
2340
+ this.grabRadius = options?.grabRadius ?? 0.15;
2341
+ this.grabOffsetPosition = options?.grabOffsetPosition ?? {
2342
+ x: 0,
2343
+ y: 0,
2344
+ z: 0
2345
+ };
2346
+ this.grabOffsetRotation = options?.grabOffsetRotation ?? {
2347
+ x: 0,
2348
+ y: 0,
2349
+ z: 0
2350
+ };
2351
+ this.throwOnRelease = options?.throwOnRelease ?? true;
2352
+ this.throwStrength = options?.throwStrength ?? 1;
2297
2353
  this.highlightOnHover = options?.highlightOnHover ?? true;
2298
2354
  }
2299
2355
  };
@@ -2358,6 +2414,7 @@ function registerDefaultComponentFactories(objectManagementSystem) {
2358
2414
  objectManagementSystem.registerComponentFactory("image", createImageComponent);
2359
2415
  objectManagementSystem.registerComponentFactory("xrRig", createXRRigComponent);
2360
2416
  objectManagementSystem.registerComponentFactory("vrTeleportArea", createVRTeleportAreaComponent);
2417
+ objectManagementSystem.registerComponentFactory("xrHandPose", createXRHandPoseComponent);
2361
2418
  objectManagementSystem.registerComponentFactory("xrInteractable", createXRInteractableComponent);
2362
2419
  objectManagementSystem.registerComponentFactory("xrInteractor", createXRInteractorComponent);
2363
2420
  objectManagementSystem.registerComponentFactory("xrInteractorSide", createXRInteractorSideComponent);
@@ -3683,6 +3740,7 @@ exports.createSpriteComponent = createSpriteComponent;
3683
3740
  exports.createTransformComponent = createTransformComponent;
3684
3741
  exports.createVRTeleportAreaComponent = createVRTeleportAreaComponent;
3685
3742
  exports.createVideoComponent = createVideoComponent;
3743
+ exports.createXRHandPoseComponent = createXRHandPoseComponent;
3686
3744
  exports.createXRInteractableComponent = createXRInteractableComponent;
3687
3745
  exports.createXRInteractorComponent = createXRInteractorComponent;
3688
3746
  exports.createXRInteractorSideComponent = createXRInteractorSideComponent;