@viamrobotics/motion-tools 0.3.8 → 0.5.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/README.md +10 -10
- package/dist/components/App.svelte +2 -0
- package/dist/components/AxesHelper.svelte +69 -9
- package/dist/components/AxesHelper.svelte.d.ts +9 -2
- package/dist/components/Camera.svelte +5 -12
- package/dist/components/CameraControls.svelte +4 -4
- package/dist/components/CameraControls.svelte.d.ts +2 -2
- package/dist/components/Details.svelte +11 -2
- package/dist/components/Focus.svelte +0 -2
- package/dist/components/Geometry.svelte +1 -1
- package/dist/components/Scene.svelte +1 -1
- package/dist/components/SceneProviders.svelte +2 -0
- package/dist/components/Tree/Tree.svelte +11 -2
- package/dist/components/Tree/Tree.svelte.d.ts +2 -0
- package/dist/components/Tree/TreeContainer.svelte +21 -40
- package/dist/components/dashboard/Button.svelte +47 -0
- package/dist/components/dashboard/Button.svelte.d.ts +12 -0
- package/dist/components/dashboard/Dashboard.svelte +77 -0
- package/dist/components/dashboard/Dashboard.svelte.d.ts +26 -0
- package/dist/hooks/useDraggable.svelte.d.ts +10 -2
- package/dist/hooks/useDraggable.svelte.js +24 -13
- package/dist/hooks/usePointclouds.svelte.js +2 -2
- package/dist/hooks/useSettings.svelte.d.ts +9 -0
- package/dist/hooks/useSettings.svelte.js +25 -0
- package/dist/hooks/useShapes.svelte.js +2 -2
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -6
- package/dist/lib.d.ts +9 -0
- package/dist/lib.js +12 -0
- package/dist/loaders/pcd/index.d.ts +1 -1
- package/dist/loaders/pcd/index.js +1 -2
- package/dist/test/createRandomPcdBinary.d.ts +1 -0
- package/dist/test/createRandomPcdBinary.js +31 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +1 -0
- package/dist/three/OrientationVector.d.ts +71 -0
- package/dist/three/OrientationVector.js +233 -0
- package/dist/transform.js +1 -1
- package/package.json +28 -21
- package/dist/three/AxesHelper.d.ts +0 -5
- package/dist/three/AxesHelper.js +0 -35
package/README.md
CHANGED
|
@@ -11,19 +11,19 @@ Open the machine config page (bottom right) and enter in connection details to v
|
|
|
11
11
|
|
|
12
12
|
## Todo
|
|
13
13
|
|
|
14
|
-
- animated sequence
|
|
15
|
-
- double click to set trackball center
|
|
16
|
-
- Give
|
|
17
|
-
- default pointcloud color
|
|
18
|
-
- remote IP access
|
|
19
|
-
-
|
|
20
|
-
- geometries parented to parent
|
|
21
|
-
- end effector pose visualized
|
|
22
|
-
- poses of all frames
|
|
14
|
+
- animated sequence of motion plan
|
|
15
|
+
- double click to set trackball center in object view
|
|
16
|
+
- Give better fetching / connection state info
|
|
17
|
+
- Set default pointcloud color in settings
|
|
18
|
+
- remote IP access when custom drawing, to draw on remote computers
|
|
19
|
+
- points are not sized right in ortho cam view
|
|
20
|
+
- geometries need to be parented to parent
|
|
23
21
|
- bounding boxes should include just the thing and not children
|
|
24
|
-
- configure frames
|
|
22
|
+
- configure frames in app
|
|
25
23
|
- color pallet for resource to color
|
|
26
24
|
|
|
25
|
+
- foxglove / rviz
|
|
26
|
+
|
|
27
27
|
## Env files
|
|
28
28
|
|
|
29
29
|
To add a list of connection configs in an `.env.local` file, use the following format:
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import XR from './xr/XR.svelte'
|
|
12
12
|
import { World } from '@threlte/rapier'
|
|
13
13
|
import { createPartIDContext } from '../hooks/usePartID.svelte'
|
|
14
|
+
import Dashboard from './dashboard/Dashboard.svelte'
|
|
14
15
|
|
|
15
16
|
interface Props {
|
|
16
17
|
partID?: string
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
</Scene>
|
|
52
53
|
|
|
53
54
|
<DomPortal element={root}>
|
|
55
|
+
<Dashboard />
|
|
54
56
|
<Details />
|
|
55
57
|
</DomPortal>
|
|
56
58
|
|
|
@@ -1,17 +1,77 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { T, type Props as ThrelteProps } from '@threlte/core'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { Color } from 'three'
|
|
4
|
+
import { Line2 } from 'three/examples/jsm/lines/Line2.js'
|
|
5
|
+
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
|
|
6
|
+
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
|
|
7
|
+
|
|
8
|
+
interface Props extends ThrelteProps<Line2> {
|
|
9
|
+
length?: number
|
|
10
|
+
width?: number
|
|
11
|
+
axesColors?: [x: string, y: string, z: string]
|
|
12
|
+
depthTest?: boolean
|
|
8
13
|
}
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
const {
|
|
16
|
+
length = 1,
|
|
17
|
+
width = 0.1,
|
|
18
|
+
axesColors = ['red', 'green', 'blue'],
|
|
19
|
+
depthTest = true,
|
|
20
|
+
...rest
|
|
21
|
+
}: Props = $props()
|
|
22
|
+
|
|
23
|
+
const TOTAL_VERTICES = 9
|
|
24
|
+
const VERTEX_COMPONENTS = 3
|
|
25
|
+
|
|
26
|
+
const line = new Line2()
|
|
27
|
+
const material = $state(new LineMaterial())
|
|
28
|
+
const geometry = new LineGeometry()
|
|
29
|
+
const color = new Color()
|
|
30
|
+
const colors = $state(new Float32Array(TOTAL_VERTICES * VERTEX_COMPONENTS))
|
|
31
|
+
const positions = $state(new Float32Array(TOTAL_VERTICES * VERTEX_COMPONENTS))
|
|
32
|
+
|
|
33
|
+
// Assign colors per vertex
|
|
34
|
+
$effect.pre(() => {
|
|
35
|
+
for (let i = 0, l = axesColors.length; i < l; i += 1) {
|
|
36
|
+
const axis = axesColors[i]
|
|
37
|
+
|
|
38
|
+
color.set(axis)
|
|
39
|
+
|
|
40
|
+
const axisBufferStart = i * TOTAL_VERTICES
|
|
41
|
+
const axisBufferEnd = axisBufferStart + TOTAL_VERTICES
|
|
42
|
+
|
|
43
|
+
for (let j = axisBufferStart; j < axisBufferEnd; j += VERTEX_COMPONENTS) {
|
|
44
|
+
colors[j + 0] = color.r
|
|
45
|
+
colors[j + 1] = color.g
|
|
46
|
+
colors[j + 2] = color.b
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
geometry.setColors(colors)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const X_AXIS_X_COMPONENT_INDEX = 3
|
|
54
|
+
const Y_AXIS_Y_COMPONENT_INDEX = 13
|
|
55
|
+
const Z_AXIS_Z_COMPONENT_INDEX = 23
|
|
56
|
+
|
|
57
|
+
$effect.pre(() => {
|
|
58
|
+
positions[X_AXIS_X_COMPONENT_INDEX] = length
|
|
59
|
+
positions[Y_AXIS_Y_COMPONENT_INDEX] = length
|
|
60
|
+
positions[Z_AXIS_Z_COMPONENT_INDEX] = length
|
|
61
|
+
geometry.setPositions(positions)
|
|
62
|
+
})
|
|
11
63
|
</script>
|
|
12
64
|
|
|
13
65
|
<T
|
|
14
|
-
is={
|
|
15
|
-
raycast={meshBounds}
|
|
66
|
+
is={line}
|
|
16
67
|
{...rest}
|
|
17
|
-
|
|
68
|
+
raycast={() => null}
|
|
69
|
+
>
|
|
70
|
+
<T is={geometry} />
|
|
71
|
+
<T
|
|
72
|
+
is={material}
|
|
73
|
+
vertexColors
|
|
74
|
+
linewidth={width}
|
|
75
|
+
{depthTest}
|
|
76
|
+
/>
|
|
77
|
+
</T>
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { type Props as ThrelteProps } from '@threlte/core';
|
|
2
|
+
import { Line2 } from 'three/examples/jsm/lines/Line2.js';
|
|
3
|
+
interface Props extends ThrelteProps<Line2> {
|
|
4
|
+
length?: number;
|
|
5
|
+
width?: number;
|
|
6
|
+
axesColors?: [x: string, y: string, z: string];
|
|
7
|
+
depthTest?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const AxesHelper: import("svelte").Component<Props, {}, "">;
|
|
3
10
|
type AxesHelper = ReturnType<typeof AxesHelper>;
|
|
4
11
|
export default AxesHelper;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { PersistedState } from 'runed'
|
|
3
2
|
import { T } from '@threlte/core'
|
|
4
3
|
import { PerspectiveCamera, OrthographicCamera } from 'three'
|
|
4
|
+
import { useSettings } from '../hooks/useSettings.svelte'
|
|
5
5
|
|
|
6
6
|
let { children, ...rest } = $props()
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const settings = useSettings()
|
|
9
|
+
const mode = $derived(settings.current.cameraMode)
|
|
9
10
|
|
|
10
11
|
const perspective = new PerspectiveCamera()
|
|
11
12
|
perspective.near = 0.01
|
|
@@ -18,15 +19,7 @@
|
|
|
18
19
|
orthographic.zoom = 200
|
|
19
20
|
</script>
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
onkeydown={({ key }) => {
|
|
23
|
-
if (key.toLowerCase() === 'c') {
|
|
24
|
-
mode.current = mode.current === 'perspective' ? 'orthographic' : 'perspective'
|
|
25
|
-
}
|
|
26
|
-
}}
|
|
27
|
-
/>
|
|
28
|
-
|
|
29
|
-
{#if mode.current === 'perspective'}
|
|
22
|
+
{#if mode === 'perspective'}
|
|
30
23
|
<T
|
|
31
24
|
is={perspective}
|
|
32
25
|
makeDefault
|
|
@@ -34,7 +27,7 @@
|
|
|
34
27
|
>
|
|
35
28
|
{@render children?.()}
|
|
36
29
|
</T>
|
|
37
|
-
{:else if mode
|
|
30
|
+
{:else if mode === 'orthographic'}
|
|
38
31
|
<T
|
|
39
32
|
is={orthographic}
|
|
40
33
|
makeDefault
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
Vector3,
|
|
15
15
|
Vector4,
|
|
16
16
|
} from 'three'
|
|
17
|
-
import
|
|
17
|
+
import CameraController from 'camera-controls'
|
|
18
18
|
import { T, useTask, useThrelte } from '@threlte/core'
|
|
19
19
|
import type { Snippet } from 'svelte'
|
|
20
20
|
|
|
21
21
|
let installed = false
|
|
22
22
|
|
|
23
23
|
const install = () => {
|
|
24
|
-
|
|
24
|
+
CameraController.install({
|
|
25
25
|
THREE: {
|
|
26
26
|
Box3,
|
|
27
27
|
Matrix4,
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
<script lang="ts">
|
|
42
42
|
interface Props {
|
|
43
|
-
ref?:
|
|
43
|
+
ref?: CameraController
|
|
44
44
|
enabled?: boolean
|
|
45
45
|
children?: Snippet
|
|
46
46
|
}
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
|
|
54
54
|
const { camera, dom, invalidate } = useThrelte()
|
|
55
55
|
|
|
56
|
-
const controls = new
|
|
56
|
+
const controls = new CameraController(camera.current as PerspectiveCamera, dom)
|
|
57
57
|
|
|
58
58
|
$effect.pre(() => {
|
|
59
59
|
controls.camera = $camera as PerspectiveCamera
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { useSelectedObject, useFocusedObject, useFocused } from '../hooks/useSelection.svelte'
|
|
3
3
|
import { Check, Copy } from 'lucide-svelte'
|
|
4
4
|
import { Button, Icon } from '@viamrobotics/prime-core'
|
|
5
|
+
import { useDraggable } from '../hooks/useDraggable.svelte'
|
|
5
6
|
|
|
6
7
|
const focused = useFocused()
|
|
7
8
|
const selectedObject = useSelectedObject()
|
|
@@ -9,14 +10,22 @@
|
|
|
9
10
|
const object = $derived(focusedObject.current ?? selectedObject.current)
|
|
10
11
|
|
|
11
12
|
let copied = $state(false)
|
|
13
|
+
|
|
14
|
+
const draggable = useDraggable('details')
|
|
12
15
|
</script>
|
|
13
16
|
|
|
14
17
|
{#if object}
|
|
15
18
|
{@const { geometry, pose } = object}
|
|
16
|
-
<div
|
|
19
|
+
<div
|
|
20
|
+
class="border-medium bg-extralight absolute top-0 right-0 z-10 m-2 w-60 border p-2 text-xs"
|
|
21
|
+
style:transform="translate({draggable.current.x}px, {draggable.current.y}px)"
|
|
22
|
+
>
|
|
17
23
|
<div class="flex items-center justify-between gap-2 pb-2">
|
|
18
24
|
<div class="flex items-center gap-1">
|
|
19
|
-
<button
|
|
25
|
+
<button
|
|
26
|
+
onmousedown={draggable.onDragStart}
|
|
27
|
+
onmouseup={draggable.onDragEnd}
|
|
28
|
+
>
|
|
20
29
|
<Icon name="drag" />
|
|
21
30
|
</button>
|
|
22
31
|
{object.name}
|
|
@@ -14,13 +14,11 @@
|
|
|
14
14
|
const vec = new Vector3()
|
|
15
15
|
|
|
16
16
|
let center = $state.raw<[number, number, number]>([0, 0, 0])
|
|
17
|
-
// let size = $state.raw<[number, number, number]>([0, 0, 0])
|
|
18
17
|
|
|
19
18
|
$effect(() => {
|
|
20
19
|
if (object3d) {
|
|
21
20
|
box.setFromObject(object3d)
|
|
22
21
|
center = box.getCenter(vec).toArray()
|
|
23
|
-
// size = box.getSize(vec).toArray()
|
|
24
22
|
}
|
|
25
23
|
})
|
|
26
24
|
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { provideObjects } from '../hooks/useObjects.svelte'
|
|
15
15
|
import { provideMotionClient } from '../hooks/useMotionClient.svelte'
|
|
16
16
|
import { provideLogs } from '../hooks/useLogs.svelte'
|
|
17
|
+
import { provideSettings } from '../hooks/useSettings.svelte'
|
|
17
18
|
|
|
18
19
|
interface Props {
|
|
19
20
|
children: Snippet<[{ focus: boolean }]>
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
|
|
24
25
|
const partID = usePartID()
|
|
25
26
|
|
|
27
|
+
provideSettings()
|
|
26
28
|
provideTransformControls()
|
|
27
29
|
provideVisibility()
|
|
28
30
|
provideRefreshRates()
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { useExpanded } from './useExpanded.svelte'
|
|
9
9
|
import { VirtualList } from 'svelte-virtuallists'
|
|
10
10
|
import { observe } from '@threlte/core'
|
|
11
|
+
import { Icon } from '@viamrobotics/prime-core'
|
|
11
12
|
|
|
12
13
|
const visibility = useVisibility()
|
|
13
14
|
const expanded = useExpanded()
|
|
@@ -16,9 +17,11 @@
|
|
|
16
17
|
rootNode: TreeNode
|
|
17
18
|
selections: string[]
|
|
18
19
|
onSelectionChange?: (event: tree.SelectionChangeDetails) => void
|
|
20
|
+
onDragStart?: (event: MouseEvent) => void
|
|
21
|
+
onDragEnd?: (event: MouseEvent) => void
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
let { rootNode, selections, onSelectionChange }: Props = $props()
|
|
24
|
+
let { rootNode, selections, onSelectionChange, onDragStart, onDragEnd }: Props = $props()
|
|
22
25
|
|
|
23
26
|
const collection = tree.collection<TreeNode>({
|
|
24
27
|
nodeToValue: (node) => node.id,
|
|
@@ -143,7 +146,13 @@
|
|
|
143
146
|
|
|
144
147
|
<div class="root-node">
|
|
145
148
|
<div {...api.getRootProps() as object}>
|
|
146
|
-
<div class="border-medium border-b p-2">
|
|
149
|
+
<div class="border-medium flex items-center gap-1 border-b p-2">
|
|
150
|
+
<button
|
|
151
|
+
onmousedown={onDragStart}
|
|
152
|
+
onmouseup={onDragEnd}
|
|
153
|
+
>
|
|
154
|
+
<Icon name="drag" />
|
|
155
|
+
</button>
|
|
147
156
|
<h3 {...api.getLabelProps() as object}>{rootNode.name}</h3>
|
|
148
157
|
</div>
|
|
149
158
|
|
|
@@ -4,6 +4,8 @@ interface Props {
|
|
|
4
4
|
rootNode: TreeNode;
|
|
5
5
|
selections: string[];
|
|
6
6
|
onSelectionChange?: (event: tree.SelectionChangeDetails) => void;
|
|
7
|
+
onDragStart?: (event: MouseEvent) => void;
|
|
8
|
+
onDragEnd?: (event: MouseEvent) => void;
|
|
7
9
|
}
|
|
8
10
|
declare const Tree: import("svelte").Component<Props, {}, "">;
|
|
9
11
|
type Tree = ReturnType<typeof Tree>;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { PersistedState } from 'runed'
|
|
3
2
|
import Tree from './Tree.svelte'
|
|
4
|
-
|
|
5
|
-
import { Keybindings } from '../../keybindings'
|
|
6
|
-
import { ListTree } from 'lucide-svelte'
|
|
3
|
+
|
|
7
4
|
import { buildTreeNodes, type TreeNode } from './buildTree'
|
|
8
5
|
import { useSelected } from '../../hooks/useSelection.svelte'
|
|
9
6
|
import { provideTreeExpandedContext } from './useExpanded.svelte'
|
|
@@ -11,13 +8,13 @@
|
|
|
11
8
|
import { useObjects } from '../../hooks/useObjects.svelte'
|
|
12
9
|
import Settings from './Settings.svelte'
|
|
13
10
|
import Logs from './Logs.svelte'
|
|
14
|
-
|
|
15
|
-
const showTreeview = new PersistedState('show-treeview', true)
|
|
11
|
+
import { useDraggable } from '../../hooks/useDraggable.svelte'
|
|
16
12
|
|
|
17
13
|
provideTreeExpandedContext()
|
|
18
14
|
|
|
19
15
|
const selected = useSelected()
|
|
20
16
|
const objects = useObjects()
|
|
17
|
+
const draggable = useDraggable('treeview')
|
|
21
18
|
|
|
22
19
|
let rootNode = $state<TreeNode>({
|
|
23
20
|
id: 'world',
|
|
@@ -35,38 +32,22 @@
|
|
|
35
32
|
})
|
|
36
33
|
</script>
|
|
37
34
|
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
showTreeview.current = !showTreeview.current
|
|
42
|
-
}
|
|
43
|
-
}}
|
|
44
|
-
/>
|
|
45
|
-
|
|
46
|
-
<button
|
|
47
|
-
class="absolute top-2 left-2 p-2"
|
|
48
|
-
onclick={() => (showTreeview.current = !showTreeview.current)}
|
|
35
|
+
<div
|
|
36
|
+
class="bg-extralight border-medium absolute top-0 left-0 m-2 overflow-y-auto border text-xs"
|
|
37
|
+
style:transform="translate({draggable.current.x}px, {draggable.current.y}px)"
|
|
49
38
|
>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}}
|
|
66
|
-
/>
|
|
67
|
-
{/key}
|
|
68
|
-
|
|
69
|
-
<Logs />
|
|
70
|
-
<Settings />
|
|
71
|
-
</div>
|
|
72
|
-
{/if}
|
|
39
|
+
{#key rootNode}
|
|
40
|
+
<Tree
|
|
41
|
+
{rootNode}
|
|
42
|
+
selections={selected.current ? [selected.current] : []}
|
|
43
|
+
onSelectionChange={(event) => {
|
|
44
|
+
selected.set(event.selectedValue[0])
|
|
45
|
+
}}
|
|
46
|
+
onDragStart={draggable.onDragStart}
|
|
47
|
+
onDragEnd={draggable.onDragEnd}
|
|
48
|
+
/>
|
|
49
|
+
{/key}
|
|
50
|
+
|
|
51
|
+
<Logs />
|
|
52
|
+
<Settings />
|
|
53
|
+
</div>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Icon, type IconName, Tooltip } from '@viamrobotics/prime-core'
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
icon: IconName
|
|
6
|
+
active?: boolean
|
|
7
|
+
description: string
|
|
8
|
+
hotkey: string
|
|
9
|
+
class?: string
|
|
10
|
+
onclick?: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
icon,
|
|
15
|
+
active = false,
|
|
16
|
+
description,
|
|
17
|
+
hotkey,
|
|
18
|
+
class: className = '',
|
|
19
|
+
onclick,
|
|
20
|
+
}: Props = $props()
|
|
21
|
+
|
|
22
|
+
const activeClasses = 'z-10 border-gray-5 bg-white text-gray-8'
|
|
23
|
+
const inactiveClasses = 'bg-light border-medium text-disabled'
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<Tooltip
|
|
27
|
+
let:tooltipID
|
|
28
|
+
location="bottom"
|
|
29
|
+
>
|
|
30
|
+
<label
|
|
31
|
+
class={[className, 'relative block border', active ? activeClasses : inactiveClasses]}
|
|
32
|
+
aria-describedby={tooltipID}
|
|
33
|
+
>
|
|
34
|
+
<button
|
|
35
|
+
class="p-1.5"
|
|
36
|
+
role="radio"
|
|
37
|
+
aria-label={description}
|
|
38
|
+
aria-checked={active}
|
|
39
|
+
{onclick}
|
|
40
|
+
>
|
|
41
|
+
<Icon name={icon} />
|
|
42
|
+
</button>
|
|
43
|
+
</label>
|
|
44
|
+
<p slot="description">
|
|
45
|
+
{description} <span class="text-gray-5 pl-1">{hotkey}</span>
|
|
46
|
+
</p>
|
|
47
|
+
</Tooltip>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type IconName } from '@viamrobotics/prime-core';
|
|
2
|
+
interface Props {
|
|
3
|
+
icon: IconName;
|
|
4
|
+
active?: boolean;
|
|
5
|
+
description: string;
|
|
6
|
+
hotkey: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
onclick?: () => void;
|
|
9
|
+
}
|
|
10
|
+
declare const Button: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Button = ReturnType<typeof Button>;
|
|
12
|
+
export default Button;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
3
|
+
import Button from './Button.svelte'
|
|
4
|
+
|
|
5
|
+
const settings = useSettings()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<svelte:window
|
|
9
|
+
onkeydown={({ key }) => {
|
|
10
|
+
if (key.toLowerCase() === 'c') {
|
|
11
|
+
settings.current.cameraMode =
|
|
12
|
+
settings.current.cameraMode === 'perspective' ? 'orthographic' : 'perspective'
|
|
13
|
+
}
|
|
14
|
+
}}
|
|
15
|
+
/>
|
|
16
|
+
|
|
17
|
+
<div class="absolute top-2 flex w-full justify-center">
|
|
18
|
+
<!-- transform -->
|
|
19
|
+
<!-- <fieldset>
|
|
20
|
+
<Button
|
|
21
|
+
icon="cursor-move"
|
|
22
|
+
active={$transformMode === TransformModes.TRANSLATE}
|
|
23
|
+
description="Translate"
|
|
24
|
+
hotkey="T"
|
|
25
|
+
onclick={() => transformMode.set(TransformModes.TRANSLATE)}
|
|
26
|
+
/>
|
|
27
|
+
<Button
|
|
28
|
+
icon="sync"
|
|
29
|
+
active={$transformMode === TransformModes.ROTATE}
|
|
30
|
+
description="Rotate"
|
|
31
|
+
hotkey="R"
|
|
32
|
+
class="-my-px"
|
|
33
|
+
onclick={() => transformMode.set(TransformModes.ROTATE)}
|
|
34
|
+
/>
|
|
35
|
+
<Button
|
|
36
|
+
icon="resize"
|
|
37
|
+
active={$transformMode === TransformModes.SCALE}
|
|
38
|
+
description="Scale"
|
|
39
|
+
hotkey="S"
|
|
40
|
+
onclick={() => transformMode.set(TransformModes.SCALE)}
|
|
41
|
+
/>
|
|
42
|
+
</fieldset> -->
|
|
43
|
+
|
|
44
|
+
<!-- snapping -->
|
|
45
|
+
<!-- <fieldset>
|
|
46
|
+
<Button
|
|
47
|
+
icon={$snapMode ? 'magnet' : 'magnet-off'}
|
|
48
|
+
active={$snapMode === true}
|
|
49
|
+
description="Snapping"
|
|
50
|
+
hotkey="Spacebar"
|
|
51
|
+
onClick={() => snapMode.set(!$snapMode)}
|
|
52
|
+
/>
|
|
53
|
+
</fieldset> -->
|
|
54
|
+
|
|
55
|
+
<!-- camera view -->
|
|
56
|
+
<fieldset class="flex">
|
|
57
|
+
<Button
|
|
58
|
+
icon="grid-orthographic"
|
|
59
|
+
active={settings.current.cameraMode === 'orthographic'}
|
|
60
|
+
description="Orthographic view"
|
|
61
|
+
hotkey="C"
|
|
62
|
+
onclick={() => {
|
|
63
|
+
settings.current.cameraMode = 'orthographic'
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
<Button
|
|
67
|
+
icon="grid-perspective"
|
|
68
|
+
active={settings.current.cameraMode === 'perspective'}
|
|
69
|
+
description="Perspective view"
|
|
70
|
+
hotkey="C"
|
|
71
|
+
class="-ml-px"
|
|
72
|
+
onclick={() => {
|
|
73
|
+
settings.current.cameraMode = 'perspective'
|
|
74
|
+
}}
|
|
75
|
+
/>
|
|
76
|
+
</fieldset>
|
|
77
|
+
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default Dashboard;
|
|
2
|
+
type Dashboard = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Dashboard: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
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> {
|
|
15
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
+
$$bindings?: Bindings;
|
|
17
|
+
} & Exports;
|
|
18
|
+
(internal: unknown, props: {
|
|
19
|
+
$$events?: Events;
|
|
20
|
+
$$slots?: Slots;
|
|
21
|
+
}): Exports & {
|
|
22
|
+
$set?: any;
|
|
23
|
+
$on?: any;
|
|
24
|
+
};
|
|
25
|
+
z_$$bindings?: Bindings;
|
|
26
|
+
}
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
interface Context {
|
|
2
|
+
onDragStart: (event: MouseEvent) => void;
|
|
3
|
+
onDragEnd: (event: MouseEvent) => void;
|
|
4
|
+
readonly current: {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare const useDraggable: (name: string) => Context;
|
|
10
|
+
export {};
|