@viamrobotics/motion-tools 1.32.0 → 1.33.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.
Files changed (75) hide show
  1. package/dist/components/App.svelte +17 -11
  2. package/dist/components/App.svelte.d.ts +14 -7
  3. package/dist/components/Scene.svelte +40 -47
  4. package/dist/components/SceneProviders.svelte +0 -3
  5. package/dist/components/overlay/settings/ConnectionSettings.svelte +42 -0
  6. package/dist/components/overlay/settings/ConnectionSettings.svelte.d.ts +18 -0
  7. package/dist/components/overlay/settings/DebugSettings.svelte +13 -0
  8. package/dist/components/{xr/frame-configure/Controllers.svelte.d.ts → overlay/settings/DebugSettings.svelte.d.ts} +3 -3
  9. package/dist/components/overlay/settings/PointcloudSettings.svelte +61 -0
  10. package/dist/components/overlay/settings/PointcloudSettings.svelte.d.ts +3 -0
  11. package/dist/components/overlay/settings/SceneSettings.svelte +110 -0
  12. package/dist/components/overlay/settings/SceneSettings.svelte.d.ts +18 -0
  13. package/dist/components/overlay/settings/Settings.svelte +27 -312
  14. package/dist/components/overlay/settings/Settings.svelte.d.ts +8 -1
  15. package/dist/components/overlay/settings/Tabs.svelte +5 -3
  16. package/dist/components/overlay/settings/Tabs.svelte.d.ts +3 -3
  17. package/dist/components/overlay/settings/VisionSettings.svelte +31 -0
  18. package/dist/components/overlay/settings/VisionSettings.svelte.d.ts +3 -0
  19. package/dist/components/overlay/settings/WeblabSettings.svelte +27 -0
  20. package/dist/components/overlay/settings/WeblabSettings.svelte.d.ts +18 -0
  21. package/dist/components/overlay/settings/WidgetSettings.svelte +49 -0
  22. package/dist/components/overlay/settings/WidgetSettings.svelte.d.ts +3 -0
  23. package/dist/components/overlay/widgets/FramePov.svelte +1 -12
  24. package/dist/{components/xr → plugins/XR}/ArmTeleop.svelte +3 -5
  25. package/dist/plugins/XR/DebugPanel.svelte +29 -0
  26. package/dist/plugins/XR/DebugPanel.svelte.d.ts +3 -0
  27. package/dist/plugins/XR/OriginMarker.svelte +341 -0
  28. package/dist/plugins/XR/PendingEditsPanel.svelte +60 -0
  29. package/dist/plugins/XR/PendingEditsPanel.svelte.d.ts +18 -0
  30. package/dist/plugins/XR/WristDisplay.svelte +60 -0
  31. package/dist/plugins/XR/WristDisplay.svelte.d.ts +19 -0
  32. package/dist/{components/xr → plugins/XR}/XR.svelte +69 -23
  33. package/dist/plugins/XR/XRPlugins.svelte +9 -0
  34. package/dist/plugins/XR/XRPlugins.svelte.d.ts +26 -0
  35. package/dist/plugins/XR/XRSettings.svelte +240 -0
  36. package/dist/plugins/XR/XRSettings.svelte.d.ts +3 -0
  37. package/dist/{components/xr → plugins/XR}/XRToast.svelte +6 -9
  38. package/dist/plugins/XR/debug.svelte.d.ts +7 -0
  39. package/dist/plugins/XR/debug.svelte.js +13 -0
  40. package/dist/plugins/XR/frame-configure/Controllers.svelte +413 -0
  41. package/dist/plugins/XR/teleop/Controllers.svelte.d.ts +3 -0
  42. package/dist/{components/xr → plugins/XR}/useAnchors.svelte.d.ts +4 -0
  43. package/dist/{components/xr → plugins/XR}/useAnchors.svelte.js +22 -0
  44. package/dist/plugins/XR/useOrigin.svelte.d.ts +24 -0
  45. package/dist/plugins/XR/useOrigin.svelte.js +50 -0
  46. package/dist/plugins/index.d.ts +2 -0
  47. package/dist/plugins/index.js +2 -0
  48. package/dist/three/OBBHelper.js +1 -0
  49. package/package.json +1 -1
  50. package/dist/components/xr/OriginMarker.svelte +0 -151
  51. package/dist/components/xr/XRControllerSettings.svelte +0 -242
  52. package/dist/components/xr/XRControllerSettings.svelte.d.ts +0 -3
  53. package/dist/components/xr/frame-configure/Controllers.svelte +0 -6
  54. package/dist/components/xr/useOrigin.svelte.d.ts +0 -9
  55. package/dist/components/xr/useOrigin.svelte.js +0 -27
  56. /package/dist/{components/xr → plugins/XR}/ArmTeleop.svelte.d.ts +0 -0
  57. /package/dist/{components/xr → plugins/XR}/BentPlaneGeometry.svelte +0 -0
  58. /package/dist/{components/xr → plugins/XR}/BentPlaneGeometry.svelte.d.ts +0 -0
  59. /package/dist/{components/xr → plugins/XR}/CameraFeed.svelte +0 -0
  60. /package/dist/{components/xr → plugins/XR}/CameraFeed.svelte.d.ts +0 -0
  61. /package/dist/{components/xr → plugins/XR}/JointLimitsWidget.svelte +0 -0
  62. /package/dist/{components/xr → plugins/XR}/JointLimitsWidget.svelte.d.ts +0 -0
  63. /package/dist/{components/xr → plugins/XR}/OriginMarker.svelte.d.ts +0 -0
  64. /package/dist/{components/xr → plugins/XR}/PointDistance.svelte +0 -0
  65. /package/dist/{components/xr → plugins/XR}/PointDistance.svelte.d.ts +0 -0
  66. /package/dist/{components/xr → plugins/XR}/XR.svelte.d.ts +0 -0
  67. /package/dist/{components/xr → plugins/XR}/XRConfigPanel.svelte +0 -0
  68. /package/dist/{components/xr → plugins/XR}/XRConfigPanel.svelte.d.ts +0 -0
  69. /package/dist/{components/xr → plugins/XR}/XRToast.svelte.d.ts +0 -0
  70. /package/dist/{components/xr/teleop → plugins/XR/frame-configure}/Controllers.svelte.d.ts +0 -0
  71. /package/dist/{components/xr → plugins/XR}/math.d.ts +0 -0
  72. /package/dist/{components/xr → plugins/XR}/math.js +0 -0
  73. /package/dist/{components/xr → plugins/XR}/teleop/Controllers.svelte +0 -0
  74. /package/dist/{components/xr → plugins/XR}/toasts.svelte.d.ts +0 -0
  75. /package/dist/{components/xr → plugins/XR}/toasts.svelte.js +0 -0
@@ -1,43 +1,34 @@
1
1
  <script lang="ts">
2
+ import type { Component } from 'svelte'
3
+
2
4
  import { useThrelte } from '@threlte/core'
3
5
  import { Portal } from '@threlte/extras'
4
- import { Input, Switch } from '@viamrobotics/prime-core'
5
- import { useResourceNames } from '@viamrobotics/svelte-sdk'
6
6
  import { PersistedState } from 'runed'
7
- import { onMount } from 'svelte'
8
- import { Color } from 'three'
9
7
 
10
8
  import DashboardButton from '../dashboard/Button.svelte'
11
- import XRControllerSettings from '../../xr/XRControllerSettings.svelte'
12
- import { useGeometries } from '../../../hooks/useGeometries.svelte'
13
- import { usePartID } from '../../../hooks/usePartID.svelte'
14
- import { usePointcloudObjects } from '../../../hooks/usePointcloudObjects.svelte'
15
- import { usePointClouds } from '../../../hooks/usePointclouds.svelte'
16
- import { useRefetchPoses } from '../../../hooks/useRefetchPoses'
17
- import { RefreshRates, useSettings } from '../../../hooks/useSettings.svelte'
18
- import { useWeblabs, WEBLABS_EXPERIMENTS } from '../../../hooks/useWeblabs.svelte'
9
+ import { useSettings } from '../../../hooks/useSettings.svelte'
19
10
 
20
11
  import FloatingPanel from '../FloatingPanel.svelte'
21
- import RefreshRate from '../RefreshRate.svelte'
22
- import ToggleGroup from '../ToggleGroup.svelte'
12
+ import ConnectionSettings from './ConnectionSettings.svelte'
13
+ import DebugSettings from './DebugSettings.svelte'
14
+ import PointcloudSettings from './PointcloudSettings.svelte'
15
+ import SceneSettings from './SceneSettings.svelte'
23
16
  import Tabs from './Tabs.svelte'
17
+ import VisionSettings from './VisionSettings.svelte'
18
+ import WeblabSettings from './WeblabSettings.svelte'
19
+ import WidgetSettings from './WidgetSettings.svelte'
20
+
21
+ interface Props {
22
+ settingsTabs?: {
23
+ label: string
24
+ component: Component
25
+ }[]
26
+ }
27
+
28
+ let { settingsTabs = [] }: Props = $props()
24
29
 
25
30
  const { invalidate } = useThrelte()
26
- const partID = usePartID()
27
- const cameras = useResourceNames(() => partID.current, 'camera')
28
- const visionServices = useResourceNames(() => partID.current, 'vision')
29
31
  const settings = useSettings()
30
- const { disabledCameras, disabledVisionServices } = $derived(settings.current)
31
- const geometries = useGeometries()
32
- const pointclouds = usePointClouds()
33
- const pointcloudObjects = usePointcloudObjects()
34
- const { refetchPoses } = useRefetchPoses()
35
- const weblabs = useWeblabs()
36
- const knownWeblabs = Object.keys(WEBLABS_EXPERIMENTS)
37
-
38
- onMount(() => {
39
- weblabs.load(knownWeblabs)
40
- })
41
32
 
42
33
  // Invalidate the renderer for any settings change
43
34
  $effect(() => {
@@ -49,14 +40,8 @@
49
40
  invalidate()
50
41
  })
51
42
 
52
- const currentRobotCameraWidgets = $derived(
53
- settings.current.openCameraWidgets[partID.current] || []
54
- )
55
-
56
43
  const isOpen = new PersistedState('settings-is-open', false)
57
44
  const activeTab = new PersistedState('settings-active-tab', 'Connection')
58
-
59
- const colorHex = $derived(`#${new Color(settings.current.pointColor).getHexString()}`)
60
45
  </script>
61
46
 
62
47
  <Portal id="dashboard">
@@ -72,276 +57,6 @@
72
57
  </fieldset>
73
58
  </Portal>
74
59
 
75
- {#snippet SectionTitle(title: string)}
76
- <h3 class="border-gray-3 border-b py-1 text-sm"><strong>{title}</strong></h3>
77
- {/snippet}
78
-
79
- {#snippet Connection()}
80
- <div class="flex flex-col gap-2.5 text-xs">
81
- {@render SectionTitle('Polling rates')}
82
-
83
- <RefreshRate
84
- id={RefreshRates.poses}
85
- label="Poses"
86
- allowLive
87
- onManualRefetch={() => {
88
- refetchPoses()
89
- geometries.refetch()
90
- }}
91
- />
92
- <RefreshRate
93
- id={RefreshRates.pointclouds}
94
- label="Pointclouds from cameras"
95
- onManualRefetch={() => {
96
- pointclouds.refetch()
97
- }}
98
- />
99
- <RefreshRate
100
- id={RefreshRates.vision}
101
- label="Vision service pointcloud segments and objects"
102
- onManualRefetch={() => {
103
- pointcloudObjects.refetch()
104
- }}
105
- />
106
- </div>
107
- {/snippet}
108
-
109
- {#snippet Pointclouds()}
110
- <div class="flex flex-col gap-1 text-xs">
111
- <label class="flex items-center justify-between gap-2">
112
- Default point size
113
-
114
- <div class="w-20">
115
- <Input
116
- bind:value={settings.current.pointSize}
117
- on:keydown={(event) => event.stopImmediatePropagation()}
118
- />
119
- </div>
120
- </label>
121
-
122
- <label class="flex items-center justify-between gap-2">
123
- Default point color
124
-
125
- <div class="w-20">
126
- <Input
127
- type="color"
128
- value={colorHex}
129
- on:change={(event) => {
130
- const value = (event.target as HTMLInputElement).value
131
- settings.current.pointColor = value
132
- }}
133
- on:keydown={(event) => event.stopImmediatePropagation()}
134
- />
135
- </div>
136
- </label>
137
-
138
- {@render SectionTitle('Enabled cameras')}
139
-
140
- {#each cameras.current as camera (camera)}
141
- <div class="flex items-center justify-between py-0.5 text-xs">
142
- {camera.name}
143
- <Switch
144
- on={disabledCameras[camera.name] !== true}
145
- on:change={(event) => {
146
- disabledCameras[camera.name] = !event.detail
147
- }}
148
- />
149
- </div>
150
- {:else}
151
- No cameras detected
152
- {/each}
153
- </div>
154
- {/snippet}
155
-
156
- {#snippet Vision()}
157
- <div class="text-gray-9 flex flex-col gap-1 text-xs">
158
- {@render SectionTitle('Enabled vision services')}
159
-
160
- {#each visionServices.current as visionService (visionService)}
161
- <div class="flex items-center justify-between py-0.5">
162
- {visionService.name}
163
- <Switch
164
- on={disabledVisionServices[visionService.name] !== true}
165
- on:change={(event) => {
166
- disabledVisionServices[visionService.name] = !event.detail
167
- }}
168
- />
169
- </div>
170
- {:else}
171
- No vision services detected
172
- {/each}
173
- </div>
174
- {/snippet}
175
-
176
- {#snippet Scene()}
177
- <div class="text-gray-9 flex flex-col gap-1 text-xs">
178
- <label class="flex items-center justify-between gap-2 py-1">
179
- Arm Models
180
-
181
- <ToggleGroup
182
- multiple
183
- options={[
184
- {
185
- label: 'Colliders',
186
- value: 'colliders',
187
- selected: settings.current.renderArmModels.includes('colliders'),
188
- },
189
- {
190
- label: 'Model',
191
- value: 'model',
192
- selected: settings.current.renderArmModels.includes('model'),
193
- },
194
- ]}
195
- onSelect={(value) => {
196
- settings.current.renderArmModels = (value.join('+') || 'colliders') as
197
- | 'colliders'
198
- | 'model'
199
- | 'colliders+model'
200
-
201
- console.log(settings.current.renderArmModels)
202
- }}
203
- />
204
- </label>
205
-
206
- <label class="flex items-center justify-between gap-2">
207
- Single item hover details <Switch bind:on={settings.current.renderSubEntityHoverDetail} />
208
- </label>
209
-
210
- <label class="flex items-center justify-between gap-2">
211
- Object labels <Switch bind:on={settings.current.enableLabels} />
212
- </label>
213
-
214
- {@render SectionTitle('Grid')}
215
-
216
- <label class="flex items-center justify-between gap-2 py-1">
217
- Visible <Switch bind:on={settings.current.grid} />
218
- </label>
219
-
220
- <label class="flex items-center justify-between gap-2">
221
- Cell size (m)
222
-
223
- <div class="w-20">
224
- <Input
225
- bind:value={settings.current.gridCellSize}
226
- on:keydown={(event) => event.stopImmediatePropagation()}
227
- />
228
- </div>
229
- </label>
230
-
231
- <label class="flex items-center justify-between gap-2">
232
- Section size (m)
233
-
234
- <div class="w-20">
235
- <Input
236
- bind:value={settings.current.gridSectionSize}
237
- on:keydown={(event) => event.stopImmediatePropagation()}
238
- />
239
- </div>
240
- </label>
241
-
242
- <label class="flex items-center justify-between gap-2">
243
- Fade distance (m)
244
-
245
- <div class="w-20">
246
- <Input
247
- bind:value={settings.current.gridFadeDistance}
248
- on:keydown={(event) => event.stopImmediatePropagation()}
249
- />
250
- </div>
251
- </label>
252
-
253
- {@render SectionTitle('Lines')}
254
-
255
- <label class="flex items-center justify-between gap-2">
256
- Thickness
257
-
258
- <div class="w-20">
259
- <Input
260
- bind:value={settings.current.lineWidth}
261
- on:keydown={(event) => event.stopImmediatePropagation()}
262
- />
263
- </div>
264
- </label>
265
-
266
- <label class="flex items-center justify-between gap-2">
267
- Dot size
268
-
269
- <div class="w-20">
270
- <Input
271
- bind:value={settings.current.lineDotSize}
272
- on:keydown={(event) => event.stopImmediatePropagation()}
273
- />
274
- </div>
275
- </label>
276
- </div>
277
- {/snippet}
278
-
279
- {#snippet Stats()}
280
- <div class="flex w-full flex-col gap-2.5 text-xs">
281
- <label class="flex items-center justify-between gap-2">
282
- Render stats <Switch bind:on={settings.current.renderStats} />
283
- </label>
284
- </div>
285
- {/snippet}
286
-
287
- {#snippet XR()}
288
- <div class="flex flex-col gap-2.5 text-xs">
289
- <XRControllerSettings />
290
- </div>
291
- {/snippet}
292
-
293
- {#snippet Weblabs()}
294
- <div class="flex flex-col gap-1 text-xs">
295
- {#each knownWeblabs as experiment (experiment)}
296
- <label class="flex items-center justify-between gap-2 py-0.5">
297
- {experiment}
298
- <Switch
299
- on={weblabs.isActive(experiment)}
300
- on:change={() => weblabs.toggle(experiment)}
301
- />
302
- </label>
303
- {:else}
304
- No weblabs defined
305
- {/each}
306
- </div>
307
- {/snippet}
308
-
309
- {#snippet Widgets()}
310
- <div class="text-gray-9 flex flex-col gap-1 text-xs">
311
- <label class="flex items-center justify-between gap-2 py-1">
312
- Arm positions
313
- <Switch bind:on={settings.current.enableArmPositionsWidget} />
314
- </label>
315
-
316
- {@render SectionTitle('Camera widgets')}
317
-
318
- {#each cameras.current as camera (camera)}
319
- {@const isWidgetOpen = currentRobotCameraWidgets.includes(camera.name)}
320
- <div class="flex items-center justify-between gap-2 py-0.5">
321
- <span class="min-w-0 truncate">{camera.name}</span>
322
- <Switch
323
- on={isWidgetOpen}
324
- on:change={(event) => {
325
- settings.current.openCameraWidgets = event.detail
326
- ? {
327
- ...settings.current.openCameraWidgets,
328
- [partID.current]: [...currentRobotCameraWidgets, camera.name],
329
- }
330
- : {
331
- ...settings.current.openCameraWidgets,
332
- [partID.current]: currentRobotCameraWidgets.filter(
333
- (widget) => widget !== camera.name
334
- ),
335
- }
336
- }}
337
- />
338
- </div>
339
- {:else}
340
- No cameras detected
341
- {/each}
342
- </div>
343
- {/snippet}
344
-
345
60
  <FloatingPanel
346
61
  title="Settings"
347
62
  bind:isOpen={isOpen.current}
@@ -350,14 +65,14 @@
350
65
  <Tabs
351
66
  defaultTab={activeTab.current}
352
67
  items={[
353
- { label: 'Connection', content: Connection },
354
- { label: 'Scene', content: Scene },
355
- { label: 'Pointclouds', content: Pointclouds },
356
- { label: 'Vision', content: Vision },
357
- { label: 'Widgets', content: Widgets },
358
- { label: 'Stats', content: Stats },
359
- { label: 'Weblabs', content: Weblabs },
360
- ...('xr' in navigator ? [{ label: 'VR / AR', content: XR }] : []),
68
+ { label: 'Connection', component: ConnectionSettings },
69
+ { label: 'Scene', component: SceneSettings },
70
+ { label: 'Pointclouds', component: PointcloudSettings },
71
+ { label: 'Vision', component: VisionSettings },
72
+ { label: 'Widgets', component: WidgetSettings },
73
+ { label: 'Debug', component: DebugSettings },
74
+ { label: 'Weblabs', component: WeblabSettings },
75
+ ...settingsTabs,
361
76
  ]}
362
77
  onValueChange={(value) => {
363
78
  activeTab.current = value
@@ -1,3 +1,10 @@
1
- declare const Settings: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import type { Component } from 'svelte';
2
+ interface Props {
3
+ settingsTabs?: {
4
+ label: string;
5
+ component: Component;
6
+ }[];
7
+ }
8
+ declare const Settings: Component<Props, {}, "">;
2
9
  type Settings = ReturnType<typeof Settings>;
3
10
  export default Settings;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from 'svelte'
2
+ import type { Component } from 'svelte'
3
3
 
4
4
  import { normalizeProps, useMachine } from '@zag-js/svelte'
5
5
  import * as tabs from '@zag-js/tabs'
@@ -9,7 +9,7 @@
9
9
  onValueChange: (value: string) => void
10
10
  items: {
11
11
  label: string
12
- content: Snippet
12
+ component: Component
13
13
  }[]
14
14
  }
15
15
 
@@ -45,11 +45,13 @@
45
45
  </div>
46
46
 
47
47
  {#each items as item (item.label)}
48
+ {@const Component = item.component}
49
+
48
50
  <div
49
51
  {...api.getContentProps({ value: item.label })}
50
52
  class="h-full w-full overflow-y-auto p-4"
51
53
  >
52
- {@render item.content()}
54
+ <Component />
53
55
  </div>
54
56
  {/each}
55
57
  </div>
@@ -1,12 +1,12 @@
1
- import type { Snippet } from 'svelte';
1
+ import type { Component } from 'svelte';
2
2
  interface Props {
3
3
  defaultTab?: string;
4
4
  onValueChange: (value: string) => void;
5
5
  items: {
6
6
  label: string;
7
- content: Snippet;
7
+ component: Component;
8
8
  }[];
9
9
  }
10
- declare const Tabs: import("svelte").Component<Props, {}, "">;
10
+ declare const Tabs: Component<Props, {}, "">;
11
11
  type Tabs = ReturnType<typeof Tabs>;
12
12
  export default Tabs;
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import { Switch } from '@viamrobotics/prime-core'
3
+ import { useResourceNames } from '@viamrobotics/svelte-sdk'
4
+
5
+ import { usePartID } from '../../../hooks/usePartID.svelte'
6
+ import { useSettings } from '../../../hooks/useSettings.svelte'
7
+
8
+ const partID = usePartID()
9
+
10
+ const visionServices = useResourceNames(() => partID.current, 'vision')
11
+ const settings = useSettings()
12
+ const { disabledVisionServices } = $derived(settings.current)
13
+ </script>
14
+
15
+ <div class="text-gray-9 flex flex-col gap-1 text-xs">
16
+ <h3 class="border-gray-3 border-b py-1 text-sm"><strong>Enabled vision services</strong></h3>
17
+
18
+ {#each visionServices.current as visionService (visionService)}
19
+ <div class="flex items-center justify-between py-0.5">
20
+ {visionService.name}
21
+ <Switch
22
+ on={disabledVisionServices[visionService.name] !== true}
23
+ on:change={(event) => {
24
+ disabledVisionServices[visionService.name] = !event.detail
25
+ }}
26
+ />
27
+ </div>
28
+ {:else}
29
+ No vision services detected
30
+ {/each}
31
+ </div>
@@ -0,0 +1,3 @@
1
+ declare const VisionSettings: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type VisionSettings = ReturnType<typeof VisionSettings>;
3
+ export default VisionSettings;
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import { Switch } from '@viamrobotics/prime-core'
3
+ import { onMount } from 'svelte'
4
+
5
+ import { useWeblabs, WEBLABS_EXPERIMENTS } from '../../../hooks/useWeblabs.svelte'
6
+
7
+ const weblabs = useWeblabs()
8
+ const knownWeblabs = Object.keys(WEBLABS_EXPERIMENTS)
9
+
10
+ onMount(() => {
11
+ weblabs.load(knownWeblabs)
12
+ })
13
+ </script>
14
+
15
+ <div class="flex flex-col gap-1 text-xs">
16
+ {#each knownWeblabs as experiment (experiment)}
17
+ <label class="flex items-center justify-between gap-2 py-0.5">
18
+ {experiment}
19
+ <Switch
20
+ on={weblabs.isActive(experiment)}
21
+ on:change={() => weblabs.toggle(experiment)}
22
+ />
23
+ </label>
24
+ {:else}
25
+ No weblabs defined
26
+ {/each}
27
+ </div>
@@ -0,0 +1,18 @@
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 WeblabSettings: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type WeblabSettings = InstanceType<typeof WeblabSettings>;
18
+ export default WeblabSettings;
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import { Switch } from '@viamrobotics/prime-core'
3
+ import { useResourceNames } from '@viamrobotics/svelte-sdk'
4
+
5
+ import { usePartID } from '../../../hooks/usePartID.svelte'
6
+ import { useSettings } from '../../../hooks/useSettings.svelte'
7
+
8
+ const partID = usePartID()
9
+ const cameras = useResourceNames(() => partID.current, 'camera')
10
+ const settings = useSettings()
11
+
12
+ const currentRobotCameraWidgets = $derived(
13
+ settings.current.openCameraWidgets[partID.current] || []
14
+ )
15
+ </script>
16
+
17
+ <div class="text-gray-9 flex flex-col gap-1 text-xs">
18
+ <label class="flex items-center justify-between gap-2 py-1">
19
+ Arm positions
20
+ <Switch bind:on={settings.current.enableArmPositionsWidget} />
21
+ </label>
22
+
23
+ <h3 class="border-gray-3 border-b py-1 text-sm"><strong>Camera widgets</strong></h3>
24
+
25
+ {#each cameras.current as camera (camera)}
26
+ {@const isWidgetOpen = currentRobotCameraWidgets.includes(camera.name)}
27
+ <div class="flex items-center justify-between gap-2 py-0.5">
28
+ <span class="min-w-0 truncate">{camera.name}</span>
29
+ <Switch
30
+ on={isWidgetOpen}
31
+ on:change={(event) => {
32
+ settings.current.openCameraWidgets = event.detail
33
+ ? {
34
+ ...settings.current.openCameraWidgets,
35
+ [partID.current]: [...currentRobotCameraWidgets, camera.name],
36
+ }
37
+ : {
38
+ ...settings.current.openCameraWidgets,
39
+ [partID.current]: currentRobotCameraWidgets.filter(
40
+ (widget) => widget !== camera.name
41
+ ),
42
+ }
43
+ }}
44
+ />
45
+ </div>
46
+ {:else}
47
+ No cameras detected
48
+ {/each}
49
+ </div>
@@ -0,0 +1,3 @@
1
+ declare const WidgetSettings: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type WidgetSettings = ReturnType<typeof WidgetSettings>;
3
+ export default WidgetSettings;
@@ -7,7 +7,6 @@
7
7
  import { usePartID } from '../../../hooks/usePartID.svelte'
8
8
  import { useSettings } from '../../../hooks/useSettings.svelte'
9
9
 
10
- import { useOrigin } from '../../xr/useOrigin.svelte'
11
10
  import Button from '../dashboard/Button.svelte'
12
11
  import FloatingPanel from '../FloatingPanel.svelte'
13
12
 
@@ -20,7 +19,6 @@
20
19
  const { scene, renderer: mainRenderer, renderStage, invalidate } = useThrelte()
21
20
  const settings = useSettings()
22
21
  const partID = usePartID()
23
- const origin = useOrigin()
24
22
 
25
23
  // Three.js cameras look down -Z; Viam camera frames conventionally have the
26
24
  // optical axis along +Z with image-down along +Y. A 180° rotation around X
@@ -53,7 +51,6 @@
53
51
  const orthoHeight = $derived(BASE_ORTHO_HEIGHT / orthoZoom)
54
52
 
55
53
  const composed = new Matrix4()
56
- const originMat = new Matrix4()
57
54
 
58
55
  $effect(() => {
59
56
  if (!canvasEl) return
@@ -121,15 +118,7 @@
121
118
 
122
119
  const povCamera = cameraMode === 'perspective' ? perspectiveCamera : orthographicCamera
123
120
 
124
- // Compose origin × worldMatrix × VIAM_TO_THREE_CAMERA. The frame
125
- // entities' WorldMatrix lives in ECS world space; the rendered scene
126
- // is wrapped in a T.Group that applies `origin` on top, so the POV
127
- // camera needs the same origin transform to share coordinate space
128
- // with the meshes it's rendering.
129
- originMat
130
- .makeRotationZ(origin.rotation)
131
- .setPosition(origin.position[0], origin.position[1], origin.position[2])
132
- composed.copy(originMat).multiply(worldMat).multiply(VIAM_TO_THREE_CAMERA)
121
+ composed.multiplyMatrices(worldMat, VIAM_TO_THREE_CAMERA)
133
122
  composed.decompose(povCamera.position, povCamera.quaternion, povCamera.scale)
134
123
 
135
124
  const aspect = width / height
@@ -6,14 +6,12 @@
6
6
  import { createResourceClient } from '@viamrobotics/svelte-sdk'
7
7
  import { Quaternion, Vector3 } from 'three'
8
8
 
9
- import {
10
- calculatePositionTarget,
11
- getFrameTransformationQuaternion,
12
- } from './math'
13
- import { xrToast } from './toasts.svelte'
14
9
  import { usePartID } from '../../hooks/usePartID.svelte'
15
10
  import { OrientationVector } from '../../three/OrientationVector'
16
11
 
12
+ import { calculatePositionTarget, getFrameTransformationQuaternion } from './math'
13
+ import { xrToast } from './toasts.svelte'
14
+
17
15
  interface Props {
18
16
  armName: string
19
17
  gripperName?: string
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import { Text } from 'threlte-uikit'
3
+ import { Panel } from 'threlte-uikit/horizon'
4
+
5
+ import { xrDebug } from './debug.svelte'
6
+ import WristDisplay from './WristDisplay.svelte'
7
+
8
+ const messages = $derived(xrDebug.messages)
9
+ </script>
10
+
11
+ <WristDisplay position={[0, 0.005, 0.2]}>
12
+ <Panel
13
+ flexDirection="column"
14
+ padding={12}
15
+ gap={4}
16
+ backgroundColor="#0a0a0a"
17
+ borderRadius={8}
18
+ minWidth={400}
19
+ minHeight={40}
20
+ >
21
+ {#each messages as message, i (i)}
22
+ <Text
23
+ text={message}
24
+ fontSize={14}
25
+ color="#ffffff"
26
+ />
27
+ {/each}
28
+ </Panel>
29
+ </WristDisplay>
@@ -0,0 +1,3 @@
1
+ declare const DebugPanel: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type DebugPanel = ReturnType<typeof DebugPanel>;
3
+ export default DebugPanel;