@viamrobotics/motion-tools 0.19.1 → 1.0.2
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 +56 -26
- package/dist/FrameConfigUpdater.svelte.d.ts +11 -17
- package/dist/FrameConfigUpdater.svelte.js +109 -109
- package/dist/WorldObject.svelte.js +2 -15
- package/dist/common/v1/common_pb.d.ts +950 -0
- package/dist/common/v1/common_pb.js +1399 -0
- package/dist/components/App.svelte +37 -21
- package/dist/components/App.svelte.d.ts +1 -0
- package/dist/components/BatchedArrows.svelte +102 -0
- package/dist/components/BatchedArrows.svelte.d.ts +3 -0
- package/dist/components/CameraControls.svelte +2 -3
- package/dist/components/Details.svelte +364 -365
- package/dist/components/Entities.svelte +73 -0
- package/dist/components/{WorldObjects.svelte.d.ts → Entities.svelte.d.ts} +3 -3
- package/dist/components/FileDrop.svelte +9 -23
- package/dist/components/Focus.svelte +2 -3
- package/dist/components/Frame.svelte +41 -22
- package/dist/components/Frame.svelte.d.ts +4 -6
- package/dist/components/GLTF.svelte +36 -0
- package/dist/components/GLTF.svelte.d.ts +11 -0
- package/dist/components/Geometry2.svelte +201 -0
- package/dist/components/Geometry2.svelte.d.ts +18 -0
- package/dist/components/KeyboardControls.svelte +3 -3
- package/dist/components/Line.svelte +10 -13
- package/dist/components/Line.svelte.d.ts +2 -2
- package/dist/components/LiveUpdatesBanner.svelte +51 -15
- package/dist/components/MeasureTool.svelte +4 -5
- package/dist/components/Pointcloud.svelte +27 -14
- package/dist/components/Pointcloud.svelte.d.ts +2 -2
- package/dist/components/PointerMissBox.svelte +3 -3
- package/dist/components/Pose.svelte +31 -6
- package/dist/components/Pose.svelte.d.ts +2 -2
- package/dist/components/Scene.svelte +7 -6
- package/dist/components/SceneProviders.svelte +0 -6
- package/dist/components/Selected.svelte +22 -16
- package/dist/components/StaticGeometries.svelte +51 -27
- package/dist/components/Tree/Tree.svelte +28 -22
- package/dist/components/Tree/Tree.svelte.d.ts +2 -3
- package/dist/components/Tree/TreeContainer.svelte +72 -40
- package/dist/components/Tree/Widgets.svelte +2 -5
- package/dist/components/Tree/buildTree.d.ts +3 -6
- package/dist/components/Tree/buildTree.js +19 -39
- package/dist/components/__tests__/__fixtures__/entity.d.ts +2 -0
- package/dist/components/__tests__/__fixtures__/entity.js +20 -0
- package/dist/components/__tests__/__fixtures__/resource.d.ts +17 -0
- package/dist/components/__tests__/__fixtures__/resource.js +13 -0
- package/dist/components/dashboard/Dashboard.svelte +5 -3
- package/dist/components/dashboard/Dashboard.svelte.d.ts +7 -2
- package/dist/components/widgets/ArmPositions.svelte +19 -7
- package/dist/draw/v1/drawing_pb.d.ts +341 -0
- package/dist/draw/v1/drawing_pb.js +417 -0
- package/dist/draw/v1/metadata_pb.d.ts +23 -0
- package/dist/draw/v1/metadata_pb.js +39 -0
- package/dist/draw/v1/scene_pb.d.ts +230 -0
- package/dist/draw/v1/scene_pb.js +298 -0
- package/dist/draw/v1/snapshot_pb.d.ts +42 -0
- package/dist/draw/v1/snapshot_pb.js +61 -0
- package/dist/draw/v1/transforms_pb.d.ts +23 -0
- package/dist/draw/v1/transforms_pb.js +39 -0
- package/dist/ecs/index.d.ts +4 -0
- package/dist/ecs/index.js +4 -0
- package/dist/ecs/traits.d.ts +128 -0
- package/dist/ecs/traits.js +81 -0
- package/dist/ecs/useQuery.svelte.d.ts +4 -0
- package/dist/ecs/useQuery.svelte.js +49 -0
- package/dist/ecs/useTrait.svelte.d.ts +19 -0
- package/dist/ecs/useTrait.svelte.js +40 -0
- package/dist/ecs/useWorld.d.ts +4 -0
- package/dist/ecs/useWorld.js +10 -0
- package/dist/frame.d.ts +2 -0
- package/dist/frame.js +14 -0
- package/dist/geometry.js +6 -6
- package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte +41 -0
- package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte.d.ts +6 -0
- package/dist/hooks/use3DModels.svelte.js +6 -4
- package/dist/hooks/useDrawAPI.svelte.d.ts +0 -10
- package/dist/hooks/useDrawAPI.svelte.js +144 -267
- package/dist/hooks/useFramelessComponents.svelte.js +1 -1
- package/dist/hooks/useFrames.svelte.d.ts +6 -2
- package/dist/hooks/useFrames.svelte.js +144 -68
- package/dist/hooks/useGeometries.svelte.d.ts +0 -2
- package/dist/hooks/useGeometries.svelte.js +49 -25
- package/dist/hooks/useObjectEvents.svelte.d.ts +3 -2
- package/dist/hooks/useObjectEvents.svelte.js +11 -7
- package/dist/hooks/usePartConfig.svelte.d.ts +1 -1
- package/dist/hooks/usePartConfig.svelte.js +2 -1
- package/dist/hooks/usePointclouds.svelte.d.ts +0 -2
- package/dist/hooks/usePointclouds.svelte.js +52 -21
- package/dist/hooks/usePose.svelte.js +15 -7
- package/dist/hooks/useResizable.svelte.d.ts +12 -0
- package/dist/hooks/useResizable.svelte.js +45 -0
- package/dist/hooks/useResourceByName.svelte.js +8 -5
- package/dist/hooks/useSelection.svelte.d.ts +13 -23
- package/dist/hooks/useSelection.svelte.js +45 -65
- package/dist/hooks/useVisibility.svelte.d.ts +2 -1
- package/dist/hooks/useWeblabs.svelte.d.ts +0 -1
- package/dist/hooks/useWeblabs.svelte.js +0 -1
- package/dist/hooks/useWorldState.svelte.d.ts +9 -0
- package/dist/hooks/useWorldState.svelte.js +158 -107
- package/dist/lib.d.ts +1 -0
- package/dist/lib.js +2 -0
- package/dist/three/BatchedArrow.d.ts +2 -3
- package/dist/three/BatchedArrow.js +3 -11
- package/dist/three/CapsuleGeometry.d.ts +1 -1
- package/dist/three/CapsuleGeometry.js +3 -1
- package/dist/transform.js +0 -15
- package/package.json +12 -7
- package/dist/components/WorldObject.svelte +0 -28
- package/dist/components/WorldObject.svelte.d.ts +0 -11
- package/dist/components/WorldObjects.svelte +0 -159
- package/dist/components/WorldState.svelte +0 -92
- package/dist/components/WorldState.svelte.d.ts +0 -7
- package/dist/components/__tests__/__fixtures__/worldObject.svelte.d.ts +0 -2
- package/dist/components/__tests__/__fixtures__/worldObject.svelte.js +0 -35
- package/dist/components/portal/Portal.svelte +0 -25
- package/dist/components/portal/Portal.svelte.d.ts +0 -8
- package/dist/components/portal/PortalTarget.svelte +0 -18
- package/dist/components/portal/PortalTarget.svelte.d.ts +0 -6
- package/dist/components/portal/index.d.ts +0 -2
- package/dist/components/portal/index.js +0 -2
- package/dist/components/portal/usePortalContext.svelte.d.ts +0 -5
- package/dist/components/portal/usePortalContext.svelte.js +0 -5
- package/dist/hooks/useArrows.svelte.d.ts +0 -3
- package/dist/hooks/useArrows.svelte.js +0 -9
- package/dist/hooks/useDraggable.svelte.d.ts +0 -10
- package/dist/hooks/useDraggable.svelte.js +0 -36
- package/dist/hooks/useObjects.svelte.d.ts +0 -7
- package/dist/hooks/useObjects.svelte.js +0 -35
- package/dist/hooks/usePersistentUUIDs.svelte.d.ts +0 -5
- package/dist/hooks/usePersistentUUIDs.svelte.js +0 -13
- package/dist/hooks/useResourceByName.svelte.d.ts +0 -7
- package/dist/hooks/useStaticGeometries.svelte.d.ts +0 -9
- package/dist/hooks/useStaticGeometries.svelte.js +0 -47
- package/dist/workers/worldStateWorker.d.ts +0 -1
- package/dist/workers/worldStateWorker.js +0 -114
- package/dist/world-state-messages.d.ts +0 -23
- package/dist/world-state-messages.js +0 -1
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { VirtualList } from 'svelte-virtuallists'
|
|
10
10
|
import { observe } from '@threlte/core'
|
|
11
11
|
import { Icon } from '@viamrobotics/prime-core'
|
|
12
|
+
import { traits } from '../../ecs'
|
|
12
13
|
|
|
13
14
|
const visibility = useVisibility()
|
|
14
15
|
const expanded = useExpanded()
|
|
@@ -16,21 +17,26 @@
|
|
|
16
17
|
interface Props {
|
|
17
18
|
rootNode: TreeNode
|
|
18
19
|
selections: string[]
|
|
20
|
+
dragElement?: HTMLElement
|
|
19
21
|
onSelectionChange?: (event: tree.SelectionChangeDetails) => void
|
|
20
|
-
onDragStart?: (event: MouseEvent) => void
|
|
21
|
-
onDragEnd?: (event: MouseEvent) => void
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
let { rootNode, selections, onSelectionChange,
|
|
24
|
+
let { rootNode, selections, onSelectionChange, dragElement = $bindable() }: Props = $props()
|
|
25
25
|
|
|
26
|
-
const collection =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const collection = $derived(
|
|
27
|
+
tree.collection<TreeNode>({
|
|
28
|
+
nodeToValue: (node) => `${node.entity}`,
|
|
29
|
+
nodeToString: (node) => node.entity.get(traits.Name) ?? '',
|
|
30
|
+
rootNode,
|
|
31
|
+
})
|
|
32
|
+
)
|
|
31
33
|
|
|
34
|
+
const id = $props.id()
|
|
32
35
|
const service = useMachine(tree.machine, {
|
|
33
|
-
|
|
36
|
+
id,
|
|
37
|
+
get collection() {
|
|
38
|
+
return collection
|
|
39
|
+
},
|
|
34
40
|
onSelectionChange(details) {
|
|
35
41
|
onSelectionChange?.(details)
|
|
36
42
|
},
|
|
@@ -46,7 +52,10 @@
|
|
|
46
52
|
|
|
47
53
|
observe(
|
|
48
54
|
() => [selections],
|
|
49
|
-
() =>
|
|
55
|
+
() =>
|
|
56
|
+
untrack(() => {
|
|
57
|
+
api.setSelectedValue(selections)
|
|
58
|
+
})
|
|
50
59
|
)
|
|
51
60
|
|
|
52
61
|
observe(
|
|
@@ -68,7 +77,7 @@
|
|
|
68
77
|
})}
|
|
69
78
|
{@const nodeProps = { indexPath, node }}
|
|
70
79
|
{@const nodeState = api.getNodeState(nodeProps)}
|
|
71
|
-
{@const isVisible = visibility.get(node.
|
|
80
|
+
{@const isVisible = visibility.get(node.entity) ?? true}
|
|
72
81
|
{@const { selected } = nodeState}
|
|
73
82
|
|
|
74
83
|
{#if nodeState.isBranch}
|
|
@@ -93,14 +102,14 @@
|
|
|
93
102
|
class="flex items-center"
|
|
94
103
|
{...api.getBranchTextProps(nodeProps)}
|
|
95
104
|
>
|
|
96
|
-
{node.
|
|
105
|
+
{node.entity.get(traits.Name)}
|
|
97
106
|
</span>
|
|
98
107
|
|
|
99
108
|
<button
|
|
100
109
|
class="text-gray-6"
|
|
101
110
|
onclick={(event) => {
|
|
102
111
|
event.stopPropagation()
|
|
103
|
-
visibility.set(node.
|
|
112
|
+
visibility.set(node.entity, !isVisible)
|
|
104
113
|
}}
|
|
105
114
|
>
|
|
106
115
|
{#if isVisible}
|
|
@@ -113,7 +122,7 @@
|
|
|
113
122
|
<div {...api.getBranchContentProps(nodeProps)}>
|
|
114
123
|
<div {...api.getBranchIndentGuideProps(nodeProps)}></div>
|
|
115
124
|
|
|
116
|
-
{#each children as node, index (node.
|
|
125
|
+
{#each children as node, index (node.entity)}
|
|
117
126
|
{@render treeNode({ node, indexPath: [...indexPath, index], api })}
|
|
118
127
|
{/each}
|
|
119
128
|
</div>
|
|
@@ -124,14 +133,14 @@
|
|
|
124
133
|
{...api.getItemProps(nodeProps)}
|
|
125
134
|
>
|
|
126
135
|
<span class="flex items-center gap-1.5">
|
|
127
|
-
{node.
|
|
136
|
+
{node.entity.get(traits.Name)}
|
|
128
137
|
</span>
|
|
129
138
|
|
|
130
139
|
<button
|
|
131
140
|
class="text-gray-6"
|
|
132
141
|
onclick={(event) => {
|
|
133
142
|
event.stopPropagation()
|
|
134
|
-
visibility.set(node.
|
|
143
|
+
visibility.set(node.entity, !isVisible)
|
|
135
144
|
}}
|
|
136
145
|
>
|
|
137
146
|
{#if isVisible}
|
|
@@ -147,13 +156,10 @@
|
|
|
147
156
|
<div class="root-node">
|
|
148
157
|
<div {...api.getRootProps() as object}>
|
|
149
158
|
<div class="border-medium flex items-center gap-1 border-b p-2">
|
|
150
|
-
<button
|
|
151
|
-
onmousedown={onDragStart}
|
|
152
|
-
onmouseup={onDragEnd}
|
|
153
|
-
>
|
|
159
|
+
<button bind:this={dragElement}>
|
|
154
160
|
<Icon name="drag" />
|
|
155
161
|
</button>
|
|
156
|
-
<h3 {...api.getLabelProps() as object}>{rootNode.
|
|
162
|
+
<h3 {...api.getLabelProps() as object}>{rootNode.entity.get(traits.Name)}</h3>
|
|
157
163
|
</div>
|
|
158
164
|
|
|
159
165
|
<div {...api.getTreeProps()}>
|
|
@@ -174,7 +180,7 @@
|
|
|
174
180
|
style="height:{Math.min(8, Math.max(rootChildren.length, 5)) * 32}px;"
|
|
175
181
|
class="overflow-auto"
|
|
176
182
|
>
|
|
177
|
-
{#each rootChildren as node, index (node.
|
|
183
|
+
{#each rootChildren as node, index (node.entity)}
|
|
178
184
|
{@render treeNode({ node, indexPath: [Number(index)], api })}
|
|
179
185
|
{/each}
|
|
180
186
|
</div>
|
|
@@ -3,10 +3,9 @@ import type { TreeNode } from './buildTree';
|
|
|
3
3
|
interface Props {
|
|
4
4
|
rootNode: TreeNode;
|
|
5
5
|
selections: string[];
|
|
6
|
+
dragElement?: HTMLElement;
|
|
6
7
|
onSelectionChange?: (event: tree.SelectionChangeDetails) => void;
|
|
7
|
-
onDragStart?: (event: MouseEvent) => void;
|
|
8
|
-
onDragEnd?: (event: MouseEvent) => void;
|
|
9
8
|
}
|
|
10
|
-
declare const Tree: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
declare const Tree: import("svelte").Component<Props, {}, "dragElement">;
|
|
11
10
|
type Tree = ReturnType<typeof Tree>;
|
|
12
11
|
export default Tree;
|
|
@@ -1,74 +1,106 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Vector2Like } from 'three'
|
|
3
|
+
import { draggable } from '@neodrag/svelte'
|
|
2
4
|
import Tree from './Tree.svelte'
|
|
3
|
-
|
|
4
|
-
import { buildTreeNodes, type TreeNode } from './buildTree'
|
|
5
|
-
import { useSelected } from '../../hooks/useSelection.svelte'
|
|
5
|
+
import { useSelectedEntity } from '../../hooks/useSelection.svelte'
|
|
6
6
|
import { provideTreeExpandedContext } from './useExpanded.svelte'
|
|
7
|
-
import { isEqual } from 'lodash-es'
|
|
8
|
-
import { useObjects } from '../../hooks/useObjects.svelte'
|
|
9
7
|
import Settings from './Settings.svelte'
|
|
10
8
|
import Logs from './Logs.svelte'
|
|
11
|
-
import { useDraggable } from '../../hooks/useDraggable.svelte'
|
|
12
|
-
import { useWorldStates } from '../../hooks/useWorldState.svelte'
|
|
13
9
|
import Widgets from './Widgets.svelte'
|
|
14
10
|
import AddFrames from './AddFrames.svelte'
|
|
15
11
|
import { useEnvironment } from '../../hooks/useEnvironment.svelte'
|
|
16
12
|
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
17
13
|
import { usePartConfig } from '../../hooks/usePartConfig.svelte'
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
14
|
+
import { traits, useWorld } from '../../ecs'
|
|
15
|
+
import { IsExcluded, type Entity } from 'koota'
|
|
16
|
+
import { buildTreeNodes, type TreeNode } from './buildTree'
|
|
17
|
+
import { MIN_DIMENSIONS, useResizable } from '../../hooks/useResizable.svelte'
|
|
18
|
+
import { PersistedState } from 'runed'
|
|
19
|
+
|
|
20
20
|
const { ...rest } = $props()
|
|
21
21
|
|
|
22
|
+
const dragPosition = new PersistedState<Vector2Like | undefined>('tree-drag-position', undefined)
|
|
23
|
+
|
|
22
24
|
provideTreeExpandedContext()
|
|
23
25
|
|
|
26
|
+
let container = $state.raw<HTMLDivElement>()
|
|
27
|
+
let dragElement = $state.raw<HTMLElement>()
|
|
28
|
+
|
|
24
29
|
const partID = usePartID()
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const draggable = useDraggable('treeview')
|
|
28
|
-
const worldStates = useWorldStates()
|
|
30
|
+
const selectedEntity = useSelectedEntity()
|
|
31
|
+
const resizable = useResizable(() => 'treeview')
|
|
29
32
|
const environment = useEnvironment()
|
|
30
33
|
const partConfig = usePartConfig()
|
|
34
|
+
const world = useWorld()
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const worldEntity = world.spawn(IsExcluded, traits.Name('World'))
|
|
37
|
+
|
|
38
|
+
let children = $state<TreeNode[]>([])
|
|
39
|
+
|
|
40
|
+
let pending = false
|
|
41
|
+
const flush = () => {
|
|
42
|
+
if (pending) return
|
|
43
|
+
pending = true
|
|
44
|
+
window.setTimeout(() => {
|
|
45
|
+
children = buildTreeNodes(world.query(traits.Name))
|
|
46
|
+
pending = false
|
|
47
|
+
})
|
|
48
|
+
}
|
|
38
49
|
|
|
39
|
-
|
|
50
|
+
world.onAdd(traits.Name, flush)
|
|
51
|
+
world.onAdd(traits.Parent, flush)
|
|
52
|
+
world.onRemove(traits.Name, flush)
|
|
53
|
+
world.onRemove(traits.Parent, flush)
|
|
54
|
+
world.onChange(traits.Name, flush)
|
|
55
|
+
world.onChange(traits.Parent, flush)
|
|
40
56
|
|
|
41
|
-
$
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
const rootNode = $derived<TreeNode>({
|
|
58
|
+
entity: worldEntity,
|
|
59
|
+
children,
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
$effect(() => {
|
|
63
|
+
if (container) {
|
|
64
|
+
resizable.observe(container)
|
|
44
65
|
}
|
|
45
66
|
})
|
|
46
67
|
</script>
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
69
|
+
{#if resizable.isLoaded}
|
|
70
|
+
<div
|
|
71
|
+
bind:this={container}
|
|
72
|
+
class="bg-extralight border-medium absolute top-0 left-0 z-1000 m-2 resize overflow-y-auto border text-xs"
|
|
73
|
+
style:min-width="{MIN_DIMENSIONS.width}px"
|
|
74
|
+
style:min-height="{MIN_DIMENSIONS.height}px"
|
|
75
|
+
style:width={resizable.current ? `${resizable.current.width}px` : undefined}
|
|
76
|
+
style:height={resizable.current ? `${resizable.current.height}px` : undefined}
|
|
77
|
+
use:draggable={{
|
|
78
|
+
bounds: 'body',
|
|
79
|
+
handle: dragElement,
|
|
80
|
+
defaultPosition: dragPosition.current,
|
|
81
|
+
onDragEnd(data) {
|
|
82
|
+
dragPosition.current = { x: data.offsetX, y: data.offsetY }
|
|
83
|
+
},
|
|
84
|
+
}}
|
|
85
|
+
{...rest}
|
|
86
|
+
>
|
|
54
87
|
<Tree
|
|
55
88
|
{rootNode}
|
|
56
|
-
|
|
89
|
+
bind:dragElement
|
|
90
|
+
selections={selectedEntity.current ? [`${selectedEntity.current}`] : []}
|
|
57
91
|
onSelectionChange={(event) => {
|
|
58
|
-
|
|
92
|
+
const value = event.selectedValue[0]
|
|
93
|
+
|
|
94
|
+
selectedEntity.set(value ? (Number(value) as Entity) : undefined)
|
|
59
95
|
}}
|
|
60
|
-
onDragStart={draggable.onDragStart}
|
|
61
|
-
onDragEnd={draggable.onDragEnd}
|
|
62
96
|
/>
|
|
63
|
-
{/key}
|
|
64
97
|
|
|
65
|
-
<WeblabActive experiment={WEBLABS_EXPERIMENTS.MOTION_TOOLS_EDIT_FRAME}>
|
|
66
98
|
{#if environment.current.isStandalone && partID.current && partConfig.hasEditPermissions}
|
|
67
99
|
<AddFrames />
|
|
68
100
|
{/if}
|
|
69
|
-
</WeblabActive>
|
|
70
101
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</div>
|
|
102
|
+
<Logs />
|
|
103
|
+
<Settings />
|
|
104
|
+
<Widgets />
|
|
105
|
+
</div>
|
|
106
|
+
{/if}
|
|
@@ -6,11 +6,8 @@
|
|
|
6
6
|
const settings = useSettings()
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
|
-
<Drawer
|
|
10
|
-
|
|
11
|
-
defaultOpen
|
|
12
|
-
>
|
|
13
|
-
<div class="flex h-24 flex-col gap-2 overflow-scroll p-3">
|
|
9
|
+
<Drawer name="Widgets">
|
|
10
|
+
<div class="flex flex-col gap-2 overflow-scroll p-3">
|
|
14
11
|
<div class="flex items-center justify-between gap-4 py-2">
|
|
15
12
|
Arm positions
|
|
16
13
|
<Switch
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { WorldObject } from '../../WorldObject.svelte';
|
|
1
|
+
import type { Entity, QueryResult, Trait } from 'koota';
|
|
3
2
|
export interface TreeNode {
|
|
4
|
-
|
|
5
|
-
name: string;
|
|
3
|
+
entity: Entity;
|
|
6
4
|
children?: TreeNode[];
|
|
7
|
-
href: string;
|
|
8
5
|
}
|
|
9
6
|
/**
|
|
10
7
|
* Creates a tree representing parent child / relationships from a set of frames.
|
|
11
8
|
*/
|
|
12
|
-
export declare const buildTreeNodes: (
|
|
9
|
+
export declare const buildTreeNodes: (entities: QueryResult<[Trait]>) => TreeNode[];
|
|
@@ -1,52 +1,32 @@
|
|
|
1
|
+
import { traits } from '../../ecs';
|
|
1
2
|
/**
|
|
2
3
|
* Creates a tree representing parent child / relationships from a set of frames.
|
|
3
4
|
*/
|
|
4
|
-
export const buildTreeNodes = (
|
|
5
|
+
export const buildTreeNodes = (entities) => {
|
|
5
6
|
const nodeMap = new Map();
|
|
6
7
|
const rootNodes = [];
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
nodeMap.set(object.name, node);
|
|
15
|
-
if (object.referenceFrame === 'world') {
|
|
8
|
+
const childNodes = [];
|
|
9
|
+
for (const entity of entities) {
|
|
10
|
+
const parent = entity.get(traits.Parent);
|
|
11
|
+
const name = entity.get(traits.Name) ?? '';
|
|
12
|
+
const node = { entity };
|
|
13
|
+
nodeMap.set(name, node);
|
|
14
|
+
if (!parent || parent === 'world') {
|
|
16
15
|
rootNodes.push(node);
|
|
17
16
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (object.referenceFrame && object.referenceFrame !== 'world') {
|
|
21
|
-
const parentNode = nodeMap.get(object.referenceFrame);
|
|
22
|
-
const child = nodeMap.get(object.name);
|
|
23
|
-
if (parentNode && child) {
|
|
24
|
-
parentNode.children?.push(child);
|
|
25
|
-
}
|
|
17
|
+
else {
|
|
18
|
+
childNodes.push(node);
|
|
26
19
|
}
|
|
27
20
|
}
|
|
28
|
-
for (const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const child = {
|
|
37
|
-
name: object.name,
|
|
38
|
-
id: object.uuid,
|
|
39
|
-
children: [],
|
|
40
|
-
href: `/world-state/${worldState.name}/${object.name}`,
|
|
41
|
-
};
|
|
42
|
-
const parentNode = object.referenceFrame && nodeMap.has(object.referenceFrame)
|
|
43
|
-
? nodeMap.get(object.referenceFrame)
|
|
44
|
-
: node;
|
|
45
|
-
nodeMap.set(object.name, child);
|
|
46
|
-
parentNode.children?.push(child);
|
|
21
|
+
for (const node of childNodes) {
|
|
22
|
+
const parent = node.entity.get(traits.Parent);
|
|
23
|
+
if (parent) {
|
|
24
|
+
const parentNode = nodeMap.get(parent);
|
|
25
|
+
if (parentNode) {
|
|
26
|
+
parentNode.children ??= [];
|
|
27
|
+
parentNode.children?.push(node);
|
|
28
|
+
}
|
|
47
29
|
}
|
|
48
|
-
nodeMap.set(worldState.name, node);
|
|
49
|
-
rootNodes.push(node);
|
|
50
30
|
}
|
|
51
31
|
return rootNodes;
|
|
52
32
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { traits } from '../../../ecs';
|
|
2
|
+
export const createEntityFixture = (world) => {
|
|
3
|
+
return world.spawn(traits.Parent('parent_frame'), traits.Name('Test Object'), traits.Pose({
|
|
4
|
+
x: 10,
|
|
5
|
+
y: 20,
|
|
6
|
+
z: 30,
|
|
7
|
+
oX: 0.1,
|
|
8
|
+
oY: 0.2,
|
|
9
|
+
oZ: 0.3,
|
|
10
|
+
theta: 0.4,
|
|
11
|
+
}), traits.EditedPose({
|
|
12
|
+
x: 10,
|
|
13
|
+
y: 20,
|
|
14
|
+
z: 30,
|
|
15
|
+
oX: 0.1,
|
|
16
|
+
oY: 0.2,
|
|
17
|
+
oZ: 0.3,
|
|
18
|
+
theta: 0.4,
|
|
19
|
+
}), traits.Box({ x: 0.01, y: 0.02, z: 0.03 }));
|
|
20
|
+
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
3
|
-
import PortalTarget from '
|
|
3
|
+
import { PortalTarget } from '@threlte/extras'
|
|
4
4
|
import Button from './Button.svelte'
|
|
5
5
|
|
|
6
|
-
let { ...rest } = $props()
|
|
6
|
+
let { dashboard, ...rest } = $props()
|
|
7
7
|
|
|
8
8
|
const settings = useSettings()
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
11
|
<div
|
|
12
|
-
class="absolute top-2 z-
|
|
12
|
+
class="absolute top-2 z-10 flex w-full justify-center gap-2"
|
|
13
13
|
{...rest}
|
|
14
14
|
>
|
|
15
15
|
<!-- camera view -->
|
|
@@ -83,4 +83,6 @@
|
|
|
83
83
|
{/if}
|
|
84
84
|
|
|
85
85
|
<PortalTarget id="dashboard" />
|
|
86
|
+
|
|
87
|
+
{@render dashboard?.()}
|
|
86
88
|
</div>
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export default Dashboard;
|
|
2
2
|
type Dashboard = {
|
|
3
3
|
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
-
$set?(props: Partial
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
5
|
};
|
|
6
|
-
declare const Dashboard: import("svelte").Component<
|
|
6
|
+
declare const Dashboard: import("svelte").Component<{
|
|
7
|
+
dashboard: any;
|
|
8
|
+
} & Record<string, any>, {}, "">;
|
|
9
|
+
type $$ComponentProps = {
|
|
10
|
+
dashboard: any;
|
|
11
|
+
} & Record<string, any>;
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Vector2Like } from 'three'
|
|
3
|
+
import { draggable } from '@neodrag/svelte'
|
|
2
4
|
import { formatNumeric } from '../../format'
|
|
3
5
|
import Table from '../shared/Table.svelte'
|
|
4
|
-
import { useDraggable } from '../../hooks/useDraggable.svelte'
|
|
5
6
|
import { useArmClient } from '../../hooks/useArmClient.svelte'
|
|
6
7
|
import { Icon, Label, Select } from '@viamrobotics/prime-core'
|
|
8
|
+
import { PersistedState } from 'runed'
|
|
7
9
|
|
|
8
10
|
const { ...rest } = $props()
|
|
9
11
|
|
|
10
|
-
const
|
|
12
|
+
const dragPosition = new PersistedState<Vector2Like | undefined>(
|
|
13
|
+
'details-drag-position',
|
|
14
|
+
undefined
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
let dragElement = $state.raw<HTMLElement>()
|
|
18
|
+
|
|
11
19
|
const armClient = useArmClient()
|
|
12
20
|
|
|
13
21
|
let selectedArm = $state(armClient.names[0])
|
|
@@ -17,16 +25,20 @@
|
|
|
17
25
|
|
|
18
26
|
<div
|
|
19
27
|
class="bg-extralight border-medium absolute top-0 left-0 z-1000 m-2 overflow-y-auto border text-xs"
|
|
20
|
-
|
|
28
|
+
use:draggable={{
|
|
29
|
+
bounds: 'body',
|
|
30
|
+
handle: dragElement,
|
|
31
|
+
defaultPosition: dragPosition.current,
|
|
32
|
+
onDragEnd(data) {
|
|
33
|
+
dragPosition.current = { x: data.offsetX, y: data.offsetY }
|
|
34
|
+
},
|
|
35
|
+
}}
|
|
21
36
|
{...rest}
|
|
22
37
|
>
|
|
23
38
|
<div class="flex min-w-0 flex-col">
|
|
24
39
|
<div class="flex w-full items-center justify-between">
|
|
25
40
|
<div class="border-medium flex w-full items-center gap-1 border-b p-2">
|
|
26
|
-
<button
|
|
27
|
-
onmousedown={draggable.onDragStart}
|
|
28
|
-
onmouseup={draggable.onDragEnd}
|
|
29
|
-
>
|
|
41
|
+
<button bind:this={dragElement}>
|
|
30
42
|
<Icon name="drag" />
|
|
31
43
|
</button>
|
|
32
44
|
<h3>Arm positions</h3>
|