@viamrobotics/motion-tools 0.1.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 (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/dist/WorldObject.d.ts +33 -0
  4. package/dist/WorldObject.js +18 -0
  5. package/dist/assert.d.ts +14 -0
  6. package/dist/assert.js +21 -0
  7. package/dist/color.d.ts +8 -0
  8. package/dist/color.js +14 -0
  9. package/dist/components/App.svelte +63 -0
  10. package/dist/components/App.svelte.d.ts +8 -0
  11. package/dist/components/AxesHelper.svelte +17 -0
  12. package/dist/components/AxesHelper.svelte.d.ts +4 -0
  13. package/dist/components/BentPlaneGeometry.svelte +52 -0
  14. package/dist/components/BentPlaneGeometry.svelte.d.ts +29 -0
  15. package/dist/components/Camera.svelte +45 -0
  16. package/dist/components/Camera.svelte.d.ts +5 -0
  17. package/dist/components/CameraControls.svelte +82 -0
  18. package/dist/components/CameraControls.svelte.d.ts +9 -0
  19. package/dist/components/Details.svelte +161 -0
  20. package/dist/components/Details.svelte.d.ts +3 -0
  21. package/dist/components/Detections.svelte +41 -0
  22. package/dist/components/Detections.svelte.d.ts +3 -0
  23. package/dist/components/DetectionsPlane.svelte +23 -0
  24. package/dist/components/DetectionsPlane.svelte.d.ts +21 -0
  25. package/dist/components/DomPortal.svelte +20 -0
  26. package/dist/components/DomPortal.svelte.d.ts +5 -0
  27. package/dist/components/Focus.svelte +49 -0
  28. package/dist/components/Focus.svelte.d.ts +3 -0
  29. package/dist/components/Frame.svelte +112 -0
  30. package/dist/components/Frame.svelte.d.ts +16 -0
  31. package/dist/components/Frames.svelte +54 -0
  32. package/dist/components/Frames.svelte.d.ts +18 -0
  33. package/dist/components/Pointcloud.svelte +55 -0
  34. package/dist/components/Pointcloud.svelte.d.ts +10 -0
  35. package/dist/components/Pointclouds.svelte +21 -0
  36. package/dist/components/Pointclouds.svelte.d.ts +18 -0
  37. package/dist/components/Pose.svelte +19 -0
  38. package/dist/components/Pose.svelte.d.ts +12 -0
  39. package/dist/components/RefreshRate.svelte +47 -0
  40. package/dist/components/RefreshRate.svelte.d.ts +8 -0
  41. package/dist/components/Scene.svelte +81 -0
  42. package/dist/components/Scene.svelte.d.ts +7 -0
  43. package/dist/components/SceneProviders.svelte +41 -0
  44. package/dist/components/SceneProviders.svelte.d.ts +9 -0
  45. package/dist/components/Selected.svelte +44 -0
  46. package/dist/components/Selected.svelte.d.ts +3 -0
  47. package/dist/components/Shapes.svelte +49 -0
  48. package/dist/components/Shapes.svelte.d.ts +18 -0
  49. package/dist/components/StaticGeometries.svelte +79 -0
  50. package/dist/components/StaticGeometries.svelte.d.ts +18 -0
  51. package/dist/components/Tree/Settings.svelte +54 -0
  52. package/dist/components/Tree/Settings.svelte.d.ts +18 -0
  53. package/dist/components/Tree/Tree.svelte +204 -0
  54. package/dist/components/Tree/Tree.svelte.d.ts +10 -0
  55. package/dist/components/Tree/TreeContainer.svelte +70 -0
  56. package/dist/components/Tree/TreeContainer.svelte.d.ts +3 -0
  57. package/dist/components/Tree/buildTree.d.ts +11 -0
  58. package/dist/components/Tree/buildTree.js +29 -0
  59. package/dist/components/Tree/useExpanded.svelte.d.ts +5 -0
  60. package/dist/components/Tree/useExpanded.svelte.js +21 -0
  61. package/dist/components/WorldObject.svelte +27 -0
  62. package/dist/components/WorldObject.svelte.d.ts +11 -0
  63. package/dist/components/XR.svelte +20 -0
  64. package/dist/components/XR.svelte.d.ts +3 -0
  65. package/dist/components/models/README.md +5 -0
  66. package/dist/components/null-states/Connection.svelte +0 -0
  67. package/dist/components/null-states/Connection.svelte.d.ts +26 -0
  68. package/dist/components/portal/Portal.svelte +25 -0
  69. package/dist/components/portal/Portal.svelte.d.ts +8 -0
  70. package/dist/components/portal/PortalTarget.svelte +18 -0
  71. package/dist/components/portal/PortalTarget.svelte.d.ts +6 -0
  72. package/dist/components/portal/index.d.ts +2 -0
  73. package/dist/components/portal/index.js +2 -0
  74. package/dist/components/portal/usePortalContext.svelte.d.ts +5 -0
  75. package/dist/components/portal/usePortalContext.svelte.js +8 -0
  76. package/dist/components/xr/CameraFeed.svelte +81 -0
  77. package/dist/components/xr/CameraFeed.svelte.d.ts +6 -0
  78. package/dist/components/xr/Controllers.svelte +71 -0
  79. package/dist/components/xr/Controllers.svelte.d.ts +3 -0
  80. package/dist/components/xr/Draggable.svelte +101 -0
  81. package/dist/components/xr/Draggable.svelte.d.ts +11 -0
  82. package/dist/components/xr/HandCollider.svelte +19 -0
  83. package/dist/components/xr/HandCollider.svelte.d.ts +18 -0
  84. package/dist/components/xr/Hands.svelte +24 -0
  85. package/dist/components/xr/Hands.svelte.d.ts +18 -0
  86. package/dist/components/xr/OriginMarker.svelte +100 -0
  87. package/dist/components/xr/OriginMarker.svelte.d.ts +3 -0
  88. package/dist/components/xr/PointDistance.svelte +52 -0
  89. package/dist/components/xr/PointDistance.svelte.d.ts +3 -0
  90. package/dist/hooks/index.d.ts +1 -0
  91. package/dist/hooks/index.js +1 -0
  92. package/dist/hooks/useConnectionConfigs.svelte.d.ts +17 -0
  93. package/dist/hooks/useConnectionConfigs.svelte.js +40 -0
  94. package/dist/hooks/useControls.svelte.d.ts +7 -0
  95. package/dist/hooks/useControls.svelte.js +16 -0
  96. package/dist/hooks/useDraggable.svelte.d.ts +2 -0
  97. package/dist/hooks/useDraggable.svelte.js +25 -0
  98. package/dist/hooks/useFrames.svelte.d.ts +9 -0
  99. package/dist/hooks/useFrames.svelte.js +50 -0
  100. package/dist/hooks/useGeometries.svelte.d.ts +7 -0
  101. package/dist/hooks/useGeometries.svelte.js +58 -0
  102. package/dist/hooks/useMotionClient.svelte.d.ts +8 -0
  103. package/dist/hooks/useMotionClient.svelte.js +31 -0
  104. package/dist/hooks/useObjectEvents.svelte.d.ts +9 -0
  105. package/dist/hooks/useObjectEvents.svelte.js +31 -0
  106. package/dist/hooks/useObjects.svelte.d.ts +7 -0
  107. package/dist/hooks/useObjects.svelte.js +33 -0
  108. package/dist/hooks/usePartID.svelte.d.ts +6 -0
  109. package/dist/hooks/usePartID.svelte.js +14 -0
  110. package/dist/hooks/usePersistentUUIDs.svelte.d.ts +5 -0
  111. package/dist/hooks/usePersistentUUIDs.svelte.js +14 -0
  112. package/dist/hooks/usePointclouds.svelte.d.ts +7 -0
  113. package/dist/hooks/usePointclouds.svelte.js +58 -0
  114. package/dist/hooks/usePose.svelte.d.ts +3 -0
  115. package/dist/hooks/usePose.svelte.js +44 -0
  116. package/dist/hooks/usePoses.svelte.d.ts +12 -0
  117. package/dist/hooks/usePoses.svelte.js +63 -0
  118. package/dist/hooks/useRefreshRates.svelte.d.ts +5 -0
  119. package/dist/hooks/useRefreshRates.svelte.js +23 -0
  120. package/dist/hooks/useSelection.svelte.d.ts +40 -0
  121. package/dist/hooks/useSelection.svelte.js +92 -0
  122. package/dist/hooks/useShapes.svelte.d.ts +17 -0
  123. package/dist/hooks/useShapes.svelte.js +264 -0
  124. package/dist/hooks/useStaticGeometries.svelte.d.ts +9 -0
  125. package/dist/hooks/useStaticGeometries.svelte.js +37 -0
  126. package/dist/hooks/useVisibility.svelte.d.ts +5 -0
  127. package/dist/hooks/useVisibility.svelte.js +22 -0
  128. package/dist/hooks/xr/useAnchors.svelte.d.ts +0 -0
  129. package/dist/hooks/xr/useAnchors.svelte.js +1 -0
  130. package/dist/index.d.ts +1 -0
  131. package/dist/index.js +1 -0
  132. package/dist/keybindings.d.ts +12 -0
  133. package/dist/keybindings.js +12 -0
  134. package/dist/loaders/pcd/index.d.ts +4 -0
  135. package/dist/loaders/pcd/index.js +13 -0
  136. package/dist/loaders/pcd/worker.d.ts +1 -0
  137. package/dist/loaders/pcd/worker.js +26 -0
  138. package/dist/three/AxesHelper.d.ts +5 -0
  139. package/dist/three/AxesHelper.js +35 -0
  140. package/dist/three/BatchedArrow.d.ts +30 -0
  141. package/dist/three/BatchedArrow.js +126 -0
  142. package/dist/three/BoxHelper.d.ts +50 -0
  143. package/dist/three/BoxHelper.js +134 -0
  144. package/dist/three/CapsuleGeometry.d.ts +10 -0
  145. package/dist/three/CapsuleGeometry.js +17 -0
  146. package/dist/transform.d.ts +11 -0
  147. package/dist/transform.js +65 -0
  148. package/package.json +110 -0
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ import { VisionClient } from '@viamrobotics/sdk'
3
+ import DetectionsPlane from './DetectionsPlane.svelte'
4
+ import {
5
+ createResourceClient,
6
+ createResourceQuery,
7
+ useResourceNames,
8
+ } from '@viamrobotics/svelte-sdk'
9
+ import { usePartID } from '../hooks/usePartID.svelte'
10
+
11
+ const partID = usePartID()
12
+ const cameras = useResourceNames(() => partID.current, 'camera')
13
+ const services = useResourceNames(() => partID.current, 'vision')
14
+ const visionClients = $derived(
15
+ services.current.map((service) =>
16
+ createResourceClient(
17
+ VisionClient,
18
+ () => partID.current,
19
+ () => service.name
20
+ )
21
+ )
22
+ )
23
+
24
+ const queries = $derived(() =>
25
+ visionClients.map((client) =>
26
+ createResourceQuery(client, 'captureAllFromCamera', [
27
+ cameras.current[0].name,
28
+ {
29
+ returnImage: true,
30
+ returnClassifications: false,
31
+ returnDetections: true,
32
+ returnObjectPointClouds: false,
33
+ },
34
+ ])
35
+ )
36
+ )
37
+
38
+ $inspect(queries)
39
+ </script>
40
+
41
+ <DetectionsPlane detections={[]} />
@@ -0,0 +1,3 @@
1
+ declare const Detections: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type Detections = ReturnType<typeof Detections>;
3
+ export default Detections;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { T } from '@threlte/core'
3
+ import { Detection } from '@viamrobotics/sdk'
4
+
5
+ export let detections: Detection[]
6
+ </script>
7
+
8
+ <T.Group scale={0.001}>
9
+ {#each detections as { xMin, xMax, yMin, yMax }, index (index)}
10
+ {#if xMin !== undefined && xMax !== undefined && yMin !== undefined && yMax !== undefined}
11
+ <T.Mesh
12
+ scale={[Number(xMax - xMin), Number(yMax - yMin), 1]}
13
+ position={[Number(xMin), Number(yMin), 0]}
14
+ >
15
+ <T.PlaneGeometry />
16
+ <T.MeshStandardMaterial
17
+ transparent
18
+ opacity={0.5}
19
+ />
20
+ </T.Mesh>
21
+ {/if}
22
+ {/each}
23
+ </T.Group>
@@ -0,0 +1,21 @@
1
+ import { Detection } from '@viamrobotics/sdk';
2
+ 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> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const DetectionsPlane: $$__sveltets_2_IsomorphicComponent<{
16
+ detections: Detection[];
17
+ }, {
18
+ [evt: string]: CustomEvent<any>;
19
+ }, {}, {}, string>;
20
+ type DetectionsPlane = InstanceType<typeof DetectionsPlane>;
21
+ export default DetectionsPlane;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ let { children } = $props()
3
+
4
+ let div: HTMLDivElement
5
+
6
+ $effect(() => {
7
+ document.body.append(div)
8
+ return () => {
9
+ // eslint-disable-next-line svelte/no-dom-manipulating
10
+ div.remove()
11
+ }
12
+ })
13
+ </script>
14
+
15
+ <div
16
+ style="display: contents"
17
+ bind:this={div}
18
+ >
19
+ {@render children()}
20
+ </div>
@@ -0,0 +1,5 @@
1
+ declare const DomPortal: import("svelte").Component<{
2
+ children: any;
3
+ }, {}, "">;
4
+ type DomPortal = ReturnType<typeof DomPortal>;
5
+ export default DomPortal;
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import { isInstanceOf, T } from '@threlte/core'
3
+ import { TrackballControls, Gizmo } from '@threlte/extras'
4
+ import { useFocused, useFocusedObject3d } from '../hooks/useSelection.svelte'
5
+ import { Keybindings } from '../keybindings'
6
+ import { Box3, Vector3 } from 'three'
7
+ import Camera from './Camera.svelte'
8
+
9
+ const focus = useFocused()
10
+ const focusedObject = useFocusedObject3d()
11
+ const object3d = $derived(focusedObject.current)
12
+
13
+ const box = new Box3()
14
+ const vec = new Vector3()
15
+
16
+ let center = $state.raw<[number, number, number]>([0, 0, 0])
17
+ // let size = $state.raw<[number, number, number]>([0, 0, 0])
18
+
19
+ $effect(() => {
20
+ if (object3d) {
21
+ box.setFromObject(object3d)
22
+ center = box.getCenter(vec).toArray()
23
+ // size = box.getSize(vec).toArray()
24
+ }
25
+ })
26
+
27
+ const onkeydown = ({ key }: KeyboardEvent) => {
28
+ if (key === Keybindings.ESCAPE) {
29
+ focus.set(undefined)
30
+ } else if (key === Keybindings.UP || key === Keybindings.DOWN) {
31
+ if (object3d && 'material' in object3d && isInstanceOf(object3d.material, 'PointsMaterial')) {
32
+ object3d.material.size += key === Keybindings.UP ? 0.001 : -0.001
33
+ }
34
+ }
35
+ }
36
+ </script>
37
+
38
+ <svelte:window {onkeydown} />
39
+
40
+ <Camera position={[2, 0, 0]}>
41
+ <TrackballControls target={center}>
42
+ <Gizmo />
43
+ </TrackballControls>
44
+ </Camera>
45
+
46
+ {#if object3d}
47
+ <T is={object3d} />
48
+ <T.BoxHelper args={[object3d, 'red']} />
49
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const Focus: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type Focus = ReturnType<typeof Focus>;
3
+ export default Focus;
@@ -0,0 +1,112 @@
1
+ <script lang="ts">
2
+ import { T } from '@threlte/core'
3
+ import { type Snippet } from 'svelte'
4
+ import { meshBounds, MeshLineGeometry, MeshLineMaterial } from '@threlte/extras'
5
+ import { BufferGeometry, DoubleSide, FrontSide, Mesh, Object3D } from 'three'
6
+ import { CapsuleGeometry } from '../three/CapsuleGeometry'
7
+ import { poseToObject3d } from '../transform'
8
+ import { darkenColor } from '../color'
9
+ import AxesHelper from './AxesHelper.svelte'
10
+ import type { WorldObject } from '../WorldObject'
11
+ import { PLYLoader } from 'three/addons/loaders/PLYLoader.js'
12
+ import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
13
+
14
+ const plyLoader = new PLYLoader()
15
+
16
+ interface Props {
17
+ uuid: string
18
+ name: string
19
+ geometry?: WorldObject['geometry']
20
+ pose: WorldObject['pose']
21
+ metadata: WorldObject['metadata']
22
+ children?: Snippet<[{ ref: Object3D }]>
23
+ }
24
+
25
+ let { uuid, name, geometry, metadata, pose, children }: Props = $props()
26
+
27
+ const type = $derived(geometry?.case)
28
+ const mesh = $derived.by(() => {
29
+ const object3d = type === undefined ? new Object3D() : new Mesh()
30
+
31
+ if (type === 'mesh' || type === 'points' || type === 'line') {
32
+ object3d.raycast = meshBounds
33
+ }
34
+
35
+ return object3d
36
+ })
37
+
38
+ $effect.pre(() => {
39
+ poseToObject3d(pose, mesh)
40
+ })
41
+
42
+ const events = useObjectEvents(() => uuid)
43
+
44
+ let geo = $state<BufferGeometry>()
45
+ </script>
46
+
47
+ <T
48
+ is={mesh}
49
+ {name}
50
+ {uuid}
51
+ {...events}
52
+ >
53
+ {#if geometry?.case === 'mesh'}
54
+ {@const meshGeometry = plyLoader.parse(atob(geometry.value.mesh as unknown as string))}
55
+ <T is={meshGeometry} />
56
+ {:else if geometry?.case === 'line' && metadata.points}
57
+ <MeshLineGeometry points={metadata.points} />
58
+ {:else if geometry?.case === 'box'}
59
+ {@const dimsMm = geometry.value.dimsMm ?? { x: 0, y: 0, z: 0 }}
60
+ <T.BoxGeometry
61
+ args={[dimsMm.x * 0.001, dimsMm.y * 0.001, dimsMm.z * 0.001]}
62
+ oncreate={(ref) => {
63
+ geo = ref
64
+ }}
65
+ />
66
+ {:else if geometry?.case === 'sphere'}
67
+ {@const radiusMm = geometry.value.radiusMm ?? 0}
68
+ <T.SphereGeometry
69
+ args={[radiusMm * 0.001]}
70
+ oncreate={(ref) => {
71
+ geo = ref
72
+ }}
73
+ />
74
+ {:else if geometry?.case === 'capsule'}
75
+ {@const { lengthMm, radiusMm } = geometry.value}
76
+ <T
77
+ is={CapsuleGeometry}
78
+ args={[radiusMm * 0.001, lengthMm * 0.001]}
79
+ oncreate={(ref) => {
80
+ geo = ref
81
+ }}
82
+ />
83
+ {:else}
84
+ <AxesHelper
85
+ width={5}
86
+ length={0.1}
87
+ />
88
+ {/if}
89
+
90
+ {#if geometry?.case === 'line'}
91
+ <MeshLineMaterial
92
+ color={metadata.color ?? 'red'}
93
+ width={0.005}
94
+ />
95
+ {:else if geometry}
96
+ <T.MeshToonMaterial
97
+ color={metadata.color ?? 'red'}
98
+ side={geometry.case === 'mesh' ? DoubleSide : FrontSide}
99
+ transparent
100
+ opacity={0.7}
101
+ />
102
+
103
+ {#if geo}
104
+ <T.LineSegments raycast={() => null}>
105
+ <T.EdgesGeometry args={[geo, 1]} />
106
+ <T.LineBasicMaterial color={darkenColor(metadata.color ?? 'red', 10)} />
107
+ </T.LineSegments>
108
+ {/if}
109
+ {/if}
110
+
111
+ {@render children?.({ ref: mesh })}
112
+ </T>
@@ -0,0 +1,16 @@
1
+ import { type Snippet } from 'svelte';
2
+ import { Object3D } from 'three';
3
+ import type { WorldObject } from '../WorldObject';
4
+ interface Props {
5
+ uuid: string;
6
+ name: string;
7
+ geometry?: WorldObject['geometry'];
8
+ pose: WorldObject['pose'];
9
+ metadata: WorldObject['metadata'];
10
+ children?: Snippet<[{
11
+ ref: Object3D;
12
+ }]>;
13
+ }
14
+ declare const Frame: import("svelte").Component<Props, {}, "">;
15
+ type Frame = ReturnType<typeof Frame>;
16
+ export default Frame;
@@ -0,0 +1,54 @@
1
+ <script lang="ts">
2
+ import { Portal, PortalTarget } from './portal'
3
+ import Frame from './Frame.svelte'
4
+ import { useFrames } from '../hooks/useFrames.svelte'
5
+ import { useGeometries } from '../hooks/useGeometries.svelte'
6
+ import Pose from './Pose.svelte'
7
+
8
+ const frames = useFrames()
9
+ const geometries = useGeometries()
10
+ </script>
11
+
12
+ {#each frames.current as object (object.uuid)}
13
+ <Pose name={object.name}>
14
+ {#snippet children({ pose })}
15
+ {#if pose}
16
+ <Frame
17
+ uuid={object.uuid}
18
+ name={object.name}
19
+ {pose}
20
+ geometry={object.geometry}
21
+ metadata={object.metadata}
22
+ >
23
+ <PortalTarget id={object.name} />
24
+ </Frame>
25
+ {:else}
26
+ <Portal id={object.referenceFrame}>
27
+ <Frame
28
+ uuid={object.uuid}
29
+ name={object.name}
30
+ pose={pose ?? object.pose}
31
+ geometry={object.geometry}
32
+ metadata={object.metadata}
33
+ >
34
+ <PortalTarget id={object.name} />
35
+ </Frame>
36
+ </Portal>
37
+ {/if}
38
+ {/snippet}
39
+ </Pose>
40
+ {/each}
41
+
42
+ {#each geometries.current as object (object.uuid)}
43
+ <Portal id={object.referenceFrame}>
44
+ <Frame
45
+ uuid={object.uuid}
46
+ name={object.name}
47
+ pose={object.pose}
48
+ geometry={object.geometry}
49
+ metadata={object.metadata}
50
+ >
51
+ <PortalTarget id={object.name} />
52
+ </Frame>
53
+ </Portal>
54
+ {/each}
@@ -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 Frames: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type Frames = InstanceType<typeof Frames>;
18
+ export default Frames;
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import { T } from '@threlte/core'
3
+ import { Points, BufferAttribute, BufferGeometry, Color, PointsMaterial } from 'three'
4
+ import type { WorldObject } from '../WorldObject'
5
+ import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
6
+ import { meshBounds } from '@threlte/extras'
7
+ import { poseToObject3d } from '../transform'
8
+
9
+ interface Props {
10
+ object: WorldObject<{ case: 'points'; value: Float32Array }>
11
+ }
12
+
13
+ let { object }: Props = $props()
14
+
15
+ const points = new Points()
16
+ const geometry = new BufferGeometry()
17
+ const material = new PointsMaterial({
18
+ size: 0.01,
19
+ color: new Color('#888888'),
20
+ })
21
+
22
+ const colors = $derived(object.metadata.colors)
23
+ const positions = $derived(object.geometry?.value ?? [])
24
+
25
+ $effect(() => {
26
+ material.vertexColors = colors !== undefined
27
+ })
28
+
29
+ $effect.pre(() => {
30
+ geometry.setAttribute('position', new BufferAttribute(new Float32Array(positions), 3))
31
+ })
32
+
33
+ $effect.pre(() => {
34
+ if (colors) {
35
+ geometry.setAttribute('color', new BufferAttribute(new Float32Array(colors), 3))
36
+ }
37
+ })
38
+
39
+ $effect.pre(() => {
40
+ poseToObject3d(object.pose, points)
41
+ })
42
+
43
+ const events = useObjectEvents(() => object.uuid)
44
+ </script>
45
+
46
+ <T
47
+ is={points}
48
+ name={object.name}
49
+ uuid={object.uuid}
50
+ raycast={meshBounds}
51
+ {...events}
52
+ >
53
+ <T is={geometry} />
54
+ <T is={material} />
55
+ </T>
@@ -0,0 +1,10 @@
1
+ import type { WorldObject } from '../WorldObject';
2
+ interface Props {
3
+ object: WorldObject<{
4
+ case: 'points';
5
+ value: Float32Array;
6
+ }>;
7
+ }
8
+ declare const Pointcloud: import("svelte").Component<Props, {}, "">;
9
+ type Pointcloud = ReturnType<typeof Pointcloud>;
10
+ export default Pointcloud;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { Portal } from './portal'
3
+ import { usePointClouds } from '../hooks/usePointclouds.svelte'
4
+ import { useShapes } from '../hooks/useShapes.svelte'
5
+ import Pointcloud from './Pointcloud.svelte'
6
+
7
+ const points = usePointClouds()
8
+ const shapes = useShapes()
9
+ </script>
10
+
11
+ {#each points.current as object (object.uuid)}
12
+ <Portal id={object.referenceFrame}>
13
+ <Pointcloud {object} />
14
+ </Portal>
15
+ {/each}
16
+
17
+ {#each shapes.points as object (object.uuid)}
18
+ <Portal id={object.referenceFrame}>
19
+ <Pointcloud {object} />
20
+ </Portal>
21
+ {/each}
@@ -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 Pointclouds: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type Pointclouds = InstanceType<typeof Pointclouds>;
18
+ export default Pointclouds;
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import { usePose } from '../hooks/usePose.svelte'
3
+ import type { Pose } from '@viamrobotics/sdk'
4
+ import type { Snippet } from 'svelte'
5
+
6
+ interface Props {
7
+ name: string
8
+ parent?: string
9
+ children: Snippet<[{ pose: Pose | undefined }]>
10
+ }
11
+ let { name, parent, children }: Props = $props()
12
+
13
+ const pose = usePose(
14
+ () => name,
15
+ () => parent ?? 'world'
16
+ )
17
+ </script>
18
+
19
+ {@render children({ pose: pose.current })}
@@ -0,0 +1,12 @@
1
+ import type { Pose } from '@viamrobotics/sdk';
2
+ import type { Snippet } from 'svelte';
3
+ interface Props {
4
+ name: string;
5
+ parent?: string;
6
+ children: Snippet<[{
7
+ pose: Pose | undefined;
8
+ }]>;
9
+ }
10
+ declare const Pose: import("svelte").Component<Props, {}, "">;
11
+ type Pose = ReturnType<typeof Pose>;
12
+ export default Pose;
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ import { Select } from '@viamrobotics/prime-core'
3
+ import { useRefreshRates } from '../hooks/useRefreshRates.svelte'
4
+ import type { Snippet } from 'svelte'
5
+
6
+ interface Props {
7
+ name: string
8
+ children?: Snippet
9
+ }
10
+
11
+ let { name, children }: Props = $props()
12
+
13
+ const pollingRates = useRefreshRates()
14
+ const rate = $derived(pollingRates.get(name))
15
+ </script>
16
+
17
+ <label class="flex flex-col gap-1">
18
+ {name}
19
+ <Select
20
+ onchange={(event: InputEvent) => {
21
+ if (event.target instanceof HTMLSelectElement) {
22
+ const { value } = event.target
23
+ pollingRates.set(name, Number.parseInt(value, 10))
24
+ }
25
+ }}
26
+ value={String(rate ?? '')}
27
+ >
28
+ {#if children}
29
+ {@render children()}
30
+ {:else}
31
+ <option value="-1">Do not fetch</option>
32
+ <option value="0">Do not refresh</option>
33
+ <option value="500">Refresh every 0.5 second</option>
34
+ <option value="1000">Refresh every second</option>
35
+ <option value="2000">Refresh every 2 seconds</option>
36
+ <option value="5000">Refresh every 5 seconds</option>
37
+ <option value="10000">Refresh every 10 seconds</option>
38
+ <option value="30000">Refresh every 30 seconds</option>
39
+ {/if}
40
+ </Select>
41
+ </label>
42
+
43
+ <style>
44
+ label :global svg {
45
+ display: none;
46
+ }
47
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ name: string;
4
+ children?: Snippet;
5
+ }
6
+ declare const RefreshRate: import("svelte").Component<Props, {}, "">;
7
+ type RefreshRate = ReturnType<typeof RefreshRate>;
8
+ export default RefreshRate;
@@ -0,0 +1,81 @@
1
+ <script lang="ts">
2
+ import { Color, Vector3 } from 'three'
3
+ import { T } from '@threlte/core'
4
+ import { Gizmo, Grid, interactivity } from '@threlte/extras'
5
+ import { PortalTarget } from './portal'
6
+ import Frames from './Frames.svelte'
7
+ import Pointclouds from './Pointclouds.svelte'
8
+ import CameraControls from './CameraControls.svelte'
9
+ import Selected from './Selected.svelte'
10
+ import Focus from './Focus.svelte'
11
+ import StaticGeometries from './StaticGeometries.svelte'
12
+ import Shapes from './Shapes.svelte'
13
+ import Camera from './Camera.svelte'
14
+ import { useFocused } from '../hooks/useSelection.svelte'
15
+ import type { Snippet } from 'svelte'
16
+ import { useXR } from '@threlte/xr'
17
+
18
+ interface Props {
19
+ children?: Snippet
20
+ }
21
+
22
+ let { children }: Props = $props()
23
+
24
+ interactivity({
25
+ filter: (items) => {
26
+ const item = items.find((item) => {
27
+ return item.object.visible === undefined || item.object.visible === true
28
+ })
29
+
30
+ return item ? [item] : []
31
+ },
32
+ })
33
+
34
+ const focused = useFocused()
35
+
36
+ const { isPresenting } = useXR()
37
+ </script>
38
+
39
+ <T.Color
40
+ attach="background"
41
+ args={[new Color('white')]}
42
+ />
43
+
44
+ <T.Group rotation.x={$isPresenting ? -Math.PI / 2 : 0}>
45
+ {#if focused.current === undefined}
46
+ {#if !$isPresenting}
47
+ <Camera position={[3, 3, 3]}>
48
+ <CameraControls>
49
+ <Gizmo />
50
+ </CameraControls>
51
+ </Camera>
52
+ {/if}
53
+
54
+ <PortalTarget id="world" />
55
+
56
+ <StaticGeometries />
57
+ <Frames />
58
+ <Pointclouds />
59
+ <Shapes />
60
+
61
+ <Selected />
62
+
63
+ {#if !$isPresenting}
64
+ <Grid
65
+ plane="xy"
66
+ sectionColor="lightgrey"
67
+ infiniteGrid
68
+ fadeOrigin={new Vector3()}
69
+ fadeDistance={25}
70
+ />
71
+ {/if}
72
+ {:else}
73
+ <Focus />
74
+ {/if}
75
+
76
+ {@render children?.()}
77
+
78
+ <T.DirectionalLight position={[3, 3, 3]} />
79
+ <T.DirectionalLight position={[-3, -3, -3]} />
80
+ <T.AmbientLight />
81
+ </T.Group>
@@ -0,0 +1,7 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ children?: Snippet;
4
+ }
5
+ declare const Scene: import("svelte").Component<Props, {}, "">;
6
+ type Scene = ReturnType<typeof Scene>;
7
+ export default Scene;