Initial commit: creator and database data structure docs
This commit is contained in:
@@ -0,0 +1,139 @@
|
|||||||
|
# Creator Data Structure
|
||||||
|
|
||||||
|
This document describes the internal data structures used by the XRWise Creator editor.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `SceneItem`
|
||||||
|
|
||||||
|
A single object in the scene. Stored in the Zustand store as `Record<number, SceneItem>`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type SceneItem = {
|
||||||
|
// --- always present ---
|
||||||
|
type: ItemType // e.g. "Cube", "Camera", "Directional Light"
|
||||||
|
category: string // e.g. "Basic", "Light", "Streaming"
|
||||||
|
position: [number, number, number] // world-space XYZ
|
||||||
|
|
||||||
|
// --- transform ---
|
||||||
|
rotation?: number[] // Euler degrees [x, y, z]
|
||||||
|
dimensions?: number[] // XYZ scale / size in metres
|
||||||
|
|
||||||
|
// --- appearance ---
|
||||||
|
color?: string // hex color e.g. "#ffffff"
|
||||||
|
opacity?: number // 0–1
|
||||||
|
|
||||||
|
// --- lights ---
|
||||||
|
intensity?: number | string // light intensity
|
||||||
|
target?: number[] // look-at point [x, y, z]
|
||||||
|
|
||||||
|
// --- media / streaming ---
|
||||||
|
file?: string // asset path or storage key
|
||||||
|
LiveKitRoomID?: string
|
||||||
|
shader?: string // "unlit" | "lit" | "greenscreen"
|
||||||
|
GreenScreenColor?: string // hex color
|
||||||
|
GreenScreenBorderSettings?: string // numeric string
|
||||||
|
GreenScreenColorNear?: string // numeric string (0–1)
|
||||||
|
widthcrop?: number
|
||||||
|
heightcrop?: number
|
||||||
|
videoJobId?: string // in-progress conversion job ID
|
||||||
|
|
||||||
|
// --- text ---
|
||||||
|
text?: string
|
||||||
|
fontWeight?: "light" | "regular" | "bold"
|
||||||
|
fontSize?: number
|
||||||
|
|
||||||
|
// --- camera ---
|
||||||
|
zoom?: number // 1–10; maps to FOV = 50 / zoom
|
||||||
|
|
||||||
|
// --- interactions ---
|
||||||
|
grabable?: boolean
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fields by item type
|
||||||
|
|
||||||
|
| Type | Required fields | Optional fields |
|
||||||
|
|---|---|---|
|
||||||
|
| `Cube` / `Sphere` / `Cylinder` / `Cone` | `position` | `color`, `opacity`, `dimensions`, `rotation` |
|
||||||
|
| `Floor` | `position` | `color`, `opacity`, `dimensions`, `rotation` |
|
||||||
|
| `Wall` | `position` | `color`, `opacity`, `dimensions`, `rotation` |
|
||||||
|
| `Directional Light` | `position`, `target` | `color`, `intensity` |
|
||||||
|
| `Point Light` | `position` | `color`, `intensity` |
|
||||||
|
| `Entrance` / `Exit` | `position` | — |
|
||||||
|
| `Billboard` | `position`, `file` | `dimensions`, `rotation` |
|
||||||
|
| `LiveKitStream` | `position`, `LiveKitRoomID` | `shader`, `GreenScreenColor`, `GreenScreenBorderSettings`, `GreenScreenColorNear`, `widthcrop`, `heightcrop`, `dimensions`, `rotation` |
|
||||||
|
| `VideoWall` | `position` | `file`, `videoJobId`, `widthcrop`, `heightcrop`, `dimensions`, `rotation` |
|
||||||
|
| `Presentation` | `position` | `file`, `dimensions`, `rotation` |
|
||||||
|
| `Camera` | `position`, `target` | `zoom`, `rotation` |
|
||||||
|
| `Text` | `position`, `text` | `color`, `fontSize`, `fontWeight`, `dimensions`, `rotation` |
|
||||||
|
| `Custom` | `position`, `file` | `dimensions`, `rotation` |
|
||||||
|
|
||||||
|
### Common optional field (all types)
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `grabable` | `boolean` | Whether the item is interactable in-experience |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `SceneItems`
|
||||||
|
|
||||||
|
The full scene is stored as a flat map keyed by numeric ID:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type SceneItems = Record<number, SceneItem>
|
||||||
|
```
|
||||||
|
|
||||||
|
IDs are assigned sequentially when items are spawned and do not change.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `SceneStore` (Zustand)
|
||||||
|
|
||||||
|
The complete editor state. Fields marked 💾 are persisted to `localStorage` under the key `scene-storage`.
|
||||||
|
|
||||||
|
| Field | Type | Default | 💾 | Description |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `items` | `SceneItems` | `{}` | ✅ | All scene objects |
|
||||||
|
| `selected` | `number \| null` | `null` | ✅ | Currently selected item ID |
|
||||||
|
| `skyColor` | `string` | `"#ffffff"` | ✅ | Background color |
|
||||||
|
| `showGrid` | `boolean` | `true` | ✅ | Grid visibility |
|
||||||
|
| `customItems` | `CustomItem[]` | `[]` | ✅ | User-uploaded GLB assets |
|
||||||
|
| `showLights` | `boolean` | `true` | ✅ | Light helper visibility |
|
||||||
|
| `showWalls` | `boolean` | `true` | ✅ | Wall visibility |
|
||||||
|
| `showDummy` | `boolean` | `false` | ✅ | Stickman dummy visibility |
|
||||||
|
| `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 |
|
||||||
|
| `message` | `string \| null` | `null` | — | Transient toast message |
|
||||||
|
| `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 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `ITEMS_CONFIG` spawn defaults
|
||||||
|
|
||||||
|
When an item is added to the scene, it is initialized with these values from `items-config.tsx`:
|
||||||
|
|
||||||
|
| Type | `dimensions` | `color` | `rotation` | `spawnY` | `customAttributes` |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `Cube` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `0.5` | — |
|
||||||
|
| `Sphere` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `0.5` | — |
|
||||||
|
| `Cylinder` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `0.5` | — |
|
||||||
|
| `Cone` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `0.5` | — |
|
||||||
|
| `Floor` | `[10,0.1,10]` | `#ffffff` | `[0,0,0]` | `0` | — |
|
||||||
|
| `Wall` | `[20,5,0.1]` | `#ffffff` | `[0,90,0]` | `2.5` | — |
|
||||||
|
| `Point Light` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `5` | `intensity: 50, target: [0,0,0]` |
|
||||||
|
| `Directional Light` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `5` | `intensity: 20, target: [0,0,0]` |
|
||||||
|
| `Entrance` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `0.1` | — |
|
||||||
|
| `Exit` | `[1,1,1]` | `#962929` | `[0,0,0]` | `0.1` | — |
|
||||||
|
| `Billboard` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `4` | `file: "/img/default-img.png"` |
|
||||||
|
| `LiveKitStream` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `4` | `LiveKitRoomID: "Gas Station"` |
|
||||||
|
| `VideoWall` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `4` | — |
|
||||||
|
| `Presentation` | `[1,1,1]` | `#ffffff` | `[0,0,0]` | `4` | — |
|
||||||
|
| `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` | — |
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
# Database Data Structure
|
||||||
|
|
||||||
|
This document describes the JSON format saved to and loaded from the database.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Top-level: `RoomExport`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"guid": "string",
|
||||||
|
"skybox": "string | null",
|
||||||
|
"sky-color": "#rrggbb",
|
||||||
|
"jsonversion": 2.0,
|
||||||
|
"items": [ ...RoomItem ]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `guid` | `string` | Unique room identifier |
|
||||||
|
| `skybox` | `string \| null` | Skybox asset path (currently unused) |
|
||||||
|
| `sky-color` | `string` | Background hex color |
|
||||||
|
| `jsonversion` | `number` | Schema version (`2.0`) |
|
||||||
|
| `items` | `RoomItem[]` | All objects in the room |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `RoomItem`
|
||||||
|
|
||||||
|
Every item in the `items` array shares this base shape:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
|
||||||
|
"rotation": { "x": 0.0, "y": 0.0, "z": 0.0 },
|
||||||
|
"scale": { "x": 1.0, "y": 1.0, "z": 1.0 },
|
||||||
|
"type": "pre-defined | user-defined",
|
||||||
|
"resourcename": "string",
|
||||||
|
"item-custom-args": [ ...ItemArg ],
|
||||||
|
"item-custom-args-adv": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Coordinate system note:** The X-axis is flipped on save (`x` = `-creator_x`) and un-flipped on load. Y-axis rotation is also negated.
|
||||||
|
|
||||||
|
### `ItemArg`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "argument": "key", "value": "value_as_string" }
|
||||||
|
```
|
||||||
|
|
||||||
|
All values are serialized as strings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Per-type `resourcename` and custom args
|
||||||
|
|
||||||
|
### Basic shapes
|
||||||
|
|
||||||
|
| Creator type | `resourcename` | Custom args |
|
||||||
|
|---|---|---|
|
||||||
|
| `Cube` | `Cube` | `color`, `opacity` |
|
||||||
|
| `Sphere` | `Sphere` | `color` |
|
||||||
|
| `Cylinder` | `Cylinder` | `color` |
|
||||||
|
| `Cone` | `Cone` | `color` |
|
||||||
|
| `Floor` | `Plane` | `color`, `opacity` |
|
||||||
|
| `Wall` | `Wall` | `color`, `opacity` |
|
||||||
|
|
||||||
|
### Lights
|
||||||
|
|
||||||
|
| Creator type | `resourcename` | Custom args |
|
||||||
|
|---|---|---|
|
||||||
|
| `Directional Light` | `Directional Light` | `color`, `intensity`, `target` (`"x,y,z"`) |
|
||||||
|
| `Point Light` | `Point Light` | `color`, `intensity` |
|
||||||
|
|
||||||
|
### Room access
|
||||||
|
|
||||||
|
| Creator type | `resourcename` | Custom args |
|
||||||
|
|---|---|---|
|
||||||
|
| `Entrance` | `Entrance` | _(none)_ |
|
||||||
|
| `Exit` | _(not implemented in save)_ | — |
|
||||||
|
|
||||||
|
### Streaming / media
|
||||||
|
|
||||||
|
| Creator type | `resourcename` | Custom args |
|
||||||
|
|---|---|---|
|
||||||
|
| `Billboard` | `Billboard` | `url` (file path) |
|
||||||
|
| `LiveKitStream` | `LiveKitStream` | `LiveKitRoomID`, `shader`, `GreenScreenColor`, `GreenScreenBorderSettings`, `GreenScreenColorNear`, `widthcrop`, `heightcrop` |
|
||||||
|
| `VideoWall` | `VideoWall` | `file`, `widthcrop`, `heightcrop` |
|
||||||
|
| `Presentation` | `Presentation` | `file` |
|
||||||
|
| `Camera` | `CCTVCamera` | `target` (`"x,y,z"`), `fov` (derived: `zoom * 60`) |
|
||||||
|
|
||||||
|
### Other
|
||||||
|
|
||||||
|
| Creator type | `resourcename` | `type` field | Custom args |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Text` | `Text` | `pre-defined` | `text`, `color`, `fontSize`, `fontWeight` |
|
||||||
|
| `Custom` | _(the asset filename)_ | `user-defined` | `file` |
|
||||||
|
|
||||||
|
### Common optional arg (all types)
|
||||||
|
|
||||||
|
| Arg | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `grabable` | `"true" \| "false"` | Whether the item can be grabbed in-experience |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example — Directional Light
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"position": { "x": 0, "y": 5, "z": 0 },
|
||||||
|
"rotation": { "x": 0, "y": 0, "z": 0 },
|
||||||
|
"scale": { "x": 1, "y": 1, "z": 1 },
|
||||||
|
"type": "pre-defined",
|
||||||
|
"resourcename": "Directional Light",
|
||||||
|
"item-custom-args": [
|
||||||
|
{ "argument": "color", "value": "#ffffff" },
|
||||||
|
{ "argument": "intensity", "value": "20" },
|
||||||
|
{ "argument": "target", "value": "0,0,0" }
|
||||||
|
],
|
||||||
|
"item-custom-args-adv": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example — CCTV Camera
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"position": { "x": 0, "y": 4, "z": 0 },
|
||||||
|
"rotation": { "x": 0, "y": 0, "z": 0 },
|
||||||
|
"scale": { "x": 1, "y": 1, "z": 1 },
|
||||||
|
"type": "pre-defined",
|
||||||
|
"resourcename": "CCTVCamera",
|
||||||
|
"item-custom-args": [
|
||||||
|
{ "argument": "target", "value": "0,0,0" },
|
||||||
|
{ "argument": "fov", "value": "60" }
|
||||||
|
],
|
||||||
|
"item-custom-args-adv": null
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user