@threlte/xr 1.0.0-next.1 → 1.0.0-next.2
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/XR.svelte +1 -1
- package/dist/components/XR.svelte.d.ts +8 -8
- 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/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 +6 -12
- package/dist/plugins/pointerControls/setup.js +17 -17
- package/dist/plugins/teleportControls/context.d.ts +2 -2
- package/dist/plugins/teleportControls/hook.d.ts +1 -1
- package/dist/plugins/teleportControls/hook.js +2 -4
- package/dist/plugins/teleportControls/plugin.js +8 -8
- package/package.json +3 -3
- package/dist/plugins/pointerControls/useComponentEventHandlers.d.ts +0 -4
- package/dist/plugins/pointerControls/useComponentEventHandlers.js +0 -13
|
@@ -18,7 +18,7 @@ This should be placed within a Threlte `<Canvas />`.
|
|
|
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,
|
|
@@ -25,13 +25,13 @@ declare const __propDef: {
|
|
|
25
25
|
} & {
|
|
26
26
|
$$events: {
|
|
27
27
|
/** Called as an XRSession is requested */
|
|
28
|
-
sessionstart(
|
|
28
|
+
sessionstart: (event: XRSessionEvent<'sessionstart'>) => void;
|
|
29
29
|
/** Called after an XRSession is terminated */
|
|
30
|
-
sessionend(
|
|
30
|
+
sessionend: (event: XRSessionEvent<'sessionend'>) => void;
|
|
31
31
|
/** Called when an XRSession is hidden or unfocused. */
|
|
32
|
-
visibilitychange(
|
|
32
|
+
visibilitychange: (event: globalThis.XRSessionEvent) => void;
|
|
33
33
|
/** Called when available inputsources change */
|
|
34
|
-
inputsourceschange(
|
|
34
|
+
inputsourceschange: (event: globalThis.XRSessionEvent) => void;
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
37
|
slots: {
|
|
@@ -40,13 +40,13 @@ declare const __propDef: {
|
|
|
40
40
|
};
|
|
41
41
|
events: {
|
|
42
42
|
/** Called as an XRSession is requested */
|
|
43
|
-
sessionstart(
|
|
43
|
+
sessionstart: (event: XRSessionEvent<'sessionstart'>) => void;
|
|
44
44
|
/** Called after an XRSession is terminated */
|
|
45
|
-
sessionend(
|
|
45
|
+
sessionend: (event: XRSessionEvent<'sessionend'>) => void;
|
|
46
46
|
/** Called when an XRSession is hidden or unfocused. */
|
|
47
|
-
visibilitychange(
|
|
47
|
+
visibilitychange: (event: globalThis.XRSessionEvent) => void;
|
|
48
48
|
/** Called when available inputsources change */
|
|
49
|
-
inputsourceschange(
|
|
49
|
+
inputsourceschange: (event: globalThis.XRSessionEvent) => void;
|
|
50
50
|
};
|
|
51
51
|
};
|
|
52
52
|
export type XrProps = typeof __propDef.props;
|
|
@@ -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;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Object3D } from 'three';
|
|
2
|
+
import type { ControlsContext, HandContext } from './types';
|
|
3
|
+
export declare const getHandContext: (hand: 'left' | 'right') => HandContext;
|
|
4
|
+
export declare const setHandContext: (hand: 'left' | 'right', context: HandContext) => void;
|
|
5
|
+
export declare const getControlsContext: () => ControlsContext;
|
|
6
|
+
export declare const setControlsContext: (context: ControlsContext) => void;
|
|
7
|
+
interface InternalContext {
|
|
8
|
+
dispatchers: WeakMap<Object3D, Record<string, (arg: unknown) => void>>;
|
|
9
|
+
}
|
|
10
|
+
export declare const getInternalContext: () => InternalContext;
|
|
11
|
+
export declare const setInternalContext: () => void;
|
|
12
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Object3D } from 'three';
|
|
2
2
|
export declare const usePointerControls: () => {
|
|
3
|
-
addInteractiveObject: (object: Object3D) => void;
|
|
3
|
+
addInteractiveObject: (object: Object3D, events: Record<string, (arg: unknown) => void>) => void;
|
|
4
4
|
removeInteractiveObject: (object: Object3D) => void;
|
|
5
5
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { createRawEventDispatcher } from '@threlte/core';
|
|
2
1
|
import { getControlsContext, getInternalContext } from './context';
|
|
3
2
|
export const usePointerControls = () => {
|
|
4
|
-
const { dispatchers } = getInternalContext();
|
|
5
3
|
const context = getControlsContext();
|
|
6
|
-
const
|
|
7
|
-
|
|
4
|
+
const { dispatchers } = getInternalContext();
|
|
5
|
+
if (!context) {
|
|
6
|
+
throw new Error('No pointer controls context found. Did you forget to implement pointerControls()?');
|
|
7
|
+
}
|
|
8
|
+
const addInteractiveObject = (object, events) => {
|
|
8
9
|
// check if the object is already in the list
|
|
9
10
|
if (context.interactiveObjects.indexOf(object) > -1) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
|
-
dispatchers.set(object,
|
|
13
|
+
dispatchers.set(object, events);
|
|
13
14
|
context.interactiveObjects.push(object);
|
|
14
15
|
};
|
|
15
16
|
const removeInteractiveObject = (object) => {
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { injectPlugin, watch } from '@threlte/core';
|
|
2
2
|
import { writable } from 'svelte/store';
|
|
3
3
|
import { usePointerControls } from './hook';
|
|
4
|
-
import { useComponentHasEventHandlers } from './useComponentEventHandlers';
|
|
5
4
|
export const injectPointerControlsPlugin = () => {
|
|
6
|
-
injectPlugin('threlte-pointer-controls', ({ ref }) => {
|
|
7
|
-
if (ref.
|
|
5
|
+
injectPlugin('threlte-pointer-controls', ({ ref, props }) => {
|
|
6
|
+
if (!ref.isObject3D)
|
|
8
7
|
return;
|
|
9
8
|
const { addInteractiveObject, removeInteractiveObject } = usePointerControls();
|
|
10
9
|
const refStore = writable(ref);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// Because hasEventHandlers will only be set from false to true in the
|
|
14
|
-
// lifecycle of the component, we can safely assume that we do not need to
|
|
15
|
-
// remove the object from the list of interactive objects when
|
|
16
|
-
// hasEventHandlers is false.
|
|
17
|
-
if (!hasEventHandlers)
|
|
10
|
+
watch(refStore, ($refStore) => {
|
|
11
|
+
if (props.$$events === undefined)
|
|
18
12
|
return;
|
|
19
|
-
addInteractiveObject(
|
|
20
|
-
return () => removeInteractiveObject(
|
|
13
|
+
addInteractiveObject($refStore, props.$$events);
|
|
14
|
+
return () => removeInteractiveObject($refStore);
|
|
21
15
|
});
|
|
22
16
|
return {
|
|
23
17
|
onRefChange(ref) {
|
|
@@ -47,12 +47,12 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
47
47
|
hit.instanceId === hoveredObj.instanceId)) {
|
|
48
48
|
const { eventObject } = hoveredObj;
|
|
49
49
|
handContext.hovered.delete(getIntersectionId(hoveredObj));
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
50
|
+
const events = dispatchers.get(eventObject);
|
|
51
|
+
if (events !== undefined) {
|
|
52
52
|
// Clear out intersects, they are outdated by now
|
|
53
53
|
const data = { ...hoveredObj, intersections };
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
events.pointerout?.(data);
|
|
55
|
+
events.pointerleave?.(data);
|
|
56
56
|
// Deal with cancelation
|
|
57
57
|
handContext.pointerOverTarget.set(false);
|
|
58
58
|
cancelPointer([]);
|
|
@@ -80,7 +80,7 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
80
80
|
};
|
|
81
81
|
function pointerMissed(objects, event) {
|
|
82
82
|
for (const object of objects) {
|
|
83
|
-
dispatchers.get(object)?.(
|
|
83
|
+
dispatchers.get(object)?.pointermissed?.(event);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
function processHits() {
|
|
@@ -115,23 +115,23 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
115
115
|
pointer: handContext.pointer.current,
|
|
116
116
|
ray: context.raycaster.ray
|
|
117
117
|
};
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
118
|
+
const events = dispatchers.get(hit.eventObject);
|
|
119
|
+
if (events === undefined)
|
|
120
120
|
return;
|
|
121
121
|
if (isPointerMove) {
|
|
122
122
|
// Move event ...
|
|
123
123
|
handContext.pointer.update((value) => value.copy(intersectionEvent.point));
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
if (events.pointerover ||
|
|
125
|
+
events.pointerenter ||
|
|
126
|
+
events.pointerout ||
|
|
127
|
+
events.pointerleave) {
|
|
128
128
|
const id = getIntersectionId(intersectionEvent);
|
|
129
129
|
const hoveredItem = handContext.hovered.get(id);
|
|
130
130
|
if (hoveredItem === undefined) {
|
|
131
131
|
// If the object wasn't previously hovered, book it and call its handler
|
|
132
132
|
handContext.hovered.set(id, intersectionEvent);
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
events.pointerover?.(intersectionEvent);
|
|
134
|
+
events.pointerenter?.(intersectionEvent);
|
|
135
135
|
handContext.pointerOverTarget.set(true);
|
|
136
136
|
}
|
|
137
137
|
else if (hoveredItem.stopped) {
|
|
@@ -140,14 +140,14 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
// Call pointer move
|
|
143
|
-
|
|
143
|
+
events.pointermove?.(intersectionEvent);
|
|
144
144
|
}
|
|
145
145
|
else if ((!isClickEvent || handContext.initialHits.includes(hit.eventObject)) &&
|
|
146
|
-
|
|
146
|
+
events[name]) {
|
|
147
147
|
// Missed events have to come first
|
|
148
148
|
pointerMissed(context.interactiveObjects.filter((object) => !handContext.initialHits.includes(object)), event);
|
|
149
149
|
// Call the event
|
|
150
|
-
|
|
150
|
+
events[name]?.(intersectionEvent);
|
|
151
151
|
}
|
|
152
152
|
else if (isClickEvent && handContext.initialHits.includes(hit.eventObject)) {
|
|
153
153
|
pointerMissed(context.interactiveObjects.filter((object) => !handContext.initialHits.includes(object)), event);
|
|
@@ -167,7 +167,7 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
|
|
|
167
167
|
lastPosition.copy(targetRay.position);
|
|
168
168
|
}, {
|
|
169
169
|
fixedStep,
|
|
170
|
-
|
|
170
|
+
autoStart: false
|
|
171
171
|
});
|
|
172
172
|
watch(controller, (input) => {
|
|
173
173
|
if (input === undefined)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Mesh, Raycaster, Intersection } from 'three';
|
|
2
|
-
import type { CurrentWritable
|
|
2
|
+
import type { CurrentWritable } from '@threlte/core';
|
|
3
3
|
export type ComputeFunction = (context: Context, handContext: HandContext) => void;
|
|
4
4
|
export interface Context {
|
|
5
5
|
interactiveObjects: Mesh[];
|
|
6
6
|
surfaces: Map<string, Mesh>;
|
|
7
7
|
blockers: Map<string, Mesh>;
|
|
8
|
-
dispatchers: WeakMap<Mesh,
|
|
8
|
+
dispatchers: WeakMap<Mesh, Record<string, (arg: unknown) => void>>;
|
|
9
9
|
raycaster: Raycaster;
|
|
10
10
|
compute: ComputeFunction;
|
|
11
11
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Mesh } from 'three';
|
|
2
2
|
export declare const useTeleportControls: () => {
|
|
3
|
-
addSurface: (mesh: Mesh) => void;
|
|
3
|
+
addSurface: (mesh: Mesh, events: Record<string, (arg: unknown) => void>) => void;
|
|
4
4
|
removeSurface: (mesh: Mesh) => void;
|
|
5
5
|
addBlocker: (mesh: Mesh) => void;
|
|
6
6
|
removeBlocker: (mesh: Mesh) => void;
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { createRawEventDispatcher } from '@threlte/core';
|
|
2
1
|
import { getTeleportContext } from './context';
|
|
3
2
|
export const useTeleportControls = () => {
|
|
4
3
|
const context = getTeleportContext();
|
|
5
|
-
const
|
|
6
|
-
const addSurface = (mesh) => {
|
|
4
|
+
const addSurface = (mesh, events) => {
|
|
7
5
|
// check if the object is already in the list
|
|
8
6
|
if (context.interactiveObjects.indexOf(mesh) > -1) {
|
|
9
7
|
return;
|
|
10
8
|
}
|
|
11
9
|
context.interactiveObjects.push(mesh);
|
|
12
10
|
context.surfaces.set(mesh.uuid, mesh);
|
|
13
|
-
context.dispatchers.set(mesh,
|
|
11
|
+
context.dispatchers.set(mesh, events);
|
|
14
12
|
};
|
|
15
13
|
const removeSurface = (mesh) => {
|
|
16
14
|
const index = context.interactiveObjects.indexOf(mesh);
|
|
@@ -17,25 +17,25 @@ export const injectTeleportControlsPlugin = () => {
|
|
|
17
17
|
const { addBlocker, addSurface, removeBlocker, removeSurface } = useTeleportControls();
|
|
18
18
|
const refStore = writable(ref);
|
|
19
19
|
const propsStore = writable(props);
|
|
20
|
-
watch([refStore, propsStore], ([
|
|
20
|
+
watch([refStore, propsStore], ([$refStore, $propsStore]) => {
|
|
21
21
|
if (isSurface) {
|
|
22
|
-
if (
|
|
23
|
-
removeSurface(
|
|
22
|
+
if ($propsStore.teleportSurface === false) {
|
|
23
|
+
removeSurface($refStore);
|
|
24
24
|
return noop;
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
|
-
addSurface(
|
|
28
|
-
return () => removeSurface(
|
|
27
|
+
addSurface($refStore, props.$$events ?? {});
|
|
28
|
+
return () => removeSurface($refStore);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
else if (isBlocker) {
|
|
32
32
|
if (props.teleportBlocker === false) {
|
|
33
|
-
removeBlocker(
|
|
33
|
+
removeBlocker($refStore);
|
|
34
34
|
return noop;
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
addBlocker(
|
|
38
|
-
return () => removeBlocker(
|
|
37
|
+
addBlocker($refStore);
|
|
38
|
+
return () => removeBlocker($refStore);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threlte/xr",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.2",
|
|
4
4
|
"author": "Micheal Parks <michealparks1989@gmail.com> (https://parks.lol)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"devDependencies": {
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"autoprefixer": "^10.4.19",
|
|
19
19
|
"postcss": "^8.4.38",
|
|
20
20
|
"publint": "^0.2.7",
|
|
21
|
-
"svelte": "^5.0.0-next.
|
|
21
|
+
"svelte": "^5.0.0-next.107",
|
|
22
22
|
"three": "^0.163.0",
|
|
23
23
|
"tslib": "^2.6.2",
|
|
24
24
|
"vite": "^5.2.8",
|
|
25
25
|
"vite-plugin-mkcert": "^1.17.5",
|
|
26
|
-
"@threlte/core": "8.0.0-next.
|
|
26
|
+
"@threlte/core": "8.0.0-next.3"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"svelte": ">=5",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { onMount } from 'svelte';
|
|
2
|
-
import { writable } from 'svelte/store';
|
|
3
|
-
// import { events } from './types'
|
|
4
|
-
export const useComponentHasEventHandlers = () => {
|
|
5
|
-
const hasEventHandlers = writable(false);
|
|
6
|
-
onMount(() => {
|
|
7
|
-
// const match = Object.keys(component.$$.callbacks).some((callback) => events.includes(callback))
|
|
8
|
-
hasEventHandlers.set(true);
|
|
9
|
-
});
|
|
10
|
-
return {
|
|
11
|
-
hasEventHandlers
|
|
12
|
-
};
|
|
13
|
-
};
|