@viamrobotics/motion-tools 1.15.5 → 1.15.7
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/Entities/Arrows/Arrows.svelte +6 -3
- package/dist/components/Entities/Frame.svelte +5 -1
- package/dist/components/Entities/GLTF.svelte +2 -0
- package/dist/components/Entities/Geometry.svelte +20 -17
- package/dist/components/Entities/Line.svelte +2 -0
- package/dist/components/Entities/Points.svelte +2 -0
- package/dist/components/Entities/hooks/useEntityEvents.svelte.d.ts +0 -1
- package/dist/components/Entities/hooks/useEntityEvents.svelte.js +3 -8
- package/dist/components/KeyboardControls.svelte +6 -4
- package/dist/components/Scene.svelte +0 -1
- package/dist/components/SceneProviders.svelte +0 -2
- package/dist/components/hover/LinkedHoveredEntity.svelte +6 -12
- package/dist/components/hover/LinkedHoveredEntity.svelte.d.ts +0 -2
- package/dist/components/overlay/FloatingPanel.svelte +1 -1
- package/dist/components/overlay/Logs.svelte +95 -28
- package/dist/components/overlay/left-pane/Tree.svelte +17 -147
- package/dist/components/overlay/left-pane/Tree.svelte.d.ts +3 -3
- package/dist/components/overlay/left-pane/TreeNode.svelte +169 -0
- package/dist/components/overlay/left-pane/TreeNode.svelte.d.ts +10 -0
- package/dist/components/xr/OriginMarker.svelte +44 -83
- package/dist/components/xr/PointDistance.svelte +8 -14
- package/dist/components/xr/XR.svelte +32 -11
- package/dist/components/xr/frame-configure/Controllers.svelte +6 -0
- package/dist/components/xr/{HandCollider.svelte.d.ts → frame-configure/Controllers.svelte.d.ts} +3 -3
- package/dist/components/xr/{Controllers.svelte → teleop/Controllers.svelte} +4 -19
- package/dist/ecs/traits.d.ts +1 -0
- package/dist/ecs/traits.js +1 -0
- package/dist/hooks/use3DModels.svelte.js +1 -1
- package/dist/hooks/useFramelessComponents.svelte.js +3 -3
- package/dist/hooks/useSettings.svelte.d.ts +4 -2
- package/dist/hooks/useSettings.svelte.js +15 -7
- package/package.json +3 -3
- package/dist/components/xr/Draggable.svelte +0 -102
- package/dist/components/xr/Draggable.svelte.d.ts +0 -11
- package/dist/components/xr/HandCollider.svelte +0 -20
- package/dist/hooks/useVisibility.svelte.d.ts +0 -6
- package/dist/hooks/useVisibility.svelte.js +0 -10
- /package/dist/components/xr/{Controllers.svelte.d.ts → teleop/Controllers.svelte.d.ts} +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Api } from '@zag-js/tree-view'
|
|
3
|
+
|
|
4
|
+
import { ChevronRight, Eye, EyeOff } from 'lucide-svelte'
|
|
5
|
+
import { VirtualList } from 'svelte-virtuallists'
|
|
6
|
+
|
|
7
|
+
import { traits, useTrait } from '../../../ecs'
|
|
8
|
+
|
|
9
|
+
import type { TreeNode } from './buildTree'
|
|
10
|
+
|
|
11
|
+
import Self from './TreeNode.svelte'
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
node: TreeNode
|
|
15
|
+
indexPath: number[]
|
|
16
|
+
api: Api
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { node, indexPath, api }: Props = $props()
|
|
20
|
+
|
|
21
|
+
const name = useTrait(() => node.entity, traits.Name)
|
|
22
|
+
const invisible = useTrait(() => node.entity, traits.Invisible)
|
|
23
|
+
|
|
24
|
+
const nodeProps = $derived({ indexPath, node })
|
|
25
|
+
const nodeState = $derived(api.getNodeState(nodeProps))
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
{#if nodeState.isBranch}
|
|
29
|
+
{@const { expanded } = nodeState}
|
|
30
|
+
{@const { children = [] } = node}
|
|
31
|
+
<div
|
|
32
|
+
{...api.getBranchProps(nodeProps)}
|
|
33
|
+
class={[
|
|
34
|
+
'w-full',
|
|
35
|
+
{
|
|
36
|
+
'text-disabled': invisible.current,
|
|
37
|
+
'bg-medium': nodeState.selected,
|
|
38
|
+
sticky: true,
|
|
39
|
+
},
|
|
40
|
+
]}
|
|
41
|
+
>
|
|
42
|
+
<div {...api.getBranchControlProps(nodeProps)}>
|
|
43
|
+
<span
|
|
44
|
+
{...api.getBranchIndicatorProps(nodeProps)}
|
|
45
|
+
class={{ 'rotate-90': expanded }}
|
|
46
|
+
>
|
|
47
|
+
<ChevronRight size={14} />
|
|
48
|
+
</span>
|
|
49
|
+
<span
|
|
50
|
+
class="flex items-center overflow-hidden text-ellipsis"
|
|
51
|
+
{...api.getBranchTextProps(nodeProps)}
|
|
52
|
+
>
|
|
53
|
+
{name.current}
|
|
54
|
+
</span>
|
|
55
|
+
|
|
56
|
+
<button
|
|
57
|
+
class="text-gray-6"
|
|
58
|
+
onclick={(event) => {
|
|
59
|
+
event.stopPropagation()
|
|
60
|
+
|
|
61
|
+
if (node.entity.has(traits.Invisible)) {
|
|
62
|
+
node.entity.remove(traits.Invisible)
|
|
63
|
+
} else {
|
|
64
|
+
node.entity.add(traits.Invisible)
|
|
65
|
+
}
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
{#if invisible.current}
|
|
69
|
+
<EyeOff size={14} />
|
|
70
|
+
{:else}
|
|
71
|
+
<Eye size={14} />
|
|
72
|
+
{/if}
|
|
73
|
+
</button>
|
|
74
|
+
</div>
|
|
75
|
+
<div {...api.getBranchContentProps(nodeProps)}>
|
|
76
|
+
<div {...api.getBranchIndentGuideProps(nodeProps)}></div>
|
|
77
|
+
|
|
78
|
+
{#if children.length > 200}
|
|
79
|
+
<VirtualList
|
|
80
|
+
class="w-full"
|
|
81
|
+
style="height:{Math.min(8, Math.max(children.length, 5)) * 32}px;"
|
|
82
|
+
items={children}
|
|
83
|
+
>
|
|
84
|
+
{#snippet vl_slot({ index, item: node })}
|
|
85
|
+
<Self
|
|
86
|
+
{node}
|
|
87
|
+
indexPath={[...indexPath, Number(index)]}
|
|
88
|
+
{api}
|
|
89
|
+
/>
|
|
90
|
+
{/snippet}
|
|
91
|
+
</VirtualList>
|
|
92
|
+
{:else}
|
|
93
|
+
{#each children as node, index (node.entity)}
|
|
94
|
+
<Self
|
|
95
|
+
{node}
|
|
96
|
+
indexPath={[...indexPath, Number(index)]}
|
|
97
|
+
{api}
|
|
98
|
+
/>
|
|
99
|
+
{/each}
|
|
100
|
+
{/if}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
{:else}
|
|
104
|
+
<div
|
|
105
|
+
class={{
|
|
106
|
+
'flex justify-between': true,
|
|
107
|
+
'text-disabled': invisible.current,
|
|
108
|
+
'bg-medium': nodeState.selected,
|
|
109
|
+
}}
|
|
110
|
+
{...api.getItemProps(nodeProps)}
|
|
111
|
+
>
|
|
112
|
+
<span class="flex items-center gap-1.5 overflow-hidden text-nowrap text-ellipsis">
|
|
113
|
+
{node.entity.get(traits.Name)}
|
|
114
|
+
</span>
|
|
115
|
+
|
|
116
|
+
<button
|
|
117
|
+
class="text-gray-6"
|
|
118
|
+
onclick={(event) => {
|
|
119
|
+
event.stopPropagation()
|
|
120
|
+
if (node.entity.has(traits.Invisible)) {
|
|
121
|
+
node.entity.remove(traits.Invisible)
|
|
122
|
+
} else {
|
|
123
|
+
node.entity.add(traits.Invisible)
|
|
124
|
+
}
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
{#if invisible.current}
|
|
128
|
+
<EyeOff size={14} />
|
|
129
|
+
{:else}
|
|
130
|
+
<Eye size={14} />
|
|
131
|
+
{/if}
|
|
132
|
+
</button>
|
|
133
|
+
</div>
|
|
134
|
+
{/if}
|
|
135
|
+
|
|
136
|
+
<style>
|
|
137
|
+
:global(:root) {
|
|
138
|
+
[data-scope='tree-view'][data-part='item'],
|
|
139
|
+
[data-scope='tree-view'][data-part='branch-control'] {
|
|
140
|
+
user-select: none;
|
|
141
|
+
--padding-inline: 16px;
|
|
142
|
+
padding-inline-start: calc(var(--depth) * var(--padding-inline));
|
|
143
|
+
padding-inline-end: var(--padding-inline);
|
|
144
|
+
display: flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
gap: 8px;
|
|
147
|
+
min-height: 32px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
[data-scope='tree-view'][data-part='item-text'],
|
|
151
|
+
[data-scope='tree-view'][data-part='branch-text'] {
|
|
152
|
+
flex: 1;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
[data-scope='tree-view'][data-part='branch-content'] {
|
|
156
|
+
position: relative;
|
|
157
|
+
isolation: isolate;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[data-scope='tree-view'][data-part='branch-indent-guide'] {
|
|
161
|
+
position: absolute;
|
|
162
|
+
content: '';
|
|
163
|
+
border-left: 1px solid #eee;
|
|
164
|
+
height: 100%;
|
|
165
|
+
translate: calc(var(--depth) * 1.25rem);
|
|
166
|
+
z-index: 1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Api } from '@zag-js/tree-view';
|
|
2
|
+
import type { TreeNode } from './buildTree';
|
|
3
|
+
interface Props {
|
|
4
|
+
node: TreeNode;
|
|
5
|
+
indexPath: number[];
|
|
6
|
+
api: Api;
|
|
7
|
+
}
|
|
8
|
+
declare const TreeNode: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type TreeNode = ReturnType<typeof TreeNode>;
|
|
10
|
+
export default TreeNode;
|
|
@@ -1,113 +1,74 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { T, useTask } from '@threlte/core'
|
|
2
|
+
import { T } from '@threlte/core'
|
|
4
3
|
import { Grid, useGamepad } from '@threlte/extras'
|
|
5
|
-
import {
|
|
6
|
-
import { useController } from '@threlte/xr'
|
|
7
|
-
import { Euler, Group, Quaternion, Vector3 } from 'three'
|
|
4
|
+
import { Group, Quaternion, Vector2, Vector3 } from 'three'
|
|
8
5
|
|
|
6
|
+
import { useAnchors } from './useAnchors.svelte'
|
|
9
7
|
import { useOrigin } from './useOrigin.svelte'
|
|
10
8
|
|
|
11
9
|
const origin = useOrigin()
|
|
12
|
-
|
|
13
|
-
const height = 0.1
|
|
14
|
-
const radius = 0.05
|
|
10
|
+
const anchors = useAnchors()
|
|
15
11
|
|
|
16
12
|
const group = new Group()
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const vec3 = new Vector3()
|
|
20
|
-
|
|
21
|
-
const quaternion = new Quaternion()
|
|
22
|
-
const euler = new Euler()
|
|
23
|
-
|
|
24
|
-
const offset = new Vector3()
|
|
25
|
-
|
|
26
|
-
const position = new Vector3()
|
|
27
|
-
|
|
28
|
-
let dragging = $state(false)
|
|
29
|
-
let rotating = $state(false)
|
|
30
|
-
|
|
31
|
-
let currentDistance = 0
|
|
32
|
-
const rotateDown = new Vector3()
|
|
33
|
-
|
|
34
|
-
let rigidBody = $state<RigidBodyType>()
|
|
35
|
-
|
|
36
|
-
const left = useController('left')
|
|
37
|
-
const right = useController('right')
|
|
13
|
+
const anchorObject = new Group()
|
|
38
14
|
|
|
39
15
|
const leftPad = useGamepad({ xr: true, hand: 'left' })
|
|
16
|
+
const rightPad = useGamepad({ xr: true, hand: 'right' })
|
|
40
17
|
|
|
41
|
-
|
|
42
|
-
const grip = $left?.grip
|
|
18
|
+
const speed = 0.05
|
|
43
19
|
|
|
44
|
-
|
|
20
|
+
const vec2 = new Vector2()
|
|
21
|
+
const target = new Vector2()
|
|
22
|
+
|
|
23
|
+
leftPad.thumbstick.on('change', ({ value }) => {
|
|
24
|
+
if (typeof value === 'number') {
|
|
45
25
|
return
|
|
46
26
|
}
|
|
47
27
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
})
|
|
52
|
-
leftPad.trigger.on('up', () => (dragging = false))
|
|
28
|
+
const { x: vx, y: vy } = value
|
|
29
|
+
const [x, y, z] = origin.position
|
|
30
|
+
const r = origin.rotation
|
|
53
31
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!$left || !rigidBody) return
|
|
32
|
+
origin.set([x, y, z + vy * speed], r + vx * speed)
|
|
33
|
+
})
|
|
57
34
|
|
|
58
|
-
|
|
35
|
+
rightPad.thumbstick.on('change', ({ value }) => {
|
|
36
|
+
if (typeof value === 'number') {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
59
39
|
|
|
60
|
-
|
|
40
|
+
const { x: vx, y: vy } = value
|
|
41
|
+
const [x, y, z] = origin.position
|
|
42
|
+
const r = origin.rotation
|
|
61
43
|
|
|
62
|
-
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
running: () => dragging,
|
|
66
|
-
}
|
|
67
|
-
)
|
|
44
|
+
vec2.set(x, y).lerp(target.set(x + vx * speed, y + vy * speed), 0.5)
|
|
68
45
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (!$right || !rigidBody) return
|
|
46
|
+
origin.set([vec2.x, vec2.y, z], r)
|
|
47
|
+
})
|
|
72
48
|
|
|
73
|
-
|
|
49
|
+
const vec3 = new Vector3()
|
|
50
|
+
const quaternion = new Quaternion()
|
|
74
51
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
euler.setFromQuaternion(quaternion)
|
|
78
|
-
euler.z = distance + currentDistance
|
|
79
|
-
origin.set(undefined, euler.z)
|
|
52
|
+
$effect(() => {
|
|
53
|
+
vec3.fromArray(origin.position)
|
|
80
54
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
55
|
+
anchors.createAnchor(vec3, quaternion)?.then((anchor) => {
|
|
56
|
+
anchors.bindAnchorObject(anchor, anchorObject)
|
|
57
|
+
})
|
|
58
|
+
})
|
|
85
59
|
</script>
|
|
86
60
|
|
|
87
61
|
<T
|
|
88
62
|
is={group}
|
|
89
63
|
position={[0, 0.05, 0]}
|
|
90
64
|
>
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<T is={innerGroup}>
|
|
101
|
-
<Grid
|
|
102
|
-
plane="xy"
|
|
103
|
-
position.y={0.05}
|
|
104
|
-
fadeDistance={5}
|
|
105
|
-
fadeOrigin={new Vector3()}
|
|
106
|
-
cellSize={0.1}
|
|
107
|
-
cellColor="#fff"
|
|
108
|
-
sectionColor="#fff"
|
|
109
|
-
/>
|
|
110
|
-
</T>
|
|
111
|
-
</Collider>
|
|
112
|
-
</RigidBody>
|
|
65
|
+
<Grid
|
|
66
|
+
plane="xy"
|
|
67
|
+
position.y={0.05}
|
|
68
|
+
fadeDistance={5}
|
|
69
|
+
fadeOrigin={new Vector3()}
|
|
70
|
+
cellSize={0.1}
|
|
71
|
+
cellColor="#fff"
|
|
72
|
+
sectionColor="#fff"
|
|
73
|
+
/>
|
|
113
74
|
</T>
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import { Billboard, Text } from '@threlte/extras'
|
|
4
4
|
import { Mesh, Vector3 } from 'three'
|
|
5
5
|
|
|
6
|
-
import Draggable from './Draggable.svelte'
|
|
7
|
-
|
|
8
6
|
const mesh1 = new Mesh()
|
|
9
7
|
const mesh2 = new Mesh()
|
|
10
8
|
const distance = new Vector3()
|
|
@@ -29,12 +27,10 @@
|
|
|
29
27
|
</script>
|
|
30
28
|
|
|
31
29
|
<T.Group position={[-1, 1, 0]}>
|
|
32
|
-
<
|
|
33
|
-
<T
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
</T>
|
|
37
|
-
</Draggable>
|
|
30
|
+
<T is={mesh1}>
|
|
31
|
+
<T.SphereGeometry args={[0.05]} />
|
|
32
|
+
<T.MeshStandardMaterial />
|
|
33
|
+
</T>
|
|
38
34
|
</T.Group>
|
|
39
35
|
|
|
40
36
|
<T.Group position={textPosition}>
|
|
@@ -44,10 +40,8 @@
|
|
|
44
40
|
</T.Group>
|
|
45
41
|
|
|
46
42
|
<T.Group position={[-1.5, 1, 0]}>
|
|
47
|
-
<
|
|
48
|
-
<T
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
</T>
|
|
52
|
-
</Draggable>
|
|
43
|
+
<T is={mesh2}>
|
|
44
|
+
<T.SphereGeometry args={[0.05]} />
|
|
45
|
+
<T.MeshStandardMaterial />
|
|
46
|
+
</T>
|
|
53
47
|
</T.Group>
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { World } from '@threlte/rapier'
|
|
2
|
+
import { useThrelte } from '@threlte/core'
|
|
4
3
|
import { useXR, XR, XRButton } from '@threlte/xr'
|
|
5
4
|
import { SvelteMap } from 'svelte/reactivity'
|
|
5
|
+
import { Quaternion } from 'three'
|
|
6
6
|
|
|
7
7
|
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
8
8
|
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
9
9
|
|
|
10
10
|
import CameraFeed from './CameraFeed.svelte'
|
|
11
|
-
import
|
|
11
|
+
import FrameConfigureControllers from './frame-configure/Controllers.svelte'
|
|
12
12
|
import JointLimitsWidget from './JointLimitsWidget.svelte'
|
|
13
13
|
import OriginMarker from './OriginMarker.svelte'
|
|
14
|
+
import TeleopControllers from './teleop/Controllers.svelte'
|
|
15
|
+
import { provideAnchors } from './useAnchors.svelte'
|
|
14
16
|
import { useOrigin } from './useOrigin.svelte'
|
|
15
17
|
import XRToast from './XRToast.svelte'
|
|
16
18
|
|
|
@@ -19,6 +21,7 @@
|
|
|
19
21
|
const { isPresenting } = useXR()
|
|
20
22
|
const settings = useSettings()
|
|
21
23
|
const origin = useOrigin()
|
|
24
|
+
provideAnchors()
|
|
22
25
|
const enableXR = $derived(settings.current.enableXR)
|
|
23
26
|
|
|
24
27
|
const partID = usePartID()
|
|
@@ -44,6 +47,26 @@
|
|
|
44
47
|
const controllerConfig = $derived(settings.current.xrController)
|
|
45
48
|
const leftArmName = $derived(controllerConfig.left.armName)
|
|
46
49
|
const rightArmName = $derived(controllerConfig.right.armName)
|
|
50
|
+
|
|
51
|
+
const { renderer } = useThrelte()
|
|
52
|
+
|
|
53
|
+
// Move into Viam's coordinate system. This basically accomplishes
|
|
54
|
+
// the same thing as setting z up in the Camera component.
|
|
55
|
+
$effect(() => {
|
|
56
|
+
if ($isPresenting) {
|
|
57
|
+
const q = new Quaternion().setFromAxisAngle({ x: 1, y: 0, z: 0 }, -Math.PI / 2)
|
|
58
|
+
|
|
59
|
+
// after the XR session has started and a reference space exists:
|
|
60
|
+
const baseRefSpace = renderer.xr.getReferenceSpace()
|
|
61
|
+
if (baseRefSpace) {
|
|
62
|
+
const rotatedRefSpace = baseRefSpace.getOffsetReferenceSpace(
|
|
63
|
+
new XRRigidTransform({ x: 0, y: 0, z: 0, w: 1 }, { x: q.x, y: q.y, z: q.z, w: q.w })
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
renderer.xr.setReferenceSpace(rotatedRefSpace)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
})
|
|
47
70
|
</script>
|
|
48
71
|
|
|
49
72
|
{#if enableXR}
|
|
@@ -93,15 +116,13 @@
|
|
|
93
116
|
|
|
94
117
|
<XRToast />
|
|
95
118
|
|
|
96
|
-
|
|
97
|
-
<
|
|
119
|
+
{#if settings.current.xrMode === 'arm-teleop'}
|
|
120
|
+
<TeleopControllers />
|
|
121
|
+
{:else if settings.current.xrMode === 'frame-configure'}
|
|
122
|
+
<FrameConfigureControllers />
|
|
123
|
+
{/if}
|
|
98
124
|
|
|
99
|
-
|
|
100
|
-
<T.Group rotation.x={$isPresenting ? -Math.PI / 2 : 0}>
|
|
101
|
-
<OriginMarker />
|
|
102
|
-
</T.Group>
|
|
103
|
-
</T.Group>
|
|
104
|
-
</World>
|
|
125
|
+
<OriginMarker />
|
|
105
126
|
</XR>
|
|
106
127
|
|
|
107
128
|
<XRButton
|
package/dist/components/xr/{HandCollider.svelte.d.ts → frame-configure/Controllers.svelte.d.ts}
RENAMED
|
@@ -11,8 +11,8 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
11
11
|
};
|
|
12
12
|
z_$$bindings?: Bindings;
|
|
13
13
|
}
|
|
14
|
-
declare const
|
|
14
|
+
declare const Controllers: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
15
|
[evt: string]: CustomEvent<any>;
|
|
16
16
|
}, {}, {}, string>;
|
|
17
|
-
type
|
|
18
|
-
export default
|
|
17
|
+
type Controllers = InstanceType<typeof Controllers>;
|
|
18
|
+
export default Controllers;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { RigidBody } from '@threlte/rapier'
|
|
3
2
|
import { Controller } from '@threlte/xr'
|
|
4
3
|
|
|
5
|
-
import { useSettings } from '
|
|
4
|
+
import { useSettings } from '../../../hooks/useSettings.svelte'
|
|
6
5
|
|
|
7
|
-
import ArmTeleop from '
|
|
8
|
-
import HandCollider from './HandCollider.svelte'
|
|
6
|
+
import ArmTeleop from '../ArmTeleop.svelte'
|
|
9
7
|
|
|
10
8
|
const settings = useSettings()
|
|
11
9
|
|
|
@@ -25,21 +23,8 @@
|
|
|
25
23
|
const rightRotationEnabled = $derived(config.right.rotationEnabled)
|
|
26
24
|
</script>
|
|
27
25
|
|
|
28
|
-
<Controller left
|
|
29
|
-
|
|
30
|
-
<RigidBody type="kinematicPosition">
|
|
31
|
-
<HandCollider />
|
|
32
|
-
</RigidBody>
|
|
33
|
-
{/snippet}
|
|
34
|
-
</Controller>
|
|
35
|
-
|
|
36
|
-
<Controller right>
|
|
37
|
-
{#snippet grip()}
|
|
38
|
-
<RigidBody type="kinematicPosition">
|
|
39
|
-
<HandCollider />
|
|
40
|
-
</RigidBody>
|
|
41
|
-
{/snippet}
|
|
42
|
-
</Controller>
|
|
26
|
+
<Controller left />
|
|
27
|
+
<Controller right />
|
|
43
28
|
|
|
44
29
|
<!-- Left Controller Arm Teleop -->
|
|
45
30
|
{#if leftArmName}
|
package/dist/ecs/traits.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export declare const WorldPose: import("koota").Trait<{
|
|
|
51
51
|
theta: number;
|
|
52
52
|
}>;
|
|
53
53
|
export declare const Hovered: import("koota").Trait<() => boolean>;
|
|
54
|
+
export declare const Invisible: import("koota").Trait<() => boolean>;
|
|
54
55
|
/**
|
|
55
56
|
* Represents that an entity is composed of many instances, so that the treeview and
|
|
56
57
|
* details panel may display all instances
|
package/dist/ecs/traits.js
CHANGED
|
@@ -28,6 +28,7 @@ export const WorldPose = trait({
|
|
|
28
28
|
theta: 0,
|
|
29
29
|
});
|
|
30
30
|
export const Hovered = trait(() => true);
|
|
31
|
+
export const Invisible = trait(() => true);
|
|
31
32
|
/**
|
|
32
33
|
* Represents that an entity is composed of many instances, so that the treeview and
|
|
33
34
|
* details panel may display all instances
|
|
@@ -57,7 +57,7 @@ export const provide3DModels = (partID) => {
|
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
$effect(() => {
|
|
60
|
-
const shouldFetchModels = settings.
|
|
60
|
+
const shouldFetchModels = settings.isLoaded && settings.current.renderArmModels.includes('model');
|
|
61
61
|
if (shouldFetchModels) {
|
|
62
62
|
fetch3DModels();
|
|
63
63
|
}
|
|
@@ -10,14 +10,14 @@ export const provideFramelessComponents = () => {
|
|
|
10
10
|
const partComponentsWIthNoFrame = components
|
|
11
11
|
?.filter((component) => component.frame === undefined)
|
|
12
12
|
.map((component) => component.name) ?? [];
|
|
13
|
-
const fragmentComponentsWithNoFrame =
|
|
13
|
+
const fragmentComponentsWithNoFrame = new Set(partComponentsWIthNoFrame);
|
|
14
14
|
for (const fragmentComponentName of Object.keys(partConfig.componentNameToFragmentId)) {
|
|
15
15
|
if (frames.current.some((frame) => frame.referenceFrame === fragmentComponentName)) {
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
|
-
fragmentComponentsWithNoFrame.
|
|
18
|
+
fragmentComponentsWithNoFrame.add(fragmentComponentName);
|
|
19
19
|
}
|
|
20
|
-
return [...
|
|
20
|
+
return [...fragmentComponentsWithNoFrame];
|
|
21
21
|
});
|
|
22
22
|
setContext(key, {
|
|
23
23
|
get current() {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export interface Settings {
|
|
2
|
-
isLoaded: boolean;
|
|
3
2
|
cameraMode: 'orthographic' | 'perspective';
|
|
4
3
|
transforming: boolean;
|
|
5
4
|
snapping: boolean;
|
|
@@ -19,12 +18,13 @@ export interface Settings {
|
|
|
19
18
|
enableLabels: boolean;
|
|
20
19
|
enableKeybindings: boolean;
|
|
21
20
|
enableQueryDevtools: boolean;
|
|
22
|
-
enableXR: boolean;
|
|
23
21
|
enableArmPositionsWidget: boolean;
|
|
24
22
|
openCameraWidgets: Record<string, string[]>;
|
|
25
23
|
renderStats: boolean;
|
|
26
24
|
renderArmModels: 'colliders' | 'colliders+model' | 'model';
|
|
27
25
|
renderSubEntityHoverDetail: boolean;
|
|
26
|
+
enableXR: boolean;
|
|
27
|
+
xrMode: 'frame-configure' | 'arm-teleop';
|
|
28
28
|
xrController: {
|
|
29
29
|
left: {
|
|
30
30
|
armName?: string;
|
|
@@ -42,6 +42,8 @@ export interface Settings {
|
|
|
42
42
|
}
|
|
43
43
|
interface Context {
|
|
44
44
|
current: Settings;
|
|
45
|
+
isLoaded: boolean;
|
|
46
|
+
merge(value: Settings): void;
|
|
45
47
|
}
|
|
46
48
|
export declare const provideSettings: () => Context;
|
|
47
49
|
export declare const useSettings: () => Context;
|
|
@@ -2,7 +2,6 @@ import { get, set } from 'idb-keyval';
|
|
|
2
2
|
import { getContext, setContext } from 'svelte';
|
|
3
3
|
const key = Symbol('dashboard-context');
|
|
4
4
|
const defaults = () => ({
|
|
5
|
-
isLoaded: false,
|
|
6
5
|
cameraMode: 'perspective',
|
|
7
6
|
transforming: false,
|
|
8
7
|
snapping: false,
|
|
@@ -22,12 +21,13 @@ const defaults = () => ({
|
|
|
22
21
|
enableLabels: false,
|
|
23
22
|
enableKeybindings: true,
|
|
24
23
|
enableQueryDevtools: false,
|
|
25
|
-
enableXR: false,
|
|
26
24
|
enableArmPositionsWidget: false,
|
|
27
25
|
openCameraWidgets: {},
|
|
28
26
|
renderStats: false,
|
|
29
27
|
renderArmModels: 'colliders+model',
|
|
30
28
|
renderSubEntityHoverDetail: false,
|
|
29
|
+
enableXR: false,
|
|
30
|
+
xrMode: 'frame-configure',
|
|
31
31
|
xrController: {
|
|
32
32
|
left: {
|
|
33
33
|
scaleFactor: 1,
|
|
@@ -40,17 +40,19 @@ const defaults = () => ({
|
|
|
40
40
|
},
|
|
41
41
|
});
|
|
42
42
|
export const provideSettings = () => {
|
|
43
|
+
let isLoaded = $state(false);
|
|
43
44
|
let settings = $state(defaults());
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
get('motion-tools-settings')
|
|
46
|
+
.then((response) => {
|
|
46
47
|
if (response) {
|
|
47
48
|
settings = { ...settings, ...response };
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
})
|
|
51
|
+
.finally(() => {
|
|
52
|
+
isLoaded = true;
|
|
51
53
|
});
|
|
52
54
|
$effect(() => {
|
|
53
|
-
if (
|
|
55
|
+
if (isLoaded) {
|
|
54
56
|
set('motion-tools-settings', $state.snapshot(settings));
|
|
55
57
|
}
|
|
56
58
|
});
|
|
@@ -61,6 +63,12 @@ export const provideSettings = () => {
|
|
|
61
63
|
set current(value) {
|
|
62
64
|
settings = value;
|
|
63
65
|
},
|
|
66
|
+
get isLoaded() {
|
|
67
|
+
return isLoaded;
|
|
68
|
+
},
|
|
69
|
+
merge(value) {
|
|
70
|
+
settings = { ...settings, ...value };
|
|
71
|
+
},
|
|
64
72
|
};
|
|
65
73
|
setContext(key, context);
|
|
66
74
|
return context;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/motion-tools",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.7",
|
|
4
4
|
"description": "Motion visualization with Viam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"prettier-plugin-tailwindcss": "0.6.14",
|
|
63
63
|
"publint": "0.3.12",
|
|
64
64
|
"runed": "0.31.1",
|
|
65
|
-
"svelte": "5.
|
|
65
|
+
"svelte": "5.55.0",
|
|
66
66
|
"svelte-check": "4.4.5",
|
|
67
67
|
"svelte-virtuallists": "1.4.2",
|
|
68
68
|
"tailwindcss": "4.1.13",
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"@neodrag/svelte": "^2.3.3",
|
|
137
137
|
"@tanstack/svelte-query-devtools": "^6.0.2",
|
|
138
138
|
"earcut": "^3.0.2",
|
|
139
|
-
"
|
|
139
|
+
"filtrex": "^3.1.0",
|
|
140
140
|
"koota": "0.6.5",
|
|
141
141
|
"lodash-es": "4.17.23",
|
|
142
142
|
"three-mesh-bvh": "^0.9.8",
|