@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.
Files changed (135) hide show
  1. package/README.md +56 -26
  2. package/dist/FrameConfigUpdater.svelte.d.ts +11 -17
  3. package/dist/FrameConfigUpdater.svelte.js +109 -109
  4. package/dist/WorldObject.svelte.js +2 -15
  5. package/dist/common/v1/common_pb.d.ts +950 -0
  6. package/dist/common/v1/common_pb.js +1399 -0
  7. package/dist/components/App.svelte +37 -21
  8. package/dist/components/App.svelte.d.ts +1 -0
  9. package/dist/components/BatchedArrows.svelte +102 -0
  10. package/dist/components/BatchedArrows.svelte.d.ts +3 -0
  11. package/dist/components/CameraControls.svelte +2 -3
  12. package/dist/components/Details.svelte +364 -365
  13. package/dist/components/Entities.svelte +73 -0
  14. package/dist/components/{WorldObjects.svelte.d.ts → Entities.svelte.d.ts} +3 -3
  15. package/dist/components/FileDrop.svelte +9 -23
  16. package/dist/components/Focus.svelte +2 -3
  17. package/dist/components/Frame.svelte +41 -22
  18. package/dist/components/Frame.svelte.d.ts +4 -6
  19. package/dist/components/GLTF.svelte +36 -0
  20. package/dist/components/GLTF.svelte.d.ts +11 -0
  21. package/dist/components/Geometry2.svelte +201 -0
  22. package/dist/components/Geometry2.svelte.d.ts +18 -0
  23. package/dist/components/KeyboardControls.svelte +3 -3
  24. package/dist/components/Line.svelte +10 -13
  25. package/dist/components/Line.svelte.d.ts +2 -2
  26. package/dist/components/LiveUpdatesBanner.svelte +51 -15
  27. package/dist/components/MeasureTool.svelte +4 -5
  28. package/dist/components/Pointcloud.svelte +27 -14
  29. package/dist/components/Pointcloud.svelte.d.ts +2 -2
  30. package/dist/components/PointerMissBox.svelte +3 -3
  31. package/dist/components/Pose.svelte +31 -6
  32. package/dist/components/Pose.svelte.d.ts +2 -2
  33. package/dist/components/Scene.svelte +7 -6
  34. package/dist/components/SceneProviders.svelte +0 -6
  35. package/dist/components/Selected.svelte +22 -16
  36. package/dist/components/StaticGeometries.svelte +51 -27
  37. package/dist/components/Tree/Tree.svelte +28 -22
  38. package/dist/components/Tree/Tree.svelte.d.ts +2 -3
  39. package/dist/components/Tree/TreeContainer.svelte +72 -40
  40. package/dist/components/Tree/Widgets.svelte +2 -5
  41. package/dist/components/Tree/buildTree.d.ts +3 -6
  42. package/dist/components/Tree/buildTree.js +19 -39
  43. package/dist/components/__tests__/__fixtures__/entity.d.ts +2 -0
  44. package/dist/components/__tests__/__fixtures__/entity.js +20 -0
  45. package/dist/components/__tests__/__fixtures__/resource.d.ts +17 -0
  46. package/dist/components/__tests__/__fixtures__/resource.js +13 -0
  47. package/dist/components/dashboard/Dashboard.svelte +5 -3
  48. package/dist/components/dashboard/Dashboard.svelte.d.ts +7 -2
  49. package/dist/components/widgets/ArmPositions.svelte +19 -7
  50. package/dist/draw/v1/drawing_pb.d.ts +341 -0
  51. package/dist/draw/v1/drawing_pb.js +417 -0
  52. package/dist/draw/v1/metadata_pb.d.ts +23 -0
  53. package/dist/draw/v1/metadata_pb.js +39 -0
  54. package/dist/draw/v1/scene_pb.d.ts +230 -0
  55. package/dist/draw/v1/scene_pb.js +298 -0
  56. package/dist/draw/v1/snapshot_pb.d.ts +42 -0
  57. package/dist/draw/v1/snapshot_pb.js +61 -0
  58. package/dist/draw/v1/transforms_pb.d.ts +23 -0
  59. package/dist/draw/v1/transforms_pb.js +39 -0
  60. package/dist/ecs/index.d.ts +4 -0
  61. package/dist/ecs/index.js +4 -0
  62. package/dist/ecs/traits.d.ts +128 -0
  63. package/dist/ecs/traits.js +81 -0
  64. package/dist/ecs/useQuery.svelte.d.ts +4 -0
  65. package/dist/ecs/useQuery.svelte.js +49 -0
  66. package/dist/ecs/useTrait.svelte.d.ts +19 -0
  67. package/dist/ecs/useTrait.svelte.js +40 -0
  68. package/dist/ecs/useWorld.d.ts +4 -0
  69. package/dist/ecs/useWorld.js +10 -0
  70. package/dist/geometry.js +6 -6
  71. package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte +41 -0
  72. package/dist/hooks/__tests__/fixtures/ResizableTestWrapper.svelte.d.ts +6 -0
  73. package/dist/hooks/use3DModels.svelte.js +6 -4
  74. package/dist/hooks/useDrawAPI.svelte.d.ts +0 -10
  75. package/dist/hooks/useDrawAPI.svelte.js +143 -267
  76. package/dist/hooks/useFramelessComponents.svelte.js +1 -1
  77. package/dist/hooks/useFrames.svelte.d.ts +6 -2
  78. package/dist/hooks/useFrames.svelte.js +123 -19
  79. package/dist/hooks/useGeometries.svelte.d.ts +0 -2
  80. package/dist/hooks/useGeometries.svelte.js +49 -25
  81. package/dist/hooks/useObjectEvents.svelte.d.ts +3 -2
  82. package/dist/hooks/useObjectEvents.svelte.js +11 -7
  83. package/dist/hooks/usePartConfig.svelte.d.ts +1 -1
  84. package/dist/hooks/usePartConfig.svelte.js +2 -1
  85. package/dist/hooks/usePointclouds.svelte.d.ts +0 -2
  86. package/dist/hooks/usePointclouds.svelte.js +52 -21
  87. package/dist/hooks/usePose.svelte.js +15 -7
  88. package/dist/hooks/useResizable.svelte.d.ts +12 -0
  89. package/dist/hooks/useResizable.svelte.js +45 -0
  90. package/dist/hooks/useResourceByName.svelte.js +8 -5
  91. package/dist/hooks/useSelection.svelte.d.ts +13 -23
  92. package/dist/hooks/useSelection.svelte.js +45 -65
  93. package/dist/hooks/useVisibility.svelte.d.ts +2 -1
  94. package/dist/hooks/useWeblabs.svelte.d.ts +0 -1
  95. package/dist/hooks/useWeblabs.svelte.js +0 -1
  96. package/dist/hooks/useWorldState.svelte.d.ts +9 -0
  97. package/dist/hooks/useWorldState.svelte.js +158 -107
  98. package/dist/lib.d.ts +1 -0
  99. package/dist/lib.js +2 -0
  100. package/dist/three/BatchedArrow.d.ts +2 -3
  101. package/dist/three/BatchedArrow.js +3 -11
  102. package/dist/three/CapsuleGeometry.d.ts +1 -1
  103. package/dist/three/CapsuleGeometry.js +3 -1
  104. package/dist/transform.js +0 -15
  105. package/package.json +12 -7
  106. package/dist/components/WorldObject.svelte +0 -28
  107. package/dist/components/WorldObject.svelte.d.ts +0 -11
  108. package/dist/components/WorldObjects.svelte +0 -159
  109. package/dist/components/WorldState.svelte +0 -92
  110. package/dist/components/WorldState.svelte.d.ts +0 -7
  111. package/dist/components/__tests__/__fixtures__/worldObject.svelte.d.ts +0 -2
  112. package/dist/components/__tests__/__fixtures__/worldObject.svelte.js +0 -35
  113. package/dist/components/portal/Portal.svelte +0 -25
  114. package/dist/components/portal/Portal.svelte.d.ts +0 -8
  115. package/dist/components/portal/PortalTarget.svelte +0 -18
  116. package/dist/components/portal/PortalTarget.svelte.d.ts +0 -6
  117. package/dist/components/portal/index.d.ts +0 -2
  118. package/dist/components/portal/index.js +0 -2
  119. package/dist/components/portal/usePortalContext.svelte.d.ts +0 -5
  120. package/dist/components/portal/usePortalContext.svelte.js +0 -5
  121. package/dist/hooks/useArrows.svelte.d.ts +0 -3
  122. package/dist/hooks/useArrows.svelte.js +0 -9
  123. package/dist/hooks/useDraggable.svelte.d.ts +0 -10
  124. package/dist/hooks/useDraggable.svelte.js +0 -36
  125. package/dist/hooks/useObjects.svelte.d.ts +0 -7
  126. package/dist/hooks/useObjects.svelte.js +0 -35
  127. package/dist/hooks/usePersistentUUIDs.svelte.d.ts +0 -5
  128. package/dist/hooks/usePersistentUUIDs.svelte.js +0 -13
  129. package/dist/hooks/useResourceByName.svelte.d.ts +0 -7
  130. package/dist/hooks/useStaticGeometries.svelte.d.ts +0 -9
  131. package/dist/hooks/useStaticGeometries.svelte.js +0 -47
  132. package/dist/workers/worldStateWorker.d.ts +0 -1
  133. package/dist/workers/worldStateWorker.js +0 -114
  134. package/dist/world-state-messages.d.ts +0 -23
  135. package/dist/world-state-messages.js +0 -1
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ import Pose from './Pose.svelte'
3
+ import Frame from './Frame.svelte'
4
+ import Line from './Line.svelte'
5
+ import Pointcloud from './Pointcloud.svelte'
6
+ import GLTF from './GLTF.svelte'
7
+ import Label from './Label.svelte'
8
+ import { traits, useQuery } from '../ecs'
9
+ import { Or } from 'koota'
10
+
11
+ const frames = useQuery(traits.FramesAPI)
12
+ const geometries = useQuery(traits.GeometriesAPI)
13
+ const points = useQuery(traits.PointsGeometry)
14
+ const lines = useQuery(traits.LineGeometry)
15
+ const gltfs = useQuery(traits.GLTF)
16
+ const drawnMeshes = useQuery(
17
+ traits.DrawAPI,
18
+ Or(traits.Box, traits.Capsule, traits.Sphere, traits.BufferGeometry, traits.ReferenceFrame)
19
+ )
20
+ const worldStateMeshes = useQuery(
21
+ traits.WorldStateStoreAPI,
22
+ Or(traits.Box, traits.Capsule, traits.Sphere, traits.BufferGeometry, traits.ReferenceFrame)
23
+ )
24
+ </script>
25
+
26
+ {#each drawnMeshes.current as entity (entity)}
27
+ <Frame {entity}>
28
+ <Label text={entity.get(traits.Name)} />
29
+ </Frame>
30
+ {/each}
31
+
32
+ {#each worldStateMeshes.current as entity (entity)}
33
+ <Frame {entity}>
34
+ <Label text={entity.get(traits.Name)} />
35
+ </Frame>
36
+ {/each}
37
+
38
+ {#each points.current as entity (entity)}
39
+ <Pointcloud {entity}>
40
+ <Label text={entity.get(traits.Name)} />
41
+ </Pointcloud>
42
+ {/each}
43
+
44
+ {#each frames.current as entity (entity)}
45
+ <Pose {entity}>
46
+ {#snippet children({ pose })}
47
+ <Frame
48
+ {pose}
49
+ {entity}
50
+ >
51
+ <Label text={entity.get(traits.Name)} />
52
+ </Frame>
53
+ {/snippet}
54
+ </Pose>
55
+ {/each}
56
+
57
+ {#each geometries.current as entity (entity)}
58
+ <Frame {entity}>
59
+ <Label text={entity.get(traits.Name)} />
60
+ </Frame>
61
+ {/each}
62
+
63
+ {#each lines.current as entity (entity)}
64
+ <Line {entity}>
65
+ <Label text={entity.get(traits.Name)} />
66
+ </Line>
67
+ {/each}
68
+
69
+ {#each gltfs.current as entity (entity)}
70
+ <GLTF {entity}>
71
+ <Label text={entity.get(traits.Name)} />
72
+ </GLTF>
73
+ {/each}
@@ -11,8 +11,8 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
11
11
  };
12
12
  z_$$bindings?: Bindings;
13
13
  }
14
- declare const WorldObjects: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
14
+ declare const Entities: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
15
  [evt: string]: CustomEvent<any>;
16
16
  }, {}, {}, string>;
17
- type WorldObjects = InstanceType<typeof WorldObjects>;
18
- export default WorldObjects;
17
+ type Entities = InstanceType<typeof Entities>;
18
+ export default Entities;
@@ -1,12 +1,12 @@
1
1
  <script lang="ts">
2
- import { useDrawAPI } from '../hooks/useDrawAPI.svelte'
3
- import { parsePcdInWorker, WorldObject } from '../lib'
2
+ import { traits, useWorld } from '../ecs'
3
+ import { parsePcdInWorker } from '../lib'
4
4
  import { useToast, ToastVariant } from '@viamrobotics/prime-core'
5
5
  import { PLYLoader } from 'three/examples/jsm/Addons.js'
6
6
 
7
7
  let { ...rest } = $props()
8
8
 
9
- const { addPoints, addMesh } = useDrawAPI()
9
+ const world = useWorld()
10
10
 
11
11
  type DropStates = 'inactive' | 'hovering' | 'loading'
12
12
 
@@ -102,31 +102,17 @@
102
102
  if (ext === extensions.PCD) {
103
103
  const result = await parsePcdInWorker(new Uint8Array(arrayBuffer))
104
104
 
105
- addPoints(
106
- new WorldObject(
107
- file.name,
108
- undefined,
109
- undefined,
110
- {
111
- center: undefined,
112
- geometryType: {
113
- case: 'points',
114
- value: result.positions,
115
- },
116
- },
117
- result.colors ? { colors: result.colors } : undefined
118
- )
105
+ world.spawn(
106
+ traits.Name(file.name),
107
+ traits.PointsGeometry(result.positions),
108
+ result.colors ? traits.VertexColors(result.colors) : traits.Color
119
109
  )
120
110
 
121
111
  toast({ message: `Loaded ${file.name}`, variant: ToastVariant.Success })
122
112
  } else if (ext === extensions.PLY) {
123
- const result = new PLYLoader().parse(arrayBuffer)
124
- const worldObject = new WorldObject(file.name, undefined, undefined, {
125
- center: undefined,
126
- geometryType: { case: 'bufferGeometry', value: result },
127
- })
113
+ const bufferGeometry = new PLYLoader().parse(arrayBuffer)
128
114
 
129
- addMesh(worldObject)
115
+ world.spawn(traits.Name(file.name), traits.BufferGeometry(bufferGeometry))
130
116
 
131
117
  toast({ message: `Loaded ${file.name}`, variant: ToastVariant.Success })
132
118
  }
@@ -1,10 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { T } from '@threlte/core'
3
- import { TrackballControls, Gizmo } from '@threlte/extras'
3
+ import { TrackballControls, Gizmo, Portal } from '@threlte/extras'
4
4
  import { Box3, type Object3D, Vector3 } from 'three'
5
5
  import { TrackballControls as ThreeTrackballControls } from 'three/examples/jsm/controls/TrackballControls.js'
6
6
  import Camera from './Camera.svelte'
7
- import Portal from './portal/Portal.svelte'
8
7
  import Button from './dashboard/Button.svelte'
9
8
 
10
9
  interface Props {
@@ -46,7 +45,7 @@
46
45
  bind:ref={controls}
47
46
  target={center}
48
47
  >
49
- <Gizmo />
48
+ <Gizmo placement="bottom-right" />
50
49
  </TrackballControls>
51
50
  </Camera>
52
51
 
@@ -1,45 +1,64 @@
1
- <script module>
2
- const colorUtil = new Color()
3
- </script>
4
-
5
1
  <script lang="ts">
6
2
  import type { Snippet } from 'svelte'
7
- import type { WorldObject } from '../WorldObject.svelte'
8
3
  import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
9
4
  import { Color, type Object3D } from 'three'
10
- import Geometry from './Geometry.svelte'
5
+ import Geometry from './Geometry2.svelte'
11
6
  import { useWeblabs } from '../hooks/useWeblabs.svelte'
12
- import { useSelected } from '../hooks/useSelection.svelte'
7
+ import { useSelectedEntity } from '../hooks/useSelection.svelte'
13
8
  import { useSettings } from '../hooks/useSettings.svelte'
14
9
  import { use3DModels } from '../hooks/use3DModels.svelte'
15
- import { colors, darkenColor } from '../color'
10
+ import { colors, darkenColor, resourceColors } from '../color'
16
11
  import { WEBLABS_EXPERIMENTS } from '../hooks/useWeblabs.svelte'
12
+ import type { Entity } from 'koota'
13
+ import { traits, useTrait } from '../ecs'
14
+ import type { Pose } from '@viamrobotics/sdk'
15
+ import { useResourceByName } from '../hooks/useResourceByName.svelte'
17
16
 
18
17
  interface Props {
19
- uuid: string
20
- name: string
21
- geometry?: WorldObject['geometry']
22
- pose: WorldObject['pose']
23
- metadata: WorldObject['metadata']
18
+ entity: Entity
19
+ pose?: Pose
24
20
  children?: Snippet<[{ ref: Object3D }]>
25
21
  }
26
22
 
27
- let { uuid, name, ...rest }: Props = $props()
23
+ let { entity, pose, children }: Props = $props()
28
24
 
25
+ const colorUtil = new Color()
29
26
  const settings = useSettings()
30
27
  const componentModels = use3DModels()
31
- const selected = useSelected()
28
+ const selectedEntity = useSelectedEntity()
29
+ const resourceByName = useResourceByName()
32
30
  const weblabs = useWeblabs()
33
- const events = useObjectEvents(() => uuid)
31
+ const name = useTrait(() => entity, traits.Name)
32
+ const entityColor = useTrait(() => entity, traits.Color)
33
+ const events = useObjectEvents(() => entity)
34
+ const resourceColor = $derived.by(() => {
35
+ if (!name.current) {
36
+ return undefined
37
+ }
38
+ const subtype = resourceByName.current[name.current]?.subtype
39
+ return resourceColors[subtype as keyof typeof resourceColors]
40
+ })
34
41
 
35
- const color = $derived(rest.metadata.color ?? colors.default)
42
+ const color = $derived.by(() => {
43
+ if (entityColor.current) {
44
+ return colorUtil.set(entityColor.current.r, entityColor.current.g, entityColor.current.b)
45
+ }
46
+ if (resourceColor) {
47
+ return resourceColor
48
+ }
49
+ return colors.default
50
+ })
36
51
 
37
52
  const model = $derived.by(() => {
38
53
  if (!weblabs.isActive(WEBLABS_EXPERIMENTS.MOTION_TOOLS_RENDER_ARM_MODELS)) {
39
54
  return
40
55
  }
41
56
 
42
- const [componentName, id] = name.split(':')
57
+ if (!name.current) {
58
+ return
59
+ }
60
+
61
+ const [componentName, id] = name.current.split(':')
43
62
  if (!componentName || !id) {
44
63
  return
45
64
  }
@@ -48,13 +67,13 @@
48
67
  </script>
49
68
 
50
69
  <Geometry
51
- {uuid}
52
- {name}
70
+ {entity}
53
71
  {model}
72
+ {pose}
73
+ {children}
54
74
  renderMode={settings.current.renderArmModels}
55
- color={selected.current === uuid
75
+ color={selectedEntity.current === entity
56
76
  ? `#${darkenColor(color, 75).getHexString()}`
57
77
  : `#${colorUtil.set(color).getHexString()}`}
58
78
  {...events}
59
- {...rest}
60
79
  />
@@ -1,12 +1,10 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { WorldObject } from '../WorldObject.svelte';
3
2
  import { type Object3D } from 'three';
3
+ import type { Entity } from 'koota';
4
+ import type { Pose } from '@viamrobotics/sdk';
4
5
  interface Props {
5
- uuid: string;
6
- name: string;
7
- geometry?: WorldObject['geometry'];
8
- pose: WorldObject['pose'];
9
- metadata: WorldObject['metadata'];
6
+ entity: Entity;
7
+ pose?: Pose;
10
8
  children?: Snippet<[{
11
9
  ref: Object3D;
12
10
  }]>;
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import { T, type Props as ThrelteProps } from '@threlte/core'
3
+ import { Portal, PortalTarget } from '@threlte/extras'
4
+ import type { Snippet } from 'svelte'
5
+ import type { Object3D } from 'three'
6
+ import { useObjectEvents } from '../hooks/useObjectEvents.svelte'
7
+ import type { Entity } from 'koota'
8
+ import { traits, useTrait } from '../ecs'
9
+
10
+ interface Props extends ThrelteProps<Object3D> {
11
+ entity: Entity
12
+ children?: Snippet
13
+ }
14
+
15
+ let { entity, children, ...rest }: Props = $props()
16
+
17
+ const name = useTrait(() => entity, traits.Name)
18
+ const parent = useTrait(() => entity, traits.Parent)
19
+ const gltf = useTrait(() => entity, traits.GLTF)
20
+ const objectProps = useObjectEvents(() => entity)
21
+ </script>
22
+
23
+ {#if gltf.current?.scene}
24
+ <Portal id={parent.current}>
25
+ <T
26
+ is={gltf.current.scene as Object3D}
27
+ name={name.current}
28
+ {...objectProps}
29
+ {...rest}
30
+ >
31
+ {@render children?.()}
32
+
33
+ <PortalTarget id={name.current} />
34
+ </T>
35
+ </Portal>
36
+ {/if}
@@ -0,0 +1,11 @@
1
+ import { type Props as ThrelteProps } from '@threlte/core';
2
+ import type { Snippet } from 'svelte';
3
+ import type { Object3D } from 'three';
4
+ import type { Entity } from 'koota';
5
+ interface Props extends ThrelteProps<Object3D> {
6
+ entity: Entity;
7
+ children?: Snippet;
8
+ }
9
+ declare const GLTF: import("svelte").Component<Props, {}, "">;
10
+ type GLTF = ReturnType<typeof GLTF>;
11
+ export default GLTF;
@@ -0,0 +1,201 @@
1
+ <script lang="ts">
2
+ import { T, useThrelte, type Props as ThrelteProps } from '@threlte/core'
3
+ import { type Snippet } from 'svelte'
4
+ import {
5
+ meshBounds,
6
+ MeshLineMaterial,
7
+ MeshLineGeometry,
8
+ Portal,
9
+ PortalTarget,
10
+ } from '@threlte/extras'
11
+ import { BufferGeometry, Color, DoubleSide, FrontSide, Group, Mesh } from 'three'
12
+ import { CapsuleGeometry } from '../three/CapsuleGeometry'
13
+ import { colors, darkenColor } from '../color'
14
+ import AxesHelper from './AxesHelper.svelte'
15
+ import type { Entity } from 'koota'
16
+ import { traits, useTrait } from '../ecs'
17
+ import { poseToObject3d } from '../transform'
18
+ import type { Pose } from '@viamrobotics/sdk'
19
+
20
+ interface Props extends ThrelteProps<Group> {
21
+ entity: Entity
22
+ color?: string
23
+ model?: Group
24
+ pose?: Pose
25
+ renderMode?: 'model' | 'colliders' | 'colliders+model'
26
+ children?: Snippet<[{ ref: Group }]>
27
+ }
28
+
29
+ let {
30
+ entity,
31
+ color: overrideColor,
32
+ model,
33
+ renderMode = 'colliders',
34
+ pose,
35
+ children,
36
+ ...rest
37
+ }: Props = $props()
38
+
39
+ const colorUtil = new Color()
40
+
41
+ const { invalidate } = useThrelte()
42
+ const name = useTrait(() => entity, traits.Name)
43
+ const parent = useTrait(() => entity, traits.Parent)
44
+ const entityColor = useTrait(() => entity, traits.Color)
45
+ const opacity = useTrait(() => entity, traits.Opacity)
46
+ const box = useTrait(() => entity, traits.Box)
47
+ const capsule = useTrait(() => entity, traits.Capsule)
48
+ const sphere = useTrait(() => entity, traits.Sphere)
49
+ const bufferGeometry = useTrait(() => entity, traits.BufferGeometry)
50
+ const lineGeometry = useTrait(() => entity, traits.LineGeometry)
51
+ const pointsGeometry = useTrait(() => entity, traits.PointsGeometry)
52
+ const center = useTrait(() => entity, traits.Center)
53
+
54
+ const geometryType = $derived.by(() => {
55
+ if (box.current) return 'box'
56
+ if (capsule.current) return 'capsule'
57
+ if (sphere.current) return 'sphere'
58
+ if (bufferGeometry.current) return 'buffer'
59
+ if (lineGeometry.current) return 'line'
60
+ if (pointsGeometry.current) return 'points'
61
+ })
62
+
63
+ const color = $derived.by(() => {
64
+ if (overrideColor) {
65
+ return overrideColor
66
+ }
67
+ if (entityColor.current) {
68
+ return colorUtil
69
+ .setRGB(entityColor.current.r, entityColor.current.g, entityColor.current.b)
70
+ .getHexString()
71
+ }
72
+ return colors.default
73
+ })
74
+
75
+ const group = new Group()
76
+ const mesh = $derived.by(() => {
77
+ if (geometryType === undefined) {
78
+ return
79
+ }
80
+
81
+ const result = new Mesh()
82
+
83
+ if (geometryType === 'buffer' || geometryType === 'points' || geometryType === 'line') {
84
+ result.raycast = meshBounds
85
+ }
86
+
87
+ return result
88
+ })
89
+
90
+ $effect.pre(() => {
91
+ if (mesh && center.current) {
92
+ poseToObject3d(center.current, mesh)
93
+ invalidate()
94
+ }
95
+ })
96
+
97
+ const entityPose = useTrait(() => entity, traits.Pose)
98
+ const resolvedPose = $derived(pose ?? entityPose.current)
99
+ $effect.pre(() => {
100
+ if (resolvedPose) {
101
+ poseToObject3d(resolvedPose, group)
102
+ invalidate()
103
+ }
104
+ })
105
+
106
+ let geo = $state.raw<BufferGeometry>()
107
+
108
+ const oncreate = (ref: BufferGeometry) => {
109
+ geo = ref
110
+ }
111
+ </script>
112
+
113
+ <Portal id={parent.current}>
114
+ <T
115
+ is={group}
116
+ {...rest}
117
+ >
118
+ {#if geometryType}
119
+ <AxesHelper
120
+ width={3}
121
+ length={0.1}
122
+ />
123
+
124
+ <T
125
+ is={mesh}
126
+ name={name.current}
127
+ bvh={{ enabled: bufferGeometry.current !== undefined }}
128
+ >
129
+ {#if model && renderMode.includes('model')}
130
+ <T is={model} />
131
+ {/if}
132
+
133
+ {#if !model || renderMode.includes('colliders')}
134
+ {#if bufferGeometry.current}
135
+ <T
136
+ is={bufferGeometry.current}
137
+ {oncreate}
138
+ />
139
+ {:else if lineGeometry.current}
140
+ <MeshLineGeometry points={lineGeometry.current} />
141
+ {:else if box.current}
142
+ {@const { x, y, z } = box.current ?? { x: 0, y: 0, z: 0 }}
143
+ <T.BoxGeometry
144
+ args={[x * 0.001, y * 0.001, z * 0.001]}
145
+ {oncreate}
146
+ />
147
+ {:else if sphere.current}
148
+ {@const { r } = sphere.current ?? { r: 0 }}
149
+ <T.SphereGeometry
150
+ args={[r * 0.001]}
151
+ {oncreate}
152
+ />
153
+ {:else if capsule.current}
154
+ {@const { r, l } = capsule.current ?? { r: 0, l: 0 }}
155
+ <T
156
+ is={CapsuleGeometry}
157
+ args={[r * 0.001, l * 0.001]}
158
+ {oncreate}
159
+ />
160
+ {/if}
161
+ {/if}
162
+
163
+ {#if lineGeometry.current}
164
+ <MeshLineMaterial
165
+ {color}
166
+ width={0.005}
167
+ />
168
+ {:else}
169
+ <T.MeshToonMaterial
170
+ {color}
171
+ side={geometryType === 'buffer' ? DoubleSide : FrontSide}
172
+ transparent
173
+ opacity={opacity.current ?? 0.7}
174
+ />
175
+
176
+ {#if geo}
177
+ <T.LineSegments
178
+ raycast={() => null}
179
+ bvh={{ enabled: false }}
180
+ >
181
+ <T.EdgesGeometry args={[geo, 0]} />
182
+ <T.LineBasicMaterial color={darkenColor(color, 10)} />
183
+ </T.LineSegments>
184
+ {/if}
185
+ {/if}
186
+ </T>
187
+ {:else}
188
+ <AxesHelper
189
+ name={name.current}
190
+ width={3}
191
+ length={0.1}
192
+ />
193
+ {/if}
194
+
195
+ {@render children?.({ ref: group })}
196
+
197
+ {#if name.current}
198
+ <PortalTarget id={name.current} />
199
+ {/if}
200
+ </T>
201
+ </Portal>
@@ -0,0 +1,18 @@
1
+ import { type Props as ThrelteProps } from '@threlte/core';
2
+ import { type Snippet } from 'svelte';
3
+ import { Group } from 'three';
4
+ import type { Entity } from 'koota';
5
+ import type { Pose } from '@viamrobotics/sdk';
6
+ interface Props extends ThrelteProps<Group> {
7
+ entity: Entity;
8
+ color?: string;
9
+ model?: Group;
10
+ pose?: Pose;
11
+ renderMode?: 'model' | 'colliders' | 'colliders+model';
12
+ children?: Snippet<[{
13
+ ref: Group;
14
+ }]>;
15
+ }
16
+ declare const Geometry2: import("svelte").Component<Props, {}, "">;
17
+ type Geometry2 = ReturnType<typeof Geometry2>;
18
+ export default Geometry2;
@@ -3,7 +3,7 @@
3
3
  import { useTask } from '@threlte/core'
4
4
  import type { CameraControlsRef } from '@threlte/extras'
5
5
  import { PressedKeys } from 'runed'
6
- import { useFocused } from '../hooks/useSelection.svelte'
6
+ import { useFocusedEntity } from '../hooks/useSelection.svelte'
7
7
  import { useSettings } from '../hooks/useSettings.svelte'
8
8
 
9
9
  interface Props {
@@ -12,7 +12,7 @@
12
12
 
13
13
  let { cameraControls }: Props = $props()
14
14
 
15
- const focus = useFocused()
15
+ const focusedEntity = useFocusedEntity()
16
16
  const settings = useSettings()
17
17
 
18
18
  const keys = new PressedKeys()
@@ -93,7 +93,7 @@
93
93
 
94
94
  keys.onKeys('escape', () => {
95
95
  if (keys.has('escape')) {
96
- focus.set(undefined)
96
+ focusedEntity.set()
97
97
  }
98
98
  })
99
99
 
@@ -2,34 +2,31 @@
2
2
  import { T } from '@threlte/core'
3
3
  import { Instance, InstancedMesh } from '@threlte/extras'
4
4
  import Frame from './Frame.svelte'
5
- import type { WorldObject } from '../WorldObject.svelte'
6
5
  import { useSettings } from '../hooks/useSettings.svelte'
7
6
  import type { Snippet } from 'svelte'
7
+ import type { Entity } from 'koota'
8
+ import { traits, useTrait } from '../ecs'
8
9
 
9
10
  interface Props {
10
- object: WorldObject
11
+ entity: Entity
11
12
  children?: Snippet
12
13
  }
13
14
 
14
- let { object, children }: Props = $props()
15
+ let { entity, children }: Props = $props()
15
16
 
16
17
  const settings = useSettings()
18
+ const points = useTrait(() => entity, traits.LineGeometry)
19
+ const dotColor = useTrait(() => entity, traits.DottedLineColor)
17
20
  </script>
18
21
 
19
- <Frame
20
- {...object}
21
- metadata={{
22
- ...object.metadata,
23
- lineWidth: settings.current.lineWidth,
24
- }}
25
- />
22
+ <Frame {entity} />
26
23
 
27
- {#if object.metadata.lineDotColor && object.metadata.points}
24
+ {#if dotColor.current && points.current}
28
25
  <InstancedMesh frustumCulled={false}>
29
26
  <T.SphereGeometry />
30
- <T.MeshBasicMaterial color={object.metadata.lineDotColor} />
27
+ <T.MeshBasicMaterial color={[dotColor.current.r, dotColor.current.g, dotColor.current.b]} />
31
28
 
32
- {#each object.metadata.points as { x, y, z }, i (i)}
29
+ {#each points.current as { x, y, z }, i (i)}
33
30
  <Instance
34
31
  position.x={x}
35
32
  position.y={y}
@@ -1,7 +1,7 @@
1
- import type { WorldObject } from '../WorldObject.svelte';
2
1
  import type { Snippet } from 'svelte';
2
+ import type { Entity } from 'koota';
3
3
  interface Props {
4
- object: WorldObject;
4
+ entity: Entity;
5
5
  children?: Snippet;
6
6
  }
7
7
  declare const Line: import("svelte").Component<Props, {}, "">;