@threlte/xr 1.0.0-next.1 → 1.0.0-next.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/dist/components/ARButton.svelte +2 -2
- package/dist/components/ARButton.svelte.d.ts +12 -2
- package/dist/components/Controller.svelte +25 -3
- package/dist/components/Controller.svelte.d.ts +9 -12
- package/dist/components/Hand.svelte +9 -2
- package/dist/components/Hand.svelte.d.ts +9 -15
- package/dist/components/VRButton.svelte +2 -2
- package/dist/components/VRButton.svelte.d.ts +12 -2
- package/dist/components/XR.svelte +18 -13
- package/dist/components/XR.svelte.d.ts +18 -25
- package/dist/components/XRButton.svelte +9 -7
- package/dist/components/XRButton.svelte.d.ts +12 -2
- package/dist/components/internal/Cursor.svelte +12 -11
- package/dist/components/internal/Cursor.svelte.d.ts +3 -3
- package/dist/components/internal/PointerCursor.svelte +5 -6
- package/dist/components/internal/PointerCursor.svelte.d.ts +1 -0
- package/dist/components/internal/ShortRay.svelte +6 -7
- package/dist/components/internal/ShortRay.svelte.d.ts +1 -0
- package/dist/components/internal/TeleportCursor.svelte +4 -4
- package/dist/components/internal/TeleportCursor.svelte.d.ts +1 -0
- package/dist/components/internal/TeleportRay.svelte +4 -5
- package/dist/components/internal/TeleportRay.svelte.d.ts +1 -0
- package/dist/internal/stores.d.ts +5 -4
- package/dist/plugins/pointerControls/context.d.ts +12 -0
- package/dist/plugins/pointerControls/hook.d.ts +1 -1
- package/dist/plugins/pointerControls/hook.js +6 -5
- package/dist/plugins/pointerControls/plugin.js +9 -11
- package/dist/plugins/pointerControls/setup.js +35 -34
- package/dist/plugins/pointerControls/types.d.ts +10 -10
- package/dist/plugins/pointerControls/types.js +9 -9
- package/dist/plugins/teleportControls/context.d.ts +11 -5
- package/dist/plugins/teleportControls/context.js +45 -2
- package/dist/plugins/teleportControls/index.js +4 -13
- package/dist/plugins/teleportControls/plugin.js +9 -9
- package/dist/plugins/teleportControls/setup.js +1 -1
- package/dist/types.d.ts +23 -7
- package/package.json +4 -4
- package/dist/plugins/pointerControls/useComponentEventHandlers.d.ts +0 -4
- package/dist/plugins/pointerControls/useComponentEventHandlers.js +0 -13
- package/dist/plugins/teleportControls/hook.d.ts +0 -7
- package/dist/plugins/teleportControls/hook.js +0 -40
|
@@ -10,6 +10,16 @@ declare const __propDef: {
|
|
|
10
10
|
}) | undefined;
|
|
11
11
|
force?: "enter" | "exit" | undefined;
|
|
12
12
|
styled?: boolean | undefined;
|
|
13
|
+
children?: ((this: void, args_0: {
|
|
14
|
+
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
15
|
+
}) => typeof import("svelte").SnippetReturn & {
|
|
16
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
17
|
+
}) | undefined;
|
|
18
|
+
onclick?: ((event: {
|
|
19
|
+
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
20
|
+
nativeEvent: MouseEvent;
|
|
21
|
+
}) => void) | undefined;
|
|
22
|
+
onerror?: ((error: Error) => void) | undefined;
|
|
13
23
|
}, "mode" | "sessionInit"> & {
|
|
14
24
|
sessionInit?: (XRSessionInit & {
|
|
15
25
|
domOverlay?: {
|
|
@@ -30,8 +40,8 @@ export type ArButtonSlots = typeof __propDef.slots;
|
|
|
30
40
|
*
|
|
31
41
|
* ```svelte
|
|
32
42
|
* <ARButton
|
|
33
|
-
*
|
|
34
|
-
*
|
|
43
|
+
* onerror={(event) => {}}
|
|
44
|
+
* onclick={(event) => {}}
|
|
35
45
|
* />
|
|
36
46
|
* ```
|
|
37
47
|
*/
|
|
@@ -19,11 +19,33 @@ const stores = {
|
|
|
19
19
|
};
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
|
-
<script lang="ts">let {
|
|
22
|
+
<script lang="ts">let {
|
|
23
|
+
left,
|
|
24
|
+
right,
|
|
25
|
+
hand,
|
|
26
|
+
onconnected,
|
|
27
|
+
ondisconnected,
|
|
28
|
+
onselect,
|
|
29
|
+
onselectend,
|
|
30
|
+
onselectstart,
|
|
31
|
+
onsqueeze,
|
|
32
|
+
onsqueezeend,
|
|
33
|
+
onsqueezestart
|
|
34
|
+
} = $props();
|
|
23
35
|
const handedness = writable(left ? "left" : right ? "right" : hand);
|
|
24
36
|
$effect.pre(() => handedness.set(left ? "left" : right ? "right" : hand));
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
$effect.pre(
|
|
38
|
+
() => controllerEvents[$handedness].set({
|
|
39
|
+
onconnected,
|
|
40
|
+
ondisconnected,
|
|
41
|
+
onselect,
|
|
42
|
+
onselectend,
|
|
43
|
+
onselectstart,
|
|
44
|
+
onsqueeze,
|
|
45
|
+
onsqueezeend,
|
|
46
|
+
onsqueezestart
|
|
47
|
+
})
|
|
48
|
+
);
|
|
27
49
|
let store = $derived(stores[$handedness]);
|
|
28
50
|
let grip = $derived($store?.grip);
|
|
29
51
|
let targetRay = $derived($store?.targetRay);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import type {
|
|
2
|
+
import type { XRControllerEvents } from '../types';
|
|
3
3
|
declare const __propDef: {
|
|
4
|
-
props: {
|
|
4
|
+
props: (XRControllerEvents & ({
|
|
5
5
|
/** Whether the controller should be matched with the left hand. */
|
|
6
6
|
left: true;
|
|
7
7
|
right?: undefined;
|
|
@@ -16,6 +16,13 @@ declare const __propDef: {
|
|
|
16
16
|
hand: 'left' | 'right';
|
|
17
17
|
left?: undefined;
|
|
18
18
|
right?: undefined;
|
|
19
|
+
})) & {
|
|
20
|
+
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
21
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
22
|
+
}) | undefined;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
19
26
|
};
|
|
20
27
|
slots: {
|
|
21
28
|
default: {};
|
|
@@ -26,16 +33,6 @@ declare const __propDef: {
|
|
|
26
33
|
'teleport-ray': {};
|
|
27
34
|
'teleport-cursor': {};
|
|
28
35
|
};
|
|
29
|
-
events: {
|
|
30
|
-
connected: XRControllerEvent<'connected'>;
|
|
31
|
-
disconnected: XRControllerEvent<'disconnected'>;
|
|
32
|
-
select: XRControllerEvent<'select'>;
|
|
33
|
-
selectstart: XRControllerEvent<'selectstart'>;
|
|
34
|
-
selectend: XRControllerEvent<'selectend'>;
|
|
35
|
-
squeeze: XRControllerEvent<'squeeze'>;
|
|
36
|
-
squeezeend: XRControllerEvent<'squeezeend'>;
|
|
37
|
-
squeezestart: XRControllerEvent<'squeezestart'>;
|
|
38
|
-
};
|
|
39
36
|
};
|
|
40
37
|
export type ControllerProps = typeof __propDef.props;
|
|
41
38
|
export type ControllerEvents = typeof __propDef.events;
|
|
@@ -13,12 +13,19 @@ const stores = {
|
|
|
13
13
|
};
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
|
-
<script lang="ts">let { left, right, hand,
|
|
16
|
+
<script lang="ts">let { left, right, hand, onconnected, ondisconnected, onpinchend, onpinchstart } = $props();
|
|
17
17
|
const { xr } = useThrelte().renderer;
|
|
18
18
|
const space = xr.getReferenceSpace();
|
|
19
19
|
const handedness = writable(left ? "left" : right ? "right" : hand);
|
|
20
20
|
$effect.pre(() => handedness.set(left ? "left" : right ? "right" : hand));
|
|
21
|
-
$effect.pre(
|
|
21
|
+
$effect.pre(
|
|
22
|
+
() => handEvents[$handedness].set({
|
|
23
|
+
onconnected,
|
|
24
|
+
ondisconnected,
|
|
25
|
+
onpinchend,
|
|
26
|
+
onpinchstart
|
|
27
|
+
})
|
|
28
|
+
);
|
|
22
29
|
let children = new Group();
|
|
23
30
|
const { start, stop } = useTask(
|
|
24
31
|
() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import type {
|
|
2
|
+
import type { XRHandEvents } from '../types';
|
|
3
3
|
declare const __propDef: {
|
|
4
|
-
props: ({
|
|
4
|
+
props: (XRHandEvents & ({
|
|
5
5
|
/** Whether the XRHand should be matched with the left hand. */
|
|
6
6
|
left: true;
|
|
7
7
|
right?: undefined;
|
|
@@ -16,25 +16,19 @@ declare const __propDef: {
|
|
|
16
16
|
hand: 'left' | 'right';
|
|
17
17
|
left?: undefined;
|
|
18
18
|
right?: undefined;
|
|
19
|
-
}) & {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
})) & {
|
|
20
|
+
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
21
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
22
|
+
}) | undefined;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
26
26
|
};
|
|
27
27
|
slots: {
|
|
28
28
|
'target-ray': {};
|
|
29
29
|
wrist: {};
|
|
30
30
|
default: {};
|
|
31
31
|
};
|
|
32
|
-
events: {
|
|
33
|
-
connected: XRHandEvent<'connected'>;
|
|
34
|
-
disconnected: XRHandEvent<'disconnected'>;
|
|
35
|
-
pinchstart: XRHandEvent<'pinchstart'>;
|
|
36
|
-
pinchend: XRHandEvent<'pinchend'>;
|
|
37
|
-
};
|
|
38
32
|
};
|
|
39
33
|
export type HandProps = typeof __propDef.props;
|
|
40
34
|
export type HandEvents = typeof __propDef.events;
|
|
@@ -10,6 +10,16 @@ declare const __propDef: {
|
|
|
10
10
|
}) | undefined;
|
|
11
11
|
force?: "enter" | "exit" | undefined;
|
|
12
12
|
styled?: boolean | undefined;
|
|
13
|
+
children?: ((this: void, args_0: {
|
|
14
|
+
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
15
|
+
}) => typeof import("svelte").SnippetReturn & {
|
|
16
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
17
|
+
}) | undefined;
|
|
18
|
+
onclick?: ((event: {
|
|
19
|
+
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
20
|
+
nativeEvent: MouseEvent;
|
|
21
|
+
}) => void) | undefined;
|
|
22
|
+
onerror?: ((error: Error) => void) | undefined;
|
|
13
23
|
}, "mode" | "sessionInit">;
|
|
14
24
|
events: {
|
|
15
25
|
[evt: string]: CustomEvent<any>;
|
|
@@ -24,8 +34,8 @@ export type VrButtonSlots = typeof __propDef.slots;
|
|
|
24
34
|
*
|
|
25
35
|
* ```svelte
|
|
26
36
|
* <VRButton
|
|
27
|
-
*
|
|
28
|
-
*
|
|
37
|
+
* onerror={(event) => {}}
|
|
38
|
+
* onclick={(event) => {}}
|
|
29
39
|
* />
|
|
30
40
|
* ```
|
|
31
41
|
*/
|
|
@@ -9,16 +9,16 @@ This should be placed within a Threlte `<Canvas />`.
|
|
|
9
9
|
foveation={1}
|
|
10
10
|
frameRate={90}
|
|
11
11
|
referenceSpace='local-floor'
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
onsessionstart={(event: XREvent<XRManagerEvent>) => {}}
|
|
13
|
+
onsessionend={(event: XREvent<XRManagerEvent>) => {}}
|
|
14
|
+
onvisibilitychange={(event: XREvent<XRSessionEvent>) => {}}
|
|
15
|
+
oninputsourceschange={(event: XREvent<XRSessionEvent>) => {}}
|
|
16
16
|
/>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
-->
|
|
20
20
|
<script lang="ts">import { onMount } from "svelte";
|
|
21
|
-
import {
|
|
21
|
+
import { useThrelte, watch } from "@threlte/core";
|
|
22
22
|
import {
|
|
23
23
|
isHandTracking,
|
|
24
24
|
isPresenting,
|
|
@@ -34,7 +34,12 @@ let {
|
|
|
34
34
|
foveation = 1,
|
|
35
35
|
frameRate,
|
|
36
36
|
referenceSpace = "local-floor",
|
|
37
|
-
|
|
37
|
+
onsessionstart,
|
|
38
|
+
onsessionend,
|
|
39
|
+
onvisibilitychange,
|
|
40
|
+
oninputsourceschange,
|
|
41
|
+
fallback,
|
|
42
|
+
children
|
|
38
43
|
} = $props();
|
|
39
44
|
const { renderer, renderMode } = useThrelte();
|
|
40
45
|
const { xr } = renderer;
|
|
@@ -45,22 +50,22 @@ setupControllers();
|
|
|
45
50
|
setupHands();
|
|
46
51
|
const handleSessionStart = () => {
|
|
47
52
|
isPresenting.set(true);
|
|
48
|
-
|
|
53
|
+
onsessionstart?.({ type: "sessionstart", target: $session });
|
|
49
54
|
};
|
|
50
55
|
const handleSessionEnd = () => {
|
|
51
|
-
|
|
56
|
+
onsessionend?.({ type: "sessionend", target: $session });
|
|
52
57
|
isPresenting.set(false);
|
|
53
58
|
session.set(void 0);
|
|
54
59
|
};
|
|
55
60
|
const handleVisibilityChange = (event) => {
|
|
56
|
-
|
|
61
|
+
onvisibilitychange?.({ ...event, target: $session });
|
|
57
62
|
};
|
|
58
63
|
const handleInputSourcesChange = (event) => {
|
|
59
64
|
$isHandTracking = Object.values(event.session.inputSources).some((source) => source.hand);
|
|
60
|
-
|
|
65
|
+
oninputsourceschange?.({ ...event, target: $session });
|
|
61
66
|
};
|
|
62
67
|
const handleFramerateChange = (event) => {
|
|
63
|
-
|
|
68
|
+
onvisibilitychange?.({ ...event, target: $session });
|
|
64
69
|
};
|
|
65
70
|
const updateTargetFrameRate = (frameRate2) => {
|
|
66
71
|
if (frameRate2 === void 0)
|
|
@@ -113,7 +118,7 @@ $effect.pre(() => {
|
|
|
113
118
|
</script>
|
|
114
119
|
|
|
115
120
|
{#if $isPresenting}
|
|
116
|
-
|
|
121
|
+
{@render children?.()}
|
|
117
122
|
{:else}
|
|
118
|
-
|
|
123
|
+
{@render fallback?.()}
|
|
119
124
|
{/if}
|
|
@@ -22,32 +22,25 @@ declare const __propDef: {
|
|
|
22
22
|
frameRate?: number | undefined;
|
|
23
23
|
/** Type of WebXR reference space to use. Default is `local-floor` */
|
|
24
24
|
referenceSpace?: XRReferenceSpaceType | undefined;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/** Called when an XRSession is hidden or unfocused. */
|
|
32
|
-
visibilitychange(): globalThis.XRSessionEvent;
|
|
33
|
-
/** Called when available inputsources change */
|
|
34
|
-
inputsourceschange(): globalThis.XRSessionEvent;
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
slots: {
|
|
38
|
-
default: {};
|
|
39
|
-
fallback: {};
|
|
40
|
-
};
|
|
41
|
-
events: {
|
|
25
|
+
fallback?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
26
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
27
|
+
}) | undefined;
|
|
28
|
+
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
29
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
30
|
+
}) | undefined;
|
|
42
31
|
/** Called as an XRSession is requested */
|
|
43
|
-
|
|
32
|
+
onsessionstart?: ((event: XRSessionEvent<'sessionstart'>) => void) | undefined;
|
|
44
33
|
/** Called after an XRSession is terminated */
|
|
45
|
-
|
|
34
|
+
onsessionend?: ((event: XRSessionEvent<'sessionend'>) => void) | undefined;
|
|
46
35
|
/** Called when an XRSession is hidden or unfocused. */
|
|
47
|
-
|
|
36
|
+
onvisibilitychange?: ((event: globalThis.XRSessionEvent) => void) | undefined;
|
|
48
37
|
/** Called when available inputsources change */
|
|
49
|
-
|
|
38
|
+
oninputsourceschange?: ((event: globalThis.XRSessionEvent) => void) | undefined;
|
|
39
|
+
};
|
|
40
|
+
events: {
|
|
41
|
+
[evt: string]: CustomEvent<any>;
|
|
50
42
|
};
|
|
43
|
+
slots: {};
|
|
51
44
|
};
|
|
52
45
|
export type XrProps = typeof __propDef.props;
|
|
53
46
|
export type XrEvents = typeof __propDef.events;
|
|
@@ -62,10 +55,10 @@ export type XrSlots = typeof __propDef.slots;
|
|
|
62
55
|
* foveation={1}
|
|
63
56
|
* frameRate={90}
|
|
64
57
|
* referenceSpace='local-floor'
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
58
|
+
* onsessionstart={(event: XREvent<XRManagerEvent>) => {}}
|
|
59
|
+
* onsessionend={(event: XREvent<XRManagerEvent>) => {}}
|
|
60
|
+
* onvisibilitychange={(event: XREvent<XRSessionEvent>) => {}}
|
|
61
|
+
* oninputsourceschange={(event: XREvent<XRSessionEvent>) => {}}
|
|
69
62
|
* />
|
|
70
63
|
* ```
|
|
71
64
|
*/
|
|
@@ -12,28 +12,28 @@ display info about your WebXR session. This is aliased by `ARButton` and
|
|
|
12
12
|
}}
|
|
13
13
|
force={'enter' | 'exit' | undefined}
|
|
14
14
|
styled={'true' | 'false'}
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
onerror={(event) => {}}
|
|
16
|
+
onclick={(event) => {}}
|
|
17
17
|
/>
|
|
18
18
|
```
|
|
19
19
|
-->
|
|
20
20
|
<script lang="ts">import { getXRSupportState } from "../lib/getXRSupportState";
|
|
21
21
|
import { toggleXRSession } from "../lib/toggleXRSession";
|
|
22
22
|
import { session, xr } from "../internal/stores";
|
|
23
|
-
let { mode, sessionInit, force, styled = true, ...props } = $props();
|
|
23
|
+
let { mode, sessionInit, force, styled = true, onclick, onerror, children, ...props } = $props();
|
|
24
24
|
const handleButtonClick = async (nativeEvent, state) => {
|
|
25
25
|
if (!$xr) {
|
|
26
26
|
throw new Error(
|
|
27
27
|
"The <XR> component was not created. This is required to start an XR session."
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
onclick?.({ state, nativeEvent });
|
|
31
31
|
if (state !== "supported")
|
|
32
32
|
return;
|
|
33
33
|
try {
|
|
34
34
|
await toggleXRSession(mode, sessionInit, force);
|
|
35
35
|
} catch (error) {
|
|
36
|
-
|
|
36
|
+
onerror?.(error);
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
let modeText = $derived(
|
|
@@ -62,13 +62,15 @@ let style = $derived(
|
|
|
62
62
|
|
|
63
63
|
{#await getXRSupportState(mode) then state}
|
|
64
64
|
<button
|
|
65
|
-
|
|
65
|
+
onclick={(event) => {
|
|
66
66
|
handleButtonClick(event, state)
|
|
67
67
|
}}
|
|
68
68
|
{...props}
|
|
69
69
|
{style}
|
|
70
70
|
>
|
|
71
|
-
{#if
|
|
71
|
+
{#if children}
|
|
72
|
+
{@render children?.({ state })}
|
|
73
|
+
{:else if state === 'unsupported'}
|
|
72
74
|
{modeText} unsupported
|
|
73
75
|
{:else if state === 'insecure'}
|
|
74
76
|
HTTPS needed
|
|
@@ -18,6 +18,16 @@ declare const __propDef: {
|
|
|
18
18
|
force?: "enter" | "exit" | undefined;
|
|
19
19
|
/** Whether to apply automatic styling to the button. Set false to apply custom styles. Default is true. */
|
|
20
20
|
styled?: boolean | undefined;
|
|
21
|
+
children?: ((this: void, args_0: {
|
|
22
|
+
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
23
|
+
}) => typeof import("svelte").SnippetReturn & {
|
|
24
|
+
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
25
|
+
}) | undefined;
|
|
26
|
+
onclick?: ((event: {
|
|
27
|
+
state: "blocked" | "unsupported" | "insecure" | "supported";
|
|
28
|
+
nativeEvent: MouseEvent;
|
|
29
|
+
}) => void) | undefined;
|
|
30
|
+
onerror?: ((error: Error) => void) | undefined;
|
|
21
31
|
};
|
|
22
32
|
events: {
|
|
23
33
|
[evt: string]: CustomEvent<any>;
|
|
@@ -40,8 +50,8 @@ export type XrButtonSlots = typeof __propDef.slots;
|
|
|
40
50
|
* }}
|
|
41
51
|
* force={'enter' | 'exit' | undefined}
|
|
42
52
|
* styled={'true' | 'false'}
|
|
43
|
-
*
|
|
44
|
-
*
|
|
53
|
+
* onerror={(event) => {}}
|
|
54
|
+
* onclick={(event) => {}}
|
|
45
55
|
* />
|
|
46
56
|
* ```
|
|
47
57
|
*/
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<script lang="ts">import { Color, DoubleSide, RawShaderMaterial } from "three";
|
|
2
2
|
import { T } from "@threlte/core";
|
|
3
|
-
|
|
4
|
-
export let size = 0.03;
|
|
5
|
-
export let thickness = 0.035;
|
|
3
|
+
let { color = new Color("white"), size = 0.03, thickness = 0.035 } = $props();
|
|
6
4
|
const vertexShader = `
|
|
7
5
|
uniform mat4 projectionMatrix;
|
|
8
6
|
uniform mat4 modelViewMatrix;
|
|
@@ -26,21 +24,24 @@ const fragmentShader = `
|
|
|
26
24
|
gl_FragColor = vec4(color, alpha);
|
|
27
25
|
}
|
|
28
26
|
`;
|
|
27
|
+
const uniforms = {
|
|
28
|
+
thickness: { value: thickness },
|
|
29
|
+
color: { value: color }
|
|
30
|
+
};
|
|
29
31
|
const shaderMaterial = new RawShaderMaterial({
|
|
30
32
|
vertexShader,
|
|
31
33
|
fragmentShader,
|
|
32
|
-
uniforms
|
|
33
|
-
thickness: { value: thickness },
|
|
34
|
-
color: { value: color }
|
|
35
|
-
},
|
|
34
|
+
uniforms,
|
|
36
35
|
side: DoubleSide,
|
|
37
36
|
transparent: true,
|
|
38
37
|
depthTest: false
|
|
39
38
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
$effect.pre(() => {
|
|
40
|
+
uniforms.thickness.value = thickness;
|
|
41
|
+
});
|
|
42
|
+
$effect.pre(() => {
|
|
43
|
+
uniforms.color.value = color;
|
|
44
|
+
});
|
|
44
45
|
</script>
|
|
45
46
|
|
|
46
47
|
<T.Mesh scale={size}>
|
|
@@ -2,9 +2,9 @@ import { SvelteComponent } from "svelte";
|
|
|
2
2
|
import { type ColorRepresentation } from 'three';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
|
-
color
|
|
6
|
-
size
|
|
7
|
-
thickness
|
|
5
|
+
color: ColorRepresentation;
|
|
6
|
+
size: number;
|
|
7
|
+
thickness: number;
|
|
8
8
|
};
|
|
9
9
|
events: {
|
|
10
10
|
[evt: string]: CustomEvent<any>;
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
import { T, useTask } from "@threlte/core";
|
|
3
3
|
import { pointerIntersection, pointerState } from "../../internal/stores";
|
|
4
4
|
import Cursor from "./Cursor.svelte";
|
|
5
|
-
|
|
5
|
+
let { handedness } = $props();
|
|
6
6
|
const ref = new Group();
|
|
7
7
|
const vec3 = new Vector3();
|
|
8
8
|
const normalMatrix = new Matrix3();
|
|
9
9
|
const worldNormal = new Vector3();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
$:
|
|
13
|
-
intersection = pointerIntersection[handedness];
|
|
10
|
+
let hovering = $derived($pointerState[handedness].hovering);
|
|
11
|
+
let intersection = $derived(pointerIntersection[handedness]);
|
|
14
12
|
const { start, stop } = useTask(
|
|
15
13
|
() => {
|
|
16
14
|
if (intersection.current === void 0)
|
|
@@ -27,13 +25,14 @@ const { start, stop } = useTask(
|
|
|
27
25
|
autoStart: false
|
|
28
26
|
}
|
|
29
27
|
);
|
|
30
|
-
|
|
28
|
+
$effect.pre(() => {
|
|
31
29
|
if (hovering) {
|
|
32
30
|
ref.position.copy(intersection.current.point);
|
|
33
31
|
start();
|
|
34
32
|
} else {
|
|
35
33
|
stop();
|
|
36
34
|
}
|
|
35
|
+
});
|
|
37
36
|
</script>
|
|
38
37
|
|
|
39
38
|
<T
|
|
@@ -2,6 +2,7 @@ import { SvelteComponent } from "svelte";
|
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
handedness: 'left' | 'right';
|
|
5
|
+
} & {
|
|
5
6
|
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
6
7
|
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
7
8
|
}) | undefined;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<script lang="ts">import { T } from "@threlte/core";
|
|
2
2
|
import { pointerState, teleportState, teleportIntersection } from "../../internal/stores";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
intersection
|
|
8
|
-
|
|
9
|
-
visible = $pointerState[handedness].enabled || hovering && $intersection === void 0;
|
|
3
|
+
let { handedness } = $props();
|
|
4
|
+
let hovering = $derived($teleportState[handedness].hovering);
|
|
5
|
+
let intersection = $derived(teleportIntersection[handedness]);
|
|
6
|
+
let visible = $derived(
|
|
7
|
+
$pointerState[handedness].enabled || hovering && $intersection === void 0
|
|
8
|
+
);
|
|
10
9
|
</script>
|
|
11
10
|
|
|
12
11
|
<T.Group {visible}>
|
|
@@ -2,6 +2,7 @@ import { SvelteComponent } from "svelte";
|
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
handedness: 'left' | 'right';
|
|
5
|
+
} & {
|
|
5
6
|
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
6
7
|
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
7
8
|
}) | undefined;
|
|
@@ -3,13 +3,12 @@ import { Group, Matrix3, Vector3 } from "three";
|
|
|
3
3
|
import { T, useTask } from "@threlte/core";
|
|
4
4
|
import { teleportIntersection } from "../../internal/stores";
|
|
5
5
|
import Cursor from "./Cursor.svelte";
|
|
6
|
-
|
|
6
|
+
let { handedness } = $props();
|
|
7
7
|
const ref = new Group();
|
|
8
8
|
const vec3 = new Vector3();
|
|
9
9
|
const normalMatrix = new Matrix3();
|
|
10
10
|
const worldNormal = new Vector3();
|
|
11
|
-
|
|
12
|
-
intersection = teleportIntersection[handedness];
|
|
11
|
+
let intersection = $derived(teleportIntersection[handedness]);
|
|
13
12
|
const { start, stop } = useTask(
|
|
14
13
|
() => {
|
|
15
14
|
if (intersection.current === void 0)
|
|
@@ -27,7 +26,7 @@ const { start, stop } = useTask(
|
|
|
27
26
|
}
|
|
28
27
|
);
|
|
29
28
|
const size = spring(0.1, { stiffness: 0.2 });
|
|
30
|
-
|
|
29
|
+
$effect.pre(() => {
|
|
31
30
|
if ($intersection === void 0) {
|
|
32
31
|
size.set(0.1);
|
|
33
32
|
stop();
|
|
@@ -36,6 +35,7 @@ $:
|
|
|
36
35
|
ref.position.copy($intersection.point);
|
|
37
36
|
start();
|
|
38
37
|
}
|
|
38
|
+
});
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
41
|
<T
|
|
@@ -2,6 +2,7 @@ import { SvelteComponent } from "svelte";
|
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
handedness: 'left' | 'right';
|
|
5
|
+
} & {
|
|
5
6
|
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
6
7
|
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
7
8
|
}) | undefined;
|
|
@@ -4,8 +4,7 @@ import { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js";
|
|
|
4
4
|
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
|
|
5
5
|
import { T, useTask } from "@threlte/core";
|
|
6
6
|
import { teleportIntersection } from "../../internal/stores";
|
|
7
|
-
|
|
8
|
-
export let targetRay;
|
|
7
|
+
let { handedness, targetRay } = $props();
|
|
9
8
|
let lineGeometry = new LineGeometry();
|
|
10
9
|
const rayStart = new Vector3();
|
|
11
10
|
const rayMidpoint = new Vector3();
|
|
@@ -15,8 +14,7 @@ const positions = new Float32Array(rayDivisions * 3);
|
|
|
15
14
|
const vec3 = new Vector3();
|
|
16
15
|
const v2_1 = new Vector2();
|
|
17
16
|
const v2_2 = new Vector2();
|
|
18
|
-
|
|
19
|
-
intersection = teleportIntersection[handedness];
|
|
17
|
+
let intersection = $derived(teleportIntersection[handedness]);
|
|
20
18
|
const setCurvePoints = (alpha = 0.3) => {
|
|
21
19
|
if (intersection.current === void 0)
|
|
22
20
|
return;
|
|
@@ -47,13 +45,14 @@ const { start, stop } = useTask(
|
|
|
47
45
|
},
|
|
48
46
|
{ autoStart: false }
|
|
49
47
|
);
|
|
50
|
-
|
|
48
|
+
$effect.pre(() => {
|
|
51
49
|
if ($intersection === void 0) {
|
|
52
50
|
stop();
|
|
53
51
|
} else {
|
|
54
52
|
setCurvePoints(1);
|
|
55
53
|
start();
|
|
56
54
|
}
|
|
55
|
+
});
|
|
57
56
|
</script>
|
|
58
57
|
|
|
59
58
|
<slot>
|
|
@@ -4,6 +4,7 @@ declare const __propDef: {
|
|
|
4
4
|
props: {
|
|
5
5
|
handedness: 'left' | 'right';
|
|
6
6
|
targetRay: XRTargetRaySpace;
|
|
7
|
+
} & {
|
|
7
8
|
children?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
8
9
|
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
9
10
|
}) | undefined;
|