@viamrobotics/motion-tools 1.12.3 → 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 +5 -6
- 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} +48 -53
- 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/SceneProviders.svelte +2 -0
- package/dist/components/Selected.svelte +9 -9
- package/dist/components/StaticGeometries.svelte +6 -3
- package/dist/components/overlay/AddRelationship.svelte +1 -1
- package/dist/components/overlay/Details.svelte +3 -3
- package/dist/components/overlay/FloatingPanel.svelte +3 -0
- package/dist/components/overlay/FloatingPanel.svelte.d.ts +1 -0
- package/dist/components/overlay/LiveUpdatesBanner.svelte +4 -6
- package/dist/components/overlay/Logs.svelte +75 -0
- package/dist/components/overlay/left-pane/TreeContainer.svelte +0 -3
- 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 -36
- package/dist/hooks/useConfigFrames.svelte.d.ts +9 -0
- package/dist/hooks/useConfigFrames.svelte.js +87 -0
- package/dist/hooks/useDrawAPI.svelte.js +1 -1
- package/dist/hooks/useFramelessComponents.svelte.js +1 -1
- package/dist/hooks/useFrames.svelte.d.ts +1 -6
- package/dist/hooks/useFrames.svelte.js +93 -192
- package/dist/hooks/useGeometries.svelte.js +1 -1
- package/dist/hooks/useLinked.svelte.js +5 -4
- package/dist/hooks/usePartConfig.svelte.js +17 -18
- 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/useVisibility.svelte.js +0 -12
- 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/overlay/left-pane/Logs.svelte +0 -52
- /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
- /package/dist/components/overlay/{left-pane/Logs.svelte.d.ts → Logs.svelte.d.ts} +0 -0
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { Points, PointsMaterial, OrthographicCamera } from 'three'
|
|
3
3
|
import { T, useTask, useThrelte } from '@threlte/core'
|
|
4
4
|
import { Portal } from '@threlte/extras'
|
|
5
|
-
import {
|
|
6
|
-
import { poseToObject3d } from '
|
|
7
|
-
import { useSettings } from '
|
|
5
|
+
import { useEntityEvents } from './hooks/useEntityEvents.svelte'
|
|
6
|
+
import { poseToObject3d } from '../../transform'
|
|
7
|
+
import { useSettings } from '../../hooks/useSettings.svelte'
|
|
8
8
|
import type { Snippet } from 'svelte'
|
|
9
9
|
import type { Entity } from 'koota'
|
|
10
|
-
import { traits, useTrait } from '
|
|
10
|
+
import { traits, useTrait } from '../../ecs'
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
13
|
entity: Entity
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
}
|
|
94
94
|
})
|
|
95
95
|
|
|
96
|
-
const events =
|
|
96
|
+
const events = useEntityEvents(() => entity)
|
|
97
97
|
|
|
98
98
|
const { start, stop } = useTask(
|
|
99
99
|
() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { traits, useTrait } from '
|
|
3
|
-
import { usePose } from '
|
|
4
|
-
import { matrixToPose, poseToMatrix } from '
|
|
2
|
+
import { traits, useTrait } from '../../ecs'
|
|
3
|
+
import { usePose } from '../../hooks/usePose.svelte'
|
|
4
|
+
import { matrixToPose, poseToMatrix } from '../../transform'
|
|
5
5
|
import type { Pose } from '@viamrobotics/sdk'
|
|
6
6
|
import type { Entity } from 'koota'
|
|
7
7
|
import type { Snippet } from 'svelte'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type IntersectionEvent } from '@threlte/extras';
|
|
2
2
|
import type { Entity } from 'koota';
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const useEntityEvents: (entity: () => Entity | undefined) => {
|
|
4
4
|
readonly visible: boolean;
|
|
5
5
|
onpointerenter: (event: IntersectionEvent<MouseEvent>) => void;
|
|
6
6
|
onpointermove: (event: IntersectionEvent<MouseEvent>) => void;
|
package/dist/{hooks/useObjectEvents.svelte.js → components/Entities/hooks/useEntityEvents.svelte.js}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useCursor } from '@threlte/extras';
|
|
2
|
-
import { useFocusedEntity, useSelectedEntity } from '
|
|
3
|
-
import { useVisibility } from '
|
|
2
|
+
import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte';
|
|
3
|
+
import { useVisibility } from '../../../hooks/useVisibility.svelte';
|
|
4
4
|
import { Vector2 } from 'three';
|
|
5
|
-
import { traits } from '
|
|
6
|
-
import { updateHoverInfo } from '
|
|
7
|
-
import { createPose, matrixToPose, poseToMatrix } from '
|
|
8
|
-
export const
|
|
5
|
+
import { traits } from '../../../ecs';
|
|
6
|
+
import { updateHoverInfo } from '../../../HoverUpdater.svelte';
|
|
7
|
+
import { createPose, matrixToPose, poseToMatrix } from '../../../transform';
|
|
8
|
+
export const useEntityEvents = (entity) => {
|
|
9
9
|
const down = new Vector2();
|
|
10
10
|
const selectedEntity = useSelectedEntity();
|
|
11
11
|
const focusedEntity = useFocusedEntity();
|
|
@@ -26,13 +26,14 @@ const hasPrefix = (name) => {
|
|
|
26
26
|
};
|
|
27
27
|
const validatePrefix = (extension, prefix) => {
|
|
28
28
|
switch (prefix) {
|
|
29
|
-
case Prefixes.Snapshot:
|
|
29
|
+
case Prefixes.Snapshot: {
|
|
30
30
|
if (extension !== Extensions.JSON &&
|
|
31
31
|
extension !== Extensions.PB &&
|
|
32
32
|
extension !== Extensions.PB_GZ) {
|
|
33
33
|
return new FileNameError(`Only ${Extensions.JSON}, ${Extensions.PB} and ${Extensions.PB_GZ} snapshot files are supported.`);
|
|
34
34
|
}
|
|
35
35
|
break;
|
|
36
|
+
}
|
|
36
37
|
}
|
|
37
38
|
return undefined;
|
|
38
39
|
};
|
|
@@ -76,12 +77,14 @@ export const readFile = (file, reader, extension) => {
|
|
|
76
77
|
if (!extension)
|
|
77
78
|
return;
|
|
78
79
|
switch (extension) {
|
|
79
|
-
case Extensions.JSON:
|
|
80
|
+
case Extensions.JSON: {
|
|
80
81
|
return reader.readAsText(file);
|
|
82
|
+
}
|
|
81
83
|
case Extensions.PCD:
|
|
82
84
|
case Extensions.PLY:
|
|
83
85
|
case Extensions.PB:
|
|
84
|
-
case Extensions.PB_GZ:
|
|
86
|
+
case Extensions.PB_GZ: {
|
|
85
87
|
return reader.readAsArrayBuffer(file);
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
90
|
};
|
|
@@ -81,16 +81,20 @@ const decodeGzip = async (params) => {
|
|
|
81
81
|
};
|
|
82
82
|
export const snapshotDropper = async (params) => {
|
|
83
83
|
switch (params.extension) {
|
|
84
|
-
case 'json':
|
|
84
|
+
case 'json': {
|
|
85
85
|
return decodeJson(params);
|
|
86
|
-
|
|
86
|
+
}
|
|
87
|
+
case 'pb': {
|
|
87
88
|
return decodeBinary(params);
|
|
88
|
-
|
|
89
|
+
}
|
|
90
|
+
case 'pb.gz': {
|
|
89
91
|
return decodeGzip(params);
|
|
90
|
-
|
|
92
|
+
}
|
|
93
|
+
default: {
|
|
91
94
|
return {
|
|
92
95
|
success: false,
|
|
93
96
|
error: new FileDropperError(`Only ${Extensions.JSON}, ${Extensions.PB} and ${Extensions.PB_GZ} snapshot files are supported.`),
|
|
94
97
|
};
|
|
98
|
+
}
|
|
95
99
|
}
|
|
96
100
|
};
|
|
@@ -4,14 +4,17 @@ import { plyDropper } from './ply-dropper';
|
|
|
4
4
|
import { snapshotDropper } from './snapshot-dropper';
|
|
5
5
|
const createFileDropper = (extension, prefix) => {
|
|
6
6
|
switch (prefix) {
|
|
7
|
-
case Prefixes.Snapshot:
|
|
7
|
+
case Prefixes.Snapshot: {
|
|
8
8
|
return snapshotDropper;
|
|
9
|
+
}
|
|
9
10
|
}
|
|
10
11
|
switch (extension) {
|
|
11
|
-
case Extensions.PCD:
|
|
12
|
+
case Extensions.PCD: {
|
|
12
13
|
return pcdDropper;
|
|
13
|
-
|
|
14
|
+
}
|
|
15
|
+
case Extensions.PLY: {
|
|
14
16
|
return plyDropper;
|
|
17
|
+
}
|
|
15
18
|
}
|
|
16
19
|
return undefined;
|
|
17
20
|
};
|
|
@@ -74,11 +77,11 @@ export const useFileDrop = (onSuccess, onError) => {
|
|
|
74
77
|
prefix,
|
|
75
78
|
content,
|
|
76
79
|
});
|
|
77
|
-
if (
|
|
78
|
-
|
|
80
|
+
if (result.success) {
|
|
81
|
+
onSuccess(result);
|
|
79
82
|
}
|
|
80
83
|
else {
|
|
81
|
-
|
|
84
|
+
handleError(result.error.message);
|
|
82
85
|
}
|
|
83
86
|
});
|
|
84
87
|
readFile(file, reader, extension);
|
|
@@ -245,16 +245,16 @@
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
$effect(() => {
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
globalThis.addEventListener('keydown', onkeydown)
|
|
249
|
+
globalThis.addEventListener('keyup', onkeyup)
|
|
250
250
|
dom.addEventListener('pointerdown', onpointerdown)
|
|
251
251
|
dom.addEventListener('pointermove', onpointermove)
|
|
252
252
|
dom.addEventListener('pointerup', onpointerup)
|
|
253
253
|
dom.addEventListener('pointerleave', onpointerleave)
|
|
254
254
|
|
|
255
255
|
return () => {
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
globalThis.removeEventListener('keydown', onkeydown)
|
|
257
|
+
globalThis.removeEventListener('keyup', onkeyup)
|
|
258
258
|
dom.removeEventListener('pointerdown', onpointerdown)
|
|
259
259
|
dom.removeEventListener('pointermove', onpointermove)
|
|
260
260
|
dom.removeEventListener('pointerup', onpointerup)
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
import { parsePcdInWorker } from '../lib'
|
|
3
3
|
import { traits, useWorld } from '../ecs'
|
|
4
4
|
import { createBufferGeometry } from '../attribute'
|
|
5
|
-
import type { Entity } from 'koota'
|
|
5
|
+
import type { ConfigurableTrait, Entity } from 'koota'
|
|
6
6
|
|
|
7
7
|
interface Props {
|
|
8
8
|
data: Uint8Array
|
|
9
|
+
name?: string
|
|
10
|
+
renderOrder?: number
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
let { data }: Props = $props()
|
|
13
|
+
let { data, name, renderOrder }: Props = $props()
|
|
12
14
|
|
|
13
15
|
const world = useWorld()
|
|
14
16
|
|
|
@@ -18,11 +20,17 @@
|
|
|
18
20
|
parsePcdInWorker(data).then(({ positions, colors }) => {
|
|
19
21
|
const geometry = createBufferGeometry(positions, colors)
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
traits.Name('Random points'),
|
|
23
|
+
const entityTraits: ConfigurableTrait[] = [
|
|
24
|
+
traits.Name(name ?? 'Random points'),
|
|
23
25
|
traits.Points,
|
|
24
|
-
traits.BufferGeometry(geometry)
|
|
25
|
-
|
|
26
|
+
traits.BufferGeometry(geometry),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
if (renderOrder) {
|
|
30
|
+
entityTraits.push(traits.RenderOrder(renderOrder))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
entity = world.spawn(...entityTraits)
|
|
26
34
|
})
|
|
27
35
|
|
|
28
36
|
return () => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { ShaderMaterial, Vector3 } from 'three'
|
|
3
3
|
import { T } from '@threlte/core'
|
|
4
4
|
import { Environment, Grid, interactivity, PerfMonitor, PortalTarget } from '@threlte/extras'
|
|
5
|
-
import Entities from './Entities.svelte'
|
|
5
|
+
import Entities from './Entities/Entities.svelte'
|
|
6
6
|
import Selected from './Selected.svelte'
|
|
7
7
|
import Focus from './Focus.svelte'
|
|
8
8
|
import StaticGeometries from './StaticGeometries.svelte'
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
import MeasureTool from './MeasureTool/MeasureTool.svelte'
|
|
18
18
|
import PointerMissBox from './PointerMissBox.svelte'
|
|
19
19
|
import BatchedArrows from './BatchedArrows.svelte'
|
|
20
|
-
import Arrows from './Arrows/ArrowGroups.svelte'
|
|
21
20
|
import hdrImage from '../assets/ferndale_studio_11_1k.hdr'
|
|
22
21
|
|
|
23
22
|
interface Props {
|
|
@@ -103,7 +102,6 @@
|
|
|
103
102
|
|
|
104
103
|
<Entities />
|
|
105
104
|
<BatchedArrows />
|
|
106
|
-
<Arrows />
|
|
107
105
|
</T.Group>
|
|
108
106
|
|
|
109
107
|
{@render children?.()}
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import { provide3DModels } from '../hooks/use3DModels.svelte'
|
|
24
24
|
import { providePointcloudObjects } from '../hooks/usePointcloudObjects.svelte'
|
|
25
25
|
import { provideLinkedEntities } from '../hooks/useLinked.svelte'
|
|
26
|
+
import { provideConfigFrames } from '../hooks/useConfigFrames.svelte'
|
|
26
27
|
|
|
27
28
|
interface Props {
|
|
28
29
|
cameraPose?: CameraPose
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
provideDrawAPI()
|
|
44
45
|
|
|
45
46
|
provideResourceByName(() => partID.current)
|
|
47
|
+
provideConfigFrames()
|
|
46
48
|
provideFrames(() => partID.current)
|
|
47
49
|
provideGeometries(() => partID.current)
|
|
48
50
|
provide3DModels(() => partID.current)
|
|
@@ -15,19 +15,17 @@
|
|
|
15
15
|
const selectedObject3d = useSelectedObject3d()
|
|
16
16
|
|
|
17
17
|
const object = $derived.by(() => {
|
|
18
|
-
if (!
|
|
19
|
-
return
|
|
18
|
+
if (!selectedObject3d.current) {
|
|
19
|
+
return
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Create a clone in the case of meshes, which could be frames with geometries,
|
|
23
23
|
// so that our bounding box doesn't include children
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (result) {
|
|
27
|
-
selectedObject3d.current?.getWorldPosition(result.position)
|
|
28
|
-
selectedObject3d.current?.getWorldQuaternion(result.quaternion)
|
|
29
|
-
return result
|
|
24
|
+
if (isInstanceOf(selectedObject3d.current, 'Mesh')) {
|
|
25
|
+
return selectedObject3d.current?.clone(false)
|
|
30
26
|
}
|
|
27
|
+
|
|
28
|
+
return selectedObject3d.current
|
|
31
29
|
})
|
|
32
30
|
|
|
33
31
|
const { start, stop } = useTask(
|
|
@@ -44,7 +42,9 @@
|
|
|
44
42
|
mesh.getBoundingBoxAt(selectedEntity.instance, box3)
|
|
45
43
|
obb.fromBox3(box3)
|
|
46
44
|
obbHelper.setFromOBB(obb)
|
|
47
|
-
} else {
|
|
45
|
+
} else if (isInstanceOf(selectedObject3d.current, 'Mesh')) {
|
|
46
|
+
selectedObject3d.current?.getWorldPosition(object.position)
|
|
47
|
+
selectedObject3d.current?.getWorldQuaternion(object.quaternion)
|
|
48
48
|
obbHelper.setFromObject(object)
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { PressedKeys } from 'runed'
|
|
13
13
|
import { quaternionToPose, vector3ToPose } from '../transform'
|
|
14
14
|
import { Quaternion, Vector3 } from 'three'
|
|
15
|
-
import Frame from './Frame.svelte'
|
|
15
|
+
import Frame from './Entities/Frame.svelte'
|
|
16
16
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
17
17
|
import { useWorld, traits } from '../ecs'
|
|
18
18
|
import type { Entity } from 'koota'
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
const entity = world.spawn(
|
|
40
40
|
traits.Name(`custom geometry ${++index}`),
|
|
41
41
|
traits.Pose,
|
|
42
|
-
traits.Box({ x:
|
|
42
|
+
traits.Box({ x: 100, y: 100, z: 100 }),
|
|
43
43
|
traits.Removable
|
|
44
44
|
)
|
|
45
45
|
|
|
@@ -87,7 +87,10 @@
|
|
|
87
87
|
ref.quaternion.copy(quaternion)
|
|
88
88
|
entity.set(traits.Pose, pose)
|
|
89
89
|
} else if (box && mode === 'scale') {
|
|
90
|
-
|
|
90
|
+
box.x *= ref.scale.x
|
|
91
|
+
box.y *= ref.scale.y
|
|
92
|
+
box.z *= ref.scale.z
|
|
93
|
+
entity.set(traits.Box, box)
|
|
91
94
|
ref.scale.setScalar(1)
|
|
92
95
|
}
|
|
93
96
|
}}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
useFocusedObject3d,
|
|
22
22
|
useSelectedObject3d,
|
|
23
23
|
} from '../../hooks/useSelection.svelte'
|
|
24
|
-
import {
|
|
24
|
+
import { useConfigFrames } from '../../hooks/useConfigFrames.svelte'
|
|
25
25
|
import { usePartConfig } from '../../hooks/usePartConfig.svelte'
|
|
26
26
|
import { FrameConfigUpdater } from '../../FrameConfigUpdater.svelte'
|
|
27
27
|
import { useEnvironment } from '../../hooks/useEnvironment.svelte'
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
const world = useWorld()
|
|
38
38
|
const controls = useCameraControls()
|
|
39
39
|
const resourceByName = useResourceByName()
|
|
40
|
-
const
|
|
40
|
+
const configFrames = useConfigFrames()
|
|
41
41
|
const partConfig = usePartConfig()
|
|
42
42
|
const selectedEntity = useSelectedEntity()
|
|
43
43
|
const selectedObject3d = useSelectedObject3d()
|
|
@@ -402,7 +402,7 @@
|
|
|
402
402
|
{@render ParentFrame({
|
|
403
403
|
ariaLabel: 'parent frame name',
|
|
404
404
|
value: parent.current ?? 'world',
|
|
405
|
-
options:
|
|
405
|
+
options: configFrames.getParentFrameOptions(name.current ?? ''),
|
|
406
406
|
onChange: (value) => {
|
|
407
407
|
detailConfigUpdater.setFrameParent(entity, value)
|
|
408
408
|
},
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
defaultSize?: { width: number; height: number }
|
|
11
11
|
defaultPosition?: { x: number; y: number }
|
|
12
12
|
exitable?: boolean
|
|
13
|
+
persistRect?: boolean
|
|
13
14
|
strategy?: 'absolute' | 'fixed'
|
|
14
15
|
isOpen?: boolean
|
|
15
16
|
children: Snippet
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
title = '',
|
|
20
21
|
defaultSize = { width: 700, height: 500 },
|
|
21
22
|
exitable = true,
|
|
23
|
+
persistRect = true,
|
|
22
24
|
isOpen = $bindable(false),
|
|
23
25
|
children,
|
|
24
26
|
...props
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
defaultSize,
|
|
31
33
|
resizable: false,
|
|
32
34
|
allowOverflow: false,
|
|
35
|
+
persistRect,
|
|
33
36
|
open: isOpen,
|
|
34
37
|
...props,
|
|
35
38
|
}))
|
|
@@ -13,12 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
<svelte:window
|
|
15
15
|
onkeydown={(event) => {
|
|
16
|
-
if (event.metaKey) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
partConfig.save()
|
|
21
|
-
}
|
|
16
|
+
if (event.metaKey && event.key.toLowerCase() === 's') {
|
|
17
|
+
event.preventDefault()
|
|
18
|
+
event.stopImmediatePropagation()
|
|
19
|
+
partConfig.save()
|
|
22
20
|
}
|
|
23
21
|
}}
|
|
24
22
|
/>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Portal } from '@threlte/extras'
|
|
3
|
+
import { useLogs } from '../../hooks/useLogs.svelte'
|
|
4
|
+
import FloatingPanel from './FloatingPanel.svelte'
|
|
5
|
+
import DashboardButton from './dashboard/Button.svelte'
|
|
6
|
+
import { PersistedState } from 'runed'
|
|
7
|
+
|
|
8
|
+
const logs = useLogs()
|
|
9
|
+
|
|
10
|
+
const isOpen = new PersistedState('logs-is-open', false)
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Portal id="dashboard">
|
|
14
|
+
<fieldset class="relative">
|
|
15
|
+
<DashboardButton
|
|
16
|
+
active
|
|
17
|
+
icon="article"
|
|
18
|
+
description="Logs"
|
|
19
|
+
onclick={() => {
|
|
20
|
+
isOpen.current = !isOpen.current
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
{#if logs.warnings.length > 0}
|
|
24
|
+
<span
|
|
25
|
+
class="absolute z-4 -mt-1.5 -ml-1.5 h-4 w-4 rounded-full bg-yellow-700 text-center text-[10px] text-white"
|
|
26
|
+
>
|
|
27
|
+
{logs.warnings.length}
|
|
28
|
+
</span>
|
|
29
|
+
{/if}
|
|
30
|
+
|
|
31
|
+
{#if logs.errors.length > 0}
|
|
32
|
+
<span
|
|
33
|
+
class="absolute z-4 -mt-1.5 -ml-1.5 h-4 rounded-full bg-red-700 px-1.25 text-center text-[10px] text-white"
|
|
34
|
+
>
|
|
35
|
+
{logs.errors.length}
|
|
36
|
+
</span>
|
|
37
|
+
{/if}
|
|
38
|
+
</fieldset>
|
|
39
|
+
</Portal>
|
|
40
|
+
|
|
41
|
+
<FloatingPanel
|
|
42
|
+
title="Logs"
|
|
43
|
+
bind:isOpen={isOpen.current}
|
|
44
|
+
defaultSize={{ width: 240, height: 315 }}
|
|
45
|
+
>
|
|
46
|
+
<div class="flex h-70 flex-col gap-2 overflow-auto p-3 text-xs">
|
|
47
|
+
{#each logs.current as log (log.uuid)}
|
|
48
|
+
<div>
|
|
49
|
+
<div class="flex flex-wrap items-center gap-1.5">
|
|
50
|
+
<div
|
|
51
|
+
class={[
|
|
52
|
+
'h-2 w-2 rounded-full',
|
|
53
|
+
{
|
|
54
|
+
'bg-danger-dark': log.level === 'error',
|
|
55
|
+
'bg-amber-300': log.level === 'warn',
|
|
56
|
+
'bg-blue-400': log.level === 'info',
|
|
57
|
+
},
|
|
58
|
+
]}
|
|
59
|
+
></div>
|
|
60
|
+
<div class="text-subtle-2">{log.timestamp}</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div>
|
|
63
|
+
{#if log.count > 1}
|
|
64
|
+
<span class="mr-1 rounded bg-green-700 px-1 py-0.5 text-xs text-white">
|
|
65
|
+
{log.count}
|
|
66
|
+
</span>
|
|
67
|
+
{/if}
|
|
68
|
+
{log.message}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
{:else}
|
|
72
|
+
No logs
|
|
73
|
+
{/each}
|
|
74
|
+
</div>
|
|
75
|
+
</FloatingPanel>
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import Tree from './Tree.svelte'
|
|
4
4
|
import { useSelectedEntity } from '../../../hooks/useSelection.svelte'
|
|
5
5
|
import { provideTreeExpandedContext } from './useExpanded.svelte'
|
|
6
|
-
import Logs from './Logs.svelte'
|
|
7
6
|
import AddFrames from './AddFrames.svelte'
|
|
8
7
|
import { useEnvironment } from '../../../hooks/useEnvironment.svelte'
|
|
9
8
|
import { usePartID } from '../../../hooks/usePartID.svelte'
|
|
@@ -82,6 +81,4 @@
|
|
|
82
81
|
{#if environment.current.isStandalone && partID.current && partConfig.hasEditPermissions}
|
|
83
82
|
<AddFrames />
|
|
84
83
|
{/if}
|
|
85
|
-
|
|
86
|
-
<Logs />
|
|
87
84
|
</div>
|
|
@@ -285,19 +285,17 @@
|
|
|
285
285
|
<Switch
|
|
286
286
|
on={isWidgetOpen}
|
|
287
287
|
on:change={(event) => {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
}
|
|
288
|
+
settings.current.openCameraWidgets = event.detail
|
|
289
|
+
? {
|
|
290
|
+
...settings.current.openCameraWidgets,
|
|
291
|
+
[partID.current]: [...currentRobotCameraWidgets, camera.name],
|
|
292
|
+
}
|
|
293
|
+
: {
|
|
294
|
+
...settings.current.openCameraWidgets,
|
|
295
|
+
[partID.current]: currentRobotCameraWidgets.filter(
|
|
296
|
+
(widget) => widget !== camera.name
|
|
297
|
+
),
|
|
298
|
+
}
|
|
301
299
|
}}
|
|
302
300
|
/>
|
|
303
301
|
</div>
|
|
@@ -31,12 +31,14 @@
|
|
|
31
31
|
let fpsInterval: ReturnType<typeof setInterval> | undefined
|
|
32
32
|
let fpsCounterActive = false
|
|
33
33
|
|
|
34
|
+
const cleanup = () => {
|
|
35
|
+
if (fpsInterval) clearInterval(fpsInterval)
|
|
36
|
+
fpsCounterActive = false
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
// Cleanup on destroy
|
|
35
40
|
$effect(() => {
|
|
36
|
-
return
|
|
37
|
-
if (fpsInterval) clearInterval(fpsInterval)
|
|
38
|
-
fpsCounterActive = false
|
|
39
|
-
}
|
|
41
|
+
return cleanup
|
|
40
42
|
})
|
|
41
43
|
|
|
42
44
|
const onMediaLoad = (e: Event) => {
|
|
@@ -89,8 +91,8 @@
|
|
|
89
91
|
resolutions = options.map((opt) => ({ width: opt.width, height: opt.height }))
|
|
90
92
|
isLoading = false
|
|
91
93
|
})
|
|
92
|
-
.catch((
|
|
93
|
-
error =
|
|
94
|
+
.catch((error_) => {
|
|
95
|
+
error = error_ instanceof Error ? error_.message : 'Failed to get stream options'
|
|
94
96
|
isLoading = false
|
|
95
97
|
})
|
|
96
98
|
}
|
|
@@ -101,13 +103,13 @@
|
|
|
101
103
|
if (!target.value || !streamClient) return
|
|
102
104
|
|
|
103
105
|
const [w, h] = target.value.split('x').map(Number)
|
|
104
|
-
if (isNaN(w) || isNaN(h)) return
|
|
106
|
+
if (Number.isNaN(w) || Number.isNaN(h)) return
|
|
105
107
|
|
|
106
108
|
try {
|
|
107
109
|
await streamClient.setOptions(name, w, h)
|
|
108
110
|
error = undefined
|
|
109
|
-
} catch (
|
|
110
|
-
error =
|
|
111
|
+
} catch (error_) {
|
|
112
|
+
error = error_ instanceof Error ? error_.message : 'Failed to set resolution'
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
</script>
|