@viamrobotics/motion-tools 1.31.0 → 1.33.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/components/App.svelte +64 -53
- package/dist/components/App.svelte.d.ts +14 -7
- package/dist/components/Entities/Arrows/Arrows.svelte +4 -7
- package/dist/components/Entities/hooks/useEntityEvents.svelte.d.ts +0 -1
- package/dist/components/Entities/hooks/useEntityEvents.svelte.js +30 -16
- package/dist/components/InputBindings.svelte +0 -43
- package/dist/components/KeyboardBindings.svelte +38 -0
- package/dist/components/KeyboardBindings.svelte.d.ts +18 -0
- package/dist/components/PointerMissBox.svelte +6 -3
- package/dist/components/Scene.svelte +43 -61
- package/dist/components/SceneProviders.svelte +2 -7
- package/dist/components/SceneProviders.svelte.d.ts +1 -3
- package/dist/components/Selected.svelte +20 -27
- package/dist/components/SelectedTransformControls.svelte +8 -7
- package/dist/components/StaticGeometries.svelte +3 -5
- package/dist/components/hover/HoveredEntities.svelte +15 -14
- package/dist/components/hover/HoveredEntities.svelte.d.ts +17 -2
- package/dist/components/hover/HoveredEntity.svelte +8 -5
- package/dist/components/hover/HoveredEntity.svelte.d.ts +5 -1
- package/dist/components/hover/LinkedHoveredEntity.svelte +7 -11
- package/dist/components/hover/LinkedHoveredEntity.svelte.d.ts +1 -0
- package/dist/components/overlay/Details.svelte +22 -37
- package/dist/components/overlay/Details.svelte.d.ts +3 -1
- package/dist/components/overlay/controls/Controls.svelte +0 -2
- package/dist/components/overlay/dashboard/Button.svelte +5 -3
- package/dist/components/overlay/dashboard/Button.svelte.d.ts +1 -1
- package/dist/components/overlay/left-pane/Tree.svelte +13 -10
- package/dist/components/overlay/left-pane/TreeContainer.svelte +9 -4
- package/dist/components/overlay/left-pane/TreeNode.svelte +6 -4
- package/dist/components/overlay/settings/ConnectionSettings.svelte +42 -0
- package/dist/components/overlay/settings/ConnectionSettings.svelte.d.ts +18 -0
- package/dist/components/overlay/settings/DebugSettings.svelte +13 -0
- package/dist/components/{xr/frame-configure/Controllers.svelte.d.ts → overlay/settings/DebugSettings.svelte.d.ts} +3 -3
- package/dist/components/overlay/settings/PointcloudSettings.svelte +61 -0
- package/dist/components/overlay/settings/PointcloudSettings.svelte.d.ts +3 -0
- package/dist/components/overlay/settings/SceneSettings.svelte +110 -0
- package/dist/components/overlay/settings/SceneSettings.svelte.d.ts +18 -0
- package/dist/components/overlay/settings/Settings.svelte +27 -312
- package/dist/components/overlay/settings/Settings.svelte.d.ts +8 -1
- package/dist/components/overlay/settings/Tabs.svelte +5 -3
- package/dist/components/overlay/settings/Tabs.svelte.d.ts +3 -3
- package/dist/components/overlay/settings/VisionSettings.svelte +31 -0
- package/dist/components/overlay/settings/VisionSettings.svelte.d.ts +3 -0
- package/dist/components/overlay/settings/WeblabSettings.svelte +27 -0
- package/dist/components/overlay/settings/WeblabSettings.svelte.d.ts +18 -0
- package/dist/components/overlay/settings/WidgetSettings.svelte +49 -0
- package/dist/components/overlay/settings/WidgetSettings.svelte.d.ts +3 -0
- package/dist/components/overlay/widgets/FramePov.svelte +1 -12
- package/dist/draw.d.ts +1 -0
- package/dist/draw.js +1 -1
- package/dist/ecs/index.d.ts +1 -0
- package/dist/ecs/index.js +1 -0
- package/dist/ecs/traits.d.ts +22 -5
- package/dist/ecs/traits.js +33 -4
- package/dist/ecs/useTag.svelte.d.ts +5 -0
- package/dist/ecs/useTag.svelte.js +43 -0
- package/dist/hooks/useEnvironment.svelte.d.ts +1 -1
- package/dist/hooks/useLinked.svelte.js +7 -8
- package/dist/hooks/useMouseRaycaster.svelte.d.ts +4 -3
- package/dist/hooks/useMouseRaycaster.svelte.js +1 -0
- package/dist/hooks/useSettings.svelte.d.ts +1 -1
- package/dist/plugins/Focus/Focus.svelte +45 -0
- package/dist/plugins/Focus/Focus.svelte.d.ts +3 -0
- package/dist/plugins/Focus/FocusBox.svelte +75 -0
- package/dist/plugins/Focus/FocusBox.svelte.d.ts +3 -0
- package/dist/plugins/Focus/provideFocus.svelte.d.ts +1 -0
- package/dist/plugins/Focus/provideFocus.svelte.js +61 -0
- package/dist/{components → plugins}/MeasureTool/MeasureTool.svelte +6 -8
- package/dist/plugins/Selection/SelectionTool.svelte +10 -3
- package/dist/{components/xr → plugins/XR}/ArmTeleop.svelte +3 -5
- package/dist/plugins/XR/DebugPanel.svelte +29 -0
- package/dist/plugins/XR/DebugPanel.svelte.d.ts +3 -0
- package/dist/plugins/XR/OriginMarker.svelte +341 -0
- package/dist/plugins/XR/PendingEditsPanel.svelte +60 -0
- package/dist/plugins/XR/PendingEditsPanel.svelte.d.ts +18 -0
- package/dist/plugins/XR/WristDisplay.svelte +60 -0
- package/dist/plugins/XR/WristDisplay.svelte.d.ts +19 -0
- package/dist/{components/xr → plugins/XR}/XR.svelte +69 -23
- package/dist/plugins/XR/XRPlugins.svelte +9 -0
- package/dist/plugins/XR/XRPlugins.svelte.d.ts +26 -0
- package/dist/plugins/XR/XRSettings.svelte +240 -0
- package/dist/plugins/XR/XRSettings.svelte.d.ts +3 -0
- package/dist/{components/xr → plugins/XR}/XRToast.svelte +6 -9
- package/dist/plugins/XR/debug.svelte.d.ts +7 -0
- package/dist/plugins/XR/debug.svelte.js +13 -0
- package/dist/plugins/XR/frame-configure/Controllers.svelte +413 -0
- package/dist/plugins/XR/teleop/Controllers.svelte.d.ts +3 -0
- package/dist/{components/xr → plugins/XR}/useAnchors.svelte.d.ts +4 -0
- package/dist/{components/xr → plugins/XR}/useAnchors.svelte.js +22 -0
- package/dist/plugins/XR/useOrigin.svelte.d.ts +24 -0
- package/dist/plugins/XR/useOrigin.svelte.js +50 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/index.js +4 -0
- package/dist/three/OBBHelper.js +1 -0
- package/dist/three/arrow.d.ts +2 -0
- package/dist/three/arrow.js +3 -1
- package/package.json +16 -4
- package/dist/components/Focus.svelte +0 -46
- package/dist/components/Focus.svelte.d.ts +0 -7
- package/dist/components/xr/OriginMarker.svelte +0 -151
- package/dist/components/xr/XRControllerSettings.svelte +0 -242
- package/dist/components/xr/XRControllerSettings.svelte.d.ts +0 -3
- package/dist/components/xr/frame-configure/Controllers.svelte +0 -6
- package/dist/components/xr/useOrigin.svelte.d.ts +0 -9
- package/dist/components/xr/useOrigin.svelte.js +0 -27
- package/dist/hooks/useSelection.svelte.d.ts +0 -33
- package/dist/hooks/useSelection.svelte.js +0 -94
- /package/dist/{components → plugins}/MeasureTool/MeasurePoint.svelte +0 -0
- /package/dist/{components → plugins}/MeasureTool/MeasurePoint.svelte.d.ts +0 -0
- /package/dist/{components → plugins}/MeasureTool/MeasureTool.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/ArmTeleop.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/BentPlaneGeometry.svelte +0 -0
- /package/dist/{components/xr → plugins/XR}/BentPlaneGeometry.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/CameraFeed.svelte +0 -0
- /package/dist/{components/xr → plugins/XR}/CameraFeed.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/JointLimitsWidget.svelte +0 -0
- /package/dist/{components/xr → plugins/XR}/JointLimitsWidget.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/OriginMarker.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/PointDistance.svelte +0 -0
- /package/dist/{components/xr → plugins/XR}/PointDistance.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/XR.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/XRConfigPanel.svelte +0 -0
- /package/dist/{components/xr → plugins/XR}/XRConfigPanel.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/XRToast.svelte.d.ts +0 -0
- /package/dist/{components/xr/teleop → plugins/XR/frame-configure}/Controllers.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/math.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/math.js +0 -0
- /package/dist/{components/xr → plugins/XR}/teleop/Controllers.svelte +0 -0
- /package/dist/{components/xr → plugins/XR}/toasts.svelte.d.ts +0 -0
- /package/dist/{components/xr → plugins/XR}/toasts.svelte.js +0 -0
|
@@ -1,55 +1,48 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { T, useTask, useThrelte } from '@threlte/core'
|
|
3
3
|
import { BatchedMesh, Box3 } from 'three'
|
|
4
4
|
import { OBB } from 'three/addons/math/OBB.js'
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import { useSelectedEntity, useSelectedObject3d } from '../hooks/useSelection.svelte'
|
|
6
|
+
import { traits, useQuery } from '../ecs'
|
|
9
7
|
import { OBBHelper } from '../three/OBBHelper'
|
|
10
8
|
|
|
11
9
|
const box3 = new Box3()
|
|
12
10
|
const obb = new OBB()
|
|
13
|
-
const obbHelper = new OBBHelper()
|
|
14
11
|
|
|
15
|
-
const { invalidate } = useThrelte()
|
|
16
|
-
const
|
|
17
|
-
const selectedObject3d = useSelectedObject3d()
|
|
12
|
+
const { scene, invalidate } = useThrelte()
|
|
13
|
+
const selected = useQuery(traits.Selected)
|
|
18
14
|
|
|
19
|
-
const
|
|
15
|
+
const obbHelpers = $derived(selected.current.map((entity) => [entity, new OBBHelper()] as const))
|
|
20
16
|
|
|
21
17
|
useTask(
|
|
22
18
|
() => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} else {
|
|
36
|
-
obbHelper.setFromObject(object)
|
|
19
|
+
for (const [entity, obbHelper] of obbHelpers) {
|
|
20
|
+
const object = scene.getObjectByName(entity as unknown as string)
|
|
21
|
+
if (!object) continue
|
|
22
|
+
|
|
23
|
+
const instance = entity.get(traits.InstanceId)
|
|
24
|
+
if (instance !== undefined && instance >= 0) {
|
|
25
|
+
;(object as BatchedMesh).getBoundingBoxAt(instance, box3)
|
|
26
|
+
obb.fromBox3(box3)
|
|
27
|
+
obbHelper.setFromOBB(obb)
|
|
28
|
+
} else {
|
|
29
|
+
obbHelper.setFromObject(object)
|
|
30
|
+
}
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
invalidate()
|
|
40
34
|
},
|
|
41
35
|
{
|
|
42
|
-
running: () =>
|
|
36
|
+
running: () => selected.current.length > 0,
|
|
43
37
|
autoInvalidate: false,
|
|
44
38
|
}
|
|
45
39
|
)
|
|
46
40
|
</script>
|
|
47
41
|
|
|
48
|
-
{#
|
|
42
|
+
{#each obbHelpers as [entity, obbHelper] (entity)}
|
|
49
43
|
<T
|
|
50
44
|
is={obbHelper}
|
|
51
|
-
dispose={false}
|
|
52
45
|
raycast={() => null}
|
|
53
46
|
bvh={{ enabled: false }}
|
|
54
47
|
/>
|
|
55
|
-
{/
|
|
48
|
+
{/each}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { useThrelte } from '@threlte/core'
|
|
2
3
|
import { TransformControls } from '@threlte/extras'
|
|
3
4
|
import { Matrix4, Quaternion, Vector3 } from 'three'
|
|
4
5
|
|
|
5
6
|
import type { FrameEditSession } from '../editing/FrameEditSession'
|
|
6
7
|
|
|
7
|
-
import { relations, traits, useTrait } from '../ecs'
|
|
8
|
+
import { relations, traits, useQuery, useTrait } from '../ecs'
|
|
8
9
|
import { useTransformControls } from '../hooks/useControls.svelte'
|
|
9
10
|
import { useEnvironment } from '../hooks/useEnvironment.svelte'
|
|
10
11
|
import { useFrameEditSession } from '../hooks/useFrameEditSession.svelte'
|
|
11
12
|
import { usePartConfig } from '../hooks/usePartConfig.svelte'
|
|
12
|
-
import { useSelectedEntity, useSelectedObject3d } from '../hooks/useSelection.svelte'
|
|
13
13
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
14
14
|
import {
|
|
15
15
|
createPose,
|
|
@@ -20,16 +20,17 @@
|
|
|
20
20
|
vector3ToPose,
|
|
21
21
|
} from '../transform'
|
|
22
22
|
|
|
23
|
+
const { scene } = useThrelte()
|
|
23
24
|
const settings = useSettings()
|
|
24
25
|
const environment = useEnvironment()
|
|
25
26
|
const partConfig = usePartConfig()
|
|
26
27
|
const transformControls = useTransformControls()
|
|
27
|
-
const selectedEntity = useSelectedEntity()
|
|
28
|
-
const selectedObject3d = useSelectedObject3d()
|
|
29
28
|
const sessions = useFrameEditSession()
|
|
29
|
+
const selected = useQuery(traits.Selected)
|
|
30
30
|
|
|
31
31
|
const mode = $derived(settings.current.transformMode)
|
|
32
|
-
const entity = $derived(
|
|
32
|
+
const entity = $derived(selected.current[0])
|
|
33
|
+
const object3d = $derived(scene.getObjectByName(entity as unknown as string))
|
|
33
34
|
const transformable = useTrait(() => entity, traits.Transformable)
|
|
34
35
|
const invisible = useTrait(() => entity, traits.InheritedInvisible)
|
|
35
36
|
const configMatrix = useTrait(() => entity, traits.Matrix)
|
|
@@ -47,11 +48,11 @@
|
|
|
47
48
|
0
|
|
48
49
|
)
|
|
49
50
|
|
|
50
|
-
// Mesh sets name={entity} on its inner mesh, so
|
|
51
|
+
// Mesh sets name={entity} on its inner mesh, so getObjectByName resolves
|
|
51
52
|
// to that mesh — not the parent Frame Group we actually want to drive. Walk
|
|
52
53
|
// up to the Group so translate/rotate/scale apply to the whole frame, not
|
|
53
54
|
// the geometry inside it.
|
|
54
|
-
const ref = $derived(
|
|
55
|
+
const ref = $derived(object3d?.parent ?? object3d)
|
|
55
56
|
|
|
56
57
|
const activeMode = $derived.by<'translate' | 'rotate' | 'scale' | undefined>(() => {
|
|
57
58
|
if (mode === 'none' || !transformable.current) return
|
|
@@ -11,17 +11,16 @@
|
|
|
11
11
|
import { PressedKeys } from 'runed'
|
|
12
12
|
import { SvelteSet } from 'svelte/reactivity'
|
|
13
13
|
|
|
14
|
-
import { traits, useWorld } from '../ecs'
|
|
15
|
-
import { useSelectedEntity } from '../hooks/useSelection.svelte'
|
|
14
|
+
import { traits, useQuery, useWorld } from '../ecs'
|
|
16
15
|
|
|
17
16
|
import Frame from './Entities/Frame.svelte'
|
|
18
17
|
|
|
19
18
|
const world = useWorld()
|
|
20
|
-
const
|
|
19
|
+
const selected = useQuery(traits.Selected)
|
|
21
20
|
|
|
22
21
|
const entities = new SvelteSet<Entity>()
|
|
23
22
|
const selectedCustomGeometry = $derived(
|
|
24
|
-
[...entities].find((entity) => entity ===
|
|
23
|
+
[...entities].find((entity) => entity === selected.current[0])
|
|
25
24
|
)
|
|
26
25
|
|
|
27
26
|
const keys = new PressedKeys()
|
|
@@ -43,7 +42,6 @@
|
|
|
43
42
|
const entity = selectedCustomGeometry
|
|
44
43
|
entity.destroy()
|
|
45
44
|
entities.delete(entity)
|
|
46
|
-
selectedEntity.set()
|
|
47
45
|
}
|
|
48
46
|
})
|
|
49
47
|
</script>
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { traits, useTrait } from '../../ecs'
|
|
2
|
+
import { traits, useQuery, useTrait } from '../../ecs'
|
|
3
3
|
import { useLinkedEntities } from '../../hooks/useLinked.svelte'
|
|
4
|
-
import { useSelectedEntity } from '../../hooks/useSelection.svelte'
|
|
5
|
-
import { useFocusedEntity } from '../../hooks/useSelection.svelte'
|
|
6
4
|
|
|
7
5
|
import HoveredEntity from './HoveredEntity.svelte'
|
|
8
6
|
import LinkedHoveredEntity from './LinkedHoveredEntity.svelte'
|
|
9
7
|
|
|
10
|
-
const selectedEntity = useSelectedEntity()
|
|
11
|
-
const focusedEntity = useFocusedEntity()
|
|
12
8
|
const linkedEntities = useLinkedEntities()
|
|
13
|
-
|
|
14
|
-
const displayEntity = $derived(selectedEntity.current ?? focusedEntity.current)
|
|
15
|
-
const isHovered = useTrait(() => displayEntity, traits.Hovered)
|
|
9
|
+
const selected = useQuery(traits.Selected)
|
|
16
10
|
</script>
|
|
17
11
|
|
|
18
|
-
{#
|
|
19
|
-
|
|
12
|
+
{#each selected.current as entity (entity)}
|
|
13
|
+
{@const isHovered = useTrait(() => entity, traits.Hovered)}
|
|
14
|
+
|
|
15
|
+
{#if isHovered}
|
|
16
|
+
<HoveredEntity {entity} />
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
{
|
|
18
|
+
{#each linkedEntities.current as linkedEntity (linkedEntity)}
|
|
19
|
+
<LinkedHoveredEntity
|
|
20
|
+
{linkedEntity}
|
|
21
|
+
{entity}
|
|
22
|
+
/>
|
|
23
|
+
{/each}
|
|
24
|
+
{/if}
|
|
25
|
+
{/each}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 HoveredEntities: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type HoveredEntities = InstanceType<typeof HoveredEntities>;
|
|
3
18
|
export default HoveredEntities;
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Entity } from 'koota'
|
|
3
|
+
|
|
2
4
|
import { MathUtils, Quaternion, Vector3 } from 'three'
|
|
3
5
|
|
|
4
6
|
import type { HoverInfo } from '../../HoverUpdater.svelte'
|
|
5
7
|
|
|
6
8
|
import { traits, useTrait } from '../../ecs'
|
|
7
|
-
import { useFocusedEntity, useSelectedEntity } from '../../hooks/useSelection.svelte'
|
|
8
9
|
import { OrientationVector } from '../../three/OrientationVector'
|
|
9
10
|
|
|
10
11
|
import HoveredEntityTooltip from './HoveredEntityTooltip.svelte'
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
interface Props {
|
|
14
|
+
entity: Entity
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let { entity }: Props = $props()
|
|
14
18
|
|
|
15
|
-
const
|
|
16
|
-
const instancedMatrix = useTrait(() => displayEntity, traits.InstancedMatrix)
|
|
19
|
+
const instancedMatrix = useTrait(() => entity, traits.InstancedMatrix)
|
|
17
20
|
|
|
18
21
|
// Pool: InstancedMatrix's `Matrix4` is in metres (matches Three.js).
|
|
19
22
|
// Decompose for the tooltip's display, which expects metres for position
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Entity } from 'koota';
|
|
2
|
+
interface Props {
|
|
3
|
+
entity: Entity;
|
|
4
|
+
}
|
|
5
|
+
declare const HoveredEntity: import("svelte").Component<Props, {}, "">;
|
|
2
6
|
type HoveredEntity = ReturnType<typeof HoveredEntity>;
|
|
3
7
|
export default HoveredEntity;
|
|
@@ -5,36 +5,32 @@
|
|
|
5
5
|
|
|
6
6
|
import { relations, traits, useTrait } from '../../ecs'
|
|
7
7
|
import { SubEntityLinkType } from '../../ecs/relations'
|
|
8
|
-
import { useSelectedEntity } from '../../hooks/useSelection.svelte'
|
|
9
|
-
import { useFocusedEntity } from '../../hooks/useSelection.svelte'
|
|
10
8
|
import { getLinkedHoverInfo, type HoverInfo } from '../../HoverUpdater.svelte'
|
|
11
9
|
|
|
12
10
|
import HoveredEntityTooltip from './HoveredEntityTooltip.svelte'
|
|
13
11
|
|
|
14
12
|
interface Props {
|
|
15
13
|
linkedEntity: Entity
|
|
14
|
+
entity: Entity
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
let { linkedEntity }: Props = $props()
|
|
17
|
+
let { linkedEntity, entity }: Props = $props()
|
|
19
18
|
|
|
20
|
-
const
|
|
21
|
-
const focusedEntity = useFocusedEntity()
|
|
22
|
-
const displayEntity = $derived(selectedEntity.current ?? focusedEntity.current)
|
|
23
|
-
|
|
24
|
-
const displayedHoverInfo = useTrait(() => displayEntity, traits.InstancedMatrix)
|
|
19
|
+
const displayedHoverInfo = useTrait(() => entity, traits.InstancedMatrix)
|
|
25
20
|
|
|
26
21
|
let hoverInfo = $state.raw<HoverInfo | null>(null)
|
|
27
22
|
|
|
28
23
|
$effect(() => {
|
|
29
|
-
if (
|
|
30
|
-
const linkType =
|
|
24
|
+
if (entity && displayedHoverInfo.current) {
|
|
25
|
+
const linkType = entity?.get(relations.SubEntityLink(linkedEntity))?.type
|
|
31
26
|
if (linkType !== SubEntityLinkType.HoverLink) {
|
|
32
27
|
return
|
|
33
28
|
}
|
|
29
|
+
|
|
34
30
|
// Index mapping is a formula with the variable 'index' in it.
|
|
35
31
|
// Supported operations: https://github.com/cshaa/filtrex#expressions
|
|
36
32
|
const indexMapping =
|
|
37
|
-
|
|
33
|
+
entity?.get(relations.SubEntityLink(linkedEntity))?.indexMapping ?? 'index'
|
|
38
34
|
const evaluate = compileExpression(indexMapping)
|
|
39
35
|
const resolvedIndex = evaluate({ index: displayedHoverInfo.current.index })
|
|
40
36
|
const linkedHoverInfo = getLinkedHoverInfo(resolvedIndex, linkedEntity)
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import type { Pose } from '@viamrobotics/sdk'
|
|
16
16
|
import type { Entity } from 'koota'
|
|
17
17
|
import type { Snippet } from 'svelte'
|
|
18
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
18
19
|
|
|
19
20
|
import { draggable } from '@neodrag/svelte'
|
|
20
21
|
import { isInstanceOf, useThrelte } from '@threlte/core'
|
|
@@ -46,38 +47,28 @@
|
|
|
46
47
|
import { usePartConfig } from '../../hooks/usePartConfig.svelte'
|
|
47
48
|
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
48
49
|
import { useResourceByName } from '../../hooks/useResourceByName.svelte'
|
|
49
|
-
import {
|
|
50
|
-
useFocusedEntity,
|
|
51
|
-
useFocusedObject3d,
|
|
52
|
-
useSelectedEntity,
|
|
53
|
-
useSelectedObject3d,
|
|
54
|
-
} from '../../hooks/useSelection.svelte'
|
|
55
50
|
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
56
51
|
import { createPose, matrixToPose } from '../../transform'
|
|
57
52
|
|
|
58
|
-
interface Props {
|
|
53
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
54
|
+
entity: Entity
|
|
59
55
|
details?: Snippet<[{ entity: Entity }]>
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
const { details }: Props = $props()
|
|
58
|
+
const { entity, details, ...rest }: Props = $props()
|
|
63
59
|
|
|
64
60
|
const world = useWorld()
|
|
65
|
-
const { invalidate } = useThrelte()
|
|
61
|
+
const { scene, invalidate } = useThrelte()
|
|
66
62
|
const controls = useCameraControls()
|
|
67
63
|
const resourceByName = useResourceByName()
|
|
68
64
|
const configFrames = useConfigFrames()
|
|
69
65
|
const partConfig = usePartConfig()
|
|
70
66
|
const partID = usePartID()
|
|
71
67
|
const settings = useSettings()
|
|
72
|
-
const selectedEntity = useSelectedEntity()
|
|
73
|
-
const selectedObject3d = useSelectedObject3d()
|
|
74
68
|
const environment = useEnvironment()
|
|
75
|
-
const focusedEntity = useFocusedEntity()
|
|
76
|
-
const focusedObject3d = useFocusedObject3d()
|
|
77
69
|
const linkedEntities = useLinkedEntities()
|
|
78
70
|
|
|
79
|
-
const
|
|
80
|
-
const object3d = $derived(focusedObject3d.current ?? selectedObject3d.current)
|
|
71
|
+
const object3d = $derived(scene.getObjectByName(entity as unknown as string))
|
|
81
72
|
|
|
82
73
|
const name = useTrait(() => entity, traits.Name)
|
|
83
74
|
const parent = useParentName(() => entity)
|
|
@@ -129,8 +120,7 @@
|
|
|
129
120
|
})
|
|
130
121
|
|
|
131
122
|
const geometryTypes = ['none', 'box', 'sphere', 'capsule'] as const
|
|
132
|
-
|
|
133
|
-
// can write a transient override that lasts until the trait re-derives.
|
|
123
|
+
|
|
134
124
|
let geometryTabIndex = $derived(geometryTypes.indexOf(geometryType))
|
|
135
125
|
|
|
136
126
|
$effect(() => {
|
|
@@ -156,6 +146,10 @@
|
|
|
156
146
|
|
|
157
147
|
const detailConfigUpdater = new FrameConfigUpdater(partConfig.updateFrame, partConfig.deleteFrame)
|
|
158
148
|
|
|
149
|
+
const stopKeyboardPropagation = (event: KeyboardEvent) => {
|
|
150
|
+
event.stopPropagation()
|
|
151
|
+
}
|
|
152
|
+
|
|
159
153
|
const handlePositionChange = (event: PointChangeEvent) => {
|
|
160
154
|
if (event.detail.origin !== 'internal' || !entity) return
|
|
161
155
|
const next = event.detail.value as PointValue3dObject
|
|
@@ -312,13 +306,21 @@
|
|
|
312
306
|
{/snippet}
|
|
313
307
|
|
|
314
308
|
{#if entity}
|
|
309
|
+
<!-- tabindex makes the whole panel focusable so a click anywhere in it (not
|
|
310
|
+
just the inputs) raises it via `focus-within:z-5`. -->
|
|
315
311
|
<div
|
|
316
312
|
id="details-panel"
|
|
317
|
-
class="border-medium bg-extralight absolute top-0 right-0 z-4 m-2 w-70 border p-2 text-xs"
|
|
313
|
+
class="border-medium bg-extralight absolute top-0 right-0 z-4 m-2 w-70 border p-2 text-xs focus-within:z-5"
|
|
314
|
+
role="region"
|
|
315
|
+
aria-label="Details panel"
|
|
316
|
+
tabindex="-1"
|
|
317
|
+
onkeydown={stopKeyboardPropagation}
|
|
318
|
+
onkeyup={stopKeyboardPropagation}
|
|
318
319
|
use:draggable={{
|
|
319
320
|
bounds: 'body',
|
|
320
321
|
handle: dragElement,
|
|
321
322
|
}}
|
|
323
|
+
{...rest}
|
|
322
324
|
>
|
|
323
325
|
<div
|
|
324
326
|
class="flex cursor-move items-center justify-between gap-2 pb-2"
|
|
@@ -768,25 +770,8 @@
|
|
|
768
770
|
|
|
769
771
|
{@render details?.({ entity })}
|
|
770
772
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
{#if focusedEntity.current}
|
|
774
|
-
<Button
|
|
775
|
-
class="w-full"
|
|
776
|
-
icon="arrow-left"
|
|
777
|
-
variant="dark"
|
|
778
|
-
onclick={() => focusedEntity.set()}
|
|
779
|
-
>
|
|
780
|
-
Exit object view
|
|
781
|
-
</Button>
|
|
782
|
-
{:else}
|
|
783
|
-
<Button
|
|
784
|
-
class="w-full"
|
|
785
|
-
icon="image-filter-center-focus"
|
|
786
|
-
onclick={() => focusedEntity.set(entity)}
|
|
787
|
-
>
|
|
788
|
-
Enter object view
|
|
789
|
-
</Button>
|
|
773
|
+
{#if showRelationshipOptions || (showEditFrameOptions && environment.current.isStandalone)}
|
|
774
|
+
<h3 class="text-subtle-2 pt-3 pb-2">Actions</h3>
|
|
790
775
|
{/if}
|
|
791
776
|
|
|
792
777
|
{#if showRelationshipOptions}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Entity } from 'koota';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
entity: Entity;
|
|
4
6
|
details?: Snippet<[{
|
|
5
7
|
entity: Entity;
|
|
6
8
|
}]>;
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
<fieldset class="flex flex-col">
|
|
18
18
|
<Button
|
|
19
|
-
active
|
|
20
19
|
class="rounded-b-none"
|
|
21
20
|
icon="camera-outline"
|
|
22
21
|
description="Reset camera"
|
|
@@ -26,7 +25,6 @@
|
|
|
26
25
|
}}
|
|
27
26
|
/>
|
|
28
27
|
<Button
|
|
29
|
-
active
|
|
30
28
|
class="-my-0.5 rounded-t-none"
|
|
31
29
|
icon={isOrthographic ? 'grid-orthographic' : 'grid-perspective'}
|
|
32
30
|
description={isOrthographic ? 'Switch to perspective view' : 'Switch to orthographic view'}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import type { ClassValue, HTMLButtonAttributes, MouseEventHandler } from 'svelte/elements'
|
|
3
3
|
|
|
4
4
|
import { Icon, type IconName, Tooltip } from '@viamrobotics/prime-core'
|
|
5
|
-
import { MousePointer2, Ruler } from 'lucide-svelte'
|
|
5
|
+
import { Focus, MousePointer2, Ruler } from 'lucide-svelte'
|
|
6
6
|
|
|
7
7
|
interface Props extends HTMLButtonAttributes {
|
|
8
|
-
icon: IconName | 'ruler' | 'mouse-pointer'
|
|
8
|
+
icon: IconName | 'ruler' | 'mouse-pointer' | 'focus'
|
|
9
9
|
active?: boolean
|
|
10
10
|
description: string
|
|
11
11
|
hotkey?: string
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<label
|
|
34
34
|
class={[
|
|
35
35
|
className,
|
|
36
|
-
'relative block rounded-md border',
|
|
36
|
+
'relative block rounded-md border active:z-4 active:border-[#666] active:bg-[#666] active:text-white',
|
|
37
37
|
active ? 'z-4 border-[#666] bg-[#666] text-white' : 'border-gray-5 text-gray-8 bg-white',
|
|
38
38
|
]}
|
|
39
39
|
aria-describedby={tooltipID}
|
|
@@ -50,6 +50,8 @@
|
|
|
50
50
|
<Ruler size="16" />
|
|
51
51
|
{:else if icon === 'mouse-pointer'}
|
|
52
52
|
<MousePointer2 size="16" />
|
|
53
|
+
{:else if icon === 'focus'}
|
|
54
|
+
<Focus size="16" />
|
|
53
55
|
{:else}
|
|
54
56
|
<Icon name={icon} />
|
|
55
57
|
{/if}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ClassValue, HTMLButtonAttributes, MouseEventHandler } from 'svelte/elements';
|
|
2
2
|
import { type IconName } from '@viamrobotics/prime-core';
|
|
3
3
|
interface Props extends HTMLButtonAttributes {
|
|
4
|
-
icon: IconName | 'ruler' | 'mouse-pointer';
|
|
4
|
+
icon: IconName | 'ruler' | 'mouse-pointer' | 'focus';
|
|
5
5
|
active?: boolean;
|
|
6
6
|
description: string;
|
|
7
7
|
hotkey?: string;
|
|
@@ -6,15 +6,12 @@
|
|
|
6
6
|
import { VirtualList } from 'svelte-virtuallists'
|
|
7
7
|
import { SvelteSet } from 'svelte/reactivity'
|
|
8
8
|
|
|
9
|
-
import { relations, traits } from '../../../ecs'
|
|
10
|
-
import { useSelectedEntity } from '../../../hooks/useSelection.svelte'
|
|
9
|
+
import { relations, traits, useQuery } from '../../../ecs'
|
|
11
10
|
|
|
12
11
|
import type { TreeNode as TreeNodeType } from './useTree.svelte'
|
|
13
12
|
|
|
14
13
|
import TreeNode from './TreeNode.svelte'
|
|
15
14
|
|
|
16
|
-
const selected = useSelectedEntity()
|
|
17
|
-
|
|
18
15
|
interface Props {
|
|
19
16
|
rootNode: TreeNodeType
|
|
20
17
|
dragElement?: HTMLElement
|
|
@@ -31,14 +28,18 @@
|
|
|
31
28
|
})
|
|
32
29
|
)
|
|
33
30
|
|
|
34
|
-
const
|
|
31
|
+
const selected = useQuery(traits.Selected)
|
|
32
|
+
|
|
33
|
+
const selectedValue = $derived(selected.current.map((entity) => `${entity}`))
|
|
35
34
|
const expandedValues = new SvelteSet<string>()
|
|
36
35
|
|
|
37
36
|
$effect(() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
for (const entity of selected.current) {
|
|
38
|
+
let ancestor: Entity | undefined = entity.targetFor(relations.ChildOf)
|
|
39
|
+
while (ancestor) {
|
|
40
|
+
expandedValues.add(`${ancestor}`)
|
|
41
|
+
ancestor = ancestor.targetFor(relations.ChildOf)
|
|
42
|
+
}
|
|
42
43
|
}
|
|
43
44
|
})
|
|
44
45
|
|
|
@@ -46,6 +47,8 @@
|
|
|
46
47
|
const service = useMachine(tree.machine, () => ({
|
|
47
48
|
id,
|
|
48
49
|
collection,
|
|
50
|
+
selectionMode: 'multiple' as const,
|
|
51
|
+
expandOnClick: false,
|
|
49
52
|
selectedValue,
|
|
50
53
|
expandedValue: [...expandedValues],
|
|
51
54
|
onSelectionChange(details) {
|
|
@@ -64,7 +67,7 @@
|
|
|
64
67
|
|
|
65
68
|
$effect(() => {
|
|
66
69
|
const element = document.querySelector(
|
|
67
|
-
`[data-scope="tree-view"][data-value="${selected.current}"]`
|
|
70
|
+
`[data-scope="tree-view"][data-value="${selected.current.at(-1)}"]`
|
|
68
71
|
)
|
|
69
72
|
|
|
70
73
|
requestAnimationFrame(() => {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { type Entity, IsExcluded } from 'koota'
|
|
3
3
|
|
|
4
4
|
import { traits, useWorld } from '../../../ecs'
|
|
5
|
-
import { useSelectedEntity } from '../../../hooks/useSelection.svelte'
|
|
6
5
|
|
|
7
6
|
import FloatingPanel from '../FloatingPanel.svelte'
|
|
8
7
|
import Tree from './Tree.svelte'
|
|
@@ -11,7 +10,6 @@
|
|
|
11
10
|
|
|
12
11
|
provideTreeExpandedContext()
|
|
13
12
|
|
|
14
|
-
const selectedEntity = useSelectedEntity()
|
|
15
13
|
const world = useWorld()
|
|
16
14
|
|
|
17
15
|
const worldEntity = world.spawn(IsExcluded, traits.Name('World'))
|
|
@@ -35,9 +33,16 @@
|
|
|
35
33
|
<Tree
|
|
36
34
|
{rootNode}
|
|
37
35
|
onSelectionChange={(event) => {
|
|
38
|
-
const
|
|
36
|
+
const next = new Set(event.selectedValue.map(Number))
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
for (const entity of world.query(traits.Selected)) {
|
|
39
|
+
if (!next.has(entity as number)) entity.remove(traits.Selected)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const id of next) {
|
|
43
|
+
const entity = id as Entity
|
|
44
|
+
if (!entity.has(traits.Selected)) entity.add(traits.Selected)
|
|
45
|
+
}
|
|
41
46
|
}}
|
|
42
47
|
/>
|
|
43
48
|
</FloatingPanel>
|
|
@@ -63,12 +63,14 @@
|
|
|
63
63
|
]}
|
|
64
64
|
>
|
|
65
65
|
<div {...api.getBranchControlProps(nodeProps)}>
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
<button
|
|
67
|
+
type="button"
|
|
68
|
+
aria-label={expanded ? 'Collapse' : 'Expand'}
|
|
69
|
+
{...api.getBranchTriggerProps(nodeProps)}
|
|
70
|
+
class={['flex items-center', { 'rotate-90': expanded }]}
|
|
69
71
|
>
|
|
70
72
|
<ChevronRight size={14} />
|
|
71
|
-
</
|
|
73
|
+
</button>
|
|
72
74
|
<span
|
|
73
75
|
class="flex items-center overflow-hidden text-ellipsis"
|
|
74
76
|
{...api.getBranchTextProps(nodeProps)}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useGeometries } from '../../../hooks/useGeometries.svelte'
|
|
3
|
+
import { usePointcloudObjects } from '../../../hooks/usePointcloudObjects.svelte'
|
|
4
|
+
import { usePointClouds } from '../../../hooks/usePointclouds.svelte'
|
|
5
|
+
import { useRefetchPoses } from '../../../hooks/useRefetchPoses'
|
|
6
|
+
import { RefreshRates } from '../../../hooks/useSettings.svelte'
|
|
7
|
+
|
|
8
|
+
import RefreshRate from '../RefreshRate.svelte'
|
|
9
|
+
|
|
10
|
+
const geometries = useGeometries()
|
|
11
|
+
const pointclouds = usePointClouds()
|
|
12
|
+
const pointcloudObjects = usePointcloudObjects()
|
|
13
|
+
const { refetchPoses } = useRefetchPoses()
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div class="flex flex-col gap-2.5 text-xs">
|
|
17
|
+
<h3 class="border-gray-3 border-b py-1 text-sm"><strong>Polling rates</strong></h3>
|
|
18
|
+
|
|
19
|
+
<RefreshRate
|
|
20
|
+
id={RefreshRates.poses}
|
|
21
|
+
label="Poses"
|
|
22
|
+
allowLive
|
|
23
|
+
onManualRefetch={() => {
|
|
24
|
+
refetchPoses()
|
|
25
|
+
geometries.refetch()
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
<RefreshRate
|
|
29
|
+
id={RefreshRates.pointclouds}
|
|
30
|
+
label="Pointclouds from cameras"
|
|
31
|
+
onManualRefetch={() => {
|
|
32
|
+
pointclouds.refetch()
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
<RefreshRate
|
|
36
|
+
id={RefreshRates.vision}
|
|
37
|
+
label="Vision service pointcloud segments and objects"
|
|
38
|
+
onManualRefetch={() => {
|
|
39
|
+
pointcloudObjects.refetch()
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
</div>
|