@viamrobotics/motion-tools 1.13.0 → 1.13.1
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/FrameConfigUpdater.svelte.js +1 -1
- package/dist/WorldObject.svelte.js +26 -13
- package/dist/buf/draw/v1/service_connect.d.ts +14 -25
- package/dist/buf/draw/v1/service_connect.js +14 -25
- package/dist/buf/draw/v1/service_pb.d.ts +61 -76
- package/dist/buf/draw/v1/service_pb.js +58 -111
- package/dist/color.js +3 -3
- package/dist/components/App.svelte +1 -5
- package/dist/components/Camera.svelte +1 -7
- package/dist/components/Camera.svelte.d.ts +0 -1
- package/dist/components/CameraControls.svelte +2 -2
- package/dist/components/{Arrows → Entities/Arrows}/ArrowGroups.svelte +3 -3
- package/dist/components/{Arrows → Entities/Arrows}/Arrows.svelte +6 -6
- package/dist/components/{Arrows → Entities/Arrows}/Arrows.svelte.d.ts +1 -1
- package/dist/components/{Entities.svelte → Entities/Entities.svelte} +5 -1
- package/dist/components/{Frame.svelte → Entities/Frame.svelte} +8 -8
- package/dist/components/{GLTF.svelte → Entities/GLTF.svelte} +5 -5
- package/dist/components/{Geometry.svelte → Entities/Geometry.svelte} +8 -13
- package/dist/components/{Label.svelte → Entities/Label.svelte} +1 -1
- package/dist/components/{Line.svelte → Entities/Line.svelte} +2 -2
- package/dist/components/{Points.svelte → Entities/Points.svelte} +5 -5
- package/dist/components/{Pose.svelte → Entities/Pose.svelte} +3 -3
- package/dist/{hooks/useObjectEvents.svelte.d.ts → components/Entities/hooks/useEntityEvents.svelte.d.ts} +1 -1
- package/dist/{hooks/useObjectEvents.svelte.js → components/Entities/hooks/useEntityEvents.svelte.js} +6 -6
- package/dist/components/FileDrop/file-names.js +6 -3
- package/dist/components/FileDrop/snapshot-dropper.js +8 -4
- package/dist/components/FileDrop/useFileDrop.svelte.js +9 -6
- package/dist/components/Lasso/Lasso.svelte +4 -4
- package/dist/components/PCD.svelte +14 -6
- package/dist/components/PCD.svelte.d.ts +2 -0
- package/dist/components/Scene.svelte +1 -3
- package/dist/components/StaticGeometries.svelte +1 -1
- package/dist/components/overlay/AddRelationship.svelte +1 -1
- package/dist/components/overlay/LiveUpdatesBanner.svelte +4 -6
- package/dist/components/overlay/settings/Settings.svelte +11 -13
- package/dist/components/overlay/widgets/Camera.svelte +11 -9
- package/dist/components/xr/ArmTeleop.svelte +33 -33
- package/dist/components/xr/CameraFeed.svelte +21 -23
- package/dist/components/xr/JointLimitsWidget.svelte +19 -5
- package/dist/components/xr/XRConfigPanel.svelte +17 -16
- package/dist/components/xr/XRControllerSettings.svelte +5 -4
- package/dist/components/xr/XRToast.svelte +11 -6
- package/dist/ecs/relations.d.ts +1 -0
- package/dist/ecs/relations.js +1 -0
- package/dist/ecs/useQuery.svelte.js +3 -3
- package/dist/format.js +1 -1
- package/dist/hooks/use3DModels.svelte.js +35 -35
- package/dist/hooks/useConfigFrames.svelte.js +2 -7
- package/dist/hooks/useDrawAPI.svelte.js +1 -1
- package/dist/hooks/useFramelessComponents.svelte.js +1 -1
- package/dist/hooks/useFrames.svelte.js +63 -56
- package/dist/hooks/useGeometries.svelte.js +1 -1
- package/dist/hooks/useLinked.svelte.js +5 -4
- package/dist/hooks/usePartConfig.svelte.js +16 -17
- package/dist/hooks/usePointcloudObjects.svelte.js +4 -4
- package/dist/hooks/usePointclouds.svelte.js +2 -4
- package/dist/hooks/usePose.svelte.js +3 -7
- package/dist/hooks/useResizable.svelte.js +4 -3
- package/dist/hooks/useSettings.svelte.js +2 -2
- package/dist/hooks/useWeblabs.svelte.js +3 -2
- package/dist/hooks/useWorldState.svelte.js +6 -3
- package/dist/loaders/pcd/index.js +2 -1
- package/dist/loaders/pcd/worker.inline.d.ts +1 -1
- package/dist/loaders/pcd/worker.inline.js +1 -1
- package/dist/loaders/pcd/worker.js +1 -1
- package/dist/snapshot.js +7 -5
- package/dist/three/InstancedArrows/InstancedArrows.js +1 -1
- package/dist/three/InstancedArrows/box.js +1 -1
- package/dist/three/InstancedArrows/raycast.js +12 -12
- package/package.json +19 -11
- /package/dist/components/{Arrows → Entities/Arrows}/ArrowGroups.svelte.d.ts +0 -0
- /package/dist/components/{Entities.svelte.d.ts → Entities/Entities.svelte.d.ts} +0 -0
- /package/dist/components/{Frame.svelte.d.ts → Entities/Frame.svelte.d.ts} +0 -0
- /package/dist/components/{GLTF.svelte.d.ts → Entities/GLTF.svelte.d.ts} +0 -0
- /package/dist/components/{Geometry.svelte.d.ts → Entities/Geometry.svelte.d.ts} +0 -0
- /package/dist/components/{Label.svelte.d.ts → Entities/Label.svelte.d.ts} +0 -0
- /package/dist/components/{Line.svelte.d.ts → Entities/Line.svelte.d.ts} +0 -0
- /package/dist/components/{LineDots.svelte → Entities/LineDots.svelte} +0 -0
- /package/dist/components/{LineDots.svelte.d.ts → Entities/LineDots.svelte.d.ts} +0 -0
- /package/dist/components/{LineGeometry.svelte → Entities/LineGeometry.svelte} +0 -0
- /package/dist/components/{LineGeometry.svelte.d.ts → Entities/LineGeometry.svelte.d.ts} +0 -0
- /package/dist/components/{Points.svelte.d.ts → Entities/Points.svelte.d.ts} +0 -0
- /package/dist/components/{Pose.svelte.d.ts → Entities/Pose.svelte.d.ts} +0 -0
|
@@ -132,7 +132,8 @@
|
|
|
132
132
|
const iconCenterX = accentBarWidth + 30
|
|
133
133
|
const textStartX = accentBarWidth + 56
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
let index = 0
|
|
136
|
+
for (const toast of toasts) {
|
|
136
137
|
const y = index * (TOAST_HEIGHT + TOAST_GAP)
|
|
137
138
|
const style = VARIANT_STYLES[toast.variant]
|
|
138
139
|
|
|
@@ -165,7 +166,9 @@
|
|
|
165
166
|
ctx.font = '28px sans-serif'
|
|
166
167
|
ctx.textBaseline = 'middle'
|
|
167
168
|
ctx.fillText(toast.message, textStartX, y + TOAST_HEIGHT / 2)
|
|
168
|
-
|
|
169
|
+
|
|
170
|
+
index += 1
|
|
171
|
+
}
|
|
169
172
|
|
|
170
173
|
texture.needsUpdate = true
|
|
171
174
|
}
|
|
@@ -189,12 +192,14 @@
|
|
|
189
192
|
renderToasts(toasts)
|
|
190
193
|
})
|
|
191
194
|
|
|
195
|
+
const dispose = () => {
|
|
196
|
+
texture.dispose()
|
|
197
|
+
untrack(() => geometry?.dispose())
|
|
198
|
+
}
|
|
199
|
+
|
|
192
200
|
// Cleanup
|
|
193
201
|
$effect(() => {
|
|
194
|
-
return
|
|
195
|
-
texture.dispose()
|
|
196
|
-
untrack(() => geometry?.dispose())
|
|
197
|
-
}
|
|
202
|
+
return dispose
|
|
198
203
|
})
|
|
199
204
|
</script>
|
|
200
205
|
|
package/dist/ecs/relations.d.ts
CHANGED
package/dist/ecs/relations.js
CHANGED
|
@@ -31,11 +31,11 @@ export function useQuery(...parameters) {
|
|
|
31
31
|
};
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
+
const handler = () => {
|
|
35
|
+
version += 1;
|
|
36
|
+
};
|
|
34
37
|
// Force reattaching event listeners when the world is reset.
|
|
35
38
|
$effect(() => {
|
|
36
|
-
const handler = () => {
|
|
37
|
-
version += 1;
|
|
38
|
-
};
|
|
39
39
|
world[internal].resetSubscriptions.add(handler);
|
|
40
40
|
return () => {
|
|
41
41
|
world[internal].resetSubscriptions.delete(handler);
|
package/dist/format.js
CHANGED
|
@@ -18,45 +18,45 @@ export const provide3DModels = (partID) => {
|
|
|
18
18
|
const clients = $derived(armClients.filter((client) => {
|
|
19
19
|
return arms.current.some((arm) => arm.name === client.current?.name);
|
|
20
20
|
}));
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const fetch3DModels = async () => {
|
|
22
|
+
const next = {};
|
|
23
|
+
for (const client of clients) {
|
|
24
|
+
if (!client.current)
|
|
25
|
+
continue;
|
|
26
|
+
try {
|
|
27
|
+
const geometries = await client.current.getGeometries();
|
|
28
|
+
if (geometries.length === 0) {
|
|
26
29
|
continue;
|
|
27
|
-
try {
|
|
28
|
-
const geometries = await client.current.getGeometries();
|
|
29
|
-
if (geometries.length === 0) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
const geometryLabel = geometries[0].label;
|
|
33
|
-
const prefix = geometryLabel.split(':')[0];
|
|
34
|
-
const models = await client.current.get3DModels();
|
|
35
|
-
if (!(prefix in next)) {
|
|
36
|
-
next[prefix] = {};
|
|
37
|
-
}
|
|
38
|
-
for (const [id, model] of Object.entries(models)) {
|
|
39
|
-
const arrayBuffer = model.mesh.buffer.slice(model.mesh.byteOffset, model.mesh.byteOffset + model.mesh.byteLength);
|
|
40
|
-
const gltfModel = await gltfLoader.parseAsync(arrayBuffer, '');
|
|
41
|
-
next[prefix][id] = gltfModel.scene;
|
|
42
|
-
gltfModel.scene.traverse((object) => {
|
|
43
|
-
if (isInstanceOf(object, 'Mesh')) {
|
|
44
|
-
const { material } = object;
|
|
45
|
-
if (isInstanceOf(material, 'MeshStandardMaterial')) {
|
|
46
|
-
material.roughness = 0.3;
|
|
47
|
-
material.metalness = 0.1;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
current = next;
|
|
53
30
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
31
|
+
const geometryLabel = geometries[0].label;
|
|
32
|
+
const prefix = geometryLabel.split(':')[0];
|
|
33
|
+
const models = await client.current.get3DModels();
|
|
34
|
+
if (!(prefix in next)) {
|
|
35
|
+
next[prefix] = {};
|
|
36
|
+
}
|
|
37
|
+
for (const [id, model] of Object.entries(models)) {
|
|
38
|
+
const arrayBuffer = model.mesh.buffer.slice(model.mesh.byteOffset, model.mesh.byteOffset + model.mesh.byteLength);
|
|
39
|
+
const gltfModel = await gltfLoader.parseAsync(arrayBuffer, '');
|
|
40
|
+
next[prefix][id] = gltfModel.scene;
|
|
41
|
+
gltfModel.scene.traverse((object) => {
|
|
42
|
+
if (isInstanceOf(object, 'Mesh')) {
|
|
43
|
+
const { material } = object;
|
|
44
|
+
if (isInstanceOf(material, 'MeshStandardMaterial')) {
|
|
45
|
+
material.roughness = 0.3;
|
|
46
|
+
material.metalness = 0.1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
57
50
|
}
|
|
51
|
+
current = next;
|
|
58
52
|
}
|
|
59
|
-
|
|
53
|
+
catch (error) {
|
|
54
|
+
// some arms may not implement this api yet
|
|
55
|
+
console.warn(`${client.current.name} returned an error: ${error} when getting 3D models`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
$effect(() => {
|
|
60
60
|
const shouldFetchModels = settings.current.isLoaded &&
|
|
61
61
|
(settings.current.renderArmModels === 'model' ||
|
|
62
62
|
settings.current.renderArmModels === 'colliders+model');
|
|
@@ -8,12 +8,7 @@ export const provideConfigFrames = () => {
|
|
|
8
8
|
const environment = useEnvironment();
|
|
9
9
|
const partConfig = usePartConfig();
|
|
10
10
|
$effect(() => {
|
|
11
|
-
|
|
12
|
-
environment.current.viewerMode = 'edit';
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
environment.current.viewerMode = 'monitor';
|
|
16
|
-
}
|
|
11
|
+
environment.current.viewerMode = partConfig.isDirty ? 'edit' : 'monitor';
|
|
17
12
|
});
|
|
18
13
|
const [configFrames, configUnsetFrameNames] = $derived.by(() => {
|
|
19
14
|
const { components } = partConfig.current;
|
|
@@ -74,7 +69,7 @@ export const provideConfigFrames = () => {
|
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
|
-
return
|
|
72
|
+
return [...validFrames];
|
|
78
73
|
};
|
|
79
74
|
const unsetFrames = $derived([...new Set([...configUnsetFrameNames, ...fragmentUnsetFrameNames])]);
|
|
80
75
|
setContext(key, {
|
|
@@ -39,7 +39,7 @@ const tryParse = (json) => {
|
|
|
39
39
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
40
|
const lowercaseKeys = (obj) => {
|
|
41
41
|
if (Array.isArray(obj)) {
|
|
42
|
-
return obj.map(lowercaseKeys);
|
|
42
|
+
return obj.map((item) => lowercaseKeys(item));
|
|
43
43
|
}
|
|
44
44
|
else if (obj && typeof obj === 'object' && obj.constructor === Object) {
|
|
45
45
|
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k.toLowerCase(), lowercaseKeys(v)]));
|
|
@@ -12,7 +12,7 @@ export const provideFramelessComponents = () => {
|
|
|
12
12
|
.map((component) => component.name) ?? [];
|
|
13
13
|
const fragmentComponentsWithNoFrame = [];
|
|
14
14
|
for (const fragmentComponentName of Object.keys(partConfig.componentNameToFragmentId)) {
|
|
15
|
-
if (frames.current.
|
|
15
|
+
if (frames.current.some((frame) => frame.referenceFrame === fragmentComponentName)) {
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
18
|
fragmentComponentsWithNoFrame.push(fragmentComponentName);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getContext, setContext, untrack } from 'svelte';
|
|
2
2
|
import { MachineConnectionEvent, Transform } from '@viamrobotics/sdk';
|
|
3
3
|
import { useRobotClient, createRobotQuery, useMachineStatus, useConnectionStatus, } from '@viamrobotics/svelte-sdk';
|
|
4
|
+
import {} from 'koota';
|
|
4
5
|
import { useLogs } from './useLogs.svelte';
|
|
5
6
|
import { resourceNameToColor } from '../color';
|
|
6
7
|
import { useEnvironment } from './useEnvironment.svelte';
|
|
@@ -68,72 +69,78 @@ export const provideFrames = (partID) => {
|
|
|
68
69
|
}
|
|
69
70
|
});
|
|
70
71
|
$effect.pre(() => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
72
|
+
if (current.length === 0)
|
|
73
|
+
return;
|
|
74
|
+
const currentResourcesByName = resourceByName.current;
|
|
75
|
+
// We only want to update whenever "current" or "resourceByName.current" changes
|
|
76
|
+
untrack(() => {
|
|
77
|
+
const active = {};
|
|
78
|
+
for (const frame of current) {
|
|
79
|
+
const name = frame.referenceFrame;
|
|
80
|
+
active[name] = true;
|
|
81
|
+
const parent = frame.poseInObserverFrame?.referenceFrame;
|
|
82
|
+
const pose = createPose(frame.poseInObserverFrame?.pose);
|
|
83
|
+
const center = frame.physicalObject?.center
|
|
84
|
+
? createPose(frame.physicalObject.center)
|
|
85
|
+
: undefined;
|
|
86
|
+
const resourceName = currentResourcesByName[frame.referenceFrame];
|
|
87
|
+
const color = resourceNameToColor(resourceName);
|
|
88
|
+
const existing = entities.get(name);
|
|
89
|
+
if (existing) {
|
|
90
|
+
if (!parent || parent === 'world') {
|
|
91
|
+
existing.remove(traits.Parent);
|
|
92
|
+
}
|
|
93
|
+
else if (parent && existing.has(traits.Parent)) {
|
|
94
|
+
existing.set(traits.Parent, parent);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
existing.add(traits.Parent(parent));
|
|
98
|
+
}
|
|
99
|
+
if (color) {
|
|
100
|
+
existing.set(traits.Color, color);
|
|
101
|
+
}
|
|
102
|
+
if (center) {
|
|
103
|
+
existing.set(traits.Center, center);
|
|
104
|
+
}
|
|
105
|
+
existing.remove(traits.Box, traits.Sphere, traits.BufferGeometry, traits.Capsule);
|
|
106
|
+
if (frame.physicalObject) {
|
|
107
|
+
const geometry = traits.Geometry(frame.physicalObject);
|
|
108
|
+
existing.add(geometry);
|
|
109
|
+
}
|
|
110
|
+
existing.set(traits.EditedPose, pose);
|
|
111
|
+
continue;
|
|
87
112
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
113
|
+
const entityTraits = [
|
|
114
|
+
traits.Name(name),
|
|
115
|
+
traits.Pose(pose),
|
|
116
|
+
traits.EditedPose(pose),
|
|
117
|
+
traits.FramesAPI,
|
|
118
|
+
traits.ShowAxesHelper,
|
|
119
|
+
];
|
|
120
|
+
if (parent && parent !== 'world') {
|
|
121
|
+
entityTraits.push(traits.Parent(parent));
|
|
93
122
|
}
|
|
94
123
|
if (color) {
|
|
95
|
-
|
|
124
|
+
entityTraits.push(traits.Color(color));
|
|
96
125
|
}
|
|
97
126
|
if (center) {
|
|
98
|
-
|
|
127
|
+
entityTraits.push(traits.Center(center));
|
|
99
128
|
}
|
|
100
|
-
existing.remove(traits.Box, traits.Sphere, traits.BufferGeometry, traits.Capsule);
|
|
101
129
|
if (frame.physicalObject) {
|
|
102
|
-
|
|
103
|
-
existing.add(geometry);
|
|
130
|
+
entityTraits.push(traits.Geometry(frame.physicalObject));
|
|
104
131
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
const entityTraits = [
|
|
109
|
-
traits.Name(name),
|
|
110
|
-
traits.Pose(pose),
|
|
111
|
-
traits.EditedPose(pose),
|
|
112
|
-
traits.FramesAPI,
|
|
113
|
-
traits.ShowAxesHelper,
|
|
114
|
-
];
|
|
115
|
-
if (parent && parent !== 'world') {
|
|
116
|
-
entityTraits.push(traits.Parent(parent));
|
|
132
|
+
const entity = world.spawn(...entityTraits);
|
|
133
|
+
entities.set(name, entity);
|
|
117
134
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
entityTraits.push(traits.Geometry(frame.physicalObject));
|
|
126
|
-
}
|
|
127
|
-
const entity = world.spawn(...entityTraits);
|
|
128
|
-
entities.set(name, entity);
|
|
129
|
-
}
|
|
130
|
-
// Clean up non-active entities
|
|
131
|
-
for (const [name, entity] of entities) {
|
|
132
|
-
if (!frames[name]) {
|
|
133
|
-
entity?.destroy();
|
|
134
|
-
entities.delete(name);
|
|
135
|
+
// Clean up non-active entities
|
|
136
|
+
for (const [name, entity] of entities) {
|
|
137
|
+
if (!active[name]) {
|
|
138
|
+
entity?.destroy();
|
|
139
|
+
entities.delete(name);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
135
142
|
}
|
|
136
|
-
}
|
|
143
|
+
});
|
|
137
144
|
});
|
|
138
145
|
setContext(key, {
|
|
139
146
|
get current() {
|
|
@@ -68,7 +68,7 @@ export const provideGeometries = (partID) => {
|
|
|
68
68
|
for (const geometry of query.data) {
|
|
69
69
|
index += 1;
|
|
70
70
|
const resourceName = resources.current[name];
|
|
71
|
-
const label = geometry.label
|
|
71
|
+
const label = geometry.label || `${name} geometry ${index}`;
|
|
72
72
|
active[`${name}:${label}`] = true;
|
|
73
73
|
const pose = createPose(geometry.center);
|
|
74
74
|
const subtype = resourceName?.subtype;
|
|
@@ -18,11 +18,12 @@ export const provideLinkedEntities = () => {
|
|
|
18
18
|
linkedEntities = linkedEntities.filter((e) => e !== target);
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
+
const unsub = () => {
|
|
22
|
+
unsubAdd();
|
|
23
|
+
unsubRemove();
|
|
24
|
+
};
|
|
21
25
|
$effect(() => {
|
|
22
|
-
return
|
|
23
|
-
unsubAdd();
|
|
24
|
-
unsubRemove();
|
|
25
|
-
};
|
|
26
|
+
return unsub;
|
|
26
27
|
});
|
|
27
28
|
setContext(linkedKey, {
|
|
28
29
|
get current() {
|
|
@@ -79,16 +79,16 @@ export const providePartConfig = (partID, params) => {
|
|
|
79
79
|
const existingFrameIndex = fragmentMod.mods.findLastIndex(
|
|
80
80
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
81
|
(mod) => mod?.['$set']?.[modSetPath] !== undefined);
|
|
82
|
-
if (existingFrameIndex
|
|
82
|
+
if (existingFrameIndex === -1) {
|
|
83
|
+
fragmentMod.mods.push(frame);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
83
86
|
const existingGeometry = fragmentMod.mods[existingFrameIndex]['$set']?.[modSetPath].geometry;
|
|
84
87
|
if (existingGeometry && !frameGeometry) {
|
|
85
88
|
frame['$set'][modSetPath].geometry = existingGeometry;
|
|
86
89
|
}
|
|
87
90
|
fragmentMod.mods[existingFrameIndex] = frame;
|
|
88
91
|
}
|
|
89
|
-
else {
|
|
90
|
-
fragmentMod.mods.push(frame);
|
|
91
|
-
}
|
|
92
92
|
config.set(newConfig);
|
|
93
93
|
};
|
|
94
94
|
const updatePartFrame = (componentName, referenceFrame, pose, geometry) => {
|
|
@@ -127,11 +127,10 @@ export const providePartConfig = (partID, params) => {
|
|
|
127
127
|
const deletePartFrame = (componentName) => {
|
|
128
128
|
const newConfig = getCurrent();
|
|
129
129
|
const component = newConfig?.components?.find(({ name }) => name === componentName);
|
|
130
|
-
if (
|
|
131
|
-
|
|
130
|
+
if (component) {
|
|
131
|
+
delete component.frame;
|
|
132
|
+
config.set(newConfig);
|
|
132
133
|
}
|
|
133
|
-
delete component.frame;
|
|
134
|
-
config.set(newConfig);
|
|
135
134
|
};
|
|
136
135
|
const deleteFragmentFrame = (fragmentId, componentName) => {
|
|
137
136
|
const newConfig = getCurrent();
|
|
@@ -168,29 +167,29 @@ export const providePartConfig = (partID, params) => {
|
|
|
168
167
|
},
|
|
169
168
|
updateFrame: (componentName, referenceFrame, framePosition, frameGeometry) => {
|
|
170
169
|
const fragmentId = config.componentNameToFragmentId[componentName];
|
|
171
|
-
if (fragmentId
|
|
172
|
-
|
|
170
|
+
if (fragmentId === undefined) {
|
|
171
|
+
updatePartFrame(componentName, referenceFrame, framePosition, frameGeometry);
|
|
173
172
|
}
|
|
174
173
|
else {
|
|
175
|
-
|
|
174
|
+
updateFragmentFrame(fragmentId, componentName, referenceFrame, framePosition, frameGeometry);
|
|
176
175
|
}
|
|
177
176
|
},
|
|
178
177
|
deleteFrame: (componentName) => {
|
|
179
178
|
const fragmentId = config.componentNameToFragmentId[componentName];
|
|
180
|
-
if (fragmentId
|
|
181
|
-
|
|
179
|
+
if (fragmentId === undefined) {
|
|
180
|
+
deletePartFrame(componentName);
|
|
182
181
|
}
|
|
183
182
|
else {
|
|
184
|
-
|
|
183
|
+
deleteFragmentFrame(fragmentId, componentName);
|
|
185
184
|
}
|
|
186
185
|
},
|
|
187
186
|
createFrame: (componentName) => {
|
|
188
187
|
const fragmentId = config.componentNameToFragmentId[componentName];
|
|
189
|
-
if (fragmentId
|
|
190
|
-
|
|
188
|
+
if (fragmentId === undefined) {
|
|
189
|
+
createPartFrame(componentName);
|
|
191
190
|
}
|
|
192
191
|
else {
|
|
193
|
-
|
|
192
|
+
createFragmentFrame(fragmentId, componentName);
|
|
194
193
|
}
|
|
195
194
|
},
|
|
196
195
|
save: () => config.save?.(),
|
|
@@ -47,10 +47,10 @@ export const providePointcloudObjects = (partID) => {
|
|
|
47
47
|
*/
|
|
48
48
|
$effect(() => {
|
|
49
49
|
for (const [name, query] of propQueries) {
|
|
50
|
-
if (name &&
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
if (name &&
|
|
51
|
+
query.data?.objectPointCloudsSupported === false &&
|
|
52
|
+
disabledVisionServices.get(name) === undefined) {
|
|
53
|
+
disabledVisionServices.set(name, true);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
});
|
|
@@ -50,10 +50,8 @@ export const providePointclouds = (partID) => {
|
|
|
50
50
|
*/
|
|
51
51
|
$effect(() => {
|
|
52
52
|
for (const [name, query] of propQueries) {
|
|
53
|
-
if (name && query.data?.supportsPcd === false) {
|
|
54
|
-
|
|
55
|
-
disabledCameras.set(name, true);
|
|
56
|
-
}
|
|
53
|
+
if (name && query.data?.supportsPcd === false && disabledCameras.get(name) === undefined) {
|
|
54
|
+
disabledCameras.set(name, true);
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
});
|
|
@@ -10,7 +10,7 @@ import { RefetchRates } from '../components/overlay/RefreshRate.svelte';
|
|
|
10
10
|
import { useLogs } from './useLogs.svelte';
|
|
11
11
|
import { useResourceByName } from './useResourceByName.svelte';
|
|
12
12
|
import { useRefetchPoses } from './useRefetchPoses';
|
|
13
|
-
const
|
|
13
|
+
const originFrameComponentTypes = new Set(['arm', 'gantry', 'gripper', 'base']);
|
|
14
14
|
export const usePose = (name, parent) => {
|
|
15
15
|
const environment = useEnvironment();
|
|
16
16
|
const logs = useLogs();
|
|
@@ -26,12 +26,8 @@ export const usePose = (name, parent) => {
|
|
|
26
26
|
const frames = useFrames();
|
|
27
27
|
let pose = $state();
|
|
28
28
|
const interval = $derived(refreshRates.get(RefreshRates.poses));
|
|
29
|
-
const resolvedParent = $derived(
|
|
30
|
-
|
|
31
|
-
: parent());
|
|
32
|
-
const resolvedName = $derived(origingFrameComponentTypes.includes(resource?.subtype ?? '')
|
|
33
|
-
? `${currentName}_origin`
|
|
34
|
-
: currentName);
|
|
29
|
+
const resolvedParent = $derived(originFrameComponentTypes.has(parentResource?.subtype ?? '') ? `${parent()}_origin` : parent());
|
|
30
|
+
const resolvedName = $derived(originFrameComponentTypes.has(resource?.subtype ?? '') ? `${currentName}_origin` : currentName);
|
|
35
31
|
const query = createRobotQuery(robotClient, 'getPose', () => [resolvedName, resolvedParent ?? 'world', []], () => ({
|
|
36
32
|
enabled: interval !== RefetchRates.OFF && environment.current.viewerMode === 'monitor',
|
|
37
33
|
refetchInterval: interval === RefetchRates.MANUAL ? false : interval,
|
|
@@ -28,10 +28,11 @@ export const useResizable = (name, defaultDimensions) => {
|
|
|
28
28
|
});
|
|
29
29
|
observer.observe(target);
|
|
30
30
|
};
|
|
31
|
+
const disconnect = () => {
|
|
32
|
+
observer?.disconnect();
|
|
33
|
+
};
|
|
31
34
|
$effect(() => {
|
|
32
|
-
return
|
|
33
|
-
observer?.disconnect();
|
|
34
|
-
};
|
|
35
|
+
return disconnect;
|
|
35
36
|
});
|
|
36
37
|
return {
|
|
37
38
|
get current() {
|
|
@@ -30,11 +30,11 @@ const defaults = () => ({
|
|
|
30
30
|
renderSubEntityHoverDetail: false,
|
|
31
31
|
xrController: {
|
|
32
32
|
left: {
|
|
33
|
-
scaleFactor: 1
|
|
33
|
+
scaleFactor: 1,
|
|
34
34
|
rotationEnabled: true,
|
|
35
35
|
},
|
|
36
36
|
right: {
|
|
37
|
-
scaleFactor: 1
|
|
37
|
+
scaleFactor: 1,
|
|
38
38
|
rotationEnabled: true,
|
|
39
39
|
},
|
|
40
40
|
},
|
|
@@ -17,6 +17,7 @@ const addCookie = (name, value, days, path = '/') => {
|
|
|
17
17
|
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); // days in milliseconds
|
|
18
18
|
expires = '; expires=' + date.toUTCString();
|
|
19
19
|
}
|
|
20
|
+
// eslint-disable-next-line unicorn/no-document-cookie
|
|
20
21
|
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}; path=${path}`;
|
|
21
22
|
};
|
|
22
23
|
const getCookieExperiments = () => {
|
|
@@ -44,10 +45,10 @@ export const createWeblabs = () => {
|
|
|
44
45
|
};
|
|
45
46
|
};
|
|
46
47
|
export const provideWeblabs = () => {
|
|
47
|
-
const urlExperiment = new URLSearchParams(
|
|
48
|
+
const urlExperiment = new URLSearchParams(globalThis.location.search).get('experiment');
|
|
48
49
|
if (urlExperiment) {
|
|
49
50
|
const experimentSet = new Set([...getCookieExperiments(), urlExperiment]);
|
|
50
|
-
addCookie('weblab_experiments',
|
|
51
|
+
addCookie('weblab_experiments', [...experimentSet].join(','));
|
|
51
52
|
}
|
|
52
53
|
setContext(WEBLABS_CONTEXT_KEY, createWeblabs());
|
|
53
54
|
};
|
|
@@ -189,15 +189,17 @@ const createWorldState = (client) => {
|
|
|
189
189
|
continue;
|
|
190
190
|
}
|
|
191
191
|
switch (event.changeType) {
|
|
192
|
-
case TransformChangeType.REMOVED:
|
|
192
|
+
case TransformChangeType.REMOVED: {
|
|
193
193
|
eventsByUUID.set(uuid, event);
|
|
194
194
|
break;
|
|
195
|
-
|
|
195
|
+
}
|
|
196
|
+
case TransformChangeType.ADDED: {
|
|
196
197
|
if (existing.changeType !== TransformChangeType.REMOVED) {
|
|
197
198
|
eventsByUUID.set(uuid, event);
|
|
198
199
|
}
|
|
199
200
|
break;
|
|
200
|
-
|
|
201
|
+
}
|
|
202
|
+
case TransformChangeType.UPDATED: {
|
|
201
203
|
// merge with existing updated event
|
|
202
204
|
if (existing.changeType === TransformChangeType.UPDATED) {
|
|
203
205
|
existing.updatedFields ??= { paths: [] };
|
|
@@ -214,6 +216,7 @@ const createWorldState = (client) => {
|
|
|
214
216
|
eventsByUUID.set(uuid, event);
|
|
215
217
|
}
|
|
216
218
|
break;
|
|
219
|
+
}
|
|
217
220
|
}
|
|
218
221
|
}
|
|
219
222
|
pendingEvents.push(...eventsByUUID.values());
|
|
@@ -22,6 +22,7 @@ export const parsePcdInWorker = (data) => {
|
|
|
22
22
|
return new Promise((resolve, reject) => {
|
|
23
23
|
const id = ++requestId;
|
|
24
24
|
pending.set(id, { resolve, reject });
|
|
25
|
-
|
|
25
|
+
const copy = new Uint8Array(data);
|
|
26
|
+
worker.postMessage({ id, data: copy }, [copy.buffer]);
|
|
26
27
|
});
|
|
27
28
|
};
|