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