@viamrobotics/motion-tools 1.15.8 → 1.18.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 (87) hide show
  1. package/dist/attribute.d.ts +3 -2
  2. package/dist/attribute.js +24 -16
  3. package/dist/buf/draw/v1/drawing_pb.d.ts +33 -16
  4. package/dist/buf/draw/v1/drawing_pb.js +35 -17
  5. package/dist/buf/draw/v1/metadata_pb.d.ts +44 -3
  6. package/dist/buf/draw/v1/metadata_pb.js +54 -3
  7. package/dist/buf/draw/v1/scene_pb.d.ts +6 -6
  8. package/dist/buf/draw/v1/scene_pb.js +7 -7
  9. package/dist/buffer.d.ts +54 -45
  10. package/dist/buffer.js +91 -57
  11. package/dist/color.d.ts +1 -2
  12. package/dist/color.js +5 -12
  13. package/dist/components/App.svelte +18 -3
  14. package/dist/components/App.svelte.d.ts +15 -2
  15. package/dist/components/Entities/Arrows/ArrowGroups.svelte +5 -6
  16. package/dist/components/Entities/Arrows/Arrows.svelte +9 -0
  17. package/dist/components/Entities/Entities.svelte +18 -1
  18. package/dist/components/Entities/Frame.svelte +7 -1
  19. package/dist/components/Entities/GLTF.svelte +13 -2
  20. package/dist/components/Entities/Line.svelte +46 -18
  21. package/dist/components/Entities/LineDots.svelte +38 -8
  22. package/dist/components/Entities/LineDots.svelte.d.ts +2 -2
  23. package/dist/components/Entities/LineGeometry.svelte +2 -1
  24. package/dist/components/Entities/LineGeometry.svelte.d.ts +2 -0
  25. package/dist/components/Entities/Mesh.svelte +8 -1
  26. package/dist/components/Entities/Points.svelte +22 -11
  27. package/dist/components/Entities/hooks/useEntityEvents.svelte.js +6 -2
  28. package/dist/components/FileDrop/FileDrop.svelte +5 -1
  29. package/dist/components/KeyboardControls.svelte +2 -10
  30. package/dist/components/PCD.svelte +11 -4
  31. package/dist/components/PCD.svelte.d.ts +3 -1
  32. package/dist/components/SceneProviders.svelte +2 -0
  33. package/dist/components/Selected.svelte +2 -12
  34. package/dist/components/{Lasso → Selection}/Debug.svelte +8 -8
  35. package/dist/components/{Lasso → Selection}/Debug.svelte.d.ts +2 -2
  36. package/dist/components/Selection/Ellipse.svelte +294 -0
  37. package/dist/components/Selection/Ellipse.svelte.d.ts +7 -0
  38. package/dist/components/{Lasso → Selection}/Lasso.svelte +33 -61
  39. package/dist/components/{Lasso → Selection}/Lasso.svelte.d.ts +1 -0
  40. package/dist/components/Selection/Tool.svelte +94 -0
  41. package/dist/components/{Lasso → Selection}/Tool.svelte.d.ts +2 -2
  42. package/dist/components/{Lasso → Selection}/traits.d.ts +11 -2
  43. package/dist/components/{Lasso → Selection}/traits.js +7 -2
  44. package/dist/components/Selection/useSelectionPlugin.svelte.d.ts +8 -0
  45. package/dist/components/Selection/useSelectionPlugin.svelte.js +24 -0
  46. package/dist/components/Selection/utils.d.ts +5 -0
  47. package/dist/components/Selection/utils.js +38 -0
  48. package/dist/components/Snapshot.svelte +4 -2
  49. package/dist/components/overlay/AddRelationship.svelte +1 -2
  50. package/dist/components/overlay/AddRelationship.svelte.d.ts +1 -1
  51. package/dist/components/overlay/Details.svelte +12 -12
  52. package/dist/components/overlay/Details.svelte.d.ts +8 -1
  53. package/dist/components/overlay/settings/Settings.svelte +8 -1
  54. package/dist/components/xr/OriginMarker.svelte +94 -17
  55. package/dist/components/xr/XR.svelte +1 -1
  56. package/dist/draw.d.ts +13 -0
  57. package/dist/draw.js +428 -0
  58. package/dist/ecs/traits.d.ts +31 -13
  59. package/dist/ecs/traits.js +25 -8
  60. package/dist/geometry.js +3 -0
  61. package/dist/hooks/useDrawAPI.svelte.js +61 -24
  62. package/dist/hooks/useDrawService.svelte.d.ts +12 -0
  63. package/dist/hooks/useDrawService.svelte.js +240 -0
  64. package/dist/hooks/usePointcloudObjects.svelte.js +7 -2
  65. package/dist/hooks/usePointclouds.svelte.js +7 -2
  66. package/dist/hooks/useSettings.svelte.d.ts +3 -2
  67. package/dist/hooks/useSettings.svelte.js +2 -2
  68. package/dist/hooks/useWorldState.svelte.js +5 -52
  69. package/dist/index.d.ts +9 -1
  70. package/dist/index.js +10 -1
  71. package/dist/lib.d.ts +2 -0
  72. package/dist/lib.js +2 -0
  73. package/dist/loaders/pcd/index.d.ts +1 -1
  74. package/dist/loaders/pcd/messages.d.ts +2 -2
  75. package/dist/loaders/pcd/worker.inline.d.ts +1 -1
  76. package/dist/loaders/pcd/worker.inline.js +229 -187
  77. package/dist/loaders/pcd/worker.js +2 -2
  78. package/dist/metadata.d.ts +9 -15
  79. package/dist/metadata.js +45 -9
  80. package/dist/plugins/bvh.svelte.js +6 -2
  81. package/dist/snapshot.d.ts +3 -9
  82. package/dist/snapshot.js +11 -204
  83. package/dist/three/InstancedArrows/InstancedArrows.js +3 -2
  84. package/package.json +14 -11
  85. package/dist/components/Lasso/Tool.svelte +0 -108
  86. package/dist/components/xr/Hands.svelte +0 -23
  87. package/dist/components/xr/Hands.svelte.d.ts +0 -18
@@ -0,0 +1,24 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ import { useQuery, useWorld } from '../../ecs';
3
+ import * as selectionTraits from './traits';
4
+ const key = Symbol('selection-plugin-context');
5
+ export const provideSelectionPlugin = () => {
6
+ const world = useWorld();
7
+ const entities = useQuery(selectionTraits.SelectionEnclosedPoints);
8
+ const ctx = setContext(key, {
9
+ get current() {
10
+ return entities.current;
11
+ },
12
+ clearSelections() {
13
+ for (const entity of world.query(selectionTraits.SelectionEnclosedPoints)) {
14
+ if (world.has(entity)) {
15
+ entity.destroy();
16
+ }
17
+ }
18
+ },
19
+ });
20
+ return ctx;
21
+ };
22
+ export const useSelectionPlugin = () => {
23
+ return getContext(key);
24
+ };
@@ -0,0 +1,5 @@
1
+ import { Camera, Triangle, Vector3 } from 'three';
2
+ import type * as selectionTraits from './traits';
3
+ export declare const raycast: (event: PointerEvent, camera: Camera) => Vector3;
4
+ export declare const getTriangleFromIndex: (i: number, indices: number[], positions: Float32Array, outTriangle: Triangle) => void;
5
+ export declare const getTriangleBoxesFromIndices: (indices: number[], positions: Float32Array) => selectionTraits.AABB[];
@@ -0,0 +1,38 @@
1
+ import { Box3, Camera, Plane, Raycaster, Triangle, Vector2, Vector3 } from 'three';
2
+ const raycaster = new Raycaster();
3
+ const mouse = new Vector2();
4
+ const plane = new Plane(new Vector3(0, 0, 1), 0);
5
+ const point = new Vector3();
6
+ const triangle = new Triangle();
7
+ const box3 = new Box3();
8
+ const a = new Vector3();
9
+ const b = new Vector3();
10
+ const c = new Vector3();
11
+ export const raycast = (event, camera) => {
12
+ const element = event.target;
13
+ const rect = element.getBoundingClientRect();
14
+ mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
15
+ mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
16
+ raycaster.setFromCamera(mouse, camera);
17
+ raycaster.ray.intersectPlane(plane, point);
18
+ return point;
19
+ };
20
+ export const getTriangleFromIndex = (i, indices, positions, outTriangle) => {
21
+ const stride = 3;
22
+ const ia = indices[i + 0] * stride;
23
+ const ib = indices[i + 1] * stride;
24
+ const ic = indices[i + 2] * stride;
25
+ a.set(positions[ia + 0], positions[ia + 1], positions[ia + 2]);
26
+ b.set(positions[ib + 0], positions[ib + 1], positions[ib + 2]);
27
+ c.set(positions[ic + 0], positions[ic + 1], positions[ic + 2]);
28
+ outTriangle.set(a, b, c);
29
+ };
30
+ export const getTriangleBoxesFromIndices = (indices, positions) => {
31
+ const boxes = [];
32
+ for (let i = 0, l = indices.length; i < l; i += 3) {
33
+ getTriangleFromIndex(i, indices, positions, triangle);
34
+ box3.setFromPoints([triangle.a, triangle.b, triangle.c]);
35
+ boxes.push({ minX: box3.min.x, minY: box3.min.y, maxX: box3.max.x, maxY: box3.max.y });
36
+ }
37
+ return boxes;
38
+ };
@@ -24,7 +24,7 @@ Renders a Snapshot protobuf by spawning its transforms and drawings as entities
24
24
  import { useWorld } from '../ecs'
25
25
  import { useCameraControls } from '../hooks/useControls.svelte'
26
26
  import { useSettings } from '../hooks/useSettings.svelte'
27
- import { applySceneMetadata, destroyEntities, spawnSnapshotEntities } from '../snapshot'
27
+ import { applySceneMetadata, spawnSnapshotEntities } from '../snapshot'
28
28
 
29
29
  interface Props {
30
30
  snapshot: SnapshotProto
@@ -78,6 +78,8 @@ Renders a Snapshot protobuf by spawning its transforms and drawings as entities
78
78
  })
79
79
 
80
80
  onDestroy(() => {
81
- destroyEntities(world, entities)
81
+ for (const entity of entities) {
82
+ if (world.has(entity)) entity.destroy()
83
+ }
82
84
  })
83
85
  </script>
@@ -1,7 +1,6 @@
1
1
  <script lang="ts">
2
- import type { Entity } from 'koota'
3
-
4
2
  import { Button, Input, Select } from '@viamrobotics/prime-core'
3
+ import { type Entity } from 'koota'
5
4
 
6
5
  import { relations, traits, useQuery, useTrait } from '../../ecs'
7
6
  import { SubEntityLinkType } from '../../ecs/relations'
@@ -1,4 +1,4 @@
1
- import type { Entity } from 'koota';
1
+ import { type Entity } from 'koota';
2
2
  interface Props {
3
3
  entity: Entity | undefined;
4
4
  }
@@ -12,6 +12,9 @@
12
12
  </script>
13
13
 
14
14
  <script lang="ts">
15
+ import type { Entity } from 'koota'
16
+ import type { Snippet } from 'svelte'
17
+
15
18
  import { draggable } from '@neodrag/svelte'
16
19
  import { isInstanceOf, useTask } from '@threlte/core'
17
20
  import { Button, Icon, Input, Select, Tooltip } from '@viamrobotics/prime-core'
@@ -34,7 +37,11 @@
34
37
  } from '../../hooks/useSelection.svelte'
35
38
  import { createPose } from '../../transform'
36
39
 
37
- const { ...rest } = $props()
40
+ interface Props {
41
+ details?: Snippet<[{ entity: Entity }]>
42
+ }
43
+
44
+ const { details }: Props = $props()
38
45
 
39
46
  const world = useWorld()
40
47
  const controls = useCameraControls()
@@ -94,7 +101,7 @@
94
101
  }
95
102
  }
96
103
 
97
- const { start, stop } = useTask(
104
+ useTask(
98
105
  () => {
99
106
  object3d?.getWorldPosition(vec3)
100
107
  if (!vec3.equals(worldPosition)) {
@@ -114,19 +121,11 @@
114
121
  }
115
122
  },
116
123
  {
117
- autoStart: false,
118
124
  autoInvalidate: false,
125
+ running: () => object3d !== undefined,
119
126
  }
120
127
  )
121
128
 
122
- $effect.pre(() => {
123
- if (object3d) {
124
- start()
125
- } else {
126
- stop()
127
- }
128
- })
129
-
130
129
  $effect(() => {
131
130
  if (entity) {
132
131
  const worldPose = createPose({
@@ -266,7 +265,6 @@
266
265
  bounds: 'body',
267
266
  handle: dragElement,
268
267
  }}
269
- {...rest}
270
268
  >
271
269
  <div
272
270
  class="flex cursor-move items-center justify-between gap-2 pb-2"
@@ -662,6 +660,8 @@
662
660
  </div>
663
661
  {/if}
664
662
 
663
+ {@render details?.({ entity })}
664
+
665
665
  <h3 class="text-subtle-2 pt-3 pb-2">Actions</h3>
666
666
 
667
667
  {#if focusedEntity.current}
@@ -1,3 +1,10 @@
1
- declare const Details: import("svelte").Component<Record<string, any>, {}, "">;
1
+ import type { Entity } from 'koota';
2
+ import type { Snippet } from 'svelte';
3
+ interface Props {
4
+ details?: Snippet<[{
5
+ entity: Entity;
6
+ }]>;
7
+ }
8
+ declare const Details: import("svelte").Component<Props, {}, "">;
2
9
  type Details = ReturnType<typeof Details>;
3
10
  export default Details;
@@ -5,6 +5,7 @@
5
5
  import { useResourceNames } from '@viamrobotics/svelte-sdk'
6
6
  import { PersistedState } from 'runed'
7
7
  import { onMount } from 'svelte'
8
+ import { Color } from 'three'
8
9
 
9
10
  import DashboardButton from '../dashboard/Button.svelte'
10
11
  import XRControllerSettings from '../../xr/XRControllerSettings.svelte'
@@ -54,6 +55,8 @@
54
55
 
55
56
  const isOpen = new PersistedState('settings-is-open', false)
56
57
  const activeTab = new PersistedState('settings-active-tab', 'Connection')
58
+
59
+ const colorHex = $derived(`#${new Color(settings.current.pointColor).getHexString()}`)
57
60
  </script>
58
61
 
59
62
  <Portal id="dashboard">
@@ -122,7 +125,11 @@
122
125
  <div class="w-20">
123
126
  <Input
124
127
  type="color"
125
- bind:value={settings.current.pointColor}
128
+ value={colorHex}
129
+ on:change={(event) => {
130
+ const value = (event.target as HTMLInputElement).value
131
+ settings.current.pointColor = value
132
+ }}
126
133
  on:keydown={(event) => event.stopImmediatePropagation()}
127
134
  />
128
135
  </div>
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
- import { T } from '@threlte/core'
2
+ import { useTask, useThrelte } from '@threlte/core'
3
3
  import { Grid, useGamepad } from '@threlte/extras'
4
+ import { Hand, useHand, useXR } from '@threlte/xr'
4
5
  import { Group, Quaternion, Vector2, Vector3 } from 'three'
5
6
 
6
7
  import { useAnchors } from './useAnchors.svelte'
@@ -9,17 +10,20 @@
9
10
  const origin = useOrigin()
10
11
  const anchors = useAnchors()
11
12
 
12
- const group = new Group()
13
13
  const anchorObject = new Group()
14
14
 
15
15
  const leftPad = useGamepad({ xr: true, hand: 'left' })
16
16
  const rightPad = useGamepad({ xr: true, hand: 'right' })
17
17
 
18
- const speed = 0.05
18
+ let speed = $state(0.05)
19
19
 
20
20
  const vec2 = new Vector2()
21
21
  const target = new Vector2()
22
22
 
23
+ leftPad.squeeze.on('change', () => {
24
+ speed = leftPad.squeeze.pressed ? 0.005 : 0.05
25
+ })
26
+
23
27
  leftPad.thumbstick.on('change', ({ value }) => {
24
28
  if (typeof value === 'number') {
25
29
  return
@@ -29,6 +33,8 @@
29
33
  const [x, y, z] = origin.position
30
34
  const r = origin.rotation
31
35
 
36
+ vec2.set(z, r).lerp(target.set(z + vy * speed, r + vx * speed), 0.5)
37
+
32
38
  origin.set([x, y, z + vy * speed], r + vx * speed)
33
39
  })
34
40
 
@@ -56,19 +62,90 @@
56
62
  anchors.bindAnchorObject(anchor, anchorObject)
57
63
  })
58
64
  })
65
+
66
+ let startLeftPinchTranslation = new Vector3()
67
+ let leftPinchTranslation = new Vector3()
68
+ let startRightPinchTranslation = new Vector3()
69
+ let rightPinchTranslation = new Vector3()
70
+
71
+ const leftHand = useHand('left')
72
+ const rightHand = useHand('right')
73
+
74
+ let translating = $state(false)
75
+ let rotating = $state(false)
76
+
77
+ const { renderer } = useThrelte()
78
+ const { isPresenting } = useXR()
79
+
80
+ $effect(() => {
81
+ if (!$isPresenting) {
82
+ return
83
+ }
84
+ renderer.xr.getHand(0).addEventListener('pinchstart', () => {
85
+ if (leftHand.current?.targetRay.position) {
86
+ translating = true
87
+ startLeftPinchTranslation.copy(leftHand.current.targetRay.position)
88
+ }
89
+ })
90
+ })
91
+
92
+ useTask(
93
+ () => {
94
+ if (leftHand.current?.targetRay && translating) {
95
+ leftPinchTranslation
96
+ .copy(leftHand.current.targetRay.position)
97
+ .sub(startLeftPinchTranslation)
98
+ origin.set(leftPinchTranslation.toArray(), origin.rotation)
99
+ }
100
+ },
101
+ {
102
+ running: () => translating,
103
+ }
104
+ )
105
+
106
+ useTask(
107
+ () => {
108
+ if (rightHand.current?.targetRay && rotating) {
109
+ rightPinchTranslation.copy(rightHand.current.targetRay.position)
110
+ const rotation =
111
+ origin.rotation + rightPinchTranslation.distanceTo(startRightPinchTranslation)
112
+ origin.set(leftPinchTranslation.toArray(), rotation)
113
+ }
114
+ },
115
+ {
116
+ running: () => rotating,
117
+ }
118
+ )
59
119
  </script>
60
120
 
61
- <T
62
- is={group}
63
- position={[0, 0.05, 0]}
64
- >
65
- <Grid
66
- plane="xy"
67
- position.y={0.05}
68
- fadeDistance={5}
69
- fadeOrigin={new Vector3()}
70
- cellSize={0.1}
71
- cellColor="#fff"
72
- sectionColor="#fff"
73
- />
74
- </T>
121
+ <Grid
122
+ plane="xy"
123
+ fadeDistance={5}
124
+ fadeOrigin={new Vector3()}
125
+ cellSize={0.1}
126
+ cellColor="#fff"
127
+ sectionColor="#fff"
128
+ />
129
+
130
+ <Hand
131
+ left
132
+ onpinchstart={() => {
133
+ console.log('pinchstart')
134
+ if (leftHand.current?.targetRay.position) {
135
+ translating = true
136
+ startLeftPinchTranslation.copy(leftHand.current.targetRay.position)
137
+ }
138
+ }}
139
+ onpinchend={() => (translating = false)}
140
+ />
141
+
142
+ <Hand
143
+ right
144
+ onpinchstart={() => {
145
+ if (rightHand.current?.targetRay.position) {
146
+ rotating = true
147
+ startRightPinchTranslation.copy(rightHand.current.targetRay.position)
148
+ }
149
+ }}
150
+ onpinchend={() => (rotating = false)}
151
+ />
@@ -72,7 +72,7 @@
72
72
  {#if enableXR}
73
73
  <XR
74
74
  onsessionstart={() => {
75
- origin.set([0, 0, -2])
75
+ origin.set([-1, -1, 0])
76
76
  }}
77
77
  onsessionend={() => {
78
78
  origin.set([0, 0, 0])
package/dist/draw.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { TransformWithUUID } from '@viamrobotics/sdk';
2
+ import type { Entity, Trait, World } from 'koota';
3
+ import type { Transform as TransformProto } from './buf/common/v1/common_pb';
4
+ import type { Drawing } from './buf/draw/v1/drawing_pb';
5
+ export type Transform = TransformWithUUID | TransformProto;
6
+ type Options = {
7
+ removable?: boolean;
8
+ };
9
+ export declare const drawTransform: (world: World, { referenceFrame, poseInObserverFrame, physicalObject, metadata }: Transform, api: Trait, options?: Options) => Entity;
10
+ export declare const drawDrawing: (world: World, drawing: Drawing, api: Trait, options?: Options) => Entity[];
11
+ export declare const updateTransform: (entity: Entity, { poseInObserverFrame, physicalObject, metadata }: Transform, options?: Options) => void;
12
+ export declare const updateDrawing: (world: World, entities: Entity[], drawing: Drawing, api: Trait, options?: Options) => Entity[];
13
+ export {};