@viamrobotics/motion-tools 1.9.0 → 1.10.0
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/HoverUpdater.svelte.d.ts +19 -0
- package/dist/HoverUpdater.svelte.js +120 -0
- package/dist/components/App.svelte +34 -35
- package/dist/components/CameraControls.svelte +1 -1
- package/dist/components/Focus.svelte +1 -1
- package/dist/components/Frame.svelte +1 -1
- package/dist/components/Geometry2.svelte +8 -5
- package/dist/components/Label.svelte +1 -1
- package/dist/components/MeasureTool/MeasurePoint.svelte +5 -3
- package/dist/components/MeasureTool/MeasureTool.svelte +11 -11
- package/dist/components/SceneProviders.svelte +2 -0
- package/dist/components/hover/HoveredEntities.svelte +23 -0
- package/dist/components/hover/HoveredEntity.svelte +15 -0
- package/dist/components/hover/HoveredEntity.svelte.d.ts +3 -0
- package/dist/components/hover/HoveredEntityTooltip.svelte +70 -0
- package/dist/components/{HoveredEntityTooltip.svelte.d.ts → hover/HoveredEntityTooltip.svelte.d.ts} +2 -2
- package/dist/components/hover/LinkedHoveredEntity.svelte +55 -0
- package/dist/components/hover/LinkedHoveredEntity.svelte.d.ts +9 -0
- package/dist/components/overlay/AddRelationship.svelte +131 -0
- package/dist/components/overlay/AddRelationship.svelte.d.ts +7 -0
- package/dist/components/{Details.svelte → overlay/Details.svelte} +44 -11
- package/dist/components/overlay/FloatingPanel.svelte +78 -0
- package/dist/components/overlay/FloatingPanel.svelte.d.ts +13 -0
- package/dist/components/{LiveUpdatesBanner.svelte → overlay/LiveUpdatesBanner.svelte} +2 -2
- package/dist/components/{RefreshRate.svelte → overlay/RefreshRate.svelte} +1 -1
- package/dist/components/overlay/ToggleGroup.svelte +56 -0
- package/dist/components/{Overlay → overlay}/ToggleGroup.svelte.d.ts +6 -7
- package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/entity.js +1 -1
- package/dist/components/{dashboard → overlay/dashboard}/Button.svelte +1 -1
- package/dist/components/{dashboard → overlay/dashboard}/Dashboard.svelte +2 -2
- package/dist/components/{Tree → overlay/left-pane}/AddFrames.svelte +2 -2
- package/dist/components/{Tree → overlay/left-pane}/Logs.svelte +1 -1
- package/dist/components/{Tree → overlay/left-pane}/Tree.svelte +3 -3
- package/dist/components/{Tree → overlay/left-pane}/TreeContainer.svelte +8 -10
- package/dist/components/{Tree → overlay/left-pane}/Widgets.svelte +3 -3
- package/dist/components/{Tree → overlay/left-pane}/buildTree.js +1 -1
- package/dist/components/overlay/settings/Settings.svelte +279 -0
- package/dist/components/overlay/settings/Tabs.svelte +54 -0
- package/dist/components/overlay/settings/Tabs.svelte.d.ts +12 -0
- package/dist/components/{widgets → overlay/widgets}/ArmPositions.svelte +4 -4
- package/dist/components/{widgets → overlay/widgets}/Camera.svelte +5 -5
- package/dist/ecs/index.d.ts +1 -0
- package/dist/ecs/index.js +1 -0
- package/dist/ecs/relations.d.ts +7 -0
- package/dist/ecs/relations.js +7 -0
- package/dist/ecs/traits.d.ts +8 -2
- package/dist/ecs/traits.js +11 -5
- package/dist/hooks/useDrawAPI.svelte.js +1 -1
- package/dist/hooks/useFrames.svelte.js +1 -0
- package/dist/hooks/useGeometries.svelte.js +1 -1
- package/dist/hooks/useLinked.svelte.d.ts +7 -0
- package/dist/hooks/useLinked.svelte.js +35 -0
- package/dist/hooks/useObjectEvents.svelte.js +35 -16
- package/dist/hooks/usePointcloudObjects.svelte.js +1 -1
- package/dist/hooks/usePointclouds.svelte.js +30 -43
- package/dist/hooks/usePose.svelte.js +1 -1
- package/dist/hooks/useWorldState.svelte.js +1 -1
- package/package.json +4 -1
- package/dist/components/DotSprite.svelte +0 -59
- package/dist/components/DotSprite.svelte.d.ts +0 -10
- package/dist/components/HoveredEntities.svelte +0 -19
- package/dist/components/HoveredEntityTooltip.svelte +0 -241
- package/dist/components/MeasureTool.svelte +0 -123
- package/dist/components/MeasureTool.svelte.d.ts +0 -3
- package/dist/components/Overlay/ToggleGroup.svelte +0 -60
- package/dist/components/Tree/Settings.svelte +0 -221
- package/dist/components/null-states/Connection.svelte +0 -0
- package/dist/components/null-states/Connection.svelte.d.ts +0 -26
- /package/dist/components/{HoveredEntities.svelte.d.ts → hover/HoveredEntities.svelte.d.ts} +0 -0
- /package/dist/components/{Details.svelte.d.ts → overlay/Details.svelte.d.ts} +0 -0
- /package/dist/components/{LiveUpdatesBanner.svelte.d.ts → overlay/LiveUpdatesBanner.svelte.d.ts} +0 -0
- /package/dist/components/{Overlay → overlay}/Popover.svelte +0 -0
- /package/dist/components/{Overlay → overlay}/Popover.svelte.d.ts +0 -0
- /package/dist/components/{RefreshRate.svelte.d.ts → overlay/RefreshRate.svelte.d.ts} +0 -0
- /package/dist/components/{shared → overlay}/Table.svelte +0 -0
- /package/dist/components/{shared → overlay}/Table.svelte.d.ts +0 -0
- /package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/entity.d.ts +0 -0
- /package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/resource.d.ts +0 -0
- /package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/resource.js +0 -0
- /package/dist/components/{dashboard → overlay/dashboard}/Button.svelte.d.ts +0 -0
- /package/dist/components/{dashboard → overlay/dashboard}/Dashboard.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/AddFrames.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/Drawer.svelte +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/Drawer.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/Logs.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/Tree.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/TreeContainer.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/Widgets.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/buildTree.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/useExpanded.svelte.d.ts +0 -0
- /package/dist/components/{Tree → overlay/left-pane}/useExpanded.svelte.js +0 -0
- /package/dist/components/{Tree → overlay/settings}/Settings.svelte.d.ts +0 -0
- /package/dist/components/{widgets → overlay/widgets}/ArmPositions.svelte.d.ts +0 -0
- /package/dist/components/{widgets → overlay/widgets}/Camera.svelte.d.ts +0 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Switch, Input } from '@viamrobotics/prime-core'
|
|
3
|
+
import { Portal } from '@threlte/extras'
|
|
4
|
+
import RefreshRate from '../RefreshRate.svelte'
|
|
5
|
+
import { useSettings } from '../../../hooks/useSettings.svelte'
|
|
6
|
+
import { useResourceNames } from '@viamrobotics/svelte-sdk'
|
|
7
|
+
import { usePartID } from '../../../hooks/usePartID.svelte'
|
|
8
|
+
import { RefreshRates, useMachineSettings } from '../../../hooks/useMachineSettings.svelte'
|
|
9
|
+
import { useGeometries } from '../../../hooks/useGeometries.svelte'
|
|
10
|
+
import { usePointClouds } from '../../../hooks/usePointclouds.svelte'
|
|
11
|
+
import { useThrelte } from '@threlte/core'
|
|
12
|
+
import { useRefetchPoses } from '../../../hooks/useRefetchPoses'
|
|
13
|
+
import FloatingPanel from '../FloatingPanel.svelte'
|
|
14
|
+
import DashboardButton from '../dashboard/Button.svelte'
|
|
15
|
+
import Tabs from './Tabs.svelte'
|
|
16
|
+
import { PersistedState } from 'runed'
|
|
17
|
+
import ToggleGroup from '../ToggleGroup.svelte'
|
|
18
|
+
|
|
19
|
+
const { invalidate } = useThrelte()
|
|
20
|
+
const partID = usePartID()
|
|
21
|
+
const cameras = useResourceNames(() => partID.current, 'camera')
|
|
22
|
+
const visionServices = useResourceNames(() => partID.current, 'vision')
|
|
23
|
+
const settings = useSettings()
|
|
24
|
+
const { disabledCameras, disabledVisionServices } = useMachineSettings()
|
|
25
|
+
const geometries = useGeometries()
|
|
26
|
+
const pointclouds = usePointClouds()
|
|
27
|
+
const { refetchPoses } = useRefetchPoses()
|
|
28
|
+
|
|
29
|
+
// Invalidate the renderer for any settings change
|
|
30
|
+
$effect(() => {
|
|
31
|
+
for (const key in settings.current) {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
33
|
+
settings.current[key as keyof typeof settings.current]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
invalidate()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const isOpen = new PersistedState('settings-is-open', false)
|
|
40
|
+
const activeTab = new PersistedState('settings-active-tab', 'Connection')
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<Portal id="dashboard">
|
|
44
|
+
<fieldset>
|
|
45
|
+
<DashboardButton
|
|
46
|
+
active
|
|
47
|
+
icon="cog"
|
|
48
|
+
description="Settings"
|
|
49
|
+
onclick={() => {
|
|
50
|
+
isOpen.current = !isOpen.current
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
</fieldset>
|
|
54
|
+
</Portal>
|
|
55
|
+
|
|
56
|
+
{#snippet SectionTitle(title: string)}
|
|
57
|
+
<h3 class="border-gray-3 border-b py-1 text-sm"><strong>{title}</strong></h3>
|
|
58
|
+
{/snippet}
|
|
59
|
+
|
|
60
|
+
{#snippet Connection()}
|
|
61
|
+
<div class="flex flex-col gap-2.5 text-xs">
|
|
62
|
+
{@render SectionTitle('Polling rates')}
|
|
63
|
+
|
|
64
|
+
<RefreshRate
|
|
65
|
+
id={RefreshRates.poses}
|
|
66
|
+
label="Poses"
|
|
67
|
+
allowLive
|
|
68
|
+
onManualRefetch={() => {
|
|
69
|
+
refetchPoses()
|
|
70
|
+
geometries.refetch()
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
<RefreshRate
|
|
74
|
+
id={RefreshRates.pointclouds}
|
|
75
|
+
label="Pointclouds"
|
|
76
|
+
onManualRefetch={() => {
|
|
77
|
+
pointclouds.refetch()
|
|
78
|
+
}}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
{/snippet}
|
|
82
|
+
|
|
83
|
+
{#snippet Pointclouds()}
|
|
84
|
+
<div class="flex flex-col gap-1 text-xs">
|
|
85
|
+
<label class="flex items-center justify-between gap-2">
|
|
86
|
+
Default point size
|
|
87
|
+
|
|
88
|
+
<div class="w-20">
|
|
89
|
+
<Input
|
|
90
|
+
bind:value={settings.current.pointSize}
|
|
91
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
</label>
|
|
95
|
+
|
|
96
|
+
<label class="flex items-center justify-between gap-2">
|
|
97
|
+
Default point color
|
|
98
|
+
|
|
99
|
+
<div class="w-20">
|
|
100
|
+
<Input
|
|
101
|
+
type="color"
|
|
102
|
+
bind:value={settings.current.pointColor}
|
|
103
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
104
|
+
/>
|
|
105
|
+
</div>
|
|
106
|
+
</label>
|
|
107
|
+
|
|
108
|
+
{@render SectionTitle('Enabled cameras')}
|
|
109
|
+
|
|
110
|
+
{#each cameras.current as camera (camera)}
|
|
111
|
+
<div class="flex items-center justify-between py-0.5 text-xs">
|
|
112
|
+
{camera.name}
|
|
113
|
+
<Switch
|
|
114
|
+
on={disabledCameras.get(camera.name) !== true}
|
|
115
|
+
on:change={(event) => {
|
|
116
|
+
disabledCameras.set(camera.name, !event.detail)
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
{:else}
|
|
121
|
+
No cameras detected
|
|
122
|
+
{/each}
|
|
123
|
+
</div>
|
|
124
|
+
{/snippet}
|
|
125
|
+
|
|
126
|
+
{#snippet Vision()}
|
|
127
|
+
<div class="text-gray-9 flex flex-col gap-1 text-xs">
|
|
128
|
+
{@render SectionTitle('Enabled vision services')}
|
|
129
|
+
|
|
130
|
+
{#each visionServices.current as visionService (visionService)}
|
|
131
|
+
<div class="flex items-center justify-between py-0.5">
|
|
132
|
+
{visionService.name}
|
|
133
|
+
<Switch
|
|
134
|
+
on={disabledVisionServices.get(visionService.name) !== true}
|
|
135
|
+
on:change={(event) => {
|
|
136
|
+
disabledVisionServices.set(visionService.name, !event.detail)
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
{:else}
|
|
141
|
+
No vision services detected
|
|
142
|
+
{/each}
|
|
143
|
+
</div>
|
|
144
|
+
{/snippet}
|
|
145
|
+
|
|
146
|
+
{#snippet Scene()}
|
|
147
|
+
<div class="text-gray-9 flex flex-col gap-1 text-xs">
|
|
148
|
+
<label class="flex items-center justify-between gap-2 py-1">
|
|
149
|
+
Arm Models
|
|
150
|
+
|
|
151
|
+
<ToggleGroup
|
|
152
|
+
multiple
|
|
153
|
+
options={[
|
|
154
|
+
{
|
|
155
|
+
label: 'Colliders',
|
|
156
|
+
value: 'colliders',
|
|
157
|
+
selected: settings.current.renderArmModels.includes('colliders'),
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
label: 'Model',
|
|
161
|
+
value: 'model',
|
|
162
|
+
selected: settings.current.renderArmModels.includes('model'),
|
|
163
|
+
},
|
|
164
|
+
]}
|
|
165
|
+
onSelect={(value) => {
|
|
166
|
+
settings.current.renderArmModels = (value.join('+') || 'colliders') as
|
|
167
|
+
| 'colliders'
|
|
168
|
+
| 'model'
|
|
169
|
+
| 'colliders+model'
|
|
170
|
+
|
|
171
|
+
console.log(settings.current.renderArmModels)
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
</label>
|
|
175
|
+
|
|
176
|
+
<label class="flex items-center justify-between gap-2">
|
|
177
|
+
Single item hover details <Switch bind:on={settings.current.renderSubEntityHoverDetail} />
|
|
178
|
+
</label>
|
|
179
|
+
|
|
180
|
+
<label class="flex items-center justify-between gap-2">
|
|
181
|
+
Object labels <Switch bind:on={settings.current.enableLabels} />
|
|
182
|
+
</label>
|
|
183
|
+
|
|
184
|
+
{@render SectionTitle('Grid')}
|
|
185
|
+
|
|
186
|
+
<label class="flex items-center justify-between gap-2 py-1">
|
|
187
|
+
Visible <Switch bind:on={settings.current.grid} />
|
|
188
|
+
</label>
|
|
189
|
+
|
|
190
|
+
<label class="flex items-center justify-between gap-2">
|
|
191
|
+
Cell size (m)
|
|
192
|
+
|
|
193
|
+
<div class="w-20">
|
|
194
|
+
<Input
|
|
195
|
+
bind:value={settings.current.gridCellSize}
|
|
196
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
197
|
+
/>
|
|
198
|
+
</div>
|
|
199
|
+
</label>
|
|
200
|
+
|
|
201
|
+
<label class="flex items-center justify-between gap-2">
|
|
202
|
+
Section size (m)
|
|
203
|
+
|
|
204
|
+
<div class="w-20">
|
|
205
|
+
<Input
|
|
206
|
+
bind:value={settings.current.gridSectionSize}
|
|
207
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
210
|
+
</label>
|
|
211
|
+
|
|
212
|
+
<label class="flex items-center justify-between gap-2">
|
|
213
|
+
Fade distance (m)
|
|
214
|
+
|
|
215
|
+
<div class="w-20">
|
|
216
|
+
<Input
|
|
217
|
+
bind:value={settings.current.gridFadeDistance}
|
|
218
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
221
|
+
</label>
|
|
222
|
+
|
|
223
|
+
{@render SectionTitle('Lines')}
|
|
224
|
+
|
|
225
|
+
<label class="flex items-center justify-between gap-2">
|
|
226
|
+
Thickness
|
|
227
|
+
|
|
228
|
+
<div class="w-20">
|
|
229
|
+
<Input
|
|
230
|
+
bind:value={settings.current.lineWidth}
|
|
231
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
232
|
+
/>
|
|
233
|
+
</div>
|
|
234
|
+
</label>
|
|
235
|
+
|
|
236
|
+
<label class="flex items-center justify-between gap-2">
|
|
237
|
+
Dot size
|
|
238
|
+
|
|
239
|
+
<div class="w-20">
|
|
240
|
+
<Input
|
|
241
|
+
bind:value={settings.current.lineDotSize}
|
|
242
|
+
on:keydown={(event) => event.stopImmediatePropagation()}
|
|
243
|
+
/>
|
|
244
|
+
</div>
|
|
245
|
+
</label>
|
|
246
|
+
</div>
|
|
247
|
+
{/snippet}
|
|
248
|
+
|
|
249
|
+
{#snippet Stats()}
|
|
250
|
+
<div class="flex w-full flex-col gap-2.5 text-xs">
|
|
251
|
+
<label class="flex items-center justify-between gap-2">
|
|
252
|
+
Query devtools <Switch bind:on={settings.current.enableQueryDevtools} />
|
|
253
|
+
</label>
|
|
254
|
+
|
|
255
|
+
<label class="flex items-center justify-between gap-2">
|
|
256
|
+
Render stats <Switch bind:on={settings.current.renderStats} />
|
|
257
|
+
</label>
|
|
258
|
+
</div>
|
|
259
|
+
{/snippet}
|
|
260
|
+
|
|
261
|
+
<FloatingPanel
|
|
262
|
+
title="Settings"
|
|
263
|
+
bind:isOpen={isOpen.current}
|
|
264
|
+
defaultSize={{ width: 460, height: 500 }}
|
|
265
|
+
>
|
|
266
|
+
<Tabs
|
|
267
|
+
defaultTab={activeTab.current}
|
|
268
|
+
items={[
|
|
269
|
+
{ label: 'Connection', content: Connection },
|
|
270
|
+
{ label: 'Scene', content: Scene },
|
|
271
|
+
{ label: 'Pointclouds', content: Pointclouds },
|
|
272
|
+
{ label: 'Vision', content: Vision },
|
|
273
|
+
{ label: 'Stats', content: Stats },
|
|
274
|
+
]}
|
|
275
|
+
onValueChange={(value) => {
|
|
276
|
+
activeTab.current = value
|
|
277
|
+
}}
|
|
278
|
+
/>
|
|
279
|
+
</FloatingPanel>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
3
|
+
import * as tabs from '@zag-js/tabs'
|
|
4
|
+
import { useMachine, normalizeProps } from '@zag-js/svelte'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
defaultTab?: string
|
|
8
|
+
onValueChange: (value: string) => void
|
|
9
|
+
items: {
|
|
10
|
+
label: string
|
|
11
|
+
content: Snippet
|
|
12
|
+
}[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let { defaultTab, items, onValueChange }: Props = $props()
|
|
16
|
+
|
|
17
|
+
const id = $props.id()
|
|
18
|
+
const service = useMachine(tabs.machine, () => ({
|
|
19
|
+
id,
|
|
20
|
+
defaultValue: defaultTab,
|
|
21
|
+
onValueChange: (details) => onValueChange(details.value),
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
const api = $derived(tabs.connect(service, normalizeProps))
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<div
|
|
28
|
+
{...api.getRootProps()}
|
|
29
|
+
class="flex h-full gap-2 overflow-hidden"
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
{...api.getListProps()}
|
|
33
|
+
class="bg-gray-1 flex h-full flex-col items-start p-2 text-sm"
|
|
34
|
+
>
|
|
35
|
+
{#each items as item (item.label)}
|
|
36
|
+
<button
|
|
37
|
+
{...api.getTriggerProps({ value: item.label })}
|
|
38
|
+
class="text-gray-8 w-full py-1 pr-8 pl-3 text-left"
|
|
39
|
+
class:bg-gray-2={api.focusedValue === item.label}
|
|
40
|
+
>
|
|
41
|
+
{item.label}
|
|
42
|
+
</button>
|
|
43
|
+
{/each}
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
{#each items as item (item.label)}
|
|
47
|
+
<div
|
|
48
|
+
{...api.getContentProps({ value: item.label })}
|
|
49
|
+
class="h-full w-full overflow-y-auto p-4"
|
|
50
|
+
>
|
|
51
|
+
{@render item.content()}
|
|
52
|
+
</div>
|
|
53
|
+
{/each}
|
|
54
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
defaultTab?: string;
|
|
4
|
+
onValueChange: (value: string) => void;
|
|
5
|
+
items: {
|
|
6
|
+
label: string;
|
|
7
|
+
content: Snippet;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
declare const Tabs: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Tabs = ReturnType<typeof Tabs>;
|
|
12
|
+
export default Tabs;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { draggable } from '@neodrag/svelte'
|
|
3
|
-
import { formatNumeric } from '
|
|
4
|
-
import Table from '../
|
|
5
|
-
import { useArmClient } from '
|
|
3
|
+
import { formatNumeric } from '../../../format'
|
|
4
|
+
import Table from '../Table.svelte'
|
|
5
|
+
import { useArmClient } from '../../../hooks/useArmClient.svelte'
|
|
6
6
|
import { Icon, Label, Select } from '@viamrobotics/prime-core'
|
|
7
7
|
|
|
8
8
|
const { ...rest } = $props()
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
</script>
|
|
18
18
|
|
|
19
19
|
<div
|
|
20
|
-
class="bg-extralight border-medium absolute top-0 left-0 z-
|
|
20
|
+
class="bg-extralight border-medium absolute top-0 left-0 z-4 m-2 overflow-y-auto border text-xs"
|
|
21
21
|
use:draggable={{
|
|
22
22
|
bounds: 'body',
|
|
23
23
|
handle: dragElement,
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import { Icon, Select } from '@viamrobotics/prime-core'
|
|
4
4
|
import { CameraStream, useRobotClient } from '@viamrobotics/svelte-sdk'
|
|
5
5
|
import { StreamClient } from '@viamrobotics/sdk'
|
|
6
|
-
import { useSettings } from '
|
|
7
|
-
import { usePartID } from '
|
|
8
|
-
import { useEnvironment } from '
|
|
6
|
+
import { useSettings } from '../../../hooks/useSettings.svelte'
|
|
7
|
+
import { usePartID } from '../../../hooks/usePartID.svelte'
|
|
8
|
+
import { useEnvironment } from '../../../hooks/useEnvironment.svelte'
|
|
9
9
|
|
|
10
10
|
interface Resolution {
|
|
11
11
|
width: number
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
</script>
|
|
108
108
|
|
|
109
109
|
<div
|
|
110
|
-
class="bg-extralight border-medium absolute top-0 left-0 z-
|
|
110
|
+
class="bg-extralight border-medium absolute top-0 left-0 z-4 m-2 flex resize-x flex-col overflow-hidden border text-xs"
|
|
111
111
|
style:width="320px"
|
|
112
112
|
style:height="auto !important"
|
|
113
113
|
use:draggable={{
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
<!-- FPS Pill -->
|
|
177
177
|
{#if fps > 0}
|
|
178
178
|
<div
|
|
179
|
-
class="absolute bottom-2 left-2 z-
|
|
179
|
+
class="absolute bottom-2 left-2 z-4 rounded-[3px] bg-black/30 px-1 py-0.5 text-right font-mono text-xs text-white"
|
|
180
180
|
>
|
|
181
181
|
{fps.toFixed(1)}fps
|
|
182
182
|
</div>
|
package/dist/ecs/index.d.ts
CHANGED
package/dist/ecs/index.js
CHANGED
package/dist/ecs/traits.d.ts
CHANGED
|
@@ -30,12 +30,17 @@ export declare const Center: import("koota").Trait<{
|
|
|
30
30
|
oZ: number;
|
|
31
31
|
theta: number;
|
|
32
32
|
}>;
|
|
33
|
-
export declare const
|
|
34
|
-
index: number;
|
|
33
|
+
export declare const InstancedPose: import("koota").Trait<{
|
|
35
34
|
x: number;
|
|
36
35
|
y: number;
|
|
37
36
|
z: number;
|
|
37
|
+
oX: number;
|
|
38
|
+
oY: number;
|
|
39
|
+
oZ: number;
|
|
40
|
+
theta: number;
|
|
41
|
+
index: number;
|
|
38
42
|
}>;
|
|
43
|
+
export declare const Hovered: import("koota").Trait<() => boolean>;
|
|
39
44
|
/**
|
|
40
45
|
* Represents that an entity is composed of many instances, so that the treeview and
|
|
41
46
|
* details panel may display all instances
|
|
@@ -123,6 +128,7 @@ export declare const SnapshotAPI: import("koota").Trait<() => boolean>;
|
|
|
123
128
|
* Marker trait for entities created from user-dropped files (PLY, PCD, etc.)
|
|
124
129
|
*/
|
|
125
130
|
export declare const DroppedFile: import("koota").Trait<() => boolean>;
|
|
131
|
+
export declare const ShowAxesHelper: import("koota").Trait<() => boolean>;
|
|
126
132
|
/**
|
|
127
133
|
* Point size, in mm
|
|
128
134
|
*/
|
package/dist/ecs/traits.js
CHANGED
|
@@ -8,12 +8,17 @@ export const Parent = trait(() => 'world');
|
|
|
8
8
|
export const Pose = trait({ x: 0, y: 0, z: 0, oX: 0, oY: 0, oZ: 1, theta: 0 });
|
|
9
9
|
export const EditedPose = trait({ x: 0, y: 0, z: 0, oX: 0, oY: 0, oZ: 1, theta: 0 });
|
|
10
10
|
export const Center = trait({ x: 0, y: 0, z: 0, oX: 0, oY: 0, oZ: 1, theta: 0 });
|
|
11
|
-
export const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export const InstancedPose = trait({
|
|
12
|
+
x: 0,
|
|
13
|
+
y: 0,
|
|
14
|
+
z: 0,
|
|
15
|
+
oX: 0,
|
|
16
|
+
oY: 0,
|
|
17
|
+
oZ: 1,
|
|
18
|
+
theta: 0,
|
|
19
|
+
index: -1,
|
|
16
20
|
});
|
|
21
|
+
export const Hovered = trait(() => true);
|
|
17
22
|
/**
|
|
18
23
|
* Represents that an entity is composed of many instances, so that the treeview and
|
|
19
24
|
* details panel may display all instances
|
|
@@ -74,6 +79,7 @@ export const SnapshotAPI = trait(() => true);
|
|
|
74
79
|
* Marker trait for entities created from user-dropped files (PLY, PCD, etc.)
|
|
75
80
|
*/
|
|
76
81
|
export const DroppedFile = trait(() => true);
|
|
82
|
+
export const ShowAxesHelper = trait(() => true);
|
|
77
83
|
// === Shape Properties ===
|
|
78
84
|
/**
|
|
79
85
|
* Point size, in mm
|
|
@@ -149,7 +149,7 @@ export const provideDrawAPI = () => {
|
|
|
149
149
|
if (frame.geometry) {
|
|
150
150
|
entityTraits.push(geometryTrait());
|
|
151
151
|
}
|
|
152
|
-
entityTraits.push(traits.Name(name), traits.Pose(pose), traits.DrawAPI, traits.ReferenceFrame, traits.Removable);
|
|
152
|
+
entityTraits.push(traits.Name(name), traits.Pose(pose), traits.DrawAPI, traits.ReferenceFrame, traits.Removable, traits.ShowAxesHelper);
|
|
153
153
|
const entity = world.spawn(...entityTraits);
|
|
154
154
|
entities.set(name, entity);
|
|
155
155
|
}
|
|
@@ -9,7 +9,7 @@ import { useResourceByName } from './useResourceByName.svelte';
|
|
|
9
9
|
import { traits, useWorld } from '../ecs';
|
|
10
10
|
import {} from 'koota';
|
|
11
11
|
import { createPose } from '../transform';
|
|
12
|
-
import { RefetchRates } from '../components/RefreshRate.svelte';
|
|
12
|
+
import { RefetchRates } from '../components/overlay/RefreshRate.svelte';
|
|
13
13
|
import { useEnvironment } from './useEnvironment.svelte';
|
|
14
14
|
const key = Symbol('geometries-context');
|
|
15
15
|
const colorUtil = new Color();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
import { relations, useWorld } from '../ecs';
|
|
3
|
+
import { useFocusedEntity, useSelectedEntity } from './useSelection.svelte';
|
|
4
|
+
const linkedKey = Symbol('linked-context');
|
|
5
|
+
export const provideLinkedEntities = () => {
|
|
6
|
+
const world = useWorld();
|
|
7
|
+
const selectedEntity = useSelectedEntity();
|
|
8
|
+
const focusedEntity = useFocusedEntity();
|
|
9
|
+
const displayEntity = $derived(selectedEntity.current ?? focusedEntity.current);
|
|
10
|
+
let linkedEntities = $derived(displayEntity?.targetsFor(relations.SubEntityLink) ?? []);
|
|
11
|
+
const unsubAdd = world.onAdd(relations.SubEntityLink, (entity, target) => {
|
|
12
|
+
if (entity === displayEntity) {
|
|
13
|
+
linkedEntities = [...linkedEntities, target];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const unsubRemove = world.onRemove(relations.SubEntityLink, (entity, target) => {
|
|
17
|
+
if (entity === displayEntity) {
|
|
18
|
+
linkedEntities = linkedEntities.filter((e) => e !== target);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
$effect(() => {
|
|
22
|
+
return () => {
|
|
23
|
+
unsubAdd();
|
|
24
|
+
unsubRemove();
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
setContext(linkedKey, {
|
|
28
|
+
get current() {
|
|
29
|
+
return linkedEntities;
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
export const useLinkedEntities = () => {
|
|
34
|
+
return getContext(linkedKey);
|
|
35
|
+
};
|
|
@@ -3,6 +3,7 @@ import { useFocusedEntity, useSelectedEntity } from './useSelection.svelte';
|
|
|
3
3
|
import { useVisibility } from './useVisibility.svelte';
|
|
4
4
|
import { Vector2 } from 'three';
|
|
5
5
|
import { traits } from '../ecs';
|
|
6
|
+
import { updateHoverInfo } from '../HoverUpdater.svelte';
|
|
6
7
|
export const useObjectEvents = (entity) => {
|
|
7
8
|
const down = new Vector2();
|
|
8
9
|
const selectedEntity = useSelectedEntity();
|
|
@@ -14,31 +15,49 @@ export const useObjectEvents = (entity) => {
|
|
|
14
15
|
const onpointerenter = (event) => {
|
|
15
16
|
event.stopPropagation();
|
|
16
17
|
cursor.onPointerEnter();
|
|
17
|
-
if (currentEntity && !currentEntity.has(traits.
|
|
18
|
-
currentEntity
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
if (currentEntity && !currentEntity.has(traits.Hovered)) {
|
|
19
|
+
const hoverInfo = updateHoverInfo(currentEntity, event);
|
|
20
|
+
if (hoverInfo) {
|
|
21
|
+
currentEntity.add(traits.InstancedPose({
|
|
22
|
+
index: hoverInfo.index,
|
|
23
|
+
x: hoverInfo.x,
|
|
24
|
+
y: hoverInfo.y,
|
|
25
|
+
z: hoverInfo.z,
|
|
26
|
+
oX: hoverInfo.oX,
|
|
27
|
+
oY: hoverInfo.oY,
|
|
28
|
+
oZ: hoverInfo.oZ,
|
|
29
|
+
theta: hoverInfo.theta,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
currentEntity.add(traits.Hovered);
|
|
24
33
|
}
|
|
25
34
|
};
|
|
26
35
|
const onpointermove = (event) => {
|
|
27
36
|
event.stopPropagation();
|
|
28
|
-
if (currentEntity && currentEntity.has(traits.
|
|
29
|
-
currentEntity
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
if (currentEntity && currentEntity.has(traits.Hovered)) {
|
|
38
|
+
const hoverInfo = updateHoverInfo(currentEntity, event);
|
|
39
|
+
if (hoverInfo) {
|
|
40
|
+
currentEntity.set(traits.InstancedPose, {
|
|
41
|
+
index: hoverInfo.index,
|
|
42
|
+
x: hoverInfo.x,
|
|
43
|
+
y: hoverInfo.y,
|
|
44
|
+
z: hoverInfo.z,
|
|
45
|
+
oX: hoverInfo.oX,
|
|
46
|
+
oY: hoverInfo.oY,
|
|
47
|
+
oZ: hoverInfo.oZ,
|
|
48
|
+
theta: hoverInfo.theta,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
35
51
|
}
|
|
36
52
|
};
|
|
37
53
|
const onpointerleave = (event) => {
|
|
38
54
|
event.stopPropagation();
|
|
39
55
|
cursor.onPointerLeave();
|
|
40
|
-
if (currentEntity?.has(traits.
|
|
41
|
-
currentEntity.remove(traits.
|
|
56
|
+
if (currentEntity?.has(traits.Hovered)) {
|
|
57
|
+
currentEntity.remove(traits.Hovered);
|
|
58
|
+
}
|
|
59
|
+
if (currentEntity?.has(traits.InstancedPose)) {
|
|
60
|
+
currentEntity.remove(traits.InstancedPose);
|
|
42
61
|
}
|
|
43
62
|
};
|
|
44
63
|
const ondblclick = (event) => {
|
|
@@ -7,7 +7,7 @@ import { getContext, setContext } from 'svelte';
|
|
|
7
7
|
import { traits, useWorld } from '../ecs';
|
|
8
8
|
import { createBufferGeometry, updateBufferGeometry } from '../attribute';
|
|
9
9
|
import { useEnvironment } from './useEnvironment.svelte';
|
|
10
|
-
import { RefetchRates } from '../components/RefreshRate.svelte';
|
|
10
|
+
import { RefetchRates } from '../components/overlay/RefreshRate.svelte';
|
|
11
11
|
import { createPose } from '../transform';
|
|
12
12
|
const key = Symbol('pointcloud-object-context');
|
|
13
13
|
export const providePointcloudObjects = (partID) => {
|