@viamrobotics/motion-tools 0.5.1 → 0.5.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/README.md +0 -25
- package/dist/color.js +4 -5
- package/dist/components/App.svelte +2 -2
- package/dist/components/Focus.svelte +2 -16
- package/dist/components/Frame.svelte +4 -2
- package/dist/components/Geometry.svelte +2 -1
- package/dist/components/KeyboardControls.svelte +102 -0
- package/dist/components/KeyboardControls.svelte.d.ts +7 -0
- package/dist/components/Scene.svelte +19 -4
- package/dist/components/SceneProviders.svelte +2 -0
- package/dist/components/StaticGeometries.svelte +13 -31
- package/dist/components/StaticGeometries.svelte.d.ts +2 -17
- package/dist/components/dashboard/Dashboard.svelte +0 -9
- package/dist/components/portal/PortalTarget.svelte +4 -4
- package/dist/components/xr/Controllers.svelte +38 -50
- package/dist/components/xr/Controllers.svelte.d.ts +17 -2
- package/dist/components/xr/Hands.svelte +1 -0
- package/dist/components/xr/OriginMarker.svelte +70 -30
- package/dist/components/xr/XR.svelte +13 -13
- package/dist/components/xr/XR.svelte.d.ts +2 -17
- package/dist/components/xr/useAnchors.svelte.d.ts +2 -0
- package/dist/components/xr/useAnchors.svelte.js +55 -0
- package/dist/components/xr/useOrigin.svelte.d.ts +9 -0
- package/dist/components/xr/useOrigin.svelte.js +27 -0
- package/dist/hooks/useObjectEvents.svelte.d.ts +1 -0
- package/dist/hooks/useObjectEvents.svelte.js +8 -1
- package/dist/hooks/useSettings.svelte.d.ts +2 -0
- package/dist/hooks/useSettings.svelte.js +3 -1
- package/dist/lib.d.ts +0 -2
- package/dist/lib.js +0 -2
- package/package.json +59 -58
- package/dist/components/CameraControls.svelte +0 -81
- package/dist/components/CameraControls.svelte.d.ts +0 -10
- package/dist/keybindings.d.ts +0 -12
- package/dist/keybindings.js +0 -12
package/README.md
CHANGED
|
@@ -9,31 +9,6 @@ To visit the visualizer, go to `http://localhost:5173/`
|
|
|
9
9
|
|
|
10
10
|
Open the machine config page (bottom right) and enter in connection details to visualize a specific machine.
|
|
11
11
|
|
|
12
|
-
## Todo
|
|
13
|
-
|
|
14
|
-
----- hard -----
|
|
15
|
-
|
|
16
|
-
- animated sequence of motion plan
|
|
17
|
-
- Give better fetching / connection state info
|
|
18
|
-
- configure frames in app
|
|
19
|
-
- embed in teleop
|
|
20
|
-
|
|
21
|
-
----- medium -----
|
|
22
|
-
|
|
23
|
-
- remote IP access when custom drawing, to draw on remote computers
|
|
24
|
-
- geometries need to be parented to parent
|
|
25
|
-
- color pallet for resource to color
|
|
26
|
-
- measurement tool
|
|
27
|
-
|
|
28
|
-
----- easy ------
|
|
29
|
-
|
|
30
|
-
- double click to set trackball center in object view
|
|
31
|
-
- Set default pointcloud color in settings
|
|
32
|
-
- points are not sized right in ortho cam view
|
|
33
|
-
- bounding boxes should include just the thing and not children
|
|
34
|
-
|
|
35
|
-
--- action items ----
|
|
36
|
-
|
|
37
12
|
## Env files
|
|
38
13
|
|
|
39
14
|
To add a list of connection configs in an `.env.local` file, use the following format:
|
package/dist/color.js
CHANGED
|
@@ -14,7 +14,7 @@ const toHex = (x) => {
|
|
|
14
14
|
const oklchToHex = (raw) => {
|
|
15
15
|
const match = raw.match(/oklch\(\s*([\d.]+)%\s+([\d.]+)\s+([\d.]+)\s*\)/);
|
|
16
16
|
if (!match) {
|
|
17
|
-
return
|
|
17
|
+
return raw;
|
|
18
18
|
}
|
|
19
19
|
const l = parseFloat(match[1]) / 100;
|
|
20
20
|
const c = parseFloat(match[2]);
|
|
@@ -46,11 +46,10 @@ const oklchToHex = (raw) => {
|
|
|
46
46
|
* @returns A new THREE.Color instance with the darkened color.
|
|
47
47
|
*/
|
|
48
48
|
export const darkenColor = (value, percent) => {
|
|
49
|
-
const
|
|
50
|
-
const hsl = { h: 0, s: 0, l: 0 };
|
|
51
|
-
color.getHSL(hsl);
|
|
49
|
+
const original = new Color(value);
|
|
50
|
+
const hsl = original.getHSL({ h: 0, s: 0, l: 0 });
|
|
52
51
|
hsl.l = Math.max(0, hsl.l * (1 - percent / 100));
|
|
53
|
-
return
|
|
52
|
+
return new Color().setHSL(hsl.h, hsl.s, hsl.l);
|
|
54
53
|
};
|
|
55
54
|
export const colors = {
|
|
56
55
|
selected: oklchToHex(twColors.red['900']),
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { T } from '@threlte/core'
|
|
3
3
|
import { TrackballControls, Gizmo } from '@threlte/extras'
|
|
4
|
-
import {
|
|
5
|
-
import { Keybindings } from '../keybindings'
|
|
4
|
+
import { useFocusedObject3d } from '../hooks/useSelection.svelte'
|
|
6
5
|
import { Box3, Vector3 } from 'three'
|
|
7
6
|
import Camera from './Camera.svelte'
|
|
8
7
|
|
|
9
|
-
const focus = useFocused()
|
|
10
8
|
const focusedObject = useFocusedObject3d()
|
|
11
9
|
const object3d = $derived(focusedObject.current)
|
|
12
10
|
|
|
@@ -21,20 +19,8 @@
|
|
|
21
19
|
center = box.getCenter(vec).toArray()
|
|
22
20
|
}
|
|
23
21
|
})
|
|
24
|
-
|
|
25
|
-
const onkeydown = ({ key }: KeyboardEvent) => {
|
|
26
|
-
if (key === Keybindings.ESCAPE) {
|
|
27
|
-
focus.set(undefined)
|
|
28
|
-
} else if (key === Keybindings.UP || key === Keybindings.DOWN) {
|
|
29
|
-
if (object3d && 'material' in object3d && isInstanceOf(object3d.material, 'PointsMaterial')) {
|
|
30
|
-
object3d.material.size += key === Keybindings.UP ? 0.001 : -0.001
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
22
|
</script>
|
|
35
23
|
|
|
36
|
-
<svelte:window {onkeydown} />
|
|
37
|
-
|
|
38
24
|
<Camera position={[2, 0, 0]}>
|
|
39
25
|
<TrackballControls target={center}>
|
|
40
26
|
<Gizmo />
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
|
|
6
6
|
import Geometry from './Geometry.svelte'
|
|
7
7
|
import { useSelected } from '../hooks/useSelection.svelte'
|
|
8
|
-
import { colors } from '../color'
|
|
8
|
+
import { colors, darkenColor } from '../color'
|
|
9
9
|
|
|
10
10
|
interface Props {
|
|
11
11
|
uuid: string
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
|
|
25
25
|
<Geometry
|
|
26
26
|
{uuid}
|
|
27
|
-
color={selected.current === uuid
|
|
27
|
+
color={selected.current === uuid
|
|
28
|
+
? `#${darkenColor(rest.metadata.color ?? colors.default, 75).getHexString()}`
|
|
29
|
+
: undefined}
|
|
28
30
|
{...events}
|
|
29
31
|
{...rest}
|
|
30
32
|
/>
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
{...rest}
|
|
65
65
|
>
|
|
66
66
|
{#if geometry?.case === 'mesh'}
|
|
67
|
-
{@const
|
|
67
|
+
{@const mesh = geometry.value.mesh as Uint8Array<ArrayBuffer>}
|
|
68
|
+
{@const meshGeometry = plyLoader.parse(typeof mesh === 'string' ? atob(mesh) : mesh.buffer)}
|
|
68
69
|
<T
|
|
69
70
|
is={meshGeometry}
|
|
70
71
|
{oncreate}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { MathUtils } from 'three'
|
|
3
|
+
import { useTask } from '@threlte/core'
|
|
4
|
+
import type { CameraControlsRef } from '@threlte/extras'
|
|
5
|
+
import { PressedKeys } from 'runed'
|
|
6
|
+
import { useFocused } from '../hooks/useSelection.svelte'
|
|
7
|
+
import { useSettings } from '../hooks/useSettings.svelte'
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
cameraControls: CameraControlsRef
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let { cameraControls }: Props = $props()
|
|
14
|
+
|
|
15
|
+
const focus = useFocused()
|
|
16
|
+
const settings = useSettings()
|
|
17
|
+
|
|
18
|
+
const keys = new PressedKeys()
|
|
19
|
+
const w = $derived(keys.has('w'))
|
|
20
|
+
const s = $derived(keys.has('s'))
|
|
21
|
+
const a = $derived(keys.has('a'))
|
|
22
|
+
const d = $derived(keys.has('d'))
|
|
23
|
+
const up = $derived(keys.has('arrowup'))
|
|
24
|
+
const left = $derived(keys.has('arrowleft'))
|
|
25
|
+
const down = $derived(keys.has('arrowdown'))
|
|
26
|
+
const right = $derived(keys.has('arrowright'))
|
|
27
|
+
const any = $derived(w || s || a || d || up || left || down || right)
|
|
28
|
+
|
|
29
|
+
const { start, stop } = useTask(
|
|
30
|
+
(delta) => {
|
|
31
|
+
const dt = delta * 1000
|
|
32
|
+
|
|
33
|
+
if (a) {
|
|
34
|
+
cameraControls.truck(-0.01 * dt, 0, true)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (d) {
|
|
38
|
+
cameraControls.truck(0.01 * dt, 0, true)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (w) {
|
|
42
|
+
cameraControls.forward(0.01 * dt, true)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (s) {
|
|
46
|
+
cameraControls.forward(-0.01 * dt, true)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (left) {
|
|
50
|
+
cameraControls.rotate(-0.1 * MathUtils.DEG2RAD * dt, 0, true)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (right) {
|
|
54
|
+
cameraControls.rotate(0.1 * MathUtils.DEG2RAD * dt, 0, true)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (up) {
|
|
58
|
+
cameraControls.rotate(0, -0.05 * MathUtils.DEG2RAD * dt, true)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (down) {
|
|
62
|
+
cameraControls.rotate(0, 0.05 * MathUtils.DEG2RAD * dt, true)
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{ autoStart: false, autoInvalidate: false }
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
$effect.pre(() => {
|
|
69
|
+
if (any) {
|
|
70
|
+
start()
|
|
71
|
+
} else {
|
|
72
|
+
stop()
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
keys.onKeys('escape', () => {
|
|
77
|
+
if (keys.has('escape')) {
|
|
78
|
+
focus.set(undefined)
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
keys.onKeys('c', () => {
|
|
83
|
+
settings.current.cameraMode =
|
|
84
|
+
settings.current.cameraMode === 'perspective' ? 'orthographic' : 'perspective'
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
keys.onKeys('1', () => {
|
|
88
|
+
settings.current.transformMode = 'translate'
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
keys.onKeys('2', () => {
|
|
92
|
+
settings.current.transformMode = 'rotate'
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
keys.onKeys('3', () => {
|
|
96
|
+
settings.current.transformMode = 'scale'
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
keys.onKeys(['ctrl', 'x'], () => {
|
|
100
|
+
settings.current.enableXR = !settings.current.enableXR
|
|
101
|
+
})
|
|
102
|
+
</script>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CameraControlsRef } from '@threlte/extras';
|
|
2
|
+
interface Props {
|
|
3
|
+
cameraControls: CameraControlsRef;
|
|
4
|
+
}
|
|
5
|
+
declare const KeyboardControls: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type KeyboardControls = ReturnType<typeof KeyboardControls>;
|
|
7
|
+
export default KeyboardControls;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Color, Vector3 } from 'three'
|
|
3
3
|
import { T } from '@threlte/core'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
CameraControls,
|
|
6
|
+
type CameraControlsRef,
|
|
7
|
+
Gizmo,
|
|
8
|
+
Grid,
|
|
9
|
+
interactivity,
|
|
10
|
+
} from '@threlte/extras'
|
|
5
11
|
import { PortalTarget } from './portal'
|
|
6
12
|
import Frames from './Frames.svelte'
|
|
7
13
|
import Pointclouds from './Pointclouds.svelte'
|
|
8
|
-
import CameraControls from './CameraControls.svelte'
|
|
9
14
|
import Selected from './Selected.svelte'
|
|
10
15
|
import Focus from './Focus.svelte'
|
|
11
16
|
import StaticGeometries from './StaticGeometries.svelte'
|
|
@@ -15,6 +20,8 @@
|
|
|
15
20
|
import type { Snippet } from 'svelte'
|
|
16
21
|
import { useXR } from '@threlte/xr'
|
|
17
22
|
import { useTransformControls } from '../hooks/useControls.svelte'
|
|
23
|
+
import KeyboardControls from './KeyboardControls.svelte'
|
|
24
|
+
import { useOrigin } from './xr/useOrigin.svelte'
|
|
18
25
|
|
|
19
26
|
interface Props {
|
|
20
27
|
children?: Snippet
|
|
@@ -34,6 +41,7 @@
|
|
|
34
41
|
|
|
35
42
|
const focused = useFocused()
|
|
36
43
|
const transformControls = useTransformControls()
|
|
44
|
+
const origin = useOrigin()
|
|
37
45
|
|
|
38
46
|
const { isPresenting } = useXR()
|
|
39
47
|
</script>
|
|
@@ -43,12 +51,19 @@
|
|
|
43
51
|
args={[new Color('white')]}
|
|
44
52
|
/>
|
|
45
53
|
|
|
46
|
-
<T.Group
|
|
54
|
+
<T.Group
|
|
55
|
+
position={origin.position}
|
|
56
|
+
rotation.x={$isPresenting ? -Math.PI / 2 : 0}
|
|
57
|
+
rotation.z={origin.rotation}
|
|
58
|
+
>
|
|
47
59
|
{#if focused.current === undefined}
|
|
48
60
|
{#if !$isPresenting}
|
|
49
61
|
<Camera position={[3, 3, 3]}>
|
|
50
62
|
<CameraControls enabled={!transformControls.active}>
|
|
51
|
-
|
|
63
|
+
{#snippet children({ ref }: { ref: CameraControlsRef })}
|
|
64
|
+
<KeyboardControls cameraControls={ref} />
|
|
65
|
+
<Gizmo />
|
|
66
|
+
{/snippet}
|
|
52
67
|
</CameraControls>
|
|
53
68
|
</Camera>
|
|
54
69
|
{/if}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { provideMotionClient } from '../hooks/useMotionClient.svelte'
|
|
15
15
|
import { provideLogs } from '../hooks/useLogs.svelte'
|
|
16
16
|
import { provideSettings } from '../hooks/useSettings.svelte'
|
|
17
|
+
import { provideOrigin } from './xr/useOrigin.svelte'
|
|
17
18
|
|
|
18
19
|
interface Props {
|
|
19
20
|
children: Snippet<[{ focus: boolean }]>
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
provideRefreshRates()
|
|
30
31
|
provideLogs()
|
|
31
32
|
|
|
33
|
+
provideOrigin()
|
|
32
34
|
provideStaticGeometries()
|
|
33
35
|
provideShapes()
|
|
34
36
|
|
|
@@ -3,45 +3,27 @@
|
|
|
3
3
|
import { useSelected } from '../hooks/useSelection.svelte'
|
|
4
4
|
import { useStaticGeometries } from '../hooks/useStaticGeometries.svelte'
|
|
5
5
|
import { useTransformControls } from '../hooks/useControls.svelte'
|
|
6
|
-
import {
|
|
7
|
-
import { PersistedState } from 'runed'
|
|
6
|
+
import { PressedKeys } from 'runed'
|
|
8
7
|
import { quaternionToPose, scaleToDimensions, vector3ToPose } from '../transform'
|
|
9
8
|
import { Quaternion, Vector3 } from 'three'
|
|
10
9
|
import Frame from './Frame.svelte'
|
|
10
|
+
import { useSettings } from '../hooks/useSettings.svelte'
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const settings = useSettings()
|
|
14
13
|
const transformControls = useTransformControls()
|
|
15
14
|
const geometries = useStaticGeometries()
|
|
16
15
|
const selected = useSelected()
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
const mode = $derived(settings.current.transformMode)
|
|
19
18
|
|
|
20
19
|
const quaternion = new Quaternion()
|
|
21
20
|
const vector3 = new Vector3()
|
|
22
|
-
</script>
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
onkeydown={(event) => {
|
|
26
|
-
if (event.metaKey || event.ctrlKey) {
|
|
27
|
-
return
|
|
28
|
-
}
|
|
22
|
+
const keys = new PressedKeys()
|
|
29
23
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
geometries.add()
|
|
34
|
-
} else if (key === Keybindings.REMOVE_GEOMETRY) {
|
|
35
|
-
geometries.remove(selected.current ?? '')
|
|
36
|
-
} else if (key === Keybindings.TRANSLATE) {
|
|
37
|
-
mode.current = 'translate'
|
|
38
|
-
} else if (key === Keybindings.ROTATE) {
|
|
39
|
-
mode.current = 'rotate'
|
|
40
|
-
} else if (key === Keybindings.SCALE) {
|
|
41
|
-
mode.current = 'scale'
|
|
42
|
-
}
|
|
43
|
-
}}
|
|
44
|
-
/>
|
|
24
|
+
keys.onKeys('=', () => geometries.add())
|
|
25
|
+
keys.onKeys('-', () => geometries.remove(selected.current ?? ''))
|
|
26
|
+
</script>
|
|
45
27
|
|
|
46
28
|
{#each geometries.current as object (object.uuid)}
|
|
47
29
|
<Frame
|
|
@@ -53,20 +35,20 @@
|
|
|
53
35
|
>
|
|
54
36
|
{#snippet children({ ref })}
|
|
55
37
|
{#if selected.current === ref.uuid}
|
|
56
|
-
{#key mode
|
|
38
|
+
{#key mode}
|
|
57
39
|
<TransformControls
|
|
58
40
|
object={ref}
|
|
59
|
-
|
|
41
|
+
{mode}
|
|
60
42
|
onmouseDown={() => transformControls.setActive(true)}
|
|
61
43
|
onmouseUp={() => {
|
|
62
44
|
transformControls.setActive(false)
|
|
63
45
|
|
|
64
|
-
if (mode
|
|
46
|
+
if (mode === 'translate') {
|
|
65
47
|
vector3ToPose(ref.getWorldPosition(vector3), object.pose)
|
|
66
|
-
} else if (mode
|
|
48
|
+
} else if (mode === 'rotate') {
|
|
67
49
|
quaternionToPose(ref.getWorldQuaternion(quaternion), object.pose)
|
|
68
50
|
ref.quaternion.copy(quaternion)
|
|
69
|
-
} else if (mode
|
|
51
|
+
} else if (mode === 'scale' && object.geometry?.case === 'box') {
|
|
70
52
|
scaleToDimensions(ref.scale, object.geometry)
|
|
71
53
|
ref.scale.setScalar(1)
|
|
72
54
|
}
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 StaticGeometries: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {}, {}, string>;
|
|
17
|
-
type StaticGeometries = InstanceType<typeof StaticGeometries>;
|
|
1
|
+
declare const StaticGeometries: import("svelte").Component<Record<string, never>, {}, "">;
|
|
2
|
+
type StaticGeometries = ReturnType<typeof StaticGeometries>;
|
|
18
3
|
export default StaticGeometries;
|
|
@@ -5,15 +5,6 @@
|
|
|
5
5
|
const settings = useSettings()
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
|
-
<svelte:window
|
|
9
|
-
onkeydown={({ key }) => {
|
|
10
|
-
if (key.toLowerCase() === 'c') {
|
|
11
|
-
settings.current.cameraMode =
|
|
12
|
-
settings.current.cameraMode === 'perspective' ? 'orthographic' : 'perspective'
|
|
13
|
-
}
|
|
14
|
-
}}
|
|
15
|
-
/>
|
|
16
|
-
|
|
17
8
|
<div class="absolute top-2 flex w-full justify-center">
|
|
18
9
|
<!-- transform -->
|
|
19
10
|
<!-- <fieldset>
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
let { id = 'default' }: Props = $props()
|
|
9
9
|
|
|
10
10
|
const portals = usePortalContext()
|
|
11
|
-
const
|
|
11
|
+
const childrenArray = $derived(portals.get(id))
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
|
-
{#if
|
|
15
|
-
{#each
|
|
16
|
-
{@render children
|
|
14
|
+
{#if childrenArray !== undefined}
|
|
15
|
+
{#each childrenArray as children (children)}
|
|
16
|
+
{@render children()}
|
|
17
17
|
{/each}
|
|
18
18
|
{/if}
|
|
@@ -1,56 +1,48 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Controller } from '@threlte/xr'
|
|
3
|
-
import { useGamepad } from '@threlte/extras'
|
|
3
|
+
// import { useGamepad } from '@threlte/extras'
|
|
4
4
|
|
|
5
|
-
import { BaseClient } from '@viamrobotics/sdk'
|
|
5
|
+
// import { BaseClient } from '@viamrobotics/sdk'
|
|
6
6
|
|
|
7
7
|
import { RigidBody } from '@threlte/rapier'
|
|
8
8
|
import HandCollider from './HandCollider.svelte'
|
|
9
|
-
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
10
|
-
import { useResourceNames, useRobotClient } from '@viamrobotics/svelte-sdk'
|
|
11
|
-
|
|
12
|
-
const gamepadLeft = useGamepad({ xr: true, hand: 'left' })
|
|
13
|
-
|
|
14
|
-
const partID = usePartID()
|
|
15
|
-
const resources = useResourceNames(() => partID.current)
|
|
16
|
-
const robotClient = useRobotClient(() => partID.current)
|
|
17
|
-
const resource = $derived(resources.current.find((r) => r.subtype === 'base'))
|
|
18
|
-
const baseClient = $derived(
|
|
19
|
-
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
const linear = { x: 0, y: 0, z: 0 }
|
|
23
|
-
const angular = { x: 0, y: 0, z: 0 }
|
|
24
|
-
|
|
25
|
-
gamepadLeft.squeeze.on('change', (event) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
gamepadLeft.trigger.on('change', (event) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
gamepadLeft.thumbstick.on('change', (event) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
const onselectstart = () => {}
|
|
45
|
-
|
|
46
|
-
const onselectend = () => {}
|
|
9
|
+
// import { usePartID } from '../../hooks/usePartID.svelte'
|
|
10
|
+
// import { useResourceNames, useRobotClient } from '@viamrobotics/svelte-sdk'
|
|
11
|
+
|
|
12
|
+
// const gamepadLeft = useGamepad({ xr: true, hand: 'left' })
|
|
13
|
+
|
|
14
|
+
// const partID = usePartID()
|
|
15
|
+
// const resources = useResourceNames(() => partID.current)
|
|
16
|
+
// const robotClient = useRobotClient(() => partID.current)
|
|
17
|
+
// const resource = $derived(resources.current.find((r) => r.subtype === 'base'))
|
|
18
|
+
// const baseClient = $derived(
|
|
19
|
+
// robotClient.current && resource ? new BaseClient(robotClient.current, resource.name) : undefined
|
|
20
|
+
// )
|
|
21
|
+
|
|
22
|
+
// const linear = { x: 0, y: 0, z: 0 }
|
|
23
|
+
// const angular = { x: 0, y: 0, z: 0 }
|
|
24
|
+
|
|
25
|
+
// gamepadLeft.squeeze.on('change', (event) => {
|
|
26
|
+
// linear.y = -event.value
|
|
27
|
+
// baseClient?.setPower(linear, angular)
|
|
28
|
+
// })
|
|
29
|
+
|
|
30
|
+
// gamepadLeft.trigger.on('change', (event) => {
|
|
31
|
+
// if (typeof event.value === 'number') {
|
|
32
|
+
// linear.y = event.value
|
|
33
|
+
// baseClient?.setPower(linear, angular)
|
|
34
|
+
// }
|
|
35
|
+
// })
|
|
36
|
+
|
|
37
|
+
// gamepadLeft.thumbstick.on('change', (event) => {
|
|
38
|
+
// if (typeof event.value === 'object') {
|
|
39
|
+
// angular.z = event.value.x
|
|
40
|
+
// baseClient?.setPower(linear, angular)
|
|
41
|
+
// }
|
|
42
|
+
// })
|
|
47
43
|
</script>
|
|
48
44
|
|
|
49
|
-
<Controller
|
|
50
|
-
left
|
|
51
|
-
{onselectstart}
|
|
52
|
-
{onselectend}
|
|
53
|
-
>
|
|
45
|
+
<Controller left>
|
|
54
46
|
{#snippet grip()}
|
|
55
47
|
<RigidBody type="kinematicPosition">
|
|
56
48
|
<HandCollider />
|
|
@@ -58,11 +50,7 @@
|
|
|
58
50
|
{/snippet}
|
|
59
51
|
</Controller>
|
|
60
52
|
|
|
61
|
-
<Controller
|
|
62
|
-
right
|
|
63
|
-
{onselectstart}
|
|
64
|
-
{onselectend}
|
|
65
|
-
>
|
|
53
|
+
<Controller right>
|
|
66
54
|
{#snippet grip()}
|
|
67
55
|
<RigidBody type="kinematicPosition">
|
|
68
56
|
<HandCollider />
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 Controllers: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type Controllers = InstanceType<typeof Controllers>;
|
|
3
18
|
export default Controllers;
|
|
@@ -4,62 +4,112 @@
|
|
|
4
4
|
import { Collider, RigidBody } from '@threlte/rapier'
|
|
5
5
|
import { RigidBody as RigidBodyType } from '@dimforge/rapier3d-compat'
|
|
6
6
|
import { useController } from '@threlte/xr'
|
|
7
|
-
import {
|
|
7
|
+
import { Euler, Group, Quaternion, Vector3 } from 'three'
|
|
8
|
+
import { useOrigin } from './useOrigin.svelte'
|
|
9
|
+
|
|
10
|
+
const origin = useOrigin()
|
|
8
11
|
|
|
9
12
|
const height = 0.1
|
|
10
13
|
const radius = 0.05
|
|
11
14
|
|
|
12
15
|
const group = new Group()
|
|
13
|
-
const
|
|
16
|
+
const innerGroup = new Group()
|
|
14
17
|
|
|
15
18
|
const vec3 = new Vector3()
|
|
19
|
+
|
|
16
20
|
const quaternion = new Quaternion()
|
|
21
|
+
const euler = new Euler()
|
|
17
22
|
|
|
18
23
|
const offset = new Vector3()
|
|
24
|
+
|
|
19
25
|
const position = new Vector3()
|
|
20
26
|
|
|
21
|
-
let hovering = $state(false)
|
|
22
27
|
let dragging = $state(false)
|
|
23
28
|
let rotating = $state(false)
|
|
24
29
|
|
|
25
|
-
let
|
|
30
|
+
let currentDistance = 0
|
|
31
|
+
const rotateDown = new Vector3()
|
|
32
|
+
|
|
33
|
+
let rigidBody = $state<RigidBodyType>()
|
|
26
34
|
|
|
27
35
|
const left = useController('left')
|
|
36
|
+
const right = useController('right')
|
|
37
|
+
|
|
28
38
|
const leftPad = useGamepad({ xr: true, hand: 'left' })
|
|
39
|
+
const rightPad = useGamepad({ xr: true, hand: 'right' })
|
|
29
40
|
|
|
30
41
|
leftPad.trigger.on('down', () => {
|
|
42
|
+
const grip = $left?.grip
|
|
43
|
+
|
|
44
|
+
if (!grip) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
dragging = true
|
|
32
|
-
|
|
49
|
+
innerGroup.getWorldPosition(vec3)
|
|
33
50
|
offset.copy($left!.grip.position).sub(vec3)
|
|
34
51
|
})
|
|
35
52
|
leftPad.trigger.on('up', () => (dragging = false))
|
|
36
53
|
|
|
37
|
-
|
|
54
|
+
rightPad.trigger.on('down', () => {
|
|
55
|
+
const grip = $right?.grip
|
|
56
|
+
|
|
57
|
+
if (!grip) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
rotating = true
|
|
39
|
-
|
|
62
|
+
rotateDown.copy($right?.grip.position)
|
|
63
|
+
currentDistance = euler.z
|
|
40
64
|
})
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const onsensorenter = () => (hovering = true)
|
|
44
|
-
const onsensorexit = () => (hovering = false)
|
|
65
|
+
rightPad.trigger.on('up', () => (rotating = false))
|
|
45
66
|
|
|
46
|
-
const
|
|
67
|
+
const dragTask = useTask(
|
|
47
68
|
() => {
|
|
48
69
|
if (!$left || !rigidBody) return
|
|
49
70
|
|
|
50
71
|
position.copy($left.grip.position).sub(offset)
|
|
51
72
|
|
|
73
|
+
origin.set(position)
|
|
74
|
+
|
|
52
75
|
rigidBody.setNextKinematicTranslation({ x: position.x, y: position.y, z: position.z })
|
|
53
76
|
},
|
|
54
77
|
{ autoStart: false }
|
|
55
78
|
)
|
|
56
79
|
|
|
57
|
-
|
|
58
|
-
|
|
80
|
+
const rotateTask = useTask(
|
|
81
|
+
() => {
|
|
82
|
+
if (!$right || !rigidBody) return
|
|
59
83
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
84
|
+
const distance = rotateDown.distanceToSquared($right.grip.position)
|
|
85
|
+
|
|
86
|
+
const rotation = rigidBody.rotation()
|
|
87
|
+
quaternion.copy(rotation)
|
|
88
|
+
euler.setFromQuaternion(quaternion)
|
|
89
|
+
euler.z = distance + currentDistance
|
|
90
|
+
origin.set(undefined, euler.z)
|
|
91
|
+
|
|
92
|
+
rigidBody.setNextKinematicRotation(quaternion.setFromEuler(euler))
|
|
93
|
+
},
|
|
94
|
+
{ autoStart: false }
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
$effect.pre(() => {
|
|
98
|
+
if (dragging) {
|
|
99
|
+
dragTask.start()
|
|
100
|
+
} else {
|
|
101
|
+
dragTask.stop()
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
$effect.pre(() => {
|
|
106
|
+
if (rotating) {
|
|
107
|
+
rotateTask.start()
|
|
108
|
+
} else {
|
|
109
|
+
rotateTask.stop()
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
</script>
|
|
63
113
|
|
|
64
114
|
<T
|
|
65
115
|
is={group}
|
|
@@ -73,23 +123,13 @@
|
|
|
73
123
|
sensor
|
|
74
124
|
shape="cone"
|
|
75
125
|
args={[height / 2, radius]}
|
|
76
|
-
{onsensorenter}
|
|
77
|
-
{onsensorexit}
|
|
78
126
|
>
|
|
79
|
-
<T is={
|
|
80
|
-
<T.ConeGeometry
|
|
81
|
-
args={[radius, height]}
|
|
82
|
-
oncreate={(ref) => {
|
|
83
|
-
ref.rotateX(-Math.PI / 2)
|
|
84
|
-
ref.translate(0, 0, height / 2)
|
|
85
|
-
}}
|
|
86
|
-
/>
|
|
87
|
-
<T.MeshStandardMaterial color={hovering ? 'hotpink' : 'red'} />
|
|
88
|
-
|
|
127
|
+
<T is={innerGroup}>
|
|
89
128
|
<Grid
|
|
90
129
|
plane="xy"
|
|
91
130
|
position.y={0.05}
|
|
92
|
-
fadeDistance={
|
|
131
|
+
fadeDistance={5}
|
|
132
|
+
fadeOrigin={new Vector3()}
|
|
93
133
|
cellSize={0.1}
|
|
94
134
|
cellColor="#fff"
|
|
95
135
|
sectionColor="#fff"
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { XR, XRButton } from '@threlte/xr'
|
|
2
|
+
import { T } from '@threlte/core'
|
|
3
|
+
import { useXR, XR, XRButton } from '@threlte/xr'
|
|
4
4
|
import OriginMarker from './OriginMarker.svelte'
|
|
5
5
|
import DomPortal from '../DomPortal.svelte'
|
|
6
|
+
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
7
|
+
import Controllers from './Controllers.svelte'
|
|
6
8
|
|
|
7
|
-
const
|
|
9
|
+
const { isPresenting } = useXR()
|
|
10
|
+
const settings = useSettings()
|
|
11
|
+
const enableXR = $derived(settings.current.enableXR)
|
|
8
12
|
</script>
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
onkeydown={(event) => {
|
|
12
|
-
if (event.ctrlKey && event.key.toLowerCase() === 'a') {
|
|
13
|
-
enableXR.current = !enableXR.current
|
|
14
|
-
}
|
|
15
|
-
}}
|
|
16
|
-
/>
|
|
17
|
-
|
|
18
|
-
{#if enableXR.current}
|
|
14
|
+
{#if enableXR}
|
|
19
15
|
<XR>
|
|
20
|
-
<
|
|
16
|
+
<T.Group rotation.x={$isPresenting ? -Math.PI / 2 : 0}>
|
|
17
|
+
<OriginMarker />
|
|
18
|
+
</T.Group>
|
|
19
|
+
|
|
20
|
+
<Controllers />
|
|
21
21
|
</XR>
|
|
22
22
|
|
|
23
23
|
<DomPortal>
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 Xr: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {}, {}, string>;
|
|
17
|
-
type Xr = InstanceType<typeof Xr>;
|
|
1
|
+
declare const Xr: import("svelte").Component<Record<string, never>, {}, "">;
|
|
2
|
+
type Xr = ReturnType<typeof Xr>;
|
|
18
3
|
export default Xr;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useTask, useThrelte, watch } from '@threlte/core';
|
|
2
|
+
import { useXR } from '@threlte/xr';
|
|
3
|
+
import { getContext, setContext } from 'svelte';
|
|
4
|
+
import { Matrix4 } from 'three';
|
|
5
|
+
const key = Symbol('anchors-context');
|
|
6
|
+
export const provideAnchors = () => {
|
|
7
|
+
const matrix4 = new Matrix4();
|
|
8
|
+
const { renderer } = useThrelte();
|
|
9
|
+
const { xrFrame, isPresenting } = useXR();
|
|
10
|
+
const map = new WeakMap();
|
|
11
|
+
let space = renderer.xr.getReferenceSpace();
|
|
12
|
+
const createAnchor = (position, orientation) => {
|
|
13
|
+
space ??= renderer.xr.getReferenceSpace();
|
|
14
|
+
if (space === null)
|
|
15
|
+
return;
|
|
16
|
+
const pose = new XRRigidTransform(position, orientation);
|
|
17
|
+
return xrFrame.current.createAnchor?.(pose, space);
|
|
18
|
+
};
|
|
19
|
+
const { start, stop } = useTask(() => {
|
|
20
|
+
space ??= renderer.xr.getReferenceSpace();
|
|
21
|
+
if (!space) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const frame = xrFrame.current;
|
|
25
|
+
if (!frame.trackedAnchors) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
for (const anchor of frame.trackedAnchors) {
|
|
29
|
+
const object3d = map.get(anchor);
|
|
30
|
+
if (!object3d) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const anchorPose = frame.getPose(anchor.anchorSpace, space);
|
|
34
|
+
if (!anchorPose) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
matrix4.fromArray(anchorPose.transform.matrix);
|
|
38
|
+
object3d.applyMatrix4(matrix4);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
watch(isPresenting, ($isPresenting) => {
|
|
42
|
+
if ($isPresenting) {
|
|
43
|
+
start();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
stop();
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
setContext(key, {
|
|
50
|
+
createAnchor,
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
export const useAnchors = () => {
|
|
54
|
+
getContext(key);
|
|
55
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Vector3, Vector3Tuple } from 'three';
|
|
2
|
+
interface Context {
|
|
3
|
+
position: Vector3Tuple;
|
|
4
|
+
rotation: number;
|
|
5
|
+
set: (pos?: Vector3, rot?: number) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const provideOrigin: () => void;
|
|
8
|
+
export declare const useOrigin: () => Context;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
const key = Symbol('origin-context');
|
|
3
|
+
export const provideOrigin = () => {
|
|
4
|
+
const position = $state([0, 0, 0]);
|
|
5
|
+
let rotation = $state(0);
|
|
6
|
+
setContext(key, {
|
|
7
|
+
get position() {
|
|
8
|
+
return position;
|
|
9
|
+
},
|
|
10
|
+
get rotation() {
|
|
11
|
+
return rotation;
|
|
12
|
+
},
|
|
13
|
+
set(pos, rot) {
|
|
14
|
+
if (pos) {
|
|
15
|
+
position[0] = pos.x;
|
|
16
|
+
position[1] = pos.y;
|
|
17
|
+
position[2] = pos.z;
|
|
18
|
+
}
|
|
19
|
+
if (rot) {
|
|
20
|
+
rotation = rot;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
export const useOrigin = () => {
|
|
26
|
+
return getContext(key);
|
|
27
|
+
};
|
|
@@ -4,6 +4,7 @@ export declare const useObjectEvents: (uuid: () => string) => {
|
|
|
4
4
|
onpointerenter: (event: IntersectionEvent<MouseEvent>) => void;
|
|
5
5
|
onpointerleave: (event: IntersectionEvent<MouseEvent>) => void;
|
|
6
6
|
ondblclick: (event: IntersectionEvent<MouseEvent>) => void;
|
|
7
|
+
onpointerdown: (event: IntersectionEvent<MouseEvent>) => void;
|
|
7
8
|
onclick: (event: IntersectionEvent<MouseEvent>) => void;
|
|
8
9
|
onpointermissed: () => void;
|
|
9
10
|
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { useCursor } from '@threlte/extras';
|
|
2
2
|
import { useFocused, useSelected } from './useSelection.svelte';
|
|
3
3
|
import { useVisibility } from './useVisibility.svelte';
|
|
4
|
+
import { Vector2 } from 'three';
|
|
4
5
|
export const useObjectEvents = (uuid) => {
|
|
5
6
|
const { onPointerEnter, onPointerLeave } = useCursor();
|
|
6
7
|
const selected = useSelected();
|
|
7
8
|
const focused = useFocused();
|
|
8
9
|
const visibility = useVisibility();
|
|
10
|
+
const down = new Vector2();
|
|
9
11
|
return {
|
|
10
12
|
get visible() {
|
|
11
13
|
return visibility.get(uuid());
|
|
@@ -22,9 +24,14 @@ export const useObjectEvents = (uuid) => {
|
|
|
22
24
|
event.stopPropagation();
|
|
23
25
|
focused.set(uuid());
|
|
24
26
|
},
|
|
27
|
+
onpointerdown: (event) => {
|
|
28
|
+
down.copy(event.pointer);
|
|
29
|
+
},
|
|
25
30
|
onclick: (event) => {
|
|
26
31
|
event.stopPropagation();
|
|
27
|
-
|
|
32
|
+
if (down.distanceToSquared(event.pointer) < 0.1) {
|
|
33
|
+
selected.set(uuid());
|
|
34
|
+
}
|
|
28
35
|
},
|
|
29
36
|
onpointermissed: () => selected.set(),
|
|
30
37
|
};
|
|
@@ -3,12 +3,14 @@ import { getContext, setContext } from 'svelte';
|
|
|
3
3
|
const key = Symbol('dashboard-context');
|
|
4
4
|
const defaults = () => ({
|
|
5
5
|
cameraMode: 'perspective',
|
|
6
|
+
transformMode: 'translate',
|
|
7
|
+
enableXR: false,
|
|
6
8
|
});
|
|
7
9
|
export const provideSettings = () => {
|
|
8
10
|
let settings = $state(defaults());
|
|
9
11
|
get('motion-tools-settings').then((response) => {
|
|
10
12
|
if (response) {
|
|
11
|
-
settings = response;
|
|
13
|
+
settings = { ...settings, ...response };
|
|
12
14
|
}
|
|
13
15
|
});
|
|
14
16
|
$effect(() => {
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export { default as CameraControls } from './components/CameraControls.svelte';
|
|
2
|
-
export { type default as CameraController } from 'camera-controls';
|
|
3
1
|
export { default as Geometry } from './components/Geometry.svelte';
|
|
4
2
|
export { default as AxesHelper } from './components/AxesHelper.svelte';
|
|
5
3
|
export { BatchedArrow } from './three/BatchedArrow';
|
package/dist/lib.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
// Components
|
|
2
|
-
export { default as CameraControls } from './components/CameraControls.svelte';
|
|
3
|
-
export {} from 'camera-controls';
|
|
4
2
|
export { default as Geometry } from './components/Geometry.svelte';
|
|
5
3
|
export { default as AxesHelper } from './components/AxesHelper.svelte';
|
|
6
4
|
// Classes
|
package/package.json
CHANGED
|
@@ -1,71 +1,72 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/motion-tools",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Motion visualization with Viam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"devDependencies": {
|
|
8
|
-
"@ag-grid-community/client-side-row-model": "
|
|
9
|
-
"@ag-grid-community/core": "
|
|
10
|
-
"@ag-grid-community/styles": "
|
|
11
|
-
"@changesets/cli": "
|
|
12
|
-
"@dimforge/rapier3d-compat": "
|
|
13
|
-
"@eslint/compat": "
|
|
14
|
-
"@eslint/js": "
|
|
15
|
-
"@playwright/test": "
|
|
8
|
+
"@ag-grid-community/client-side-row-model": "32.3.5",
|
|
9
|
+
"@ag-grid-community/core": "32.3.5",
|
|
10
|
+
"@ag-grid-community/styles": "32.3.5",
|
|
11
|
+
"@changesets/cli": "2.29.4",
|
|
12
|
+
"@dimforge/rapier3d-compat": "0.17.3",
|
|
13
|
+
"@eslint/compat": "1.3.0",
|
|
14
|
+
"@eslint/js": "9.28.0",
|
|
15
|
+
"@playwright/test": "1.53.0",
|
|
16
16
|
"@skeletonlabs/skeleton": "3.1.3",
|
|
17
17
|
"@skeletonlabs/skeleton-svelte": "1.2.3",
|
|
18
|
-
"@sveltejs/adapter-static": "
|
|
19
|
-
"@sveltejs/kit": "
|
|
20
|
-
"@sveltejs/package": "
|
|
21
|
-
"@sveltejs/vite-plugin-svelte": "
|
|
22
|
-
"@tailwindcss/forms": "
|
|
23
|
-
"@tailwindcss/vite": "
|
|
24
|
-
"@tanstack/svelte-query": "
|
|
25
|
-
"@tanstack/svelte-query-devtools": "
|
|
26
|
-
"@testing-library/jest-dom": "
|
|
27
|
-
"@testing-library/svelte": "
|
|
28
|
-
"@threlte/core": "
|
|
29
|
-
"@threlte/extras": "
|
|
30
|
-
"@threlte/rapier": "
|
|
31
|
-
"@threlte/xr": "
|
|
32
|
-
"@types/bun": "
|
|
33
|
-
"@types/lodash-es": "
|
|
34
|
-
"@types/three": "
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "
|
|
36
|
-
"@typescript-eslint/parser": "
|
|
37
|
-
"@viamrobotics/prime-core": "
|
|
18
|
+
"@sveltejs/adapter-static": "3.0.8",
|
|
19
|
+
"@sveltejs/kit": "2.21.4",
|
|
20
|
+
"@sveltejs/package": "2.3.11",
|
|
21
|
+
"@sveltejs/vite-plugin-svelte": "5.1.0",
|
|
22
|
+
"@tailwindcss/forms": "0.5.10",
|
|
23
|
+
"@tailwindcss/vite": "4.1.10",
|
|
24
|
+
"@tanstack/svelte-query": "5.80.6",
|
|
25
|
+
"@tanstack/svelte-query-devtools": "5.80.6",
|
|
26
|
+
"@testing-library/jest-dom": "6.6.3",
|
|
27
|
+
"@testing-library/svelte": "5.2.8",
|
|
28
|
+
"@threlte/core": "8.0.4",
|
|
29
|
+
"@threlte/extras": "9.4.0",
|
|
30
|
+
"@threlte/rapier": "3.1.4",
|
|
31
|
+
"@threlte/xr": "1.0.6",
|
|
32
|
+
"@types/bun": "1.2.15",
|
|
33
|
+
"@types/lodash-es": "4.17.12",
|
|
34
|
+
"@types/three": "0.177.0",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "8.34.0",
|
|
36
|
+
"@typescript-eslint/parser": "8.34.0",
|
|
37
|
+
"@viamrobotics/prime-core": "0.1.5",
|
|
38
38
|
"@viamrobotics/sdk": "0.43.0",
|
|
39
39
|
"@viamrobotics/svelte-sdk": "0.3.3",
|
|
40
|
-
"@vitejs/plugin-basic-ssl": "
|
|
41
|
-
"@zag-js/svelte": "1.15.
|
|
42
|
-
"@zag-js/tree-view": "1.15.
|
|
43
|
-
"camera-controls": "
|
|
44
|
-
"eslint": "
|
|
45
|
-
"eslint-config-prettier": "
|
|
46
|
-
"eslint-plugin-svelte": "
|
|
47
|
-
"globals": "
|
|
48
|
-
"idb-keyval": "
|
|
49
|
-
"jsdom": "
|
|
50
|
-
"lodash-es": "
|
|
51
|
-
"lucide-svelte": "
|
|
52
|
-
"prettier": "
|
|
53
|
-
"prettier-plugin-svelte": "
|
|
54
|
-
"prettier-plugin-tailwindcss": "
|
|
55
|
-
"publint": "
|
|
56
|
-
"runed": "
|
|
57
|
-
"svelte": "5.33.
|
|
58
|
-
"svelte-check": "
|
|
59
|
-
"svelte-virtuallists": "
|
|
60
|
-
"tailwindcss": "
|
|
61
|
-
"three": "
|
|
62
|
-
"threlte-uikit": "
|
|
63
|
-
"tsx": "
|
|
64
|
-
"typescript": "
|
|
65
|
-
"typescript-eslint": "
|
|
66
|
-
"vite": "
|
|
67
|
-
"vite-plugin-
|
|
68
|
-
"
|
|
40
|
+
"@vitejs/plugin-basic-ssl": "2.0.0",
|
|
41
|
+
"@zag-js/svelte": "1.15.2",
|
|
42
|
+
"@zag-js/tree-view": "1.15.2",
|
|
43
|
+
"camera-controls": "2.10.1",
|
|
44
|
+
"eslint": "9.28.0",
|
|
45
|
+
"eslint-config-prettier": "10.1.5",
|
|
46
|
+
"eslint-plugin-svelte": "3.9.2",
|
|
47
|
+
"globals": "16.2.0",
|
|
48
|
+
"idb-keyval": "6.2.2",
|
|
49
|
+
"jsdom": "26.1.0",
|
|
50
|
+
"lodash-es": "4.17.21",
|
|
51
|
+
"lucide-svelte": "0.514.0",
|
|
52
|
+
"prettier": "3.5.3",
|
|
53
|
+
"prettier-plugin-svelte": "3.4.0",
|
|
54
|
+
"prettier-plugin-tailwindcss": "0.6.12",
|
|
55
|
+
"publint": "0.3.12",
|
|
56
|
+
"runed": "0.28.0",
|
|
57
|
+
"svelte": "5.33.19",
|
|
58
|
+
"svelte-check": "4.2.1",
|
|
59
|
+
"svelte-virtuallists": "1.4.2",
|
|
60
|
+
"tailwindcss": "4.1.10",
|
|
61
|
+
"three": "0.177.0",
|
|
62
|
+
"threlte-uikit": "1.1.0",
|
|
63
|
+
"tsx": "4.20.1",
|
|
64
|
+
"typescript": "5.8.3",
|
|
65
|
+
"typescript-eslint": "8.34.0",
|
|
66
|
+
"vite": "6.3.5",
|
|
67
|
+
"vite-plugin-devtools-json": "0.2.0",
|
|
68
|
+
"vite-plugin-mkcert": "1.17.8",
|
|
69
|
+
"vitest": "3.2.3"
|
|
69
70
|
},
|
|
70
71
|
"peerDependencies": {
|
|
71
72
|
"@dimforge/rapier3d-compat": ">=0.17",
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
<script
|
|
2
|
-
module
|
|
3
|
-
lang="ts"
|
|
4
|
-
>
|
|
5
|
-
import {
|
|
6
|
-
Box3,
|
|
7
|
-
Matrix4,
|
|
8
|
-
PerspectiveCamera,
|
|
9
|
-
Quaternion,
|
|
10
|
-
Raycaster,
|
|
11
|
-
Sphere,
|
|
12
|
-
Spherical,
|
|
13
|
-
Vector2,
|
|
14
|
-
Vector3,
|
|
15
|
-
Vector4,
|
|
16
|
-
} from 'three'
|
|
17
|
-
import CameraController from 'camera-controls'
|
|
18
|
-
import { T, useTask, useThrelte } from '@threlte/core'
|
|
19
|
-
import type { Snippet } from 'svelte'
|
|
20
|
-
|
|
21
|
-
let installed = false
|
|
22
|
-
|
|
23
|
-
const install = () => {
|
|
24
|
-
CameraController.install({
|
|
25
|
-
THREE: {
|
|
26
|
-
Box3,
|
|
27
|
-
Matrix4,
|
|
28
|
-
Quaternion,
|
|
29
|
-
Raycaster,
|
|
30
|
-
Sphere,
|
|
31
|
-
Spherical,
|
|
32
|
-
Vector2,
|
|
33
|
-
Vector3,
|
|
34
|
-
Vector4,
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
installed = true
|
|
38
|
-
}
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<script lang="ts">
|
|
42
|
-
interface Props {
|
|
43
|
-
ref?: CameraController
|
|
44
|
-
enabled?: boolean
|
|
45
|
-
children?: Snippet
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
let { ref = $bindable(), enabled = true, children }: Props = $props()
|
|
49
|
-
|
|
50
|
-
if (!installed) {
|
|
51
|
-
install()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const { camera, dom, invalidate } = useThrelte()
|
|
55
|
-
|
|
56
|
-
const controls = new CameraController(camera.current as PerspectiveCamera, dom)
|
|
57
|
-
|
|
58
|
-
$effect.pre(() => {
|
|
59
|
-
controls.camera = $camera as PerspectiveCamera
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
$effect.pre(() => {
|
|
63
|
-
controls.enabled = enabled
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
useTask(
|
|
67
|
-
(delta) => {
|
|
68
|
-
if (controls.update(delta)) {
|
|
69
|
-
invalidate()
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
{ autoInvalidate: false }
|
|
73
|
-
)
|
|
74
|
-
</script>
|
|
75
|
-
|
|
76
|
-
<T
|
|
77
|
-
is={controls}
|
|
78
|
-
bind:ref
|
|
79
|
-
>
|
|
80
|
-
{@render children?.()}
|
|
81
|
-
</T>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import CameraController from 'camera-controls';
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
interface Props {
|
|
4
|
-
ref?: CameraController;
|
|
5
|
-
enabled?: boolean;
|
|
6
|
-
children?: Snippet;
|
|
7
|
-
}
|
|
8
|
-
declare const CameraControls: import("svelte").Component<Props, {}, "ref">;
|
|
9
|
-
type CameraControls = ReturnType<typeof CameraControls>;
|
|
10
|
-
export default CameraControls;
|
package/dist/keybindings.d.ts
DELETED