@viamrobotics/motion-tools 0.11.7 → 0.12.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.
- package/dist/WorldObject.svelte.d.ts +12 -24
- package/dist/WorldObject.svelte.js +1 -1
- package/dist/components/App.svelte +32 -25
- package/dist/components/Details.svelte +94 -10
- package/dist/components/FileDrop.svelte +5 -2
- package/dist/components/Geometry.svelte +86 -70
- package/dist/components/Geometry.svelte.d.ts +3 -3
- package/dist/components/Pointcloud.svelte +3 -3
- package/dist/components/Pointcloud.svelte.d.ts +2 -5
- package/dist/components/RefreshRate.svelte +11 -6
- package/dist/components/RefreshRate.svelte.d.ts +3 -1
- package/dist/components/SceneProviders.svelte +5 -1
- package/dist/components/StaticGeometries.svelte +2 -2
- package/dist/components/Tree/Settings.svelte +10 -4
- package/dist/components/Tree/TreeContainer.svelte +2 -0
- package/dist/components/Tree/Widgets.svelte +24 -0
- package/dist/components/Tree/Widgets.svelte.d.ts +18 -0
- package/dist/components/WorldObjects.svelte +9 -9
- package/dist/components/shared/Table.svelte +37 -0
- package/dist/components/shared/Table.svelte.d.ts +7 -0
- package/dist/components/weblab/WeblabActive.svelte +20 -0
- package/dist/components/weblab/WeblabActive.svelte.d.ts +8 -0
- package/dist/components/weblab/WeblabProvider.svelte +8 -0
- package/dist/components/weblab/WeblabProvider.svelte.d.ts +5 -0
- package/dist/components/widgets/ArmPositions.svelte +76 -0
- package/dist/components/widgets/ArmPositions.svelte.d.ts +3 -0
- package/dist/format.d.ts +1 -0
- package/dist/format.js +15 -0
- package/dist/hooks/useArmClient.svelte.d.ts +7 -0
- package/dist/hooks/useArmClient.svelte.js +36 -0
- package/dist/hooks/useArrows.svelte.d.ts +3 -0
- package/dist/hooks/useArrows.svelte.js +9 -0
- package/dist/hooks/useDrawAPI.svelte.d.ts +0 -4
- package/dist/hooks/useDrawAPI.svelte.js +34 -29
- package/dist/hooks/useFrames.svelte.js +5 -8
- package/dist/hooks/useGeometries.svelte.js +4 -7
- package/dist/hooks/useMachineSettings.svelte.d.ts +4 -0
- package/dist/hooks/useMachineSettings.svelte.js +8 -1
- package/dist/hooks/usePointclouds.svelte.js +3 -6
- package/dist/hooks/usePose.svelte.js +2 -2
- package/dist/hooks/useSettings.svelte.d.ts +1 -0
- package/dist/hooks/useSettings.svelte.js +1 -0
- package/dist/hooks/useStaticGeometries.svelte.js +1 -1
- package/dist/hooks/useWeblabs.svelte.d.ts +12 -0
- package/dist/hooks/useWeblabs.svelte.js +25 -0
- package/dist/hooks/useWorldState.svelte.d.ts +2 -38
- package/dist/three/BatchedArrow.d.ts +2 -2
- package/dist/three/BatchedArrow.js +11 -6
- package/package.json +1 -1
- package/dist/hooks/usePoses.svelte.d.ts +0 -12
- package/dist/hooks/usePoses.svelte.js +0 -63
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import type { Geometry, Pose, TransformWithUUID } from '@viamrobotics/sdk';
|
|
2
2
|
import { BatchedMesh, Box3, Object3D, Vector3, type ColorRepresentation } from 'three';
|
|
3
3
|
export type PointsGeometry = {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
center: undefined;
|
|
5
|
+
geometryType: {
|
|
6
|
+
case: 'points';
|
|
7
|
+
value: Float32Array<ArrayBuffer>;
|
|
8
|
+
};
|
|
6
9
|
};
|
|
7
10
|
export type LinesGeometry = {
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
center: undefined;
|
|
12
|
+
geometryType: {
|
|
13
|
+
case: 'line';
|
|
14
|
+
value: Float32Array;
|
|
15
|
+
};
|
|
10
16
|
};
|
|
11
|
-
export type Geometries = Geometry
|
|
17
|
+
export type Geometries = Geometry | PointsGeometry | LinesGeometry;
|
|
12
18
|
export type Metadata = {
|
|
13
19
|
colors?: Float32Array;
|
|
14
20
|
color?: ColorRepresentation;
|
|
@@ -35,22 +41,4 @@ export declare class WorldObject<T extends Geometries = Geometries> {
|
|
|
35
41
|
metadata: Metadata;
|
|
36
42
|
constructor(name: string, pose?: Pose, parent?: string, geometry?: T, metadata?: Metadata);
|
|
37
43
|
}
|
|
38
|
-
export declare const fromTransform: (transform: TransformWithUUID) => WorldObject<
|
|
39
|
-
case: undefined;
|
|
40
|
-
value?: undefined;
|
|
41
|
-
} | {
|
|
42
|
-
case: "sphere";
|
|
43
|
-
value: import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Sphere>;
|
|
44
|
-
} | {
|
|
45
|
-
case: "box";
|
|
46
|
-
value: import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").RectangularPrism>;
|
|
47
|
-
} | {
|
|
48
|
-
case: "capsule";
|
|
49
|
-
value: import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Capsule>;
|
|
50
|
-
} | {
|
|
51
|
-
case: "mesh";
|
|
52
|
-
value: import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Mesh>;
|
|
53
|
-
} | {
|
|
54
|
-
case: "pointcloud";
|
|
55
|
-
value: import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").PointCloud>;
|
|
56
|
-
}>;
|
|
44
|
+
export declare const fromTransform: (transform: TransformWithUUID) => WorldObject<import("@viamrobotics/sdk").PlainMessage<import("@viamrobotics/sdk/dist/gen/common/v1/common_pb").Geometry>>;
|
|
@@ -61,7 +61,7 @@ export const fromTransform = (transform) => {
|
|
|
61
61
|
const metadata = transform.metadata
|
|
62
62
|
? parseMetadata(transform.metadata.fields)
|
|
63
63
|
: {};
|
|
64
|
-
const worldObject = new WorldObject(transform.referenceFrame, transform.poseInObserverFrame?.pose, transform.poseInObserverFrame?.referenceFrame, transform.physicalObject
|
|
64
|
+
const worldObject = new WorldObject(transform.referenceFrame, transform.poseInObserverFrame?.pose, transform.poseInObserverFrame?.referenceFrame, transform.physicalObject, metadata);
|
|
65
65
|
worldObject.uuid = transform.uuidString;
|
|
66
66
|
return worldObject;
|
|
67
67
|
};
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
import { domPortal } from '../portal'
|
|
16
16
|
import { provideSettings } from '../hooks/useSettings.svelte'
|
|
17
17
|
import FileDrop from './FileDrop.svelte'
|
|
18
|
-
|
|
18
|
+
import WeblabProvider from './weblab/WeblabProvider.svelte'
|
|
19
|
+
import ArmPositions from './widgets/ArmPositions.svelte'
|
|
19
20
|
interface Props {
|
|
20
21
|
partID?: string
|
|
21
22
|
enableKeybindings?: boolean
|
|
@@ -41,32 +42,38 @@
|
|
|
41
42
|
<SvelteQueryDevtools initialIsOpen />
|
|
42
43
|
{/if}
|
|
43
44
|
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
<WeblabProvider>
|
|
46
|
+
<div
|
|
47
|
+
class="relative h-full w-full overflow-hidden"
|
|
48
|
+
bind:this={root}
|
|
49
|
+
>
|
|
50
|
+
<Canvas renderMode="always">
|
|
51
|
+
<World>
|
|
52
|
+
<SceneProviders>
|
|
53
|
+
{#snippet children({ focus })}
|
|
54
|
+
<Scene>
|
|
55
|
+
{@render appChildren?.()}
|
|
56
|
+
</Scene>
|
|
57
|
+
|
|
58
|
+
<XR {@attach domPortal(root)} />
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
<Dashboard {@attach domPortal(root)} />
|
|
61
|
+
<Details {@attach domPortal(root)} />
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
{#if !focus}
|
|
64
|
+
<TreeContainer {@attach domPortal(root)} />
|
|
65
|
+
{/if}
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
{#if !focus && settings.current.enableArmPositionsWidget}
|
|
68
|
+
<ArmPositions {@attach domPortal(root)} />
|
|
69
|
+
{/if}
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
<FileDrop {@attach domPortal(root)} />
|
|
72
|
+
{/snippet}
|
|
73
|
+
</SceneProviders>
|
|
74
|
+
</World>
|
|
75
|
+
</Canvas>
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
</div>
|
|
77
|
+
<ToastContainer />
|
|
78
|
+
</div>
|
|
79
|
+
</WeblabProvider>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
useSelectedObject3d,
|
|
23
23
|
} from '../hooks/useSelection.svelte'
|
|
24
24
|
import { useDraggable } from '../hooks/useDraggable.svelte'
|
|
25
|
-
|
|
25
|
+
import WeblabActive from './weblab/WeblabActive.svelte'
|
|
26
26
|
const { ...rest } = $props()
|
|
27
27
|
|
|
28
28
|
const focused = useFocused()
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
const worldPosition = $state({ x: 0, y: 0, z: 0 })
|
|
38
38
|
const worldOrientation = $state({ x: 0, y: 0, z: 1, th: 0 })
|
|
39
39
|
|
|
40
|
+
const localPose = $derived(object?.pose)
|
|
41
|
+
const referenceFrame = $derived(object?.referenceFrame ?? 'world')
|
|
42
|
+
|
|
40
43
|
let copied = $state(false)
|
|
41
44
|
|
|
42
45
|
const draggable = useDraggable('details')
|
|
@@ -157,11 +160,77 @@
|
|
|
157
160
|
</div>
|
|
158
161
|
{/if}
|
|
159
162
|
|
|
163
|
+
<WeblabActive experiment="MOTION_TOOLS_EDIT_FRAME">
|
|
164
|
+
{#if localPose}
|
|
165
|
+
<div>
|
|
166
|
+
<strong class="font-semibold">local position</strong>
|
|
167
|
+
|
|
168
|
+
<div class="flex gap-3">
|
|
169
|
+
<div>
|
|
170
|
+
<span
|
|
171
|
+
class="text-subtle-2"
|
|
172
|
+
aria-label="local position x coordinate">x</span
|
|
173
|
+
>
|
|
174
|
+
{localPose.x.toFixed(2)}
|
|
175
|
+
</div>
|
|
176
|
+
<div>
|
|
177
|
+
<span
|
|
178
|
+
class="text-subtle-2"
|
|
179
|
+
aria-label="local position y coordinate">y</span
|
|
180
|
+
>
|
|
181
|
+
{localPose.y.toFixed(2)}
|
|
182
|
+
</div>
|
|
183
|
+
<div>
|
|
184
|
+
<span
|
|
185
|
+
class="text-subtle-2"
|
|
186
|
+
aria-label="local position z coordinate">z</span
|
|
187
|
+
>
|
|
188
|
+
{localPose.z.toFixed(2)}
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div>
|
|
194
|
+
<strong class="font-semibold">local orientation</strong>
|
|
195
|
+
<div class="flex gap-3">
|
|
196
|
+
<div>
|
|
197
|
+
<span
|
|
198
|
+
class="text-subtle-2"
|
|
199
|
+
aria-label="local orientation x coordinate">x</span
|
|
200
|
+
>
|
|
201
|
+
{localPose.oX.toFixed(2)}
|
|
202
|
+
</div>
|
|
203
|
+
<div>
|
|
204
|
+
<span
|
|
205
|
+
class="text-subtle-2"
|
|
206
|
+
aria-label="local orientation y coordinate">y</span
|
|
207
|
+
>
|
|
208
|
+
{localPose.oY.toFixed(2)}
|
|
209
|
+
</div>
|
|
210
|
+
<div>
|
|
211
|
+
<span
|
|
212
|
+
class="text-subtle-2"
|
|
213
|
+
aria-label="local orientation z coordinate">z</span
|
|
214
|
+
>
|
|
215
|
+
{localPose.oZ.toFixed(2)}
|
|
216
|
+
</div>
|
|
217
|
+
<div>
|
|
218
|
+
<span
|
|
219
|
+
class="text-subtle-2"
|
|
220
|
+
aria-label="local orientation theta degrees">th</span
|
|
221
|
+
>
|
|
222
|
+
{localPose.theta.toFixed(2)}
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
{/if}
|
|
227
|
+
</WeblabActive>
|
|
228
|
+
|
|
160
229
|
{#if geometry}
|
|
161
|
-
{#if geometry.case === 'box'}
|
|
162
|
-
{@const { dimsMm } = geometry.value}
|
|
230
|
+
{#if geometry.geometryType.case === 'box'}
|
|
231
|
+
{@const { dimsMm } = geometry.geometryType.value}
|
|
163
232
|
<div>
|
|
164
|
-
<strong class="font-semibold">dimensions</strong>
|
|
233
|
+
<strong class="font-semibold">dimensions (box)</strong>
|
|
165
234
|
<div class="flex gap-3">
|
|
166
235
|
<div>
|
|
167
236
|
<span class="text-subtle-2">x</span>
|
|
@@ -177,10 +246,10 @@
|
|
|
177
246
|
</div>
|
|
178
247
|
</div>
|
|
179
248
|
</div>
|
|
180
|
-
{:else if geometry.case === 'capsule'}
|
|
181
|
-
{@const { value } = geometry}
|
|
249
|
+
{:else if geometry.geometryType.case === 'capsule'}
|
|
250
|
+
{@const { value } = geometry.geometryType}
|
|
182
251
|
<div>
|
|
183
|
-
<strong class="font-semibold">dimensions</strong>
|
|
252
|
+
<strong class="font-semibold">dimensions (capsule)</strong>
|
|
184
253
|
<div class="flex gap-3">
|
|
185
254
|
<div>
|
|
186
255
|
<span class="text-subtle-2">r</span>
|
|
@@ -192,20 +261,35 @@
|
|
|
192
261
|
</div>
|
|
193
262
|
</div>
|
|
194
263
|
</div>
|
|
195
|
-
{:else if geometry.case === 'sphere'}
|
|
264
|
+
{:else if geometry.geometryType.case === 'sphere'}
|
|
196
265
|
<div class="flex justify-between">
|
|
197
266
|
<div>
|
|
198
|
-
<strong class="font-semibold">dimensions</strong>
|
|
267
|
+
<strong class="font-semibold">dimensions (sphere)</strong>
|
|
199
268
|
<div class="flex gap-3">
|
|
200
269
|
<div>
|
|
201
270
|
<span class="text-subtle-2">r</span>
|
|
202
|
-
{geometry.value.radiusMm.toFixed(2)}
|
|
271
|
+
{geometry.geometryType.value.radiusMm.toFixed(2)}
|
|
203
272
|
</div>
|
|
204
273
|
</div>
|
|
205
274
|
</div>
|
|
206
275
|
</div>
|
|
207
276
|
{/if}
|
|
208
277
|
{/if}
|
|
278
|
+
|
|
279
|
+
<WeblabActive experiment="MOTION_TOOLS_EDIT_FRAME">
|
|
280
|
+
<div>
|
|
281
|
+
<strong class="font-semibold">parent frame</strong>
|
|
282
|
+
<div class="flex gap-3">
|
|
283
|
+
<div>
|
|
284
|
+
<span
|
|
285
|
+
class="text-subtle-2"
|
|
286
|
+
aria-label="parent frame name">name</span
|
|
287
|
+
>
|
|
288
|
+
{referenceFrame}
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
</WeblabActive>
|
|
209
293
|
</div>
|
|
210
294
|
|
|
211
295
|
<h3 class="text-subtle-2 pt-3 pb-2">Actions</h3>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { T, type Props as ThrelteProps } from '@threlte/core'
|
|
3
3
|
import { type Snippet } from 'svelte'
|
|
4
4
|
import { meshBounds, MeshLineGeometry, MeshLineMaterial } from '@threlte/extras'
|
|
5
|
-
import { BufferGeometry, DoubleSide, FrontSide,
|
|
5
|
+
import { BufferGeometry, DoubleSide, FrontSide, Group, Mesh } from 'three'
|
|
6
6
|
import { CapsuleGeometry } from '../three/CapsuleGeometry'
|
|
7
7
|
import { poseToObject3d } from '../transform'
|
|
8
8
|
import { colors, darkenColor } from '../color'
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
const plyLoader = new PLYLoader()
|
|
14
14
|
|
|
15
|
-
interface Props extends ThrelteProps<
|
|
15
|
+
interface Props extends ThrelteProps<Group> {
|
|
16
16
|
uuid: string
|
|
17
17
|
name: string
|
|
18
18
|
geometry?: WorldObject['geometry']
|
|
19
19
|
pose: WorldObject['pose']
|
|
20
20
|
metadata: WorldObject['metadata']
|
|
21
|
-
children?: Snippet<[{ ref:
|
|
21
|
+
children?: Snippet<[{ ref: Group }]>
|
|
22
22
|
color?: string
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -33,19 +33,31 @@
|
|
|
33
33
|
...rest
|
|
34
34
|
}: Props = $props()
|
|
35
35
|
|
|
36
|
-
const type = $derived(geometry?.case)
|
|
36
|
+
const type = $derived(geometry?.geometryType?.case)
|
|
37
|
+
const color = $derived(overrideColor ?? metadata.color ?? colors.default)
|
|
38
|
+
|
|
39
|
+
const group = new Group()
|
|
37
40
|
const mesh = $derived.by(() => {
|
|
38
|
-
|
|
41
|
+
if (type === undefined) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
const result = new Mesh()
|
|
39
45
|
|
|
40
46
|
if (type === 'mesh' || type === 'points' || type === 'line') {
|
|
41
|
-
|
|
47
|
+
result.raycast = meshBounds
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
return
|
|
50
|
+
return result
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
$effect.pre(() => {
|
|
54
|
+
if (geometry?.center && mesh) {
|
|
55
|
+
poseToObject3d(geometry.center, mesh)
|
|
56
|
+
}
|
|
45
57
|
})
|
|
46
58
|
|
|
47
59
|
$effect.pre(() => {
|
|
48
|
-
poseToObject3d(pose,
|
|
60
|
+
poseToObject3d(pose, group)
|
|
49
61
|
})
|
|
50
62
|
|
|
51
63
|
let geo = $state.raw<BufferGeometry>()
|
|
@@ -53,75 +65,79 @@
|
|
|
53
65
|
const oncreate = (ref: BufferGeometry) => {
|
|
54
66
|
geo = ref
|
|
55
67
|
}
|
|
56
|
-
|
|
57
|
-
const color = $derived(overrideColor ?? metadata.color ?? colors.default)
|
|
58
68
|
</script>
|
|
59
69
|
|
|
60
70
|
<T
|
|
61
|
-
is={
|
|
62
|
-
{name}
|
|
63
|
-
{uuid}
|
|
71
|
+
is={group}
|
|
64
72
|
{...rest}
|
|
65
|
-
bvh={{ enabled: false }}
|
|
66
73
|
>
|
|
67
|
-
|
|
68
|
-
{
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/>
|
|
74
|
-
{:else if geometry?.case === 'line' && metadata.points}
|
|
75
|
-
<MeshLineGeometry points={metadata.points} />
|
|
76
|
-
{:else if geometry?.case === 'box'}
|
|
77
|
-
{@const dimsMm = geometry.value.dimsMm ?? { x: 0, y: 0, z: 0 }}
|
|
78
|
-
<T.BoxGeometry
|
|
79
|
-
args={[dimsMm.x * 0.001, dimsMm.y * 0.001, dimsMm.z * 0.001]}
|
|
80
|
-
{oncreate}
|
|
81
|
-
/>
|
|
82
|
-
{:else if geometry?.case === 'sphere'}
|
|
83
|
-
{@const radiusMm = geometry.value.radiusMm ?? 0}
|
|
84
|
-
<T.SphereGeometry
|
|
85
|
-
args={[radiusMm * 0.001]}
|
|
86
|
-
{oncreate}
|
|
87
|
-
/>
|
|
88
|
-
{:else if geometry?.case === 'capsule'}
|
|
89
|
-
{@const { lengthMm, radiusMm } = geometry.value}
|
|
74
|
+
<AxesHelper
|
|
75
|
+
width={3}
|
|
76
|
+
length={0.1}
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
{#if geometry?.geometryType}
|
|
90
80
|
<T
|
|
91
|
-
is={
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
81
|
+
is={mesh}
|
|
82
|
+
{name}
|
|
83
|
+
{uuid}
|
|
84
|
+
bvh={{ enabled: false }}
|
|
85
|
+
>
|
|
86
|
+
{#if geometry.geometryType.case === 'mesh'}
|
|
87
|
+
{@const mesh = geometry.geometryType.value.mesh as Uint8Array<ArrayBuffer>}
|
|
88
|
+
{@const meshGeometry = plyLoader.parse(typeof mesh === 'string' ? atob(mesh) : mesh.buffer)}
|
|
89
|
+
<T
|
|
90
|
+
is={meshGeometry}
|
|
91
|
+
{oncreate}
|
|
92
|
+
/>
|
|
93
|
+
{:else if geometry.geometryType.case === 'line' && metadata.points}
|
|
94
|
+
<MeshLineGeometry points={metadata.points} />
|
|
95
|
+
{:else if geometry.geometryType.case === 'box'}
|
|
96
|
+
{@const dimsMm = geometry.geometryType.value.dimsMm ?? { x: 0, y: 0, z: 0 }}
|
|
97
|
+
<T.BoxGeometry
|
|
98
|
+
args={[dimsMm.x * 0.001, dimsMm.y * 0.001, dimsMm.z * 0.001]}
|
|
99
|
+
{oncreate}
|
|
100
|
+
/>
|
|
101
|
+
{:else if geometry.geometryType.case === 'sphere'}
|
|
102
|
+
{@const radiusMm = geometry.geometryType.value.radiusMm ?? 0}
|
|
103
|
+
<T.SphereGeometry
|
|
104
|
+
args={[radiusMm * 0.001]}
|
|
105
|
+
{oncreate}
|
|
106
|
+
/>
|
|
107
|
+
{:else if geometry.geometryType.case === 'capsule'}
|
|
108
|
+
{@const { lengthMm, radiusMm } = geometry.geometryType.value}
|
|
109
|
+
<T
|
|
110
|
+
is={CapsuleGeometry}
|
|
111
|
+
args={[radiusMm * 0.001, lengthMm * 0.001]}
|
|
112
|
+
{oncreate}
|
|
113
|
+
/>
|
|
114
|
+
{:else}{/if}
|
|
115
|
+
|
|
116
|
+
{#if geometry.geometryType.case === 'line'}
|
|
117
|
+
<MeshLineMaterial
|
|
118
|
+
{color}
|
|
119
|
+
width={metadata.lineWidth ?? 0.005}
|
|
120
|
+
/>
|
|
121
|
+
{:else}
|
|
122
|
+
<T.MeshToonMaterial
|
|
123
|
+
{color}
|
|
124
|
+
side={geometry.geometryType.case === 'mesh' ? DoubleSide : FrontSide}
|
|
125
|
+
transparent
|
|
126
|
+
opacity={metadata.opacity ?? 0.7}
|
|
127
|
+
/>
|
|
101
128
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
/>
|
|
114
|
-
|
|
115
|
-
{#if geo}
|
|
116
|
-
<T.LineSegments
|
|
117
|
-
raycast={() => null}
|
|
118
|
-
bvh={{ enabled: false }}
|
|
119
|
-
>
|
|
120
|
-
<T.EdgesGeometry args={[geo, 0]} />
|
|
121
|
-
<T.LineBasicMaterial color={darkenColor(color, 10)} />
|
|
122
|
-
</T.LineSegments>
|
|
123
|
-
{/if}
|
|
129
|
+
{#if geo}
|
|
130
|
+
<T.LineSegments
|
|
131
|
+
raycast={() => null}
|
|
132
|
+
bvh={{ enabled: false }}
|
|
133
|
+
>
|
|
134
|
+
<T.EdgesGeometry args={[geo, 0]} />
|
|
135
|
+
<T.LineBasicMaterial color={darkenColor(color, 10)} />
|
|
136
|
+
</T.LineSegments>
|
|
137
|
+
{/if}
|
|
138
|
+
{/if}
|
|
139
|
+
</T>
|
|
124
140
|
{/if}
|
|
125
141
|
|
|
126
|
-
{@render children?.({ ref:
|
|
142
|
+
{@render children?.({ ref: group })}
|
|
127
143
|
</T>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { type Props as ThrelteProps } from '@threlte/core';
|
|
2
2
|
import { type Snippet } from 'svelte';
|
|
3
|
-
import {
|
|
3
|
+
import { Group } from 'three';
|
|
4
4
|
import type { WorldObject } from '../WorldObject.svelte';
|
|
5
|
-
interface Props extends ThrelteProps<
|
|
5
|
+
interface Props extends ThrelteProps<Group> {
|
|
6
6
|
uuid: string;
|
|
7
7
|
name: string;
|
|
8
8
|
geometry?: WorldObject['geometry'];
|
|
9
9
|
pose: WorldObject['pose'];
|
|
10
10
|
metadata: WorldObject['metadata'];
|
|
11
11
|
children?: Snippet<[{
|
|
12
|
-
ref:
|
|
12
|
+
ref: Group;
|
|
13
13
|
}]>;
|
|
14
14
|
color?: string;
|
|
15
15
|
}
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
OrthographicCamera,
|
|
8
8
|
} from 'three'
|
|
9
9
|
import { T, useTask, useThrelte } from '@threlte/core'
|
|
10
|
-
import type { WorldObject } from '../WorldObject.svelte'
|
|
10
|
+
import type { PointsGeometry, WorldObject } from '../WorldObject.svelte'
|
|
11
11
|
import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
|
|
12
12
|
import { poseToObject3d } from '../transform'
|
|
13
13
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
14
14
|
import type { Snippet } from 'svelte'
|
|
15
15
|
|
|
16
16
|
interface Props {
|
|
17
|
-
object: WorldObject<
|
|
17
|
+
object: WorldObject<PointsGeometry>
|
|
18
18
|
children?: Snippet
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
const colors = $derived(object.metadata.colors)
|
|
27
27
|
const pointSize = $derived(object.metadata.pointSize ?? settings.current.pointSize)
|
|
28
|
-
const positions = $derived(object.geometry?.value ?? new Float32Array())
|
|
28
|
+
const positions = $derived(object.geometry?.geometryType?.value ?? new Float32Array())
|
|
29
29
|
const orthographic = $derived(settings.current.cameraMode === 'orthographic')
|
|
30
30
|
|
|
31
31
|
const points = new Points()
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { WorldObject } from '../WorldObject.svelte';
|
|
1
|
+
import type { PointsGeometry, WorldObject } from '../WorldObject.svelte';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
interface Props {
|
|
4
|
-
object: WorldObject<
|
|
5
|
-
case: 'points';
|
|
6
|
-
value: Float32Array<ArrayBuffer>;
|
|
7
|
-
}>;
|
|
4
|
+
object: WorldObject<PointsGeometry>;
|
|
8
5
|
children?: Snippet;
|
|
9
6
|
}
|
|
10
7
|
declare const Pointcloud: import("svelte").Component<Props, {}, "">;
|
|
@@ -4,23 +4,25 @@
|
|
|
4
4
|
import type { Snippet } from 'svelte'
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
-
|
|
7
|
+
id: string
|
|
8
|
+
label: string
|
|
9
|
+
allowLive?: boolean
|
|
8
10
|
children?: Snippet
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
let {
|
|
13
|
+
let { id, label, allowLive = false, children }: Props = $props()
|
|
12
14
|
|
|
13
15
|
const { refreshRates } = useMachineSettings()
|
|
14
|
-
const rate = $derived(refreshRates.get(
|
|
16
|
+
const rate = $derived(refreshRates.get(id))
|
|
15
17
|
</script>
|
|
16
18
|
|
|
17
19
|
<label class="flex flex-col gap-1">
|
|
18
|
-
{
|
|
20
|
+
{label}
|
|
19
21
|
<Select
|
|
20
22
|
onchange={(event: InputEvent) => {
|
|
21
23
|
if (event.target instanceof HTMLSelectElement) {
|
|
22
24
|
const { value } = event.target
|
|
23
|
-
refreshRates.set(
|
|
25
|
+
refreshRates.set(id, Number.parseInt(value, 10))
|
|
24
26
|
}
|
|
25
27
|
}}
|
|
26
28
|
value={String(rate ?? '')}
|
|
@@ -30,12 +32,15 @@
|
|
|
30
32
|
{:else}
|
|
31
33
|
<option value="-1">Do not fetch</option>
|
|
32
34
|
<option value="0">Do not refresh</option>
|
|
35
|
+
{#if allowLive}
|
|
36
|
+
<option value="17">60fps</option>
|
|
37
|
+
<option value="33">30fps</option>
|
|
38
|
+
{/if}
|
|
33
39
|
<option value="500">Refresh every 0.5 second</option>
|
|
34
40
|
<option value="1000">Refresh every second</option>
|
|
35
41
|
<option value="2000">Refresh every 2 seconds</option>
|
|
36
42
|
<option value="5000">Refresh every 5 seconds</option>
|
|
37
43
|
<option value="10000">Refresh every 10 seconds</option>
|
|
38
|
-
<option value="30000">Refresh every 30 seconds</option>
|
|
39
44
|
{/if}
|
|
40
45
|
</Select>
|
|
41
46
|
</label>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
2
3
|
import { provideFrames } from '../hooks/useFrames.svelte'
|
|
3
4
|
import { provideGeometries } from '../hooks/useGeometries.svelte'
|
|
4
5
|
import { providePointclouds } from '../hooks/usePointclouds.svelte'
|
|
@@ -9,12 +10,13 @@
|
|
|
9
10
|
import { provideDrawAPI } from '../hooks/useDrawAPI.svelte'
|
|
10
11
|
import { provideMachineSettings } from '../hooks/useMachineSettings.svelte'
|
|
11
12
|
import { provideTransformControls } from '../hooks/useControls.svelte'
|
|
12
|
-
import type { Snippet } from 'svelte'
|
|
13
13
|
import { provideObjects } from '../hooks/useObjects.svelte'
|
|
14
14
|
import { provideMotionClient } from '../hooks/useMotionClient.svelte'
|
|
15
15
|
import { provideLogs } from '../hooks/useLogs.svelte'
|
|
16
16
|
import { provideOrigin } from './xr/useOrigin.svelte'
|
|
17
17
|
import { provideWorldStates } from '../hooks/useWorldState.svelte'
|
|
18
|
+
import { provideArmClient } from '../hooks/useArmClient.svelte'
|
|
19
|
+
import { provideArrows } from '../hooks/useArrows.svelte'
|
|
18
20
|
interface Props {
|
|
19
21
|
children: Snippet<[{ focus: boolean }]>
|
|
20
22
|
}
|
|
@@ -28,6 +30,7 @@
|
|
|
28
30
|
provideMachineSettings()
|
|
29
31
|
provideLogs()
|
|
30
32
|
|
|
33
|
+
provideArrows()
|
|
31
34
|
provideOrigin()
|
|
32
35
|
provideStaticGeometries()
|
|
33
36
|
provideDrawAPI()
|
|
@@ -38,6 +41,7 @@
|
|
|
38
41
|
provideMotionClient(() => partID.current)
|
|
39
42
|
provideObjects()
|
|
40
43
|
provideWorldStates()
|
|
44
|
+
provideArmClient(() => partID.current)
|
|
41
45
|
|
|
42
46
|
const { focus } = provideSelection()
|
|
43
47
|
</script>
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
} else if (mode === 'rotate') {
|
|
60
60
|
quaternionToPose(ref.getWorldQuaternion(quaternion), object.pose)
|
|
61
61
|
ref.quaternion.copy(quaternion)
|
|
62
|
-
} else if (mode === 'scale' && object.geometry?.case === 'box') {
|
|
63
|
-
scaleToDimensions(ref.scale, object.geometry)
|
|
62
|
+
} else if (mode === 'scale' && object.geometry?.geometryType.case === 'box') {
|
|
63
|
+
scaleToDimensions(ref.scale, object.geometry.geometryType)
|
|
64
64
|
ref.scale.setScalar(1)
|
|
65
65
|
}
|
|
66
66
|
}}
|