@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
|
@@ -8,24 +8,29 @@
|
|
|
8
8
|
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
9
9
|
|
|
10
10
|
import CameraFeed from './CameraFeed.svelte'
|
|
11
|
+
import DebugPanel from './DebugPanel.svelte'
|
|
11
12
|
import FrameConfigureControllers from './frame-configure/Controllers.svelte'
|
|
12
13
|
import JointLimitsWidget from './JointLimitsWidget.svelte'
|
|
13
14
|
import OriginMarker from './OriginMarker.svelte'
|
|
15
|
+
import PendingEditsPanel from './PendingEditsPanel.svelte'
|
|
14
16
|
import TeleopControllers from './teleop/Controllers.svelte'
|
|
15
17
|
import { provideAnchors } from './useAnchors.svelte'
|
|
16
|
-
import {
|
|
18
|
+
import { provideOrigin } from './useOrigin.svelte'
|
|
19
|
+
import XRPlugins from './XRPlugins.svelte'
|
|
17
20
|
import XRToast from './XRToast.svelte'
|
|
18
21
|
|
|
19
22
|
const { ...rest } = $props()
|
|
20
23
|
|
|
21
|
-
const
|
|
22
|
-
const settings = useSettings()
|
|
23
|
-
const origin = useOrigin()
|
|
24
|
+
const origin = provideOrigin()
|
|
24
25
|
provideAnchors()
|
|
25
|
-
const enableXR = $derived(settings.current.enableXR)
|
|
26
26
|
|
|
27
|
+
const { renderer } = useThrelte()
|
|
28
|
+
const { isPresenting } = useXR()
|
|
29
|
+
const settings = useSettings()
|
|
27
30
|
const partID = usePartID()
|
|
28
31
|
|
|
32
|
+
const enableXR = $derived(settings.current.enableXR)
|
|
33
|
+
|
|
29
34
|
// Get all enabled camera widgets for the current part
|
|
30
35
|
const enabledCameras = $derived.by(() => {
|
|
31
36
|
const openWidgets = settings.current.openCameraWidgets
|
|
@@ -48,34 +53,57 @@
|
|
|
48
53
|
const leftArmName = $derived(controllerConfig.left.armName)
|
|
49
54
|
const rightArmName = $derived(controllerConfig.right.armName)
|
|
50
55
|
|
|
51
|
-
|
|
56
|
+
// Compose the XR reference space from:
|
|
57
|
+
// 1) a -π/2 rotation around X to switch from WebXR's Y-up to Viam's Z-up
|
|
58
|
+
// 2) the scene origin (position + yaw) so the origin's pose lives at the
|
|
59
|
+
// composed space's identity. With this, controllers, camera, and scene
|
|
60
|
+
// content all share one frame — no separate origin group needed.
|
|
61
|
+
let baseRefSpace: XRReferenceSpace | undefined
|
|
52
62
|
|
|
53
|
-
// Move into Viam's coordinate system. This basically accomplishes
|
|
54
|
-
// the same thing as setting z up in the Camera component.
|
|
55
63
|
$effect(() => {
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const baseRefSpace = renderer.xr.getReferenceSpace()
|
|
61
|
-
if (baseRefSpace) {
|
|
62
|
-
const rotatedRefSpace = baseRefSpace.getOffsetReferenceSpace(
|
|
63
|
-
new XRRigidTransform({ x: 0, y: 0, z: 0, w: 1 }, { x: q.x, y: q.y, z: q.z, w: q.w })
|
|
64
|
-
)
|
|
64
|
+
if (!$isPresenting) {
|
|
65
|
+
baseRefSpace = undefined
|
|
66
|
+
return
|
|
67
|
+
}
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
if (!baseRefSpace) {
|
|
70
|
+
const current = renderer.xr.getReferenceSpace()
|
|
71
|
+
if (!current) return
|
|
72
|
+
baseRefSpace = current
|
|
68
73
|
}
|
|
74
|
+
|
|
75
|
+
const [ox, oy, oz] = origin.position
|
|
76
|
+
const oRot = origin.rotation
|
|
77
|
+
|
|
78
|
+
const zUpQ = new Quaternion().setFromAxisAngle({ x: 1, y: 0, z: 0 }, -Math.PI / 2)
|
|
79
|
+
const originQ = new Quaternion().setFromAxisAngle({ x: 0, y: 0, z: 1 }, oRot)
|
|
80
|
+
|
|
81
|
+
const composed = baseRefSpace
|
|
82
|
+
.getOffsetReferenceSpace(
|
|
83
|
+
new XRRigidTransform(
|
|
84
|
+
{ x: 0, y: 0, z: 0, w: 1 },
|
|
85
|
+
{ x: zUpQ.x, y: zUpQ.y, z: zUpQ.z, w: zUpQ.w }
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
.getOffsetReferenceSpace(
|
|
89
|
+
new XRRigidTransform(
|
|
90
|
+
{ x: ox, y: oy, z: oz },
|
|
91
|
+
{ x: originQ.x, y: originQ.y, z: originQ.z, w: originQ.w }
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
renderer.xr.setReferenceSpace(composed)
|
|
69
96
|
})
|
|
70
97
|
</script>
|
|
71
98
|
|
|
99
|
+
{#if $isPresenting}
|
|
100
|
+
<XRPlugins />
|
|
101
|
+
{/if}
|
|
102
|
+
|
|
72
103
|
{#if enableXR}
|
|
73
104
|
<XR
|
|
74
|
-
onsessionstart={() => {
|
|
75
|
-
origin.set([-1, -1, 0])
|
|
76
|
-
}}
|
|
77
105
|
onsessionend={() => {
|
|
78
|
-
origin.set([0, 0, 0])
|
|
106
|
+
origin.set([0, 0, 0], 0)
|
|
79
107
|
}}
|
|
80
108
|
>
|
|
81
109
|
<!-- Render camera feeds only when presenting to avoid conflicting with overlay Camera widgets -->
|
|
@@ -115,6 +143,8 @@
|
|
|
115
143
|
<!-- <XRConfigPanel offset={{ x: 0, y: 2.5, z: -2.5 }} scale={0.7} /> -->
|
|
116
144
|
|
|
117
145
|
<XRToast />
|
|
146
|
+
<DebugPanel />
|
|
147
|
+
<PendingEditsPanel />
|
|
118
148
|
|
|
119
149
|
{#if settings.current.xrMode === 'arm-teleop'}
|
|
120
150
|
<TeleopControllers />
|
|
@@ -127,6 +157,22 @@
|
|
|
127
157
|
|
|
128
158
|
<XRButton
|
|
129
159
|
mode="immersive-ar"
|
|
160
|
+
sessionInit={{
|
|
161
|
+
optionalFeatures: [
|
|
162
|
+
'local-floor',
|
|
163
|
+
'bounded-floor',
|
|
164
|
+
'anchors',
|
|
165
|
+
// Required for cross-session persistence — enables
|
|
166
|
+
// `anchor.requestPersistentHandle()` and
|
|
167
|
+
// `session.restorePersistentAnchor()` on Quest Browser.
|
|
168
|
+
'persistent-anchors',
|
|
169
|
+
'plane-detection',
|
|
170
|
+
'hand-tracking',
|
|
171
|
+
'layers',
|
|
172
|
+
'hit-test',
|
|
173
|
+
],
|
|
174
|
+
}}
|
|
175
|
+
style="color: #555; border-color: #ccc; backdrop-filter: blur(4px); background: rgba(255,255,255,0.5)"
|
|
130
176
|
{...rest}
|
|
131
177
|
/>
|
|
132
178
|
{/if}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default XRPlugins;
|
|
2
|
+
type XRPlugins = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const XRPlugins: $$__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
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Select, Switch } from '@viamrobotics/prime-core'
|
|
3
|
+
import { useResourceNames } from '@viamrobotics/svelte-sdk'
|
|
4
|
+
|
|
5
|
+
import { useArmClient } from '../../hooks/useArmClient.svelte'
|
|
6
|
+
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
7
|
+
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
8
|
+
|
|
9
|
+
const settings = useSettings()
|
|
10
|
+
const armClient = useArmClient()
|
|
11
|
+
const partID = usePartID()
|
|
12
|
+
const resources = useResourceNames(() => partID.current, 'gripper')
|
|
13
|
+
|
|
14
|
+
const armNames = $derived(armClient.names || [])
|
|
15
|
+
const gripperNames = $derived(
|
|
16
|
+
resources.current
|
|
17
|
+
.filter((r) => r.subtype === 'gripper' && r.type === 'component')
|
|
18
|
+
.map((r) => r.name)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const config = $derived(settings.current.xrController)
|
|
22
|
+
|
|
23
|
+
// Filter available arms/grippers - exclude what the other controller has selected
|
|
24
|
+
const leftAvailableArms = $derived(
|
|
25
|
+
armNames.filter((name) => name === config.left.armName || name !== config.right.armName)
|
|
26
|
+
)
|
|
27
|
+
const rightAvailableArms = $derived(
|
|
28
|
+
armNames.filter((name) => name === config.right.armName || name !== config.left.armName)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const leftAvailableGrippers = $derived(
|
|
32
|
+
gripperNames.filter(
|
|
33
|
+
(name) => name === config.left.gripperName || name !== config.right.gripperName
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
const rightAvailableGrippers = $derived(
|
|
37
|
+
gripperNames.filter(
|
|
38
|
+
(name) => name === config.right.gripperName || name !== config.left.gripperName
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
function updateConfig(
|
|
43
|
+
hand: 'left' | 'right',
|
|
44
|
+
key: string,
|
|
45
|
+
value: string | number | boolean | undefined
|
|
46
|
+
) {
|
|
47
|
+
settings.current.xrController[hand] = {
|
|
48
|
+
...settings.current.xrController[hand],
|
|
49
|
+
[key]: value,
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<div class="flex flex-col gap-2.5 text-xs">
|
|
55
|
+
<div class="flex flex-col gap-2.5">
|
|
56
|
+
<label class="flex items-center justify-between gap-2">
|
|
57
|
+
Enable VR / AR mode <Switch bind:on={settings.current.enableXR} />
|
|
58
|
+
</label>
|
|
59
|
+
|
|
60
|
+
<h3 class="border-gray-3 border-b py-1 text-sm"><strong>Left Controller</strong></h3>
|
|
61
|
+
|
|
62
|
+
<label class="flex items-center justify-between gap-2">
|
|
63
|
+
Arm
|
|
64
|
+
<Select
|
|
65
|
+
value={config.left.armName || ''}
|
|
66
|
+
onchange={(event: Event) => {
|
|
67
|
+
if (event.target instanceof HTMLSelectElement) {
|
|
68
|
+
updateConfig('left', 'armName', event.target.value || undefined)
|
|
69
|
+
}
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<option value="">None</option>
|
|
73
|
+
{#each leftAvailableArms as armName (armName)}
|
|
74
|
+
<option value={armName}>{armName}</option>
|
|
75
|
+
{/each}
|
|
76
|
+
</Select>
|
|
77
|
+
</label>
|
|
78
|
+
|
|
79
|
+
<label class="flex items-center justify-between gap-2">
|
|
80
|
+
Gripper
|
|
81
|
+
<Select
|
|
82
|
+
value={config.left.gripperName || ''}
|
|
83
|
+
onchange={(event: Event) => {
|
|
84
|
+
if (event.target instanceof HTMLSelectElement) {
|
|
85
|
+
updateConfig('left', 'gripperName', event.target.value || undefined)
|
|
86
|
+
}
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<option value="">None</option>
|
|
90
|
+
{#each leftAvailableGrippers as gripperName (gripperName)}
|
|
91
|
+
<option value={gripperName}>{gripperName}</option>
|
|
92
|
+
{/each}
|
|
93
|
+
</Select>
|
|
94
|
+
</label>
|
|
95
|
+
|
|
96
|
+
<label class="flex items-center justify-between gap-2">
|
|
97
|
+
Scale: {config.left.scaleFactor.toFixed(1)}
|
|
98
|
+
<input
|
|
99
|
+
class="w-20"
|
|
100
|
+
type="range"
|
|
101
|
+
min="0.1"
|
|
102
|
+
max="3.0"
|
|
103
|
+
step="0.1"
|
|
104
|
+
value={config.left.scaleFactor}
|
|
105
|
+
style="--value: {((config.left.scaleFactor - 0.1) / (3 - 0.1)) * 100}%"
|
|
106
|
+
oninput={(e) =>
|
|
107
|
+
updateConfig('left', 'scaleFactor', Number.parseFloat(e.currentTarget.value))}
|
|
108
|
+
/>
|
|
109
|
+
</label>
|
|
110
|
+
|
|
111
|
+
<label class="flex items-center justify-between gap-2">
|
|
112
|
+
Rotation
|
|
113
|
+
<Switch
|
|
114
|
+
on={config.left.rotationEnabled}
|
|
115
|
+
on:change={(event) => {
|
|
116
|
+
updateConfig('left', 'rotationEnabled', event.detail)
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
</label>
|
|
120
|
+
|
|
121
|
+
<!-- Right Controller -->
|
|
122
|
+
<h3 class="border-gray-3 border-b py-1 text-sm"><strong>Right Controller</strong></h3>
|
|
123
|
+
|
|
124
|
+
<label class="flex items-center justify-between gap-2">
|
|
125
|
+
Arm
|
|
126
|
+
<Select
|
|
127
|
+
value={config.right.armName || ''}
|
|
128
|
+
onchange={(event: Event) => {
|
|
129
|
+
if (event.target instanceof HTMLSelectElement) {
|
|
130
|
+
updateConfig('right', 'armName', event.target.value || undefined)
|
|
131
|
+
}
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
<option value="">None</option>
|
|
135
|
+
{#each rightAvailableArms as armName (armName)}
|
|
136
|
+
<option value={armName}>{armName}</option>
|
|
137
|
+
{/each}
|
|
138
|
+
</Select>
|
|
139
|
+
</label>
|
|
140
|
+
|
|
141
|
+
<label class="flex items-center justify-between gap-2">
|
|
142
|
+
Gripper
|
|
143
|
+
<Select
|
|
144
|
+
value={config.right.gripperName || ''}
|
|
145
|
+
onchange={(event: Event) => {
|
|
146
|
+
if (event.target instanceof HTMLSelectElement) {
|
|
147
|
+
updateConfig('right', 'gripperName', event.target.value || undefined)
|
|
148
|
+
}
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
<option value="">None</option>
|
|
152
|
+
{#each rightAvailableGrippers as gripperName (gripperName)}
|
|
153
|
+
<option value={gripperName}>{gripperName}</option>
|
|
154
|
+
{/each}
|
|
155
|
+
</Select>
|
|
156
|
+
</label>
|
|
157
|
+
|
|
158
|
+
<label class="flex items-center justify-between gap-2">
|
|
159
|
+
Scale: {config.right.scaleFactor.toFixed(1)}
|
|
160
|
+
<input
|
|
161
|
+
class="w-20"
|
|
162
|
+
type="range"
|
|
163
|
+
min="0.1"
|
|
164
|
+
max="3.0"
|
|
165
|
+
step="0.1"
|
|
166
|
+
value={config.right.scaleFactor}
|
|
167
|
+
style="--value: {((config.right.scaleFactor - 0.1) / (3 - 0.1)) * 100}%"
|
|
168
|
+
oninput={(e) =>
|
|
169
|
+
updateConfig('right', 'scaleFactor', Number.parseFloat(e.currentTarget.value))}
|
|
170
|
+
/>
|
|
171
|
+
</label>
|
|
172
|
+
|
|
173
|
+
<label class="flex items-center justify-between gap-2">
|
|
174
|
+
Rotation
|
|
175
|
+
<Switch
|
|
176
|
+
on={config.right.rotationEnabled}
|
|
177
|
+
on:change={(event) => {
|
|
178
|
+
updateConfig('right', 'rotationEnabled', event.detail)
|
|
179
|
+
}}
|
|
180
|
+
/>
|
|
181
|
+
</label>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<style>
|
|
186
|
+
input[type='range'] {
|
|
187
|
+
-webkit-appearance: none;
|
|
188
|
+
appearance: none;
|
|
189
|
+
width: 100%;
|
|
190
|
+
background: linear-gradient(
|
|
191
|
+
to right,
|
|
192
|
+
#3d7d3f 0%,
|
|
193
|
+
#3d7d3f var(--value),
|
|
194
|
+
#d1d5db var(--value),
|
|
195
|
+
#d1d5db 100%
|
|
196
|
+
);
|
|
197
|
+
border-radius: 0.25rem;
|
|
198
|
+
height: 0.5rem;
|
|
199
|
+
cursor: pointer;
|
|
200
|
+
outline: none;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Webkit browsers (Chrome, Safari, Edge) */
|
|
204
|
+
input[type='range']::-webkit-slider-track {
|
|
205
|
+
background: transparent;
|
|
206
|
+
height: 0.5rem;
|
|
207
|
+
border-radius: 0.25rem;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
input[type='range']::-webkit-slider-thumb {
|
|
211
|
+
-webkit-appearance: none;
|
|
212
|
+
appearance: none;
|
|
213
|
+
background: #3d7d3f;
|
|
214
|
+
height: 1.25rem;
|
|
215
|
+
width: 1.25rem;
|
|
216
|
+
border-radius: 50%;
|
|
217
|
+
border: 2px solid white;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Firefox */
|
|
221
|
+
input[type='range']::-moz-range-track {
|
|
222
|
+
background: transparent;
|
|
223
|
+
height: 0.5rem;
|
|
224
|
+
border-radius: 0.25rem;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
input[type='range']::-moz-range-thumb {
|
|
228
|
+
background: #3d7d3f;
|
|
229
|
+
height: 1.25rem;
|
|
230
|
+
width: 1.25rem;
|
|
231
|
+
border-radius: 50%;
|
|
232
|
+
border: 2px solid white;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
input[type='range']::-moz-range-progress {
|
|
236
|
+
background: #3d7d3f;
|
|
237
|
+
height: 0.5rem;
|
|
238
|
+
border-radius: 0.25rem;
|
|
239
|
+
}
|
|
240
|
+
</style>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { T } from '@threlte/core'
|
|
3
|
-
import { Headset } from '@threlte/xr'
|
|
4
3
|
import { untrack } from 'svelte'
|
|
5
4
|
import { CanvasTexture, PlaneGeometry } from 'three'
|
|
6
5
|
|
|
7
6
|
import { type ToastVariant, xrToast, type XRToastItem } from './toasts.svelte'
|
|
7
|
+
import WristDisplay from './WristDisplay.svelte'
|
|
8
8
|
|
|
9
9
|
const CANVAS_WIDTH = 700
|
|
10
10
|
const TOAST_HEIGHT = 80
|
|
@@ -204,12 +204,9 @@
|
|
|
204
204
|
})
|
|
205
205
|
</script>
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
{
|
|
209
|
-
<T.Mesh
|
|
210
|
-
position={[0, -0.3, -1.5]}
|
|
211
|
-
renderOrder={999}
|
|
212
|
-
>
|
|
207
|
+
{#if hasToasts && geometry}
|
|
208
|
+
<WristDisplay position={[0, 0.005, 0.02]}>
|
|
209
|
+
<T.Mesh renderOrder={999}>
|
|
213
210
|
<T is={geometry} />
|
|
214
211
|
<T.MeshBasicMaterial
|
|
215
212
|
map={texture}
|
|
@@ -217,5 +214,5 @@
|
|
|
217
214
|
depthTest={false}
|
|
218
215
|
/>
|
|
219
216
|
</T.Mesh>
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
</WristDisplay>
|
|
218
|
+
{/if}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class DebugStore {
|
|
2
|
+
messages = $state(['debug panel ready']);
|
|
3
|
+
add(message) {
|
|
4
|
+
this.messages.push(message);
|
|
5
|
+
if (this.messages.length > 8) {
|
|
6
|
+
this.messages = this.messages.slice(-8);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
clear() {
|
|
10
|
+
this.messages = [];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export const xrDebug = new DebugStore();
|