@relu-interactives/spatial-ecs 0.3.14 → 0.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-XHMOFI3Q.js → chunk-GULLCPO6.js} +15 -10
- package/dist/chunk-GULLCPO6.js.map +1 -0
- package/dist/docs/guide/vr-and-hand-poses.md +11 -0
- package/dist/{index-CbrjAm_8.d.cts → index-BKGV3VvQ.d.cts} +8 -3
- package/dist/{index-CvIXdHzx.d.ts → index-Bi7L3QHF.d.ts} +8 -3
- package/dist/index.cjs +13 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/systems/index.cjs +13 -8
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +1 -1
- package/dist/systems/index.d.ts +1 -1
- package/dist/systems/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-XHMOFI3Q.js.map +0 -1
|
@@ -114,6 +114,17 @@ export default class Rifle extends Behaviour {
|
|
|
114
114
|
|
|
115
115
|
Every grab setting is a plain field on the component, so a script can change it mid-session — switch on resizing, retune throw strength, or move an attach point in response to what the player is doing.
|
|
116
116
|
|
|
117
|
+
## Vision Pro
|
|
118
|
+
|
|
119
|
+
Vision Pro drives WebXR entirely through **gaze and pinch**. There are no controllers, and the input source for a pinch is created when the pinch starts and destroyed when it ends. That has a few consequences worth designing around:
|
|
120
|
+
|
|
121
|
+
- **Look at a thing and pinch** to select or grab it. The pick ray starts between the user's eyes and is then carried by the hand, so aiming is "pinch, then move your hand", not "point, then press".
|
|
122
|
+
- **There is no hover before a pinch** — the input source does not exist until then. Pointer rays and hover feedback therefore only appear *during* a pinch, not while the user looks around.
|
|
123
|
+
- **Grip/squeeze is never reported.** Set an interactable's **Gesture** to `Pinch` or `Any`; `Full grip` can never trigger on Vision Pro.
|
|
124
|
+
- Grabbing does not teleport the user, the same as on hand tracking elsewhere.
|
|
125
|
+
- Hand tracking (and therefore hand poses) is available on visionOS 2 and later, but asks the user for a second permission. The OS draws the user's real hands.
|
|
126
|
+
- `immersive-ar` is not supported by Safari on visionOS, so VR projects are the only kind that run there.
|
|
127
|
+
|
|
117
128
|
## Hand poses
|
|
118
129
|
|
|
119
130
|
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.
|
|
@@ -501,15 +501,20 @@ declare class XRInteractionSystem implements EcsSystem {
|
|
|
501
501
|
/** True when any source is holding something. */
|
|
502
502
|
isGrabbing(): boolean;
|
|
503
503
|
/**
|
|
504
|
-
* Whether this
|
|
504
|
+
* Whether this input's primary action is committed to interaction.
|
|
505
505
|
*
|
|
506
|
-
* True while the
|
|
506
|
+
* True while the source holds something, and also while it merely HOVERS a
|
|
507
507
|
* grabbable — because the pinch that is about to grab must not be read as a
|
|
508
508
|
* teleport by the locomotion system. Without the hover half, the first pinch
|
|
509
509
|
* of a grab teleports the player, and so does the pinch that takes an object
|
|
510
510
|
* from the other hand.
|
|
511
|
+
*
|
|
512
|
+
* Keyed on the INPUT SOURCE rather than handedness. Vision Pro reports
|
|
513
|
+
* `handedness: "none"` for every gaze-pinch (it is hard-coded in WebKit), so a
|
|
514
|
+
* handedness-keyed check silently never matched there and each pinch both
|
|
515
|
+
* grabbed and teleported.
|
|
511
516
|
*/
|
|
512
|
-
|
|
517
|
+
isSourceBusy(world: World, input: XrInputState): boolean;
|
|
513
518
|
/** True when THIS hand is holding something. */
|
|
514
519
|
isGrabbingWith(handedness: XrInputState["handedness"]): boolean;
|
|
515
520
|
/**
|
|
@@ -501,15 +501,20 @@ declare class XRInteractionSystem implements EcsSystem {
|
|
|
501
501
|
/** True when any source is holding something. */
|
|
502
502
|
isGrabbing(): boolean;
|
|
503
503
|
/**
|
|
504
|
-
* Whether this
|
|
504
|
+
* Whether this input's primary action is committed to interaction.
|
|
505
505
|
*
|
|
506
|
-
* True while the
|
|
506
|
+
* True while the source holds something, and also while it merely HOVERS a
|
|
507
507
|
* grabbable — because the pinch that is about to grab must not be read as a
|
|
508
508
|
* teleport by the locomotion system. Without the hover half, the first pinch
|
|
509
509
|
* of a grab teleports the player, and so does the pinch that takes an object
|
|
510
510
|
* from the other hand.
|
|
511
|
+
*
|
|
512
|
+
* Keyed on the INPUT SOURCE rather than handedness. Vision Pro reports
|
|
513
|
+
* `handedness: "none"` for every gaze-pinch (it is hard-coded in WebKit), so a
|
|
514
|
+
* handedness-keyed check silently never matched there and each pinch both
|
|
515
|
+
* grabbed and teleported.
|
|
511
516
|
*/
|
|
512
|
-
|
|
517
|
+
isSourceBusy(world: World, input: XrInputState): boolean;
|
|
513
518
|
/** True when THIS hand is holding something. */
|
|
514
519
|
isGrabbingWith(handedness: XrInputState["handedness"]): boolean;
|
|
515
520
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -11728,17 +11728,22 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
11728
11728
|
return this.grabs.size > 0;
|
|
11729
11729
|
}
|
|
11730
11730
|
/**
|
|
11731
|
-
* Whether this
|
|
11731
|
+
* Whether this input's primary action is committed to interaction.
|
|
11732
11732
|
*
|
|
11733
|
-
* True while the
|
|
11733
|
+
* True while the source holds something, and also while it merely HOVERS a
|
|
11734
11734
|
* grabbable — because the pinch that is about to grab must not be read as a
|
|
11735
11735
|
* teleport by the locomotion system. Without the hover half, the first pinch
|
|
11736
11736
|
* of a grab teleports the player, and so does the pinch that takes an object
|
|
11737
11737
|
* from the other hand.
|
|
11738
|
+
*
|
|
11739
|
+
* Keyed on the INPUT SOURCE rather than handedness. Vision Pro reports
|
|
11740
|
+
* `handedness: "none"` for every gaze-pinch (it is hard-coded in WebKit), so a
|
|
11741
|
+
* handedness-keyed check silently never matched there and each pinch both
|
|
11742
|
+
* grabbed and teleported.
|
|
11738
11743
|
*/
|
|
11739
|
-
|
|
11740
|
-
if (this.
|
|
11741
|
-
const hover = this.
|
|
11744
|
+
isSourceBusy(world, input) {
|
|
11745
|
+
if (this.grabs.has(input)) return true;
|
|
11746
|
+
const hover = this.hovers.get(input);
|
|
11742
11747
|
if (!hover) return false;
|
|
11743
11748
|
const interactable = world.getComponent(
|
|
11744
11749
|
hover.entityId,
|
|
@@ -11832,7 +11837,7 @@ var _TeleportAimGate = class _TeleportAimGate {
|
|
|
11832
11837
|
if (aiming) this.aiming.add(source);
|
|
11833
11838
|
if (!releasing) return false;
|
|
11834
11839
|
this.aiming.delete(source);
|
|
11835
|
-
return hadAim;
|
|
11840
|
+
return hadAim || aiming;
|
|
11836
11841
|
}
|
|
11837
11842
|
/** True if this source currently has an aim engaged. */
|
|
11838
11843
|
isAiming(source) {
|
|
@@ -12006,7 +12011,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
12006
12011
|
const targets = this.collectTeleportTargets(world);
|
|
12007
12012
|
for (const input of inputs) {
|
|
12008
12013
|
const source = input;
|
|
12009
|
-
if (
|
|
12014
|
+
if (this.interactionSystem?.isSourceBusy(world, input)) {
|
|
12010
12015
|
if (this.teleportAim.cancel(source)) {
|
|
12011
12016
|
this.aimCurve = [];
|
|
12012
12017
|
this.landingPoint = null;
|
|
@@ -12015,7 +12020,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
12015
12020
|
continue;
|
|
12016
12021
|
}
|
|
12017
12022
|
const stick = this.readStickAim(input, source);
|
|
12018
|
-
const aiming = input.select || stick.aiming;
|
|
12023
|
+
const aiming = input.select || input.selectStart || stick.aiming;
|
|
12019
12024
|
const releasing = input.selectEnd || stick.released;
|
|
12020
12025
|
const commit = this.teleportAim.update(source, aiming, releasing);
|
|
12021
12026
|
if (!aiming && !commit) continue;
|