update dcs

This commit is contained in:
luzieahrens
2026-07-04 09:03:58 +02:00
parent c73a82943f
commit 14de604ad2
4 changed files with 182 additions and 3 deletions
+58 -1
View File
@@ -48,6 +48,7 @@ type SceneItem = {
// --- interactions ---
grabable?: boolean
locked?: boolean // blocks move gizmo + deletion in the editor
}
```
@@ -68,12 +69,14 @@ type SceneItem = {
| `Camera` | `position`, `target` | `zoom`, `rotation` |
| `Text` | `position`, `text` | `color`, `fontSize`, `fontWeight`, `dimensions`, `rotation` |
| `Custom` | `position`, `file` | `dimensions`, `rotation` |
| `Area` | `position` | `dimensions` (X/Z footprint only — Y is fixed), `rotation` |
### Common optional field (all types)
| Field | Type | Description |
|---|---|---|
| `grabable` | `boolean` | Whether the item is interactable in-experience |
| `locked` | `boolean` | When `true`, hides the move gizmo for the item and blocks deletion until unlocked from the menubar |
---
@@ -89,6 +92,27 @@ IDs are assigned sequentially when items are spawned and do not change.
---
## `SceneGroups`
Used by the Grouping feature to let several items (or nested groups) be selected, moved, and managed as one.
```ts
type GroupChild =
| { kind: "item"; id: number }
| { kind: "group"; id: number }
type SceneGroup = {
name: string
children: GroupChild[]
}
type SceneGroups = Record<number, SceneGroup>
```
Group IDs are assigned sequentially from the store's `nextGroupId` counter, independent of item IDs. A group's `children` reference item/group IDs directly — there is no `groupId` field on `SceneItem` itself.
---
## `SceneStore` (Zustand)
The complete editor state. Fields marked 💾 are persisted to `localStorage` under the key `scene-storage`.
@@ -102,16 +126,48 @@ The complete editor state. Fields marked 💾 are persisted to `localStorage` un
| `customItems` | `CustomItem[]` | `[]` | ✅ | User-uploaded GLB assets |
| `showLights` | `boolean` | `true` | ✅ | Light helper visibility |
| `showWalls` | `boolean` | `true` | ✅ | Wall visibility |
| `showDummy` | `boolean` | `false` | ✅ | Stickman dummy visibility |
| `showAreas` | `boolean` | `true` | ✅ | Area Collider visibility (Canvas Toggles) |
| `cameraTarget` | `number[]` | `[0,0,0]` | ✅ | OrbitControls look-at point |
| `cameraRotation` | `number[]` | `[0,0,0]` | ✅ | Editor camera rotation |
| `cameraQuaternion` | `[x,y,z,w]` | `[0,0,0,0]` | ✅ | Editor camera quaternion |
| `graphicalCoding` | `{ nodes, connections } \| null` | `null` | ✅ | Legacy node-graph coding state (superseded by `blockCoding`) |
| `blockCoding` | `{ scripts: unknown[] } \| null` | `null` | ✅ | Block Coding scripts — see [Block Coding data structure](./data-structure-block-coding.md) |
| `backgroundSound` | `string \| null` | `null` | ✅ | Uploaded ambient sound storage path (World Settings → Sound) |
| `groups` | `SceneGroups` | `{}` | ✅ | All item/group hierarchies |
| `nextGroupId` | `number` | `1` | ✅ | Next group ID to assign |
| `selectedGroup` | `number \| null` | `null` | — | Currently selected group ID |
| `multiSelectedItems` | `number[]` | `[]` | — | Item IDs in a multi-select (shift-click) |
| `multiSelectedGroups` | `number[]` | `[]` | — | Group IDs in a multi-select |
| `past` / `future` | `HistorySnapshot[]` | `[]` | — | Undo/redo stacks — see [Undo/Redo](#undoredo) below |
| `message` | `string \| null` | `null` | — | Transient toast message |
| `hovered` | `number \| null` | `null` | — | Item ID currently hovered in canvas or panel |
| `focusItem` | `number \| null` | `null` | — | Item ID the camera should focus on |
| `isDragging` | `boolean` | `false` | — | Pointer drag state |
| `isTyping` | `boolean` | `false` | — | Text input focus state |
| `orbitControls` | `OrbitControlsImpl \| null` | `null` | — | Live OrbitControls ref |
| `api` | `ScreenshotAPI \| null` | `null` | — | Screenshot renderer ref |
💾 reflects the `partialize` allowlist in `lib/SceneStore.ts``selectedGroup`, `multiSelectedItems`, `multiSelectedGroups`, `past`, `future`, and the transient/ref fields below them are intentionally excluded, so undo history and multi-selection do not survive a page refresh.
---
## Undo/Redo
`past`/`future` hold up to `MAX_HISTORY` (50) `HistorySnapshot`s:
```ts
type HistorySnapshot = {
items: SceneItems
groups: SceneGroups
nextGroupId: number
}
```
- Mutations that go through `setItems`, `updateItem`, `batchUpdateItems`, or any group action (`createGroup`, `createGroupFromSelection`, `disbandGroup`, `renameGroup`) push the *pre-change* state onto `past` and clear `future`.
- Pushes are coalesced: rapid successive edits (e.g. dragging a gizmo) within 400ms of the last push are merged into one history entry, so undo steps back per gesture rather than per frame.
- `undo()`/`redo()` swap `items`/`groups`/`nextGroupId` between `past`/`future` and clear the current selection state (`selectedGroup`, `multiSelectedItems`, `multiSelectedGroups`).
- History is in-memory only — it is not part of `partialize` and does not round-trip through save/load or the database JSON.
---
## `ITEMS_CONFIG` spawn defaults
@@ -137,3 +193,4 @@ When an item is added to the scene, it is initialized with these values from `it
| `Camera` | `[1,1,1]` | `#444444` | `[0,0,0]` | `4` | `zoom: 1, target: [0,0,0]` |
| `Text` | `[0.5,0.5,0.5]` | `black` | `[0,0,0]` | `2` | `text: "Text", fontWeight: "regular", fontSize: 5` |
| `Custom` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `1` | — |
| `Area` | `[10,0.1,10]` | `#ffffff` | `[0,0,0]` | `0` | — |