@viamrobotics/motion-tools 1.31.0 → 1.32.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/components/App.svelte +51 -46
- package/dist/components/App.svelte.d.ts +1 -1
- package/dist/components/Entities/Arrows/Arrows.svelte +4 -7
- package/dist/components/Entities/hooks/useEntityEvents.svelte.d.ts +0 -1
- package/dist/components/Entities/hooks/useEntityEvents.svelte.js +30 -16
- package/dist/components/InputBindings.svelte +0 -43
- package/dist/components/KeyboardBindings.svelte +38 -0
- package/dist/components/KeyboardBindings.svelte.d.ts +18 -0
- package/dist/components/PointerMissBox.svelte +6 -3
- package/dist/components/Scene.svelte +34 -45
- package/dist/components/SceneProviders.svelte +2 -4
- package/dist/components/SceneProviders.svelte.d.ts +1 -3
- package/dist/components/Selected.svelte +20 -27
- package/dist/components/SelectedTransformControls.svelte +8 -7
- package/dist/components/StaticGeometries.svelte +3 -5
- package/dist/components/hover/HoveredEntities.svelte +15 -14
- package/dist/components/hover/HoveredEntities.svelte.d.ts +17 -2
- package/dist/components/hover/HoveredEntity.svelte +8 -5
- package/dist/components/hover/HoveredEntity.svelte.d.ts +5 -1
- package/dist/components/hover/LinkedHoveredEntity.svelte +7 -11
- package/dist/components/hover/LinkedHoveredEntity.svelte.d.ts +1 -0
- package/dist/components/overlay/Details.svelte +22 -37
- package/dist/components/overlay/Details.svelte.d.ts +3 -1
- package/dist/components/overlay/controls/Controls.svelte +0 -2
- package/dist/components/overlay/dashboard/Button.svelte +5 -3
- package/dist/components/overlay/dashboard/Button.svelte.d.ts +1 -1
- package/dist/components/overlay/left-pane/Tree.svelte +13 -10
- package/dist/components/overlay/left-pane/TreeContainer.svelte +9 -4
- package/dist/components/overlay/left-pane/TreeNode.svelte +6 -4
- package/dist/draw.d.ts +1 -0
- package/dist/draw.js +1 -1
- package/dist/ecs/index.d.ts +1 -0
- package/dist/ecs/index.js +1 -0
- package/dist/ecs/traits.d.ts +22 -5
- package/dist/ecs/traits.js +33 -4
- package/dist/ecs/useTag.svelte.d.ts +5 -0
- package/dist/ecs/useTag.svelte.js +43 -0
- package/dist/hooks/useEnvironment.svelte.d.ts +1 -1
- package/dist/hooks/useLinked.svelte.js +7 -8
- package/dist/hooks/useMouseRaycaster.svelte.d.ts +4 -3
- package/dist/hooks/useMouseRaycaster.svelte.js +1 -0
- package/dist/hooks/useSettings.svelte.d.ts +1 -1
- package/dist/plugins/Focus/Focus.svelte +45 -0
- package/dist/plugins/Focus/Focus.svelte.d.ts +3 -0
- package/dist/plugins/Focus/FocusBox.svelte +75 -0
- package/dist/plugins/Focus/FocusBox.svelte.d.ts +3 -0
- package/dist/plugins/Focus/provideFocus.svelte.d.ts +1 -0
- package/dist/plugins/Focus/provideFocus.svelte.js +61 -0
- package/dist/{components → plugins}/MeasureTool/MeasureTool.svelte +6 -8
- package/dist/plugins/Selection/SelectionTool.svelte +10 -3
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +2 -0
- package/dist/three/arrow.d.ts +2 -0
- package/dist/three/arrow.js +3 -1
- package/package.json +16 -4
- package/dist/components/Focus.svelte +0 -46
- package/dist/components/Focus.svelte.d.ts +0 -7
- package/dist/hooks/useSelection.svelte.d.ts +0 -33
- package/dist/hooks/useSelection.svelte.js +0 -94
- /package/dist/{components → plugins}/MeasureTool/MeasurePoint.svelte +0 -0
- /package/dist/{components → plugins}/MeasureTool/MeasurePoint.svelte.d.ts +0 -0
- /package/dist/{components → plugins}/MeasureTool/MeasureTool.svelte.d.ts +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Struct } from '@viamrobotics/sdk'
|
|
3
3
|
import type { Entity } from 'koota'
|
|
4
|
-
import type { Snippet } from 'svelte'
|
|
5
4
|
|
|
6
5
|
import { Canvas } from '@threlte/core'
|
|
7
6
|
import { PortalTarget } from '@threlte/extras'
|
|
8
7
|
import { useXR } from '@threlte/xr'
|
|
9
8
|
import { provideToast, ToastContainer } from '@viamrobotics/prime-core'
|
|
10
9
|
import { primeTheme } from '@viamrobotics/tweakpane-config'
|
|
10
|
+
import { onMount, type Snippet } from 'svelte'
|
|
11
11
|
import { ThemeUtils } from 'svelte-tweakpane-ui'
|
|
12
12
|
|
|
13
13
|
import type { FragmentInfo } from '../hooks/usePartConfig.svelte'
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import TreeContainer from './overlay/left-pane/TreeContainer.svelte'
|
|
19
19
|
import Settings from './overlay/settings/Settings.svelte'
|
|
20
20
|
import XR from './xr/XR.svelte'
|
|
21
|
-
import { provideWorld } from '../ecs'
|
|
21
|
+
import { provideWorld, traits, useQuery } from '../ecs'
|
|
22
22
|
import { type CameraPose, provideCameraControls } from '../hooks/useControls.svelte'
|
|
23
23
|
import { provideEnvironment } from '../hooks/useEnvironment.svelte'
|
|
24
24
|
import { providePartConfig } from '../hooks/usePartConfig.svelte'
|
|
@@ -107,9 +107,11 @@
|
|
|
107
107
|
environment.current.isStandalone = !localConfigProps
|
|
108
108
|
})
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
onMount(() => {
|
|
111
111
|
ThemeUtils.setGlobalDefaultTheme(primeTheme)
|
|
112
112
|
})
|
|
113
|
+
|
|
114
|
+
const selected = useQuery(traits.Selected)
|
|
113
115
|
</script>
|
|
114
116
|
|
|
115
117
|
<div
|
|
@@ -118,53 +120,56 @@
|
|
|
118
120
|
>
|
|
119
121
|
<Canvas renderMode="on-demand">
|
|
120
122
|
<SceneProviders>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
<Scene>
|
|
124
|
+
{@render appChildren?.()}
|
|
125
|
+
</Scene>
|
|
126
|
+
|
|
127
|
+
<XR {@attach domPortal(root)} />
|
|
128
|
+
|
|
129
|
+
{#if settings.current.renderSubEntityHoverDetail}
|
|
130
|
+
<HoveredEntities />
|
|
131
|
+
{/if}
|
|
132
|
+
|
|
133
|
+
<!-- Overlays that need Threlte context -->
|
|
134
|
+
<div {@attach domPortal(root)}>
|
|
135
|
+
<FileDrop />
|
|
136
|
+
<Dashboard {dashboard} />
|
|
137
|
+
<Controls />
|
|
138
|
+
|
|
139
|
+
{#each selected.current as entity, index (entity)}
|
|
140
|
+
<Details
|
|
141
|
+
{entity}
|
|
142
|
+
{details}
|
|
143
|
+
style="transform: translate(0, {index * 40}px)"
|
|
144
|
+
/>
|
|
145
|
+
{/each}
|
|
146
|
+
|
|
147
|
+
{#if environment.current.isStandalone}
|
|
148
|
+
<LiveUpdatesBanner />
|
|
149
|
+
{/if}
|
|
125
150
|
|
|
126
|
-
<
|
|
151
|
+
<TreeContainer />
|
|
127
152
|
|
|
128
|
-
{#if settings.current.
|
|
129
|
-
<
|
|
153
|
+
{#if settings.current.enableArmPositionsWidget}
|
|
154
|
+
<ArmPositions />
|
|
130
155
|
{/if}
|
|
131
156
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<ArmPositions />
|
|
149
|
-
{/if}
|
|
150
|
-
|
|
151
|
-
{#if !focus && !$isPresenting}
|
|
152
|
-
{#each currentRobotCameraWidgets as cameraName (cameraName)}
|
|
153
|
-
<Camera name={cameraName} />
|
|
154
|
-
{/each}
|
|
155
|
-
|
|
156
|
-
{#each currentFramePovWidgets as povFrameName (povFrameName)}
|
|
157
|
-
<FramePov frameName={povFrameName} />
|
|
158
|
-
{/each}
|
|
159
|
-
{/if}
|
|
160
|
-
|
|
161
|
-
<PortalTarget id="dom" />
|
|
162
|
-
|
|
163
|
-
<Settings />
|
|
164
|
-
<Logs />
|
|
165
|
-
<AddFrames />
|
|
166
|
-
</div>
|
|
167
|
-
{/snippet}
|
|
157
|
+
{#if !$isPresenting}
|
|
158
|
+
{#each currentRobotCameraWidgets as cameraName (cameraName)}
|
|
159
|
+
<Camera name={cameraName} />
|
|
160
|
+
{/each}
|
|
161
|
+
|
|
162
|
+
{#each currentFramePovWidgets as povFrameName (povFrameName)}
|
|
163
|
+
<FramePov frameName={povFrameName} />
|
|
164
|
+
{/each}
|
|
165
|
+
{/if}
|
|
166
|
+
|
|
167
|
+
<PortalTarget id="dom" />
|
|
168
|
+
|
|
169
|
+
<Settings />
|
|
170
|
+
<Logs />
|
|
171
|
+
<AddFrames />
|
|
172
|
+
</div>
|
|
168
173
|
</SceneProviders>
|
|
169
174
|
</Canvas>
|
|
170
175
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Struct } from '@viamrobotics/sdk';
|
|
2
2
|
import type { Entity } from 'koota';
|
|
3
|
-
import type
|
|
3
|
+
import { type Snippet } from 'svelte';
|
|
4
4
|
import type { FragmentInfo } from '../hooks/usePartConfig.svelte';
|
|
5
5
|
import { type CameraPose } from '../hooks/useControls.svelte';
|
|
6
6
|
interface LocalConfigProps {
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import AxesHelper from '../../AxesHelper.svelte'
|
|
9
9
|
import { useEntityEvents } from '../hooks/useEntityEvents.svelte'
|
|
10
|
-
import { traits, useTrait } from '../../../ecs'
|
|
11
|
-
import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte'
|
|
10
|
+
import { traits, useTag, useTrait } from '../../../ecs'
|
|
12
11
|
import { meshBoundsRaycast, raycast } from '../../../three/InstancedArrows/raycast'
|
|
13
12
|
|
|
14
13
|
interface Props {
|
|
@@ -20,19 +19,17 @@
|
|
|
20
19
|
|
|
21
20
|
const { invalidate } = useThrelte()
|
|
22
21
|
const worldMatrix = useTrait(() => entity, traits.WorldMatrix)
|
|
22
|
+
const selected = useTag(() => entity, traits.Selected)
|
|
23
23
|
const invisible = useTrait(() => entity, traits.InheritedInvisible)
|
|
24
24
|
const showAxesHelper = useTrait(() => entity, traits.ShowAxesHelper)
|
|
25
25
|
|
|
26
26
|
const events = useEntityEvents(() => entity)
|
|
27
|
-
const selectedEntity = useSelectedEntity()
|
|
28
|
-
const focusedEntity = useFocusedEntity()
|
|
29
|
-
|
|
30
|
-
const displayEntity = $derived(selectedEntity.current ?? focusedEntity.current)
|
|
31
27
|
|
|
32
28
|
const raycastFunction = $derived.by(() => {
|
|
33
|
-
if (
|
|
29
|
+
if (selected.current) {
|
|
34
30
|
return raycast
|
|
35
31
|
}
|
|
32
|
+
|
|
36
33
|
return meshBoundsRaycast
|
|
37
34
|
})
|
|
38
35
|
|
|
@@ -4,7 +4,6 @@ export declare const useEntityEvents: (entity: () => Entity | undefined) => {
|
|
|
4
4
|
onpointerenter: (event: IntersectionEvent<MouseEvent>) => void;
|
|
5
5
|
onpointermove: (event: IntersectionEvent<MouseEvent>) => void;
|
|
6
6
|
onpointerleave: (event: IntersectionEvent<MouseEvent>) => void;
|
|
7
|
-
ondblclick: (event: IntersectionEvent<MouseEvent>) => void;
|
|
8
7
|
onpointerdown: (event: IntersectionEvent<MouseEvent>) => void;
|
|
9
8
|
onclick: (event: IntersectionEvent<MouseEvent>) => void;
|
|
10
9
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useCursor } from '@threlte/extras';
|
|
2
2
|
import { MathUtils, Matrix4, Quaternion, Vector2 } from 'three';
|
|
3
|
-
import { traits, useTrait } from '../../../ecs';
|
|
4
|
-
import { useFocusedEntity, useSelectedEntity } from '../../../hooks/useSelection.svelte';
|
|
3
|
+
import { traits, useTrait, useWorld } from '../../../ecs';
|
|
5
4
|
import { updateHoverInfo } from '../../../HoverUpdater.svelte';
|
|
6
5
|
import { OrientationVector } from '../../../three/OrientationVector';
|
|
7
6
|
const tempHoverMatrix = new Matrix4();
|
|
@@ -15,8 +14,7 @@ const infoToLocalMatrix = (info, out) => {
|
|
|
15
14
|
};
|
|
16
15
|
export const useEntityEvents = (entity) => {
|
|
17
16
|
const down = new Vector2();
|
|
18
|
-
const
|
|
19
|
-
const focusedEntity = useFocusedEntity();
|
|
17
|
+
const world = useWorld();
|
|
20
18
|
const cursor = useCursor();
|
|
21
19
|
const invisible = useTrait(entity, traits.InheritedInvisible);
|
|
22
20
|
const onpointerenter = (event) => {
|
|
@@ -80,25 +78,42 @@ export const useEntityEvents = (entity) => {
|
|
|
80
78
|
currentEntity.remove(traits.InstancedMatrix);
|
|
81
79
|
}
|
|
82
80
|
};
|
|
83
|
-
const ondblclick = (event) => {
|
|
84
|
-
if (invisible.current)
|
|
85
|
-
return;
|
|
86
|
-
event.stopPropagation();
|
|
87
|
-
const currentEntity = entity();
|
|
88
|
-
focusedEntity.set(currentEntity, event.instanceId ?? event.batchId);
|
|
89
|
-
};
|
|
90
81
|
const onpointerdown = (event) => {
|
|
91
82
|
if (invisible.current)
|
|
92
83
|
return;
|
|
93
84
|
down.copy(event.pointer);
|
|
94
85
|
};
|
|
95
86
|
const onclick = (event) => {
|
|
96
|
-
if (invisible.current)
|
|
87
|
+
if (invisible.current) {
|
|
97
88
|
return;
|
|
89
|
+
}
|
|
98
90
|
event.stopPropagation();
|
|
99
|
-
if (down.distanceToSquared(event.pointer)
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
if (down.distanceToSquared(event.pointer) >= 0.1) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const currentEntity = entity();
|
|
95
|
+
if (!currentEntity)
|
|
96
|
+
return;
|
|
97
|
+
if (event.nativeEvent.shiftKey) {
|
|
98
|
+
if (currentEntity.has(traits.Selected)) {
|
|
99
|
+
currentEntity.remove(traits.Selected);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
currentEntity.add(traits.Selected);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
for (const entity of world.query(traits.Selected)) {
|
|
107
|
+
if (entity !== currentEntity) {
|
|
108
|
+
entity.remove(traits.Selected);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!currentEntity.has(traits.Selected)) {
|
|
112
|
+
currentEntity.add(traits.Selected);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (event.instanceId || event.batchId) {
|
|
116
|
+
currentEntity.add(traits.InstanceId(event.instanceId ?? event.batchId));
|
|
102
117
|
}
|
|
103
118
|
};
|
|
104
119
|
$effect(() => {
|
|
@@ -117,7 +132,6 @@ export const useEntityEvents = (entity) => {
|
|
|
117
132
|
onpointerenter,
|
|
118
133
|
onpointermove,
|
|
119
134
|
onpointerleave,
|
|
120
|
-
ondblclick,
|
|
121
135
|
onpointerdown,
|
|
122
136
|
onclick,
|
|
123
137
|
};
|
|
@@ -3,26 +3,14 @@
|
|
|
3
3
|
|
|
4
4
|
import { isInstanceOf, useTask } from '@threlte/core'
|
|
5
5
|
import { useGamepad, useInputMap, useKeyboard } from '@threlte/extras'
|
|
6
|
-
import { PressedKeys } from 'runed'
|
|
7
6
|
import { MathUtils, Vector3 } from 'three'
|
|
8
7
|
|
|
9
|
-
import { traits } from '../ecs'
|
|
10
|
-
import { useFocusedEntity, useSelectedEntity } from '../hooks/useSelection.svelte'
|
|
11
|
-
import { useSettings } from '../hooks/useSettings.svelte'
|
|
12
|
-
|
|
13
8
|
interface Props {
|
|
14
9
|
cameraControls: CameraControlsRef
|
|
15
10
|
}
|
|
16
11
|
|
|
17
12
|
let { cameraControls }: Props = $props()
|
|
18
13
|
|
|
19
|
-
const focusedEntity = useFocusedEntity()
|
|
20
|
-
const selectedEntity = useSelectedEntity()
|
|
21
|
-
|
|
22
|
-
const entity = $derived(focusedEntity.current ?? selectedEntity.current)
|
|
23
|
-
|
|
24
|
-
const settings = useSettings()
|
|
25
|
-
|
|
26
14
|
const keyboard = useKeyboard()
|
|
27
15
|
const gamepad = useGamepad()
|
|
28
16
|
const input = useInputMap(
|
|
@@ -125,35 +113,4 @@
|
|
|
125
113
|
autoInvalidate: false,
|
|
126
114
|
}
|
|
127
115
|
)
|
|
128
|
-
|
|
129
|
-
const keys = new PressedKeys()
|
|
130
|
-
|
|
131
|
-
keys.onKeys('escape', () => {
|
|
132
|
-
focusedEntity.set()
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
keys.onKeys('c', () => {
|
|
136
|
-
settings.current.cameraMode =
|
|
137
|
-
settings.current.cameraMode === 'perspective' ? 'orthographic' : 'perspective'
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
keys.onKeys('1', () => {
|
|
141
|
-
settings.current.transformMode = 'translate'
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
keys.onKeys('2', () => {
|
|
145
|
-
settings.current.transformMode = 'rotate'
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
keys.onKeys('3', () => {
|
|
149
|
-
settings.current.transformMode = 'scale'
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
keys.onKeys('h', () => {
|
|
153
|
-
if (entity?.has(traits.Invisible)) {
|
|
154
|
-
entity.remove(traits.Invisible)
|
|
155
|
-
} else {
|
|
156
|
-
entity?.add(traits.Invisible)
|
|
157
|
-
}
|
|
158
|
-
})
|
|
159
116
|
</script>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PressedKeys } from 'runed'
|
|
3
|
+
|
|
4
|
+
import { traits, useQuery } from '../ecs'
|
|
5
|
+
import { useSettings } from '../hooks/useSettings.svelte'
|
|
6
|
+
|
|
7
|
+
const selected = useQuery(traits.Selected)
|
|
8
|
+
|
|
9
|
+
const settings = useSettings()
|
|
10
|
+
const keys = new PressedKeys()
|
|
11
|
+
|
|
12
|
+
keys.onKeys('c', () => {
|
|
13
|
+
settings.current.cameraMode =
|
|
14
|
+
settings.current.cameraMode === 'perspective' ? 'orthographic' : 'perspective'
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
keys.onKeys('1', () => {
|
|
18
|
+
settings.current.transformMode = 'translate'
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
keys.onKeys('2', () => {
|
|
22
|
+
settings.current.transformMode = 'rotate'
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
keys.onKeys('3', () => {
|
|
26
|
+
settings.current.transformMode = 'scale'
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
keys.onKeys('h', () => {
|
|
30
|
+
for (const entity of selected.current) {
|
|
31
|
+
if (entity?.has(traits.Invisible)) {
|
|
32
|
+
entity.remove(traits.Invisible)
|
|
33
|
+
} else {
|
|
34
|
+
entity?.add(traits.Invisible)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const KeyboardBindings: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type KeyboardBindings = InstanceType<typeof KeyboardBindings>;
|
|
18
|
+
export default KeyboardBindings;
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
import { MeshDiscardMaterial } from '@threlte/extras'
|
|
4
4
|
import { BackSide, Mesh, Vector3 } from 'three'
|
|
5
5
|
|
|
6
|
+
import { traits, useQuery } from '../ecs'
|
|
6
7
|
import { useTransformControls } from '../hooks/useControls.svelte'
|
|
7
|
-
import { useSelectedEntity } from '../hooks/useSelection.svelte'
|
|
8
8
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
9
9
|
|
|
10
10
|
const { camera } = useThrelte()
|
|
11
11
|
const settings = useSettings()
|
|
12
|
-
const selectedEntity = useSelectedEntity()
|
|
13
12
|
const transformControls = useTransformControls()
|
|
13
|
+
const selected = useQuery(traits.Selected)
|
|
14
|
+
|
|
14
15
|
const cameraDown = new Vector3()
|
|
15
16
|
|
|
16
17
|
const enabled = $derived(settings.current.interactionMode === 'navigate')
|
|
@@ -32,7 +33,9 @@
|
|
|
32
33
|
return
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
for (const entity of selected.current) {
|
|
37
|
+
entity.remove(traits.Selected)
|
|
38
|
+
}
|
|
36
39
|
}}
|
|
37
40
|
>
|
|
38
41
|
<T.BoxGeometry args={[size, size, size]} />
|
|
@@ -4,22 +4,20 @@
|
|
|
4
4
|
import { T, useThrelte } from '@threlte/core'
|
|
5
5
|
import { Environment, Grid, interactivity, PerfMonitor, PortalTarget } from '@threlte/extras'
|
|
6
6
|
import { useXR } from '@threlte/xr'
|
|
7
|
-
import { ShaderMaterial
|
|
7
|
+
import { ShaderMaterial } from 'three'
|
|
8
8
|
|
|
9
9
|
import Camera from './Camera.svelte'
|
|
10
10
|
import Entities from './Entities/Entities.svelte'
|
|
11
|
-
import Focus from './Focus.svelte'
|
|
12
11
|
import Selected from './Selected.svelte'
|
|
13
12
|
import SelectedTransformControls from './SelectedTransformControls.svelte'
|
|
14
13
|
import StaticGeometries from './StaticGeometries.svelte'
|
|
15
14
|
import { bvh } from '../hooks/plugins/bvh.svelte'
|
|
16
|
-
import { useFocusedObject3d } from '../hooks/useSelection.svelte'
|
|
17
15
|
import { useSettings } from '../hooks/useSettings.svelte'
|
|
18
16
|
|
|
19
17
|
import hdrImage from '../assets/ferndale_studio_11_1k.hdr'
|
|
20
18
|
import BatchedArrows from './BatchedArrows.svelte'
|
|
21
19
|
import CameraControls from './CameraControls.svelte'
|
|
22
|
-
import
|
|
20
|
+
import KeyboardBindings from './KeyboardBindings.svelte'
|
|
23
21
|
import PointerMissBox from './PointerMissBox.svelte'
|
|
24
22
|
import { useOrigin } from './xr/useOrigin.svelte'
|
|
25
23
|
|
|
@@ -31,7 +29,6 @@
|
|
|
31
29
|
|
|
32
30
|
const threlte = useThrelte()
|
|
33
31
|
const settings = useSettings()
|
|
34
|
-
const focusedObject3d = useFocusedObject3d()
|
|
35
32
|
const origin = useOrigin()
|
|
36
33
|
|
|
37
34
|
// @ts-expect-error This is for debugging
|
|
@@ -59,8 +56,6 @@
|
|
|
59
56
|
|
|
60
57
|
bvh(raycaster, () => ({ helper: false, enabled: bvhEnabled }))
|
|
61
58
|
|
|
62
|
-
const focusedObject = $derived(focusedObject3d.current)
|
|
63
|
-
|
|
64
59
|
const { isPresenting } = useXR()
|
|
65
60
|
</script>
|
|
66
61
|
|
|
@@ -68,6 +63,7 @@
|
|
|
68
63
|
<PerfMonitor anchorX="right" />
|
|
69
64
|
{/if}
|
|
70
65
|
|
|
66
|
+
<KeyboardBindings />
|
|
71
67
|
<Environment url={hdrImage} />
|
|
72
68
|
|
|
73
69
|
<T.Group
|
|
@@ -75,47 +71,40 @@
|
|
|
75
71
|
rotation.z={origin.rotation}
|
|
76
72
|
>
|
|
77
73
|
<PointerMissBox />
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
{#if
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
infiniteGrid
|
|
104
|
-
renderOrder={999}
|
|
105
|
-
cellSize={settings.current.gridCellSize}
|
|
106
|
-
sectionSize={settings.current.gridSectionSize}
|
|
107
|
-
fadeOrigin={new Vector3()}
|
|
108
|
-
fadeDistance={settings.current.gridFadeDistance}
|
|
109
|
-
/>
|
|
110
|
-
{/if}
|
|
74
|
+
<SelectedTransformControls />
|
|
75
|
+
|
|
76
|
+
{#if !$isPresenting && settings.current.grid}
|
|
77
|
+
<Grid
|
|
78
|
+
oncreate={(ref) => {
|
|
79
|
+
const material = ref.material as ShaderMaterial
|
|
80
|
+
material.depthWrite = false
|
|
81
|
+
}}
|
|
82
|
+
raycast={() => null}
|
|
83
|
+
bvh={{ enabled: false }}
|
|
84
|
+
plane="xy"
|
|
85
|
+
sectionColor="#333"
|
|
86
|
+
infiniteGrid
|
|
87
|
+
renderOrder={999}
|
|
88
|
+
cellSize={settings.current.gridCellSize}
|
|
89
|
+
sectionSize={settings.current.gridSectionSize}
|
|
90
|
+
fadeOrigin={[0, 0, 0]}
|
|
91
|
+
fadeDistance={settings.current.gridFadeDistance}
|
|
92
|
+
/>
|
|
93
|
+
{/if}
|
|
94
|
+
|
|
95
|
+
{#if !$isPresenting}
|
|
96
|
+
<Camera position={[3, 3, 3]}>
|
|
97
|
+
<CameraControls />
|
|
98
|
+
</Camera>
|
|
111
99
|
{/if}
|
|
112
100
|
|
|
113
|
-
<
|
|
114
|
-
|
|
101
|
+
<StaticGeometries />
|
|
102
|
+
<Selected />
|
|
103
|
+
|
|
104
|
+
<PortalTarget />
|
|
115
105
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
</T.Group>
|
|
106
|
+
<Entities />
|
|
107
|
+
<BatchedArrows />
|
|
119
108
|
|
|
120
109
|
{@render children?.()}
|
|
121
110
|
|
|
@@ -19,13 +19,12 @@
|
|
|
19
19
|
import { providePointclouds } from '../hooks/usePointclouds.svelte'
|
|
20
20
|
import { provideRelationships } from '../hooks/useRelationships.svelte'
|
|
21
21
|
import { provideResourceByName } from '../hooks/useResourceByName.svelte'
|
|
22
|
-
import { provideSelection } from '../hooks/useSelection.svelte'
|
|
23
22
|
import { provideWorldStates } from '../hooks/useWorldState.svelte'
|
|
24
23
|
|
|
25
24
|
import { provideOrigin } from './xr/useOrigin.svelte'
|
|
26
25
|
|
|
27
26
|
interface Props {
|
|
28
|
-
children: Snippet
|
|
27
|
+
children: Snippet
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
let { children }: Props = $props()
|
|
@@ -55,8 +54,7 @@
|
|
|
55
54
|
provideWorldStates()
|
|
56
55
|
provideFramelessComponents()
|
|
57
56
|
|
|
58
|
-
const { focus } = provideSelection()
|
|
59
57
|
provideLinkedEntities()
|
|
60
58
|
</script>
|
|
61
59
|
|
|
62
|
-
{@render children(
|
|
60
|
+
{@render children()}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
interface Props {
|
|
3
|
-
children: Snippet
|
|
4
|
-
focus: boolean;
|
|
5
|
-
}]>;
|
|
3
|
+
children: Snippet;
|
|
6
4
|
}
|
|
7
5
|
declare const SceneProviders: import("svelte").Component<Props, {}, "">;
|
|
8
6
|
type SceneProviders = ReturnType<typeof SceneProviders>;
|
|
@@ -1,55 +1,48 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { T, useTask, useThrelte } from '@threlte/core'
|
|
3
3
|
import { BatchedMesh, Box3 } from 'three'
|
|
4
4
|
import { OBB } from 'three/addons/math/OBB.js'
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import { useSelectedEntity, useSelectedObject3d } from '../hooks/useSelection.svelte'
|
|
6
|
+
import { traits, useQuery } from '../ecs'
|
|
9
7
|
import { OBBHelper } from '../three/OBBHelper'
|
|
10
8
|
|
|
11
9
|
const box3 = new Box3()
|
|
12
10
|
const obb = new OBB()
|
|
13
|
-
const obbHelper = new OBBHelper()
|
|
14
11
|
|
|
15
|
-
const { invalidate } = useThrelte()
|
|
16
|
-
const
|
|
17
|
-
const selectedObject3d = useSelectedObject3d()
|
|
12
|
+
const { scene, invalidate } = useThrelte()
|
|
13
|
+
const selected = useQuery(traits.Selected)
|
|
18
14
|
|
|
19
|
-
const
|
|
15
|
+
const obbHelpers = $derived(selected.current.map((entity) => [entity, new OBBHelper()] as const))
|
|
20
16
|
|
|
21
17
|
useTask(
|
|
22
18
|
() => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} else {
|
|
36
|
-
obbHelper.setFromObject(object)
|
|
19
|
+
for (const [entity, obbHelper] of obbHelpers) {
|
|
20
|
+
const object = scene.getObjectByName(entity as unknown as string)
|
|
21
|
+
if (!object) continue
|
|
22
|
+
|
|
23
|
+
const instance = entity.get(traits.InstanceId)
|
|
24
|
+
if (instance !== undefined && instance >= 0) {
|
|
25
|
+
;(object as BatchedMesh).getBoundingBoxAt(instance, box3)
|
|
26
|
+
obb.fromBox3(box3)
|
|
27
|
+
obbHelper.setFromOBB(obb)
|
|
28
|
+
} else {
|
|
29
|
+
obbHelper.setFromObject(object)
|
|
30
|
+
}
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
invalidate()
|
|
40
34
|
},
|
|
41
35
|
{
|
|
42
|
-
running: () =>
|
|
36
|
+
running: () => selected.current.length > 0,
|
|
43
37
|
autoInvalidate: false,
|
|
44
38
|
}
|
|
45
39
|
)
|
|
46
40
|
</script>
|
|
47
41
|
|
|
48
|
-
{#
|
|
42
|
+
{#each obbHelpers as [entity, obbHelper] (entity)}
|
|
49
43
|
<T
|
|
50
44
|
is={obbHelper}
|
|
51
|
-
dispose={false}
|
|
52
45
|
raycast={() => null}
|
|
53
46
|
bvh={{ enabled: false }}
|
|
54
47
|
/>
|
|
55
|
-
{/
|
|
48
|
+
{/each}
|