@relu-interactives/spatial-ecs 0.3.18 → 0.3.20

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 (40) hide show
  1. package/dist/{XRHandPose-B8xxFb9A.d.cts → XRHandPose-CLl4MiHx.d.cts} +12 -2
  2. package/dist/{XRHandPose-ubMe5Igc.d.ts → XRHandPose-CrzI57JA.d.ts} +12 -2
  3. package/dist/{chunk-7SSOZWXM.js → chunk-CDSE7476.js} +82 -6
  4. package/dist/chunk-CDSE7476.js.map +1 -0
  5. package/dist/{chunk-PFE2SDXR.js → chunk-D6KXWNYT.js} +3 -3
  6. package/dist/{chunk-PFE2SDXR.js.map → chunk-D6KXWNYT.js.map} +1 -1
  7. package/dist/{chunk-J3EUNW57.js → chunk-H6DQ7JRE.js} +48 -18
  8. package/dist/chunk-H6DQ7JRE.js.map +1 -0
  9. package/dist/{chunk-KRWBNC6Y.js → chunk-P42OE3RU.js} +4 -4
  10. package/dist/{chunk-KRWBNC6Y.js.map → chunk-P42OE3RU.js.map} +1 -1
  11. package/dist/components/index.cjs +33 -10
  12. package/dist/components/index.cjs.map +1 -1
  13. package/dist/components/index.d.cts +3 -3
  14. package/dist/components/index.d.ts +3 -3
  15. package/dist/components/index.js +1 -1
  16. package/dist/docs/guide/vr-and-hand-poses.md +167 -0
  17. package/dist/factories/index.cjs +8 -0
  18. package/dist/factories/index.cjs.map +1 -1
  19. package/dist/factories/index.d.cts +2 -2
  20. package/dist/factories/index.d.ts +2 -2
  21. package/dist/factories/index.js +3 -3
  22. package/dist/{handPose-dFxqbFFY.d.cts → handPose-DlcTtqgx.d.cts} +26 -1
  23. package/dist/{handPose-dFxqbFFY.d.ts → handPose-DlcTtqgx.d.ts} +26 -1
  24. package/dist/{index-D7aSZ-e9.d.ts → index-6l4hn2Sh.d.ts} +15 -1
  25. package/dist/{index-7CFf45fo.d.cts → index-C2I5PxCI.d.cts} +15 -1
  26. package/dist/{index-DhWfxUgL.d.ts → index-JRcoel9F.d.ts} +3 -2
  27. package/dist/{index-CA9fqh4Z.d.cts → index-g777AmFv.d.cts} +3 -2
  28. package/dist/index.cjs +123 -16
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +11 -8
  31. package/dist/index.d.ts +11 -8
  32. package/dist/index.js +8 -8
  33. package/dist/systems/index.cjs +114 -16
  34. package/dist/systems/index.cjs.map +1 -1
  35. package/dist/systems/index.d.cts +2 -2
  36. package/dist/systems/index.d.ts +2 -2
  37. package/dist/systems/index.js +3 -3
  38. package/package.json +1 -1
  39. package/dist/chunk-7SSOZWXM.js.map +0 -1
  40. package/dist/chunk-J3EUNW57.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import * as THREE from 'three';
2
2
  import { C as Component, p as EcsEntityKind, F as EcsEntityEditorKind, r as EntityId } from './System-BhnLw0fZ.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
+ import { a as XrFinger, c as XrHandPoseDirection, b as XrHandPoseOrientation, X as XrHandPoseDefinition } from './handPose-DlcTtqgx.cjs';
5
5
 
6
6
  interface StateMachine {
7
7
  name: string;
@@ -1607,6 +1607,15 @@ type XrHandPoseEntry = {
1607
1607
  curls: Record<XrFinger, number>;
1608
1608
  /** Slack around each curl target. Larger is easier to perform. */
1609
1609
  tolerance: number;
1610
+ /**
1611
+ * Directions each finger may point. Empty means the finger may point anywhere.
1612
+ *
1613
+ * Any ONE listed direction satisfies the finger, mirroring fingerpose's
1614
+ * `addDirection` — "thumb up OR diagonally up" is one pose, not two.
1615
+ */
1616
+ directions: Record<XrFinger, XrHandPoseDirection[]>;
1617
+ /** How far a finger may point from an accepted direction, in degrees. */
1618
+ directionTolerance: number;
1610
1619
  /** Which hand may trigger it; null for either. */
1611
1620
  hand: "left" | "right" | null;
1612
1621
  /** Optional direction requirement. */
@@ -1620,6 +1629,7 @@ type XRHandPoseOptions = {
1620
1629
  poses?: XrHandPoseEntry[];
1621
1630
  };
1622
1631
  declare const DEFAULT_POSE_CURLS: Record<XrFinger, number>;
1632
+ declare const DEFAULT_POSE_DIRECTIONS: Record<XrFinger, XrHandPoseDirection[]>;
1623
1633
  /** A pose entry with every field populated, for the editor and AI tools. */
1624
1634
  declare function createHandPoseEntry(partial: Partial<XrHandPoseEntry> & {
1625
1635
  id: string;
@@ -1647,4 +1657,4 @@ declare class XRHandPoseComponent extends Component {
1647
1657
  constructor(options?: XRHandPoseOptions);
1648
1658
  }
1649
1659
 
1650
- 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, AnimationStateMachine as aA, AnimationStateManager as aB, type StateMachine as aC, 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 XrAttachPoint as ah, type XrDistanceGrabBehavior as ai, type XrGrabGesture as aj, type XrGrabHands as ak, type XrGrabReach as al, type XrHandPoseEntry as am, type XrHandPreset as an, type XrInteractorSide as ao, type XrInteractorType as ap, type XrLocomotionMode as aq, type XrTrackingOrigin as ar, type XrTwoHandRotation as as, createAttachPoint as at, createHandPoseEntry as au, defaultMaterialValue as av, handPoseDefinitionFor as aw, normalizePhysicsState as ax, setPhysicsLiveRef as ay, type AnimationStateCallbacks as az, 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 };
1660
+ export { Selectable as $, AnimationComponent as A, type MaterialValueState as B, CameraComponent as C, DEFAULT_COLLIDER_STATE as D, type EditableMeshObjectKind as E, MeshComponent as F, MeshGeometryComponent as G, type MeshGeometryParameters as H, ImageComponent as I, type MeshGeometryParametersByKind as J, ModelComponent as K, LightComponent as L, MaterialComponent as M, Name as N, Object3DRef as O, PhysicsComponent as P, type PhysicsState as Q, type PlaneMeshParameters as R, type RadiusHeightMeshParameters as S, type RadiusMeshParameters as T, type RigidbodyState as U, type RigidbodyType as V, ScriptComponent as W, type ScriptEntry as X, ScriptObjectComponent as Y, type ScriptObjectComponentInput as Z, type ScriptObjectRuntimeState as _, type AnimationComponentOptions as a, SelectionTransformState as a0, SpriteComponent as a1, type TextureFilteringValue as a2, type TransformModeValue as a3, type TransformSpaceValue as a4, VRTeleportAreaComponent as a5, type VRTeleportAreaOptions as a6, VideoComponent as a7, type VrTeleportShape as a8, XRHandPoseComponent as a9, type AnimationStateCallbacks as aA, AnimationStateMachine as aB, AnimationStateManager as aC, type StateMachine as aD, type XRHandPoseOptions as aa, XRInteractableComponent as ab, type XRInteractableOptions as ac, XRInteractorComponent as ad, type XRInteractorOptions as ae, XRInteractorSideComponent as af, XRRigComponent as ag, type XRRigOptions as ah, type XrAttachPoint as ai, type XrDistanceGrabBehavior as aj, type XrGrabGesture as ak, type XrGrabHands as al, type XrGrabReach as am, type XrHandPoseEntry as an, type XrHandPreset as ao, type XrInteractorSide as ap, type XrInteractorType as aq, type XrLocomotionMode as ar, type XrTrackingOrigin as as, type XrTwoHandRotation as at, createAttachPoint as au, createHandPoseEntry as av, defaultMaterialValue as aw, handPoseDefinitionFor as ax, normalizePhysicsState as ay, setPhysicsLiveRef as az, 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_POSE_DIRECTIONS as n, DEFAULT_RIGIDBODY_STATE as o, EntityType as p, ImageTarget as q, ImageTargetAnchor as r, type ImageTargetAnchorOptions as s, type ImageTargetReference as t, InstanceSlotComponent as u, type InstanceTransform as v, InstancedMeshComponent as w, type InstancedMeshKind as x, type LightValueState as y, type MaterialTypeValue as z };
@@ -1,7 +1,7 @@
1
1
  import * as THREE from 'three';
2
2
  import { C as Component, p as EcsEntityKind, F as EcsEntityEditorKind, r as EntityId } from './System-BhnLw0fZ.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
+ import { a as XrFinger, c as XrHandPoseDirection, b as XrHandPoseOrientation, X as XrHandPoseDefinition } from './handPose-DlcTtqgx.js';
5
5
 
6
6
  interface StateMachine {
7
7
  name: string;
@@ -1607,6 +1607,15 @@ type XrHandPoseEntry = {
1607
1607
  curls: Record<XrFinger, number>;
1608
1608
  /** Slack around each curl target. Larger is easier to perform. */
1609
1609
  tolerance: number;
1610
+ /**
1611
+ * Directions each finger may point. Empty means the finger may point anywhere.
1612
+ *
1613
+ * Any ONE listed direction satisfies the finger, mirroring fingerpose's
1614
+ * `addDirection` — "thumb up OR diagonally up" is one pose, not two.
1615
+ */
1616
+ directions: Record<XrFinger, XrHandPoseDirection[]>;
1617
+ /** How far a finger may point from an accepted direction, in degrees. */
1618
+ directionTolerance: number;
1610
1619
  /** Which hand may trigger it; null for either. */
1611
1620
  hand: "left" | "right" | null;
1612
1621
  /** Optional direction requirement. */
@@ -1620,6 +1629,7 @@ type XRHandPoseOptions = {
1620
1629
  poses?: XrHandPoseEntry[];
1621
1630
  };
1622
1631
  declare const DEFAULT_POSE_CURLS: Record<XrFinger, number>;
1632
+ declare const DEFAULT_POSE_DIRECTIONS: Record<XrFinger, XrHandPoseDirection[]>;
1623
1633
  /** A pose entry with every field populated, for the editor and AI tools. */
1624
1634
  declare function createHandPoseEntry(partial: Partial<XrHandPoseEntry> & {
1625
1635
  id: string;
@@ -1647,4 +1657,4 @@ declare class XRHandPoseComponent extends Component {
1647
1657
  constructor(options?: XRHandPoseOptions);
1648
1658
  }
1649
1659
 
1650
- 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, AnimationStateMachine as aA, AnimationStateManager as aB, type StateMachine as aC, 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 XrAttachPoint as ah, type XrDistanceGrabBehavior as ai, type XrGrabGesture as aj, type XrGrabHands as ak, type XrGrabReach as al, type XrHandPoseEntry as am, type XrHandPreset as an, type XrInteractorSide as ao, type XrInteractorType as ap, type XrLocomotionMode as aq, type XrTrackingOrigin as ar, type XrTwoHandRotation as as, createAttachPoint as at, createHandPoseEntry as au, defaultMaterialValue as av, handPoseDefinitionFor as aw, normalizePhysicsState as ax, setPhysicsLiveRef as ay, type AnimationStateCallbacks as az, 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 };
1660
+ export { Selectable as $, AnimationComponent as A, type MaterialValueState as B, CameraComponent as C, DEFAULT_COLLIDER_STATE as D, type EditableMeshObjectKind as E, MeshComponent as F, MeshGeometryComponent as G, type MeshGeometryParameters as H, ImageComponent as I, type MeshGeometryParametersByKind as J, ModelComponent as K, LightComponent as L, MaterialComponent as M, Name as N, Object3DRef as O, PhysicsComponent as P, type PhysicsState as Q, type PlaneMeshParameters as R, type RadiusHeightMeshParameters as S, type RadiusMeshParameters as T, type RigidbodyState as U, type RigidbodyType as V, ScriptComponent as W, type ScriptEntry as X, ScriptObjectComponent as Y, type ScriptObjectComponentInput as Z, type ScriptObjectRuntimeState as _, type AnimationComponentOptions as a, SelectionTransformState as a0, SpriteComponent as a1, type TextureFilteringValue as a2, type TransformModeValue as a3, type TransformSpaceValue as a4, VRTeleportAreaComponent as a5, type VRTeleportAreaOptions as a6, VideoComponent as a7, type VrTeleportShape as a8, XRHandPoseComponent as a9, type AnimationStateCallbacks as aA, AnimationStateMachine as aB, AnimationStateManager as aC, type StateMachine as aD, type XRHandPoseOptions as aa, XRInteractableComponent as ab, type XRInteractableOptions as ac, XRInteractorComponent as ad, type XRInteractorOptions as ae, XRInteractorSideComponent as af, XRRigComponent as ag, type XRRigOptions as ah, type XrAttachPoint as ai, type XrDistanceGrabBehavior as aj, type XrGrabGesture as ak, type XrGrabHands as al, type XrGrabReach as am, type XrHandPoseEntry as an, type XrHandPreset as ao, type XrInteractorSide as ap, type XrInteractorType as aq, type XrLocomotionMode as ar, type XrTrackingOrigin as as, type XrTwoHandRotation as at, createAttachPoint as au, createHandPoseEntry as av, defaultMaterialValue as aw, handPoseDefinitionFor as ax, normalizePhysicsState as ay, setPhysicsLiveRef as az, 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_POSE_DIRECTIONS as n, DEFAULT_RIGIDBODY_STATE as o, EntityType as p, ImageTarget as q, ImageTargetAnchor as r, type ImageTargetAnchorOptions as s, type ImageTargetReference as t, InstanceSlotComponent as u, type InstanceTransform as v, InstancedMeshComponent as w, type InstancedMeshKind as x, type LightValueState as y, type MaterialTypeValue as z };
@@ -1,5 +1,5 @@
1
- import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-PFE2SDXR.js';
2
- import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ParentId, ScriptComponent, ScriptObjectComponent, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, createAttachPoint, XRHandPoseComponent, createHandPoseEntry, XRInteractorComponent, XRInteractorSideComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance, handPoseDefinitionFor, getHandPosePreset } from './chunk-J3EUNW57.js';
1
+ import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-D6KXWNYT.js';
2
+ import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ParentId, ScriptComponent, ScriptObjectComponent, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, createAttachPoint, XRHandPoseComponent, createHandPoseEntry, XRInteractorComponent, XRInteractorSideComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance, handPoseDefinitionFor, getHandPosePreset } from './chunk-H6DQ7JRE.js';
3
3
  import { __name } from './chunk-OY7ZODZP.js';
4
4
  import * as THREE19 from 'three';
5
5
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
@@ -6463,6 +6463,25 @@ var _XRInputSystem = class _XRInputSystem {
6463
6463
  }
6464
6464
  return null;
6465
6465
  }
6466
+ /**
6467
+ * The ARTICULATED source for a hand — the one carrying joint poses.
6468
+ *
6469
+ * Distinct from {@link getInput} because a hand can be backed by several
6470
+ * sources at once: a Quest reports a controller AND a tracked hand for the
6471
+ * same handedness, and Vision Pro adds a transient pinch alongside its two
6472
+ * persistent hands. `getInput` returns whichever was seen first, so anything
6473
+ * needing JOINTS has to ask for them specifically — taking the first match
6474
+ * silently handed pose detection a controller with no joints, and no pose
6475
+ * ever fired.
6476
+ */
6477
+ getHandInput(handedness) {
6478
+ for (const record of this.records.values()) {
6479
+ const state = record.state;
6480
+ if (state.handedness !== handedness) continue;
6481
+ if (state.joints) return state;
6482
+ }
6483
+ return null;
6484
+ }
6466
6485
  /** True while ANY source is selecting — the portable "is the user acting" check. */
6467
6486
  isSelecting() {
6468
6487
  for (const record of this.records.values()) {
@@ -8506,10 +8525,22 @@ function computeHandShape(joints, handedness) {
8506
8525
  const direction = new THREE19.Vector3().subVectors(thumbTip, thumbBase);
8507
8526
  if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
8508
8527
  }
8528
+ const fingerDirections = {};
8529
+ for (const finger of XR_FINGERS) {
8530
+ const base = joints[METACARPAL_JOINTS[finger]];
8531
+ const tip = joints[TIP_JOINTS[finger]];
8532
+ if (!base || !tip) {
8533
+ fingerDirections[finger] = null;
8534
+ continue;
8535
+ }
8536
+ const direction = new THREE19.Vector3().subVectors(tip, base);
8537
+ fingerDirections[finger] = direction.lengthSq() > 1e-12 ? direction.normalize() : null;
8538
+ }
8509
8539
  return {
8510
8540
  handedness,
8511
8541
  fingers,
8512
8542
  pinch,
8543
+ fingerDirections,
8513
8544
  spread: {
8514
8545
  thumbIndex: computeSpread(joints, "thumb", "index") ?? 0,
8515
8546
  indexMiddle: computeSpread(joints, "index", "middle") ?? 0,
@@ -8534,6 +8565,7 @@ function scoreAgainst(actual, target, tolerance) {
8534
8565
  return clamp01(1 - (error - tolerance) / MATCH_FALLOFF);
8535
8566
  }
8536
8567
  __name(scoreAgainst, "scoreAgainst");
8568
+ var DEFAULT_DIRECTION_TOLERANCE = 45;
8537
8569
  var WORLD_DIRECTIONS = {
8538
8570
  up: new THREE19.Vector3(0, 1, 0),
8539
8571
  down: new THREE19.Vector3(0, -1, 0),
@@ -8561,6 +8593,22 @@ function resolveDirection(direction, shape, context) {
8561
8593
  return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
8562
8594
  }
8563
8595
  __name(resolveDirection, "resolveDirection");
8596
+ function scoreDirections(actual, accepted, shape, toleranceDegrees, context) {
8597
+ if (!actual) return 0;
8598
+ let best = 0;
8599
+ for (const direction of accepted) {
8600
+ const wanted = resolveDirection(direction, shape, context);
8601
+ if (!wanted) continue;
8602
+ const angle = THREE19.MathUtils.radToDeg(
8603
+ Math.acos(THREE19.MathUtils.clamp(actual.dot(wanted), -1, 1))
8604
+ );
8605
+ const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
8606
+ const score = clamp01(1 - normalizedError / MATCH_FALLOFF);
8607
+ if (score > best) best = score;
8608
+ }
8609
+ return best;
8610
+ }
8611
+ __name(scoreDirections, "scoreDirections");
8564
8612
  function matchHandPose(shape, definition, context) {
8565
8613
  if (definition.hand && definition.hand !== shape.handedness) return NO_MATCH;
8566
8614
  let confidence = 1;
@@ -8590,6 +8638,18 @@ function matchHandPose(shape, definition, context) {
8590
8638
  `${finger} tip`
8591
8639
  );
8592
8640
  }
8641
+ if (target.directions && target.directions.length > 0) {
8642
+ consider(
8643
+ scoreDirections(
8644
+ shape.fingerDirections[finger],
8645
+ target.directions,
8646
+ shape,
8647
+ definition.directionToleranceDegrees ?? DEFAULT_DIRECTION_TOLERANCE,
8648
+ context
8649
+ ),
8650
+ `${finger} direction`
8651
+ );
8652
+ }
8593
8653
  }
8594
8654
  if (definition.pinch) {
8595
8655
  const { finger, target, tolerance } = definition.pinch;
@@ -8686,6 +8746,8 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
8686
8746
  /** Reused so head-relative orientation checks allocate nothing per frame. */
8687
8747
  this.headPosition = new THREE19.Vector3();
8688
8748
  this.elapsed = 0;
8749
+ this.warnedNoHands = false;
8750
+ this.noHandSeconds = 0;
8689
8751
  this.inputSystem = inputSystem;
8690
8752
  }
8691
8753
  update(world, deltaTime) {
@@ -8697,6 +8759,20 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
8697
8759
  this.refreshShapes();
8698
8760
  const entries = this.collectEntries(world);
8699
8761
  if (entries.length === 0) return;
8762
+ if (!this.warnedNoHands) {
8763
+ const tracked = this.shapes.get("left") !== null || this.shapes.get("right") !== null;
8764
+ if (tracked) {
8765
+ this.warnedNoHands = true;
8766
+ } else {
8767
+ this.noHandSeconds += deltaTime;
8768
+ if (this.noHandSeconds > 5) {
8769
+ this.warnedNoHands = true;
8770
+ console.warn(
8771
+ "[XRHandPoseSystem] Hand poses are configured but no tracked hands have been seen. Hand poses need HAND TRACKING \u2014 put the controllers down and enable hand tracking on the headset."
8772
+ );
8773
+ }
8774
+ }
8775
+ }
8700
8776
  world.getCamera().getWorldPosition(this.headPosition);
8701
8777
  const context = { headPosition: this.headPosition };
8702
8778
  for (const { entityId, entry } of entries) {
@@ -8741,7 +8817,7 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
8741
8817
  /** Derive each hand's shape once for the whole frame. */
8742
8818
  refreshShapes() {
8743
8819
  for (const handedness of ["left", "right"]) {
8744
- const input = this.inputSystem.getInput(handedness);
8820
+ const input = this.inputSystem.getHandInput(handedness);
8745
8821
  const joints = input?.joints ?? null;
8746
8822
  this.shapes.set(
8747
8823
  handedness,
@@ -8952,6 +9028,6 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
8952
9028
  __name(_XRHoverVisualSystem, "XRHoverVisualSystem");
8953
9029
  var XRHoverVisualSystem = _XRHoverVisualSystem;
8954
9030
 
8955
- export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, TeleportAimGate, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRHandPoseSystem, XRHoverVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, XR_HOVER_SHELL_FLAG, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
8956
- //# sourceMappingURL=chunk-7SSOZWXM.js.map
8957
- //# sourceMappingURL=chunk-7SSOZWXM.js.map
9031
+ export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_DIRECTION_TOLERANCE, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, TeleportAimGate, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRHandPoseSystem, XRHoverVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, XR_HOVER_SHELL_FLAG, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
9032
+ //# sourceMappingURL=chunk-CDSE7476.js.map
9033
+ //# sourceMappingURL=chunk-CDSE7476.js.map