@realitycollective/xrblocks-interactions 0.1.0-preview.1 → 0.1.0-preview.3

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- Change log for the Reality Collective WebXR Interaction Extensions packages. All four packages are versioned and released together; the version below is the one carried by the `v<version>` release tag.
3
+ Change log for the Reality Collective WebXR Interaction Extensions packages. All five packages are versioned and released together; the version below is the one carried by the `v<version>` release tag.
4
4
 
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Preview builds are not listed separately. The entry for a version accumulates while its previews are published, and is dated when that version is released.
6
6
 
@@ -13,15 +13,34 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
13
13
  - `@realitycollective/iwsdk-interactions` - Meta IWSDK adapter: player-rig poses and stateful gamepads as the provider, IWSDK's own targeting (`Pressed` / `Grabbed` tags) forwarded as pre-resolved hints, and native grab fulfilment when the app enables IWSDK grabbing/physics. One-call `registerInteractions(world)` setup.
14
14
  - `@realitycollective/xrblocks-interactions` - EXPERIMENTAL Google XR Blocks adapter, structurally typed against xrblocks v0.20.0 (`Input.getFrame()` ray sources and direct touches, pooled structs copied, no haptics upstream).
15
15
  - `demos/playground` - the standalone interaction playground: the full station set from one portable `InteractionDescriptor`, with client-side audio cues, opt-in controller haptics and client-side toss ballistics.
16
+ - `@realitycollective/webxr-interactions` - per-source velocity. `VelocityTracker` differentiates the grip poses the runtime already samples into linear and angular velocity, and the runtime runs one by default (`velocity: false` turns it off, `{ smoothing }` averages it). A source on its first frame, or one that reappears after dropping out, reports no velocity rather than a jump from its last known pose, and a provider that supplies its own velocity keeps it. Read it from `runtime.onSample(...)` or `runtime.getSource(id)`. The differentiation itself is `velocityBetween` from `@realitycollective/webxr-input`, re-exported here; `clampDeadzone` joins the math helpers.
17
+ - `@realitycollective/webxr-interactions` - `routeAudioToSink`, the audio counterpart to `routeHapticsToProvider`: an opt-in that plays the cues named in a map through a client-supplied sink. Cues absent from the map are ignored, so an app sonifies only the moments it has sounds for.
18
+ - `@realitycollective/iwsdk-interactions` and `@realitycollective/threejs-interactions` - presence control. `setPresenceVisible(target, visible)` shows and hides the hand and controller visuals per side; the IWSDK adapter adds `setPresenceModality(mode)` to force hands or controllers over the automatic choice, and the three.js adapter takes the app's own models through `registerVisual(handedness, root)`. Every provider reports whether it can do this through `capabilities.presence`; the XR Blocks adapter reports false, since XR Blocks exposes no way to hide its visuals.
19
+ - `@realitycollective/threejs-interactions` - native WebXR pose velocity. Where the browser reports `linearVelocity` or `angularVelocity` with a grip pose (or with the wrist joint a hand falls back to), the provider passes it through on the snapshot and the core's tracker leaves it alone; where it does not, the tracker derives velocity from consecutive poses as before. The desktop mouse source synthesises nothing: its grip rides the camera ray, so the derived velocity is camera motion, and hand mechanics should be gated on `handedness !== "none"`.
20
+ - `@realitycollective/babylon-interactions` - a Babylon.js adapter, the fourth engine. It reads a `WebXRDefaultExperience` (controllers, motion controller trigger and squeeze, hand-tracking joints, session manager) for input, with `scene.onPointerObservable` as the desktop fallback, haptics through the motion controller's `pulse`, and presence over the visuals Babylon builds - motion controller root meshes and hand meshes. Babylon picks the visual per input source, so there is no modality switch. Hit-testing is a sphere test over registered nodes, with an optional `pickWithRay` hook for mesh-accurate targeting; the transform port moves, rotates and scales Babylon nodes from rest. Structurally typed against the Babylon API rather than importing `@babylonjs/core`, as the XR Blocks adapter is, so an upstream release cannot break the install - and so the whole adapter is covered headlessly by structural fakes. Written against the documented Babylon 7 API and not yet exercised against a real Babylon runtime.
21
+ - Tests for `@realitycollective/iwsdk-interactions`, which had none. `@iwsdk/core` imports headlessly in node, so the provider is covered against a structural fake world with no module mocking, and a parity suite instantiates all four providers and runs the shared contract suite against each one. The package's coverage ratchet moves off zero, and the other three ratchets rise to the floor they now measure.
16
22
 
17
23
  ### Changed
18
24
 
25
+ - Every provider reports presence through `capabilities.presence`, the required key `@realitycollective/webxr-input` 0.1.1 adds to `InputCapabilities`. The class-level `supportsPresence` field the four adapters carried while that key was unpublished is gone. This fixes a client-visible defect on the IWSDK adapter, which built its capabilities without a `presence` key at all: an app that read `capabilities.presence` saw false and hid a feature that worked. The value each provider reports is the one its own field computed - always true on IWSDK, true once Babylon has built a visual to hide, true on three.js once a model is registered, and always false on XR Blocks.
26
+ - `@realitycollective/threejs-interactions` - `registerVisual` and the new `unregisterVisual` now re-derive capabilities and notify `onCapabilitiesChanged`. Presence on this adapter is genuinely conditional: your app builds its own hand and controller models, so `capabilities.presence` is false until you hand the first one over and false again once you take the last one back.
27
+ - The Input 0.1.1 types replace the local stand-ins that were waiting on them. `InputSourceSnapshot` now carries `linearVelocity` and `angularVelocity` itself, so the `InputSourceSnapshotWithVelocity` alias is gone; the local `poseVelocity` is gone in favour of the shipped `velocityBetween`; and the per-adapter `PresenceTarget` and `PresenceModality` declarations are gone. `PresenceModality` now comes from the contracts, and a presence target is written as the contract writes it, `Handedness | "all"`. All three names were re-exported from these packages and are removed from that surface.
28
+ - Every package now requires `@realitycollective/webxr-input` at `^0.1.1` rather than `^0.1.0`, because the code above uses members that only exist from 0.1.1. A fresh install resolved to 0.1.1 either way; the range says so now, so a consumer holding an older lockfile fails at install rather than at run time.
29
+ - The provider parity suite is now three lines over `inputProviderContractCases()` from `@realitycollective/webxr-input`, run against all four adapters, instead of a hand-written copy of the same checks. The shared cases are stricter: they assert the capability record has exactly the contract's keys and that every snapshot is well formed. Two adapter-specific checks stay on top of them.
30
+ - `@realitycollective/iwsdk-interactions` - `setPresenceVisible` and `setPresenceModality` write nothing when nothing changed. The provider holds what it last applied per side - visibility, modality and the hand-tracking capability presence is derived from - and skips a side whose three inputs are unchanged. An app pushing presence from a state subscription, which is the documented pattern, no longer walks every descendant of both visual families on every unrelated state change. The per-frame re-apply during `sample()` stays unconditional, because IWSDK re-asserts its own visuals from its update loop and a capability refresh can change the modality underneath the adapter.
31
+
32
+ - `@realitycollective/iwsdk-interactions` - `pulse` resolves the side from the handedness recorded while sampling, rather than parsing the source id. Parsing the id remains the fallback for an id the provider did not produce.
33
+
19
34
  - `@realitycollective/iwsdk-interactions` targets **IWSDK 0.5.x**. Its peer range is now `>=0.5.0 <0.6.0` and it is developed and tested against `@iwsdk/core` 0.5.3. The adapter is source-compatible with 0.4.x and needed no code change, but 0.5 is the only line exercised, so it is the only line supported. Every symbol and runtime member the provider uses is present in both, and it already reads `world.input.xr.gamepads` rather than the accessor 0.5 deprecates.
20
35
  - `demos/playground` no longer compiles UIKitML at build time. `@iwsdk/vite-plugin-uikitml` was discontinued at 0.4.2 and only ever did `JSON.stringify(parse(source))`, so the panel is served as `.uikitml` from `public/ui/` and parsed on load. The demo drops that plugin, and its station markup uses `rgba()` rather than `background-opacity`, which the 0.5 parser removed.
21
36
 
37
+ ### Deprecated
38
+
39
+ - `@realitycollective/webxr-interactions` - `InteractionRuntime.onSourcesSampled` is deprecated in favour of `onSample`. They are the same stream, and since `InputSourceSnapshot` carries the velocity fields itself the two signatures are now identical, so only one name is needed. Nothing is removed: existing callers keep working and the method will go in a later major release.
40
+
22
41
  ### Notes
23
42
 
24
- - All four packages depend on `@realitycollective/webxr-input`, released independently from the [WebXR-Input](https://github.com/realitycollective/WebXR-Input) repository. That package must be published before this one.
43
+ - All five packages depend on `@realitycollective/webxr-input`, released independently from the [WebXR-Input](https://github.com/realitycollective/WebXR-Input) repository. That package must be published before this one.
25
44
  - The interaction packages themselves carry no IWSDK coupling beyond the adapter: `webxr-interactions` is engine-free, and `threejs-interactions` and `xrblocks-interactions` peer only on three.js.
26
45
 
27
46
  [0.1.0]: https://github.com/realitycollective/WebXR-Interactions/commits/main
package/dist/provider.js CHANGED
@@ -121,6 +121,10 @@ export class XRBlocksInputProvider {
121
121
  pointer2d: mouse,
122
122
  headPose: true,
123
123
  haptics: false, // xrblocks v0.20.0 has no haptics API
124
+ // XR Blocks owns its controller and hand visuals and exposes no way
125
+ // to hide them, so there is no presence to offer and neither
126
+ // setPresenceVisible nor setPresenceModality is implemented.
127
+ presence: false,
124
128
  };
125
129
  if (JSON.stringify(next) !== JSON.stringify(this.capabilities)) {
126
130
  this.capabilities = next;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * XRBlocksInputProvider - EXPERIMENTAL.\n *\n * Binds to the SHAPE of Google XR Blocks (verified against xrblocks\n * v0.20.0 source, 2026-08) without importing `xrblocks`, per the\n * UI Extensions structural-typing convention:\n *\n * - `xb.input.getFrame()` → `{ raySources, directTouches }`. Those slot\n * objects are POOLED AND MUTATED per frame upstream - everything is\n * copied here, never retained.\n * - `RaySourceInput`: `{ controller, sourceType: 'mouse'|'controller-ray'\n * |'hand-ray'|'gaze'|'simulator', ray, selected }` - handedness from\n * `controller.inputSource?.handedness`; analog select only via\n * `controller.gamepad?.buttons[0].value`; squeeze only as the boolean\n * `controller.userData.squeezing`.\n * - `DirectTouchInput`: `{ handIndex (0=left,1=right), point }` - the\n * index-fingertip world position, merged into the matching hand source.\n * - Grip poses are not exposed by the frame struct; the ray pose doubles\n * as the carry pose (XR Blocks keeps grip transforms behind\n * `options.controllers.visualization`).\n * - Gaze rides `sourceType: 'gaze'` and never raw-selects (XR Blocks\n * selects gaze via its own dwell; ours is the core's dwell).\n * - Haptics: none in XR Blocks (verified) - capability stays false.\n */\nimport {\n NO_CAPABILITIES,\n type HeadPose,\n type InputCapabilities,\n type InputProvider,\n type InputSourceSnapshot,\n type Unsubscribe,\n} from \"@realitycollective/webxr-input\";\n\n/** Structural slice of THREE.Vector3 / Quaternion. */\ninterface Vec3Like {\n x: number;\n y: number;\n z: number;\n}\ninterface QuatLike extends Vec3Like {\n w: number;\n}\n\ninterface RayLike {\n origin: Vec3Like;\n direction: Vec3Like;\n}\n\ninterface ControllerLike {\n inputSource?: { handedness?: string };\n gamepad?: { buttons?: ReadonlyArray<{ value: number }> };\n userData?: { squeezing?: boolean; selected?: boolean; id?: number };\n}\n\n/** Structural `RaySourceInput` (xrblocks src/interaction/InteractionTypes.ts). */\nexport interface XBRaySourceLike {\n controller: ControllerLike;\n sourceType: string; // 'mouse' | 'controller-ray' | 'hand-ray' | 'gaze' | 'simulator'\n ray: RayLike;\n selected: boolean;\n}\n\n/** Structural `DirectTouchInput`. */\nexport interface XBDirectTouchLike {\n controller: ControllerLike;\n handIndex: number; // 0 = LEFT, 1 = RIGHT (xrblocks Handedness enum)\n point: Vec3Like;\n selected: boolean;\n}\n\nexport interface XBFrameLike {\n raySources: readonly XBRaySourceLike[];\n directTouches: readonly XBDirectTouchLike[];\n}\n\n/** The slice of the XR Blocks singletons the provider binds to. */\nexport interface XRBlocksContext {\n /** `xb.input` - must expose `getFrame()`. */\n input: { getFrame(): XBFrameLike };\n /** `xb.camera` / `xb.core.camera` - the head pose. */\n camera: {\n getWorldPosition(target: Vec3Like): Vec3Like;\n getWorldQuaternion(target: QuatLike): QuatLike;\n };\n}\n\nconst SCRATCH_V = { x: 0, y: 0, z: 0 };\nconst SCRATCH_Q = { x: 0, y: 0, z: 0, w: 1 };\n\nexport class XRBlocksInputProvider implements InputProvider {\n private readonly context: XRBlocksContext;\n private capabilities: InputCapabilities = { ...NO_CAPABILITIES, headPose: true, gaze: true };\n private readonly capsListeners = new Set<(c: InputCapabilities) => void>();\n\n constructor(context: XRBlocksContext) {\n this.context = context;\n }\n\n getCapabilities(): InputCapabilities {\n return this.capabilities;\n }\n\n onCapabilitiesChanged(listener: (c: InputCapabilities) => void): Unsubscribe {\n this.capsListeners.add(listener);\n return () => this.capsListeners.delete(listener);\n }\n\n onSourcesChanged(): Unsubscribe {\n return () => undefined;\n }\n\n sample(): readonly InputSourceSnapshot[] {\n const frame = this.context.input.getFrame();\n const snapshots: InputSourceSnapshot[] = [];\n const byHandedness = new Map<string, InputSourceSnapshot>();\n\n let sawRay = false;\n let sawTouch = false;\n let sawMouse = false;\n\n for (const source of frame.raySources) {\n if (source.sourceType === \"gaze\") {\n snapshots.push({\n id: \"xb-gaze\",\n kind: \"gaze\",\n handedness: \"none\",\n ray: copyRay(source.ray),\n select: 0, // gaze never raw-selects in XR Blocks\n squeeze: 0,\n });\n continue;\n }\n const handedness = normalizeHandedness(source.controller.inputSource?.handedness);\n const isMouse = source.sourceType === \"mouse\";\n if (isMouse) sawMouse = true;\n else sawRay = true;\n const analog = source.controller.gamepad?.buttons?.[0]?.value;\n const select = analog !== undefined && analog > 0 ? analog : source.selected ? 1 : 0;\n const ray = copyRay(source.ray);\n const snapshot: InputSourceSnapshot = {\n id: isMouse ? \"xb-mouse\" : `xb-${handedness}-${source.sourceType}`,\n kind: isMouse ? \"pointer2d\" : source.sourceType === \"hand-ray\" ? \"hand\" : \"controller\",\n handedness,\n ray,\n // XR Blocks does not expose grip transforms in the frame struct;\n // the ray pose doubles as the carry pose.\n gripPose: { position: ray.origin, quaternion: [0, 0, 0, 1] },\n select,\n squeeze: source.controller.userData?.squeezing ? 1 : 0,\n };\n snapshots.push(snapshot);\n if (handedness !== \"none\") byHandedness.set(handedness, snapshot);\n }\n\n for (const touch of frame.directTouches) {\n sawTouch = true;\n const handedness = touch.handIndex === 0 ? \"left\" : \"right\";\n const existing = byHandedness.get(handedness);\n const tip: [number, number, number] = [touch.point.x, touch.point.y, touch.point.z];\n if (existing) {\n existing.indexTip = tip;\n existing.kind = \"hand\";\n } else {\n snapshots.push({\n id: `xb-${handedness}-touch`,\n kind: \"hand\",\n handedness,\n indexTip: tip,\n gripPose: { position: tip, quaternion: [0, 0, 0, 1] },\n select: touch.selected ? 1 : 0,\n squeeze: 0,\n });\n }\n }\n\n this.refreshCapabilities(sawRay, sawTouch, sawMouse);\n return snapshots;\n }\n\n private refreshCapabilities(rays: boolean, touches: boolean, mouse: boolean): void {\n const next: InputCapabilities = {\n ...NO_CAPABILITIES,\n rays,\n pokes: touches,\n grabs: rays || touches ? \"poseOnly\" : \"none\",\n handJoints: touches,\n pinch: touches,\n gaze: true,\n pointer2d: mouse,\n headPose: true,\n haptics: false, // xrblocks v0.20.0 has no haptics API\n };\n if (JSON.stringify(next) !== JSON.stringify(this.capabilities)) {\n this.capabilities = next;\n for (const listener of [...this.capsListeners]) listener(next);\n }\n }\n\n getHeadPose(): HeadPose {\n const position = this.context.camera.getWorldPosition(SCRATCH_V);\n const quaternion = this.context.camera.getWorldQuaternion(SCRATCH_Q);\n return {\n position: [position.x, position.y, position.z],\n quaternion: [quaternion.x, quaternion.y, quaternion.z, quaternion.w ?? 1],\n };\n }\n}\n\nfunction normalizeHandedness(value: string | undefined): \"left\" | \"right\" | \"none\" {\n return value === \"left\" || value === \"right\" ? value : \"none\";\n}\n\nfunction copyRay(ray: RayLike): {\n origin: [number, number, number];\n direction: [number, number, number];\n} {\n // Upstream slot objects are pooled - copy, never retain.\n return {\n origin: [ray.origin.x, ray.origin.y, ray.origin.z],\n direction: [ray.direction.x, ray.direction.y, ray.direction.z],\n };\n}\n"]}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * XRBlocksInputProvider - EXPERIMENTAL.\n *\n * Binds to the SHAPE of Google XR Blocks (verified against xrblocks\n * v0.20.0 source, 2026-08) without importing `xrblocks`, per the\n * UI Extensions structural-typing convention:\n *\n * - `xb.input.getFrame()` → `{ raySources, directTouches }`. Those slot\n * objects are POOLED AND MUTATED per frame upstream - everything is\n * copied here, never retained.\n * - `RaySourceInput`: `{ controller, sourceType: 'mouse'|'controller-ray'\n * |'hand-ray'|'gaze'|'simulator', ray, selected }` - handedness from\n * `controller.inputSource?.handedness`; analog select only via\n * `controller.gamepad?.buttons[0].value`; squeeze only as the boolean\n * `controller.userData.squeezing`.\n * - `DirectTouchInput`: `{ handIndex (0=left,1=right), point }` - the\n * index-fingertip world position, merged into the matching hand source.\n * - Grip poses are not exposed by the frame struct; the ray pose doubles\n * as the carry pose (XR Blocks keeps grip transforms behind\n * `options.controllers.visualization`).\n * - Gaze rides `sourceType: 'gaze'` and never raw-selects (XR Blocks\n * selects gaze via its own dwell; ours is the core's dwell).\n * - Haptics: none in XR Blocks (verified) - capability stays false.\n */\nimport {\n NO_CAPABILITIES,\n type HeadPose,\n type InputCapabilities,\n type InputProvider,\n type InputSourceSnapshot,\n type Unsubscribe,\n} from \"@realitycollective/webxr-input\";\n\n/** Structural slice of THREE.Vector3 / Quaternion. */\ninterface Vec3Like {\n x: number;\n y: number;\n z: number;\n}\ninterface QuatLike extends Vec3Like {\n w: number;\n}\n\ninterface RayLike {\n origin: Vec3Like;\n direction: Vec3Like;\n}\n\ninterface ControllerLike {\n inputSource?: { handedness?: string };\n gamepad?: { buttons?: ReadonlyArray<{ value: number }> };\n userData?: { squeezing?: boolean; selected?: boolean; id?: number };\n}\n\n/** Structural `RaySourceInput` (xrblocks src/interaction/InteractionTypes.ts). */\nexport interface XBRaySourceLike {\n controller: ControllerLike;\n sourceType: string; // 'mouse' | 'controller-ray' | 'hand-ray' | 'gaze' | 'simulator'\n ray: RayLike;\n selected: boolean;\n}\n\n/** Structural `DirectTouchInput`. */\nexport interface XBDirectTouchLike {\n controller: ControllerLike;\n handIndex: number; // 0 = LEFT, 1 = RIGHT (xrblocks Handedness enum)\n point: Vec3Like;\n selected: boolean;\n}\n\nexport interface XBFrameLike {\n raySources: readonly XBRaySourceLike[];\n directTouches: readonly XBDirectTouchLike[];\n}\n\n/** The slice of the XR Blocks singletons the provider binds to. */\nexport interface XRBlocksContext {\n /** `xb.input` - must expose `getFrame()`. */\n input: { getFrame(): XBFrameLike };\n /** `xb.camera` / `xb.core.camera` - the head pose. */\n camera: {\n getWorldPosition(target: Vec3Like): Vec3Like;\n getWorldQuaternion(target: QuatLike): QuatLike;\n };\n}\n\nconst SCRATCH_V = { x: 0, y: 0, z: 0 };\nconst SCRATCH_Q = { x: 0, y: 0, z: 0, w: 1 };\n\nexport class XRBlocksInputProvider implements InputProvider {\n private readonly context: XRBlocksContext;\n private capabilities: InputCapabilities = { ...NO_CAPABILITIES, headPose: true, gaze: true };\n private readonly capsListeners = new Set<(c: InputCapabilities) => void>();\n\n constructor(context: XRBlocksContext) {\n this.context = context;\n }\n\n getCapabilities(): InputCapabilities {\n return this.capabilities;\n }\n\n onCapabilitiesChanged(listener: (c: InputCapabilities) => void): Unsubscribe {\n this.capsListeners.add(listener);\n return () => this.capsListeners.delete(listener);\n }\n\n onSourcesChanged(): Unsubscribe {\n return () => undefined;\n }\n\n sample(): readonly InputSourceSnapshot[] {\n const frame = this.context.input.getFrame();\n const snapshots: InputSourceSnapshot[] = [];\n const byHandedness = new Map<string, InputSourceSnapshot>();\n\n let sawRay = false;\n let sawTouch = false;\n let sawMouse = false;\n\n for (const source of frame.raySources) {\n if (source.sourceType === \"gaze\") {\n snapshots.push({\n id: \"xb-gaze\",\n kind: \"gaze\",\n handedness: \"none\",\n ray: copyRay(source.ray),\n select: 0, // gaze never raw-selects in XR Blocks\n squeeze: 0,\n });\n continue;\n }\n const handedness = normalizeHandedness(source.controller.inputSource?.handedness);\n const isMouse = source.sourceType === \"mouse\";\n if (isMouse) sawMouse = true;\n else sawRay = true;\n const analog = source.controller.gamepad?.buttons?.[0]?.value;\n const select = analog !== undefined && analog > 0 ? analog : source.selected ? 1 : 0;\n const ray = copyRay(source.ray);\n const snapshot: InputSourceSnapshot = {\n id: isMouse ? \"xb-mouse\" : `xb-${handedness}-${source.sourceType}`,\n kind: isMouse ? \"pointer2d\" : source.sourceType === \"hand-ray\" ? \"hand\" : \"controller\",\n handedness,\n ray,\n // XR Blocks does not expose grip transforms in the frame struct;\n // the ray pose doubles as the carry pose.\n gripPose: { position: ray.origin, quaternion: [0, 0, 0, 1] },\n select,\n squeeze: source.controller.userData?.squeezing ? 1 : 0,\n };\n snapshots.push(snapshot);\n if (handedness !== \"none\") byHandedness.set(handedness, snapshot);\n }\n\n for (const touch of frame.directTouches) {\n sawTouch = true;\n const handedness = touch.handIndex === 0 ? \"left\" : \"right\";\n const existing = byHandedness.get(handedness);\n const tip: [number, number, number] = [touch.point.x, touch.point.y, touch.point.z];\n if (existing) {\n existing.indexTip = tip;\n existing.kind = \"hand\";\n } else {\n snapshots.push({\n id: `xb-${handedness}-touch`,\n kind: \"hand\",\n handedness,\n indexTip: tip,\n gripPose: { position: tip, quaternion: [0, 0, 0, 1] },\n select: touch.selected ? 1 : 0,\n squeeze: 0,\n });\n }\n }\n\n this.refreshCapabilities(sawRay, sawTouch, sawMouse);\n return snapshots;\n }\n\n private refreshCapabilities(rays: boolean, touches: boolean, mouse: boolean): void {\n const next: InputCapabilities = {\n ...NO_CAPABILITIES,\n rays,\n pokes: touches,\n grabs: rays || touches ? \"poseOnly\" : \"none\",\n handJoints: touches,\n pinch: touches,\n gaze: true,\n pointer2d: mouse,\n headPose: true,\n haptics: false, // xrblocks v0.20.0 has no haptics API\n // XR Blocks owns its controller and hand visuals and exposes no way\n // to hide them, so there is no presence to offer and neither\n // setPresenceVisible nor setPresenceModality is implemented.\n presence: false,\n };\n if (JSON.stringify(next) !== JSON.stringify(this.capabilities)) {\n this.capabilities = next;\n for (const listener of [...this.capsListeners]) listener(next);\n }\n }\n\n getHeadPose(): HeadPose {\n const position = this.context.camera.getWorldPosition(SCRATCH_V);\n const quaternion = this.context.camera.getWorldQuaternion(SCRATCH_Q);\n return {\n position: [position.x, position.y, position.z],\n quaternion: [quaternion.x, quaternion.y, quaternion.z, quaternion.w ?? 1],\n };\n }\n}\n\nfunction normalizeHandedness(value: string | undefined): \"left\" | \"right\" | \"none\" {\n return value === \"left\" || value === \"right\" ? value : \"none\";\n}\n\nfunction copyRay(ray: RayLike): {\n origin: [number, number, number];\n direction: [number, number, number];\n} {\n // Upstream slot objects are pooled - copy, never retain.\n return {\n origin: [ray.origin.x, ray.origin.y, ray.origin.z],\n direction: [ray.direction.x, ray.direction.y, ray.direction.z],\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realitycollective/xrblocks-interactions",
3
- "version": "0.1.0-preview.1",
3
+ "version": "0.1.0-preview.3",
4
4
  "description": "EXPERIMENTAL Google XR Blocks adapter for the Reality Collective Interaction Extensions - maps XR Blocks' input pipeline (Input.getFrame() ray sources + direct touches, Script select events) into the engine-free @realitycollective/webxr-interactions core, reusing the three.js hit-testing/transform machinery. Structurally typed: no xrblocks import. Re-exports the core.",
5
5
  "keywords": [
6
6
  "realitycollective",
@@ -33,9 +33,9 @@
33
33
  "typecheck": "tsc -p tsconfig.json --noEmit"
34
34
  },
35
35
  "dependencies": {
36
- "@realitycollective/webxr-input": "^0.1.0",
37
- "@realitycollective/webxr-interactions": "^0.1.0-preview.1",
38
- "@realitycollective/threejs-interactions": "^0.1.0-preview.1"
36
+ "@realitycollective/webxr-input": "^0.1.1",
37
+ "@realitycollective/webxr-interactions": "^0.1.0-preview.3",
38
+ "@realitycollective/threejs-interactions": "^0.1.0-preview.3"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "three": ">=0.170.0"