@viamrobotics/motion-tools 0.19.2 → 1.0.2
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 +56 -26
- package/dist/FrameConfigUpdater.svelte.d.ts +11 -17
- package/dist/FrameConfigUpdater.svelte.js +109 -109
- package/dist/WorldObject.svelte.js +2 -15
- package/dist/common/v1/common_pb.d.ts +950 -0
- package/dist/common/v1/common_pb.js +1399 -0
- package/dist/components/App.svelte +37 -21
- package/dist/components/App.svelte.d.ts +1 -0
- package/dist/components/BatchedArrows.svelte +102 -0
- package/dist/components/BatchedArrows.svelte.d.ts +3 -0
- package/dist/components/CameraControls.svelte +2 -3
- package/dist/components/Details.svelte +364 -365
- package/dist/components/Entities.svelte +73 -0
- package/dist/components/{WorldObjects.svelte.d.ts → Entities.svelte.d.ts} +3 -3
- package/dist/components/FileDrop.svelte +9 -23
- package/dist/components/Focus.svelte +2 -3
- package/dist/components/Frame.svelte +41 -22
- package/dist/components/Frame.svelte.d.ts +4 -6
- package/dist/components/GLTF.svelte +36 -0
- package/dist/components/GLTF.svelte.d.ts +11 -0
- package/dist/components/Geometry2.svelte +201 -0
- package/dist/components/Geometry2.svelte.d.ts +18 -0
- package/dist/components/KeyboardControls.svelte +3 -3
- package/dist/components/Line.svelte +10 -13
- package/dist/components/Line.svelte.d.ts +2 -2
- package/dist/components/LiveUpdatesBanner.svelte +51 -15
- package/dist/components/MeasureTool.svelte +4 -5
- package/dist/components/Pointcloud.svelte +27 -14
- package/dist/components/Pointcloud.svelte.d.ts +2 -2
- package/dist/components/PointerMissBox.svelte +3 -3
- package/dist/components/Pose.svelte +31 -6
- package/dist/components/Pose.svelte.d.ts +2 -2
- package/dist/components/Scene.svelte +7 -6
- package/dist/components/SceneProviders.svelte +0 -6
- package/dist/components/Selected.svelte +22 -16
- package/dist/components/StaticGeometries.svelte +51 -27
- package/dist/components/Tree/Tree.svelte +28 -22
- package/dist/components/Tree/Tree.svelte.d.ts +2 -3
- package/dist/components/Tree/TreeContainer.svelte +72 -40
- package/dist/components/Tree/Widgets.svelte +2 -5
- package/dist/components/Tree/buildTree.d.ts +3 -6
- package/dist/components/Tree/buildTree.js +19 -39
- package/dist/components/__tests__/__fixtures__/entity.d.ts +2 -0
- package/dist/components/__tests__/__fixtures__/entity.js +20 -0
- package/dist/components/__tests__/__fixtures__/resource.d.ts +17 -0
- package/dist/components/__tests__/__fixtures__/resource.js +13 -0
- package/dist/components/dashboard/Dashboard.svelte +5 -3
- package/dist/components/dashboard/Dashboard.svelte.d.ts +7 -2
- package/dist/components/widgets/ArmPositions.svelte +19 -7
- package/dist/draw/v1/drawing_pb.d.ts +341 -0
- package/dist/draw/v1/drawing_pb.js +417 -0
- package/dist/draw/v1/metadata_pb.d.ts +23 -0
- package/dist/draw/v1/metadata_pb.js +39 -0
- package/dist/draw/v1/scene_pb.d.ts +230 -0
- package/dist/draw/v1/scene_pb.js +298 -0
- package/dist/draw/v1/snapshot_pb.d.ts +42 -0
- package/dist/draw/v1/snapshot_pb.js +61 -0
- package/dist/draw/v1/transforms_pb.d.ts +23 -0
- package/dist/draw/v1/transforms_pb.js +39 -0
- package/dist/ecs/index.d.ts +4 -0
- package/dist/ecs/index.js +4 -0
- package/dist/ecs/traits.d.ts +128 -0
- package/dist/ecs/traits.js +81 -0
- package/dist/ecs/useQuery.svelte.d.ts +4 -0
- package/dist/ecs/useQuery.svelte.js +49 -0
- package/dist/ecs/useTrait.svelte.d.ts +19 -0
- package/dist/ecs/useTrait.svelte.js +40 -0
- package/dist/ecs/useWorld.d.ts +4 -0
- package/dist/ecs/useWorld.js +10 -0
- package/dist/geometry.js +6 -6
- package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte +41 -0
- package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte.d.ts +6 -0
- package/dist/hooks/use3DModels.svelte.js +6 -4
- package/dist/hooks/useDrawAPI.svelte.d.ts +0 -10
- package/dist/hooks/useDrawAPI.svelte.js +143 -267
- package/dist/hooks/useFramelessComponents.svelte.js +1 -1
- package/dist/hooks/useFrames.svelte.d.ts +6 -2
- package/dist/hooks/useFrames.svelte.js +123 -19
- package/dist/hooks/useGeometries.svelte.d.ts +0 -2
- package/dist/hooks/useGeometries.svelte.js +49 -25
- package/dist/hooks/useObjectEvents.svelte.d.ts +3 -2
- package/dist/hooks/useObjectEvents.svelte.js +11 -7
- package/dist/hooks/usePartConfig.svelte.d.ts +1 -1
- package/dist/hooks/usePartConfig.svelte.js +2 -1
- package/dist/hooks/usePointclouds.svelte.d.ts +0 -2
- package/dist/hooks/usePointclouds.svelte.js +52 -21
- package/dist/hooks/usePose.svelte.js +15 -7
- package/dist/hooks/useResizable.svelte.d.ts +12 -0
- package/dist/hooks/useResizable.svelte.js +45 -0
- package/dist/hooks/useResourceByName.svelte.js +8 -5
- package/dist/hooks/useSelection.svelte.d.ts +13 -23
- package/dist/hooks/useSelection.svelte.js +45 -65
- package/dist/hooks/useVisibility.svelte.d.ts +2 -1
- package/dist/hooks/useWeblabs.svelte.d.ts +0 -1
- package/dist/hooks/useWeblabs.svelte.js +0 -1
- package/dist/hooks/useWorldState.svelte.d.ts +9 -0
- package/dist/hooks/useWorldState.svelte.js +158 -107
- package/dist/lib.d.ts +1 -0
- package/dist/lib.js +2 -0
- package/dist/three/BatchedArrow.d.ts +2 -3
- package/dist/three/BatchedArrow.js +3 -11
- package/dist/three/CapsuleGeometry.d.ts +1 -1
- package/dist/three/CapsuleGeometry.js +3 -1
- package/dist/transform.js +0 -15
- package/package.json +12 -7
- package/dist/components/WorldObject.svelte +0 -28
- package/dist/components/WorldObject.svelte.d.ts +0 -11
- package/dist/components/WorldObjects.svelte +0 -159
- package/dist/components/WorldState.svelte +0 -92
- package/dist/components/WorldState.svelte.d.ts +0 -7
- package/dist/components/__tests__/__fixtures__/worldObject.svelte.d.ts +0 -2
- package/dist/components/__tests__/__fixtures__/worldObject.svelte.js +0 -35
- package/dist/components/portal/Portal.svelte +0 -25
- package/dist/components/portal/Portal.svelte.d.ts +0 -8
- package/dist/components/portal/PortalTarget.svelte +0 -18
- package/dist/components/portal/PortalTarget.svelte.d.ts +0 -6
- package/dist/components/portal/index.d.ts +0 -2
- package/dist/components/portal/index.js +0 -2
- package/dist/components/portal/usePortalContext.svelte.d.ts +0 -5
- package/dist/components/portal/usePortalContext.svelte.js +0 -5
- package/dist/hooks/useArrows.svelte.d.ts +0 -3
- package/dist/hooks/useArrows.svelte.js +0 -9
- package/dist/hooks/useDraggable.svelte.d.ts +0 -10
- package/dist/hooks/useDraggable.svelte.js +0 -36
- package/dist/hooks/useObjects.svelte.d.ts +0 -7
- package/dist/hooks/useObjects.svelte.js +0 -35
- package/dist/hooks/usePersistentUUIDs.svelte.d.ts +0 -5
- package/dist/hooks/usePersistentUUIDs.svelte.js +0 -13
- package/dist/hooks/useResourceByName.svelte.d.ts +0 -7
- package/dist/hooks/useStaticGeometries.svelte.d.ts +0 -9
- package/dist/hooks/useStaticGeometries.svelte.js +0 -47
- package/dist/workers/worldStateWorker.d.ts +0 -1
- package/dist/workers/worldStateWorker.js +0 -114
- package/dist/world-state-messages.d.ts +0 -23
- package/dist/world-state-messages.js +0 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { getContext, setContext } from 'svelte';
|
|
2
|
-
import { Color,
|
|
2
|
+
import { Color, Vector3, Vector4 } from 'three';
|
|
3
3
|
import { NURBSCurve } from 'three/addons/curves/NURBSCurve.js';
|
|
4
4
|
import { UuidTool } from 'uuid-tool';
|
|
5
5
|
import { parsePcdInWorker } from '../loaders/pcd';
|
|
6
6
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
7
|
-
import { WorldObject } from '../WorldObject.svelte';
|
|
8
|
-
import { useArrows } from './useArrows.svelte';
|
|
9
|
-
import { createGeometry } from '../geometry';
|
|
10
7
|
import { createPose, createPoseFromFrame } from '../transform';
|
|
11
8
|
import { useCameraControls } from './useControls.svelte';
|
|
9
|
+
import { useWorld, traits } from '../ecs';
|
|
12
10
|
import { useThrelte } from '@threlte/core';
|
|
13
|
-
import {
|
|
11
|
+
import {} from 'koota';
|
|
12
|
+
import { parsePlyInput } from '../ply';
|
|
14
13
|
import { useLogs } from './useLogs.svelte';
|
|
14
|
+
import { createBox, createCapsule, createSphere } from '../geometry';
|
|
15
|
+
const colorUtil = new Color();
|
|
15
16
|
const bufferTypes = {
|
|
16
17
|
DRAW_POINTS: 0,
|
|
17
18
|
DRAW_POSES: 1,
|
|
@@ -19,9 +20,6 @@ const bufferTypes = {
|
|
|
19
20
|
DRAW_PCD: 3,
|
|
20
21
|
DRAW_GLTF: 4,
|
|
21
22
|
};
|
|
22
|
-
const axis = new Vector3();
|
|
23
|
-
const quaternion = new Quaternion();
|
|
24
|
-
const ov = new OrientationVector();
|
|
25
23
|
const key = Symbol('draw-api-context-key');
|
|
26
24
|
const tryParse = (json) => {
|
|
27
25
|
try {
|
|
@@ -50,26 +48,25 @@ class Float32Reader {
|
|
|
50
48
|
littleEndian = true;
|
|
51
49
|
offset = 0;
|
|
52
50
|
buffer = new ArrayBuffer();
|
|
51
|
+
array = new Float32Array();
|
|
53
52
|
view = new DataView(this.buffer);
|
|
54
53
|
header = { requestID: '', type: -1 };
|
|
55
54
|
async init(data) {
|
|
56
55
|
this.buffer = await data.arrayBuffer();
|
|
57
|
-
this.header =
|
|
58
|
-
|
|
59
|
-
type: new DataView(this.buffer).getFloat32(16, true),
|
|
60
|
-
};
|
|
61
|
-
// Slice away the request header and leave the body
|
|
56
|
+
this.header.requestID = UuidTool.toString([...new Uint8Array(this.buffer.slice(0, 16))]);
|
|
57
|
+
this.header.type = new Float32Array(this.buffer.slice(16, 20))[0];
|
|
62
58
|
this.buffer = this.buffer.slice(20);
|
|
63
|
-
this.
|
|
59
|
+
this.array = new Float32Array(this.buffer);
|
|
64
60
|
return this;
|
|
65
61
|
}
|
|
66
62
|
read() {
|
|
67
|
-
const result = this.
|
|
68
|
-
this.offset +=
|
|
63
|
+
const result = this.array[this.offset];
|
|
64
|
+
this.offset += 1;
|
|
69
65
|
return result;
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
68
|
export const provideDrawAPI = () => {
|
|
69
|
+
const world = useWorld();
|
|
73
70
|
const logs = useLogs();
|
|
74
71
|
const cameraControls = useCameraControls();
|
|
75
72
|
const { invalidate } = useThrelte();
|
|
@@ -79,148 +76,134 @@ export const provideDrawAPI = () => {
|
|
|
79
76
|
let reconnectDelay = 200;
|
|
80
77
|
const maxReconnectDelay = 5_000;
|
|
81
78
|
let ws;
|
|
82
|
-
const frames = $state([]);
|
|
83
|
-
const points = $state([]);
|
|
84
|
-
const lines = $state([]);
|
|
85
|
-
const meshes = $state([]);
|
|
86
|
-
const poses = $state([]);
|
|
87
|
-
const nurbs = $state([]);
|
|
88
|
-
const models = $state([]);
|
|
89
79
|
let connectionStatus = $state('connecting');
|
|
90
|
-
const color = new Color();
|
|
91
80
|
const direction = new Vector3();
|
|
92
81
|
const origin = new Vector3();
|
|
93
82
|
const loader = new GLTFLoader();
|
|
94
|
-
const
|
|
83
|
+
const entities = new Map();
|
|
95
84
|
const sendResponse = (response) => {
|
|
96
85
|
ws.send(JSON.stringify(response));
|
|
97
86
|
};
|
|
98
87
|
const drawFrames = async (data) => {
|
|
99
|
-
for (const
|
|
100
|
-
const
|
|
101
|
-
const pose = createPoseFromFrame(
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
88
|
+
for (const rawFrame of data) {
|
|
89
|
+
const frame = lowercaseKeys(rawFrame);
|
|
90
|
+
const pose = createPoseFromFrame(frame);
|
|
91
|
+
const name = frame.name ?? frame.id ?? '';
|
|
92
|
+
const parent = frame.parent;
|
|
93
|
+
const existing = entities.get(name);
|
|
94
|
+
if (existing) {
|
|
95
|
+
existing.set(traits.Pose, pose);
|
|
96
|
+
if (parent && parent !== 'world') {
|
|
97
|
+
existing.set(traits.Parent, parent);
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
109
100
|
}
|
|
110
|
-
|
|
111
|
-
geometry
|
|
112
|
-
|
|
113
|
-
|
|
101
|
+
const geometryTrait = () => {
|
|
102
|
+
if (frame.geometry?.type === 'box') {
|
|
103
|
+
return traits.Box(frame.geometry);
|
|
104
|
+
}
|
|
105
|
+
else if (frame.geometry?.type === 'sphere') {
|
|
106
|
+
return traits.Sphere(frame.geometry);
|
|
107
|
+
}
|
|
108
|
+
else if (frame.geometry?.type === 'capsule') {
|
|
109
|
+
return traits.Capsule(frame.geometry);
|
|
110
|
+
}
|
|
111
|
+
return traits.ReferenceFrame;
|
|
112
|
+
};
|
|
113
|
+
const entityTraits = [];
|
|
114
|
+
if (parent && parent !== 'world') {
|
|
115
|
+
entityTraits.push(traits.Parent(parent));
|
|
114
116
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
geometry.geometryType.case = 'capsule';
|
|
118
|
-
geometry.geometryType.value = { lengthMm: frame.geometry.l, radiusMm: frame.geometry.r };
|
|
117
|
+
if (frame.geometry) {
|
|
118
|
+
entityTraits.push(geometryTrait());
|
|
119
119
|
}
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
entityTraits.push(traits.Name(name), traits.Pose(pose), traits.DrawAPI, traits.ReferenceFrame);
|
|
121
|
+
const entity = world.spawn(...entityTraits);
|
|
122
|
+
entities.set(name, entity);
|
|
122
123
|
}
|
|
123
124
|
};
|
|
124
125
|
const drawPCD = async (buffer) => {
|
|
125
126
|
const { positions, colors } = await parsePcdInWorker(new Uint8Array(buffer));
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
value: positions,
|
|
131
|
-
},
|
|
132
|
-
}, colors ? { colors } : undefined));
|
|
127
|
+
const entity = world.spawn(traits.Name(`Points ${++pointsIndex}`), traits.PointsGeometry(positions), traits.DrawAPI);
|
|
128
|
+
if (colors) {
|
|
129
|
+
entity.add(traits.VertexColors(colors));
|
|
130
|
+
}
|
|
133
131
|
};
|
|
134
132
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
135
133
|
const drawGeometry = (data, color, parent) => {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
const name = data.label ?? `geometry ${++geometryIndex}`;
|
|
135
|
+
const pose = createPose(data.center);
|
|
136
|
+
const existing = entities.get(name);
|
|
137
|
+
if (existing) {
|
|
138
|
+
existing.set(traits.Pose, pose);
|
|
139
139
|
return;
|
|
140
140
|
}
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
141
|
+
const geometryTrait = () => {
|
|
142
|
+
if ('mesh' in data) {
|
|
143
|
+
const geometry = parsePlyInput(data.mesh.mesh);
|
|
144
|
+
return traits.BufferGeometry(geometry);
|
|
145
|
+
}
|
|
146
|
+
else if ('box' in data) {
|
|
147
|
+
return traits.Box(createBox(data.box));
|
|
148
|
+
}
|
|
149
|
+
else if ('sphere' in data) {
|
|
150
|
+
return traits.Sphere(createSphere(data.sphere));
|
|
151
|
+
}
|
|
152
|
+
else if ('capsule' in data) {
|
|
153
|
+
return traits.Capsule(createCapsule(data.capsule));
|
|
154
|
+
}
|
|
155
|
+
return traits.ReferenceFrame;
|
|
156
|
+
};
|
|
157
|
+
const entityTraits = [];
|
|
158
|
+
if (parent && parent !== 'world') {
|
|
159
|
+
entityTraits.push(traits.Parent(parent));
|
|
157
160
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
meshes.push(object);
|
|
161
|
+
entityTraits.push(traits.Name(data.label ?? ++geometryIndex), traits.Pose(pose), traits.Color(colorUtil.set(color)), geometryTrait(), traits.DrawAPI);
|
|
162
|
+
const entity = world.spawn(...entityTraits);
|
|
163
|
+
entities.set(name, entity);
|
|
162
164
|
};
|
|
163
165
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
164
166
|
const drawNurbs = (data, color) => {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
nurbs.splice(index, 1);
|
|
168
|
-
}
|
|
167
|
+
const name = data.Name;
|
|
168
|
+
const existing = entities.get(name);
|
|
169
169
|
const controlPoints = data.ControlPts.map((point) => new Vector4(point.x / 1000, point.y / 1000, point.z / 1000));
|
|
170
170
|
const curve = new NURBSCurve(data.Degree, data.Knots, controlPoints);
|
|
171
|
-
const
|
|
172
|
-
|
|
171
|
+
const points = curve.getPoints(200);
|
|
172
|
+
if (existing) {
|
|
173
|
+
existing.set(traits.LineGeometry, points);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const entity = world.spawn(traits.Name(name), traits.Color(colorUtil.set(color)), traits.LineGeometry(points), traits.DrawAPI);
|
|
177
|
+
entities.set(name, entity);
|
|
173
178
|
};
|
|
179
|
+
const vec3 = new Vector3();
|
|
180
|
+
const pose = createPose();
|
|
174
181
|
const drawPoses = async (reader) => {
|
|
175
182
|
// Read counts
|
|
176
183
|
const nPoints = reader.read();
|
|
177
184
|
const nColors = reader.read();
|
|
178
185
|
const arrowHeadAtPose = reader.read();
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
colors[i] = reader.read();
|
|
188
|
-
}
|
|
189
|
-
const length = 0.1;
|
|
190
|
-
for (let i = 0, j = 0, l = nextPoses.length; i < l; i += 6, j += 3) {
|
|
191
|
-
origin.set(nextPoses[i], nextPoses[i + 1], nextPoses[i + 2]).multiplyScalar(0.001);
|
|
192
|
-
direction.set(nextPoses[i + 3], nextPoses[i + 4], nextPoses[i + 5]);
|
|
193
|
-
color.set(colors[j], colors[j + 1], colors[j + 2]);
|
|
194
|
-
const arrowId = batchedArrow.addArrow(direction, origin, length, color, arrowHeadAtPose === 1);
|
|
195
|
-
const pose = createPose();
|
|
186
|
+
const entities = [];
|
|
187
|
+
for (let i = 0; i < nPoints; i += 1) {
|
|
188
|
+
origin.set(reader.read(), reader.read(), reader.read()).multiplyScalar(0.001);
|
|
189
|
+
direction.set(reader.read(), reader.read(), reader.read());
|
|
190
|
+
if (arrowHeadAtPose === 1) {
|
|
191
|
+
// Compute the base position so the arrow ends at the origin
|
|
192
|
+
origin.sub(vec3.copy(direction).multiplyScalar(/** arrow length */ 0.1));
|
|
193
|
+
}
|
|
196
194
|
pose.x = origin.x;
|
|
197
195
|
pose.y = origin.y;
|
|
198
196
|
pose.z = origin.z;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
ov.setFromQuaternion(quaternion);
|
|
211
|
-
pose.oX = ov.x;
|
|
212
|
-
pose.oY = ov.y;
|
|
213
|
-
pose.oZ = ov.z;
|
|
214
|
-
pose.theta = MathUtils.radToDeg(ov.th);
|
|
215
|
-
poses.push(new WorldObject(`pose ${++poseIndex}`, pose, 'world', undefined, {
|
|
216
|
-
getBoundingBoxAt(box3) {
|
|
217
|
-
return batchedArrow.getBoundingBoxAt(arrowId, box3);
|
|
218
|
-
},
|
|
219
|
-
batched: {
|
|
220
|
-
id: arrowId,
|
|
221
|
-
object: batchedArrow.object3d,
|
|
222
|
-
},
|
|
223
|
-
}));
|
|
197
|
+
pose.oX = direction.x;
|
|
198
|
+
pose.oY = direction.y;
|
|
199
|
+
pose.oZ = direction.z;
|
|
200
|
+
const entity = world.spawn(traits.Name(`Pose ${++poseIndex}`), traits.Pose(pose), traits.Color, traits.DrawAPI, traits.Arrow);
|
|
201
|
+
entities.push(entity);
|
|
202
|
+
}
|
|
203
|
+
for (let i = 0; i < nColors; i += 1) {
|
|
204
|
+
const entity = entities[i];
|
|
205
|
+
colorUtil.set(reader.read(), reader.read(), reader.read());
|
|
206
|
+
entity.set(traits.Color, colorUtil);
|
|
224
207
|
}
|
|
225
208
|
};
|
|
226
209
|
const drawPoints = async (reader) => {
|
|
@@ -230,10 +213,9 @@ export const provideDrawAPI = () => {
|
|
|
230
213
|
for (let i = 0; i < labelLen; i++) {
|
|
231
214
|
label += String.fromCharCode(reader.read());
|
|
232
215
|
}
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
216
|
+
const entities = world.query(traits.DrawAPI);
|
|
217
|
+
const entity = entities.find((entity) => entity.get(traits.Name) === label);
|
|
218
|
+
entity?.destroy();
|
|
237
219
|
// Read counts
|
|
238
220
|
const nPoints = reader.read();
|
|
239
221
|
const nColors = reader.read();
|
|
@@ -241,45 +223,22 @@ export const provideDrawAPI = () => {
|
|
|
241
223
|
const r = reader.read();
|
|
242
224
|
const g = reader.read();
|
|
243
225
|
const b = reader.read();
|
|
244
|
-
|
|
245
|
-
const positions =
|
|
246
|
-
|
|
247
|
-
|
|
226
|
+
const nPointsElements = nPoints * 3;
|
|
227
|
+
const positions = reader.array.slice(reader.offset, reader.offset + nPointsElements);
|
|
228
|
+
reader.offset += nPointsElements;
|
|
229
|
+
const nColorsElements = nColors * 3;
|
|
230
|
+
const rawColors = reader.array.slice(reader.offset, reader.offset + nColorsElements);
|
|
231
|
+
reader.offset += nColorsElements;
|
|
232
|
+
const colors = new Float32Array(nPointsElements);
|
|
233
|
+
colors.set(rawColors);
|
|
234
|
+
// Cover the gap for any points not colored
|
|
235
|
+
for (let i = nColors; i < nPoints; i++) {
|
|
236
|
+
const offset = i * 3;
|
|
237
|
+
colors[offset] = r;
|
|
238
|
+
colors[offset + 1] = g;
|
|
239
|
+
colors[offset + 2] = b;
|
|
248
240
|
}
|
|
249
|
-
|
|
250
|
-
// Read raw colors
|
|
251
|
-
const rawColors = new Float32Array(nColors * 3);
|
|
252
|
-
for (let i = 0; i < nColors * 3; i++) {
|
|
253
|
-
rawColors[i] = reader.read();
|
|
254
|
-
}
|
|
255
|
-
const colors = new Float32Array(nPoints * 3);
|
|
256
|
-
colors.set(rawColors);
|
|
257
|
-
// Cover the gap for any points not colored
|
|
258
|
-
for (let i = nColors; i < nPoints; i++) {
|
|
259
|
-
const offset = i * 3;
|
|
260
|
-
colors[offset] = r;
|
|
261
|
-
colors[offset + 1] = g;
|
|
262
|
-
colors[offset + 2] = b;
|
|
263
|
-
}
|
|
264
|
-
return colors;
|
|
265
|
-
};
|
|
266
|
-
const metadata = nColors > 0
|
|
267
|
-
? {
|
|
268
|
-
colors: getColors(),
|
|
269
|
-
color: new Color(r, g, b).convertLinearToSRGB(),
|
|
270
|
-
}
|
|
271
|
-
: r === -1
|
|
272
|
-
? undefined
|
|
273
|
-
: {
|
|
274
|
-
color: new Color(r, g, b).convertLinearToSRGB(),
|
|
275
|
-
};
|
|
276
|
-
points.push(new WorldObject(label, undefined, undefined, {
|
|
277
|
-
center: undefined,
|
|
278
|
-
geometryType: {
|
|
279
|
-
case: 'points',
|
|
280
|
-
value: positions,
|
|
281
|
-
},
|
|
282
|
-
}, metadata));
|
|
241
|
+
world.spawn(traits.Name(label), traits.Color(colorUtil.set(r, g, b)), traits.PointsGeometry(positions), traits.VertexColors(colors), traits.DrawAPI);
|
|
283
242
|
};
|
|
284
243
|
const drawLine = async (reader) => {
|
|
285
244
|
// Read label length
|
|
@@ -288,39 +247,24 @@ export const provideDrawAPI = () => {
|
|
|
288
247
|
for (let i = 0; i < labelLen; i++) {
|
|
289
248
|
label += String.fromCharCode(reader.read());
|
|
290
249
|
}
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
250
|
+
const entities = world.query(traits.DrawAPI);
|
|
251
|
+
const entity = entities.find((entity) => entity.get(traits.Name) === label);
|
|
252
|
+
entity?.destroy();
|
|
295
253
|
// Read counts
|
|
296
254
|
const nPoints = reader.read();
|
|
297
255
|
// Read default color
|
|
298
|
-
const
|
|
299
|
-
const
|
|
300
|
-
const
|
|
256
|
+
const r = reader.read();
|
|
257
|
+
const g = reader.read();
|
|
258
|
+
const b = reader.read();
|
|
301
259
|
const dotR = reader.read();
|
|
302
260
|
const dotG = reader.read();
|
|
303
261
|
const dotB = reader.read();
|
|
304
262
|
// Read positions
|
|
305
|
-
const positions = new Float32Array(nPoints * 3);
|
|
306
|
-
for (let i = 0; i < nPoints * 3; i++) {
|
|
307
|
-
positions[i] = reader.read();
|
|
308
|
-
}
|
|
309
263
|
const points = [];
|
|
310
|
-
for (let i = 0; i <
|
|
311
|
-
points.push(new Vector3(
|
|
264
|
+
for (let i = 0; i < nPoints * 3; i += 3) {
|
|
265
|
+
points.push(new Vector3(reader.read(), reader.read(), reader.read()));
|
|
312
266
|
}
|
|
313
|
-
|
|
314
|
-
center: undefined,
|
|
315
|
-
geometryType: {
|
|
316
|
-
case: 'line',
|
|
317
|
-
value: positions,
|
|
318
|
-
},
|
|
319
|
-
}, {
|
|
320
|
-
points,
|
|
321
|
-
color: lineR === -1 ? undefined : new Color().setRGB(lineR, lineG, lineB),
|
|
322
|
-
lineDotColor: dotR === -1 ? undefined : new Color().setRGB(dotR, dotG, dotB),
|
|
323
|
-
}));
|
|
267
|
+
world.spawn(traits.Name(label), traits.Color({ r, g, b }), traits.LineGeometry(points), traits.DottedLineColor({ r: dotR, g: dotG, b: dotB }), traits.DrawAPI);
|
|
324
268
|
};
|
|
325
269
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
326
270
|
const drawGeometries = (geometries, colors, parent) => {
|
|
@@ -334,67 +278,26 @@ export const provideDrawAPI = () => {
|
|
|
334
278
|
const blob = new Blob([buffer], { type: 'model/gltf-binary' });
|
|
335
279
|
const url = URL.createObjectURL(blob);
|
|
336
280
|
const gltf = await loader.loadAsync(url);
|
|
337
|
-
|
|
281
|
+
world.spawn(traits.Name(gltf.scene.name), traits.GLTF(gltf), traits.DrawAPI);
|
|
338
282
|
URL.revokeObjectURL(url);
|
|
339
283
|
};
|
|
340
284
|
const remove = (names) => {
|
|
341
|
-
let index = -1;
|
|
342
285
|
for (const name of names) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
index = points.findIndex((p) => p.name === name);
|
|
349
|
-
if (index !== -1) {
|
|
350
|
-
points.splice(index, 1);
|
|
351
|
-
continue;
|
|
352
|
-
}
|
|
353
|
-
index = meshes.findIndex((m) => m.name === name);
|
|
354
|
-
if (index !== -1) {
|
|
355
|
-
meshes.splice(index, 1);
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
index = poses.findIndex((p) => p.name === name);
|
|
359
|
-
if (index !== -1) {
|
|
360
|
-
const id = poses[index].metadata.batched?.id;
|
|
361
|
-
if (id) {
|
|
362
|
-
batchedArrow.removeArrow(id);
|
|
363
|
-
poses.splice(index, 1);
|
|
364
|
-
continue;
|
|
286
|
+
for (const entity of world.query(traits.DrawAPI)) {
|
|
287
|
+
if (entity.get(traits.Name) === name) {
|
|
288
|
+
entity.destroy();
|
|
365
289
|
}
|
|
366
290
|
}
|
|
367
|
-
index = nurbs.findIndex((n) => n.name === name);
|
|
368
|
-
if (index !== -1) {
|
|
369
|
-
nurbs.splice(index, 1);
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
|
-
index = models.findIndex((m) => m.name === name);
|
|
373
|
-
if (index !== -1) {
|
|
374
|
-
models.splice(index, 1);
|
|
375
|
-
continue;
|
|
376
|
-
}
|
|
377
|
-
index = lines.findIndex((m) => m.name === name);
|
|
378
|
-
if (index !== -1) {
|
|
379
|
-
lines.splice(index, 1);
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
291
|
}
|
|
383
292
|
};
|
|
384
293
|
const removeAll = () => {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
meshes.splice(0, meshes.length);
|
|
389
|
-
nurbs.splice(0, nurbs.length);
|
|
390
|
-
models.splice(0, models.length);
|
|
391
|
-
poses.splice(0, poses.length);
|
|
392
|
-
batchedArrow.clear();
|
|
294
|
+
for (const entity of world.query(traits.DrawAPI)) {
|
|
295
|
+
entity.destroy();
|
|
296
|
+
}
|
|
393
297
|
pointsIndex = 0;
|
|
394
298
|
geometryIndex = 0;
|
|
395
299
|
poseIndex = 0;
|
|
396
300
|
};
|
|
397
|
-
const { BACKEND_IP, BUN_SERVER_PORT } = globalThis;
|
|
398
301
|
const scheduleReconnect = () => {
|
|
399
302
|
setTimeout(() => {
|
|
400
303
|
reconnectDelay = Math.min(reconnectDelay * 2, maxReconnectDelay);
|
|
@@ -405,7 +308,7 @@ export const provideDrawAPI = () => {
|
|
|
405
308
|
const onOpen = () => {
|
|
406
309
|
connectionStatus = 'open';
|
|
407
310
|
reconnectDelay = 1000;
|
|
408
|
-
logs.add(`Connected to drawing server at ${BACKEND_IP}:${
|
|
311
|
+
logs.add(`Connected to drawing server at ${BACKEND_IP}:${WS_PORT}`);
|
|
409
312
|
};
|
|
410
313
|
const onClose = () => {
|
|
411
314
|
connectionStatus = 'closed';
|
|
@@ -507,9 +410,9 @@ export const provideDrawAPI = () => {
|
|
|
507
410
|
invalidate();
|
|
508
411
|
};
|
|
509
412
|
const connect = () => {
|
|
510
|
-
if (BACKEND_IP &&
|
|
413
|
+
if (BACKEND_IP && WS_PORT) {
|
|
511
414
|
const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
512
|
-
ws = new WebSocket(`${protocol}://${BACKEND_IP}:${
|
|
415
|
+
ws = new WebSocket(`${protocol}://${BACKEND_IP}:${WS_PORT}/ws`);
|
|
513
416
|
ws.onclose = onClose;
|
|
514
417
|
ws.onerror = onError;
|
|
515
418
|
ws.onopen = onOpen;
|
|
@@ -518,36 +421,9 @@ export const provideDrawAPI = () => {
|
|
|
518
421
|
};
|
|
519
422
|
connect();
|
|
520
423
|
setContext(key, {
|
|
521
|
-
get frames() {
|
|
522
|
-
return frames;
|
|
523
|
-
},
|
|
524
|
-
get points() {
|
|
525
|
-
return points;
|
|
526
|
-
},
|
|
527
|
-
get lines() {
|
|
528
|
-
return lines;
|
|
529
|
-
},
|
|
530
|
-
get meshes() {
|
|
531
|
-
return meshes;
|
|
532
|
-
},
|
|
533
|
-
get poses() {
|
|
534
|
-
return poses;
|
|
535
|
-
},
|
|
536
|
-
get nurbs() {
|
|
537
|
-
return nurbs;
|
|
538
|
-
},
|
|
539
|
-
get models() {
|
|
540
|
-
return models;
|
|
541
|
-
},
|
|
542
424
|
get connectionStatus() {
|
|
543
425
|
return connectionStatus;
|
|
544
426
|
},
|
|
545
|
-
addPoints(worldObject) {
|
|
546
|
-
points.push(worldObject);
|
|
547
|
-
},
|
|
548
|
-
addMesh(worldObject) {
|
|
549
|
-
meshes.push(worldObject);
|
|
550
|
-
},
|
|
551
427
|
});
|
|
552
428
|
};
|
|
553
429
|
export const useDrawAPI = () => {
|
|
@@ -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.find((
|
|
15
|
+
if (frames.current.find((frame) => frame.transform.referenceFrame === fragmentComponentName)) {
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
18
|
fragmentComponentsWithNoFrame.push(fragmentComponentName);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transform } from '@viamrobotics/sdk';
|
|
2
|
+
interface FrameTransform {
|
|
3
|
+
type: 'machine' | 'config' | 'fragment';
|
|
4
|
+
transform: Transform;
|
|
5
|
+
}
|
|
2
6
|
interface FramesContext {
|
|
3
|
-
current:
|
|
7
|
+
current: FrameTransform[];
|
|
4
8
|
getParentFrameOptions: (componentName: string) => string[];
|
|
5
9
|
}
|
|
6
10
|
export declare const provideFrames: (partID: () => string) => void;
|