feat(editor): edit hierarchical map nodes
This commit is contained in:
+11
-18
@@ -4,7 +4,7 @@ This document describes the map editor that exists in the current codebase.
|
||||
|
||||
## Purpose
|
||||
|
||||
The editor is a React route used to inspect and adjust the `public/map.json` scene data from inside the La-Fabrik app. It shares the same `MapNode` data format as the game scene and uses React Three Fiber for rendering.
|
||||
The editor is a React route used to inspect and adjust the current hierarchical `public/map.json` scene data from inside the La-Fabrik app. It exposes editable object nodes as a flat list for UI selection, while preserving and saving the full map tree.
|
||||
|
||||
## Routing
|
||||
|
||||
@@ -72,7 +72,7 @@ src/
|
||||
|
||||
`src/controls/editor/FlyController.tsx` provides editor movement controls for player-style navigation.
|
||||
|
||||
`src/utils/map/loadMapSceneData.ts` is shared by the game map and editor. It loads `/map.json` and resolves available `public/models/{name}/model.glb` files first, then falls back to `public/models/{name}/model.gltf`.
|
||||
`src/utils/map/loadMapSceneData.ts` is shared by the game map and editor. It loads `/map.json`, validates the hierarchical payload, exposes editable nodes with their tree path, and resolves available `public/models/{name}/model.glb` files first, then falls back to `public/models/{name}/model.gltf`.
|
||||
|
||||
`src/utils/editor/loadEditorScene.ts` contains editor-only upload handling for user-selected folders.
|
||||
|
||||
@@ -90,19 +90,9 @@ interface MapNode {
|
||||
}
|
||||
```
|
||||
|
||||
`public/map.json` is expected to be a `MapNode[]`.
|
||||
`public/map.json` may be hierarchical. The editor keeps the hierarchy in `SceneData.mapTree` and stores editable entries in `SceneData.mapNodes` with a `path` back to the real tree node.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "pylone",
|
||||
"type": "Mesh",
|
||||
"position": [0, 5, 0],
|
||||
"rotation": [0, 1.57, 0],
|
||||
"scale": [1, 1, 1]
|
||||
}
|
||||
]
|
||||
```
|
||||
Group nodes use `role: "group"`; editable nodes keep `name`, `type`, `position`, `rotation`, and `scale`.
|
||||
|
||||
Each node `name` maps to a model folder:
|
||||
|
||||
@@ -124,7 +114,7 @@ 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, history actions, export, save, JSON preview, selection lock, and the cinematic/dialogue/SRT editors.
|
||||
7. `EditorControls` exposes transform mode, terrain snap, add/delete node, precise scale inputs, history actions, export, save, JSON preview, selection lock, and the cinematic/dialogue/SRT editors.
|
||||
|
||||
## Controls
|
||||
|
||||
@@ -136,6 +126,9 @@ If `model.glb` and `model.gltf` are both missing, the editor renders a fallback
|
||||
- `T`: translate mode.
|
||||
- `R`: rotate mode.
|
||||
- `S`: scale mode.
|
||||
- Snap terrain on move: enabled by default and applied when releasing a translated object.
|
||||
- Add node: creates a fallback cube under `blocking` using the requested model folder name.
|
||||
- Delete selected node: removes the editable node from the preserved map tree.
|
||||
- `Ctrl+Z` or `Cmd+Z`: undo.
|
||||
- `Ctrl+Y` or `Cmd+Y`: redo.
|
||||
- `WASD`, `ZQSD`, or arrow keys: move in player-controller mode.
|
||||
@@ -146,10 +139,10 @@ If `model.glb` and `model.gltf` are both missing, the editor renders a fallback
|
||||
|
||||
The editor supports two output paths:
|
||||
|
||||
- Export JSON downloads the current `MapNode[]` as `map.json`.
|
||||
- Save to Server posts the current `MapNode[]` to `/api/save-map`.
|
||||
- Export JSON downloads the current hierarchical map tree as `map.json`.
|
||||
- Save to Server posts the current hierarchical map tree to `/api/save-map`.
|
||||
|
||||
The dev-only `/api/save-map` endpoint is implemented by the Vite plugin in `vite.config.ts`. It writes to `public/map.json` and enforces a maximum payload size.
|
||||
The dev-only `/api/save-map` endpoint is implemented by the Vite plugin in `vite.config.ts`. It validates the payload through the shared map parser, writes to `public/map.json`, and enforces a maximum payload size.
|
||||
|
||||
## Editor Loading Overlay
|
||||
|
||||
|
||||
+30
-9
@@ -6,7 +6,7 @@ The map editor is available at `/editor`. It is a browser-based tool for editing
|
||||
|
||||
Use the editor when you need to:
|
||||
|
||||
- move, rotate, or scale objects from `public/map.json`
|
||||
- move, rotate, scale, add, or delete objects from `public/map.json`
|
||||
- inspect the raw JSON generated by the editor
|
||||
- preview and edit cinematics from `public/cinematics.json`
|
||||
- create, preview, and validate dialogue entries from `public/sounds/dialogue/dialogues.json`
|
||||
@@ -14,13 +14,13 @@ Use the editor when you need to:
|
||||
|
||||
The map editor reads the same map data as the runtime scene:
|
||||
|
||||
- `public/map.json` contains the object list.
|
||||
- `public/map.json` contains the current hierarchical runtime map.
|
||||
- `public/models/{name}/model.glb` contains the matching 3D model for each object name. `model.gltf` is still supported as a fallback during migration.
|
||||
- Missing models are displayed as gray fallback cubes, so incomplete maps remain editable.
|
||||
|
||||
## Map Node Format
|
||||
|
||||
Each entry in `public/map.json` represents one object:
|
||||
`public/map.json` is hierarchical. Group nodes such as `Scene`, `blocking`, `vegetation`, or `agriculture` organize the map. Editable object nodes still use the same transform fields:
|
||||
|
||||
| Field | Description |
|
||||
| ---------- | ------------------------------------------------- |
|
||||
@@ -47,9 +47,22 @@ Only the `Editor` group is open by default. Open the other groups when you need
|
||||
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. Check the JSON inspector if you need exact values.
|
||||
6. Use undo or redo if the transform is not correct.
|
||||
7. Export the JSON or save it to the dev server.
|
||||
5. Keep `Snap terrain on move` enabled when placing objects on the terrain.
|
||||
6. Adjust scale numerically from the `Selection` section if the gizmo is not precise enough.
|
||||
7. Check the JSON inspector if you need exact values.
|
||||
8. Use undo or redo if the transform is not correct.
|
||||
9. Export the JSON or save it to the dev server.
|
||||
|
||||
## Adding And Deleting Nodes
|
||||
|
||||
Use `Add Node` to create a new editable object under the `blocking` group.
|
||||
|
||||
- The new object starts as a fallback cube at `[0, 0, 0]`.
|
||||
- Name it with the model folder name you want, for example `maison1`.
|
||||
- If `public/models/{name}/model.glb` or `model.gltf` exists, saving and reloading will display the matching model.
|
||||
- If no matching model exists, the node stays editable as a gray cube.
|
||||
|
||||
Use the trash button in `Selection` to delete the selected node from the map tree.
|
||||
|
||||
## Controls
|
||||
|
||||
@@ -76,6 +89,14 @@ The `Selection` section shows the selected object name and its index in `public/
|
||||
- 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.
|
||||
- Use the scale fields to edit X/Y/Z scale precisely.
|
||||
- Use the trash button to remove the selected object.
|
||||
|
||||
## Terrain Snapping
|
||||
|
||||
`Snap terrain on move` is enabled by default. When you move an object and release the transform gizmo, the editor samples the terrain height at the object's X/Z position and updates its Y position.
|
||||
|
||||
This is intended for map objects that should sit on the ground. Disable it when you intentionally need a floating object.
|
||||
|
||||
When selection is locked:
|
||||
|
||||
@@ -90,7 +111,7 @@ The `Lock view` action switches the editor into a movement mode closer to the ru
|
||||
|
||||
## JSON Inspector
|
||||
|
||||
The `JSON` section shows the raw map data that will be exported or saved:
|
||||
The `JSON` section shows the editable node data:
|
||||
|
||||
- When no object is selected, it shows the full map node list.
|
||||
- When an object is selected, it highlights the JSON lines for that object.
|
||||
@@ -101,11 +122,11 @@ Use it to verify exact numeric transform values before saving or exporting. The
|
||||
|
||||
### Export JSON
|
||||
|
||||
`Export JSON` downloads the current map node list as `map.json`. Use this when you want to manually replace `public/map.json`.
|
||||
`Export JSON` downloads the current hierarchical map tree as `map.json`. Use this when you want to manually replace `public/map.json`.
|
||||
|
||||
### Save To Server
|
||||
|
||||
`Save to server` is available only during local development. It writes the edited map back to `public/map.json` through the Vite dev-server endpoint.
|
||||
`Save to server` is available only during local development. It writes the edited hierarchical map back to `public/map.json` through the Vite dev-server endpoint.
|
||||
|
||||
The button is hidden in production builds because production persistence is not implemented.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user