@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
@@ -612,7 +612,7 @@ type CreateContext = {
612
612
  isEditor?: boolean;
613
613
  };
614
614
  type EntityFactory = (context: CreateContext) => EntityId;
615
- type EcsComponentFactoryKind = "animation" | "audio" | "camera" | "environment" | "entityType" | "image" | "imageTargetAnchor" | "imageTarget" | "light" | "material" | "mesh" | "meshGeometry" | "model" | "name" | "object3DRef" | "parentId" | "physics" | "postprocessing" | "script" | "scriptObject" | "selectable" | "selectionTransformState" | "sprite" | "transform" | "video" | "instancedMesh" | "xrRig" | "vrTeleportArea" | "xrInteractable" | "xrInteractor" | "xrInteractorSide";
615
+ type EcsComponentFactoryKind = "animation" | "audio" | "camera" | "environment" | "entityType" | "image" | "imageTargetAnchor" | "imageTarget" | "light" | "material" | "mesh" | "meshGeometry" | "model" | "name" | "object3DRef" | "parentId" | "physics" | "postprocessing" | "script" | "scriptObject" | "selectable" | "selectionTransformState" | "sprite" | "transform" | "video" | "instancedMesh" | "xrRig" | "vrTeleportArea" | "xrHandPose" | "xrInteractable" | "xrInteractor" | "xrInteractorSide";
616
616
  type ComponentFactory = (world: World, entityId: EntityId, ...args: any[]) => unknown;
617
617
  declare class ObjectManagementSystem implements EcsSystem {
618
618
  private readonly scene;
@@ -612,7 +612,7 @@ type CreateContext = {
612
612
  isEditor?: boolean;
613
613
  };
614
614
  type EntityFactory = (context: CreateContext) => EntityId;
615
- type EcsComponentFactoryKind = "animation" | "audio" | "camera" | "environment" | "entityType" | "image" | "imageTargetAnchor" | "imageTarget" | "light" | "material" | "mesh" | "meshGeometry" | "model" | "name" | "object3DRef" | "parentId" | "physics" | "postprocessing" | "script" | "scriptObject" | "selectable" | "selectionTransformState" | "sprite" | "transform" | "video" | "instancedMesh" | "xrRig" | "vrTeleportArea" | "xrInteractable" | "xrInteractor" | "xrInteractorSide";
615
+ type EcsComponentFactoryKind = "animation" | "audio" | "camera" | "environment" | "entityType" | "image" | "imageTargetAnchor" | "imageTarget" | "light" | "material" | "mesh" | "meshGeometry" | "model" | "name" | "object3DRef" | "parentId" | "physics" | "postprocessing" | "script" | "scriptObject" | "selectable" | "selectionTransformState" | "sprite" | "transform" | "video" | "instancedMesh" | "xrRig" | "vrTeleportArea" | "xrHandPose" | "xrInteractable" | "xrInteractor" | "xrInteractorSide";
616
616
  type ComponentFactory = (world: World, entityId: EntityId, ...args: any[]) => unknown;
617
617
  declare class ObjectManagementSystem implements EcsSystem {
618
618
  private readonly scene;
@@ -1,6 +1,7 @@
1
1
  import * as THREE from 'three';
2
- import { C as Component, p as EcsEntityKind, F as EcsEntityEditorKind, r as EntityId } from './System-TmC2EijF.js';
2
+ import { C as Component, p as EcsEntityKind, F as EcsEntityEditorKind, r as EntityId } from './System-31wk-A0g.js';
3
3
  import * as RAPIER from '@dimforge/rapier3d-compat';
4
+ import { a as XrFinger, b as XrHandPoseOrientation, X as XrHandPoseDefinition } from './handPose-dFxqbFFY.js';
4
5
 
5
6
  interface StateMachine {
6
7
  name: string;
@@ -1208,46 +1209,105 @@ declare class VRTeleportAreaComponent extends Component {
1208
1209
  }
1209
1210
 
1210
1211
  /**
1211
- * How a grabbed entity behaves while held.
1212
+ * How an entity behaves while held.
1212
1213
  *
1213
- * `kinematic` snaps it to the hand and ignores physics — predictable, and the
1214
- * right default. `physics` keeps the body simulated so it can collide while
1215
- * held and carry momentum when thrown.
1214
+ * `kinematic` snaps it to the hand and ignores physics — predictable, and right
1215
+ * for tools and UI. `physics` keeps the body simulated so it can collide while
1216
+ * held and, crucially, carry momentum when released (see {@link throwOnRelease}).
1216
1217
  */
1217
1218
  type XrGrabMode = "kinematic" | "physics";
1219
+ /**
1220
+ * How close the user must be to grab.
1221
+ *
1222
+ * `physical` requires the hand to actually reach the object — the honest,
1223
+ * embodied interaction. `distance` allows grabbing across the room along the
1224
+ * pointer ray, which is what makes seated and room-scale play comfortable.
1225
+ * `both` accepts either, and is the friendliest default.
1226
+ */
1227
+ type XrGrabReach = "physical" | "distance" | "both";
1228
+ /**
1229
+ * What a distance grab does to the object.
1230
+ *
1231
+ * `snap` brings it to the hand (Half-Life: Alyx style — good for picking things
1232
+ * up). `remote` leaves it where it is and manipulates it at range, which suits
1233
+ * large or anchored objects that would look absurd flying into your palm.
1234
+ */
1235
+ type XrDistanceGrabBehavior = "snap" | "remote";
1236
+ /**
1237
+ * Which gesture grabs the object.
1238
+ *
1239
+ * `pinch` maps to the primary action (trigger / finger pinch), `full` to the
1240
+ * grip squeeze (whole-hand close). Distinguishing them lets a scene mix
1241
+ * precise pickups with firm grabs — a chess piece versus a suitcase handle.
1242
+ */
1243
+ type XrGrabGesture = "any" | "pinch" | "full";
1218
1244
  /** Optional initializer for {@link XRInteractableComponent}. */
1219
1245
  type XRInteractableOptions = {
1220
- /** Disable to keep the entity authored but non-interactive. */
1221
1246
  enabled?: boolean;
1222
- /** Can be picked up and held. */
1223
1247
  grabbable?: boolean;
1224
- /** Can be hit by a pointer ray (hover + select), without being grabbable. */
1225
1248
  pointable?: boolean;
1226
- /** Behaviour while held. */
1227
1249
  grabMode?: XrGrabMode;
1228
- /** Emphasize the entity while a pointer is over it. */
1250
+ grabReach?: XrGrabReach;
1251
+ distanceBehavior?: XrDistanceGrabBehavior;
1252
+ grabGesture?: XrGrabGesture;
1253
+ /** Metres within which a `physical` grab registers. */
1254
+ grabRadius?: number;
1255
+ /** Where the object sits relative to the hand once held. */
1256
+ grabOffsetPosition?: {
1257
+ x: number;
1258
+ y: number;
1259
+ z: number;
1260
+ };
1261
+ /** Orientation offset, in radians. */
1262
+ grabOffsetRotation?: {
1263
+ x: number;
1264
+ y: number;
1265
+ z: number;
1266
+ };
1267
+ /** Carry the hand's momentum into the body on release. */
1268
+ throwOnRelease?: boolean;
1269
+ /** Scales released velocity; >1 makes throws feel stronger than real life. */
1270
+ throwStrength?: number;
1229
1271
  highlightOnHover?: boolean;
1230
1272
  };
1231
1273
  /**
1232
1274
  * Makes an entity respond to XR pointers and hands.
1233
1275
  *
1234
- * Split into `pointable` and `grabbable` because they are genuinely different
1235
- * affordances: a wall-mounted UI panel should receive select events without
1236
- * being liftable, while a physics prop should be both. Interaction is opt-in
1237
- * per entity so a scene's interactive surface is explicit.
1276
+ * Split into `pointable` and `grabbable` because they are different
1277
+ * affordances: a wall panel should receive select events without being
1278
+ * liftable, while a physics prop should be both.
1238
1279
  *
1239
1280
  * @category Components
1240
1281
  */
1241
1282
  declare class XRInteractableComponent extends Component {
1242
- /** Whether this entity currently responds to XR input. */
1243
1283
  enabled: boolean;
1244
- /** Can be picked up and held. */
1245
1284
  grabbable: boolean;
1246
- /** Can be hit by a pointer ray. */
1247
1285
  pointable: boolean;
1248
- /** Behaviour while held. */
1249
1286
  grabMode: XrGrabMode;
1250
- /** Emphasize while hovered. */
1287
+ /** Whether the object can be grabbed up close, at range, or either. */
1288
+ grabReach: XrGrabReach;
1289
+ /** What a distance grab does — bring it here, or manipulate it in place. */
1290
+ distanceBehavior: XrDistanceGrabBehavior;
1291
+ /** Which gesture grabs it. */
1292
+ grabGesture: XrGrabGesture;
1293
+ /** Metres within which a physical grab registers. */
1294
+ grabRadius: number;
1295
+ /** Position offset from the hand while held. */
1296
+ grabOffsetPosition: {
1297
+ x: number;
1298
+ y: number;
1299
+ z: number;
1300
+ };
1301
+ /** Rotation offset (radians) while held. */
1302
+ grabOffsetRotation: {
1303
+ x: number;
1304
+ y: number;
1305
+ z: number;
1306
+ };
1307
+ /** Carry hand momentum into the body on release. */
1308
+ throwOnRelease: boolean;
1309
+ /** Multiplier on released velocity. */
1310
+ throwStrength: number;
1251
1311
  highlightOnHover: boolean;
1252
1312
  constructor(options?: XRInteractableOptions);
1253
1313
  }
@@ -1389,4 +1449,63 @@ declare class XRInteractorSideComponent extends Component {
1389
1449
  });
1390
1450
  }
1391
1451
 
1392
- export { SpriteComponent as $, AnimationComponent as A, MeshGeometryComponent as B, CameraComponent as C, DEFAULT_COLLIDER_STATE as D, type EditableMeshObjectKind as E, type MeshGeometryParameters as F, type MeshGeometryParametersByKind as G, ModelComponent as H, ImageComponent as I, type PhysicsState as J, type PlaneMeshParameters as K, LightComponent as L, MaterialComponent as M, Name as N, Object3DRef as O, PhysicsComponent as P, type RadiusMeshParameters as Q, type RadiusHeightMeshParameters as R, type RigidbodyState as S, type RigidbodyType as T, ScriptComponent as U, type ScriptEntry as V, ScriptObjectComponent as W, type ScriptObjectComponentInput as X, type ScriptObjectRuntimeState as Y, Selectable as Z, SelectionTransformState as _, type AnimationComponentOptions as a, type TextureFilteringValue as a0, type TransformModeValue as a1, type TransformSpaceValue as a2, VRTeleportAreaComponent as a3, type VRTeleportAreaOptions as a4, VideoComponent as a5, type VrTeleportShape as a6, XRInteractableComponent as a7, type XRInteractableOptions as a8, XRInteractorComponent as a9, type XRInteractorOptions as aa, XRInteractorSideComponent as ab, XRRigComponent as ac, type XRRigOptions as ad, type XrGrabMode as ae, type XrHandPreset as af, type XrInteractorSide as ag, type XrInteractorType as ah, type XrLocomotionMode as ai, type XrTrackingOrigin as aj, defaultMaterialValue as ak, normalizePhysicsState as al, setPhysicsLiveRef as am, type AnimationStateCallbacks as an, AnimationStateMachine as ao, AnimationStateManager as ap, type StateMachine as aq, AudioComponent as b, type CameraComponentOptions as c, type CameraProjection as d, type CameraRuntimeType as e, type ColliderShape as f, type ColliderState as g, type CubeMeshParameters as h, DEFAULT_INSTANCED_MESH_PARAMETERS as i, DEFAULT_INSTANCE_TRANSFORM as j, DEFAULT_MESH_GEOMETRY_PARAMETERS as k, DEFAULT_PHYSICS_STATE as l, DEFAULT_RIGIDBODY_STATE as m, EntityType as n, ImageTarget as o, ImageTargetAnchor as p, type ImageTargetAnchorOptions as q, type ImageTargetReference as r, InstanceSlotComponent as s, type InstanceTransform as t, InstancedMeshComponent as u, type InstancedMeshKind as v, type LightValueState as w, type MaterialTypeValue as x, type MaterialValueState as y, MeshComponent as z };
1452
+ /**
1453
+ * One pose an entity listens for.
1454
+ *
1455
+ * A pose is either a named PRESET or a CUSTOM set of finger curls. Storing the
1456
+ * preset id rather than a copy of its numbers means a preset improved in a later
1457
+ * release reaches existing scenes, while custom poses stay pinned to exactly
1458
+ * what the author dialled in.
1459
+ */
1460
+ type XrHandPoseEntry = {
1461
+ /** Stable id, unique within the component. Used in Behaviour hooks. */
1462
+ id: string;
1463
+ /** Shown in the inspector and passed to scripts. */
1464
+ name: string;
1465
+ /** Preset id, or null for a custom pose. */
1466
+ preset: string | null;
1467
+ /** Per-finger curl targets, 0 extended → 1 curled. Custom poses only. */
1468
+ curls: Record<XrFinger, number>;
1469
+ /** Slack around each curl target. Larger is easier to perform. */
1470
+ tolerance: number;
1471
+ /** Which hand may trigger it; null for either. */
1472
+ hand: "left" | "right" | null;
1473
+ /** Optional direction requirement. */
1474
+ orientation: XrHandPoseOrientation | null;
1475
+ /** Seconds the pose must be held before it fires. */
1476
+ minHoldSeconds: number;
1477
+ enabled: boolean;
1478
+ };
1479
+ type XRHandPoseOptions = {
1480
+ enabled?: boolean;
1481
+ poses?: XrHandPoseEntry[];
1482
+ };
1483
+ declare const DEFAULT_POSE_CURLS: Record<XrFinger, number>;
1484
+ /** A pose entry with every field populated, for the editor and AI tools. */
1485
+ declare function createHandPoseEntry(partial: Partial<XrHandPoseEntry> & {
1486
+ id: string;
1487
+ }): XrHandPoseEntry;
1488
+ /**
1489
+ * Resolve an entry to the definition the matcher consumes.
1490
+ *
1491
+ * Preset entries defer to the shared library but still honour the entry's own
1492
+ * hand restriction and hold time, so a scene can reuse "thumbs up" while
1493
+ * scoping it to one hand.
1494
+ */
1495
+ declare function handPoseDefinitionFor(entry: XrHandPoseEntry, resolvePreset: (id: string) => XrHandPoseDefinition | null): XrHandPoseDefinition | null;
1496
+ /**
1497
+ * Listens for hand poses and reports them to the entity's Behaviours.
1498
+ *
1499
+ * Attached to any entity that wants to react to a gesture — the poses are
1500
+ * detected on the user's hands, not on the entity, so this is a subscription
1501
+ * rather than a property of the object itself.
1502
+ *
1503
+ * @category Components
1504
+ */
1505
+ declare class XRHandPoseComponent extends Component {
1506
+ enabled: boolean;
1507
+ poses: XrHandPoseEntry[];
1508
+ constructor(options?: XRHandPoseOptions);
1509
+ }
1510
+
1511
+ export { SelectionTransformState as $, AnimationComponent as A, MeshComponent as B, CameraComponent as C, DEFAULT_COLLIDER_STATE as D, type EditableMeshObjectKind as E, MeshGeometryComponent as F, type MeshGeometryParameters as G, type MeshGeometryParametersByKind as H, ImageComponent as I, ModelComponent as J, type PhysicsState as K, LightComponent as L, MaterialComponent as M, Name as N, Object3DRef as O, PhysicsComponent as P, type PlaneMeshParameters as Q, type RadiusHeightMeshParameters as R, type RadiusMeshParameters as S, type RigidbodyState as T, type RigidbodyType as U, ScriptComponent as V, type ScriptEntry as W, ScriptObjectComponent as X, type ScriptObjectComponentInput as Y, type ScriptObjectRuntimeState as Z, Selectable as _, type AnimationComponentOptions as a, SpriteComponent as a0, type TextureFilteringValue as a1, type TransformModeValue as a2, type TransformSpaceValue as a3, VRTeleportAreaComponent as a4, type VRTeleportAreaOptions as a5, VideoComponent as a6, type VrTeleportShape as a7, XRHandPoseComponent as a8, type XRHandPoseOptions as a9, XRInteractableComponent as aa, type XRInteractableOptions as ab, XRInteractorComponent as ac, type XRInteractorOptions as ad, XRInteractorSideComponent as ae, XRRigComponent as af, type XRRigOptions as ag, type XrGrabMode as ah, type XrHandPoseEntry as ai, type XrHandPreset as aj, type XrInteractorSide as ak, type XrInteractorType as al, type XrLocomotionMode as am, type XrTrackingOrigin as an, createHandPoseEntry as ao, defaultMaterialValue as ap, handPoseDefinitionFor as aq, normalizePhysicsState as ar, setPhysicsLiveRef as as, type AnimationStateCallbacks as at, AnimationStateMachine as au, AnimationStateManager as av, type StateMachine as aw, AudioComponent as b, type CameraComponentOptions as c, type CameraProjection as d, type CameraRuntimeType as e, type ColliderShape as f, type ColliderState as g, type CubeMeshParameters as h, DEFAULT_INSTANCED_MESH_PARAMETERS as i, DEFAULT_INSTANCE_TRANSFORM as j, DEFAULT_MESH_GEOMETRY_PARAMETERS as k, DEFAULT_PHYSICS_STATE as l, DEFAULT_POSE_CURLS as m, DEFAULT_RIGIDBODY_STATE as n, EntityType as o, ImageTarget as p, ImageTargetAnchor as q, type ImageTargetAnchorOptions as r, type ImageTargetReference as s, InstanceSlotComponent as t, type InstanceTransform as u, InstancedMeshComponent as v, type InstancedMeshKind as w, type LightValueState as x, type MaterialTypeValue as y, type MaterialValueState as z };
@@ -1,6 +1,7 @@
1
1
  import * as THREE from 'three';
2
- import { C as Component, p as EcsEntityKind, F as EcsEntityEditorKind, r as EntityId } from './System-TmC2EijF.cjs';
2
+ import { C as Component, p as EcsEntityKind, F as EcsEntityEditorKind, r as EntityId } from './System-31wk-A0g.cjs';
3
3
  import * as RAPIER from '@dimforge/rapier3d-compat';
4
+ import { a as XrFinger, b as XrHandPoseOrientation, X as XrHandPoseDefinition } from './handPose-dFxqbFFY.cjs';
4
5
 
5
6
  interface StateMachine {
6
7
  name: string;
@@ -1208,46 +1209,105 @@ declare class VRTeleportAreaComponent extends Component {
1208
1209
  }
1209
1210
 
1210
1211
  /**
1211
- * How a grabbed entity behaves while held.
1212
+ * How an entity behaves while held.
1212
1213
  *
1213
- * `kinematic` snaps it to the hand and ignores physics — predictable, and the
1214
- * right default. `physics` keeps the body simulated so it can collide while
1215
- * held and carry momentum when thrown.
1214
+ * `kinematic` snaps it to the hand and ignores physics — predictable, and right
1215
+ * for tools and UI. `physics` keeps the body simulated so it can collide while
1216
+ * held and, crucially, carry momentum when released (see {@link throwOnRelease}).
1216
1217
  */
1217
1218
  type XrGrabMode = "kinematic" | "physics";
1219
+ /**
1220
+ * How close the user must be to grab.
1221
+ *
1222
+ * `physical` requires the hand to actually reach the object — the honest,
1223
+ * embodied interaction. `distance` allows grabbing across the room along the
1224
+ * pointer ray, which is what makes seated and room-scale play comfortable.
1225
+ * `both` accepts either, and is the friendliest default.
1226
+ */
1227
+ type XrGrabReach = "physical" | "distance" | "both";
1228
+ /**
1229
+ * What a distance grab does to the object.
1230
+ *
1231
+ * `snap` brings it to the hand (Half-Life: Alyx style — good for picking things
1232
+ * up). `remote` leaves it where it is and manipulates it at range, which suits
1233
+ * large or anchored objects that would look absurd flying into your palm.
1234
+ */
1235
+ type XrDistanceGrabBehavior = "snap" | "remote";
1236
+ /**
1237
+ * Which gesture grabs the object.
1238
+ *
1239
+ * `pinch` maps to the primary action (trigger / finger pinch), `full` to the
1240
+ * grip squeeze (whole-hand close). Distinguishing them lets a scene mix
1241
+ * precise pickups with firm grabs — a chess piece versus a suitcase handle.
1242
+ */
1243
+ type XrGrabGesture = "any" | "pinch" | "full";
1218
1244
  /** Optional initializer for {@link XRInteractableComponent}. */
1219
1245
  type XRInteractableOptions = {
1220
- /** Disable to keep the entity authored but non-interactive. */
1221
1246
  enabled?: boolean;
1222
- /** Can be picked up and held. */
1223
1247
  grabbable?: boolean;
1224
- /** Can be hit by a pointer ray (hover + select), without being grabbable. */
1225
1248
  pointable?: boolean;
1226
- /** Behaviour while held. */
1227
1249
  grabMode?: XrGrabMode;
1228
- /** Emphasize the entity while a pointer is over it. */
1250
+ grabReach?: XrGrabReach;
1251
+ distanceBehavior?: XrDistanceGrabBehavior;
1252
+ grabGesture?: XrGrabGesture;
1253
+ /** Metres within which a `physical` grab registers. */
1254
+ grabRadius?: number;
1255
+ /** Where the object sits relative to the hand once held. */
1256
+ grabOffsetPosition?: {
1257
+ x: number;
1258
+ y: number;
1259
+ z: number;
1260
+ };
1261
+ /** Orientation offset, in radians. */
1262
+ grabOffsetRotation?: {
1263
+ x: number;
1264
+ y: number;
1265
+ z: number;
1266
+ };
1267
+ /** Carry the hand's momentum into the body on release. */
1268
+ throwOnRelease?: boolean;
1269
+ /** Scales released velocity; >1 makes throws feel stronger than real life. */
1270
+ throwStrength?: number;
1229
1271
  highlightOnHover?: boolean;
1230
1272
  };
1231
1273
  /**
1232
1274
  * Makes an entity respond to XR pointers and hands.
1233
1275
  *
1234
- * Split into `pointable` and `grabbable` because they are genuinely different
1235
- * affordances: a wall-mounted UI panel should receive select events without
1236
- * being liftable, while a physics prop should be both. Interaction is opt-in
1237
- * per entity so a scene's interactive surface is explicit.
1276
+ * Split into `pointable` and `grabbable` because they are different
1277
+ * affordances: a wall panel should receive select events without being
1278
+ * liftable, while a physics prop should be both.
1238
1279
  *
1239
1280
  * @category Components
1240
1281
  */
1241
1282
  declare class XRInteractableComponent extends Component {
1242
- /** Whether this entity currently responds to XR input. */
1243
1283
  enabled: boolean;
1244
- /** Can be picked up and held. */
1245
1284
  grabbable: boolean;
1246
- /** Can be hit by a pointer ray. */
1247
1285
  pointable: boolean;
1248
- /** Behaviour while held. */
1249
1286
  grabMode: XrGrabMode;
1250
- /** Emphasize while hovered. */
1287
+ /** Whether the object can be grabbed up close, at range, or either. */
1288
+ grabReach: XrGrabReach;
1289
+ /** What a distance grab does — bring it here, or manipulate it in place. */
1290
+ distanceBehavior: XrDistanceGrabBehavior;
1291
+ /** Which gesture grabs it. */
1292
+ grabGesture: XrGrabGesture;
1293
+ /** Metres within which a physical grab registers. */
1294
+ grabRadius: number;
1295
+ /** Position offset from the hand while held. */
1296
+ grabOffsetPosition: {
1297
+ x: number;
1298
+ y: number;
1299
+ z: number;
1300
+ };
1301
+ /** Rotation offset (radians) while held. */
1302
+ grabOffsetRotation: {
1303
+ x: number;
1304
+ y: number;
1305
+ z: number;
1306
+ };
1307
+ /** Carry hand momentum into the body on release. */
1308
+ throwOnRelease: boolean;
1309
+ /** Multiplier on released velocity. */
1310
+ throwStrength: number;
1251
1311
  highlightOnHover: boolean;
1252
1312
  constructor(options?: XRInteractableOptions);
1253
1313
  }
@@ -1389,4 +1449,63 @@ declare class XRInteractorSideComponent extends Component {
1389
1449
  });
1390
1450
  }
1391
1451
 
1392
- export { SpriteComponent as $, AnimationComponent as A, MeshGeometryComponent as B, CameraComponent as C, DEFAULT_COLLIDER_STATE as D, type EditableMeshObjectKind as E, type MeshGeometryParameters as F, type MeshGeometryParametersByKind as G, ModelComponent as H, ImageComponent as I, type PhysicsState as J, type PlaneMeshParameters as K, LightComponent as L, MaterialComponent as M, Name as N, Object3DRef as O, PhysicsComponent as P, type RadiusMeshParameters as Q, type RadiusHeightMeshParameters as R, type RigidbodyState as S, type RigidbodyType as T, ScriptComponent as U, type ScriptEntry as V, ScriptObjectComponent as W, type ScriptObjectComponentInput as X, type ScriptObjectRuntimeState as Y, Selectable as Z, SelectionTransformState as _, type AnimationComponentOptions as a, type TextureFilteringValue as a0, type TransformModeValue as a1, type TransformSpaceValue as a2, VRTeleportAreaComponent as a3, type VRTeleportAreaOptions as a4, VideoComponent as a5, type VrTeleportShape as a6, XRInteractableComponent as a7, type XRInteractableOptions as a8, XRInteractorComponent as a9, type XRInteractorOptions as aa, XRInteractorSideComponent as ab, XRRigComponent as ac, type XRRigOptions as ad, type XrGrabMode as ae, type XrHandPreset as af, type XrInteractorSide as ag, type XrInteractorType as ah, type XrLocomotionMode as ai, type XrTrackingOrigin as aj, defaultMaterialValue as ak, normalizePhysicsState as al, setPhysicsLiveRef as am, type AnimationStateCallbacks as an, AnimationStateMachine as ao, AnimationStateManager as ap, type StateMachine as aq, AudioComponent as b, type CameraComponentOptions as c, type CameraProjection as d, type CameraRuntimeType as e, type ColliderShape as f, type ColliderState as g, type CubeMeshParameters as h, DEFAULT_INSTANCED_MESH_PARAMETERS as i, DEFAULT_INSTANCE_TRANSFORM as j, DEFAULT_MESH_GEOMETRY_PARAMETERS as k, DEFAULT_PHYSICS_STATE as l, DEFAULT_RIGIDBODY_STATE as m, EntityType as n, ImageTarget as o, ImageTargetAnchor as p, type ImageTargetAnchorOptions as q, type ImageTargetReference as r, InstanceSlotComponent as s, type InstanceTransform as t, InstancedMeshComponent as u, type InstancedMeshKind as v, type LightValueState as w, type MaterialTypeValue as x, type MaterialValueState as y, MeshComponent as z };
1452
+ /**
1453
+ * One pose an entity listens for.
1454
+ *
1455
+ * A pose is either a named PRESET or a CUSTOM set of finger curls. Storing the
1456
+ * preset id rather than a copy of its numbers means a preset improved in a later
1457
+ * release reaches existing scenes, while custom poses stay pinned to exactly
1458
+ * what the author dialled in.
1459
+ */
1460
+ type XrHandPoseEntry = {
1461
+ /** Stable id, unique within the component. Used in Behaviour hooks. */
1462
+ id: string;
1463
+ /** Shown in the inspector and passed to scripts. */
1464
+ name: string;
1465
+ /** Preset id, or null for a custom pose. */
1466
+ preset: string | null;
1467
+ /** Per-finger curl targets, 0 extended → 1 curled. Custom poses only. */
1468
+ curls: Record<XrFinger, number>;
1469
+ /** Slack around each curl target. Larger is easier to perform. */
1470
+ tolerance: number;
1471
+ /** Which hand may trigger it; null for either. */
1472
+ hand: "left" | "right" | null;
1473
+ /** Optional direction requirement. */
1474
+ orientation: XrHandPoseOrientation | null;
1475
+ /** Seconds the pose must be held before it fires. */
1476
+ minHoldSeconds: number;
1477
+ enabled: boolean;
1478
+ };
1479
+ type XRHandPoseOptions = {
1480
+ enabled?: boolean;
1481
+ poses?: XrHandPoseEntry[];
1482
+ };
1483
+ declare const DEFAULT_POSE_CURLS: Record<XrFinger, number>;
1484
+ /** A pose entry with every field populated, for the editor and AI tools. */
1485
+ declare function createHandPoseEntry(partial: Partial<XrHandPoseEntry> & {
1486
+ id: string;
1487
+ }): XrHandPoseEntry;
1488
+ /**
1489
+ * Resolve an entry to the definition the matcher consumes.
1490
+ *
1491
+ * Preset entries defer to the shared library but still honour the entry's own
1492
+ * hand restriction and hold time, so a scene can reuse "thumbs up" while
1493
+ * scoping it to one hand.
1494
+ */
1495
+ declare function handPoseDefinitionFor(entry: XrHandPoseEntry, resolvePreset: (id: string) => XrHandPoseDefinition | null): XrHandPoseDefinition | null;
1496
+ /**
1497
+ * Listens for hand poses and reports them to the entity's Behaviours.
1498
+ *
1499
+ * Attached to any entity that wants to react to a gesture — the poses are
1500
+ * detected on the user's hands, not on the entity, so this is a subscription
1501
+ * rather than a property of the object itself.
1502
+ *
1503
+ * @category Components
1504
+ */
1505
+ declare class XRHandPoseComponent extends Component {
1506
+ enabled: boolean;
1507
+ poses: XrHandPoseEntry[];
1508
+ constructor(options?: XRHandPoseOptions);
1509
+ }
1510
+
1511
+ export { SelectionTransformState as $, AnimationComponent as A, MeshComponent as B, CameraComponent as C, DEFAULT_COLLIDER_STATE as D, type EditableMeshObjectKind as E, MeshGeometryComponent as F, type MeshGeometryParameters as G, type MeshGeometryParametersByKind as H, ImageComponent as I, ModelComponent as J, type PhysicsState as K, LightComponent as L, MaterialComponent as M, Name as N, Object3DRef as O, PhysicsComponent as P, type PlaneMeshParameters as Q, type RadiusHeightMeshParameters as R, type RadiusMeshParameters as S, type RigidbodyState as T, type RigidbodyType as U, ScriptComponent as V, type ScriptEntry as W, ScriptObjectComponent as X, type ScriptObjectComponentInput as Y, type ScriptObjectRuntimeState as Z, Selectable as _, type AnimationComponentOptions as a, SpriteComponent as a0, type TextureFilteringValue as a1, type TransformModeValue as a2, type TransformSpaceValue as a3, VRTeleportAreaComponent as a4, type VRTeleportAreaOptions as a5, VideoComponent as a6, type VrTeleportShape as a7, XRHandPoseComponent as a8, type XRHandPoseOptions as a9, XRInteractableComponent as aa, type XRInteractableOptions as ab, XRInteractorComponent as ac, type XRInteractorOptions as ad, XRInteractorSideComponent as ae, XRRigComponent as af, type XRRigOptions as ag, type XrGrabMode as ah, type XrHandPoseEntry as ai, type XrHandPreset as aj, type XrInteractorSide as ak, type XrInteractorType as al, type XrLocomotionMode as am, type XrTrackingOrigin as an, createHandPoseEntry as ao, defaultMaterialValue as ap, handPoseDefinitionFor as aq, normalizePhysicsState as ar, setPhysicsLiveRef as as, type AnimationStateCallbacks as at, AnimationStateMachine as au, AnimationStateManager as av, type StateMachine as aw, AudioComponent as b, type CameraComponentOptions as c, type CameraProjection as d, type CameraRuntimeType as e, type ColliderShape as f, type ColliderState as g, type CubeMeshParameters as h, DEFAULT_INSTANCED_MESH_PARAMETERS as i, DEFAULT_INSTANCE_TRANSFORM as j, DEFAULT_MESH_GEOMETRY_PARAMETERS as k, DEFAULT_PHYSICS_STATE as l, DEFAULT_POSE_CURLS as m, DEFAULT_RIGIDBODY_STATE as n, EntityType as o, ImageTarget as p, ImageTargetAnchor as q, type ImageTargetAnchorOptions as r, type ImageTargetReference as s, InstanceSlotComponent as t, type InstanceTransform as u, InstancedMeshComponent as v, type InstancedMeshKind as w, type LightValueState as x, type MaterialTypeValue as y, type MaterialValueState as z };
@@ -1,5 +1,5 @@
1
- import { createTransform, applyTransform, resolveDracoDecoderPath, loadSharedGltf, cloneModelScene } from './chunk-JRJ3CL5H.js';
2
- import { AnimationComponent, AudioComponent, Object3DRef, CameraComponent, MeshGeometryComponent, PhysicsComponent, Environment, EntityType, ImageComponent, ImageTargetAnchor, ImageTarget, LightComponent, MaterialComponent, MeshComponent, ModelComponent, Name, ParentId, Postprocessing, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, InstancedMeshComponent, InstanceSlotComponent, VideoComponent, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, DEFAULT_INSTANCE_TRANSFORM } from './chunk-N4GKZ7IV.js';
1
+ import { createTransform, applyTransform, resolveDracoDecoderPath, loadSharedGltf, cloneModelScene } from './chunk-L5BP727H.js';
2
+ import { AnimationComponent, AudioComponent, Object3DRef, CameraComponent, MeshGeometryComponent, PhysicsComponent, Environment, EntityType, ImageComponent, ImageTargetAnchor, ImageTarget, LightComponent, MaterialComponent, MeshComponent, ModelComponent, Name, ParentId, Postprocessing, ScriptComponent, ScriptObjectComponent, Selectable, SelectionTransformState, SpriteComponent, TransformComponent, InstancedMeshComponent, InstanceSlotComponent, VideoComponent, XRRigComponent, VRTeleportAreaComponent, XRHandPoseComponent, XRInteractableComponent, XRInteractorComponent, XRInteractorSideComponent, DEFAULT_INSTANCE_TRANSFORM } from './chunk-KVGGAL5V.js';
3
3
  import { __name } from './chunk-OY7ZODZP.js';
4
4
  import * as THREE25 from 'three';
5
5
  import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js';
@@ -406,6 +406,14 @@ function createVRTeleportAreaComponent(world, entityId, ...args) {
406
406
  }
407
407
  __name(createVRTeleportAreaComponent, "createVRTeleportAreaComponent");
408
408
 
409
+ // core/factories/components/XRHandPoseFactory.ts
410
+ function createXRHandPoseComponent(world, entityId, ...args) {
411
+ const component = new XRHandPoseComponent(...args);
412
+ world.addComponent(entityId, component);
413
+ return component;
414
+ }
415
+ __name(createXRHandPoseComponent, "createXRHandPoseComponent");
416
+
409
417
  // core/factories/components/XRInteractableFactory.ts
410
418
  function createXRInteractableComponent(world, entityId, ...args) {
411
419
  const component = new XRInteractableComponent(...args);
@@ -441,6 +449,7 @@ function registerDefaultComponentFactories(objectManagementSystem) {
441
449
  objectManagementSystem.registerComponentFactory("image", createImageComponent);
442
450
  objectManagementSystem.registerComponentFactory("xrRig", createXRRigComponent);
443
451
  objectManagementSystem.registerComponentFactory("vrTeleportArea", createVRTeleportAreaComponent);
452
+ objectManagementSystem.registerComponentFactory("xrHandPose", createXRHandPoseComponent);
444
453
  objectManagementSystem.registerComponentFactory("xrInteractable", createXRInteractableComponent);
445
454
  objectManagementSystem.registerComponentFactory("xrInteractor", createXRInteractorComponent);
446
455
  objectManagementSystem.registerComponentFactory("xrInteractorSide", createXRInteractorSideComponent);
@@ -1655,6 +1664,6 @@ function registerDefaultFactories(objectManagementSystem) {
1655
1664
  }
1656
1665
  __name(registerDefaultFactories, "registerDefaultFactories");
1657
1666
 
1658
- export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRInteractableComponent, createXRInteractorComponent, createXRInteractorSideComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories };
1659
- //# sourceMappingURL=chunk-FQTOC7HK.js.map
1660
- //# sourceMappingURL=chunk-FQTOC7HK.js.map
1667
+ export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRHandPoseComponent, createXRInteractableComponent, createXRInteractorComponent, createXRInteractorSideComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories };
1668
+ //# sourceMappingURL=chunk-KIKIWCEB.js.map
1669
+ //# sourceMappingURL=chunk-KIKIWCEB.js.map