@viamrobotics/motion-tools 1.9.0 → 1.9.1

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 (67) hide show
  1. package/dist/components/App.svelte +6 -6
  2. package/dist/components/CameraControls.svelte +1 -1
  3. package/dist/components/Focus.svelte +1 -1
  4. package/dist/components/Frame.svelte +1 -1
  5. package/dist/components/Geometry2.svelte +8 -5
  6. package/dist/components/HoveredEntityTooltip.svelte +1 -0
  7. package/dist/components/Label.svelte +1 -1
  8. package/dist/components/MeasureTool/MeasurePoint.svelte +2 -0
  9. package/dist/components/MeasureTool/MeasureTool.svelte +5 -5
  10. package/dist/components/{Details.svelte → overlay/Details.svelte} +10 -10
  11. package/dist/components/{LiveUpdatesBanner.svelte → overlay/LiveUpdatesBanner.svelte} +2 -2
  12. package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/entity.js +1 -1
  13. package/dist/components/{dashboard → overlay/dashboard}/Button.svelte +1 -1
  14. package/dist/components/{dashboard → overlay/dashboard}/Dashboard.svelte +2 -2
  15. package/dist/components/{Tree → overlay/left-pane}/AddFrames.svelte +2 -2
  16. package/dist/components/{Tree → overlay/left-pane}/Logs.svelte +1 -1
  17. package/dist/components/{RefreshRate.svelte → overlay/left-pane/RefreshRate.svelte} +1 -1
  18. package/dist/components/{Tree → overlay/left-pane}/Settings.svelte +7 -7
  19. package/dist/components/{Tree → overlay/left-pane}/Tree.svelte +3 -3
  20. package/dist/components/{Tree → overlay/left-pane}/TreeContainer.svelte +8 -8
  21. package/dist/components/{Tree → overlay/left-pane}/Widgets.svelte +3 -3
  22. package/dist/components/{Tree → overlay/left-pane}/buildTree.js +1 -1
  23. package/dist/components/{widgets → overlay/widgets}/ArmPositions.svelte +4 -4
  24. package/dist/components/{widgets → overlay/widgets}/Camera.svelte +5 -5
  25. package/dist/ecs/traits.d.ts +1 -0
  26. package/dist/ecs/traits.js +1 -0
  27. package/dist/hooks/useDrawAPI.svelte.js +1 -1
  28. package/dist/hooks/useFrames.svelte.js +1 -0
  29. package/dist/hooks/useGeometries.svelte.js +1 -1
  30. package/dist/hooks/usePointcloudObjects.svelte.js +1 -1
  31. package/dist/hooks/usePointclouds.svelte.js +28 -41
  32. package/dist/hooks/usePose.svelte.js +1 -1
  33. package/dist/hooks/useWorldState.svelte.js +1 -1
  34. package/package.json +1 -1
  35. package/dist/components/DotSprite.svelte +0 -59
  36. package/dist/components/DotSprite.svelte.d.ts +0 -10
  37. package/dist/components/MeasureTool.svelte +0 -123
  38. package/dist/components/MeasureTool.svelte.d.ts +0 -3
  39. package/dist/components/null-states/Connection.svelte +0 -0
  40. package/dist/components/null-states/Connection.svelte.d.ts +0 -26
  41. /package/dist/components/{Details.svelte.d.ts → overlay/Details.svelte.d.ts} +0 -0
  42. /package/dist/components/{LiveUpdatesBanner.svelte.d.ts → overlay/LiveUpdatesBanner.svelte.d.ts} +0 -0
  43. /package/dist/components/{Overlay → overlay}/Popover.svelte +0 -0
  44. /package/dist/components/{Overlay → overlay}/Popover.svelte.d.ts +0 -0
  45. /package/dist/components/{shared → overlay}/Table.svelte +0 -0
  46. /package/dist/components/{shared → overlay}/Table.svelte.d.ts +0 -0
  47. /package/dist/components/{Overlay → overlay}/ToggleGroup.svelte +0 -0
  48. /package/dist/components/{Overlay → overlay}/ToggleGroup.svelte.d.ts +0 -0
  49. /package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/entity.d.ts +0 -0
  50. /package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/resource.d.ts +0 -0
  51. /package/dist/components/{__tests__ → overlay/__tests__}/__fixtures__/resource.js +0 -0
  52. /package/dist/components/{dashboard → overlay/dashboard}/Button.svelte.d.ts +0 -0
  53. /package/dist/components/{dashboard → overlay/dashboard}/Dashboard.svelte.d.ts +0 -0
  54. /package/dist/components/{Tree → overlay/left-pane}/AddFrames.svelte.d.ts +0 -0
  55. /package/dist/components/{Tree → overlay/left-pane}/Drawer.svelte +0 -0
  56. /package/dist/components/{Tree → overlay/left-pane}/Drawer.svelte.d.ts +0 -0
  57. /package/dist/components/{Tree → overlay/left-pane}/Logs.svelte.d.ts +0 -0
  58. /package/dist/components/{RefreshRate.svelte.d.ts → overlay/left-pane/RefreshRate.svelte.d.ts} +0 -0
  59. /package/dist/components/{Tree → overlay/left-pane}/Settings.svelte.d.ts +0 -0
  60. /package/dist/components/{Tree → overlay/left-pane}/Tree.svelte.d.ts +0 -0
  61. /package/dist/components/{Tree → overlay/left-pane}/TreeContainer.svelte.d.ts +0 -0
  62. /package/dist/components/{Tree → overlay/left-pane}/Widgets.svelte.d.ts +0 -0
  63. /package/dist/components/{Tree → overlay/left-pane}/buildTree.d.ts +0 -0
  64. /package/dist/components/{Tree → overlay/left-pane}/useExpanded.svelte.d.ts +0 -0
  65. /package/dist/components/{Tree → overlay/left-pane}/useExpanded.svelte.js +0 -0
  66. /package/dist/components/{widgets → overlay/widgets}/ArmPositions.svelte.d.ts +0 -0
  67. /package/dist/components/{widgets → overlay/widgets}/Camera.svelte.d.ts +0 -0
@@ -5,20 +5,20 @@
5
5
  import { provideToast, ToastContainer } from '@viamrobotics/prime-core'
6
6
  import type { Struct } from '@viamrobotics/sdk'
7
7
  import Scene from './Scene.svelte'
8
- import TreeContainer from './Tree/TreeContainer.svelte'
9
- import Details from './Details.svelte'
8
+ import TreeContainer from './overlay/left-pane/TreeContainer.svelte'
9
+ import Details from './overlay/Details.svelte'
10
10
  import SceneProviders from './SceneProviders.svelte'
11
11
  import XR from './xr/XR.svelte'
12
12
  import { createPartIDContext } from '../hooks/usePartID.svelte'
13
- import Dashboard from './dashboard/Dashboard.svelte'
13
+ import Dashboard from './overlay/dashboard/Dashboard.svelte'
14
14
  import { domPortal } from '../portal'
15
15
  import { provideSettings } from '../hooks/useSettings.svelte'
16
16
  import FileDrop from './FileDrop/FileDrop.svelte'
17
17
  import { provideWeblabs } from '../hooks/useWeblabs.svelte'
18
18
  import { providePartConfig } from '../hooks/usePartConfig.svelte'
19
19
  import { useViamClient } from '@viamrobotics/svelte-sdk'
20
- import LiveUpdatesBanner from './LiveUpdatesBanner.svelte'
21
- import ArmPositions from './widgets/ArmPositions.svelte'
20
+ import LiveUpdatesBanner from './overlay/LiveUpdatesBanner.svelte'
21
+ import ArmPositions from './overlay/widgets/ArmPositions.svelte'
22
22
  import { provideEnvironment } from '../hooks/useEnvironment.svelte'
23
23
  import type { CameraPose } from '../hooks/useControls.svelte'
24
24
  import { provideWorld } from '../ecs'
@@ -26,7 +26,7 @@
26
26
  provideDrawConnectionConfig,
27
27
  type DrawConnectionConfig,
28
28
  } from '../hooks/useDrawConnectionConfig.svelte'
29
- import Camera from './widgets/Camera.svelte'
29
+ import Camera from './overlay/widgets/Camera.svelte'
30
30
  import HoveredEntities from './HoveredEntities.svelte'
31
31
 
32
32
  interface LocalConfigProps {
@@ -3,7 +3,7 @@
3
3
  import { CameraControls, type CameraControlsRef, Gizmo, Portal } from '@threlte/extras'
4
4
  import { useCameraControls, useTransformControls } from '../hooks/useControls.svelte'
5
5
  import KeyboardControls from './KeyboardControls.svelte'
6
- import Button from './dashboard/Button.svelte'
6
+ import Button from './overlay/dashboard/Button.svelte'
7
7
  import { useSettings } from '../hooks/useSettings.svelte'
8
8
 
9
9
  const cameraControls = useCameraControls()
@@ -4,7 +4,7 @@
4
4
  import { Box3, type Object3D, Vector3 } from 'three'
5
5
  import { TrackballControls as ThreeTrackballControls } from 'three/examples/jsm/controls/TrackballControls.js'
6
6
  import Camera from './Camera.svelte'
7
- import Button from './dashboard/Button.svelte'
7
+ import Button from './overlay/dashboard/Button.svelte'
8
8
 
9
9
  interface Props {
10
10
  object3d: Object3D
@@ -62,7 +62,7 @@
62
62
  if (!componentName || !id) {
63
63
  return
64
64
  }
65
- return componentModels.current?.[componentName]?.[id]
65
+ return componentModels.current?.[componentName]?.[id].clone()
66
66
  })
67
67
  </script>
68
68
 
@@ -46,6 +46,7 @@
46
46
  const linePositions = useTrait(() => entity, traits.LinePositions)
47
47
  const lineWidth = useTrait(() => entity, traits.LineWidth)
48
48
  const center = useTrait(() => entity, traits.Center)
49
+ const showAxesHelper = useTrait(() => entity, traits.ShowAxesHelper)
49
50
 
50
51
  const geometryType = $derived.by(() => {
51
52
  if (box.current) return 'box'
@@ -124,10 +125,12 @@
124
125
  {...rest}
125
126
  >
126
127
  {#if geometryType}
127
- <AxesHelper
128
- width={3}
129
- length={0.1}
130
- />
128
+ {#if showAxesHelper.current}
129
+ <AxesHelper
130
+ width={3}
131
+ length={0.1}
132
+ />
133
+ {/if}
131
134
 
132
135
  <T
133
136
  is={mesh}
@@ -196,7 +199,7 @@
196
199
  {/if}
197
200
  {/if}
198
201
  </T>
199
- {:else}
202
+ {:else if showAxesHelper.current}
200
203
  <AxesHelper
201
204
  name={name.current}
202
205
  width={3}
@@ -158,6 +158,7 @@
158
158
  <HTML
159
159
  position={tooltipData.subEntityPosition.toArray()}
160
160
  class="pointer-events-none"
161
+ zIndexRange={[3, 0]}
161
162
  >
162
163
  <div
163
164
  class="border-medium pointer-events-none relative -mb-2 -translate-x-1/2 -translate-y-full border bg-white px-3 py-2.5 text-xs shadow-md"
@@ -17,7 +17,7 @@
17
17
  {#if labels && text}
18
18
  <HTML
19
19
  center
20
- zIndexRange={[100, 0]}
20
+ zIndexRange={[3, 0]}
21
21
  class="border-gray-7 border bg-white px-2 py-1 text-xs"
22
22
  >
23
23
  {text}
@@ -17,11 +17,13 @@
17
17
  >
18
18
  <HTML
19
19
  center
20
+ zIndexRange={[3, 0]}
20
21
  class="h-2.5 w-2.5 rounded-full bg-black/70"
21
22
  />
22
23
 
23
24
  <HTML
24
25
  class="pointer-events-none mb-2 w-16 -translate-x-1/2 -translate-y-[calc(100%+10px)] border border-black bg-white px-1 py-0.5 text-xs text-wrap"
26
+ zIndexRange={[3, 0]}
25
27
  >
26
28
  <div class="flex justify-between">
27
29
  <span class="text-subtle-2">x</span>
@@ -4,20 +4,19 @@
4
4
  import { T } from '@threlte/core'
5
5
  import { HTML, MeshLineGeometry, MeshLineMaterial, Portal } from '@threlte/extras'
6
6
  import { useSettings } from '../../hooks/useSettings.svelte'
7
- import Button from '../dashboard/Button.svelte'
7
+ import Button from '../overlay/dashboard/Button.svelte'
8
8
  import MeasurePoint from './MeasurePoint.svelte'
9
9
  import { useMouseRaycaster } from '../../hooks/useMouseRaycaster.svelte'
10
10
  import { useFocusedEntity } from '../../hooks/useSelection.svelte'
11
- import ToggleGroup from '../Overlay/ToggleGroup.svelte'
12
- import Popover from '../Overlay/Popover.svelte'
11
+ import ToggleGroup from '../overlay/ToggleGroup.svelte'
12
+ import Popover from '../overlay/Popover.svelte'
13
13
 
14
14
  const focusedEntity = useFocusedEntity()
15
15
  const settings = useSettings()
16
16
 
17
17
  const htmlPosition = new Vector3()
18
18
 
19
- let step: 'idle' | 'p1' | 'p2' = 'idle'
20
-
19
+ let step = $state<'idle' | 'p1' | 'p2'>('idle')
21
20
  let intersection = $state<Intersection>()
22
21
  let p1 = $state.raw<Vector3>()
23
22
  let p2 = $state.raw<Vector3>()
@@ -166,6 +165,7 @@
166
165
  <HTML
167
166
  center
168
167
  position={htmlPosition.lerpVectors(p1, p2, 0.5).toArray()}
168
+ zIndexRange={[3, 0]}
169
169
  >
170
170
  <div class="border border-black bg-white px-1 py-0.5 text-xs">
171
171
  {p1.distanceTo(p2).toFixed(2)}<span class="text-subtle-2">m</span>
@@ -2,7 +2,7 @@
2
2
  module
3
3
  lang="ts"
4
4
  >
5
- import { OrientationVector } from '../three/OrientationVector'
5
+ import { OrientationVector } from '../../three/OrientationVector'
6
6
  import { Quaternion, Vector3, MathUtils, BufferAttribute } from 'three'
7
7
 
8
8
  const vec3 = new Vector3()
@@ -20,14 +20,14 @@
20
20
  useFocusedEntity,
21
21
  useFocusedObject3d,
22
22
  useSelectedObject3d,
23
- } from '../hooks/useSelection.svelte'
24
- import { useFrames } from '../hooks/useFrames.svelte'
25
- import { usePartConfig } from '../hooks/usePartConfig.svelte'
26
- import { FrameConfigUpdater } from '../FrameConfigUpdater.svelte'
27
- import { useEnvironment } from '../hooks/useEnvironment.svelte'
28
- import { traits, useTrait, useWorld } from '../ecs'
29
- import { useResourceByName } from '../hooks/useResourceByName.svelte'
30
- import { useCameraControls } from '../hooks/useControls.svelte'
23
+ } from '../../hooks/useSelection.svelte'
24
+ import { useFrames } from '../../hooks/useFrames.svelte'
25
+ import { usePartConfig } from '../../hooks/usePartConfig.svelte'
26
+ import { FrameConfigUpdater } from '../../FrameConfigUpdater.svelte'
27
+ import { useEnvironment } from '../../hooks/useEnvironment.svelte'
28
+ import { traits, useTrait, useWorld } from '../../ecs'
29
+ import { useResourceByName } from '../../hooks/useResourceByName.svelte'
30
+ import { useCameraControls } from '../../hooks/useControls.svelte'
31
31
 
32
32
  const { ...rest } = $props()
33
33
 
@@ -232,7 +232,7 @@
232
232
 
233
233
  <div
234
234
  id="details-panel"
235
- class="border-medium bg-extralight absolute top-0 right-0 z-10 m-2 {showEditFrameOptions
235
+ class="border-medium bg-extralight absolute top-0 right-0 z-4 m-2 {showEditFrameOptions
236
236
  ? 'w-80'
237
237
  : 'w-60'} border p-2 text-xs"
238
238
  use:draggable={{
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { Button, Icon } from '@viamrobotics/prime-core'
3
- import { usePartConfig } from '../hooks/usePartConfig.svelte'
3
+ import { usePartConfig } from '../../hooks/usePartConfig.svelte'
4
4
 
5
5
  const partConfig = usePartConfig()
6
6
 
@@ -25,7 +25,7 @@
25
25
 
26
26
  {#if partConfig.isDirty}
27
27
  <div
28
- class="absolute bottom-8 z-10 flex w-full justify-center gap-2"
28
+ class="absolute bottom-8 z-4 flex w-full justify-center gap-2"
29
29
  {...rest}
30
30
  >
31
31
  <div
@@ -1,4 +1,4 @@
1
- import { traits } from '../../../ecs';
1
+ import { traits } from '../../../../ecs';
2
2
  export const createEntityFixture = (world) => {
3
3
  return world.spawn(traits.Parent('parent_frame'), traits.Name('Test Object'), traits.Pose({
4
4
  x: 10,
@@ -33,7 +33,7 @@
33
33
  class={[
34
34
  className,
35
35
  'relative block border',
36
- active ? 'border-gray-5 text-gray-8 z-10 bg-white' : 'bg-light border-medium text-disabled',
36
+ active ? 'border-gray-5 text-gray-8 z-4 bg-white' : 'bg-light border-medium text-disabled',
37
37
  ]}
38
38
  aria-describedby={tooltipID}
39
39
  >
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { useSettings } from '../../hooks/useSettings.svelte'
2
+ import { useSettings } from '../../../hooks/useSettings.svelte'
3
3
  import { PortalTarget } from '@threlte/extras'
4
4
  import Button from './Button.svelte'
5
5
 
@@ -9,7 +9,7 @@
9
9
  </script>
10
10
 
11
11
  <div
12
- class="absolute top-2 z-10 flex w-full justify-center gap-2"
12
+ class="absolute top-2 z-4 flex w-full justify-center gap-2"
13
13
  {...rest}
14
14
  >
15
15
  <!-- camera view -->
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { IconButton } from '@viamrobotics/prime-core'
3
3
  import Drawer from './Drawer.svelte'
4
- import { usePartConfig } from '../../hooks/usePartConfig.svelte'
5
- import { useFramelessComponents } from '../../hooks/useFramelessComponents.svelte'
4
+ import { usePartConfig } from '../../../hooks/usePartConfig.svelte'
5
+ import { useFramelessComponents } from '../../../hooks/useFramelessComponents.svelte'
6
6
 
7
7
  const framelessComponents = useFramelessComponents()
8
8
  const partConfig = usePartConfig()
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { useLogs } from '../../hooks/useLogs.svelte'
2
+ import { useLogs } from '../../../hooks/useLogs.svelte'
3
3
  import Drawer from './Drawer.svelte'
4
4
 
5
5
  const logs = useLogs()
@@ -17,7 +17,7 @@
17
17
 
18
18
  <script lang="ts">
19
19
  import { Select, IconButton } from '@viamrobotics/prime-core'
20
- import { useMachineSettings } from '../hooks/useMachineSettings.svelte'
20
+ import { useMachineSettings } from '../../../hooks/useMachineSettings.svelte'
21
21
  import type { Snippet } from 'svelte'
22
22
 
23
23
  interface Props {
@@ -1,15 +1,15 @@
1
1
  <script lang="ts">
2
2
  import { Select, Switch, Input } from '@viamrobotics/prime-core'
3
- import RefreshRate from '../RefreshRate.svelte'
3
+ import RefreshRate from './RefreshRate.svelte'
4
4
  import Drawer from './Drawer.svelte'
5
- import { useSettings } from '../../hooks/useSettings.svelte'
5
+ import { useSettings } from '../../../hooks/useSettings.svelte'
6
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'
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
11
  import { useThrelte } from '@threlte/core'
12
- import { useRefetchPoses } from '../../hooks/useRefetchPoses'
12
+ import { useRefetchPoses } from '../../../hooks/useRefetchPoses'
13
13
 
14
14
  const { invalidate } = useThrelte()
15
15
  const partID = usePartID()
@@ -2,12 +2,12 @@
2
2
  import * as tree from '@zag-js/tree-view'
3
3
  import { useMachine, normalizeProps } from '@zag-js/svelte'
4
4
  import { ChevronRight, Eye, EyeOff } from 'lucide-svelte'
5
- import { useVisibility } from '../../hooks/useVisibility.svelte'
5
+ import { useVisibility } from '../../../hooks/useVisibility.svelte'
6
6
  import type { TreeNode } from './buildTree'
7
7
  import { VirtualList } from 'svelte-virtuallists'
8
8
  import { Icon } from '@viamrobotics/prime-core'
9
- import { traits } from '../../ecs'
10
- import { useSelectedEntity } from '../../hooks/useSelection.svelte'
9
+ import { traits } from '../../../ecs'
10
+ import { useSelectedEntity } from '../../../hooks/useSelection.svelte'
11
11
  import { SvelteSet } from 'svelte/reactivity'
12
12
 
13
13
  const selected = useSelectedEntity()
@@ -1,20 +1,20 @@
1
1
  <script lang="ts">
2
2
  import { draggable } from '@neodrag/svelte'
3
3
  import Tree from './Tree.svelte'
4
- import { useSelectedEntity } from '../../hooks/useSelection.svelte'
4
+ import { useSelectedEntity } from '../../../hooks/useSelection.svelte'
5
5
  import { provideTreeExpandedContext } from './useExpanded.svelte'
6
6
  import Settings from './Settings.svelte'
7
7
  import Logs from './Logs.svelte'
8
8
  import Widgets from './Widgets.svelte'
9
9
  import AddFrames from './AddFrames.svelte'
10
- import { useEnvironment } from '../../hooks/useEnvironment.svelte'
11
- import { usePartID } from '../../hooks/usePartID.svelte'
12
- import { usePartConfig } from '../../hooks/usePartConfig.svelte'
13
- import { useFrames } from '../../hooks/useFrames.svelte'
14
- import { traits, useQuery, useWorld } from '../../ecs'
10
+ import { useEnvironment } from '../../../hooks/useEnvironment.svelte'
11
+ import { usePartID } from '../../../hooks/usePartID.svelte'
12
+ import { usePartConfig } from '../../../hooks/usePartConfig.svelte'
13
+ import { useFrames } from '../../../hooks/useFrames.svelte'
14
+ import { traits, useQuery, useWorld } from '../../../ecs'
15
15
  import { IsExcluded, type Entity } from 'koota'
16
16
  import { buildTreeNodes, type TreeNode } from './buildTree'
17
- import { MIN_DIMENSIONS, useResizable } from '../../hooks/useResizable.svelte'
17
+ import { MIN_DIMENSIONS, useResizable } from '../../../hooks/useResizable.svelte'
18
18
 
19
19
  const { ...rest } = $props()
20
20
 
@@ -59,7 +59,7 @@
59
59
 
60
60
  <div
61
61
  bind:this={container}
62
- class="bg-extralight border-medium absolute top-0 left-0 z-1000 m-2 resize overflow-y-auto border text-xs"
62
+ class="bg-extralight border-medium absolute top-0 left-0 z-4 m-2 resize overflow-y-auto border text-xs"
63
63
  style:min-width="{MIN_DIMENSIONS.width}px"
64
64
  style:min-height="{MIN_DIMENSIONS.height}px"
65
65
  style:width={resizable.current ? `${resizable.current.width}px` : undefined}
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { Switch } from '@viamrobotics/prime-core'
3
3
  import Drawer from './Drawer.svelte'
4
- import { useSettings } from '../../hooks/useSettings.svelte'
5
- import { useResourceByName } from '../../hooks/useResourceByName.svelte'
6
- import { usePartID } from '../../hooks/usePartID.svelte'
4
+ import { useSettings } from '../../../hooks/useSettings.svelte'
5
+ import { useResourceByName } from '../../../hooks/useResourceByName.svelte'
6
+ import { usePartID } from '../../../hooks/usePartID.svelte'
7
7
 
8
8
  const settings = useSettings()
9
9
  const resourceByName = useResourceByName()
@@ -1,4 +1,4 @@
1
- import { traits } from '../../ecs';
1
+ import { traits } from '../../../ecs';
2
2
  /**
3
3
  * Creates a tree representing parent child / relationships from a set of frames.
4
4
  */
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { draggable } from '@neodrag/svelte'
3
- import { formatNumeric } from '../../format'
4
- import Table from '../shared/Table.svelte'
5
- import { useArmClient } from '../../hooks/useArmClient.svelte'
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-1000 m-2 overflow-y-auto border text-xs"
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 '../../hooks/useSettings.svelte'
7
- import { usePartID } from '../../hooks/usePartID.svelte'
8
- import { useEnvironment } from '../../hooks/useEnvironment.svelte'
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-1000 m-2 flex resize-x flex-col overflow-hidden border text-xs"
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-10 rounded-[3px] bg-black/30 px-1 py-0.5 text-right font-mono text-xs text-white"
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>
@@ -123,6 +123,7 @@ export declare const SnapshotAPI: import("koota").Trait<() => boolean>;
123
123
  * Marker trait for entities created from user-dropped files (PLY, PCD, etc.)
124
124
  */
125
125
  export declare const DroppedFile: import("koota").Trait<() => boolean>;
126
+ export declare const ShowAxesHelper: import("koota").Trait<() => boolean>;
126
127
  /**
127
128
  * Point size, in mm
128
129
  */
@@ -74,6 +74,7 @@ export const SnapshotAPI = trait(() => true);
74
74
  * Marker trait for entities created from user-dropped files (PLY, PCD, etc.)
75
75
  */
76
76
  export const DroppedFile = trait(() => true);
77
+ export const ShowAxesHelper = trait(() => true);
77
78
  // === Shape Properties ===
78
79
  /**
79
80
  * 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
  }
@@ -199,6 +199,7 @@ export const provideFrames = (partID) => {
199
199
  traits.Pose(pose),
200
200
  traits.EditedPose(pose),
201
201
  traits.FramesAPI,
202
+ traits.ShowAxesHelper,
202
203
  ];
203
204
  if (parent && parent !== 'world') {
204
205
  entityTraits.push(traits.Parent(parent));
@@ -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/left-pane/RefreshRate.svelte';
13
13
  import { useEnvironment } from './useEnvironment.svelte';
14
14
  const key = Symbol('geometries-context');
15
15
  const colorUtil = new Color();
@@ -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/left-pane/RefreshRate.svelte';
11
11
  import { createPose } from '../transform';
12
12
  const key = Symbol('pointcloud-object-context');
13
13
  export const providePointcloudObjects = (partID) => {
@@ -1,10 +1,10 @@
1
1
  import { CameraClient } from '@viamrobotics/sdk';
2
- import { setContext, getContext } from 'svelte';
2
+ import { setContext, getContext, untrack } from 'svelte';
3
3
  import { createResourceClient, createResourceQuery, useResourceNames, } from '@viamrobotics/svelte-sdk';
4
4
  import { parsePcdInWorker } from '../loaders/pcd';
5
5
  import { RefreshRates, useMachineSettings } from './useMachineSettings.svelte';
6
6
  import { useLogs } from './useLogs.svelte';
7
- import { RefetchRates } from '../components/RefreshRate.svelte';
7
+ import { RefetchRates } from '../components/overlay/left-pane/RefreshRate.svelte';
8
8
  import { traits, useWorld } from '../ecs';
9
9
  import { useEnvironment } from './useEnvironment.svelte';
10
10
  import { createBufferGeometry, updateBufferGeometry } from '../attribute';
@@ -59,7 +59,7 @@ export const providePointclouds = (partID) => {
59
59
  }
60
60
  });
61
61
  const options = $derived({
62
- refetchInterval: interval,
62
+ refetchInterval: interval === RefetchRates.MANUAL ? false : interval,
63
63
  });
64
64
  const queries = $derived(enabledClients.map((client) => [client.current.name, createResourceQuery(client, 'getPointCloud', () => options)]));
65
65
  const queryMap = $derived(typeSafeObjectFromEntries(queries));
@@ -73,46 +73,33 @@ export const providePointclouds = (partID) => {
73
73
  }
74
74
  }
75
75
  });
76
- let pcObjects = $state.raw([]);
77
- $effect(() => {
78
- const binaries = [];
79
- for (const [name, query] of queries) {
80
- const { data } = query;
81
- if (name && data) {
82
- binaries.push([name, data]);
83
- }
84
- }
85
- Promise.allSettled(binaries.map(async ([name, uint8array]) => {
86
- const { positions, colors } = await parsePcdInWorker(new Uint8Array(uint8array));
87
- return { name, positions, colors };
88
- })).then((results) => {
89
- const fulfilledResults = [];
90
- for (const result of results) {
91
- if (result.status === 'fulfilled') {
92
- fulfilledResults.push(result.value);
93
- }
94
- else if (result.status === 'rejected') {
95
- logs.add(result.reason, 'error');
96
- }
97
- }
98
- pcObjects = fulfilledResults;
99
- });
100
- });
101
76
  const entities = new Map();
102
77
  $effect(() => {
103
- // Create or update entities
104
- for (const { name, positions, colors } of pcObjects) {
105
- const existing = entities.get(name);
106
- if (existing) {
107
- const geometry = existing.get(traits.BufferGeometry);
108
- if (geometry) {
109
- updateBufferGeometry(geometry, positions, colors);
110
- continue;
111
- }
112
- }
113
- const geometry = createBufferGeometry(positions, colors);
114
- const entity = world.spawn(traits.Parent(name), traits.Name(`${name} pointcloud`), traits.BufferGeometry(geometry), traits.Points);
115
- entities.set(name, entity);
78
+ for (const [name, query] of queries) {
79
+ untrack(() => {
80
+ $effect(() => {
81
+ const { data } = query;
82
+ if (!data || data.length === 0)
83
+ return;
84
+ parsePcdInWorker(data)
85
+ .then(({ positions, colors }) => {
86
+ const existing = entities.get(name);
87
+ if (existing) {
88
+ const geometry = existing.get(traits.BufferGeometry);
89
+ if (geometry) {
90
+ updateBufferGeometry(geometry, positions, colors);
91
+ return;
92
+ }
93
+ }
94
+ const geometry = createBufferGeometry(positions, colors);
95
+ const entity = world.spawn(traits.Parent(name), traits.Name(`${name} pointcloud`), traits.BufferGeometry(geometry), traits.Points);
96
+ entities.set(name, entity);
97
+ })
98
+ .catch((error) => {
99
+ logs.add(error.reason, 'error');
100
+ });
101
+ });
102
+ });
116
103
  }
117
104
  // Clean up old entities
118
105
  for (const [name, entity] of entities) {
@@ -6,7 +6,7 @@ import { useEnvironment } from './useEnvironment.svelte';
6
6
  import { observe } from '@threlte/core';
7
7
  import { untrack } from 'svelte';
8
8
  import { useFrames } from './useFrames.svelte';
9
- import { RefetchRates } from '../components/RefreshRate.svelte';
9
+ import { RefetchRates } from '../components/overlay/left-pane/RefreshRate.svelte';
10
10
  import { useLogs } from './useLogs.svelte';
11
11
  import { useResourceByName } from './useResourceByName.svelte';
12
12
  import { useRefetchPoses } from './useRefetchPoses';
@@ -80,7 +80,7 @@ const createWorldState = (client) => {
80
80
  if (metadata.shape === 'arrow') {
81
81
  entityTraits.push(traits.Arrow);
82
82
  }
83
- entityTraits.push(traits.Name(transform.referenceFrame), traits.Pose(pose), traits.WorldStateStoreAPI);
83
+ entityTraits.push(traits.Name(transform.referenceFrame), traits.Pose(pose), traits.ShowAxesHelper, traits.WorldStateStoreAPI);
84
84
  const entity = world.spawn(...entityTraits);
85
85
  entities.set(transform.uuidString, entity);
86
86
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viamrobotics/motion-tools",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Motion visualization with Viam",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -1,59 +0,0 @@
1
- <script lang="ts">
2
- import { T, type Props as ThrelteProps } from '@threlte/core'
3
- import type { ColorRepresentation, Vector3Tuple, Group } from 'three'
4
- import { HTML } from '@threlte/extras'
5
-
6
- interface Props extends ThrelteProps<typeof Group> {
7
- position: Vector3Tuple
8
- color?: ColorRepresentation
9
- opacity?: number
10
- }
11
-
12
- let { position, color, opacity = 1, ref = $bindable(), ...rest }: Props = $props()
13
- </script>
14
-
15
- <T.Group
16
- bind:ref
17
- {...rest}
18
- {position}
19
- >
20
- <T.Mesh
21
- bvh={{ enabled: false }}
22
- raycast={() => null}
23
- scale={0.01}
24
- renderOrder={1}
25
- >
26
- <T.SphereGeometry />
27
- <T.MeshBasicMaterial
28
- color={color ?? 'black'}
29
- transparent
30
- depthTest={false}
31
- {opacity}
32
- />
33
- </T.Mesh>
34
-
35
- <HTML
36
- class="pointer-events-none mb-2 w-16 -translate-x-1/2 -translate-y-[calc(100%+10px)] border border-black bg-white px-1 py-0.5 text-xs text-wrap"
37
- >
38
- <div class="flex justify-between">
39
- <span class="text-subtle-2">x</span>
40
- <div>
41
- {position[0].toFixed(2)}<span class="text-subtle-2">m</span>
42
- </div>
43
- </div>
44
-
45
- <div class="flex justify-between">
46
- <span class="text-subtle-2">y</span>
47
- <div>
48
- {position[1].toFixed(2)}<span class="text-subtle-2">m</span>
49
- </div>
50
- </div>
51
-
52
- <div class="flex justify-between">
53
- <span class="text-subtle-2">z</span>
54
- <div>
55
- {position[2].toFixed(2)}<span class="text-subtle-2">m</span>
56
- </div>
57
- </div>
58
- </HTML>
59
- </T.Group>
@@ -1,10 +0,0 @@
1
- import { type Props as ThrelteProps } from '@threlte/core';
2
- import type { ColorRepresentation, Vector3Tuple, Group } from 'three';
3
- interface Props extends ThrelteProps<typeof Group> {
4
- position: Vector3Tuple;
5
- color?: ColorRepresentation;
6
- opacity?: number;
7
- }
8
- declare const DotSprite: import("svelte").Component<Props, {}, "ref">;
9
- type DotSprite = ReturnType<typeof DotSprite>;
10
- export default DotSprite;
@@ -1,123 +0,0 @@
1
- <script lang="ts">
2
- import { untrack } from 'svelte'
3
- import { Vector3, type Intersection } from 'three'
4
- import { T } from '@threlte/core'
5
- import { HTML, MeshLineGeometry, MeshLineMaterial, Portal } from '@threlte/extras'
6
- import { useSettings } from '../hooks/useSettings.svelte'
7
- import Button from './dashboard/Button.svelte'
8
- import DotSprite from './DotSprite.svelte'
9
- import { useMouseRaycaster } from '../hooks/useMouseRaycaster.svelte'
10
- import { useFocusedEntity } from '../hooks/useSelection.svelte'
11
-
12
- const focusedEntity = useFocusedEntity()
13
- const settings = useSettings()
14
-
15
- const htmlPosition = new Vector3()
16
-
17
- let step: 'idle' | 'p1' | 'p2' = 'idle'
18
-
19
- let intersection = $state.raw<Intersection>()
20
- let p1 = $state.raw<Vector3>()
21
- let p2 = $state.raw<Vector3>()
22
-
23
- const enabled = $derived(settings.current.enableMeasure)
24
-
25
- const { onclick, onmove, raycaster } = useMouseRaycaster(() => ({
26
- enabled,
27
- }))
28
- raycaster.firstHitOnly = true
29
- raycaster.params.Points.threshold = 0.005
30
-
31
- onmove((event) => {
32
- intersection = event.intersections[0]
33
- })
34
-
35
- onclick(() => {
36
- if (step === 'idle' && intersection) {
37
- p1 = intersection.point.clone()
38
- step = 'p1'
39
- } else if (step === 'p1' && intersection) {
40
- p2 = intersection.point.clone()
41
- step = 'p2'
42
- } else if (step === 'p2') {
43
- p1 = undefined
44
- p2 = undefined
45
- step = 'idle'
46
- }
47
- })
48
-
49
- const clear = () => {
50
- p1 = undefined
51
- p2 = undefined
52
- step = 'idle'
53
- }
54
-
55
- $effect(() => {
56
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
57
- ;(focusedEntity.current, enabled)
58
- untrack(() => clear())
59
- })
60
- </script>
61
-
62
- <Portal id="dashboard">
63
- <fieldset>
64
- <Button
65
- active
66
- icon="ruler"
67
- class={enabled ? '' : 'text-gray-4!'}
68
- description="{enabled ? 'Disable' : 'Enable'} measurement"
69
- onclick={() => {
70
- settings.current.enableMeasure = !settings.current.enableMeasure
71
- }}
72
- />
73
- </fieldset>
74
- </Portal>
75
-
76
- {#if enabled}
77
- {#if intersection}
78
- <DotSprite
79
- position={intersection?.point.toArray()}
80
- opacity={0.5}
81
- />
82
- {/if}
83
-
84
- {#if p1}
85
- <DotSprite
86
- position={p1.toArray()}
87
- opacity={0.5}
88
- />
89
- {/if}
90
-
91
- {#if p2}
92
- <DotSprite
93
- position={p2.toArray()}
94
- opacity={0.5}
95
- />
96
- {/if}
97
-
98
- {#if p1 && p2}
99
- <T.Mesh
100
- raycast={() => null}
101
- bvh={{ enabled: false }}
102
- renderOrder={1}
103
- >
104
- <MeshLineGeometry points={[p1, p2]} />
105
- <MeshLineMaterial
106
- width={2.5}
107
- depthTest={false}
108
- color="black"
109
- opacity={0.5}
110
- attenuate={false}
111
- transparent
112
- />
113
- </T.Mesh>
114
- <HTML
115
- center
116
- position={htmlPosition.lerpVectors(p1, p2, 0.5).toArray()}
117
- >
118
- <div class="border border-black bg-white px-1 py-0.5 text-xs">
119
- {p1.distanceTo(p2).toFixed(2)}<span class="text-subtle-2">m</span>
120
- </div>
121
- </HTML>
122
- {/if}
123
- {/if}
@@ -1,3 +0,0 @@
1
- declare const MeasureTool: import("svelte").Component<Record<string, never>, {}, "">;
2
- type MeasureTool = ReturnType<typeof MeasureTool>;
3
- export default MeasureTool;
File without changes
@@ -1,26 +0,0 @@
1
- export default Connection;
2
- type Connection = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const Connection: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
- 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> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
- $$bindings?: Bindings;
17
- } & Exports;
18
- (internal: unknown, props: {
19
- $$events?: Events;
20
- $$slots?: Slots;
21
- }): Exports & {
22
- $set?: any;
23
- $on?: any;
24
- };
25
- z_$$bindings?: Bindings;
26
- }