@viamrobotics/motion-tools 1.13.0 → 1.14.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/dist/FrameConfigUpdater.svelte.js +1 -1
- package/dist/attribute.js +10 -2
- 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/buffer.d.ts +56 -7
- package/dist/buffer.js +70 -12
- 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} +7 -3
- package/dist/components/Entities/Frame.svelte +86 -0
- package/dist/components/{Frame.svelte.d.ts → Entities/Frame.svelte.d.ts} +1 -0
- package/dist/components/{GLTF.svelte → Entities/GLTF.svelte} +5 -5
- package/dist/components/Entities/Geometry.svelte +75 -0
- package/dist/components/Entities/Geometry.svelte.d.ts +10 -0
- package/dist/components/{Label.svelte → Entities/Label.svelte} +1 -1
- package/dist/components/Entities/Line.svelte +90 -0
- package/dist/components/Entities/Mesh.svelte +130 -0
- package/dist/components/Entities/Mesh.svelte.d.ts +4 -0
- 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/Selected.svelte +2 -0
- 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/left-pane/buildTree.js +15 -0
- 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/traits.d.ts +2 -19
- package/dist/ecs/traits.js +33 -6
- package/dist/ecs/useQuery.svelte.js +3 -3
- package/dist/format.js +1 -1
- package/dist/hooks/use3DModels.svelte.js +36 -38
- 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 +62 -56
- package/dist/hooks/useGeometries.svelte.js +59 -36
- package/dist/hooks/useLinked.svelte.js +5 -4
- package/dist/hooks/usePartConfig.svelte.js +16 -17
- package/dist/hooks/usePointcloudObjects.svelte.js +107 -62
- package/dist/hooks/usePointclouds.svelte.js +50 -32
- 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 +31 -28
- 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/metadata.d.ts +22 -0
- package/dist/metadata.js +66 -0
- package/dist/snapshot.d.ts +20 -0
- package/dist/snapshot.js +72 -28
- 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/dist/three/OBBHelper.d.ts +3 -2
- package/dist/three/OBBHelper.js +17 -5
- package/package.json +19 -11
- package/dist/WorldObject.svelte.d.ts +0 -27
- package/dist/WorldObject.svelte.js +0 -114
- package/dist/components/Frame.svelte +0 -89
- package/dist/components/Geometry.svelte +0 -211
- package/dist/components/Geometry.svelte.d.ts +0 -19
- package/dist/components/Line.svelte +0 -43
- /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/{GLTF.svelte.d.ts → Entities/GLTF.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
package/dist/buffer.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Proto messages pack float32 data as `Uint8Array` (bytes fields). These utilities
|
|
5
5
|
* provide efficient conversion to `Float32Array` for Three.js BufferAttributes.
|
|
6
6
|
*/
|
|
7
|
+
import { Color } from 'three';
|
|
7
8
|
/**
|
|
8
9
|
* Stride constants for proto binary data formats.
|
|
9
10
|
* Each value represents the number of float32 elements per item.
|
|
@@ -37,16 +38,64 @@ export declare const STRIDE: {
|
|
|
37
38
|
*/
|
|
38
39
|
export declare const asFloat32Array: (bytes: Uint8Array<ArrayBuffer>) => Float32Array<ArrayBuffer>;
|
|
39
40
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
41
|
+
* Sets a Three.js Color from 3 bytes of a uint8 color array starting at `offset`.
|
|
42
|
+
* Mutates and returns `target` — pass a pre-allocated Color to avoid allocations
|
|
43
|
+
* in hot paths.
|
|
42
44
|
*
|
|
43
|
-
* @param
|
|
44
|
-
* @
|
|
45
|
+
* @param bytes - Uint8Array with at least `offset + 3` elements [r, g, b, ...]
|
|
46
|
+
* @param target - Color instance to write into
|
|
47
|
+
* @param offset - Byte offset to start reading from (default 0)
|
|
48
|
+
* @returns The mutated `target`, or black if the array has fewer than `offset + 3` elements
|
|
45
49
|
*
|
|
46
50
|
* @example
|
|
47
51
|
* ```ts
|
|
48
|
-
*
|
|
49
|
-
*
|
|
52
|
+
* asColor(colors.current, material.color)
|
|
53
|
+
* asColor(colors.current, pointColorUtil, stride) // read second color
|
|
50
54
|
* ```
|
|
51
55
|
*/
|
|
52
|
-
export declare const
|
|
56
|
+
export declare const asColor: (bytes: Uint8Array<ArrayBuffer>, target: Color, offset?: number) => Color;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a Uint8Array from a Three.js Color.
|
|
59
|
+
*
|
|
60
|
+
* @param color - The Three.js Color to convert
|
|
61
|
+
* @returns A Uint8Array with the RGBA values
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const color = fromColor(new Color(0, 1, 0))
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare const fromColor: (color: Color) => Uint8Array<ArrayBuffer>;
|
|
69
|
+
/**
|
|
70
|
+
* Reads a byte from a uint8 color array at `offset` and normalizes it to 0-1.
|
|
71
|
+
* Returns `fallback` when the array has fewer than `offset + 1` elements.
|
|
72
|
+
*
|
|
73
|
+
* @param bytes - ArrayLike of uint8 color values
|
|
74
|
+
* @param fallback - Value to return when no alpha byte is present (default 1)
|
|
75
|
+
* @param offset - Byte index to read from (default 3, the alpha channel of the first color)
|
|
76
|
+
* @returns Normalized opacity in 0-1 range, or the fallback value
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* material.opacity = asOpacity(colors.current)
|
|
81
|
+
* material.opacity = asOpacity(colors.current, 1, stride + 3) // alpha of second color
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare const asOpacity: (bytes: Uint8Array<ArrayBuffer>, fallback?: number, offset?: number) => number;
|
|
85
|
+
/**
|
|
86
|
+
* Returns true when `colors` contains exactly one color entry per point (RGB or RGBA).
|
|
87
|
+
* Use this to distinguish per-vertex color buffers from a single uniform color.
|
|
88
|
+
*
|
|
89
|
+
* @param colors - Uint8Array of packed color bytes
|
|
90
|
+
* @param numVertex - Number of points/vertices the color buffer should cover
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* if (isPerVertexColors(colors, positions.length / STRIDE.POSITIONS)) {
|
|
95
|
+
* // treat as per-vertex
|
|
96
|
+
* } else {
|
|
97
|
+
* addColorTraits(entityTraits, colors)
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare const isPerVertexColors: (colors: Uint8Array<ArrayBuffer>, numVertex: number) => boolean;
|
package/dist/buffer.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Proto messages pack float32 data as `Uint8Array` (bytes fields). These utilities
|
|
5
5
|
* provide efficient conversion to `Float32Array` for Three.js BufferAttributes.
|
|
6
6
|
*/
|
|
7
|
+
import { Color } from 'three';
|
|
7
8
|
/**
|
|
8
9
|
* Stride constants for proto binary data formats.
|
|
9
10
|
* Each value represents the number of float32 elements per item.
|
|
@@ -50,22 +51,79 @@ export const asFloat32Array = (bytes) => {
|
|
|
50
51
|
return aligned;
|
|
51
52
|
};
|
|
52
53
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
54
|
+
* Sets a Three.js Color from 3 bytes of a uint8 color array starting at `offset`.
|
|
55
|
+
* Mutates and returns `target` — pass a pre-allocated Color to avoid allocations
|
|
56
|
+
* in hot paths.
|
|
55
57
|
*
|
|
56
|
-
* @param
|
|
57
|
-
* @
|
|
58
|
+
* @param bytes - Uint8Array with at least `offset + 3` elements [r, g, b, ...]
|
|
59
|
+
* @param target - Color instance to write into
|
|
60
|
+
* @param offset - Byte offset to start reading from (default 0)
|
|
61
|
+
* @returns The mutated `target`, or black if the array has fewer than `offset + 3` elements
|
|
58
62
|
*
|
|
59
63
|
* @example
|
|
60
64
|
* ```ts
|
|
61
|
-
*
|
|
62
|
-
*
|
|
65
|
+
* asColor(colors.current, material.color)
|
|
66
|
+
* asColor(colors.current, pointColorUtil, stride) // read second color
|
|
63
67
|
* ```
|
|
64
68
|
*/
|
|
65
|
-
export const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
export const asColor = (bytes, target, offset = 0) => {
|
|
70
|
+
if (bytes.length < offset + 3)
|
|
71
|
+
return target.setRGB(0, 0, 0);
|
|
72
|
+
return target.setRGB(bytes[offset] / 255, bytes[offset + 1] / 255, bytes[offset + 2] / 255);
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Creates a Uint8Array from a Three.js Color.
|
|
76
|
+
*
|
|
77
|
+
* @param color - The Three.js Color to convert
|
|
78
|
+
* @returns A Uint8Array with the RGBA values
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const color = fromColor(new Color(0, 1, 0))
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export const fromColor = (color) => {
|
|
86
|
+
return new Uint8Array([
|
|
87
|
+
Math.round(color.r * 255),
|
|
88
|
+
Math.round(color.g * 255),
|
|
89
|
+
Math.round(color.b * 255),
|
|
90
|
+
]);
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Reads a byte from a uint8 color array at `offset` and normalizes it to 0-1.
|
|
94
|
+
* Returns `fallback` when the array has fewer than `offset + 1` elements.
|
|
95
|
+
*
|
|
96
|
+
* @param bytes - ArrayLike of uint8 color values
|
|
97
|
+
* @param fallback - Value to return when no alpha byte is present (default 1)
|
|
98
|
+
* @param offset - Byte index to read from (default 3, the alpha channel of the first color)
|
|
99
|
+
* @returns Normalized opacity in 0-1 range, or the fallback value
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* material.opacity = asOpacity(colors.current)
|
|
104
|
+
* material.opacity = asOpacity(colors.current, 1, stride + 3) // alpha of second color
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export const asOpacity = (bytes, fallback = 1, offset = 3) => {
|
|
108
|
+
if (bytes.length < offset + 1)
|
|
109
|
+
return fallback;
|
|
110
|
+
return bytes[offset] / 255;
|
|
71
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* Returns true when `colors` contains exactly one color entry per point (RGB or RGBA).
|
|
114
|
+
* Use this to distinguish per-vertex color buffers from a single uniform color.
|
|
115
|
+
*
|
|
116
|
+
* @param colors - Uint8Array of packed color bytes
|
|
117
|
+
* @param numVertex - Number of points/vertices the color buffer should cover
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* if (isPerVertexColors(colors, positions.length / STRIDE.POSITIONS)) {
|
|
122
|
+
* // treat as per-vertex
|
|
123
|
+
* } else {
|
|
124
|
+
* addColorTraits(entityTraits, colors)
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export const isPerVertexColors = (colors, numVertex) => colors.length === numVertex * STRIDE.COLORS_RGB ||
|
|
129
|
+
colors.length === numVertex * STRIDE.COLORS_RGBA;
|
package/dist/color.js
CHANGED
|
@@ -17,9 +17,9 @@ const oklchToHex = (raw) => {
|
|
|
17
17
|
if (!match) {
|
|
18
18
|
return raw;
|
|
19
19
|
}
|
|
20
|
-
const l = parseFloat(match[1]) / 100;
|
|
21
|
-
const c = parseFloat(match[2]);
|
|
22
|
-
const h = parseFloat(match[3]);
|
|
20
|
+
const l = Number.parseFloat(match[1]) / 100;
|
|
21
|
+
const c = Number.parseFloat(match[2]);
|
|
22
|
+
const h = Number.parseFloat(match[3]);
|
|
23
23
|
// Convert h from degrees to radians
|
|
24
24
|
const hRad = (h * Math.PI) / 180;
|
|
25
25
|
// Step 1: OKLCH → OKLab
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { T
|
|
2
|
+
import { T } from '@threlte/core'
|
|
3
3
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
4
|
-
import type { Camera } from 'three'
|
|
5
4
|
|
|
6
5
|
let { children, ...rest } = $props()
|
|
7
6
|
|
|
8
|
-
const { camera } = useThrelte()
|
|
9
7
|
const settings = useSettings()
|
|
10
8
|
const mode = $derived(settings.current.cameraMode)
|
|
11
|
-
|
|
12
|
-
$effect(() => {
|
|
13
|
-
;(window as unknown as { camera: Camera }).camera = $camera
|
|
14
|
-
})
|
|
15
9
|
</script>
|
|
16
10
|
|
|
17
11
|
{#if mode === 'perspective'}
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
enabled={!transformControls.active}
|
|
31
31
|
oncreate={(ref) => {
|
|
32
32
|
cameraControls.set(ref)
|
|
33
|
-
;(
|
|
34
|
-
;(
|
|
33
|
+
;(globalThis as unknown as { MathUtils: typeof MathUtils }).MathUtils = MathUtils
|
|
34
|
+
;(globalThis as unknown as { cameraControls: CameraControlsRef }).cameraControls = ref
|
|
35
35
|
}}
|
|
36
36
|
>
|
|
37
37
|
{#snippet children({ ref }: { ref: CameraControlsRef })}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { InstancedArrows } from '
|
|
3
|
-
import { traits, useWorld } from '
|
|
2
|
+
import { InstancedArrows } from '../../../three/InstancedArrows/InstancedArrows'
|
|
3
|
+
import { traits, useWorld } from '../../../ecs'
|
|
4
4
|
import type { Entity } from 'koota'
|
|
5
|
-
import { STRIDE } from '
|
|
5
|
+
import { STRIDE } from '../../../buffer'
|
|
6
6
|
import { SvelteMap } from 'svelte/reactivity'
|
|
7
7
|
import { Color } from 'three'
|
|
8
8
|
import Arrows from './Arrows.svelte'
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { T } from '@threlte/core'
|
|
3
3
|
import { Portal } from '@threlte/extras'
|
|
4
4
|
import type { Entity } from 'koota'
|
|
5
|
-
import { traits } from '
|
|
6
|
-
import {
|
|
7
|
-
import type { InstancedArrows } from '
|
|
8
|
-
import { useFocusedEntity, useSelectedEntity } from '
|
|
9
|
-
import { meshBoundsRaycast, raycast } from '
|
|
5
|
+
import { traits } from '../../../ecs'
|
|
6
|
+
import { useEntityEvents } from '../hooks/useEntityEvents.svelte'
|
|
7
|
+
import type { InstancedArrows } from '../../../three/InstancedArrows/InstancedArrows'
|
|
8
|
+
import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte'
|
|
9
|
+
import { meshBoundsRaycast, raycast } from '../../../three/InstancedArrows/raycast'
|
|
10
10
|
|
|
11
11
|
interface Props {
|
|
12
12
|
entity: Entity
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
let { entity, arrows }: Props = $props()
|
|
17
17
|
|
|
18
|
-
const events =
|
|
18
|
+
const events = useEntityEvents(() => entity)
|
|
19
19
|
const selectedEntity = useSelectedEntity()
|
|
20
20
|
const focusedEntity = useFocusedEntity()
|
|
21
21
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Entity } from 'koota';
|
|
2
|
-
import type { InstancedArrows } from '
|
|
2
|
+
import type { InstancedArrows } from '../../../three/InstancedArrows/InstancedArrows';
|
|
3
3
|
interface Props {
|
|
4
4
|
entity: Entity;
|
|
5
5
|
arrows: InstancedArrows;
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
import Label from './Label.svelte'
|
|
6
6
|
import Line from './Line.svelte'
|
|
7
7
|
import Points from './Points.svelte'
|
|
8
|
-
import
|
|
8
|
+
import Arrows from './Arrows/ArrowGroups.svelte'
|
|
9
|
+
import { traits, useQuery } from '../../ecs'
|
|
9
10
|
import { Not, Or } from 'koota'
|
|
11
|
+
import Geometry from './Geometry.svelte'
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Frames from a live machine are bucketed into their own query
|
|
@@ -60,9 +62,9 @@
|
|
|
60
62
|
{/each}
|
|
61
63
|
|
|
62
64
|
{#each resourceGeometriesEntities.current as entity (entity)}
|
|
63
|
-
<
|
|
65
|
+
<Geometry {entity}>
|
|
64
66
|
<Label text={entity.get(traits.Name)} />
|
|
65
|
-
</
|
|
67
|
+
</Geometry>
|
|
66
68
|
{/each}
|
|
67
69
|
|
|
68
70
|
{#each worldStateEntities.current as entity (entity)}
|
|
@@ -94,3 +96,5 @@
|
|
|
94
96
|
<Label text={entity.get(traits.Name)} />
|
|
95
97
|
</GLTF>
|
|
96
98
|
{/each}
|
|
99
|
+
|
|
100
|
+
<Arrows />
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
|
|
4
|
+
Renders a Viam Frame object
|
|
5
|
+
-->
|
|
6
|
+
<script module>
|
|
7
|
+
import { Color } from 'three'
|
|
8
|
+
|
|
9
|
+
const colorUtil = new Color()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import type { Snippet } from 'svelte'
|
|
14
|
+
import { Group, type Object3D } from 'three'
|
|
15
|
+
import { T, useThrelte } from '@threlte/core'
|
|
16
|
+
import { Portal, PortalTarget } from '@threlte/extras'
|
|
17
|
+
import { useEntityEvents } from './hooks/useEntityEvents.svelte'
|
|
18
|
+
import Mesh from './Mesh.svelte'
|
|
19
|
+
import { colors, resourceColors } from '../../color'
|
|
20
|
+
import type { Entity } from 'koota'
|
|
21
|
+
import { traits, useTrait } from '../../ecs'
|
|
22
|
+
import type { Pose } from '@viamrobotics/sdk'
|
|
23
|
+
import { useResourceByName } from '../../hooks/useResourceByName.svelte'
|
|
24
|
+
import { poseToObject3d } from '../../transform'
|
|
25
|
+
|
|
26
|
+
interface Props {
|
|
27
|
+
entity: Entity
|
|
28
|
+
pose?: Pose
|
|
29
|
+
children?: Snippet<[{ ref: Object3D }]>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let { entity, pose, children }: Props = $props()
|
|
33
|
+
|
|
34
|
+
const { invalidate } = useThrelte()
|
|
35
|
+
const resourceByName = useResourceByName()
|
|
36
|
+
|
|
37
|
+
const name = useTrait(() => entity, traits.Name)
|
|
38
|
+
const parent = useTrait(() => entity, traits.Parent)
|
|
39
|
+
const entityColor = useTrait(() => entity, traits.Color)
|
|
40
|
+
const entityPose = useTrait(() => entity, traits.Pose)
|
|
41
|
+
const center = useTrait(() => entity, traits.Center)
|
|
42
|
+
|
|
43
|
+
const events = useEntityEvents(() => entity)
|
|
44
|
+
|
|
45
|
+
const color = $derived.by(() => {
|
|
46
|
+
if (entityColor.current) {
|
|
47
|
+
return `#${colorUtil.set(entityColor.current.r, entityColor.current.g, entityColor.current.b).getHexString()}`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const subtype = resourceByName.current[name.current ?? '']?.subtype
|
|
51
|
+
const resourceColor = resourceColors[subtype as keyof typeof resourceColors]
|
|
52
|
+
|
|
53
|
+
if (resourceColor) {
|
|
54
|
+
return resourceColor
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return colors.default
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const group = new Group()
|
|
61
|
+
|
|
62
|
+
const resolvedPose = $derived(pose ?? entityPose.current)
|
|
63
|
+
$effect.pre(() => {
|
|
64
|
+
if (resolvedPose) {
|
|
65
|
+
poseToObject3d(resolvedPose, group)
|
|
66
|
+
invalidate()
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<Portal id={parent.current}>
|
|
72
|
+
<T is={group}>
|
|
73
|
+
<Mesh
|
|
74
|
+
{entity}
|
|
75
|
+
{color}
|
|
76
|
+
{...events}
|
|
77
|
+
center={center.current}
|
|
78
|
+
/>
|
|
79
|
+
|
|
80
|
+
{#if name.current}
|
|
81
|
+
<PortalTarget id={name.current} />
|
|
82
|
+
{/if}
|
|
83
|
+
|
|
84
|
+
{@render children?.({ ref: group })}
|
|
85
|
+
</T>
|
|
86
|
+
</Portal>
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
import { Portal, PortalTarget, useGltfAnimations, type ThrelteGltf } from '@threlte/extras'
|
|
17
17
|
import type { Snippet } from 'svelte'
|
|
18
18
|
import { Group, type Object3D } from 'three'
|
|
19
|
-
import {
|
|
19
|
+
import { useEntityEvents } from './hooks/useEntityEvents.svelte'
|
|
20
20
|
import type { Entity } from 'koota'
|
|
21
|
-
import { traits, useTrait } from '
|
|
22
|
-
import { poseToObject3d } from '
|
|
21
|
+
import { traits, useTrait } from '../../ecs'
|
|
22
|
+
import { poseToObject3d } from '../../transform'
|
|
23
23
|
|
|
24
24
|
interface Props extends ThrelteProps<Object3D> {
|
|
25
25
|
entity: Entity
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
const pose = useTrait(() => entity, traits.Pose)
|
|
36
36
|
const gltfTrait = useTrait(() => entity, traits.GLTF)
|
|
37
37
|
const scale = useTrait(() => entity, traits.Scale)
|
|
38
|
-
const
|
|
38
|
+
const events = useEntityEvents(() => entity)
|
|
39
39
|
|
|
40
40
|
const animationName = $derived(gltfTrait.current?.animationName)
|
|
41
41
|
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
is={$gltf.scene as Object3D}
|
|
86
86
|
scale={[scale.current?.x ?? 1, scale.current?.y ?? 1, scale.current?.z ?? 1]}
|
|
87
87
|
name={entity}
|
|
88
|
-
{...
|
|
88
|
+
{...events}
|
|
89
89
|
{...rest}
|
|
90
90
|
>
|
|
91
91
|
{@render children?.()}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
|
|
4
|
+
Renders a Viam Geometry object
|
|
5
|
+
-->
|
|
6
|
+
<script lang="ts">
|
|
7
|
+
import { T, useThrelte } from '@threlte/core'
|
|
8
|
+
import { traits, useTrait } from '../../ecs'
|
|
9
|
+
import { use3DModels } from '../../hooks/use3DModels.svelte'
|
|
10
|
+
import { Portal } from '@threlte/extras'
|
|
11
|
+
import { poseToObject3d } from '../../transform'
|
|
12
|
+
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
13
|
+
import Mesh from './Mesh.svelte'
|
|
14
|
+
import { useEntityEvents } from './hooks/useEntityEvents.svelte'
|
|
15
|
+
import type { Entity } from 'koota'
|
|
16
|
+
import type { Snippet } from 'svelte'
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
entity: Entity
|
|
20
|
+
children?: Snippet
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { entity, children }: Props = $props()
|
|
24
|
+
|
|
25
|
+
const settings = useSettings()
|
|
26
|
+
|
|
27
|
+
const { invalidate } = useThrelte()
|
|
28
|
+
const models = use3DModels()
|
|
29
|
+
|
|
30
|
+
const name = useTrait(() => entity, traits.Name)
|
|
31
|
+
const parent = useTrait(() => entity, traits.Parent)
|
|
32
|
+
const center = useTrait(() => entity, traits.Center)
|
|
33
|
+
|
|
34
|
+
const model = $derived.by(() => {
|
|
35
|
+
if (!settings.current.renderArmModels.includes('model')) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!name.current) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const [componentName, id] = name.current.split(':')
|
|
44
|
+
if (!componentName || !id) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return models.current[componentName]?.[id].clone()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
$effect.pre(() => {
|
|
52
|
+
if (model && center.current) {
|
|
53
|
+
poseToObject3d(center.current, model)
|
|
54
|
+
invalidate()
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const events = useEntityEvents(() => entity)
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<Portal id={parent.current}>
|
|
62
|
+
{#if model}
|
|
63
|
+
<T is={model} />
|
|
64
|
+
{/if}
|
|
65
|
+
|
|
66
|
+
{#if settings.current.renderArmModels.includes('colliders') || !model}
|
|
67
|
+
<Mesh
|
|
68
|
+
{entity}
|
|
69
|
+
center={center.current}
|
|
70
|
+
{...events}
|
|
71
|
+
>
|
|
72
|
+
{@render children?.()}
|
|
73
|
+
</Mesh>
|
|
74
|
+
{/if}
|
|
75
|
+
</Portal>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Entity } from 'koota';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface Props {
|
|
4
|
+
entity: Entity;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
/** Renders a Viam Geometry object */
|
|
8
|
+
declare const Geometry: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Geometry = ReturnType<typeof Geometry>;
|
|
10
|
+
export default Geometry;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { Color } from 'three'
|
|
3
|
+
|
|
4
|
+
const colorUtil = new Color()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import type { Snippet } from 'svelte'
|
|
9
|
+
import { T, useThrelte } from '@threlte/core'
|
|
10
|
+
import { meshBounds, Portal, PortalTarget } from '@threlte/extras'
|
|
11
|
+
import type { Entity } from 'koota'
|
|
12
|
+
import { traits, useTrait } from '../../ecs'
|
|
13
|
+
import LineDots from './LineDots.svelte'
|
|
14
|
+
import { darkenColor } from '../../color'
|
|
15
|
+
import { useEntityEvents } from './hooks/useEntityEvents.svelte'
|
|
16
|
+
import { Line2, LineMaterial } from 'three/examples/jsm/Addons.js'
|
|
17
|
+
import LineGeometry from './LineGeometry.svelte'
|
|
18
|
+
import { poseToObject3d } from '../../transform'
|
|
19
|
+
|
|
20
|
+
interface Props {
|
|
21
|
+
entity: Entity
|
|
22
|
+
children?: Snippet
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let { entity, children }: Props = $props()
|
|
26
|
+
|
|
27
|
+
const { invalidate } = useThrelte()
|
|
28
|
+
const name = useTrait(() => entity, traits.Name)
|
|
29
|
+
const parent = useTrait(() => entity, traits.Parent)
|
|
30
|
+
const pose = useTrait(() => entity, traits.Pose)
|
|
31
|
+
const color = useTrait(() => entity, traits.Color)
|
|
32
|
+
const pointSize = useTrait(() => entity, traits.PointSize)
|
|
33
|
+
const linePositions = useTrait(() => entity, traits.LinePositions)
|
|
34
|
+
const lineWidth = useTrait(() => entity, traits.LineWidth)
|
|
35
|
+
const opacity = useTrait(() => entity, traits.Opacity)
|
|
36
|
+
const materialProps = useTrait(() => entity, traits.Material)
|
|
37
|
+
const renderOrder = useTrait(() => entity, traits.RenderOrder)
|
|
38
|
+
|
|
39
|
+
const events = useEntityEvents(() => entity)
|
|
40
|
+
|
|
41
|
+
const currentOpacity = $derived(opacity.current ?? 0.7)
|
|
42
|
+
|
|
43
|
+
const mesh = new Line2()
|
|
44
|
+
|
|
45
|
+
$effect.pre(() => {
|
|
46
|
+
if (pose.current) {
|
|
47
|
+
poseToObject3d(pose.current, mesh)
|
|
48
|
+
invalidate()
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<Portal id={parent.current}>
|
|
54
|
+
<T
|
|
55
|
+
is={mesh}
|
|
56
|
+
name={entity}
|
|
57
|
+
userData.name={name}
|
|
58
|
+
raycast={meshBounds}
|
|
59
|
+
renderOrder={renderOrder.current}
|
|
60
|
+
{...events}
|
|
61
|
+
>
|
|
62
|
+
<LineGeometry positions={linePositions.current} />
|
|
63
|
+
<T
|
|
64
|
+
is={LineMaterial}
|
|
65
|
+
color={[color.current?.r ?? 1, color.current?.g ?? 0, color.current?.b ?? 0]}
|
|
66
|
+
transparent={currentOpacity < 1}
|
|
67
|
+
depthWrite={currentOpacity === 1}
|
|
68
|
+
opacity={currentOpacity}
|
|
69
|
+
width={lineWidth.current ? lineWidth.current * 0.001 : 0.5}
|
|
70
|
+
depthTest={materialProps.current?.depthTest ?? true}
|
|
71
|
+
/>
|
|
72
|
+
</T>
|
|
73
|
+
|
|
74
|
+
{#if linePositions.current && pointSize.current}
|
|
75
|
+
<LineDots
|
|
76
|
+
color={darkenColor(
|
|
77
|
+
colorUtil.setRGB(color.current?.r ?? 1, color.current?.g ?? 0, color.current?.b ?? 0),
|
|
78
|
+
10
|
|
79
|
+
)}
|
|
80
|
+
positions={linePositions.current}
|
|
81
|
+
scale={pointSize.current * 0.001}
|
|
82
|
+
/>
|
|
83
|
+
{/if}
|
|
84
|
+
|
|
85
|
+
{#if name.current}
|
|
86
|
+
<PortalTarget id={name.current} />
|
|
87
|
+
{/if}
|
|
88
|
+
|
|
89
|
+
{@render children?.()}
|
|
90
|
+
</Portal>
|