@viamrobotics/motion-tools 1.13.1 → 1.15.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 (136) hide show
  1. package/dist/FrameConfigUpdater.svelte.d.ts +2 -2
  2. package/dist/HoverUpdater.svelte.d.ts +1 -1
  3. package/dist/attribute.js +11 -3
  4. package/dist/buffer.d.ts +56 -7
  5. package/dist/buffer.js +70 -12
  6. package/dist/color.d.ts +1 -1
  7. package/dist/color.js +2 -2
  8. package/dist/components/App.svelte +25 -21
  9. package/dist/components/App.svelte.d.ts +1 -1
  10. package/dist/components/BatchedArrows.svelte +5 -3
  11. package/dist/components/Camera.svelte +1 -0
  12. package/dist/components/CameraControls.svelte +5 -3
  13. package/dist/components/Entities/Arrows/ArrowGroups.svelte +6 -3
  14. package/dist/components/Entities/Arrows/Arrows.svelte +6 -3
  15. package/dist/components/Entities/Entities.svelte +9 -7
  16. package/dist/components/Entities/Frame.svelte +48 -48
  17. package/dist/components/Entities/Frame.svelte.d.ts +3 -2
  18. package/dist/components/Entities/GLTF.svelte +8 -5
  19. package/dist/components/Entities/GLTF.svelte.d.ts +2 -2
  20. package/dist/components/Entities/Geometry.svelte +45 -173
  21. package/dist/components/Entities/Geometry.svelte.d.ts +5 -14
  22. package/dist/components/Entities/Line.svelte +69 -19
  23. package/dist/components/Entities/Line.svelte.d.ts +1 -1
  24. package/dist/components/Entities/LineDots.svelte +1 -1
  25. package/dist/components/Entities/LineGeometry.svelte +1 -1
  26. package/dist/components/Entities/Mesh.svelte +133 -0
  27. package/dist/components/Entities/Mesh.svelte.d.ts +4 -0
  28. package/dist/components/Entities/Points.svelte +9 -6
  29. package/dist/components/Entities/Points.svelte.d.ts +2 -2
  30. package/dist/components/Entities/Pose.svelte +4 -3
  31. package/dist/components/Entities/hooks/useEntityEvents.svelte.d.ts +1 -1
  32. package/dist/components/Entities/hooks/useEntityEvents.svelte.js +2 -2
  33. package/dist/components/FileDrop/FileDrop.svelte +10 -6
  34. package/dist/components/FileDrop/file-dropper.d.ts +1 -1
  35. package/dist/components/FileDrop/pcd-dropper.js +1 -1
  36. package/dist/components/FileDrop/ply-dropper.js +1 -1
  37. package/dist/components/FileDrop/snapshot-dropper.js +1 -1
  38. package/dist/components/Focus.svelte +4 -2
  39. package/dist/components/KeyboardControls.svelte +4 -2
  40. package/dist/components/Lasso/Debug.svelte +5 -2
  41. package/dist/components/Lasso/Lasso.svelte +9 -6
  42. package/dist/components/Lasso/Tool.svelte +10 -7
  43. package/dist/components/MeasureTool/MeasurePoint.svelte +2 -1
  44. package/dist/components/MeasureTool/MeasurePoint.svelte.d.ts +1 -1
  45. package/dist/components/MeasureTool/MeasureTool.svelte +7 -5
  46. package/dist/components/PCD.svelte +4 -3
  47. package/dist/components/PointerMissBox.svelte +3 -2
  48. package/dist/components/Scene.svelte +12 -9
  49. package/dist/components/SceneProviders.svelte +20 -18
  50. package/dist/components/Selected.svelte +7 -3
  51. package/dist/components/Snapshot.svelte +8 -5
  52. package/dist/components/StaticGeometries.svelte +10 -7
  53. package/dist/components/hover/HoveredEntities.svelte +2 -1
  54. package/dist/components/hover/HoveredEntity.svelte +2 -1
  55. package/dist/components/hover/HoveredEntityTooltip.svelte +1 -0
  56. package/dist/components/hover/LinkedHoveredEntity.svelte +7 -5
  57. package/dist/components/overlay/AddRelationship.svelte +4 -2
  58. package/dist/components/overlay/Details.svelte +21 -19
  59. package/dist/components/overlay/FloatingPanel.svelte +40 -3
  60. package/dist/components/overlay/FloatingPanel.svelte.d.ts +1 -0
  61. package/dist/components/overlay/LiveUpdatesBanner.svelte +1 -0
  62. package/dist/components/overlay/Logs.svelte +4 -2
  63. package/dist/components/overlay/Popover.svelte +3 -2
  64. package/dist/components/overlay/RefreshRate.svelte +4 -2
  65. package/dist/components/overlay/dashboard/Button.svelte +2 -1
  66. package/dist/components/overlay/dashboard/Button.svelte.d.ts +1 -1
  67. package/dist/components/overlay/dashboard/Dashboard.svelte +3 -1
  68. package/dist/components/overlay/left-pane/AddFrames.svelte +4 -2
  69. package/dist/components/overlay/left-pane/Drawer.svelte +3 -2
  70. package/dist/components/overlay/left-pane/Tree.svelte +6 -12
  71. package/dist/components/overlay/left-pane/TreeContainer.svelte +33 -50
  72. package/dist/components/overlay/left-pane/TreeContainer.svelte.d.ts +1 -1
  73. package/dist/components/overlay/left-pane/buildTree.js +15 -0
  74. package/dist/components/overlay/settings/Settings.svelte +37 -10
  75. package/dist/components/overlay/settings/Tabs.svelte +2 -1
  76. package/dist/components/overlay/widgets/ArmPositions.svelte +3 -2
  77. package/dist/components/overlay/widgets/Camera.svelte +6 -5
  78. package/dist/components/weblab/WeblabActive.svelte +2 -1
  79. package/dist/components/xr/ArmTeleop.svelte +7 -6
  80. package/dist/components/xr/BentPlaneGeometry.svelte +3 -2
  81. package/dist/components/xr/CameraFeed.svelte +2 -0
  82. package/dist/components/xr/Controllers.svelte +5 -3
  83. package/dist/components/xr/Draggable.svelte +4 -3
  84. package/dist/components/xr/HandCollider.svelte +2 -1
  85. package/dist/components/xr/JointLimitsWidget.svelte +1 -0
  86. package/dist/components/xr/OriginMarker.svelte +2 -1
  87. package/dist/components/xr/PointDistance.svelte +3 -2
  88. package/dist/components/xr/XR.svelte +8 -6
  89. package/dist/components/xr/XRConfigPanel.svelte +4 -3
  90. package/dist/components/xr/XRControllerSettings.svelte +2 -1
  91. package/dist/components/xr/XRToast.svelte +4 -3
  92. package/dist/ecs/traits.d.ts +3 -20
  93. package/dist/ecs/traits.js +34 -7
  94. package/dist/ecs/useQuery.svelte.js +1 -1
  95. package/dist/frame.js +1 -1
  96. package/dist/hooks/use3DModels.svelte.js +4 -6
  97. package/dist/hooks/useConfigFrames.svelte.js +3 -3
  98. package/dist/hooks/useDrawAPI.svelte.js +9 -9
  99. package/dist/hooks/useFramelessComponents.svelte.js +1 -1
  100. package/dist/hooks/useFrames.svelte.js +18 -19
  101. package/dist/hooks/useGeometries.svelte.js +66 -43
  102. package/dist/hooks/useMouseRaycaster.svelte.d.ts +1 -1
  103. package/dist/hooks/useMouseRaycaster.svelte.js +1 -1
  104. package/dist/hooks/usePartConfig.svelte.d.ts +1 -1
  105. package/dist/hooks/usePartConfig.svelte.js +3 -3
  106. package/dist/hooks/usePointcloudObjects.svelte.js +108 -63
  107. package/dist/hooks/usePointclouds.svelte.js +53 -33
  108. package/dist/hooks/usePose.svelte.js +7 -7
  109. package/dist/hooks/useSelection.svelte.d.ts +1 -1
  110. package/dist/hooks/useWeblabs.svelte.d.ts +1 -0
  111. package/dist/hooks/useWeblabs.svelte.js +15 -3
  112. package/dist/hooks/useWorldState.svelte.js +31 -31
  113. package/dist/metadata.d.ts +22 -0
  114. package/dist/metadata.js +66 -0
  115. package/dist/plugins/bvh.svelte.js +2 -2
  116. package/dist/snapshot.d.ts +22 -2
  117. package/dist/snapshot.js +67 -25
  118. package/dist/three/BatchedArrow.d.ts +1 -1
  119. package/dist/three/BatchedArrow.js +1 -1
  120. package/dist/three/InstancedArrows/InstancedArrows.d.ts +1 -1
  121. package/dist/three/InstancedArrows/InstancedArrows.js +3 -3
  122. package/dist/three/InstancedArrows/box.js +1 -1
  123. package/dist/three/InstancedArrows/geometry.js +1 -1
  124. package/dist/three/InstancedArrows/raycast.d.ts +1 -1
  125. package/dist/three/InstancedArrows/raycast.js +1 -1
  126. package/dist/three/OBBHelper.d.ts +3 -2
  127. package/dist/three/OBBHelper.js +17 -5
  128. package/dist/three/OrientationVector.js +1 -1
  129. package/dist/transform.js +1 -1
  130. package/package.json +3 -2
  131. package/dist/WorldObject.svelte.d.ts +0 -27
  132. package/dist/WorldObject.svelte.js +0 -127
  133. package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte +0 -41
  134. package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte.d.ts +0 -6
  135. package/dist/hooks/useResizable.svelte.d.ts +0 -12
  136. package/dist/hooks/useResizable.svelte.js +0 -46
@@ -1,7 +1,7 @@
1
- import type { Entity } from 'koota';
2
1
  import type { Pose } from '@viamrobotics/sdk';
3
- import type { Frame } from './frame';
2
+ import type { Entity } from 'koota';
4
3
  import type { Vector3Like } from 'three';
4
+ import type { Frame } from './frame';
5
5
  type UpdateFrameCallback = {
6
6
  (componentName: string, referenceFrame: string, pose: Pose, geometry?: Frame['geometry']): void;
7
7
  };
@@ -1,5 +1,5 @@
1
- import type { Entity } from 'koota';
2
1
  import type { IntersectionEvent } from '@threlte/extras';
2
+ import type { Entity } from 'koota';
3
3
  export interface HoverInfo {
4
4
  index: number;
5
5
  x: number;
package/dist/attribute.js CHANGED
@@ -1,9 +1,16 @@
1
- import { BufferGeometry, BufferAttribute } from 'three';
1
+ import { BufferAttribute, BufferGeometry } from 'three';
2
+ import { STRIDE } from './buffer';
3
+ const colorStride = (colors, positions) => {
4
+ const numVertices = positions.length / STRIDE.POSITIONS;
5
+ const stride = colors.length / numVertices;
6
+ return stride === STRIDE.COLORS_RGBA ? STRIDE.COLORS_RGBA : STRIDE.COLORS_RGB;
7
+ };
2
8
  export const createBufferGeometry = (positions, colors) => {
3
9
  const geometry = new BufferGeometry();
4
10
  geometry.setAttribute('position', new BufferAttribute(positions, 3));
5
11
  if (colors) {
6
- geometry.setAttribute('color', new BufferAttribute(colors, 3, true));
12
+ const stride = colorStride(colors, positions);
13
+ geometry.setAttribute('color', new BufferAttribute(colors, stride, true));
7
14
  }
8
15
  return geometry;
9
16
  };
@@ -24,7 +31,8 @@ export const updateBufferGeometry = (geometry, positions, colors) => {
24
31
  colorAttr.needsUpdate = true;
25
32
  }
26
33
  else {
27
- geometry.setAttribute('color', new BufferAttribute(colors, 3, true));
34
+ const stride = colorStride(colors, positions);
35
+ geometry.setAttribute('color', new BufferAttribute(colors, stride, true));
28
36
  }
29
37
  }
30
38
  };
package/dist/buffer.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * Proto messages pack float32 data as `Uint8Array` (bytes fields). These utilities
5
5
  * provide efficient conversion to `Float32Array` for Three.js BufferAttributes.
6
6
  */
7
+ import { Color } from 'three';
7
8
  /**
8
9
  * Stride constants for proto binary data formats.
9
10
  * Each value represents the number of float32 elements per item.
@@ -37,16 +38,64 @@ export declare const STRIDE: {
37
38
  */
38
39
  export declare const asFloat32Array: (bytes: Uint8Array<ArrayBuffer>) => Float32Array<ArrayBuffer>;
39
40
  /**
40
- * Converts uint8 RGBA colors to normalized float32 colors (0-1 range).
41
- * Three.js expects colors in 0-1 range for BufferAttributes.
41
+ * Sets a Three.js Color from 3 bytes of a uint8 color array starting at `offset`.
42
+ * Mutates and returns `target` — pass a pre-allocated Color to avoid allocations
43
+ * in hot paths.
42
44
  *
43
- * @param colors - Uint8Array of RGBA color data [r, g, b, a, ...]
44
- * @returns Float32Array with normalized color values
45
+ * @param bytes - Uint8Array with at least `offset + 3` elements [r, g, b, ...]
46
+ * @param target - Color instance to write into
47
+ * @param offset - Byte offset to start reading from (default 0)
48
+ * @returns The mutated `target`, or black if the array has fewer than `offset + 3` elements
45
49
  *
46
50
  * @example
47
51
  * ```ts
48
- * const colors = normalizeColorsRGBA(metadata.colors)
49
- * geometry.setAttribute('color', new BufferAttribute(colors, 4))
52
+ * asColor(colors.current, material.color)
53
+ * asColor(colors.current, pointColorUtil, stride) // read second color
50
54
  * ```
51
55
  */
52
- export declare const normalizeColorsRGBA: (colors: Float32Array) => Float32Array;
56
+ export declare const asColor: (bytes: Uint8Array<ArrayBuffer>, target: Color, offset?: number) => Color;
57
+ /**
58
+ * Creates a Uint8Array from a Three.js Color.
59
+ *
60
+ * @param color - The Three.js Color to convert
61
+ * @returns A Uint8Array with the RGBA values
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const color = fromColor(new Color(0, 1, 0))
66
+ * ```
67
+ */
68
+ export declare const fromColor: (color: Color) => Uint8Array<ArrayBuffer>;
69
+ /**
70
+ * Reads a byte from a uint8 color array at `offset` and normalizes it to 0-1.
71
+ * Returns `fallback` when the array has fewer than `offset + 1` elements.
72
+ *
73
+ * @param bytes - ArrayLike of uint8 color values
74
+ * @param fallback - Value to return when no alpha byte is present (default 1)
75
+ * @param offset - Byte index to read from (default 3, the alpha channel of the first color)
76
+ * @returns Normalized opacity in 0-1 range, or the fallback value
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * material.opacity = asOpacity(colors.current)
81
+ * material.opacity = asOpacity(colors.current, 1, stride + 3) // alpha of second color
82
+ * ```
83
+ */
84
+ export declare const asOpacity: (bytes: Uint8Array<ArrayBuffer>, fallback?: number, offset?: number) => number;
85
+ /**
86
+ * Returns true when `colors` contains exactly one color entry per point (RGB or RGBA).
87
+ * Use this to distinguish per-vertex color buffers from a single uniform color.
88
+ *
89
+ * @param colors - Uint8Array of packed color bytes
90
+ * @param numVertex - Number of points/vertices the color buffer should cover
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * if (isPerVertexColors(colors, positions.length / STRIDE.POSITIONS)) {
95
+ * // treat as per-vertex
96
+ * } else {
97
+ * addColorTraits(entityTraits, colors)
98
+ * }
99
+ * ```
100
+ */
101
+ export declare const isPerVertexColors: (colors: Uint8Array<ArrayBuffer>, numVertex: number) => boolean;
package/dist/buffer.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * Proto messages pack float32 data as `Uint8Array` (bytes fields). These utilities
5
5
  * provide efficient conversion to `Float32Array` for Three.js BufferAttributes.
6
6
  */
7
+ import { Color } from 'three';
7
8
  /**
8
9
  * Stride constants for proto binary data formats.
9
10
  * Each value represents the number of float32 elements per item.
@@ -50,22 +51,79 @@ export const asFloat32Array = (bytes) => {
50
51
  return aligned;
51
52
  };
52
53
  /**
53
- * Converts uint8 RGBA colors to normalized float32 colors (0-1 range).
54
- * Three.js expects colors in 0-1 range for BufferAttributes.
54
+ * Sets a Three.js Color from 3 bytes of a uint8 color array starting at `offset`.
55
+ * Mutates and returns `target` — pass a pre-allocated Color to avoid allocations
56
+ * in hot paths.
55
57
  *
56
- * @param colors - Uint8Array of RGBA color data [r, g, b, a, ...]
57
- * @returns Float32Array with normalized color values
58
+ * @param bytes - Uint8Array with at least `offset + 3` elements [r, g, b, ...]
59
+ * @param target - Color instance to write into
60
+ * @param offset - Byte offset to start reading from (default 0)
61
+ * @returns The mutated `target`, or black if the array has fewer than `offset + 3` elements
58
62
  *
59
63
  * @example
60
64
  * ```ts
61
- * const colors = normalizeColorsRGBA(metadata.colors)
62
- * geometry.setAttribute('color', new BufferAttribute(colors, 4))
65
+ * asColor(colors.current, material.color)
66
+ * asColor(colors.current, pointColorUtil, stride) // read second color
63
67
  * ```
64
68
  */
65
- export const normalizeColorsRGBA = (colors) => {
66
- const normalized = new Float32Array(colors.length);
67
- for (let i = 0; i < colors.length; i++) {
68
- normalized[i] = colors[i] / 255;
69
- }
70
- return normalized;
69
+ export const asColor = (bytes, target, offset = 0) => {
70
+ if (bytes.length < offset + 3)
71
+ return target.setRGB(0, 0, 0);
72
+ return target.setRGB(bytes[offset] / 255, bytes[offset + 1] / 255, bytes[offset + 2] / 255);
73
+ };
74
+ /**
75
+ * Creates a Uint8Array from a Three.js Color.
76
+ *
77
+ * @param color - The Three.js Color to convert
78
+ * @returns A Uint8Array with the RGBA values
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const color = fromColor(new Color(0, 1, 0))
83
+ * ```
84
+ */
85
+ export const fromColor = (color) => {
86
+ return new Uint8Array([
87
+ Math.round(color.r * 255),
88
+ Math.round(color.g * 255),
89
+ Math.round(color.b * 255),
90
+ ]);
91
+ };
92
+ /**
93
+ * Reads a byte from a uint8 color array at `offset` and normalizes it to 0-1.
94
+ * Returns `fallback` when the array has fewer than `offset + 1` elements.
95
+ *
96
+ * @param bytes - ArrayLike of uint8 color values
97
+ * @param fallback - Value to return when no alpha byte is present (default 1)
98
+ * @param offset - Byte index to read from (default 3, the alpha channel of the first color)
99
+ * @returns Normalized opacity in 0-1 range, or the fallback value
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * material.opacity = asOpacity(colors.current)
104
+ * material.opacity = asOpacity(colors.current, 1, stride + 3) // alpha of second color
105
+ * ```
106
+ */
107
+ export const asOpacity = (bytes, fallback = 1, offset = 3) => {
108
+ if (bytes.length < offset + 1)
109
+ return fallback;
110
+ return bytes[offset] / 255;
71
111
  };
112
+ /**
113
+ * Returns true when `colors` contains exactly one color entry per point (RGB or RGBA).
114
+ * Use this to distinguish per-vertex color buffers from a single uniform color.
115
+ *
116
+ * @param colors - Uint8Array of packed color bytes
117
+ * @param numVertex - Number of points/vertices the color buffer should cover
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * if (isPerVertexColors(colors, positions.length / STRIDE.POSITIONS)) {
122
+ * // treat as per-vertex
123
+ * } else {
124
+ * addColorTraits(entityTraits, colors)
125
+ * }
126
+ * ```
127
+ */
128
+ export const isPerVertexColors = (colors, numVertex) => colors.length === numVertex * STRIDE.COLORS_RGB ||
129
+ colors.length === numVertex * STRIDE.COLORS_RGBA;
package/dist/color.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Color, type ColorRepresentation, type RGB } from 'three';
2
1
  import { ResourceName } from '@viamrobotics/sdk';
2
+ import { Color, type ColorRepresentation, type RGB } from 'three';
3
3
  /**
4
4
  * Darkens a THREE.Color by a given percentage while preserving hue.
5
5
  * @param color The original THREE.Color instance.
package/dist/color.js CHANGED
@@ -1,6 +1,6 @@
1
- import { Color } from 'three';
2
- import twColors from 'tailwindcss/colors';
3
1
  import { ResourceName } from '@viamrobotics/sdk';
2
+ import twColors from 'tailwindcss/colors';
3
+ import { Color } from 'three';
4
4
  // Step 3: linear sRGB → sRGB
5
5
  const linearToSrgb = (x) => {
6
6
  return x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;
@@ -1,36 +1,40 @@
1
1
  <script lang="ts">
2
+ import type { Struct } from '@viamrobotics/sdk'
2
3
  import type { Snippet } from 'svelte'
4
+
5
+ import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'
3
6
  import { Canvas } from '@threlte/core'
4
7
  import { PortalTarget } from '@threlte/extras'
5
- import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'
8
+ import { useXR } from '@threlte/xr'
6
9
  import { provideToast, ToastContainer } from '@viamrobotics/prime-core'
7
- import type { Struct } from '@viamrobotics/sdk'
8
- import Scene from './Scene.svelte'
9
- import TreeContainer from './overlay/left-pane/TreeContainer.svelte'
10
+
11
+ import type { CameraPose } from '../hooks/useControls.svelte'
12
+
13
+ import Dashboard from './overlay/dashboard/Dashboard.svelte'
10
14
  import Details from './overlay/Details.svelte'
11
- import SceneProviders from './SceneProviders.svelte'
15
+ import TreeContainer from './overlay/left-pane/TreeContainer.svelte'
16
+ import Settings from './overlay/settings/Settings.svelte'
12
17
  import XR from './xr/XR.svelte'
13
- import { createPartIDContext } from '../hooks/usePartID.svelte'
14
- import Dashboard from './overlay/dashboard/Dashboard.svelte'
15
- import { domPortal } from '../portal'
16
- import { provideSettings } from '../hooks/useSettings.svelte'
17
- import FileDrop from './FileDrop/FileDrop.svelte'
18
- import { provideWeblabs } from '../hooks/useWeblabs.svelte'
19
- import { providePartConfig } from '../hooks/usePartConfig.svelte'
20
- import LiveUpdatesBanner from './overlay/LiveUpdatesBanner.svelte'
21
- import ArmPositions from './overlay/widgets/ArmPositions.svelte'
22
- import { provideEnvironment } from '../hooks/useEnvironment.svelte'
23
- import type { CameraPose } from '../hooks/useControls.svelte'
24
18
  import { provideWorld } from '../ecs'
25
19
  import {
26
- provideDrawConnectionConfig,
27
20
  type DrawConnectionConfig,
21
+ provideDrawConnectionConfig,
28
22
  } from '../hooks/useDrawConnectionConfig.svelte'
29
- import Camera from './overlay/widgets/Camera.svelte'
23
+ import { provideEnvironment } from '../hooks/useEnvironment.svelte'
24
+ import { providePartConfig } from '../hooks/usePartConfig.svelte'
25
+ import { createPartIDContext } from '../hooks/usePartID.svelte'
26
+ import { provideSettings } from '../hooks/useSettings.svelte'
27
+ import { provideWeblabs } from '../hooks/useWeblabs.svelte'
28
+ import { domPortal } from '../portal'
29
+
30
+ import FileDrop from './FileDrop/FileDrop.svelte'
30
31
  import HoveredEntities from './hover/HoveredEntities.svelte'
31
- import Settings from './overlay/settings/Settings.svelte'
32
- import { useXR } from '@threlte/xr'
32
+ import LiveUpdatesBanner from './overlay/LiveUpdatesBanner.svelte'
33
33
  import Logs from './overlay/Logs.svelte'
34
+ import ArmPositions from './overlay/widgets/ArmPositions.svelte'
35
+ import Camera from './overlay/widgets/Camera.svelte'
36
+ import Scene from './Scene.svelte'
37
+ import SceneProviders from './SceneProviders.svelte'
34
38
 
35
39
  interface LocalConfigProps {
36
40
  current: Struct
@@ -96,7 +100,7 @@
96
100
  {/if}
97
101
 
98
102
  <div
99
- class="relative h-full w-full overflow-hidden"
103
+ class="relative h-full w-full overflow-hidden dark:bg-white"
100
104
  bind:this={root}
101
105
  >
102
106
  <Canvas renderMode="on-demand">
@@ -1,5 +1,5 @@
1
- import type { Snippet } from 'svelte';
2
1
  import type { Struct } from '@viamrobotics/sdk';
2
+ import type { Snippet } from 'svelte';
3
3
  import type { CameraPose } from '../hooks/useControls.svelte';
4
4
  import { type DrawConnectionConfig } from '../hooks/useDrawConnectionConfig.svelte';
5
5
  interface LocalConfigProps {
@@ -1,11 +1,13 @@
1
1
  <script lang="ts">
2
+ import type { Entity } from 'koota'
3
+
2
4
  import { T } from '@threlte/core'
3
5
  import { Portal } from '@threlte/extras'
4
- import { BatchedArrow } from '../three/BatchedArrow'
5
- import { traits, useWorld } from '../ecs'
6
- import type { Entity } from 'koota'
7
6
  import { Color, Vector3 } from 'three'
8
7
 
8
+ import { traits, useWorld } from '../ecs'
9
+ import { BatchedArrow } from '../three/BatchedArrow'
10
+
9
11
  const arrowBatchMap = $state<Record<string, BatchedArrow>>({
10
12
  world: new BatchedArrow(),
11
13
  })
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { T } from '@threlte/core'
3
+
3
4
  import { useSettings } from '../hooks/useSettings.svelte'
4
5
 
5
6
  let { children, ...rest } = $props()
@@ -1,11 +1,13 @@
1
1
  <script lang="ts">
2
- import { MathUtils } from 'three'
3
2
  import { CameraControls, type CameraControlsRef, Gizmo, Portal } from '@threlte/extras'
4
- import { useCameraControls, useTransformControls } from '../hooks/useControls.svelte'
5
- import KeyboardControls from './KeyboardControls.svelte'
3
+ import { MathUtils } from 'three'
4
+
6
5
  import Button from './overlay/dashboard/Button.svelte'
6
+ import { useCameraControls, useTransformControls } from '../hooks/useControls.svelte'
7
7
  import { useSettings } from '../hooks/useSettings.svelte'
8
8
 
9
+ import KeyboardControls from './KeyboardControls.svelte'
10
+
9
11
  const cameraControls = useCameraControls()
10
12
  const settings = useSettings()
11
13
  const transformControls = useTransformControls()
@@ -1,10 +1,13 @@
1
1
  <script lang="ts">
2
- import { InstancedArrows } from '../../../three/InstancedArrows/InstancedArrows'
3
- import { traits, useWorld } from '../../../ecs'
4
2
  import type { Entity } from 'koota'
5
- import { STRIDE } from '../../../buffer'
3
+
6
4
  import { SvelteMap } from 'svelte/reactivity'
7
5
  import { Color } from 'three'
6
+
7
+ import { STRIDE } from '../../../buffer'
8
+ import { traits, useWorld } from '../../../ecs'
9
+ import { InstancedArrows } from '../../../three/InstancedArrows/InstancedArrows'
10
+
8
11
  import Arrows from './Arrows.svelte'
9
12
 
10
13
  const world = useWorld()
@@ -1,10 +1,13 @@
1
1
  <script lang="ts">
2
+ import type { Entity } from 'koota'
3
+
2
4
  import { T } from '@threlte/core'
3
5
  import { Portal } from '@threlte/extras'
4
- import type { Entity } from 'koota'
5
- import { traits } from '../../../ecs'
6
- import { useEntityEvents } from '../hooks/useEntityEvents.svelte'
6
+
7
7
  import type { InstancedArrows } from '../../../three/InstancedArrows/InstancedArrows'
8
+
9
+ import { useEntityEvents } from '../hooks/useEntityEvents.svelte'
10
+ import { traits } from '../../../ecs'
8
11
  import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte'
9
12
  import { meshBoundsRaycast, raycast } from '../../../three/InstancedArrows/raycast'
10
13
 
@@ -1,14 +1,16 @@
1
1
  <script lang="ts">
2
- import Pose from './Pose.svelte'
2
+ import { Not, Or } from 'koota'
3
+
4
+ import { traits, useQuery } from '../../ecs'
5
+
6
+ import Arrows from './Arrows/ArrowGroups.svelte'
3
7
  import Frame from './Frame.svelte'
8
+ import Geometry from './Geometry.svelte'
4
9
  import GLTF from './GLTF.svelte'
5
10
  import Label from './Label.svelte'
6
11
  import Line from './Line.svelte'
7
12
  import Points from './Points.svelte'
8
- import Arrows from './Arrows/ArrowGroups.svelte'
9
-
10
- import { traits, useQuery } from '../../ecs'
11
- import { Not, Or } from 'koota'
13
+ import Pose from './Pose.svelte'
12
14
 
13
15
  /**
14
16
  * Frames from a live machine are bucketed into their own query
@@ -62,9 +64,9 @@
62
64
  {/each}
63
65
 
64
66
  {#each resourceGeometriesEntities.current as entity (entity)}
65
- <Frame {entity}>
67
+ <Geometry {entity}>
66
68
  <Label text={entity.get(traits.Name)} />
67
- </Frame>
69
+ </Geometry>
68
70
  {/each}
69
71
 
70
72
  {#each worldStateEntities.current as entity (entity)}
@@ -1,17 +1,30 @@
1
+ <!--
2
+ @component
3
+
4
+ Renders a Viam Frame object
5
+ -->
6
+ <script module>
7
+ import { Color } from 'three'
8
+
9
+ const colorUtil = new Color()
10
+ </script>
11
+
1
12
  <script lang="ts">
2
- import type { Snippet } from 'svelte'
3
- import { useEntityEvents } from './hooks/useEntityEvents.svelte'
4
- import { Color, Group, type Object3D } from 'three'
5
- import Geometry from './Geometry.svelte'
6
- import { useSelectedEntity } from '../../hooks/useSelection.svelte'
7
- import { useSettings } from '../../hooks/useSettings.svelte'
8
- import { use3DModels } from '../../hooks/use3DModels.svelte'
9
- import { colors, darkenColor, resourceColors } from '../../color'
13
+ import type { Pose } from '@viamrobotics/sdk'
10
14
  import type { Entity } from 'koota'
15
+ import type { Snippet } from 'svelte'
16
+
17
+ import { T, useThrelte } from '@threlte/core'
18
+ import { Portal, PortalTarget } from '@threlte/extras'
19
+ import { Group, type Object3D } from 'three'
20
+
21
+ import { colors, resourceColors } from '../../color'
11
22
  import { traits, useTrait } from '../../ecs'
12
- import type { Pose } from '@viamrobotics/sdk'
13
23
  import { useResourceByName } from '../../hooks/useResourceByName.svelte'
14
- import { Portal, PortalTarget } from '@threlte/extras'
24
+ import { poseToObject3d } from '../../transform'
25
+
26
+ import { useEntityEvents } from './hooks/useEntityEvents.svelte'
27
+ import Mesh from './Mesh.svelte'
15
28
 
16
29
  interface Props {
17
30
  entity: Entity
@@ -21,69 +34,56 @@
21
34
 
22
35
  let { entity, pose, children }: Props = $props()
23
36
 
24
- let ref = $state<Group>()
25
-
26
- const colorUtil = new Color()
27
-
28
- const settings = useSettings()
29
- const componentModels = use3DModels()
30
- const selectedEntity = useSelectedEntity()
37
+ const { invalidate } = useThrelte()
31
38
  const resourceByName = useResourceByName()
32
39
 
33
40
  const name = useTrait(() => entity, traits.Name)
34
41
  const parent = useTrait(() => entity, traits.Parent)
35
42
  const entityColor = useTrait(() => entity, traits.Color)
43
+ const entityPose = useTrait(() => entity, traits.Pose)
44
+ const center = useTrait(() => entity, traits.Center)
36
45
 
37
46
  const events = useEntityEvents(() => entity)
38
- const resourceColor = $derived.by(() => {
39
- if (!name.current) {
40
- return undefined
41
- }
42
- const subtype = resourceByName.current[name.current]?.subtype
43
- return resourceColors[subtype as keyof typeof resourceColors]
44
- })
45
47
 
46
48
  const color = $derived.by(() => {
47
49
  if (entityColor.current) {
48
- return colorUtil.set(entityColor.current.r, entityColor.current.g, entityColor.current.b)
50
+ return `#${colorUtil.set(entityColor.current.r, entityColor.current.g, entityColor.current.b).getHexString()}`
49
51
  }
52
+
53
+ const subtype = resourceByName.current[name.current ?? '']?.subtype
54
+ const resourceColor = resourceColors[subtype as keyof typeof resourceColors]
55
+
50
56
  if (resourceColor) {
51
57
  return resourceColor
52
58
  }
59
+
53
60
  return colors.default
54
61
  })
55
62
 
56
- const model = $derived.by(() => {
57
- if (!name.current) {
58
- return
59
- }
63
+ const group = new Group()
60
64
 
61
- const [componentName, id] = name.current.split(':')
62
- if (!componentName || !id) {
63
- return
65
+ const resolvedPose = $derived(pose ?? entityPose.current)
66
+ $effect.pre(() => {
67
+ if (resolvedPose) {
68
+ poseToObject3d(resolvedPose, group)
69
+ invalidate()
64
70
  }
65
- return componentModels.current?.[componentName]?.[id].clone()
66
71
  })
67
72
  </script>
68
73
 
69
74
  <Portal id={parent.current}>
70
- <Geometry
71
- bind:ref
72
- {entity}
73
- {model}
74
- {pose}
75
- renderMode={settings.current.renderArmModels}
76
- color={selectedEntity.current === entity
77
- ? `#${darkenColor(color, 75).getHexString()}`
78
- : `#${colorUtil.set(color).getHexString()}`}
79
- {...events}
80
- >
75
+ <T is={group}>
76
+ <Mesh
77
+ {entity}
78
+ {color}
79
+ {...events}
80
+ center={center.current}
81
+ />
82
+
81
83
  {#if name.current}
82
84
  <PortalTarget id={name.current} />
83
85
  {/if}
84
86
 
85
- {#if ref}
86
- {@render children?.({ ref })}
87
- {/if}
88
- </Geometry>
87
+ {@render children?.({ ref: group })}
88
+ </T>
89
89
  </Portal>
@@ -1,7 +1,7 @@
1
+ import type { Pose } from '@viamrobotics/sdk';
2
+ import type { Entity } from 'koota';
1
3
  import type { Snippet } from 'svelte';
2
4
  import { type Object3D } from 'three';
3
- import type { Entity } from 'koota';
4
- import type { Pose } from '@viamrobotics/sdk';
5
5
  interface Props {
6
6
  entity: Entity;
7
7
  pose?: Pose;
@@ -9,6 +9,7 @@ interface Props {
9
9
  ref: Object3D;
10
10
  }]>;
11
11
  }
12
+ /** Renders a Viam Frame object */
12
13
  declare const Frame: import("svelte").Component<Props, {}, "">;
13
14
  type Frame = ReturnType<typeof Frame>;
14
15
  export default Frame;
@@ -2,7 +2,7 @@
2
2
  module
3
3
  lang="ts"
4
4
  >
5
- import { GLTFLoader, DRACOLoader } from 'three/examples/jsm/Addons.js'
5
+ import { DRACOLoader, GLTFLoader } from 'three/examples/jsm/Addons.js'
6
6
 
7
7
  const dracoLoader = new DRACOLoader()
8
8
  const gltfLoader = new GLTFLoader()
@@ -12,15 +12,18 @@
12
12
  </script>
13
13
 
14
14
  <script lang="ts">
15
- import { T, type Props as ThrelteProps } from '@threlte/core'
16
- import { Portal, PortalTarget, useGltfAnimations, type ThrelteGltf } from '@threlte/extras'
15
+ import type { Entity } from 'koota'
17
16
  import type { Snippet } from 'svelte'
17
+
18
+ import { T, type Props as ThrelteProps } from '@threlte/core'
19
+ import { Portal, PortalTarget, type ThrelteGltf, useGltfAnimations } from '@threlte/extras'
18
20
  import { Group, type Object3D } from 'three'
19
- import { useEntityEvents } from './hooks/useEntityEvents.svelte'
20
- import type { Entity } from 'koota'
21
+
21
22
  import { traits, useTrait } from '../../ecs'
22
23
  import { poseToObject3d } from '../../transform'
23
24
 
25
+ import { useEntityEvents } from './hooks/useEntityEvents.svelte'
26
+
24
27
  interface Props extends ThrelteProps<Object3D> {
25
28
  entity: Entity
26
29
  children?: Snippet
@@ -1,7 +1,7 @@
1
- import { type Props as ThrelteProps } from '@threlte/core';
1
+ import type { Entity } from 'koota';
2
2
  import type { Snippet } from 'svelte';
3
+ import { type Props as ThrelteProps } from '@threlte/core';
3
4
  import { type Object3D } from 'three';
4
- import type { Entity } from 'koota';
5
5
  interface Props extends ThrelteProps<Object3D> {
6
6
  entity: Entity;
7
7
  children?: Snippet;