@viamrobotics/motion-tools 1.5.0 → 1.7.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 +16 -9
- package/dist/components/App.svelte +12 -0
- package/dist/components/Frame.svelte +0 -7
- package/dist/components/Tree/Settings.svelte +18 -22
- package/dist/components/Tree/Widgets.svelte +44 -0
- package/dist/components/Tree/Widgets.svelte.d.ts +2 -17
- package/dist/components/widgets/Camera.svelte +195 -0
- package/dist/components/widgets/Camera.svelte.d.ts +6 -0
- package/dist/hooks/use3DModels.svelte.js +1 -3
- package/dist/hooks/useSettings.svelte.d.ts +1 -0
- package/dist/hooks/useSettings.svelte.js +1 -0
- package/dist/hooks/useWeblabs.svelte.d.ts +1 -3
- package/dist/hooks/useWeblabs.svelte.js +1 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,21 +17,28 @@ make setup
|
|
|
17
17
|
|
|
18
18
|
This single command will:
|
|
19
19
|
|
|
20
|
-
1. Install
|
|
21
|
-
2. Install
|
|
22
|
-
3. Install **
|
|
23
|
-
4. Install **
|
|
20
|
+
1. Install **fnm** (Fast Node Manager) and **Node.js 22**
|
|
21
|
+
2. Install **pnpm** package manager
|
|
22
|
+
3. Install **bun** runtime
|
|
23
|
+
4. Install **Go** and **buf** (for protobuf generation)
|
|
24
24
|
5. Install all project dependencies
|
|
25
|
+
6. Generate protobuf code
|
|
26
|
+
|
|
27
|
+
After setup completes, add the shell configuration it prints to your shell config file (`~/.zshrc` or `~/.bashrc`), then restart your terminal.
|
|
25
28
|
|
|
26
29
|
#### Manual setup
|
|
27
30
|
|
|
28
31
|
If the above does not work for you, or if you prefer to install dependencies manually:
|
|
29
32
|
|
|
30
|
-
1. [Install
|
|
31
|
-
2. Install Node.js
|
|
32
|
-
3. [Install pnpm](https://pnpm.io/installation)
|
|
33
|
-
4. [Install bun](https://bun.sh/docs/installation)
|
|
34
|
-
5. Install
|
|
33
|
+
1. [Install fnm](https://github.com/Schniz/fnm#installation): `curl -fsSL https://fnm.vercel.app/install | bash`
|
|
34
|
+
2. Install Node.js: `fnm install 22 && fnm use 22`
|
|
35
|
+
3. [Install pnpm](https://pnpm.io/installation): `curl -fsSL https://get.pnpm.io/install.sh | sh -`
|
|
36
|
+
4. [Install bun](https://bun.sh/docs/installation): `curl -fsSL https://bun.sh/install | bash`
|
|
37
|
+
5. [Install Go](https://go.dev/doc/install)
|
|
38
|
+
6. [Install buf](https://buf.build/docs/installation): download from GitHub releases
|
|
39
|
+
7. Install Go tools: `go install google.golang.org/protobuf/cmd/protoc-gen-go@latest`
|
|
40
|
+
8. Install dependencies: `pnpm install`
|
|
41
|
+
9. Generate protobufs: `make proto`
|
|
35
42
|
|
|
36
43
|
### Env files for machine configs
|
|
37
44
|
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
provideDrawConnectionConfig,
|
|
27
27
|
type DrawConnectionConfig,
|
|
28
28
|
} from '../hooks/useDrawConnectionConfig.svelte'
|
|
29
|
+
import Camera from './widgets/Camera.svelte'
|
|
29
30
|
|
|
30
31
|
interface LocalConfigProps {
|
|
31
32
|
getLocalPartConfig: () => Struct
|
|
@@ -64,6 +65,8 @@
|
|
|
64
65
|
const settings = provideSettings()
|
|
65
66
|
const environment = provideEnvironment()
|
|
66
67
|
|
|
68
|
+
const currentRobotCameraWidgets = $derived(settings.current.openCameraWidgets[partID] || [])
|
|
69
|
+
|
|
67
70
|
$effect(() => {
|
|
68
71
|
settings.current.enableKeybindings = enableKeybindings
|
|
69
72
|
})
|
|
@@ -138,6 +141,15 @@
|
|
|
138
141
|
<ArmPositions {@attach domPortal(root)} />
|
|
139
142
|
{/if}
|
|
140
143
|
|
|
144
|
+
{#if !focus}
|
|
145
|
+
{#each currentRobotCameraWidgets as cameraName (cameraName)}
|
|
146
|
+
<Camera
|
|
147
|
+
name={cameraName}
|
|
148
|
+
{@attach domPortal(root)}
|
|
149
|
+
/>
|
|
150
|
+
{/each}
|
|
151
|
+
{/if}
|
|
152
|
+
|
|
141
153
|
<FileDrop {@attach domPortal(root)} />
|
|
142
154
|
{/snippet}
|
|
143
155
|
</SceneProviders>
|
|
@@ -3,12 +3,10 @@
|
|
|
3
3
|
import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
|
|
4
4
|
import { Color, Group, type Object3D } from 'three'
|
|
5
5
|
import Geometry from './Geometry2.svelte'
|
|
6
|
-
import { useWeblabs } from '../hooks/useWeblabs.svelte'
|
|
7
6
|
import { useSelectedEntity } from '../hooks/useSelection.svelte'
|
|
8
7
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
9
8
|
import { use3DModels } from '../hooks/use3DModels.svelte'
|
|
10
9
|
import { colors, darkenColor, resourceColors } from '../color'
|
|
11
|
-
import { WEBLABS_EXPERIMENTS } from '../hooks/useWeblabs.svelte'
|
|
12
10
|
import type { Entity } from 'koota'
|
|
13
11
|
import { traits, useTrait } from '../ecs'
|
|
14
12
|
import type { Pose } from '@viamrobotics/sdk'
|
|
@@ -31,7 +29,6 @@
|
|
|
31
29
|
const componentModels = use3DModels()
|
|
32
30
|
const selectedEntity = useSelectedEntity()
|
|
33
31
|
const resourceByName = useResourceByName()
|
|
34
|
-
const weblabs = useWeblabs()
|
|
35
32
|
|
|
36
33
|
const name = useTrait(() => entity, traits.Name)
|
|
37
34
|
const parent = useTrait(() => entity, traits.Parent)
|
|
@@ -57,10 +54,6 @@
|
|
|
57
54
|
})
|
|
58
55
|
|
|
59
56
|
const model = $derived.by(() => {
|
|
60
|
-
if (!weblabs.isActive(WEBLABS_EXPERIMENTS.MOTION_TOOLS_RENDER_ARM_MODELS)) {
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
|
|
64
57
|
if (!name.current) {
|
|
65
58
|
return
|
|
66
59
|
}
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
import { useResourceNames } from '@viamrobotics/svelte-sdk'
|
|
7
7
|
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
8
8
|
import { RefreshRates, useMachineSettings } from '../../hooks/useMachineSettings.svelte'
|
|
9
|
-
import WeblabActive from '../weblab/WeblabActive.svelte'
|
|
10
|
-
import { WEBLABS_EXPERIMENTS } from '../../hooks/useWeblabs.svelte'
|
|
11
9
|
import { useGeometries } from '../../hooks/useGeometries.svelte'
|
|
12
10
|
import { usePointClouds } from '../../hooks/usePointclouds.svelte'
|
|
13
11
|
import { useThrelte } from '@threlte/core'
|
|
@@ -195,26 +193,24 @@
|
|
|
195
193
|
<label class="flex items-center justify-between gap-2">
|
|
196
194
|
Render stats <Switch bind:on={settings.current.renderStats} />
|
|
197
195
|
</label>
|
|
198
|
-
<
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
>
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
</label>
|
|
217
|
-
</WeblabActive>
|
|
196
|
+
<label class="flex items-center justify-between gap-2">
|
|
197
|
+
Render Arm Models
|
|
198
|
+
<Select
|
|
199
|
+
value={settings.current.renderArmModels}
|
|
200
|
+
onchange={(event: InputEvent) => {
|
|
201
|
+
if (event.target instanceof HTMLSelectElement) {
|
|
202
|
+
settings.current.renderArmModels = event.target.value as
|
|
203
|
+
| 'colliders'
|
|
204
|
+
| 'colliders+model'
|
|
205
|
+
| 'model'
|
|
206
|
+
}
|
|
207
|
+
}}
|
|
208
|
+
>
|
|
209
|
+
<option value="colliders">Colliders</option>
|
|
210
|
+
<option value="colliders+model">Colliders + Model</option>
|
|
211
|
+
<option value="model">Model</option>
|
|
212
|
+
</Select>
|
|
213
|
+
</label>
|
|
218
214
|
</div>
|
|
219
215
|
</div>
|
|
220
216
|
</Drawer>
|
|
@@ -2,8 +2,20 @@
|
|
|
2
2
|
import { Switch } from '@viamrobotics/prime-core'
|
|
3
3
|
import Drawer from './Drawer.svelte'
|
|
4
4
|
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
5
|
+
import { useResourceByName } from '../../hooks/useResourceByName.svelte'
|
|
6
|
+
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
5
7
|
|
|
6
8
|
const settings = useSettings()
|
|
9
|
+
const resourceByName = useResourceByName()
|
|
10
|
+
const partID = usePartID()
|
|
11
|
+
|
|
12
|
+
const cameras = $derived(
|
|
13
|
+
Object.values(resourceByName.current).filter((resource) => resource?.subtype === 'camera')
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
const currentRobotCameraWidgets = $derived(
|
|
17
|
+
settings.current.openCameraWidgets[partID.current] || []
|
|
18
|
+
)
|
|
7
19
|
</script>
|
|
8
20
|
|
|
9
21
|
<Drawer name="Widgets">
|
|
@@ -17,5 +29,37 @@
|
|
|
17
29
|
}}
|
|
18
30
|
/>
|
|
19
31
|
</div>
|
|
32
|
+
|
|
33
|
+
<div class="mt-4">
|
|
34
|
+
<h3 class="text-sm"><strong>Camera Widgets</strong></h3>
|
|
35
|
+
{#each cameras as camera (camera?.name)}
|
|
36
|
+
{#if camera}
|
|
37
|
+
{@const isOpen = currentRobotCameraWidgets.includes(camera.name)}
|
|
38
|
+
<div class="flex items-center justify-between gap-4 py-2">
|
|
39
|
+
{camera.name}
|
|
40
|
+
<Switch
|
|
41
|
+
on={isOpen}
|
|
42
|
+
on:change={(event) => {
|
|
43
|
+
if (event.detail) {
|
|
44
|
+
settings.current.openCameraWidgets = {
|
|
45
|
+
...settings.current.openCameraWidgets,
|
|
46
|
+
[partID.current]: [...currentRobotCameraWidgets, camera.name],
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
settings.current.openCameraWidgets = {
|
|
50
|
+
...settings.current.openCameraWidgets,
|
|
51
|
+
[partID.current]: currentRobotCameraWidgets.filter(
|
|
52
|
+
(widget) => widget !== camera.name
|
|
53
|
+
),
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}}
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
{/if}
|
|
60
|
+
{:else}
|
|
61
|
+
<div class="py-2">No cameras detected</div>
|
|
62
|
+
{/each}
|
|
63
|
+
</div>
|
|
20
64
|
</div>
|
|
21
65
|
</Drawer>
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 Widgets: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
-
[evt: string]: CustomEvent<any>;
|
|
16
|
-
}, {}, {}, string>;
|
|
17
|
-
type Widgets = InstanceType<typeof Widgets>;
|
|
1
|
+
declare const Widgets: import("svelte").Component<Record<string, never>, {}, "">;
|
|
2
|
+
type Widgets = ReturnType<typeof Widgets>;
|
|
18
3
|
export default Widgets;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { draggable } from '@neodrag/svelte'
|
|
3
|
+
import { Icon, Select } from '@viamrobotics/prime-core'
|
|
4
|
+
import { CameraStream, useRobotClient } from '@viamrobotics/svelte-sdk'
|
|
5
|
+
import { StreamClient } from '@viamrobotics/sdk'
|
|
6
|
+
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
7
|
+
import { usePartID } from '../../hooks/usePartID.svelte'
|
|
8
|
+
import { useEnvironment } from '../../hooks/useEnvironment.svelte'
|
|
9
|
+
|
|
10
|
+
interface Resolution {
|
|
11
|
+
width: number
|
|
12
|
+
height: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { name, ...rest } = $props<{ name: string }>()
|
|
16
|
+
|
|
17
|
+
const settings = useSettings()
|
|
18
|
+
const partID = usePartID()
|
|
19
|
+
const client = useRobotClient(() => partID.current)
|
|
20
|
+
const environment = useEnvironment()
|
|
21
|
+
|
|
22
|
+
let dragElement = $state.raw<HTMLElement>()
|
|
23
|
+
let aspectRatio = $state.raw<number | undefined>(undefined)
|
|
24
|
+
let fps = $state(0)
|
|
25
|
+
let resolutions = $state<Resolution[]>([])
|
|
26
|
+
let currentResolution = $state<string>('')
|
|
27
|
+
let isLoading = $state(true)
|
|
28
|
+
let error = $state<string | undefined>(undefined)
|
|
29
|
+
|
|
30
|
+
let fpsInterval: ReturnType<typeof setInterval> | undefined
|
|
31
|
+
let fpsCounterActive = false
|
|
32
|
+
|
|
33
|
+
// Cleanup on destroy
|
|
34
|
+
$effect(() => {
|
|
35
|
+
return () => {
|
|
36
|
+
if (fpsInterval) clearInterval(fpsInterval)
|
|
37
|
+
fpsCounterActive = false
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const onMediaLoad = (e: Event) => {
|
|
42
|
+
const target = e.target as HTMLVideoElement
|
|
43
|
+
|
|
44
|
+
// Update aspect ratio
|
|
45
|
+
if (target.videoWidth && target.videoHeight) {
|
|
46
|
+
aspectRatio = target.videoWidth / target.videoHeight
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Start FPS counter
|
|
50
|
+
if ('requestVideoFrameCallback' in target) {
|
|
51
|
+
if (fpsInterval) clearInterval(fpsInterval)
|
|
52
|
+
fpsCounterActive = false
|
|
53
|
+
|
|
54
|
+
let frameCount = 0
|
|
55
|
+
fpsCounterActive = true
|
|
56
|
+
|
|
57
|
+
const onFrame = () => {
|
|
58
|
+
if (!fpsCounterActive) return
|
|
59
|
+
frameCount++
|
|
60
|
+
target.requestVideoFrameCallback(onFrame)
|
|
61
|
+
}
|
|
62
|
+
target.requestVideoFrameCallback(onFrame)
|
|
63
|
+
|
|
64
|
+
// Update FPS state every 500ms
|
|
65
|
+
fpsInterval = setInterval(() => {
|
|
66
|
+
// FPS = frames / 0.5s = frames * 2
|
|
67
|
+
fps = frameCount * 2
|
|
68
|
+
frameCount = 0
|
|
69
|
+
}, 500)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Create a single StreamClient instance per robot client
|
|
74
|
+
let streamClient = $derived(client.current ? new StreamClient(client.current) : undefined)
|
|
75
|
+
|
|
76
|
+
$effect(() => {
|
|
77
|
+
if (streamClient) {
|
|
78
|
+
isLoading = true
|
|
79
|
+
error = undefined
|
|
80
|
+
streamClient
|
|
81
|
+
.getOptions(name)
|
|
82
|
+
.then((options) => {
|
|
83
|
+
resolutions = options.map((opt) => ({ width: opt.width, height: opt.height }))
|
|
84
|
+
isLoading = false
|
|
85
|
+
})
|
|
86
|
+
.catch((e) => {
|
|
87
|
+
error = e instanceof Error ? e.message : 'Failed to get stream options'
|
|
88
|
+
isLoading = false
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const handleResolutionChange = async (e: Event) => {
|
|
94
|
+
const target = e.target as HTMLSelectElement
|
|
95
|
+
if (!target.value || !streamClient) return
|
|
96
|
+
|
|
97
|
+
const [w, h] = target.value.split('x').map(Number)
|
|
98
|
+
if (isNaN(w) || isNaN(h)) return
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
await streamClient.setOptions(name, w, h)
|
|
102
|
+
error = undefined
|
|
103
|
+
} catch (err) {
|
|
104
|
+
error = err instanceof Error ? err.message : 'Failed to set resolution'
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<div
|
|
110
|
+
class="bg-extralight border-medium absolute top-0 left-0 z-1000 m-2 flex resize-x flex-col overflow-hidden border text-xs"
|
|
111
|
+
style:width="320px"
|
|
112
|
+
style:height="auto !important"
|
|
113
|
+
use:draggable={{
|
|
114
|
+
bounds: 'body',
|
|
115
|
+
handle: dragElement,
|
|
116
|
+
}}
|
|
117
|
+
{...rest}
|
|
118
|
+
>
|
|
119
|
+
<div class="flex h-full min-w-0 flex-col">
|
|
120
|
+
<div class="flex w-full shrink-0 items-center justify-between">
|
|
121
|
+
<div class="border-medium flex w-full items-center gap-1 border-b p-2">
|
|
122
|
+
<button bind:this={dragElement}>
|
|
123
|
+
<Icon name="drag" />
|
|
124
|
+
</button>
|
|
125
|
+
<h3 class="min-w-0 truncate">{name}</h3>
|
|
126
|
+
<div class="flex-1"></div>
|
|
127
|
+
|
|
128
|
+
{#if isLoading}
|
|
129
|
+
<span class="text-subtle mr-2">Loading...</span>
|
|
130
|
+
{:else if resolutions.length > 0}
|
|
131
|
+
<div class="mr-2 w-32">
|
|
132
|
+
<Select
|
|
133
|
+
bind:value={currentResolution}
|
|
134
|
+
onchange={handleResolutionChange}
|
|
135
|
+
>
|
|
136
|
+
<option value="">Default</option>
|
|
137
|
+
{#each resolutions as res (`${res.width}x${res.height}`)}
|
|
138
|
+
<option value={`${res.width}x${res.height}`}>{res.width}x{res.height}</option>
|
|
139
|
+
{/each}
|
|
140
|
+
</Select>
|
|
141
|
+
</div>
|
|
142
|
+
{/if}
|
|
143
|
+
|
|
144
|
+
<button
|
|
145
|
+
aria-label="close"
|
|
146
|
+
class="hover:text-default"
|
|
147
|
+
onclick={() => {
|
|
148
|
+
const widgets = settings.current.openCameraWidgets[partID.current] || []
|
|
149
|
+
settings.current.openCameraWidgets = {
|
|
150
|
+
...settings.current.openCameraWidgets,
|
|
151
|
+
[partID.current]: widgets.filter((widget) => widget !== name),
|
|
152
|
+
}
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
<Icon
|
|
156
|
+
name="close"
|
|
157
|
+
size="xs"
|
|
158
|
+
/>
|
|
159
|
+
</button>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<div
|
|
164
|
+
class="relative min-h-0 w-full flex-1 overflow-hidden bg-black [&_img]:h-full [&_img]:w-full [&_img]:object-fill [&_video]:h-full [&_video]:w-full [&_video]:object-fill"
|
|
165
|
+
style:aspect-ratio={aspectRatio}
|
|
166
|
+
>
|
|
167
|
+
{#key environment.current.viewerMode === 'monitor'}
|
|
168
|
+
<CameraStream
|
|
169
|
+
{name}
|
|
170
|
+
partID={partID.current}
|
|
171
|
+
onloadedmetadata={onMediaLoad}
|
|
172
|
+
onload={onMediaLoad}
|
|
173
|
+
/>
|
|
174
|
+
{/key}
|
|
175
|
+
|
|
176
|
+
<!-- FPS Pill -->
|
|
177
|
+
{#if fps > 0}
|
|
178
|
+
<div
|
|
179
|
+
class="absolute bottom-2 left-2 z-10 rounded-[3px] bg-black/30 px-1 py-0.5 text-right font-mono text-xs text-white"
|
|
180
|
+
>
|
|
181
|
+
{fps.toFixed(1)}fps
|
|
182
|
+
</div>
|
|
183
|
+
{/if}
|
|
184
|
+
|
|
185
|
+
<!-- Error display -->
|
|
186
|
+
{#if error}
|
|
187
|
+
<div
|
|
188
|
+
class="absolute inset-0 flex items-center justify-center bg-black/50 p-2 text-center text-white"
|
|
189
|
+
>
|
|
190
|
+
{error}
|
|
191
|
+
</div>
|
|
192
|
+
{/if}
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ArmClient } from '@viamrobotics/sdk';
|
|
2
2
|
import { createResourceClient, useResourceNames } from '@viamrobotics/svelte-sdk';
|
|
3
3
|
import { getContext, setContext } from 'svelte';
|
|
4
|
-
import { useWeblabs, WEBLABS_EXPERIMENTS } from './useWeblabs.svelte';
|
|
5
4
|
import { useSettings } from './useSettings.svelte';
|
|
6
5
|
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
7
6
|
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
|
|
@@ -11,7 +10,6 @@ dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5
|
|
|
11
10
|
gltfLoader.setDRACOLoader(dracoLoader);
|
|
12
11
|
const key = Symbol('3d-models-context');
|
|
13
12
|
export const provide3DModels = (partID) => {
|
|
14
|
-
const weblabs = useWeblabs();
|
|
15
13
|
const settings = useSettings();
|
|
16
14
|
let current = $state.raw({});
|
|
17
15
|
const arms = useResourceNames(partID, 'arm');
|
|
@@ -52,7 +50,7 @@ export const provide3DModels = (partID) => {
|
|
|
52
50
|
const shouldFetchModels = settings.current.isLoaded &&
|
|
53
51
|
(settings.current.renderArmModels === 'model' ||
|
|
54
52
|
settings.current.renderArmModels === 'colliders+model');
|
|
55
|
-
if (
|
|
53
|
+
if (shouldFetchModels) {
|
|
56
54
|
fetch3DModels();
|
|
57
55
|
}
|
|
58
56
|
});
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export declare const WEBLABS_EXPERIMENTS: {
|
|
2
|
-
readonly MOTION_TOOLS_RENDER_ARM_MODELS: "MOTION_TOOLS_RENDER_ARM_MODELS";
|
|
3
|
-
};
|
|
1
|
+
export declare const WEBLABS_EXPERIMENTS: {};
|
|
4
2
|
export declare const WEBLABS_CONTEXT_KEY: unique symbol;
|
|
5
3
|
interface Context {
|
|
6
4
|
load: (experiments: string[]) => void;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { getContext, setContext } from 'svelte';
|
|
2
2
|
import { SvelteSet } from 'svelte/reactivity';
|
|
3
|
-
export const WEBLABS_EXPERIMENTS = {
|
|
4
|
-
MOTION_TOOLS_RENDER_ARM_MODELS: 'MOTION_TOOLS_RENDER_ARM_MODELS',
|
|
5
|
-
};
|
|
3
|
+
export const WEBLABS_EXPERIMENTS = {};
|
|
6
4
|
export const WEBLABS_CONTEXT_KEY = Symbol('weblabs-context');
|
|
7
5
|
const getCookie = (name) => {
|
|
8
6
|
const value = `; ${document.cookie}`;
|