@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,206 +1,78 @@
1
+ <!--
2
+ @component
3
+
4
+ Renders a Viam Geometry object
5
+ -->
1
6
  <script lang="ts">
2
- import { T, useThrelte, type Props as ThrelteProps } from '@threlte/core'
3
- import { type Snippet } from 'svelte'
4
- import { meshBounds } from '@threlte/extras'
5
- import { BufferGeometry, Color, DoubleSide, FrontSide, Group, Mesh } from 'three'
6
- import { Line2, LineMaterial } from 'three/examples/jsm/Addons.js'
7
- import { CapsuleGeometry } from '../../three/CapsuleGeometry'
8
- import { colors, darkenColor } from '../../color'
9
- import AxesHelper from '../AxesHelper.svelte'
10
7
  import type { Entity } from 'koota'
8
+ import type { Snippet } from 'svelte'
9
+
10
+ import { T, useThrelte } from '@threlte/core'
11
+ import { Portal } from '@threlte/extras'
12
+
11
13
  import { traits, useTrait } from '../../ecs'
14
+ import { use3DModels } from '../../hooks/use3DModels.svelte'
15
+ import { useSettings } from '../../hooks/useSettings.svelte'
12
16
  import { poseToObject3d } from '../../transform'
13
- import type { Pose } from '@viamrobotics/sdk'
14
- import LineGeometry from './LineGeometry.svelte'
15
17
 
16
- interface Props extends ThrelteProps<Group> {
18
+ import { useEntityEvents } from './hooks/useEntityEvents.svelte'
19
+ import Mesh from './Mesh.svelte'
20
+
21
+ interface Props {
17
22
  entity: Entity
18
- color?: string
19
- model?: Group
20
- pose?: Pose
21
- renderMode?: 'model' | 'colliders' | 'colliders+model'
22
- ref?: Group
23
- children?: Snippet<[{ ref: Group }]>
23
+ children?: Snippet
24
24
  }
25
25
 
26
- let {
27
- entity,
28
- color: overrideColor,
29
- model,
30
- renderMode = 'colliders',
31
- pose,
32
- ref = $bindable(),
33
- children,
34
- ...rest
35
- }: Props = $props()
26
+ const { entity, children }: Props = $props()
36
27
 
37
- const colorUtil = new Color()
28
+ const settings = useSettings()
38
29
 
39
30
  const { invalidate } = useThrelte()
31
+ const models = use3DModels()
32
+
40
33
  const name = useTrait(() => entity, traits.Name)
41
- const entityColor = useTrait(() => entity, traits.Color)
42
- const opacity = useTrait(() => entity, traits.Opacity)
43
- const box = useTrait(() => entity, traits.Box)
44
- const capsule = useTrait(() => entity, traits.Capsule)
45
- const sphere = useTrait(() => entity, traits.Sphere)
46
- const bufferGeometry = useTrait(() => entity, traits.BufferGeometry)
47
- const linePositions = useTrait(() => entity, traits.LinePositions)
48
- const lineWidth = useTrait(() => entity, traits.LineWidth)
34
+ const parent = useTrait(() => entity, traits.Parent)
49
35
  const center = useTrait(() => entity, traits.Center)
50
- const showAxesHelper = useTrait(() => entity, traits.ShowAxesHelper)
51
- const materialProps = useTrait(() => entity, traits.Material)
52
- const renderOrder = useTrait(() => entity, traits.RenderOrder)
53
-
54
- const geometryType = $derived.by(() => {
55
- if (box.current) return 'box'
56
- if (capsule.current) return 'capsule'
57
- if (sphere.current) return 'sphere'
58
- if (bufferGeometry.current) return 'buffer'
59
- if (linePositions.current) return 'line'
60
- })
61
36
 
62
- const color = $derived.by(() => {
63
- if (overrideColor) {
64
- return overrideColor
65
- }
66
- if (entityColor.current) {
67
- return colorUtil
68
- .setRGB(entityColor.current.r, entityColor.current.g, entityColor.current.b)
69
- .getHexString()
37
+ const model = $derived.by(() => {
38
+ if (!settings.current.renderArmModels.includes('model')) {
39
+ return
70
40
  }
71
- return colors.default
72
- })
73
41
 
74
- const group = new Group()
75
- ref = group
76
-
77
- const mesh = $derived.by(() => {
78
- if (geometryType === undefined) {
42
+ if (!name.current) {
79
43
  return
80
44
  }
81
45
 
82
- const result = geometryType === 'line' ? new Line2() : new Mesh()
83
-
84
- if (geometryType === 'line') {
85
- result.raycast = meshBounds
46
+ const [componentName, id] = name.current.split(':')
47
+ if (!componentName || !id) {
48
+ return
86
49
  }
87
50
 
88
- return result
51
+ return models.current[componentName]?.[id].clone()
89
52
  })
90
53
 
91
54
  $effect.pre(() => {
92
- if (mesh && center.current) {
93
- poseToObject3d(center.current, mesh)
55
+ if (model && center.current) {
56
+ poseToObject3d(center.current, model)
94
57
  invalidate()
95
58
  }
96
59
  })
97
60
 
98
- const entityPose = useTrait(() => entity, traits.Pose)
99
- const resolvedPose = $derived(pose ?? entityPose.current)
100
- $effect.pre(() => {
101
- if (resolvedPose) {
102
- poseToObject3d(resolvedPose, group)
103
- invalidate()
104
- }
105
- })
106
-
107
- let geo = $state.raw<BufferGeometry>()
108
-
109
- const oncreate = (bufferGeometry: BufferGeometry) => {
110
- geo = bufferGeometry
111
- }
112
-
113
- $effect.pre(() => {
114
- if (mesh && bufferGeometry.current) {
115
- mesh.geometry = bufferGeometry.current
116
- oncreate(bufferGeometry.current)
117
-
118
- return () => {
119
- geo = undefined
120
- mesh?.geometry?.dispose()
121
- }
122
- }
123
- })
61
+ const events = useEntityEvents(() => entity)
124
62
  </script>
125
63
 
126
- <T
127
- is={group}
128
- {...rest}
129
- >
130
- {#if geometryType}
131
- {#if model && renderMode.includes('model')}
132
- <T is={model} />
133
- {/if}
134
-
135
- {#if !model || renderMode.includes('colliders')}
136
- <T
137
- is={mesh}
138
- name={entity}
139
- userData.name={name}
140
- renderOrder={renderOrder.current}
141
- >
142
- {#if linePositions.current}
143
- <LineGeometry positions={linePositions.current} />
144
- {:else if box.current}
145
- {@const { x, y, z } = box.current ?? { x: 0, y: 0, z: 0 }}
146
- <T.BoxGeometry
147
- args={[x * 0.001, y * 0.001, z * 0.001]}
148
- {oncreate}
149
- />
150
- {:else if sphere.current}
151
- {@const { r } = sphere.current ?? { r: 0 }}
152
- <T.SphereGeometry
153
- args={[r * 0.001]}
154
- {oncreate}
155
- />
156
- {:else if capsule.current}
157
- {@const { r, l } = capsule.current ?? { r: 0, l: 0 }}
158
- <T
159
- is={CapsuleGeometry}
160
- args={[r * 0.001, l * 0.001]}
161
- {oncreate}
162
- />
163
- {/if}
164
-
165
- {#if linePositions.current}
166
- <T
167
- is={LineMaterial}
168
- {color}
169
- width={lineWidth.current ? lineWidth.current * 0.001 : 0.5}
170
- depthTest={materialProps.current?.depthTest ?? true}
171
- />
172
- {:else}
173
- {@const currentOpacity = opacity.current ?? 0.7}
174
- <T.MeshToonMaterial
175
- {color}
176
- side={geometryType === 'buffer' ? DoubleSide : FrontSide}
177
- transparent={currentOpacity < 1}
178
- depthWrite={currentOpacity === 1}
179
- opacity={currentOpacity}
180
- depthTest={materialProps.current?.depthTest ?? true}
181
- />
182
-
183
- {#if geo && (renderMode.includes('colliders') || !model)}
184
- <T.LineSegments
185
- raycast={() => null}
186
- bvh={{ enabled: false }}
187
- >
188
- <T.EdgesGeometry args={[geo, 0]} />
189
- <T.LineBasicMaterial color={darkenColor(color, 10)} />
190
- </T.LineSegments>
191
- {/if}
192
- {/if}
193
- </T>
194
- {/if}
64
+ <Portal id={parent.current}>
65
+ {#if model}
66
+ <T is={model} />
195
67
  {/if}
196
68
 
197
- {#if showAxesHelper.current}
198
- <AxesHelper
199
- name={entity}
200
- width={3}
201
- length={0.1}
202
- />
69
+ {#if settings.current.renderArmModels.includes('colliders') || !model}
70
+ <Mesh
71
+ {entity}
72
+ center={center.current}
73
+ {...events}
74
+ >
75
+ {@render children?.()}
76
+ </Mesh>
203
77
  {/if}
204
-
205
- {@render children?.({ ref: group })}
206
- </T>
78
+ </Portal>
@@ -1,19 +1,10 @@
1
- import { type Props as ThrelteProps } from '@threlte/core';
2
- import { type Snippet } from 'svelte';
3
- import { Group } from 'three';
4
1
  import type { Entity } from 'koota';
5
- import type { Pose } from '@viamrobotics/sdk';
6
- interface Props extends ThrelteProps<Group> {
2
+ import type { Snippet } from 'svelte';
3
+ interface Props {
7
4
  entity: Entity;
8
- color?: string;
9
- model?: Group;
10
- pose?: Pose;
11
- renderMode?: 'model' | 'colliders' | 'colliders+model';
12
- ref?: Group;
13
- children?: Snippet<[{
14
- ref: Group;
15
- }]>;
5
+ children?: Snippet;
16
6
  }
17
- declare const Geometry: import("svelte").Component<Props, {}, "ref">;
7
+ /** Renders a Viam Geometry object */
8
+ declare const Geometry: import("svelte").Component<Props, {}, "">;
18
9
  type Geometry = ReturnType<typeof Geometry>;
19
10
  export default Geometry;
@@ -5,12 +5,20 @@
5
5
  </script>
6
6
 
7
7
  <script lang="ts">
8
- import Frame from './Frame.svelte'
9
- import type { Snippet } from 'svelte'
10
8
  import type { Entity } from 'koota'
9
+ import type { Snippet } from 'svelte'
10
+
11
+ import { T, useThrelte } from '@threlte/core'
12
+ import { meshBounds, Portal, PortalTarget } from '@threlte/extras'
13
+ import { Line2, LineMaterial } from 'three/examples/jsm/Addons.js'
14
+
15
+ import { darkenColor } from '../../color'
11
16
  import { traits, useTrait } from '../../ecs'
17
+ import { poseToObject3d } from '../../transform'
18
+
19
+ import { useEntityEvents } from './hooks/useEntityEvents.svelte'
12
20
  import LineDots from './LineDots.svelte'
13
- import { darkenColor } from '../../color'
21
+ import LineGeometry from './LineGeometry.svelte'
14
22
 
15
23
  interface Props {
16
24
  entity: Entity
@@ -19,25 +27,67 @@
19
27
 
20
28
  let { entity, children }: Props = $props()
21
29
 
22
- const linePositions = useTrait(() => entity, traits.LinePositions)
30
+ const { invalidate } = useThrelte()
31
+ const name = useTrait(() => entity, traits.Name)
32
+ const parent = useTrait(() => entity, traits.Parent)
33
+ const pose = useTrait(() => entity, traits.Pose)
23
34
  const color = useTrait(() => entity, traits.Color)
24
35
  const pointSize = useTrait(() => entity, traits.PointSize)
36
+ const linePositions = useTrait(() => entity, traits.LinePositions)
37
+ const lineWidth = useTrait(() => entity, traits.LineWidth)
38
+ const opacity = useTrait(() => entity, traits.Opacity)
39
+ const materialProps = useTrait(() => entity, traits.Material)
40
+ const renderOrder = useTrait(() => entity, traits.RenderOrder)
41
+
42
+ const events = useEntityEvents(() => entity)
43
+
44
+ const currentOpacity = $derived(opacity.current ?? 0.7)
45
+
46
+ const mesh = new Line2()
25
47
 
26
- const resolvedColor = $derived(
27
- colorUtil
28
- .setRGB(color.current?.r ?? 1, color.current?.g ?? 0, color.current?.b ?? 0)
29
- .getHexString()
30
- )
48
+ $effect.pre(() => {
49
+ if (pose.current) {
50
+ poseToObject3d(pose.current, mesh)
51
+ invalidate()
52
+ }
53
+ })
31
54
  </script>
32
55
 
33
- <Frame {entity}>
56
+ <Portal id={parent.current}>
57
+ <T
58
+ is={mesh}
59
+ name={entity}
60
+ userData.name={name}
61
+ raycast={meshBounds}
62
+ renderOrder={renderOrder.current}
63
+ {...events}
64
+ >
65
+ <LineGeometry positions={linePositions.current} />
66
+ <T
67
+ is={LineMaterial}
68
+ color={[color.current?.r ?? 1, color.current?.g ?? 0, color.current?.b ?? 0]}
69
+ transparent={currentOpacity < 1}
70
+ depthWrite={currentOpacity === 1}
71
+ opacity={currentOpacity}
72
+ width={lineWidth.current ? lineWidth.current * 0.001 : 0.5}
73
+ depthTest={materialProps.current?.depthTest ?? true}
74
+ />
75
+ </T>
76
+
77
+ {#if linePositions.current && pointSize.current}
78
+ <LineDots
79
+ color={darkenColor(
80
+ colorUtil.setRGB(color.current?.r ?? 1, color.current?.g ?? 0, color.current?.b ?? 0),
81
+ 10
82
+ )}
83
+ positions={linePositions.current}
84
+ scale={pointSize.current * 0.001}
85
+ />
86
+ {/if}
87
+
88
+ {#if name.current}
89
+ <PortalTarget id={name.current} />
90
+ {/if}
91
+
34
92
  {@render children?.()}
35
- </Frame>
36
-
37
- {#if linePositions.current && pointSize.current}
38
- <LineDots
39
- color={darkenColor(resolvedColor, 10)}
40
- positions={linePositions.current}
41
- scale={pointSize.current * 0.001}
42
- />
43
- {/if}
93
+ </Portal>
@@ -1,5 +1,5 @@
1
- import type { Snippet } from 'svelte';
2
1
  import type { Entity } from 'koota';
2
+ import type { Snippet } from 'svelte';
3
3
  interface Props {
4
4
  entity: Entity;
5
5
  children?: Snippet;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { T } from '@threlte/core'
3
- import { BatchedMesh, Matrix4, SphereGeometry, Vector3, type ColorRepresentation } from 'three'
3
+ import { BatchedMesh, type ColorRepresentation, Matrix4, SphereGeometry, Vector3 } from 'three'
4
4
 
5
5
  interface Props {
6
6
  color: ColorRepresentation
@@ -1,7 +1,7 @@
1
1
  <script>
2
- import { LineGeometry } from 'three/examples/jsm/Addons.js'
3
2
  import { T } from '@threlte/core'
4
3
  import { untrack } from 'svelte'
4
+ import { LineGeometry } from 'three/examples/jsm/Addons.js'
5
5
 
6
6
  let { positions } = $props()
7
7
 
@@ -0,0 +1,133 @@
1
+ <script lang="ts">
2
+ import type { Pose } from '@viamrobotics/sdk'
3
+ import type { Entity } from 'koota'
4
+
5
+ import { T, type Props as ThrelteProps, useThrelte } from '@threlte/core'
6
+ import { type Snippet } from 'svelte'
7
+ import { BufferGeometry, Color, DoubleSide, FrontSide, Mesh } from 'three'
8
+
9
+ import { colors, darkenColor } from '../../color'
10
+ import { traits, useTrait } from '../../ecs'
11
+ import { CapsuleGeometry } from '../../three/CapsuleGeometry'
12
+ import { poseToObject3d } from '../../transform'
13
+
14
+ import AxesHelper from '../AxesHelper.svelte'
15
+
16
+ interface Props extends ThrelteProps<Mesh> {
17
+ entity: Entity
18
+ color?: string
19
+ center?: Pose
20
+ children?: Snippet
21
+ }
22
+
23
+ let { entity, color: overrideColor, center, children, ...rest }: Props = $props()
24
+
25
+ const colorUtil = new Color()
26
+
27
+ const { invalidate } = useThrelte()
28
+ const name = useTrait(() => entity, traits.Name)
29
+ const entityColor = useTrait(() => entity, traits.Color)
30
+ const opacity = useTrait(() => entity, traits.Opacity)
31
+ const box = useTrait(() => entity, traits.Box)
32
+ const capsule = useTrait(() => entity, traits.Capsule)
33
+ const sphere = useTrait(() => entity, traits.Sphere)
34
+ const bufferGeometry = useTrait(() => entity, traits.BufferGeometry)
35
+ const showAxesHelper = useTrait(() => entity, traits.ShowAxesHelper)
36
+ const materialProps = useTrait(() => entity, traits.Material)
37
+ const renderOrder = useTrait(() => entity, traits.RenderOrder)
38
+
39
+ const color = $derived.by(() => {
40
+ if (overrideColor) {
41
+ return overrideColor
42
+ }
43
+
44
+ if (entityColor.current) {
45
+ return colorUtil.setRGB(entityColor.current.r, entityColor.current.g, entityColor.current.b)
46
+ }
47
+
48
+ return colors.default
49
+ })
50
+
51
+ const mesh = new Mesh()
52
+
53
+ $effect.pre(() => {
54
+ if (center) {
55
+ poseToObject3d(center, mesh)
56
+ invalidate()
57
+ }
58
+ })
59
+
60
+ let geo = $state.raw<BufferGeometry>()
61
+
62
+ const oncreate = (bufferGeometry: BufferGeometry) => {
63
+ geo = bufferGeometry
64
+ }
65
+ </script>
66
+
67
+ <T
68
+ is={mesh}
69
+ name={entity}
70
+ userData.name={name}
71
+ renderOrder={renderOrder.current}
72
+ {...rest}
73
+ >
74
+ {#if box.current}
75
+ {@const { x, y, z } = box.current ?? { x: 0, y: 0, z: 0 }}
76
+ <T.BoxGeometry
77
+ args={[x * 0.001, y * 0.001, z * 0.001]}
78
+ {oncreate}
79
+ />
80
+ {:else if sphere.current}
81
+ {@const { r } = sphere.current ?? { r: 0 }}
82
+ <T.SphereGeometry
83
+ args={[r * 0.001]}
84
+ {oncreate}
85
+ />
86
+ {:else if capsule.current}
87
+ {@const { r, l } = capsule.current ?? { r: 0, l: 0 }}
88
+ <T
89
+ is={CapsuleGeometry}
90
+ args={[r * 0.001, l * 0.001]}
91
+ {oncreate}
92
+ />
93
+ {:else if bufferGeometry.current}
94
+ <T
95
+ is={bufferGeometry.current}
96
+ {oncreate}
97
+ />
98
+ {/if}
99
+
100
+ {@const currentOpacity = opacity.current ?? 0.7}
101
+ <T.MeshToonMaterial
102
+ {color}
103
+ side={bufferGeometry.current ? DoubleSide : FrontSide}
104
+ transparent={currentOpacity < 1}
105
+ depthWrite={currentOpacity === 1}
106
+ opacity={currentOpacity}
107
+ depthTest={materialProps.current?.depthTest ?? true}
108
+ />
109
+
110
+ <!--
111
+ TODO(mp) currently some bufferGeometries are coming in empty,
112
+ this is a quick fix but this should be handled upstream
113
+ -->
114
+ {#if geo && geo.getAttribute('position').array.length > 0}
115
+ <T.LineSegments
116
+ raycast={() => null}
117
+ bvh={{ enabled: false }}
118
+ >
119
+ <T.EdgesGeometry args={[geo, 0]} />
120
+ <T.LineBasicMaterial color={darkenColor(color, 10)} />
121
+ </T.LineSegments>
122
+ {/if}
123
+
124
+ {@render children?.()}
125
+ </T>
126
+
127
+ {#if showAxesHelper.current}
128
+ <AxesHelper
129
+ name={entity}
130
+ width={3}
131
+ length={0.1}
132
+ />
133
+ {/if}
@@ -0,0 +1,4 @@
1
+ import { Mesh } from 'three';
2
+ declare const Mesh: any;
3
+ type Mesh = ReturnType<typeof Mesh>;
4
+ export default Mesh;
@@ -1,13 +1,16 @@
1
1
  <script lang="ts">
2
- import { Points, PointsMaterial, OrthographicCamera } from 'three'
2
+ import type { Entity } from 'koota'
3
+ import type { Snippet } from 'svelte'
4
+
3
5
  import { T, useTask, useThrelte } from '@threlte/core'
4
6
  import { Portal } from '@threlte/extras'
5
- import { useEntityEvents } from './hooks/useEntityEvents.svelte'
6
- import { poseToObject3d } from '../../transform'
7
- import { useSettings } from '../../hooks/useSettings.svelte'
8
- import type { Snippet } from 'svelte'
9
- import type { Entity } from 'koota'
7
+ import { OrthographicCamera, Points, PointsMaterial } from 'three'
8
+
10
9
  import { traits, useTrait } from '../../ecs'
10
+ import { useSettings } from '../../hooks/useSettings.svelte'
11
+ import { poseToObject3d } from '../../transform'
12
+
13
+ import { useEntityEvents } from './hooks/useEntityEvents.svelte'
11
14
 
12
15
  interface Props {
13
16
  entity: Entity
@@ -1,6 +1,6 @@
1
- import { Points } from 'three';
2
- import type { Snippet } from 'svelte';
3
1
  import type { Entity } from 'koota';
2
+ import type { Snippet } from 'svelte';
3
+ import { Points } from 'three';
4
4
  interface Props {
5
5
  entity: Entity;
6
6
  children?: Snippet;
@@ -1,11 +1,12 @@
1
1
  <script lang="ts">
2
- import { traits, useTrait } from '../../ecs'
3
- import { usePose } from '../../hooks/usePose.svelte'
4
- import { matrixToPose, poseToMatrix } from '../../transform'
5
2
  import type { Pose } from '@viamrobotics/sdk'
6
3
  import type { Entity } from 'koota'
7
4
  import type { Snippet } from 'svelte'
8
5
 
6
+ import { traits, useTrait } from '../../ecs'
7
+ import { usePose } from '../../hooks/usePose.svelte'
8
+ import { matrixToPose, poseToMatrix } from '../../transform'
9
+
9
10
  interface Props {
10
11
  entity: Entity
11
12
  children: Snippet<[{ pose: Pose | undefined }]>
@@ -1,5 +1,5 @@
1
- import { type IntersectionEvent } from '@threlte/extras';
2
1
  import type { Entity } from 'koota';
2
+ import { type IntersectionEvent } from '@threlte/extras';
3
3
  export declare const useEntityEvents: (entity: () => Entity | undefined) => {
4
4
  readonly visible: boolean;
5
5
  onpointerenter: (event: IntersectionEvent<MouseEvent>) => void;
@@ -1,8 +1,8 @@
1
1
  import { useCursor } from '@threlte/extras';
2
- import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte';
3
- import { useVisibility } from '../../../hooks/useVisibility.svelte';
4
2
  import { Vector2 } from 'three';
5
3
  import { traits } from '../../../ecs';
4
+ import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte';
5
+ import { useVisibility } from '../../../hooks/useVisibility.svelte';
6
6
  import { updateHoverInfo } from '../../../HoverUpdater.svelte';
7
7
  import { createPose, matrixToPose, poseToMatrix } from '../../../transform';
8
8
  export const useEntityEvents = (entity) => {
@@ -1,13 +1,17 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLAttributes } from 'svelte/elements'
3
- import { useToast, ToastVariant } from '@viamrobotics/prime-core'
4
- import { useFileDrop } from './useFileDrop.svelte'
5
- import { useWorld } from '../../ecs/useWorld'
6
- import type { FileDropperSuccess } from './file-dropper'
3
+
4
+ import { ToastVariant, useToast } from '@viamrobotics/prime-core'
5
+
6
+ import { createBufferGeometry } from '../../attribute'
7
7
  import { traits } from '../../ecs'
8
- import { spawnSnapshotEntities } from '../../snapshot'
8
+ import { useWorld } from '../../ecs/useWorld'
9
9
  import { useCameraControls } from '../../hooks/useControls.svelte'
10
- import { createBufferGeometry } from '../../attribute'
10
+ import { spawnSnapshotEntities } from '../../snapshot'
11
+
12
+ import type { FileDropperSuccess } from './file-dropper'
13
+
14
+ import { useFileDrop } from './useFileDrop.svelte'
11
15
 
12
16
  const props: HTMLAttributes<HTMLDivElement> = $props()
13
17
 
@@ -1,6 +1,6 @@
1
+ import type { BufferGeometry } from 'three';
1
2
  import type { Snapshot } from '../../buf/draw/v1/snapshot_pb';
2
3
  import type { SuccessMessage } from '../../loaders/pcd/messages';
3
- import type { BufferGeometry } from 'three';
4
4
  interface FileDropSuccess {
5
5
  success: true;
6
6
  name: string;
@@ -1,6 +1,6 @@
1
1
  import { isArrayBuffer } from 'lodash-es';
2
- import { FileDropperError } from './file-dropper';
3
2
  import { parsePcdInWorker } from '../../loaders/pcd';
3
+ import { FileDropperError } from './file-dropper';
4
4
  export const pcdDropper = async (params) => {
5
5
  const { name, content } = params;
6
6
  if (!isArrayBuffer(content)) {
@@ -1,6 +1,6 @@
1
1
  import { isArrayBuffer } from 'lodash-es';
2
- import { FileDropperError } from './file-dropper';
3
2
  import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader.js';
3
+ import { FileDropperError } from './file-dropper';
4
4
  export const plyDropper = async (params) => {
5
5
  const { name, content } = params;
6
6
  if (!isArrayBuffer(content)) {
@@ -1,5 +1,5 @@
1
- import { Snapshot } from '../../buf/draw/v1/snapshot_pb';
2
1
  import { isArrayBuffer, isString } from 'lodash-es';
2
+ import { Snapshot } from '../../buf/draw/v1/snapshot_pb';
3
3
  import { FileDropperError, } from './file-dropper';
4
4
  import { Extensions } from './file-names';
5
5
  const decodeJson = (params) => {