@viamrobotics/motion-tools 0.5.3 → 0.5.4
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/WorldObject.d.ts +3 -2
- package/dist/components/App.svelte +1 -1
- package/dist/components/Details.svelte +0 -1
- package/dist/components/Focus.svelte +3 -1
- package/dist/components/KeyboardControls.svelte +11 -1
- package/dist/components/Pointcloud.svelte +13 -10
- package/dist/components/Scene.svelte +2 -0
- package/dist/components/SceneProviders.svelte +0 -1
- package/dist/components/dashboard/Button.svelte +5 -4
- package/dist/hooks/useFrames.svelte.js +3 -3
- package/dist/hooks/useSelection.svelte.d.ts +7 -8
- package/dist/hooks/useShapes.svelte.js +119 -32
- package/dist/three/BatchedArrow.d.ts +2 -2
- package/dist/three/BatchedArrow.js +2 -1
- package/package.json +32 -32
package/dist/WorldObject.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Geometry, Pose } from '@viamrobotics/sdk';
|
|
2
|
-
import { BatchedMesh, Box3, Object3D, Vector3 } from 'three';
|
|
2
|
+
import { BatchedMesh, Box3, Object3D, Vector3, type ColorRepresentation } from 'three';
|
|
3
3
|
export type PointsGeometry = {
|
|
4
4
|
case: 'points';
|
|
5
5
|
value: Float32Array<ArrayBuffer>;
|
|
@@ -11,11 +11,12 @@ export type LinesGeometry = {
|
|
|
11
11
|
export type Geometries = Geometry['geometryType'] | PointsGeometry | LinesGeometry;
|
|
12
12
|
export type Metadata = {
|
|
13
13
|
colors?: Float32Array;
|
|
14
|
-
color?:
|
|
14
|
+
color?: ColorRepresentation;
|
|
15
15
|
gltf?: {
|
|
16
16
|
scene: Object3D;
|
|
17
17
|
};
|
|
18
18
|
points?: Vector3[];
|
|
19
|
+
pointSize?: number;
|
|
19
20
|
batched?: {
|
|
20
21
|
id: number;
|
|
21
22
|
object: BatchedMesh;
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
|
|
22
22
|
const object = $derived(focusedObject.current ?? selectedObject.current)
|
|
23
23
|
const object3d = $derived(focusedObject3d.current ?? selectedObject3d.current)
|
|
24
|
-
|
|
25
24
|
const worldPosition = $derived(object3d?.getWorldPosition(new Vector3()))
|
|
26
25
|
const worldQuaternion = $derived(object3d?.getWorldQuaternion(new Quaternion()))
|
|
27
26
|
const worldOrientation = $derived(
|
|
@@ -12,16 +12,18 @@
|
|
|
12
12
|
const vec = new Vector3()
|
|
13
13
|
|
|
14
14
|
let center = $state.raw<[number, number, number]>([0, 0, 0])
|
|
15
|
+
let size = $state.raw<[number, number, number]>([0, 0, 0])
|
|
15
16
|
|
|
16
17
|
$effect(() => {
|
|
17
18
|
if (object3d) {
|
|
18
19
|
box.setFromObject(object3d)
|
|
20
|
+
size = box.getSize(vec).toArray()
|
|
19
21
|
center = box.getCenter(vec).toArray()
|
|
20
22
|
}
|
|
21
23
|
})
|
|
22
24
|
</script>
|
|
23
25
|
|
|
24
|
-
<Camera position={[
|
|
26
|
+
<Camera position={[size[0], 0, 0]}>
|
|
25
27
|
<TrackballControls target={center}>
|
|
26
28
|
<Gizmo />
|
|
27
29
|
</TrackballControls>
|
|
@@ -20,11 +20,13 @@
|
|
|
20
20
|
const s = $derived(keys.has('s'))
|
|
21
21
|
const a = $derived(keys.has('a'))
|
|
22
22
|
const d = $derived(keys.has('d'))
|
|
23
|
+
const r = $derived(keys.has('r'))
|
|
24
|
+
const f = $derived(keys.has('f'))
|
|
23
25
|
const up = $derived(keys.has('arrowup'))
|
|
24
26
|
const left = $derived(keys.has('arrowleft'))
|
|
25
27
|
const down = $derived(keys.has('arrowdown'))
|
|
26
28
|
const right = $derived(keys.has('arrowright'))
|
|
27
|
-
const any = $derived(w || s || a || d || up || left || down || right)
|
|
29
|
+
const any = $derived(w || s || a || d || r || f || up || left || down || right)
|
|
28
30
|
|
|
29
31
|
const { start, stop } = useTask(
|
|
30
32
|
(delta) => {
|
|
@@ -46,6 +48,14 @@
|
|
|
46
48
|
cameraControls.forward(-0.01 * dt, true)
|
|
47
49
|
}
|
|
48
50
|
|
|
51
|
+
if (r) {
|
|
52
|
+
cameraControls.dolly(0.01 * dt, true)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (f) {
|
|
56
|
+
cameraControls.dolly(-0.01 * dt, true)
|
|
57
|
+
}
|
|
58
|
+
|
|
49
59
|
if (left) {
|
|
50
60
|
cameraControls.rotate(-0.1 * MathUtils.DEG2RAD * dt, 0, true)
|
|
51
61
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { Points, BufferAttribute, BufferGeometry, PointsMaterial } from 'three'
|
|
3
|
+
|
|
2
4
|
import { T } from '@threlte/core'
|
|
3
|
-
import { Points, BufferAttribute, BufferGeometry, Color, PointsMaterial } from 'three'
|
|
4
5
|
import type { WorldObject } from '../WorldObject'
|
|
5
6
|
import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
|
|
6
7
|
import { meshBounds } from '@threlte/extras'
|
|
@@ -12,18 +13,15 @@
|
|
|
12
13
|
|
|
13
14
|
let { object }: Props = $props()
|
|
14
15
|
|
|
15
|
-
const points = new Points()
|
|
16
|
-
const geometry = new BufferGeometry()
|
|
17
|
-
const material = new PointsMaterial({
|
|
18
|
-
size: 0.01,
|
|
19
|
-
color: new Color('#888888'),
|
|
20
|
-
})
|
|
21
|
-
|
|
22
16
|
const colors = $derived(object.metadata.colors)
|
|
23
17
|
const positions = $derived(object.geometry?.value ?? new Float32Array())
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
const points = new Points()
|
|
20
|
+
const geometry = new BufferGeometry()
|
|
21
|
+
const material = new PointsMaterial()
|
|
22
|
+
|
|
23
|
+
$effect.pre(() => {
|
|
24
|
+
material.size = object.metadata.pointSize ?? 0.01
|
|
27
25
|
})
|
|
28
26
|
|
|
29
27
|
$effect.pre(() => {
|
|
@@ -31,8 +29,13 @@
|
|
|
31
29
|
})
|
|
32
30
|
|
|
33
31
|
$effect.pre(() => {
|
|
32
|
+
material.vertexColors = colors !== undefined
|
|
33
|
+
material.color.set(colors ? 0xffffff : (object.metadata.color ?? '#888888'))
|
|
34
|
+
|
|
35
|
+
material.toneMapped = false
|
|
34
36
|
if (colors) {
|
|
35
37
|
geometry.setAttribute('color', new BufferAttribute(colors, 3))
|
|
38
|
+
geometry.attributes.color.needsUpdate = true
|
|
36
39
|
}
|
|
37
40
|
})
|
|
38
41
|
|
|
@@ -18,9 +18,6 @@
|
|
|
18
18
|
class: className = '',
|
|
19
19
|
onclick,
|
|
20
20
|
}: Props = $props()
|
|
21
|
-
|
|
22
|
-
const activeClasses = 'z-10 border-gray-5 bg-white text-gray-8'
|
|
23
|
-
const inactiveClasses = 'bg-light border-medium text-disabled'
|
|
24
21
|
</script>
|
|
25
22
|
|
|
26
23
|
<Tooltip
|
|
@@ -28,7 +25,11 @@
|
|
|
28
25
|
location="bottom"
|
|
29
26
|
>
|
|
30
27
|
<label
|
|
31
|
-
class={[
|
|
28
|
+
class={[
|
|
29
|
+
className,
|
|
30
|
+
'relative block border',
|
|
31
|
+
active ? 'border-gray-5 text-gray-8 z-10 bg-white' : 'bg-light border-medium text-disabled',
|
|
32
|
+
]}
|
|
32
33
|
aria-describedby={tooltipID}
|
|
33
34
|
>
|
|
34
35
|
<button
|
|
@@ -6,14 +6,14 @@ import { observe } from '@threlte/core';
|
|
|
6
6
|
import { useLogs } from './useLogs.svelte';
|
|
7
7
|
const key = Symbol('frames-context');
|
|
8
8
|
export const provideFrames = (partID) => {
|
|
9
|
+
const client = useRobotClient(partID);
|
|
10
|
+
const machineStatus = useMachineStatus(partID);
|
|
11
|
+
const logs = useLogs();
|
|
9
12
|
const refreshRates = useRefreshRates();
|
|
10
13
|
if (!refreshRates.has('Frames')) {
|
|
11
14
|
refreshRates.set('Frames', 1);
|
|
12
15
|
}
|
|
13
|
-
const logs = useLogs();
|
|
14
|
-
const client = useRobotClient(partID);
|
|
15
16
|
const query = createRobotQuery(client, 'frameSystemConfig');
|
|
16
|
-
const machineStatus = useMachineStatus(partID);
|
|
17
17
|
const revision = $derived(machineStatus.current?.config.revision);
|
|
18
18
|
const shouldFetch = $derived(refreshRates.get('Frames') === 1);
|
|
19
19
|
observe.pre(() => [revision], () => {
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { Object3D } from 'three';
|
|
2
2
|
import type { WorldObject } from '../WorldObject';
|
|
3
|
-
type UUID = string;
|
|
4
3
|
interface SelectionContext {
|
|
5
|
-
readonly current:
|
|
6
|
-
set(value?:
|
|
4
|
+
readonly current: string | undefined;
|
|
5
|
+
set(value?: string): void;
|
|
7
6
|
}
|
|
8
7
|
interface FocusContext {
|
|
9
|
-
readonly current:
|
|
10
|
-
set(value?:
|
|
8
|
+
readonly current: string | undefined;
|
|
9
|
+
set(value?: string): void;
|
|
11
10
|
}
|
|
12
11
|
export declare const provideSelection: () => {
|
|
13
12
|
selection: {
|
|
14
13
|
readonly current: string | undefined;
|
|
15
|
-
set(value?:
|
|
14
|
+
set(value?: string): void;
|
|
16
15
|
};
|
|
17
16
|
focus: {
|
|
18
17
|
readonly current: string | undefined;
|
|
19
|
-
set(value?:
|
|
18
|
+
set(value?: string): void;
|
|
20
19
|
};
|
|
21
20
|
hover: {
|
|
22
21
|
readonly current: string | undefined;
|
|
23
|
-
set(value?:
|
|
22
|
+
set(value?: string): void;
|
|
24
23
|
};
|
|
25
24
|
};
|
|
26
25
|
export declare const useSelected: () => SelectionContext;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getContext, setContext } from 'svelte';
|
|
2
|
-
import { Vector3, Vector4 } from 'three';
|
|
2
|
+
import { Color, Vector3, Vector4 } from 'three';
|
|
3
3
|
import { NURBSCurve } from 'three/addons/curves/NURBSCurve.js';
|
|
4
4
|
import { parsePcdInWorker } from '../loaders/pcd';
|
|
5
5
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
@@ -28,8 +28,12 @@ export const provideShapes = () => {
|
|
|
28
28
|
const nurbs = $state([]);
|
|
29
29
|
const models = $state([]);
|
|
30
30
|
let connectionStatus = $state('connecting');
|
|
31
|
+
const color = new Color();
|
|
32
|
+
const direction = new Vector3();
|
|
33
|
+
const origin = new Vector3();
|
|
34
|
+
const vec3 = new Vector3();
|
|
31
35
|
const loader = new GLTFLoader();
|
|
32
|
-
const
|
|
36
|
+
const addPCD = async (data) => {
|
|
33
37
|
const buffer = await data.arrayBuffer();
|
|
34
38
|
const { positions, colors } = await parsePcdInWorker(new Uint8Array(buffer));
|
|
35
39
|
points.push(new WorldObject(`points ${++pointsIndex}`, undefined, undefined, {
|
|
@@ -70,23 +74,41 @@ export const provideShapes = () => {
|
|
|
70
74
|
const object = new WorldObject(data.name, data.pose, data.parent, { case: 'line', value: new Float32Array() }, { color, points: curve.getPoints(200) });
|
|
71
75
|
nurbs.push(object);
|
|
72
76
|
};
|
|
73
|
-
const direction = new Vector3();
|
|
74
|
-
const origin = new Vector3();
|
|
75
|
-
const vec3 = new Vector3();
|
|
76
77
|
const batchedArrow = new BatchedArrow();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
const addPoses = async (data) => {
|
|
79
|
+
const buffer = await data.arrayBuffer();
|
|
80
|
+
const view = new DataView(buffer);
|
|
81
|
+
let offset = 0;
|
|
82
|
+
function readFloat32() {
|
|
83
|
+
const val = view.getFloat32(offset, true); // true = little-endian
|
|
84
|
+
offset += 4;
|
|
85
|
+
return val;
|
|
86
|
+
}
|
|
87
|
+
// Read counts
|
|
88
|
+
const nPoints = readFloat32();
|
|
89
|
+
const nColors = readFloat32();
|
|
90
|
+
const arrowHeadAtPose = readFloat32();
|
|
91
|
+
// Read positions
|
|
92
|
+
const nextPoses = new Float32Array(nPoints * 6);
|
|
93
|
+
for (let i = 0; i < nPoints * 6; i++) {
|
|
94
|
+
nextPoses[i] = readFloat32();
|
|
95
|
+
}
|
|
96
|
+
// Read raw colors
|
|
97
|
+
const colors = new Float32Array(nColors * 3);
|
|
98
|
+
for (let i = 0; i < nColors * 3; i++) {
|
|
99
|
+
colors[i] = readFloat32();
|
|
100
|
+
}
|
|
101
|
+
const length = 0.1;
|
|
102
|
+
for (let i = 0, j = 0, l = nextPoses.length; i < l; i += 6, j += 3) {
|
|
103
|
+
origin.set(nextPoses[i], nextPoses[i + 1], nextPoses[i + 2]).multiplyScalar(0.001);
|
|
104
|
+
direction.set(nextPoses[i + 3], nextPoses[i + 4], nextPoses[i + 5]);
|
|
105
|
+
if (arrowHeadAtPose === 1) {
|
|
85
106
|
// Compute the base position so the arrow ends at the origin
|
|
86
107
|
origin.sub(vec3.copy(direction).multiplyScalar(length));
|
|
87
108
|
}
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
color.set(colors[j], colors[j + 1], colors[j + 2]);
|
|
110
|
+
const arrowId = batchedArrow.addArrow(direction, origin, length, color);
|
|
111
|
+
poses.push(new WorldObject(`pose ${++poseIndex}`, undefined, undefined, undefined, {
|
|
90
112
|
getBoundingBoxAt(box3) {
|
|
91
113
|
return batchedArrow.getBoundingBoxAt(arrowId, box3);
|
|
92
114
|
},
|
|
@@ -97,6 +119,66 @@ export const provideShapes = () => {
|
|
|
97
119
|
}));
|
|
98
120
|
}
|
|
99
121
|
};
|
|
122
|
+
const addPoints = async (data) => {
|
|
123
|
+
const buffer = await data.arrayBuffer();
|
|
124
|
+
const view = new DataView(buffer);
|
|
125
|
+
let offset = 0;
|
|
126
|
+
function readFloat32() {
|
|
127
|
+
const val = view.getFloat32(offset, true); // true = little-endian
|
|
128
|
+
offset += 4;
|
|
129
|
+
return val;
|
|
130
|
+
}
|
|
131
|
+
// Read label length
|
|
132
|
+
const labelLen = readFloat32();
|
|
133
|
+
let label = '';
|
|
134
|
+
for (let i = 0; i < labelLen; i++) {
|
|
135
|
+
label += String.fromCharCode(readFloat32());
|
|
136
|
+
}
|
|
137
|
+
// Read counts
|
|
138
|
+
const nPoints = readFloat32();
|
|
139
|
+
const nColors = readFloat32();
|
|
140
|
+
// Read default color
|
|
141
|
+
const r = readFloat32();
|
|
142
|
+
const g = readFloat32();
|
|
143
|
+
const b = readFloat32();
|
|
144
|
+
// Read positions
|
|
145
|
+
const positions = new Float32Array(nPoints * 3);
|
|
146
|
+
for (let i = 0; i < nPoints * 3; i++) {
|
|
147
|
+
positions[i] = readFloat32();
|
|
148
|
+
}
|
|
149
|
+
const getColors = () => {
|
|
150
|
+
// Read raw colors
|
|
151
|
+
const rawColors = new Float32Array(nColors * 3);
|
|
152
|
+
for (let i = 0; i < nColors * 3; i++) {
|
|
153
|
+
rawColors[i] = readFloat32();
|
|
154
|
+
}
|
|
155
|
+
const colors = new Float32Array(nPoints * 3);
|
|
156
|
+
colors.set(rawColors);
|
|
157
|
+
// Cover the gap for any points not colored
|
|
158
|
+
for (let i = nColors; i < nPoints; i++) {
|
|
159
|
+
const offset = i * 3;
|
|
160
|
+
colors[offset] = r;
|
|
161
|
+
colors[offset + 1] = g;
|
|
162
|
+
colors[offset + 2] = b;
|
|
163
|
+
}
|
|
164
|
+
return colors;
|
|
165
|
+
};
|
|
166
|
+
const pointSize = 0.01;
|
|
167
|
+
const metadata = nColors > 0
|
|
168
|
+
? {
|
|
169
|
+
colors: getColors(),
|
|
170
|
+
color: new Color(r, g, b).convertLinearToSRGB(),
|
|
171
|
+
pointSize,
|
|
172
|
+
}
|
|
173
|
+
: {
|
|
174
|
+
color: new Color(r, g, b).convertLinearToSRGB(),
|
|
175
|
+
pointSize,
|
|
176
|
+
};
|
|
177
|
+
points.push(new WorldObject(label ?? `points ${++pointsIndex}`, undefined, undefined, {
|
|
178
|
+
case: 'points',
|
|
179
|
+
value: positions,
|
|
180
|
+
}, metadata));
|
|
181
|
+
};
|
|
100
182
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
101
183
|
const addGeometries = (geometries, colors, parent) => {
|
|
102
184
|
let i = 0;
|
|
@@ -105,6 +187,14 @@ export const provideShapes = () => {
|
|
|
105
187
|
i += 1;
|
|
106
188
|
}
|
|
107
189
|
};
|
|
190
|
+
const addGLTF = async (data) => {
|
|
191
|
+
const buffer = await data.arrayBuffer();
|
|
192
|
+
const blob = new Blob([buffer], { type: 'model/gltf-binary' });
|
|
193
|
+
const url = URL.createObjectURL(blob);
|
|
194
|
+
const gltf = await loader.loadAsync(url);
|
|
195
|
+
models.push(new WorldObject(gltf.scene.name, undefined, undefined, undefined, { gltf }));
|
|
196
|
+
URL.revokeObjectURL(url);
|
|
197
|
+
};
|
|
108
198
|
const remove = (names) => {
|
|
109
199
|
let index = -1;
|
|
110
200
|
for (const name of names) {
|
|
@@ -153,20 +243,12 @@ export const provideShapes = () => {
|
|
|
153
243
|
let metadata = undefined;
|
|
154
244
|
const handleMetadata = (data) => {
|
|
155
245
|
const json = tryParse(data);
|
|
156
|
-
if ('
|
|
246
|
+
if ('type' in json) {
|
|
157
247
|
metadata = json;
|
|
158
248
|
return true;
|
|
159
249
|
}
|
|
160
250
|
return false;
|
|
161
251
|
};
|
|
162
|
-
const loadGLTF = async (data) => {
|
|
163
|
-
const buffer = await data.arrayBuffer();
|
|
164
|
-
const blob = new Blob([buffer], { type: 'model/gltf-binary' });
|
|
165
|
-
const url = URL.createObjectURL(blob);
|
|
166
|
-
const gltf = await loader.loadAsync(url);
|
|
167
|
-
models.push(new WorldObject(gltf.scene.name, undefined, undefined, undefined, { gltf }));
|
|
168
|
-
URL.revokeObjectURL(url);
|
|
169
|
-
};
|
|
170
252
|
const { BACKEND_IP, BUN_SERVER_PORT } = globalThis;
|
|
171
253
|
const scheduleReconnect = () => {
|
|
172
254
|
setTimeout(() => {
|
|
@@ -196,13 +278,21 @@ export const provideShapes = () => {
|
|
|
196
278
|
}
|
|
197
279
|
}
|
|
198
280
|
if (typeof event.data === 'object' && 'arrayBuffer' in event.data) {
|
|
199
|
-
if (metadata
|
|
200
|
-
|
|
281
|
+
if (!metadata) {
|
|
282
|
+
return console.error('metadata is undefined');
|
|
201
283
|
}
|
|
202
|
-
|
|
203
|
-
|
|
284
|
+
if (metadata.type === 'glb') {
|
|
285
|
+
return addGLTF(event.data);
|
|
286
|
+
}
|
|
287
|
+
else if (metadata.type === 'pcd') {
|
|
288
|
+
return addPCD(event.data);
|
|
289
|
+
}
|
|
290
|
+
else if (metadata.type === 'points') {
|
|
291
|
+
return addPoints(event.data);
|
|
292
|
+
}
|
|
293
|
+
else if (metadata.type === 'poses') {
|
|
294
|
+
return addPoses(event.data);
|
|
204
295
|
}
|
|
205
|
-
return;
|
|
206
296
|
}
|
|
207
297
|
const data = tryParse(event.data);
|
|
208
298
|
if (!data)
|
|
@@ -219,9 +309,6 @@ export const provideShapes = () => {
|
|
|
219
309
|
if ('Knots' in data) {
|
|
220
310
|
return addNurbs(data, data.Color);
|
|
221
311
|
}
|
|
222
|
-
if ('poses' in data) {
|
|
223
|
-
return addPoses(data.poses, data.colors, data.arrowHeadAtPose);
|
|
224
|
-
}
|
|
225
312
|
if ('geometry' in data) {
|
|
226
313
|
addGeometry(data.geometry, data.color);
|
|
227
314
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BatchedMesh, MeshBasicMaterial, Object3D, Vector3, Box3, Matrix4 } from 'three';
|
|
1
|
+
import { BatchedMesh, MeshBasicMaterial, Object3D, Vector3, Box3, Matrix4, type ColorRepresentation } from 'three';
|
|
2
2
|
interface Arrow {
|
|
3
3
|
shaftId: number;
|
|
4
4
|
headId: number;
|
|
@@ -17,7 +17,7 @@ export declare class BatchedArrow {
|
|
|
17
17
|
shaftWidth?: number | undefined;
|
|
18
18
|
material?: MeshBasicMaterial | undefined;
|
|
19
19
|
});
|
|
20
|
-
addArrow(dir: Vector3, origin: Vector3, length?: number, color?:
|
|
20
|
+
addArrow(dir: Vector3, origin: Vector3, length?: number, color?: ColorRepresentation): number;
|
|
21
21
|
getArrowId(instanceId: number): number | undefined;
|
|
22
22
|
getBoundingBoxAt(arrowId: number, target: Box3): Box3 | undefined;
|
|
23
23
|
removeArrow(arrowId: number): void;
|
|
@@ -6,6 +6,7 @@ const box1 = new Box3();
|
|
|
6
6
|
const box2 = new Box3();
|
|
7
7
|
const mat4_1 = new Matrix4();
|
|
8
8
|
const mat4_2 = new Matrix4();
|
|
9
|
+
const col = new Color();
|
|
9
10
|
let index = 0;
|
|
10
11
|
export class BatchedArrow {
|
|
11
12
|
batchedMesh;
|
|
@@ -57,7 +58,7 @@ export class BatchedArrow {
|
|
|
57
58
|
const coneMatrix = this._computeTransform(coneOrigin, dir, headLength, headWidth * 4);
|
|
58
59
|
this.batchedMesh.setMatrixAt(headId, coneMatrix);
|
|
59
60
|
if (color) {
|
|
60
|
-
|
|
61
|
+
col.set(color);
|
|
61
62
|
this.batchedMesh.setColorAt(shaftId, col);
|
|
62
63
|
this.batchedMesh.setColorAt(headId, col);
|
|
63
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/motion-tools",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Motion visualization with Viam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -8,65 +8,65 @@
|
|
|
8
8
|
"@ag-grid-community/client-side-row-model": "32.3.5",
|
|
9
9
|
"@ag-grid-community/core": "32.3.5",
|
|
10
10
|
"@ag-grid-community/styles": "32.3.5",
|
|
11
|
-
"@changesets/cli": "2.29.
|
|
11
|
+
"@changesets/cli": "2.29.5",
|
|
12
12
|
"@dimforge/rapier3d-compat": "0.17.3",
|
|
13
|
-
"@eslint/compat": "1.3.
|
|
14
|
-
"@eslint/js": "9.
|
|
15
|
-
"@playwright/test": "1.53.
|
|
13
|
+
"@eslint/compat": "1.3.1",
|
|
14
|
+
"@eslint/js": "9.29.0",
|
|
15
|
+
"@playwright/test": "1.53.1",
|
|
16
16
|
"@skeletonlabs/skeleton": "3.1.3",
|
|
17
17
|
"@skeletonlabs/skeleton-svelte": "1.2.3",
|
|
18
18
|
"@sveltejs/adapter-static": "3.0.8",
|
|
19
|
-
"@sveltejs/kit": "2.
|
|
20
|
-
"@sveltejs/package": "2.3.
|
|
19
|
+
"@sveltejs/kit": "2.22.2",
|
|
20
|
+
"@sveltejs/package": "2.3.12",
|
|
21
21
|
"@sveltejs/vite-plugin-svelte": "5.1.0",
|
|
22
22
|
"@tailwindcss/forms": "0.5.10",
|
|
23
|
-
"@tailwindcss/vite": "4.1.
|
|
24
|
-
"@tanstack/svelte-query": "5.
|
|
25
|
-
"@tanstack/svelte-query-devtools": "5.
|
|
23
|
+
"@tailwindcss/vite": "4.1.11",
|
|
24
|
+
"@tanstack/svelte-query": "5.81.2",
|
|
25
|
+
"@tanstack/svelte-query-devtools": "5.81.2",
|
|
26
26
|
"@testing-library/jest-dom": "6.6.3",
|
|
27
27
|
"@testing-library/svelte": "5.2.8",
|
|
28
|
-
"@threlte/core": "8.0.
|
|
28
|
+
"@threlte/core": "8.0.5",
|
|
29
29
|
"@threlte/extras": "9.4.0",
|
|
30
30
|
"@threlte/rapier": "3.1.4",
|
|
31
|
-
"@threlte/xr": "1.0.
|
|
32
|
-
"@types/bun": "1.2.
|
|
31
|
+
"@threlte/xr": "1.0.8",
|
|
32
|
+
"@types/bun": "1.2.17",
|
|
33
33
|
"@types/lodash-es": "4.17.12",
|
|
34
34
|
"@types/three": "0.177.0",
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
36
|
-
"@typescript-eslint/parser": "8.
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "8.35.0",
|
|
36
|
+
"@typescript-eslint/parser": "8.35.0",
|
|
37
37
|
"@viamrobotics/prime-core": "0.1.5",
|
|
38
|
-
"@viamrobotics/sdk": "0.
|
|
39
|
-
"@viamrobotics/svelte-sdk": "0.
|
|
38
|
+
"@viamrobotics/sdk": "0.44.0",
|
|
39
|
+
"@viamrobotics/svelte-sdk": "0.4.0",
|
|
40
40
|
"@vitejs/plugin-basic-ssl": "2.0.0",
|
|
41
|
-
"@zag-js/svelte": "1.
|
|
42
|
-
"@zag-js/tree-view": "1.
|
|
41
|
+
"@zag-js/svelte": "1.17.1",
|
|
42
|
+
"@zag-js/tree-view": "1.17.1",
|
|
43
43
|
"camera-controls": "2.10.1",
|
|
44
|
-
"eslint": "9.
|
|
44
|
+
"eslint": "9.29.0",
|
|
45
45
|
"eslint-config-prettier": "10.1.5",
|
|
46
|
-
"eslint-plugin-svelte": "3.
|
|
46
|
+
"eslint-plugin-svelte": "3.10.0",
|
|
47
47
|
"globals": "16.2.0",
|
|
48
48
|
"idb-keyval": "6.2.2",
|
|
49
49
|
"jsdom": "26.1.0",
|
|
50
50
|
"lodash-es": "4.17.21",
|
|
51
|
-
"lucide-svelte": "0.
|
|
52
|
-
"prettier": "3.
|
|
51
|
+
"lucide-svelte": "0.523.0",
|
|
52
|
+
"prettier": "3.6.1",
|
|
53
53
|
"prettier-plugin-svelte": "3.4.0",
|
|
54
|
-
"prettier-plugin-tailwindcss": "0.6.
|
|
54
|
+
"prettier-plugin-tailwindcss": "0.6.13",
|
|
55
55
|
"publint": "0.3.12",
|
|
56
|
-
"runed": "0.
|
|
57
|
-
"svelte": "5.
|
|
58
|
-
"svelte-check": "4.2.
|
|
56
|
+
"runed": "0.29.1",
|
|
57
|
+
"svelte": "5.34.8",
|
|
58
|
+
"svelte-check": "4.2.2",
|
|
59
59
|
"svelte-virtuallists": "1.4.2",
|
|
60
|
-
"tailwindcss": "4.1.
|
|
60
|
+
"tailwindcss": "4.1.11",
|
|
61
61
|
"three": "0.177.0",
|
|
62
|
-
"threlte-uikit": "1.
|
|
63
|
-
"tsx": "4.20.
|
|
62
|
+
"threlte-uikit": "1.2.0",
|
|
63
|
+
"tsx": "4.20.3",
|
|
64
64
|
"typescript": "5.8.3",
|
|
65
|
-
"typescript-eslint": "8.
|
|
65
|
+
"typescript-eslint": "8.35.0",
|
|
66
66
|
"vite": "6.3.5",
|
|
67
67
|
"vite-plugin-devtools-json": "0.2.0",
|
|
68
68
|
"vite-plugin-mkcert": "1.17.8",
|
|
69
|
-
"vitest": "3.2.
|
|
69
|
+
"vitest": "3.2.4"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"@dimforge/rapier3d-compat": ">=0.17",
|