@viamrobotics/motion-tools 1.11.0 → 1.12.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.
Files changed (45) hide show
  1. package/dist/components/App.svelte +6 -1
  2. package/dist/components/CameraControls.svelte +1 -1
  3. package/dist/components/Focus.svelte +1 -8
  4. package/dist/components/Geometry.svelte +13 -13
  5. package/dist/components/Lasso/Debug.svelte +72 -0
  6. package/dist/components/Lasso/Debug.svelte.d.ts +8 -0
  7. package/dist/components/Lasso/Lasso.svelte +299 -0
  8. package/dist/components/Lasso/Lasso.svelte.d.ts +6 -0
  9. package/dist/components/Lasso/Tool.svelte +94 -0
  10. package/dist/components/Lasso/Tool.svelte.d.ts +9 -0
  11. package/dist/components/Lasso/traits.d.ts +21 -0
  12. package/dist/components/Lasso/traits.js +16 -0
  13. package/dist/components/LineGeometry.svelte +20 -0
  14. package/dist/components/LineGeometry.svelte.d.ts +12 -0
  15. package/dist/components/MeasureTool/MeasureTool.svelte +2 -2
  16. package/dist/components/PCD.svelte +34 -0
  17. package/dist/components/PCD.svelte.d.ts +6 -0
  18. package/dist/components/PointerMissBox.svelte +1 -2
  19. package/dist/components/Points.svelte +1 -1
  20. package/dist/components/Scene.svelte +10 -8
  21. package/dist/components/hover/HoveredEntityTooltip.svelte +2 -1
  22. package/dist/components/overlay/FloatingPanel.svelte +17 -10
  23. package/dist/components/overlay/FloatingPanel.svelte.d.ts +5 -0
  24. package/dist/components/xr/CameraFeed.svelte +3 -0
  25. package/dist/components/xr/CameraFeed.svelte.d.ts +1 -0
  26. package/dist/components/xr/JointLimitsWidget.svelte +25 -22
  27. package/dist/components/xr/XR.svelte +28 -20
  28. package/dist/ecs/traits.d.ts +8 -0
  29. package/dist/ecs/traits.js +8 -0
  30. package/dist/hooks/useControls.svelte.d.ts +2 -1
  31. package/dist/hooks/useControls.svelte.js +7 -2
  32. package/dist/hooks/usePartConfig.svelte.js +1 -1
  33. package/dist/hooks/useSettings.svelte.d.ts +1 -1
  34. package/dist/hooks/useSettings.svelte.js +1 -1
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +3 -0
  37. package/dist/pcd.d.ts +1 -0
  38. package/dist/pcd.js +44 -0
  39. package/dist/plugins/bvh.svelte.d.ts +8 -0
  40. package/dist/plugins/bvh.svelte.js +74 -0
  41. package/dist/ply.d.ts +1 -1
  42. package/dist/ply.js +5 -0
  43. package/dist/test/createRandomPcdBinary.d.ts +1 -1
  44. package/dist/test/createRandomPcdBinary.js +14 -27
  45. package/package.json +4 -1
@@ -0,0 +1,74 @@
1
+ import { injectPlugin, isInstanceOf } from '@threlte/core';
2
+ import { BatchedMesh, Points, Mesh } from 'three';
3
+ import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree, computeBatchedBoundsTree, disposeBatchedBoundsTree, PointsBVH, SAH, BVHHelper, } from 'three-mesh-bvh';
4
+ export const bvh = (raycaster, options) => {
5
+ const bvhOptions = $derived({
6
+ strategy: SAH,
7
+ verbose: false,
8
+ setBoundingBox: true,
9
+ maxDepth: 20,
10
+ maxLeafSize: 10,
11
+ indirect: false,
12
+ helper: false,
13
+ ...options?.(),
14
+ });
15
+ raycaster.firstHitOnly = true;
16
+ raycaster.params.Points.threshold = 0.005;
17
+ injectPlugin('bvh', (args) => {
18
+ const { props } = $derived(args);
19
+ const opts = $derived(props.bvh ? { ...bvhOptions, ...props.bvh } : bvhOptions);
20
+ $effect(() => {
21
+ const { ref } = args;
22
+ if (opts.enabled === false) {
23
+ return;
24
+ }
25
+ if (isInstanceOf(ref, 'Points')) {
26
+ ref.geometry.computeBoundsTree = computeBoundsTree;
27
+ ref.geometry.disposeBoundsTree = disposeBoundsTree;
28
+ ref.raycast = acceleratedRaycast;
29
+ computeBoundsTree.call(ref.geometry, { type: PointsBVH, ...opts });
30
+ const helper = opts.helper ? new BVHHelper(ref) : undefined;
31
+ if (helper)
32
+ ref.add(helper);
33
+ return () => {
34
+ ref.raycast = Points.prototype.raycast;
35
+ if (helper)
36
+ ref.remove(helper);
37
+ };
38
+ }
39
+ else if (isInstanceOf(ref, 'BatchedMesh')) {
40
+ /* @ts-expect-error Some sort of ambient type is conflicing here, likely from @threlte/extras */
41
+ ref.geometry.computeBoundsTree = computeBatchedBoundsTree;
42
+ ref.geometry.disposeBoundsTree = disposeBatchedBoundsTree;
43
+ ref.raycast = acceleratedRaycast;
44
+ const helper = opts.helper ? new BVHHelper(ref) : undefined;
45
+ if (helper)
46
+ ref.add(helper);
47
+ return () => {
48
+ ref.raycast = BatchedMesh.prototype.raycast;
49
+ if (helper)
50
+ ref.remove(helper);
51
+ };
52
+ }
53
+ else if (isInstanceOf(ref, 'Mesh') &&
54
+ /**
55
+ * (mp) Line2s sort of suck. Their buffer attribute design internally is much different
56
+ * but they give no indication other than this that they are different.
57
+ */
58
+ ref.geometry.attributes.position) {
59
+ ref.geometry.computeBoundsTree = computeBoundsTree;
60
+ ref.geometry.disposeBoundsTree = disposeBoundsTree;
61
+ ref.raycast = acceleratedRaycast;
62
+ computeBoundsTree.call(ref.geometry, opts);
63
+ const helper = opts.helper ? new BVHHelper(ref) : undefined;
64
+ if (helper)
65
+ ref.add(helper);
66
+ return () => {
67
+ ref.raycast = Mesh.prototype.raycast;
68
+ if (helper)
69
+ ref.remove(helper);
70
+ };
71
+ }
72
+ });
73
+ });
74
+ };
package/dist/ply.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import type { BufferGeometry } from 'three';
1
+ import { BufferGeometry } from 'three';
2
2
  export declare const parsePlyInput: (mesh: string | Uint8Array) => BufferGeometry;
package/dist/ply.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { BufferGeometry } from 'three';
1
2
  import { PLYLoader } from 'three/addons/loaders/PLYLoader.js';
2
3
  const plyLoader = new PLYLoader();
3
4
  export const parsePlyInput = (mesh) => {
@@ -5,6 +6,10 @@ export const parsePlyInput = (mesh) => {
5
6
  if (typeof mesh === 'string') {
6
7
  return plyLoader.parse(atob(mesh));
7
8
  }
9
+ // First, determine if ply has any geometry
10
+ if (mesh.length === 0) {
11
+ return new BufferGeometry();
12
+ }
8
13
  // Case 2: detect text vs binary PLY in Uint8Array
9
14
  const header = new TextDecoder().decode(mesh.slice(0, 50));
10
15
  const isAscii = header.includes('format ascii');
@@ -1 +1 @@
1
- export declare const createRandomPcdBinary: (numPoints?: number, scale?: number, axes?: string) => Uint8Array;
1
+ export declare const createRandomPcdBinary: (numPoints?: number, scale?: number, axes?: string) => Promise<Uint8Array>;
@@ -1,31 +1,18 @@
1
- export const createRandomPcdBinary = (numPoints = 200, scale = 1, axes = 'xyz') => {
2
- const header = `
3
- # .PCD v0.7 - Point Cloud Data file format
4
- VERSION 0.7
5
- FIELDS x y z rgb
6
- SIZE 4 4 4 4
7
- TYPE F F F F
8
- COUNT 1 1 1
9
- WIDTH ${numPoints}
10
- HEIGHT 1
11
- VIEWPOINT 0 0 0 1 0 0 0
12
- POINTS ${numPoints}
13
- DATA ascii
14
- `.trim();
1
+ import { createBinaryPCD } from '../pcd';
2
+ export const createRandomPcdBinary = async (numPoints = 200, scale = 1, axes = 'xyz') => {
15
3
  const doX = axes.includes('x');
16
4
  const doY = axes.includes('y');
17
5
  const doZ = axes.includes('z');
18
- const points = Array.from({ length: numPoints }, () => {
19
- const x = doX ? ((Math.random() - 0.5) * scale).toFixed(6) : '0.000000';
20
- const y = doY ? ((Math.random() - 0.5) * scale).toFixed(6) : '0.000000';
21
- const z = doZ ? ((Math.random() - 0.5) * scale).toFixed(6) : '0.000000';
22
- const red = Math.floor(Math.random() * 256);
23
- const green = Math.floor(Math.random() * 256);
24
- const blue = Math.floor(Math.random() * 256);
25
- const rgbInt = (red << 16) | (green << 8) | blue;
26
- const rgbFloat = String(new Float32Array(new Uint32Array([rgbInt]).buffer)[0]);
27
- return `${x} ${y} ${z} ${rgbFloat}`;
28
- });
29
- const encoder = new TextEncoder();
30
- return encoder.encode(`${header}\n${points.join('\n')}`);
6
+ const positions = new Float32Array(numPoints * 3);
7
+ const colors = new Uint8Array(numPoints * 3);
8
+ for (let i = 0, l = positions.length; i < l; i += 1) {
9
+ positions[i] = doX ? (Math.random() - 0.5) * scale : 0;
10
+ positions[i + 1] = doY ? (Math.random() - 0.5) * scale : 0;
11
+ positions[i + 2] = doZ ? (Math.random() - 0.5) * scale : 0;
12
+ colors[i] = Math.floor(Math.random() * 256);
13
+ colors[i + 1] = Math.floor(Math.random() * 256);
14
+ colors[i + 2] = Math.floor(Math.random() * 256);
15
+ }
16
+ const buffer = await createBinaryPCD(positions, colors).arrayBuffer();
17
+ return new Uint8Array(buffer);
31
18
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viamrobotics/motion-tools",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "Motion visualization with Viam",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -30,6 +30,7 @@
30
30
  "@threlte/rapier": "3.2.0",
31
31
  "@threlte/xr": "1.0.8",
32
32
  "@types/bun": "1.2.21",
33
+ "@types/earcut": "^3.0.0",
33
34
  "@types/lodash-es": "4.17.12",
34
35
  "@types/three": "0.181.0",
35
36
  "@typescript-eslint/eslint-plugin": "8.42.0",
@@ -132,9 +133,11 @@
132
133
  "@connectrpc/connect-web": "1.7.0",
133
134
  "@neodrag/svelte": "^2.3.3",
134
135
  "@tanstack/svelte-query-devtools": "^6.0.2",
136
+ "earcut": "^3.0.2",
135
137
  "expr-eval": "^2.0.2",
136
138
  "koota": "0.6.5",
137
139
  "lodash-es": "4.17.23",
140
+ "three-mesh-bvh": "^0.9.8",
138
141
  "uuid-tool": "^2.0.3"
139
142
  },
140
143
  "scripts": {