feat(editor): add multi-selection transforms

This commit is contained in:
Tom Boullay
2026-05-28 00:29:00 +02:00
parent 81cd935bba
commit 65651405b6
6 changed files with 233 additions and 46 deletions
+5 -3
View File
@@ -52,7 +52,7 @@ src/
## Responsibilities
`src/pages/editor/page.tsx` is the route-level composition component. It owns route-specific state such as selected object, hovered object, transform mode, selection lock, player-mode toggle, cinematic preview requests, and editor scene loading state.
`src/pages/editor/page.tsx` is the route-level composition component. It owns route-specific state such as primary selected object, selected object indexes, hovered object, transform mode, selection lock, player-mode toggle, cinematic preview requests, and editor scene loading state.
`src/hooks/editor/useEditorSceneData.ts` loads the default map data and handles folder uploads.
@@ -60,7 +60,7 @@ src/
`src/components/editor/scene/EditorScene.tsx` composes the editor canvas scene, camera controls, lights, keyboard shortcuts, and `EditorMap`.
`src/components/editor/scene/EditorMap.tsx` renders map nodes, fallback cubes, selection highlighting, and transform controls.
`src/components/editor/scene/EditorMap.tsx` renders map nodes, fallback cubes, selection highlighting, and transform controls. For multi-selection, it attaches `TransformControls` to a temporary group centered on the selected nodes, then decomposes the group delta back into each selected node transform.
`src/components/editor/EditorControls.tsx` renders the HTML control panel outside the canvas. The panel is organized into top-level `details` groups: `Editor`, `Cinematics`, `Dialogues`, and `SRT`.
@@ -115,11 +115,12 @@ If `model.glb` and `model.gltf` are both missing, the editor renders a fallback
4. If `/map.json` is missing, the page displays a folder-upload flow.
5. `EditorSceneLoadingTracker` uses drei `useProgress()` to update the fullscreen editor loading overlay while models load.
6. `EditorScene` renders the grid, lights, camera controls, and map nodes inside `Suspense`.
7. `EditorControls` exposes transform mode, terrain snap, terrain-selection lock, add/delete node, precise scale inputs, history actions, camera focus/reset, export, save, JSON preview, selection lock, and the cinematic/dialogue/SRT editors.
7. `EditorControls` exposes transform mode, terrain snap, terrain-selection lock, add/delete node, precise scale inputs, history actions, camera focus/reset, export, save, JSON preview, selection lock, multi-selection status, and the cinematic/dialogue/SRT editors.
## Controls
- Click: select a node.
- `Shift` + right click: add or remove a node from the multi-selection.
- `Esc`: clear selection.
- Click empty space: clear selection.
- Selection lock button: prevent object clicks, empty-space clicks, and `Esc` from changing the current selection.
@@ -128,6 +129,7 @@ If `model.glb` and `model.gltf` are both missing, the editor renders a fallback
- `R`: rotate mode.
- `S`: scale mode.
- Snap terrain on move: enabled by default and applied while translating an object.
- Multi-selection transforms use a temporary centered group and write the resulting position, rotation, and scale back to every selected map node.
- Lock terrain: enabled by default so terrain remains visible but ignores selection clicks.
- Camera action: centers on the selected object or resets to the editor home view.
- Add node: creates a fallback cube under `blocking` using the requested model folder name.
+12 -8
View File
@@ -45,14 +45,15 @@ Only the `Editor` group is open by default. Open the other groups when you need
1. Open `/editor` in the local app.
2. Click an object in the scene to select it.
3. Choose a transform mode: translate, rotate, or scale.
4. Drag the transform gizmo in the 3D view.
5. Keep `Snap terrain on move` enabled when placing objects on the terrain.
6. Use `Center on object` or `Reset camera` from the `View` section when navigating large maps.
7. Adjust scale numerically from the `Selection` section if the gizmo is not precise enough.
8. Check the JSON inspector if you need exact values.
9. Use undo or redo if the transform is not correct.
10. Export the JSON or save it to the dev server.
3. Use `Shift + right click` on other objects to add or remove them from the current multi-selection.
4. Choose a transform mode: translate, rotate, or scale.
5. Drag the transform gizmo in the 3D view. With multiple objects selected, the gizmo transforms the selected group and writes each object transform back to `map.json`.
6. Keep `Snap terrain on move` enabled when placing objects on the terrain.
7. Use `Center on object` or `Reset camera` from the `View` section when navigating large maps.
8. Adjust scale numerically from the `Selection` section if the gizmo is not precise enough.
9. Check the JSON inspector if you need exact values.
10. Use undo or redo if the transform is not correct.
11. Export the JSON or save it to the dev server.
## Adding And Deleting Nodes
@@ -70,6 +71,7 @@ Use the trash button in `Selection` to delete the selected node from the map tre
| Action | Input |
| -------------------- | -------------------------- |
| Select object | Click object |
| Toggle multi-select | `Shift` + right click |
| Deselect | `Esc` or click empty space |
| Lock selection | `Lock` button in Selection |
| Clear selection | `X` button in Selection |
@@ -87,6 +89,8 @@ Use the trash button in `Selection` to delete the selected node from the map tre
The `Selection` section shows the selected object name and its index in `public/map.json`.
- Click an object to select it.
- Use `Shift + right click` on objects to add or remove them from a multi-selection.
- When several objects are selected, the gizmo appears on the selection group and applies translate, rotate, or scale to each selected node.
- Click empty space or press `Esc` to clear the selection.
- Use the `X` button to clear the selection explicitly.
- Use the `Lock` button to protect the current selection while editing.