@threlte/xr 1.0.6 → 1.0.8
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/Controller.svelte +26 -31
- package/dist/components/Hand.svelte +15 -17
- package/dist/components/Headset.svelte +16 -7
- package/dist/components/Headset.svelte.d.ts +7 -19
- package/dist/components/XR.svelte +11 -12
- package/dist/components/XRButton.svelte +3 -3
- package/dist/components/internal/Cursor.svelte +2 -1
- package/dist/components/internal/PointerCursor.svelte +29 -16
- package/dist/components/internal/ShortRay.svelte +4 -4
- package/dist/components/internal/TeleportCursor.svelte +22 -12
- package/dist/components/internal/TeleportRay.svelte +21 -15
- package/dist/plugins/pointerControls/setup.js +3 -3
- package/package.json +3 -3
- package/dist/components/internal/ScenePortal.svelte +0 -23
- package/dist/components/internal/ScenePortal.svelte.d.ts +0 -20
|
@@ -5,14 +5,12 @@
|
|
|
5
5
|
lang="ts"
|
|
6
6
|
module
|
|
7
7
|
>
|
|
8
|
-
import { writable } from 'svelte/store'
|
|
9
8
|
import { T } from '@threlte/core'
|
|
10
9
|
import { left as leftStore, right as rightStore } from '../hooks/useController'
|
|
11
10
|
import { isHandTracking, pointerState, teleportState, controllerEvents } from '../internal/stores'
|
|
12
11
|
import type { XRControllerEvents } from '../types'
|
|
13
12
|
import PointerCursor from './internal/PointerCursor.svelte'
|
|
14
13
|
import ShortRay from './internal/ShortRay.svelte'
|
|
15
|
-
import ScenePortal from './internal/ScenePortal.svelte'
|
|
16
14
|
import TeleportCursor from './internal/TeleportCursor.svelte'
|
|
17
15
|
import TeleportRay from './internal/TeleportRay.svelte'
|
|
18
16
|
import type { Snippet } from 'svelte'
|
|
@@ -77,11 +75,10 @@
|
|
|
77
75
|
teleportCursor: teleportCursorSnippet
|
|
78
76
|
}: Props = $props()
|
|
79
77
|
|
|
80
|
-
const handedness =
|
|
81
|
-
$effect.pre(() => handedness.set(left ? 'left' : right ? 'right' : (hand as 'left' | 'right')))
|
|
78
|
+
const handedness = $derived<'left' | 'right'>(left ? 'left' : right ? 'right' : hand ?? 'left')
|
|
82
79
|
|
|
83
80
|
$effect.pre(() =>
|
|
84
|
-
controllerEvents[
|
|
81
|
+
controllerEvents[handedness].set({
|
|
85
82
|
onconnected,
|
|
86
83
|
ondisconnected,
|
|
87
84
|
onselect,
|
|
@@ -93,12 +90,12 @@
|
|
|
93
90
|
})
|
|
94
91
|
)
|
|
95
92
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
const store = $derived(stores[handedness])
|
|
94
|
+
const grip = $derived($store?.grip)
|
|
95
|
+
const targetRay = $derived($store?.targetRay)
|
|
96
|
+
const model = $derived($store?.model)
|
|
97
|
+
const hasPointerControls = $derived($pointerState[handedness].enabled)
|
|
98
|
+
const hasTeleportControls = $derived($teleportState[handedness].enabled)
|
|
102
99
|
</script>
|
|
103
100
|
|
|
104
101
|
{#if !$isHandTracking}
|
|
@@ -120,7 +117,7 @@
|
|
|
120
117
|
|
|
121
118
|
{#if hasPointerControls || hasTeleportControls}
|
|
122
119
|
<ShortRay
|
|
123
|
-
|
|
120
|
+
{handedness}
|
|
124
121
|
children={pointerRaySnippet}
|
|
125
122
|
/>
|
|
126
123
|
{/if}
|
|
@@ -128,24 +125,22 @@
|
|
|
128
125
|
{/if}
|
|
129
126
|
{/if}
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
{/if}
|
|
128
|
+
{#if hasPointerControls}
|
|
129
|
+
<PointerCursor
|
|
130
|
+
{handedness}
|
|
131
|
+
children={pointerCursorSnippet}
|
|
132
|
+
/>
|
|
133
|
+
{/if}
|
|
138
134
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
135
|
+
{#if hasTeleportControls && targetRay !== undefined}
|
|
136
|
+
<TeleportRay
|
|
137
|
+
{targetRay}
|
|
138
|
+
{handedness}
|
|
139
|
+
children={teleportRaySnippet}
|
|
140
|
+
/>
|
|
145
141
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
</ScenePortal>
|
|
142
|
+
<TeleportCursor
|
|
143
|
+
{handedness}
|
|
144
|
+
children={teleportCursorSnippet}
|
|
145
|
+
/>
|
|
146
|
+
{/if}
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
import type { XRHandEvents } from '../types'
|
|
8
8
|
import { isHandTracking, handEvents } from '../internal/stores'
|
|
9
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
10
|
import type { Snippet } from 'svelte'
|
|
13
11
|
|
|
14
12
|
const stores = {
|
|
@@ -44,7 +42,7 @@
|
|
|
44
42
|
}
|
|
45
43
|
)
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
const {
|
|
48
46
|
left,
|
|
49
47
|
right,
|
|
50
48
|
hand,
|
|
@@ -57,15 +55,14 @@
|
|
|
57
55
|
wrist
|
|
58
56
|
}: Props = $props()
|
|
59
57
|
|
|
60
|
-
const { renderer, scheduler, renderStage } = useThrelte()
|
|
58
|
+
const { scene, renderer, scheduler, renderStage } = useThrelte()
|
|
61
59
|
const { xr } = renderer
|
|
62
60
|
const space = xr.getReferenceSpace()
|
|
63
61
|
|
|
64
|
-
const handedness =
|
|
65
|
-
$effect.pre(() => handedness.set(left ? 'left' : right ? 'right' : (hand as 'left' | 'right')))
|
|
62
|
+
const handedness = $derived<'left' | 'right'>(left ? 'left' : right ? 'right' : hand ?? 'left')
|
|
66
63
|
|
|
67
64
|
$effect.pre(() =>
|
|
68
|
-
handEvents[
|
|
65
|
+
handEvents[handedness].set({
|
|
69
66
|
onconnected,
|
|
70
67
|
ondisconnected,
|
|
71
68
|
onpinchend,
|
|
@@ -73,7 +70,7 @@
|
|
|
73
70
|
})
|
|
74
71
|
)
|
|
75
72
|
|
|
76
|
-
|
|
73
|
+
const group = new Group()
|
|
77
74
|
|
|
78
75
|
/**
|
|
79
76
|
* Currently children of a hand XRSpace or model will not
|
|
@@ -113,9 +110,9 @@
|
|
|
113
110
|
}
|
|
114
111
|
})
|
|
115
112
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
const store = $derived(stores[handedness])
|
|
114
|
+
const inputSource = $derived($store?.inputSource)
|
|
115
|
+
const model = $derived($store?.model)
|
|
119
116
|
</script>
|
|
120
117
|
|
|
121
118
|
{#if $store?.hand && $isHandTracking}
|
|
@@ -133,10 +130,11 @@
|
|
|
133
130
|
{/if}
|
|
134
131
|
|
|
135
132
|
{#if $isHandTracking}
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
133
|
+
<T
|
|
134
|
+
is={group}
|
|
135
|
+
attach={scene}
|
|
136
|
+
>
|
|
137
|
+
{@render wrist?.()}
|
|
138
|
+
{@render children?.()}
|
|
139
|
+
</T>
|
|
142
140
|
{/if}
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
3
|
+
import type { Group } from 'three'
|
|
4
|
+
import { T, useThrelte } from '@threlte/core'
|
|
3
5
|
import { useHeadset } from '../hooks/useHeadset'
|
|
4
|
-
import ScenePortal from './internal/ScenePortal.svelte'
|
|
5
6
|
|
|
7
|
+
interface Props {
|
|
8
|
+
children?: Snippet<[{ ref: Group }]>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { children }: Props = $props()
|
|
12
|
+
|
|
13
|
+
const { scene } = useThrelte()
|
|
6
14
|
const headset = useHeadset()
|
|
7
15
|
</script>
|
|
8
16
|
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
<T
|
|
18
|
+
is={headset}
|
|
19
|
+
attach={scene}
|
|
20
|
+
>
|
|
21
|
+
{@render children?.({ ref: headset })}
|
|
22
|
+
</T>
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}): Exports & {
|
|
9
|
-
$set?: any;
|
|
10
|
-
$on?: any;
|
|
11
|
-
};
|
|
12
|
-
z_$$bindings?: Bindings;
|
|
13
|
-
}
|
|
14
|
-
declare const Headset: $$__sveltets_2_IsomorphicComponent<any, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {
|
|
17
|
-
default: {};
|
|
18
|
-
}, {}, string>;
|
|
19
|
-
type Headset = InstanceType<typeof Headset>;
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { Group } from 'three';
|
|
3
|
+
declare const Headset: import("svelte").Component<{
|
|
4
|
+
children?: Snippet<[{
|
|
5
|
+
ref: Group;
|
|
6
|
+
}]>;
|
|
7
|
+
}, {}, "">;
|
|
20
8
|
export default Headset;
|
|
@@ -18,7 +18,7 @@ This should be placed within a Threlte `<Canvas />`.
|
|
|
18
18
|
|
|
19
19
|
-->
|
|
20
20
|
<script lang="ts">
|
|
21
|
-
import {
|
|
21
|
+
import { onMount, type Snippet } from 'svelte'
|
|
22
22
|
import { useThrelte, watch } from '@threlte/core'
|
|
23
23
|
import type { XRSessionEvent } from '../types'
|
|
24
24
|
import {
|
|
@@ -135,10 +135,6 @@ This should be placed within a Threlte `<Canvas />`.
|
|
|
135
135
|
currentSession.addEventListener('inputsourceschange', handleInputSourcesChange)
|
|
136
136
|
currentSession.addEventListener('frameratechange', handleFramerateChange)
|
|
137
137
|
|
|
138
|
-
xr.setFoveation(foveation)
|
|
139
|
-
|
|
140
|
-
updateTargetFrameRate(frameRate)
|
|
141
|
-
|
|
142
138
|
return () => {
|
|
143
139
|
currentSession.removeEventListener('visibilitychange', handleVisibilityChange)
|
|
144
140
|
currentSession.removeEventListener('inputsourceschange', handleInputSourcesChange)
|
|
@@ -166,17 +162,20 @@ This should be placed within a Threlte `<Canvas />`.
|
|
|
166
162
|
xr.enabled = false
|
|
167
163
|
xr.removeEventListener('sessionstart', handleSessionStart)
|
|
168
164
|
xr.removeEventListener('sessionend', handleSessionEnd)
|
|
165
|
+
|
|
166
|
+
// if unmounted while presenting (e.g. due to sveltekit navigation), end the session
|
|
167
|
+
session.current?.end()
|
|
169
168
|
}
|
|
170
169
|
})
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
|
|
171
|
+
$effect.pre(() => {
|
|
172
|
+
updateTargetFrameRate(frameRate)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
$effect.pre(() => {
|
|
176
|
+
xr.setFoveation(foveation)
|
|
176
177
|
})
|
|
177
178
|
|
|
178
|
-
$effect.pre(() => updateTargetFrameRate(frameRate))
|
|
179
|
-
$effect.pre(() => xr.setFoveation(foveation))
|
|
180
179
|
$effect.pre(() => {
|
|
181
180
|
xr.setReferenceSpaceType(referenceSpace)
|
|
182
181
|
$referenceSpaceType = referenceSpace
|
|
@@ -75,7 +75,7 @@ display info about your WebXR session. This is aliased by `ARButton` and
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
const modeText = $derived(
|
|
79
79
|
{
|
|
80
80
|
'immersive-vr': 'VR',
|
|
81
81
|
'immersive-ar': 'AR',
|
|
@@ -83,7 +83,7 @@ display info about your WebXR session. This is aliased by `ARButton` and
|
|
|
83
83
|
}[mode]
|
|
84
84
|
)
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
const style = $derived(
|
|
87
87
|
styled
|
|
88
88
|
? `
|
|
89
89
|
position: absolute;
|
|
@@ -111,7 +111,7 @@ display info about your WebXR session. This is aliased by `ARButton` and
|
|
|
111
111
|
{style}
|
|
112
112
|
>
|
|
113
113
|
{#if children}
|
|
114
|
-
{@render children
|
|
114
|
+
{@render children({ state })}
|
|
115
115
|
{:else if state === 'unsupported'}
|
|
116
116
|
{modeText} unsupported
|
|
117
117
|
{:else if state === 'insecure'}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
thickness?: number
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const { color = new Color('white'), size = 0.03, thickness = 0.035 }: Props = $props()
|
|
12
12
|
|
|
13
13
|
const vertexShader = `
|
|
14
14
|
uniform mat4 projectionMatrix;
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
$effect.pre(() => {
|
|
53
53
|
uniforms.thickness.value = thickness
|
|
54
54
|
})
|
|
55
|
+
|
|
55
56
|
$effect.pre(() => {
|
|
56
57
|
uniforms.color.value = color
|
|
57
58
|
})
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script
|
|
2
|
+
module
|
|
3
|
+
lang="ts"
|
|
4
|
+
>
|
|
2
5
|
import { Group, Vector3, Matrix3 } from 'three'
|
|
3
|
-
|
|
6
|
+
|
|
7
|
+
const vec3 = new Vector3()
|
|
8
|
+
const normalMatrix = new Matrix3()
|
|
9
|
+
const worldNormal = new Vector3()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { T, useTask, useThrelte } from '@threlte/core'
|
|
4
14
|
import { pointerIntersection, pointerState } from '../../internal/stores'
|
|
5
15
|
import Cursor from './Cursor.svelte'
|
|
6
16
|
import type { Snippet } from 'svelte'
|
|
@@ -10,27 +20,29 @@
|
|
|
10
20
|
children?: Snippet
|
|
11
21
|
}
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
const { handedness, children }: Props = $props()
|
|
14
24
|
|
|
25
|
+
const { scene } = useThrelte()
|
|
15
26
|
const ref = new Group()
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const worldNormal = new Vector3()
|
|
19
|
-
|
|
20
|
-
let hovering = $derived($pointerState[handedness].hovering)
|
|
21
|
-
let intersection = $derived(pointerIntersection[handedness])
|
|
27
|
+
const hovering = $derived($pointerState[handedness].hovering)
|
|
28
|
+
const intersection = $derived(pointerIntersection[handedness])
|
|
22
29
|
|
|
23
30
|
const { start, stop } = useTask(
|
|
24
31
|
() => {
|
|
25
|
-
if (intersection.current === undefined)
|
|
32
|
+
if (intersection.current === undefined) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
const { point, face, object } = intersection.current
|
|
27
37
|
ref.position.lerp(point, 0.4)
|
|
28
38
|
|
|
29
|
-
if (face) {
|
|
30
|
-
|
|
31
|
-
worldNormal.copy(face.normal).applyMatrix3(normalMatrix).normalize()
|
|
32
|
-
ref.lookAt(vec3.addVectors(point, worldNormal))
|
|
39
|
+
if (face === null || face === undefined) {
|
|
40
|
+
return
|
|
33
41
|
}
|
|
42
|
+
|
|
43
|
+
normalMatrix.getNormalMatrix(object.matrixWorld)
|
|
44
|
+
worldNormal.copy(face.normal).applyMatrix3(normalMatrix).normalize()
|
|
45
|
+
ref.lookAt(vec3.addVectors(point, worldNormal))
|
|
34
46
|
},
|
|
35
47
|
{
|
|
36
48
|
autoStart: false
|
|
@@ -38,8 +50,8 @@
|
|
|
38
50
|
)
|
|
39
51
|
|
|
40
52
|
$effect.pre(() => {
|
|
41
|
-
if (hovering) {
|
|
42
|
-
ref.position.copy(intersection.current
|
|
53
|
+
if (hovering && intersection.current) {
|
|
54
|
+
ref.position.copy(intersection.current?.point)
|
|
43
55
|
start()
|
|
44
56
|
} else {
|
|
45
57
|
stop()
|
|
@@ -49,6 +61,7 @@
|
|
|
49
61
|
|
|
50
62
|
<T
|
|
51
63
|
is={ref}
|
|
64
|
+
attach={scene}
|
|
52
65
|
visible={hovering}
|
|
53
66
|
>
|
|
54
67
|
{#if children}
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
children?: Snippet
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const { handedness, children }: Props = $props()
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const hovering = $derived($teleportState[handedness].hovering)
|
|
14
|
+
const intersection = $derived(teleportIntersection[handedness])
|
|
15
|
+
const visible = $derived(
|
|
16
16
|
$pointerState[handedness].enabled || (hovering && $intersection === undefined)
|
|
17
17
|
)
|
|
18
18
|
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
<script
|
|
2
|
-
|
|
1
|
+
<script
|
|
2
|
+
module
|
|
3
|
+
lang="ts"
|
|
4
|
+
>
|
|
3
5
|
import { Group, Matrix3, Vector3 } from 'three'
|
|
4
|
-
|
|
6
|
+
|
|
7
|
+
const vec3 = new Vector3()
|
|
8
|
+
const normalMatrix = new Matrix3()
|
|
9
|
+
const worldNormal = new Vector3()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { Spring } from 'svelte/motion'
|
|
14
|
+
import { T, useTask, useThrelte } from '@threlte/core'
|
|
5
15
|
import { teleportIntersection } from '../../internal/stores'
|
|
6
16
|
import Cursor from './Cursor.svelte'
|
|
7
17
|
import type { Snippet } from 'svelte'
|
|
@@ -11,18 +21,17 @@
|
|
|
11
21
|
children?: Snippet
|
|
12
22
|
}
|
|
13
23
|
|
|
14
|
-
|
|
24
|
+
const { handedness, children }: Props = $props()
|
|
15
25
|
|
|
26
|
+
const { scene } = useThrelte()
|
|
16
27
|
const ref = new Group()
|
|
17
|
-
const
|
|
18
|
-
const normalMatrix = new Matrix3()
|
|
19
|
-
const worldNormal = new Vector3()
|
|
20
|
-
|
|
21
|
-
let intersection = $derived(teleportIntersection[handedness])
|
|
28
|
+
const intersection = $derived(teleportIntersection[handedness])
|
|
22
29
|
|
|
23
30
|
const { start, stop } = useTask(
|
|
24
31
|
() => {
|
|
25
|
-
if (intersection.current === undefined)
|
|
32
|
+
if (intersection.current === undefined) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
26
35
|
|
|
27
36
|
const { point, face, object } = intersection.current
|
|
28
37
|
ref.position.lerp(point, 0.4)
|
|
@@ -38,7 +47,7 @@
|
|
|
38
47
|
}
|
|
39
48
|
)
|
|
40
49
|
|
|
41
|
-
const size =
|
|
50
|
+
const size = new Spring(0.1, { stiffness: 0.2 })
|
|
42
51
|
|
|
43
52
|
$effect.pre(() => {
|
|
44
53
|
if ($intersection === undefined) {
|
|
@@ -54,13 +63,14 @@
|
|
|
54
63
|
|
|
55
64
|
<T
|
|
56
65
|
is={ref}
|
|
66
|
+
attach={scene}
|
|
57
67
|
visible={$intersection !== undefined}
|
|
58
68
|
>
|
|
59
69
|
{#if children}
|
|
60
70
|
{@render children()}
|
|
61
71
|
{:else}
|
|
62
72
|
<Cursor
|
|
63
|
-
size={
|
|
73
|
+
size={size.current}
|
|
64
74
|
thickness={0.015}
|
|
65
75
|
/>
|
|
66
76
|
{/if}
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script
|
|
2
|
+
module
|
|
3
|
+
lang="ts"
|
|
4
|
+
>
|
|
2
5
|
import { Vector3, QuadraticBezierCurve3, type XRTargetRaySpace, Vector2 } from 'three'
|
|
6
|
+
|
|
7
|
+
const rayStart = new Vector3()
|
|
8
|
+
const rayMidpoint = new Vector3()
|
|
9
|
+
const curve = new QuadraticBezierCurve3()
|
|
10
|
+
const vec3 = new Vector3()
|
|
11
|
+
const v2_1 = new Vector2()
|
|
12
|
+
const v2_2 = new Vector2()
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
import type { Snippet } from 'svelte'
|
|
3
17
|
import { Line2 } from 'three/examples/jsm/lines/Line2.js'
|
|
4
18
|
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
|
|
5
19
|
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
|
|
6
|
-
import { T, useTask } from '@threlte/core'
|
|
20
|
+
import { T, useTask, useThrelte } from '@threlte/core'
|
|
7
21
|
import { teleportIntersection } from '../../internal/stores'
|
|
8
|
-
import type { Snippet } from 'svelte'
|
|
9
22
|
|
|
10
23
|
interface Props {
|
|
11
24
|
handedness: 'left' | 'right'
|
|
@@ -13,21 +26,13 @@
|
|
|
13
26
|
children?: Snippet
|
|
14
27
|
}
|
|
15
28
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let lineGeometry = new LineGeometry()
|
|
29
|
+
const { handedness, targetRay, children }: Props = $props()
|
|
19
30
|
|
|
20
|
-
const
|
|
21
|
-
const rayMidpoint = new Vector3()
|
|
22
|
-
const curve = new QuadraticBezierCurve3()
|
|
31
|
+
const { scene } = useThrelte()
|
|
23
32
|
const rayDivisions = 40
|
|
24
33
|
const positions = new Float32Array(rayDivisions * 3)
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const v2_1 = new Vector2()
|
|
28
|
-
const v2_2 = new Vector2()
|
|
29
|
-
|
|
30
|
-
let intersection = $derived(teleportIntersection[handedness])
|
|
34
|
+
const lineGeometry = new LineGeometry()
|
|
35
|
+
const intersection = $derived(teleportIntersection[handedness])
|
|
31
36
|
|
|
32
37
|
const setCurvePoints = (alpha = 0.3) => {
|
|
33
38
|
if (intersection.current === undefined) return
|
|
@@ -83,6 +88,7 @@
|
|
|
83
88
|
{:else}
|
|
84
89
|
<T
|
|
85
90
|
is={Line2}
|
|
91
|
+
attach={scene}
|
|
86
92
|
visible={$intersection !== undefined}
|
|
87
93
|
position.z={-0.01}
|
|
88
94
|
>
|
|
@@ -96,6 +96,9 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
96
96
|
let stopped = false;
|
|
97
97
|
// loop through all hits and dispatch events
|
|
98
98
|
dispatchEvents: for (const hit of hits) {
|
|
99
|
+
const events = dispatchers.get(hit.eventObject);
|
|
100
|
+
if (events === undefined)
|
|
101
|
+
continue;
|
|
99
102
|
const intersectionEvent = {
|
|
100
103
|
stopped,
|
|
101
104
|
...hit,
|
|
@@ -115,9 +118,6 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
115
118
|
pointer: handContext.pointer.current,
|
|
116
119
|
ray: context.raycaster.ray
|
|
117
120
|
};
|
|
118
|
-
const events = dispatchers.get(hit.eventObject);
|
|
119
|
-
if (events === undefined)
|
|
120
|
-
return;
|
|
121
121
|
if (isPointerMove) {
|
|
122
122
|
// Move event ...
|
|
123
123
|
handContext.pointer.update((value) => value.copy(intersectionEvent.point));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threlte/xr",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"author": "Micheal Parks <michealparks1989@gmail.com> (https://parks.lol)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Tools to more easily create VR and AR experiences with Threlte",
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"typescript-eslint": "^8.32.0",
|
|
27
27
|
"vite": "^5.2.8",
|
|
28
28
|
"vite-plugin-mkcert": "^1.17.5",
|
|
29
|
-
"@threlte/core": "8.0.
|
|
29
|
+
"@threlte/core": "8.0.5"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"svelte": ">=5",
|
|
33
|
-
"three": ">=0.
|
|
33
|
+
"three": ">=0.160"
|
|
34
34
|
},
|
|
35
35
|
"type": "module",
|
|
36
36
|
"keywords": [
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { T, useThrelte } from '@threlte/core'
|
|
3
|
-
import { Object3D } from 'three'
|
|
4
|
-
|
|
5
|
-
const { scene } = useThrelte()
|
|
6
|
-
|
|
7
|
-
const proxy = new Object3D()
|
|
8
|
-
proxy.add = (child) => {
|
|
9
|
-
scene.add(child)
|
|
10
|
-
return child
|
|
11
|
-
}
|
|
12
|
-
proxy.remove = (child) => {
|
|
13
|
-
scene.remove(child)
|
|
14
|
-
return child
|
|
15
|
-
}
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
<T
|
|
19
|
-
is={proxy}
|
|
20
|
-
attach={false}
|
|
21
|
-
>
|
|
22
|
-
<slot />
|
|
23
|
-
</T>
|
|
@@ -1,20 +0,0 @@
|
|
|
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;
|
|
11
|
-
};
|
|
12
|
-
z_$$bindings?: Bindings;
|
|
13
|
-
}
|
|
14
|
-
declare const ScenePortal: $$__sveltets_2_IsomorphicComponent<any, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {
|
|
17
|
-
default: {};
|
|
18
|
-
}, {}, string>;
|
|
19
|
-
type ScenePortal = InstanceType<typeof ScenePortal>;
|
|
20
|
-
export default ScenePortal;
|