@threlte/xr 1.0.0-next.9 → 1.0.0
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/README.md +1 -8
- package/dist/components/ARButton.svelte +10 -3
- package/dist/components/ARButton.svelte.d.ts +8 -38
- package/dist/components/Controller.svelte +86 -46
- package/dist/components/Controller.svelte.d.ts +25 -37
- package/dist/components/Hand.svelte +109 -60
- package/dist/components/Hand.svelte.d.ts +21 -33
- package/dist/components/Headset.svelte +6 -4
- package/dist/components/Headset.svelte.d.ts +18 -16
- package/dist/components/VRButton.svelte +8 -3
- package/dist/components/VRButton.svelte.d.ts +2 -32
- package/dist/components/XR.svelte +156 -96
- package/dist/components/XR.svelte.d.ts +32 -45
- package/dist/components/XRButton.svelte +71 -38
- package/dist/components/XRButton.svelte.d.ts +26 -39
- package/dist/components/internal/Cursor.svelte +38 -25
- package/dist/components/internal/Cursor.svelte.d.ts +6 -18
- package/dist/components/internal/PointerCursor.svelte +46 -34
- package/dist/components/internal/PointerCursor.svelte.d.ts +5 -17
- package/dist/components/internal/ScenePortal.svelte +15 -12
- package/dist/components/internal/ScenePortal.svelte.d.ts +18 -16
- package/dist/components/internal/ShortRay.svelte +23 -12
- package/dist/components/internal/ShortRay.svelte.d.ts +5 -17
- package/dist/components/internal/TeleportCursor.svelte +51 -37
- package/dist/components/internal/TeleportCursor.svelte.d.ts +5 -17
- package/dist/components/internal/TeleportRay.svelte +77 -54
- package/dist/components/internal/TeleportRay.svelte.d.ts +6 -18
- package/dist/hooks/useController.d.ts +0 -1
- package/dist/hooks/useHand.d.ts +1 -1
- package/dist/hooks/useHandJoint.d.ts +1 -1
- package/dist/hooks/useHitTest.d.ts +0 -1
- package/dist/hooks/useXR.d.ts +0 -1
- package/dist/internal/stores.d.ts +0 -1
- package/dist/lib/getXRSessionOptions.d.ts +0 -1
- package/dist/lib/getXRSupportState.d.ts +1 -2
- package/dist/lib/toggleXRSession.d.ts +1 -2
- package/dist/plugins/pointerControls/context.d.ts +2 -2
- package/dist/plugins/pointerControls/index.d.ts +1 -1
- package/dist/plugins/pointerControls/index.js +1 -1
- package/dist/plugins/pointerControls/plugin.svelte.js +23 -0
- package/dist/plugins/teleportControls/context.d.ts +3 -3
- package/dist/plugins/teleportControls/index.d.ts +1 -1
- package/dist/plugins/teleportControls/index.js +1 -1
- package/dist/plugins/teleportControls/plugin.svelte.js +73 -0
- package/dist/types.d.ts +0 -1
- package/package.json +12 -12
- package/dist/plugins/pointerControls/plugin.js +0 -26
- package/dist/plugins/teleportControls/plugin.js +0 -54
- /package/dist/plugins/pointerControls/{plugin.d.ts → plugin.svelte.d.ts} +0 -0
- /package/dist/plugins/teleportControls/{plugin.d.ts → plugin.svelte.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -33,14 +33,7 @@ Check out our **[documentation](https://threlte.xyz)** and our **[Discord commun
|
|
|
33
33
|
|
|
34
34
|
### Installation
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```sh
|
|
39
|
-
npm create threlte my-project
|
|
40
|
-
```
|
|
41
|
-
and select the `@threlte/xr` option.
|
|
42
|
-
|
|
43
|
-
Alternatively you can check out the full [installation instructions](https://threlte.xyz/docs/learn/getting-started/installation).
|
|
36
|
+
Check out the [installation instructions](https://threlte.xyz/docs/learn/getting-started/installation).
|
|
44
37
|
|
|
45
38
|
### Support
|
|
46
39
|
|
|
@@ -9,9 +9,16 @@
|
|
|
9
9
|
/>
|
|
10
10
|
```
|
|
11
11
|
-->
|
|
12
|
-
<script lang="ts">
|
|
13
|
-
import {
|
|
14
|
-
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import type { ComponentProps } from 'svelte'
|
|
14
|
+
import XRButton from './XRButton.svelte'
|
|
15
|
+
import { defaultFeatures } from '../internal/defaultFeatures'
|
|
16
|
+
|
|
17
|
+
type Props = Omit<ComponentProps<XRButton>, 'mode' | 'sessionInit'> & {
|
|
18
|
+
sessionInit?: XRSessionInit & { domOverlay?: { root: HTMLElement } | undefined }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let { children, ...props }: Props = $props()
|
|
15
22
|
</script>
|
|
16
23
|
|
|
17
24
|
<XRButton
|
|
@@ -1,38 +1,3 @@
|
|
|
1
|
-
/// <reference types="webxr" />
|
|
2
|
-
import { SvelteComponent } from "svelte";
|
|
3
|
-
declare const __propDef: {
|
|
4
|
-
props: Omit<import("svelte/elements").HTMLButtonAttributes & {
|
|
5
|
-
mode: XRSessionMode;
|
|
6
|
-
sessionInit?: (XRSessionInit & {
|
|
7
|
-
domOverlay?: {
|
|
8
|
-
root: HTMLElement;
|
|
9
|
-
} | undefined;
|
|
10
|
-
}) | undefined;
|
|
11
|
-
force?: "enter" | "exit" | undefined;
|
|
12
|
-
styled?: boolean | undefined;
|
|
13
|
-
children?: import("svelte").Snippet<[{
|
|
14
|
-
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
15
|
-
}]> | undefined;
|
|
16
|
-
onclick?: ((event: {
|
|
17
|
-
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
18
|
-
nativeEvent: MouseEvent;
|
|
19
|
-
}) => void) | undefined;
|
|
20
|
-
onerror?: ((error: Error) => void) | undefined;
|
|
21
|
-
}, "mode" | "sessionInit"> & {
|
|
22
|
-
sessionInit?: (XRSessionInit & {
|
|
23
|
-
domOverlay?: {
|
|
24
|
-
root: HTMLElement;
|
|
25
|
-
} | undefined;
|
|
26
|
-
}) | undefined;
|
|
27
|
-
};
|
|
28
|
-
events: {
|
|
29
|
-
[evt: string]: CustomEvent<any>;
|
|
30
|
-
};
|
|
31
|
-
slots: {};
|
|
32
|
-
};
|
|
33
|
-
export type ArButtonProps = typeof __propDef.props;
|
|
34
|
-
export type ArButtonEvents = typeof __propDef.events;
|
|
35
|
-
export type ArButtonSlots = typeof __propDef.slots;
|
|
36
1
|
/**
|
|
37
2
|
* `<ARButton />` is an HTML `<button />` that can be used to init and display info about your immersive AR session.
|
|
38
3
|
*
|
|
@@ -43,6 +8,11 @@ export type ArButtonSlots = typeof __propDef.slots;
|
|
|
43
8
|
* />
|
|
44
9
|
* ```
|
|
45
10
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
11
|
+
declare const ArButton: import("svelte").Component<Omit<Record<string, any>, "mode" | "sessionInit"> & {
|
|
12
|
+
sessionInit?: XRSessionInit & {
|
|
13
|
+
domOverlay?: {
|
|
14
|
+
root: HTMLElement;
|
|
15
|
+
} | undefined;
|
|
16
|
+
};
|
|
17
|
+
}, {}, "">;
|
|
18
|
+
export default ArButton;
|
|
@@ -4,45 +4,61 @@
|
|
|
4
4
|
<script
|
|
5
5
|
lang="ts"
|
|
6
6
|
context="module"
|
|
7
|
-
>
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
>
|
|
8
|
+
import { writable } from 'svelte/store'
|
|
9
|
+
import { T } from '@threlte/core'
|
|
10
|
+
import { left as leftStore, right as rightStore } from '../hooks/useController'
|
|
11
|
+
import { isHandTracking, pointerState, teleportState, controllerEvents } from '../internal/stores'
|
|
12
|
+
import type { XRControllerEvents } from '../types'
|
|
13
|
+
import PointerCursor from './internal/PointerCursor.svelte'
|
|
14
|
+
import ShortRay from './internal/ShortRay.svelte'
|
|
15
|
+
import ScenePortal from './internal/ScenePortal.svelte'
|
|
16
|
+
import TeleportCursor from './internal/TeleportCursor.svelte'
|
|
17
|
+
import TeleportRay from './internal/TeleportRay.svelte'
|
|
18
|
+
import type { Snippet } from 'svelte'
|
|
19
|
+
|
|
20
|
+
const stores = {
|
|
21
|
+
left: leftStore,
|
|
22
|
+
right: rightStore
|
|
23
|
+
} as const
|
|
20
24
|
</script>
|
|
21
25
|
|
|
22
|
-
<script lang="ts">
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
<script lang="ts">
|
|
27
|
+
type Props = {
|
|
28
|
+
children?: Snippet
|
|
29
|
+
grip?: Snippet
|
|
30
|
+
targetRay?: Snippet
|
|
31
|
+
pointerRay?: Snippet
|
|
32
|
+
pointerCursor?: Snippet
|
|
33
|
+
teleportRay?: Snippet
|
|
34
|
+
teleportCursor?: Snippet
|
|
35
|
+
} & XRControllerEvents &
|
|
36
|
+
(
|
|
37
|
+
| {
|
|
38
|
+
/** Whether the controller should be matched with the left hand. */
|
|
39
|
+
left: true
|
|
40
|
+
right?: undefined
|
|
41
|
+
hand?: undefined
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
/** Whether the controller should be matched with the right hand. */
|
|
45
|
+
right: true
|
|
46
|
+
left?: undefined
|
|
47
|
+
hand?: undefined
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
/** Whether the controller should be matched with the left or right hand. */
|
|
51
|
+
hand: 'left' | 'right'
|
|
52
|
+
left?: undefined
|
|
53
|
+
right?: undefined
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
let {
|
|
58
|
+
left,
|
|
59
|
+
right,
|
|
60
|
+
hand,
|
|
61
|
+
|
|
46
62
|
onconnected,
|
|
47
63
|
ondisconnected,
|
|
48
64
|
onselect,
|
|
@@ -50,15 +66,39 @@ $effect.pre(
|
|
|
50
66
|
onselectstart,
|
|
51
67
|
onsqueeze,
|
|
52
68
|
onsqueezeend,
|
|
53
|
-
onsqueezestart
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
69
|
+
onsqueezestart,
|
|
70
|
+
|
|
71
|
+
children,
|
|
72
|
+
grip: gripSnippet,
|
|
73
|
+
targetRay: targetRaySnippet,
|
|
74
|
+
pointerRay: pointerRaySnippet,
|
|
75
|
+
pointerCursor: pointerCursorSnippet,
|
|
76
|
+
teleportRay: teleportRaySnippet,
|
|
77
|
+
teleportCursor: teleportCursorSnippet
|
|
78
|
+
}: Props = $props()
|
|
79
|
+
|
|
80
|
+
const handedness = writable<'left' | 'right'>(left ? 'left' : right ? 'right' : hand)
|
|
81
|
+
$effect.pre(() => handedness.set(left ? 'left' : right ? 'right' : (hand as 'left' | 'right')))
|
|
82
|
+
|
|
83
|
+
$effect.pre(() =>
|
|
84
|
+
controllerEvents[$handedness].set({
|
|
85
|
+
onconnected,
|
|
86
|
+
ondisconnected,
|
|
87
|
+
onselect,
|
|
88
|
+
onselectend,
|
|
89
|
+
onselectstart,
|
|
90
|
+
onsqueeze,
|
|
91
|
+
onsqueezeend,
|
|
92
|
+
onsqueezestart
|
|
93
|
+
})
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
let store = $derived(stores[$handedness])
|
|
97
|
+
let grip = $derived($store?.grip)
|
|
98
|
+
let targetRay = $derived($store?.targetRay)
|
|
99
|
+
let model = $derived($store?.model)
|
|
100
|
+
let hasPointerControls = $derived($pointerState[$handedness].enabled)
|
|
101
|
+
let hasTeleportControls = $derived($teleportState[$handedness].enabled)
|
|
62
102
|
</script>
|
|
63
103
|
|
|
64
104
|
{#if !$isHandTracking}
|
|
@@ -1,40 +1,28 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import type { XRControllerEvents } from '../types';
|
|
3
2
|
import type { Snippet } from 'svelte';
|
|
4
|
-
declare const __propDef: {
|
|
5
|
-
props: {
|
|
6
|
-
children?: Snippet<[]> | undefined;
|
|
7
|
-
grip?: Snippet<[]> | undefined;
|
|
8
|
-
targetRay?: Snippet<[]> | undefined;
|
|
9
|
-
pointerRay?: Snippet<[]> | undefined;
|
|
10
|
-
pointerCursor?: Snippet<[]> | undefined;
|
|
11
|
-
teleportRay?: Snippet<[]> | undefined;
|
|
12
|
-
teleportCursor?: Snippet<[]> | undefined;
|
|
13
|
-
} & XRControllerEvents & ({
|
|
14
|
-
/** Whether the controller should be matched with the left hand. */
|
|
15
|
-
left: true;
|
|
16
|
-
right?: undefined;
|
|
17
|
-
hand?: undefined;
|
|
18
|
-
} | {
|
|
19
|
-
/** Whether the controller should be matched with the right hand. */
|
|
20
|
-
right: true;
|
|
21
|
-
left?: undefined;
|
|
22
|
-
hand?: undefined;
|
|
23
|
-
} | {
|
|
24
|
-
/** Whether the controller should be matched with the left or right hand. */
|
|
25
|
-
hand: 'left' | 'right';
|
|
26
|
-
left?: undefined;
|
|
27
|
-
right?: undefined;
|
|
28
|
-
});
|
|
29
|
-
events: {
|
|
30
|
-
[evt: string]: CustomEvent<any>;
|
|
31
|
-
};
|
|
32
|
-
slots: {};
|
|
33
|
-
};
|
|
34
|
-
export type ControllerProps = typeof __propDef.props;
|
|
35
|
-
export type ControllerEvents = typeof __propDef.events;
|
|
36
|
-
export type ControllerSlots = typeof __propDef.slots;
|
|
37
3
|
/** `<Controller />` represents a THREE.XRTargetRaySpace, a THREE.XRGripSpace, and a controller model. */
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
4
|
+
declare const Controller: import("svelte").Component<{
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
grip?: Snippet;
|
|
7
|
+
targetRay?: Snippet;
|
|
8
|
+
pointerRay?: Snippet;
|
|
9
|
+
pointerCursor?: Snippet;
|
|
10
|
+
teleportRay?: Snippet;
|
|
11
|
+
teleportCursor?: Snippet;
|
|
12
|
+
} & (XRControllerEvents & ({
|
|
13
|
+
/** Whether the controller should be matched with the left hand. */
|
|
14
|
+
left: true;
|
|
15
|
+
right?: undefined;
|
|
16
|
+
hand?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
/** Whether the controller should be matched with the right hand. */
|
|
19
|
+
right: true;
|
|
20
|
+
left?: undefined;
|
|
21
|
+
hand?: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
/** Whether the controller should be matched with the left or right hand. */
|
|
24
|
+
hand: "left" | "right";
|
|
25
|
+
left?: undefined;
|
|
26
|
+
right?: undefined;
|
|
27
|
+
})), {}, "">;
|
|
28
|
+
export default Controller;
|
|
@@ -1,72 +1,121 @@
|
|
|
1
1
|
<script
|
|
2
2
|
lang="ts"
|
|
3
3
|
context="module"
|
|
4
|
-
>
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
>
|
|
5
|
+
import { Group } from 'three'
|
|
6
|
+
import { T, useThrelte, useTask } from '@threlte/core'
|
|
7
|
+
import type { XRHandEvents } from '../types'
|
|
8
|
+
import { isHandTracking, handEvents } from '../internal/stores'
|
|
9
|
+
import { left as leftStore, right as rightStore } from '../hooks/useHand'
|
|
10
|
+
import ScenePortal from './internal/ScenePortal.svelte'
|
|
11
|
+
import { writable } from 'svelte/store'
|
|
12
|
+
import type { Snippet } from 'svelte'
|
|
13
|
+
|
|
14
|
+
const stores = {
|
|
15
|
+
left: leftStore,
|
|
16
|
+
right: rightStore
|
|
17
|
+
} as const
|
|
14
18
|
</script>
|
|
15
19
|
|
|
16
|
-
<script lang="ts">
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
type Props = {
|
|
22
|
+
children?: Snippet
|
|
23
|
+
targetRay?: Snippet
|
|
24
|
+
wrist?: Snippet
|
|
25
|
+
} & XRHandEvents &
|
|
26
|
+
(
|
|
27
|
+
| {
|
|
28
|
+
/** Whether the XRHand should be matched with the left hand. */
|
|
29
|
+
left: true
|
|
30
|
+
right?: undefined
|
|
31
|
+
hand?: undefined
|
|
32
|
+
}
|
|
33
|
+
| {
|
|
34
|
+
/** Whether the XRHand should be matched with the right hand. */
|
|
35
|
+
right: true
|
|
36
|
+
left?: undefined
|
|
37
|
+
hand?: undefined
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
/** Whether the XRHand should be matched with the left or right hand. */
|
|
41
|
+
hand: 'left' | 'right'
|
|
42
|
+
left?: undefined
|
|
43
|
+
right?: undefined
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
let {
|
|
48
|
+
left,
|
|
49
|
+
right,
|
|
50
|
+
hand,
|
|
35
51
|
onconnected,
|
|
36
52
|
ondisconnected,
|
|
37
53
|
onpinchend,
|
|
38
|
-
onpinchstart
|
|
54
|
+
onpinchstart,
|
|
55
|
+
children,
|
|
56
|
+
targetRay,
|
|
57
|
+
wrist
|
|
58
|
+
}: Props = $props()
|
|
59
|
+
|
|
60
|
+
const { renderer, scheduler, renderStage } = useThrelte()
|
|
61
|
+
const { xr } = renderer
|
|
62
|
+
const space = xr.getReferenceSpace()
|
|
63
|
+
|
|
64
|
+
const handedness = writable<'left' | 'right'>(left ? 'left' : right ? 'right' : hand)
|
|
65
|
+
$effect.pre(() => handedness.set(left ? 'left' : right ? 'right' : (hand as 'left' | 'right')))
|
|
66
|
+
|
|
67
|
+
$effect.pre(() =>
|
|
68
|
+
handEvents[$handedness].set({
|
|
69
|
+
onconnected,
|
|
70
|
+
ondisconnected,
|
|
71
|
+
onpinchend,
|
|
72
|
+
onpinchstart
|
|
73
|
+
})
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
let group = new Group()
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Currently children of a hand XRSpace or model will not
|
|
80
|
+
* move relative to their parent, so this hack of checking wrist position
|
|
81
|
+
* and syncing any snippets is used.
|
|
82
|
+
*
|
|
83
|
+
* @todo(mp) investigate why this is happening and see if there's
|
|
84
|
+
* a way to just parent to the hand to avoid this.
|
|
85
|
+
*/
|
|
86
|
+
const { start, stop } = useTask(
|
|
87
|
+
() => {
|
|
88
|
+
const frame = xr.getFrame()
|
|
89
|
+
const joint = inputSource?.get('wrist' as unknown as number)
|
|
90
|
+
|
|
91
|
+
if (joint === undefined || space === null) return
|
|
92
|
+
|
|
93
|
+
const pose = frame.getJointPose?.(joint, space)
|
|
94
|
+
|
|
95
|
+
// This isn't correctly typed by @types/xr. Pose can also be null.
|
|
96
|
+
if (pose === undefined || pose === null) return
|
|
97
|
+
|
|
98
|
+
const { position, orientation } = pose.transform
|
|
99
|
+
group.position.set(position.x, position.y, position.z)
|
|
100
|
+
group.quaternion.set(orientation.x, orientation.y, orientation.z, orientation.w)
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
autoStart: false,
|
|
104
|
+
stage: scheduler.createStage(Symbol('xr-hand-stage'), { before: renderStage })
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
$effect.pre(() => {
|
|
109
|
+
if ($isHandTracking && (wrist !== undefined || children !== undefined) && inputSource) {
|
|
110
|
+
start()
|
|
111
|
+
} else {
|
|
112
|
+
stop()
|
|
113
|
+
}
|
|
39
114
|
})
|
|
40
|
-
|
|
41
|
-
let
|
|
42
|
-
|
|
43
|
-
()
|
|
44
|
-
const frame = xr.getFrame();
|
|
45
|
-
const joint = inputSource?.get("wrist");
|
|
46
|
-
if (joint === void 0 || space === null)
|
|
47
|
-
return;
|
|
48
|
-
const pose = frame.getJointPose?.(joint, space);
|
|
49
|
-
if (pose === void 0 || pose === null)
|
|
50
|
-
return;
|
|
51
|
-
const { position, orientation } = pose.transform;
|
|
52
|
-
group.position.set(position.x, position.y, position.z);
|
|
53
|
-
group.quaternion.set(orientation.x, orientation.y, orientation.z, orientation.w);
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
autoStart: false,
|
|
57
|
-
stage: scheduler.createStage(Symbol("xr-hand-stage"), { before: renderStage })
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
$effect.pre(() => {
|
|
61
|
-
if ($isHandTracking && (wrist !== void 0 || children !== void 0) && inputSource) {
|
|
62
|
-
start();
|
|
63
|
-
} else {
|
|
64
|
-
stop();
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
let store = $derived(stores[$handedness]);
|
|
68
|
-
let inputSource = $derived($store?.inputSource);
|
|
69
|
-
let model = $derived($store?.model);
|
|
115
|
+
|
|
116
|
+
let store = $derived(stores[$handedness])
|
|
117
|
+
let inputSource = $derived($store?.inputSource)
|
|
118
|
+
let model = $derived($store?.model)
|
|
70
119
|
</script>
|
|
71
120
|
|
|
72
121
|
{#if $store?.hand && $isHandTracking}
|
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import type { XRHandEvents } from '../types';
|
|
3
2
|
import type { Snippet } from 'svelte';
|
|
4
|
-
declare const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
events: {
|
|
26
|
-
[evt: string]: CustomEvent<any>;
|
|
27
|
-
};
|
|
28
|
-
slots: {};
|
|
29
|
-
};
|
|
30
|
-
export type HandProps = typeof __propDef.props;
|
|
31
|
-
export type HandEvents = typeof __propDef.events;
|
|
32
|
-
export type HandSlots = typeof __propDef.slots;
|
|
33
|
-
export default class Hand extends SvelteComponent<HandProps, HandEvents, HandSlots> {
|
|
34
|
-
}
|
|
35
|
-
export {};
|
|
3
|
+
declare const Hand: import("svelte").Component<{
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
targetRay?: Snippet;
|
|
6
|
+
wrist?: Snippet;
|
|
7
|
+
} & (XRHandEvents & ({
|
|
8
|
+
/** Whether the XRHand should be matched with the left hand. */
|
|
9
|
+
left: true;
|
|
10
|
+
right?: undefined;
|
|
11
|
+
hand?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
/** Whether the XRHand should be matched with the right hand. */
|
|
14
|
+
right: true;
|
|
15
|
+
left?: undefined;
|
|
16
|
+
hand?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
/** Whether the XRHand should be matched with the left or right hand. */
|
|
19
|
+
hand: "left" | "right";
|
|
20
|
+
left?: undefined;
|
|
21
|
+
right?: undefined;
|
|
22
|
+
})), {}, "">;
|
|
23
|
+
export default Hand;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { T } from '@threlte/core'
|
|
3
|
+
import { useHeadset } from '../hooks/useHeadset'
|
|
4
|
+
import ScenePortal from './internal/ScenePortal.svelte'
|
|
5
|
+
|
|
6
|
+
const headset = useHeadset()
|
|
5
7
|
</script>
|
|
6
8
|
|
|
7
9
|
<ScenePortal>
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
5
11
|
};
|
|
6
|
-
|
|
7
|
-
[evt: string]: CustomEvent<any>;
|
|
8
|
-
};
|
|
9
|
-
slots: {
|
|
10
|
-
default: {};
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export type HeadsetProps = typeof __propDef.props;
|
|
14
|
-
export type HeadsetEvents = typeof __propDef.events;
|
|
15
|
-
export type HeadsetSlots = typeof __propDef.slots;
|
|
16
|
-
export default class Headset extends SvelteComponent<HeadsetProps, HeadsetEvents, HeadsetSlots> {
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
17
13
|
}
|
|
18
|
-
|
|
14
|
+
declare const Headset: $$__sveltets_2_IsomorphicComponent<any, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {
|
|
17
|
+
default: {};
|
|
18
|
+
}, {}, string>;
|
|
19
|
+
type Headset = InstanceType<typeof Headset>;
|
|
20
|
+
export default Headset;
|
|
@@ -9,9 +9,14 @@
|
|
|
9
9
|
/>
|
|
10
10
|
```
|
|
11
11
|
-->
|
|
12
|
-
<script lang="ts">
|
|
13
|
-
import {
|
|
14
|
-
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import type { ComponentProps } from 'svelte'
|
|
14
|
+
import XRButton from './XRButton.svelte'
|
|
15
|
+
import { defaultFeatures } from '../internal/defaultFeatures'
|
|
16
|
+
|
|
17
|
+
type Props = Omit<ComponentProps<XRButton>, 'mode' | 'sessionInit'>
|
|
18
|
+
|
|
19
|
+
let { ...props }: Props = $props()
|
|
15
20
|
</script>
|
|
16
21
|
|
|
17
22
|
<XRButton
|
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
/// <reference types="webxr" />
|
|
2
|
-
import { SvelteComponent } from "svelte";
|
|
3
|
-
declare const __propDef: {
|
|
4
|
-
props: Omit<import("svelte/elements").HTMLButtonAttributes & {
|
|
5
|
-
mode: XRSessionMode;
|
|
6
|
-
sessionInit?: (XRSessionInit & {
|
|
7
|
-
domOverlay?: {
|
|
8
|
-
root: HTMLElement;
|
|
9
|
-
} | undefined;
|
|
10
|
-
}) | undefined;
|
|
11
|
-
force?: "enter" | "exit" | undefined;
|
|
12
|
-
styled?: boolean | undefined;
|
|
13
|
-
children?: import("svelte").Snippet<[{
|
|
14
|
-
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
15
|
-
}]> | undefined;
|
|
16
|
-
onclick?: ((event: {
|
|
17
|
-
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
18
|
-
nativeEvent: MouseEvent;
|
|
19
|
-
}) => void) | undefined;
|
|
20
|
-
onerror?: ((error: Error) => void) | undefined;
|
|
21
|
-
}, "mode" | "sessionInit">;
|
|
22
|
-
events: {
|
|
23
|
-
[evt: string]: CustomEvent<any>;
|
|
24
|
-
};
|
|
25
|
-
slots: {};
|
|
26
|
-
};
|
|
27
|
-
export type VrButtonProps = typeof __propDef.props;
|
|
28
|
-
export type VrButtonEvents = typeof __propDef.events;
|
|
29
|
-
export type VrButtonSlots = typeof __propDef.slots;
|
|
30
1
|
/**
|
|
31
2
|
* `<VRButton />` is an HTML `<button />` that can be used to init and display info about your immersive VR session.
|
|
32
3
|
*
|
|
@@ -37,6 +8,5 @@ export type VrButtonSlots = typeof __propDef.slots;
|
|
|
37
8
|
* />
|
|
38
9
|
* ```
|
|
39
10
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export {};
|
|
11
|
+
declare const VrButton: import("svelte").Component<Omit<Record<string, any>, "mode" | "sessionInit">, {}, "">;
|
|
12
|
+
export default VrButton;
|