react-three-game 0.0.70 → 0.0.71
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/index.d.ts +10 -5
- package/dist/index.js +7 -2
- package/dist/tools/prefabeditor/EditorTree.js +2 -12
- package/dist/tools/prefabeditor/EditorTreeMenus.js +1 -19
- package/dist/tools/prefabeditor/EditorUI.js +2 -1
- package/dist/tools/prefabeditor/PrefabEditor.d.ts +1 -1
- package/dist/tools/prefabeditor/PrefabEditor.js +12 -21
- package/dist/tools/prefabeditor/PrefabRoot.d.ts +25 -12
- package/dist/tools/prefabeditor/PrefabRoot.js +61 -28
- package/dist/tools/prefabeditor/RefBridge.d.ts +24 -0
- package/dist/tools/prefabeditor/RefBridge.js +44 -0
- package/dist/tools/prefabeditor/components/AmbientLightComponent.js +10 -7
- package/dist/tools/prefabeditor/components/CameraComponent.js +8 -14
- package/dist/tools/prefabeditor/components/ClickComponent.js +2 -0
- package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +21 -1
- package/dist/tools/prefabeditor/components/DirectionalLightComponent.js +124 -52
- package/dist/tools/prefabeditor/components/EnvironmentComponent.js +5 -3
- package/dist/tools/prefabeditor/components/MaterialComponent.js +9 -6
- package/dist/tools/prefabeditor/components/ModelComponent.js +4 -2
- package/dist/tools/prefabeditor/components/PhysicsComponent.js +5 -3
- package/dist/tools/prefabeditor/components/PointLightComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/PointLightComponent.js +55 -0
- package/dist/tools/prefabeditor/components/SoundComponent.js +20 -16
- package/dist/tools/prefabeditor/components/SpotLightComponent.js +48 -24
- package/dist/tools/prefabeditor/components/index.js +2 -0
- package/dist/tools/prefabeditor/components/lightUtils.d.ts +13 -0
- package/dist/tools/prefabeditor/components/lightUtils.js +64 -0
- package/dist/tools/prefabeditor/prefab.d.ts +37 -0
- package/dist/tools/prefabeditor/prefab.js +229 -0
- package/dist/tools/prefabeditor/prefabStore.d.ts +3 -16
- package/dist/tools/prefabeditor/prefabStore.js +29 -168
- package/dist/tools/prefabeditor/{sceneApi.js → scene.js} +3 -14
- package/dist/tools/prefabeditor/utils.d.ts +0 -4
- package/dist/tools/prefabeditor/utils.js +0 -37
- package/package.json +1 -1
- /package/dist/tools/prefabeditor/{sceneApi.d.ts → scene.d.ts} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -10,20 +10,25 @@ export { useEditorContext } from './tools/prefabeditor/PrefabEditor';
|
|
|
10
10
|
export type { EditorContextType } from './tools/prefabeditor/PrefabEditor';
|
|
11
11
|
export { createPrefabStore, prefabStoreToPrefab, usePrefabStoreApi } from './tools/prefabeditor/prefabStore';
|
|
12
12
|
export type { PrefabStoreApi, PrefabStoreState } from './tools/prefabeditor/prefabStore';
|
|
13
|
-
export { createScene } from './tools/prefabeditor/
|
|
13
|
+
export { createScene } from './tools/prefabeditor/scene';
|
|
14
|
+
export { denormalizePrefab } from './tools/prefabeditor/prefab';
|
|
14
15
|
export { registerComponent } from './tools/prefabeditor/components/ComponentRegistry';
|
|
15
16
|
export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from './tools/prefabeditor/components/Input';
|
|
16
|
-
export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix,
|
|
17
|
+
export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from './tools/prefabeditor/utils';
|
|
17
18
|
export type { ExportGLBOptions } from './tools/prefabeditor/utils';
|
|
19
|
+
export { createModelNode, createImageNode, } from './tools/prefabeditor/prefab';
|
|
18
20
|
export type { PrefabEditorProps, PrefabEditorRef, } from './tools/prefabeditor/PrefabEditor';
|
|
19
|
-
export type { SpawnOptions, Scene, Entity, EntityComponent, EntityData, EntityUpdate, PropertyPath, SceneUpdates, } from './tools/prefabeditor/
|
|
20
|
-
export type { PrefabRootProps, PrefabRootRef } from './tools/prefabeditor/PrefabRoot';
|
|
21
|
-
export
|
|
21
|
+
export type { SpawnOptions, Scene, Entity, EntityComponent, EntityData, EntityUpdate, PropertyPath, SceneUpdates, } from './tools/prefabeditor/scene';
|
|
22
|
+
export type { PrefabRootProps, PrefabRootRef, SceneRuntime } from './tools/prefabeditor/PrefabRoot';
|
|
23
|
+
export { useSceneRuntime } from './tools/prefabeditor/PrefabRoot';
|
|
24
|
+
export type { Component, ComponentViewProps } from './tools/prefabeditor/components/ComponentRegistry';
|
|
22
25
|
export type { FieldDefinition, FieldType } from './tools/prefabeditor/components/Input';
|
|
23
26
|
export type { Prefab, GameObject, ComponentData } from './tools/prefabeditor/types';
|
|
24
27
|
export { findComponent, findComponentEntry, hasComponent } from './tools/prefabeditor/types';
|
|
25
28
|
export { gameEvents, useGameEvent, getEntityIdFromRigidBody } from './tools/prefabeditor/GameEvents';
|
|
26
29
|
export type { GameEventType, GameEventMap, GameEventPayload, PhysicsEventType, InteractionEventType, PhysicsEventPayload, ClickEventPayload } from './tools/prefabeditor/GameEvents';
|
|
30
|
+
export { createRefBridge } from './tools/prefabeditor/RefBridge';
|
|
31
|
+
export type { RefBridge } from './tools/prefabeditor/RefBridge';
|
|
27
32
|
export { loadFiles } from './tools/dragdrop/DragDropLoader';
|
|
28
33
|
export type { AssetLoadOptions } from './tools/dragdrop/DragDropLoader';
|
|
29
34
|
export { loadModel, loadSound, loadTexture } from './tools/dragdrop/modelLoader';
|
package/dist/index.js
CHANGED
|
@@ -10,16 +10,21 @@ export { default as PrefabRoot } from './tools/prefabeditor/PrefabRoot';
|
|
|
10
10
|
export { useEditorContext } from './tools/prefabeditor/PrefabEditor';
|
|
11
11
|
// Prefab Editor - Store & Scene API
|
|
12
12
|
export { createPrefabStore, prefabStoreToPrefab, usePrefabStoreApi } from './tools/prefabeditor/prefabStore';
|
|
13
|
-
export { createScene } from './tools/prefabeditor/
|
|
13
|
+
export { createScene } from './tools/prefabeditor/scene';
|
|
14
|
+
export { denormalizePrefab } from './tools/prefabeditor/prefab';
|
|
14
15
|
// Prefab Editor - Component Registry
|
|
15
16
|
export { registerComponent } from './tools/prefabeditor/components/ComponentRegistry';
|
|
16
17
|
// Prefab Editor - Input Components
|
|
17
18
|
export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from './tools/prefabeditor/components/Input';
|
|
18
19
|
// Prefab Editor - Utils
|
|
19
|
-
export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix,
|
|
20
|
+
export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from './tools/prefabeditor/utils';
|
|
21
|
+
export { createModelNode, createImageNode, } from './tools/prefabeditor/prefab';
|
|
22
|
+
export { useSceneRuntime } from './tools/prefabeditor/PrefabRoot';
|
|
20
23
|
export { findComponent, findComponentEntry, hasComponent } from './tools/prefabeditor/types';
|
|
21
24
|
// Game Events (physics + custom events)
|
|
22
25
|
export { gameEvents, useGameEvent, getEntityIdFromRigidBody } from './tools/prefabeditor/GameEvents';
|
|
26
|
+
// RefBridge & Systems
|
|
27
|
+
export { createRefBridge } from './tools/prefabeditor/RefBridge';
|
|
23
28
|
// Asset Loading
|
|
24
29
|
export { loadFiles } from './tools/dragdrop/DragDropLoader';
|
|
25
30
|
export { loadModel, loadSound, loadTexture } from './tools/dragdrop/modelLoader';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useCallback, useState } from 'react';
|
|
3
|
-
import { getComponentDef } from './components/ComponentRegistry';
|
|
4
3
|
import { base, colors, tree } from './styles';
|
|
5
4
|
import { useEditorContext } from './PrefabEditor';
|
|
6
5
|
import { Dropdown } from './Dropdown';
|
|
7
6
|
import { FileMenu, TreeContextMenu, TreeNodeMenu } from './EditorTreeMenus';
|
|
7
|
+
import { createEmptyNode } from './prefab';
|
|
8
8
|
import { usePrefabChildIds, usePrefabNode, usePrefabRootId, usePrefabStore, usePrefabStoreApi } from './prefabStore';
|
|
9
9
|
export default function EditorTree({ selectedId, setSelectedId, getPrefab, onReplacePrefab, onImportPrefab, onUndo, onRedo, canUndo, canRedo }) {
|
|
10
10
|
const { onFocusNode } = useEditorContext();
|
|
@@ -30,17 +30,7 @@ export default function EditorTree({ selectedId, setSelectedId, getPrefab, onRep
|
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
32
|
const handleAddChild = (parentId) => {
|
|
33
|
-
|
|
34
|
-
const newNode = {
|
|
35
|
-
id: crypto.randomUUID(),
|
|
36
|
-
name: "New Node",
|
|
37
|
-
components: {
|
|
38
|
-
transform: {
|
|
39
|
-
type: "Transform",
|
|
40
|
-
properties: Object.assign({}, (_a = getComponentDef('Transform')) === null || _a === void 0 ? void 0 : _a.defaultProperties)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
};
|
|
33
|
+
const newNode = createEmptyNode();
|
|
44
34
|
addChild(parentId, newNode);
|
|
45
35
|
setSelectedId(newNode.id);
|
|
46
36
|
};
|
|
@@ -10,28 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { useEffect, useRef, useState } from 'react';
|
|
12
12
|
import { createPortal } from 'react-dom';
|
|
13
|
+
import { createEmptyPrefab } from './prefab';
|
|
13
14
|
import { menu } from './styles';
|
|
14
15
|
import { useEditorContext } from './PrefabEditor';
|
|
15
|
-
import { getComponentDef } from './components/ComponentRegistry';
|
|
16
16
|
import { loadJson, saveJson } from './utils';
|
|
17
|
-
function createEmptyPrefab() {
|
|
18
|
-
var _a;
|
|
19
|
-
return {
|
|
20
|
-
id: crypto.randomUUID(),
|
|
21
|
-
name: 'New Prefab',
|
|
22
|
-
root: {
|
|
23
|
-
id: crypto.randomUUID(),
|
|
24
|
-
name: 'Root',
|
|
25
|
-
components: {
|
|
26
|
-
transform: {
|
|
27
|
-
type: 'Transform',
|
|
28
|
-
properties: Object.assign({}, (_a = getComponentDef('Transform')) === null || _a === void 0 ? void 0 : _a.defaultProperties)
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
children: []
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
17
|
function MenuPanel({ children, style, }) {
|
|
36
18
|
return (_jsx("div", { style: Object.assign(Object.assign(Object.assign({}, menu.container), { position: 'static' }), style), onClick: (e) => e.stopPropagation(), children: children }));
|
|
37
19
|
}
|
|
@@ -14,6 +14,7 @@ import { useState } from 'react';
|
|
|
14
14
|
import { hasComponent } from "./types";
|
|
15
15
|
import EditorTree from './EditorTree';
|
|
16
16
|
import { getAllComponentDefs } from './components/ComponentRegistry';
|
|
17
|
+
import { createComponentData } from './prefab';
|
|
17
18
|
import { base, colors, inspector, componentCard } from './styles';
|
|
18
19
|
import { usePrefabStore } from './prefabStore';
|
|
19
20
|
function EditorUI({ selectedId, setSelectedId, getPrefab, onReplacePrefab, onImportPrefab, basePath, onUndo, onRedo, canUndo, canRedo }) {
|
|
@@ -58,7 +59,7 @@ function NodeInspector({ node, updateNode, deleteNode, basePath }) {
|
|
|
58
59
|
return;
|
|
59
60
|
const def = ALL_COMPONENTS[addType];
|
|
60
61
|
if (def) {
|
|
61
|
-
updateNode(n => (Object.assign(Object.assign({}, n), { components: Object.assign(Object.assign({}, n.components), { [addType.toLowerCase()]:
|
|
62
|
+
updateNode(n => (Object.assign(Object.assign({}, n), { components: Object.assign(Object.assign({}, n.components), { [addType.toLowerCase()]: createComponentData(def.name) }) })));
|
|
62
63
|
}
|
|
63
64
|
}, title: "Add Component", children: "+" })] }) }))] });
|
|
64
65
|
}
|
|
@@ -3,7 +3,7 @@ import { Object3D, Texture } from "three";
|
|
|
3
3
|
import { GameObject, Prefab } from "./types";
|
|
4
4
|
import { PrefabRootRef } from "./PrefabRoot";
|
|
5
5
|
import type { ExportGLBOptions } from "./utils";
|
|
6
|
-
import { type Scene, type SpawnOptions } from "./
|
|
6
|
+
import { type Scene, type SpawnOptions } from "./scene";
|
|
7
7
|
export interface PrefabEditorRef {
|
|
8
8
|
screenshot: () => void;
|
|
9
9
|
exportGLB: (options?: ExportGLBOptions) => Promise<ArrayBuffer | undefined>;
|
|
@@ -16,10 +16,11 @@ import PrefabRoot from "./PrefabRoot";
|
|
|
16
16
|
import { Physics } from "@react-three/rapier";
|
|
17
17
|
import EditorUI from "./EditorUI";
|
|
18
18
|
import { base, toolbar } from "./styles";
|
|
19
|
-
import {
|
|
19
|
+
import { computeParentWorldMatrix, decompose, exportGLB as exportGLBFile, exportGLBData, focusCameraOnObject, regenerateIds } from "./utils";
|
|
20
20
|
import { loadFiles } from "../dragdrop";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
21
|
+
import { denormalizePrefab, createImageNode, createModelNode, createNode } from './prefab';
|
|
22
|
+
import { createPrefabStore, PrefabStoreProvider } from "./prefabStore";
|
|
23
|
+
import { createScene } from "./scene";
|
|
23
24
|
export var PrefabEditorMode;
|
|
24
25
|
(function (PrefabEditorMode) {
|
|
25
26
|
PrefabEditorMode["Edit"] = "edit";
|
|
@@ -38,15 +39,7 @@ const HISTORY_DEBOUNCE_MS = 500;
|
|
|
38
39
|
const DEFAULT_PREFAB = {
|
|
39
40
|
id: "prefab-default",
|
|
40
41
|
name: "New Prefab",
|
|
41
|
-
root: {
|
|
42
|
-
id: "root",
|
|
43
|
-
components: {
|
|
44
|
-
transform: {
|
|
45
|
-
type: "Transform",
|
|
46
|
-
properties: { position: [0, 0, 0], rotation: [0, 0, 0], scale: [1, 1, 1] }
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
42
|
+
root: createNode('Root', {}, { id: 'root' })
|
|
50
43
|
};
|
|
51
44
|
const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode: initialMode = PrefabEditorMode.Edit, onChange, showUI = true, enableWindowDrop = true, canvasProps, uiPlugins, children }, ref) => {
|
|
52
45
|
const [mode, setMode] = useState(initialMode);
|
|
@@ -66,10 +59,8 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
66
59
|
const canvasRef = useRef(null);
|
|
67
60
|
const controlsRef = useRef(null);
|
|
68
61
|
const onChangeRef = useRef(onChange);
|
|
69
|
-
const [injectedModels, setInjectedModels] = useState({});
|
|
70
|
-
const [injectedTextures, setInjectedTextures] = useState({});
|
|
71
62
|
const isEditMode = mode === PrefabEditorMode.Edit;
|
|
72
|
-
const getPrefab = useCallback(() =>
|
|
63
|
+
const getPrefab = useCallback(() => denormalizePrefab(prefabStore.getState()), [prefabStore]);
|
|
73
64
|
onChangeRef.current = onChange;
|
|
74
65
|
const setSelection = useCallback((nodeId) => {
|
|
75
66
|
const nextNode = nodeId ? prefabStore.getState().nodesById[nodeId] : null;
|
|
@@ -101,8 +92,6 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
101
92
|
setSelectedObject(null);
|
|
102
93
|
if (options === null || options === void 0 ? void 0 : options.resetHistory) {
|
|
103
94
|
setSelectedId(null);
|
|
104
|
-
setInjectedModels({});
|
|
105
|
-
setInjectedTextures({});
|
|
106
95
|
setHistory([prefab]);
|
|
107
96
|
historyIndexRef.current = 0;
|
|
108
97
|
setHistoryIndex(0);
|
|
@@ -124,7 +113,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
124
113
|
return;
|
|
125
114
|
}
|
|
126
115
|
lastRevision = state.revision;
|
|
127
|
-
const nextPrefab =
|
|
116
|
+
const nextPrefab = denormalizePrefab(state);
|
|
128
117
|
const changeOrigin = changeOriginRef.current;
|
|
129
118
|
if (changeOrigin !== "replace-silent") {
|
|
130
119
|
(_a = onChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onChangeRef, nextPrefab);
|
|
@@ -188,15 +177,17 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
188
177
|
addNode(regenerateIds(prefab.root), { select: false });
|
|
189
178
|
}, [addNode]);
|
|
190
179
|
const addModel = useCallback((path, model, options) => {
|
|
180
|
+
var _a;
|
|
191
181
|
const node = createModelNode(path, options === null || options === void 0 ? void 0 : options.name);
|
|
192
182
|
addNode(node, options);
|
|
193
|
-
|
|
183
|
+
(_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.addModel(path, model);
|
|
194
184
|
return node;
|
|
195
185
|
}, [addNode]);
|
|
196
186
|
const addTexture = useCallback((path, texture, options) => {
|
|
187
|
+
var _a;
|
|
197
188
|
const node = createImageNode(path, options === null || options === void 0 ? void 0 : options.name);
|
|
198
189
|
addNode(node, options);
|
|
199
|
-
|
|
190
|
+
(_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.addTexture(path, texture);
|
|
200
191
|
return node;
|
|
201
192
|
}, [addNode]);
|
|
202
193
|
const applyHistory = (index) => {
|
|
@@ -361,7 +352,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
|
|
|
361
352
|
addTexture,
|
|
362
353
|
viewRef: prefabRootRef
|
|
363
354
|
}), [addModel, addTexture, clearSelection, getPrefab, handleExportGLB, handleExportGLBData, handleScreenshot, loadPrefab, scene]);
|
|
364
|
-
const content = (_jsxs(_Fragment, { children: [_jsx("
|
|
355
|
+
const content = (_jsxs(_Fragment, { children: [_jsx("gridHelper", { args: [10, 10], position: [0, -1, 0] }), _jsx(PrefabRoot, { ref: prefabRootRef, store: prefabStore, editMode: isEditMode, selectedId: selectedId, onSelect: setSelection, basePath: basePath }), children] }));
|
|
365
356
|
return _jsx(PrefabStoreProvider, { store: prefabStore, children: _jsxs(EditorContext.Provider, { value: {
|
|
366
357
|
mode,
|
|
367
358
|
setMode: updateMode,
|
|
@@ -1,14 +1,36 @@
|
|
|
1
|
-
import { Group, Matrix4, Object3D } from "three";
|
|
1
|
+
import { Group, Matrix4, Object3D, Texture } from "three";
|
|
2
2
|
import { ThreeEvent } from "@react-three/fiber";
|
|
3
3
|
import { GameObject as GameObjectType, Prefab } from "./types";
|
|
4
|
-
import { LoadedModels
|
|
4
|
+
import { LoadedModels } from "../dragdrop";
|
|
5
5
|
import { PrefabStoreApi } from "./prefabStore";
|
|
6
|
+
import { type RefBridge } from "./RefBridge";
|
|
7
|
+
/** Runtime context available to all component Views inside a PrefabRoot. */
|
|
8
|
+
export interface SceneRuntime {
|
|
9
|
+
refBridge: RefBridge;
|
|
10
|
+
getRigidBody: (id: string) => any;
|
|
11
|
+
/** @internal Used by PhysicsComponent. */
|
|
12
|
+
registerRigidBodyRef: (id: string, rb: any) => void;
|
|
13
|
+
editMode?: boolean;
|
|
14
|
+
/** Get a loaded model by asset path. */
|
|
15
|
+
getModel: (path: string) => Object3D | null;
|
|
16
|
+
/** Get a loaded texture by asset path. */
|
|
17
|
+
getTexture: (path: string) => Texture | null;
|
|
18
|
+
/** Get a loaded sound buffer by asset path. */
|
|
19
|
+
getSound: (path: string) => AudioBuffer | null;
|
|
20
|
+
/** Get a revision string that changes when loaded assets change (for cache-busting keys). */
|
|
21
|
+
getAssetRevision: () => string;
|
|
22
|
+
}
|
|
23
|
+
/** Access the scene runtime (refBridge, getRigidBody, editMode) from within a component View. */
|
|
24
|
+
export declare function useSceneRuntime(): SceneRuntime;
|
|
6
25
|
export interface PrefabRootRef {
|
|
7
26
|
root: Group | null;
|
|
27
|
+
refBridge: RefBridge;
|
|
8
28
|
rigidBodyRefs: Map<string, any>;
|
|
9
29
|
getObject: (nodeId: string) => Object3D | null;
|
|
10
30
|
getRigidBody: (nodeId: string) => any;
|
|
11
|
-
|
|
31
|
+
addModel: (path: string, model: Object3D) => void;
|
|
32
|
+
addTexture: (path: string, texture: Texture) => void;
|
|
33
|
+
addSound: (path: string, sound: AudioBuffer) => void;
|
|
12
34
|
}
|
|
13
35
|
export interface PrefabRootProps {
|
|
14
36
|
editMode?: boolean;
|
|
@@ -17,12 +39,7 @@ export interface PrefabRootProps {
|
|
|
17
39
|
selectedId?: string | null;
|
|
18
40
|
onSelect?: (id: string | null) => void;
|
|
19
41
|
onClick?: (event: ThreeEvent<PointerEvent>, entity: GameObjectType) => void;
|
|
20
|
-
onSelectedObjectChange?: (object: Object3D | null) => void;
|
|
21
|
-
onFocusNode?: (nodeId: string) => void;
|
|
22
42
|
basePath?: string;
|
|
23
|
-
injectedModels?: LoadedModels;
|
|
24
|
-
injectedTextures?: LoadedTextures;
|
|
25
|
-
injectedSounds?: LoadedSounds;
|
|
26
43
|
}
|
|
27
44
|
export declare const PrefabRoot: import("react").ForwardRefExoticComponent<PrefabRootProps & import("react").RefAttributes<PrefabRootRef>>;
|
|
28
45
|
export declare function GameObjectRenderer(props: RendererProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -32,11 +49,7 @@ interface RendererProps {
|
|
|
32
49
|
onSelect?: (id: string) => void;
|
|
33
50
|
onClick?: (event: ThreeEvent<PointerEvent>, entity: GameObjectType) => void;
|
|
34
51
|
registerRef: (id: string, obj: Object3D | null) => void;
|
|
35
|
-
registerRigidBodyRef: (id: string, rb: any) => void;
|
|
36
|
-
getRigidBody: (id: string) => any;
|
|
37
52
|
loadedModels: LoadedModels;
|
|
38
|
-
loadedSounds: LoadedSounds;
|
|
39
|
-
loadedTextures: LoadedTextures;
|
|
40
53
|
editMode?: boolean;
|
|
41
54
|
parentMatrix?: Matrix4;
|
|
42
55
|
}
|
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { useHelper } from "@react-three/drei";
|
|
14
|
-
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
14
|
+
import { forwardRef, createContext, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
15
15
|
import { BoxHelper, Euler, Matrix4, } from "three";
|
|
16
16
|
import { useStore } from "zustand";
|
|
17
17
|
import { useClickValid } from "./useClickValid";
|
|
@@ -22,13 +22,23 @@ import { loadModel, loadSound, loadTexture } from "../dragdrop";
|
|
|
22
22
|
import { GameInstance, GameInstanceProvider, getRepeatAxesFromModelProperties, useInstanceCheck } from "./InstanceProvider";
|
|
23
23
|
import { composeTransform, decompose } from "./utils";
|
|
24
24
|
import { isPhysicsProps } from "./components/PhysicsComponent";
|
|
25
|
-
import {
|
|
25
|
+
import { denormalizePrefab } from "./prefab";
|
|
26
|
+
import { createPrefabStore, PrefabStoreProvider, useOptionalPrefabStoreApi, usePrefabChildIds, usePrefabNode, usePrefabRootId } from "./prefabStore";
|
|
27
|
+
import { createRefBridge } from "./RefBridge";
|
|
26
28
|
import { sound as soundManager } from "../../helpers/SoundManager";
|
|
27
29
|
components.forEach(registerComponent);
|
|
28
30
|
const IDENTITY = new Matrix4();
|
|
29
31
|
const EMPTY_MODELS = {};
|
|
30
32
|
const EMPTY_TEXTURES = {};
|
|
31
33
|
const EMPTY_SOUNDS = {};
|
|
34
|
+
const SceneRuntimeContext = createContext(null);
|
|
35
|
+
/** Access the scene runtime (refBridge, getRigidBody, editMode) from within a component View. */
|
|
36
|
+
export function useSceneRuntime() {
|
|
37
|
+
const ctx = useContext(SceneRuntimeContext);
|
|
38
|
+
if (!ctx)
|
|
39
|
+
throw new Error("useSceneRuntime must be used inside <PrefabRoot>");
|
|
40
|
+
return ctx;
|
|
41
|
+
}
|
|
32
42
|
/** Resolve a relative or absolute asset file path against a base path. */
|
|
33
43
|
function resolveAssetPath(basePath, file) {
|
|
34
44
|
if (file.startsWith("http://") || file.startsWith("https://"))
|
|
@@ -43,11 +53,14 @@ function isNodeReady(node, loadedModels) {
|
|
|
43
53
|
return true;
|
|
44
54
|
return Boolean(loadedModels[model.properties.filename]);
|
|
45
55
|
}
|
|
46
|
-
export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick,
|
|
56
|
+
export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick, basePath = "" }, ref) => {
|
|
47
57
|
var _a;
|
|
48
58
|
const [models, setModels] = useState({});
|
|
49
59
|
const [textures, setTextures] = useState({});
|
|
50
60
|
const [sounds, setSounds] = useState({});
|
|
61
|
+
const [injectedModels, setInjectedModels] = useState(EMPTY_MODELS);
|
|
62
|
+
const [injectedTextures, setInjectedTextures] = useState(EMPTY_TEXTURES);
|
|
63
|
+
const [injectedSounds, setInjectedSounds] = useState(EMPTY_SOUNDS);
|
|
51
64
|
const loading = useRef(new Set());
|
|
52
65
|
const failedModels = useRef(new Set());
|
|
53
66
|
const failedTextures = useRef(new Set());
|
|
@@ -55,8 +68,9 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
55
68
|
const objectRefs = useRef({});
|
|
56
69
|
const rigidBodyRefs = useRef(new Map());
|
|
57
70
|
const rootRef = useRef(null);
|
|
71
|
+
const [refBridge] = useState(() => createRefBridge());
|
|
58
72
|
const parentStore = useOptionalPrefabStoreApi();
|
|
59
|
-
const [ownedStore] = useState(() => { var _a, _b; return createPrefabStore(data !== null && data !== void 0 ? data :
|
|
73
|
+
const [ownedStore] = useState(() => { var _a, _b; return createPrefabStore(data !== null && data !== void 0 ? data : denormalizePrefab((_b = (_a = store === null || store === void 0 ? void 0 : store.getState()) !== null && _a !== void 0 ? _a : parentStore === null || parentStore === void 0 ? void 0 : parentStore.getState()) !== null && _b !== void 0 ? _b : missingStoreState())); });
|
|
60
74
|
const resolvedStore = (_a = store !== null && store !== void 0 ? store : parentStore) !== null && _a !== void 0 ? _a : ownedStore;
|
|
61
75
|
const usesOwnedStore = resolvedStore === ownedStore;
|
|
62
76
|
const shouldProvideStoreContext = !parentStore || parentStore !== resolvedStore;
|
|
@@ -66,17 +80,21 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
66
80
|
const availableSounds = useMemo(() => (Object.assign(Object.assign({}, sounds), injectedSounds)), [sounds, injectedSounds]);
|
|
67
81
|
useImperativeHandle(ref, () => ({
|
|
68
82
|
root: rootRef.current,
|
|
83
|
+
refBridge,
|
|
69
84
|
rigidBodyRefs: rigidBodyRefs.current,
|
|
70
85
|
getObject: (nodeId) => { var _a; return (_a = objectRefs.current[nodeId]) !== null && _a !== void 0 ? _a : null; },
|
|
71
86
|
getRigidBody: (nodeId) => { var _a; return (_a = rigidBodyRefs.current.get(nodeId)) !== null && _a !== void 0 ? _a : null; },
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
addModel: (path, model) => setInjectedModels(prev => (Object.assign(Object.assign({}, prev), { [path]: model }))),
|
|
88
|
+
addTexture: (path, texture) => setInjectedTextures(prev => (Object.assign(Object.assign({}, prev), { [path]: texture }))),
|
|
89
|
+
addSound: (path, sound) => {
|
|
90
|
+
soundManager.setBuffer(path, sound);
|
|
91
|
+
setInjectedSounds(prev => (Object.assign(Object.assign({}, prev), { [path]: sound })));
|
|
92
|
+
},
|
|
93
|
+
}), [refBridge]);
|
|
74
94
|
const registerRef = useCallback((id, obj) => {
|
|
75
95
|
objectRefs.current[id] = obj;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
}, [onSelectedObjectChange, selectedId]);
|
|
96
|
+
refBridge.register(id, obj);
|
|
97
|
+
}, [refBridge]);
|
|
80
98
|
const registerRigidBodyRef = useCallback((id, rb) => {
|
|
81
99
|
rigidBodyRefs.current.set(id, rb);
|
|
82
100
|
}, []);
|
|
@@ -155,11 +173,32 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
155
173
|
};
|
|
156
174
|
syncAssets();
|
|
157
175
|
}, [resolvedStore, assetManifestKey, basePath, injectedModels, injectedSounds, injectedTextures, models, sounds, textures]);
|
|
158
|
-
|
|
176
|
+
// Keep refs current so context getters are always fresh without changing context identity
|
|
177
|
+
const availableModelsRef = useRef(availableModels);
|
|
178
|
+
availableModelsRef.current = availableModels;
|
|
179
|
+
const availableTexturesRef = useRef(availableTextures);
|
|
180
|
+
availableTexturesRef.current = availableTextures;
|
|
181
|
+
const availableSoundsRef = useRef(availableSounds);
|
|
182
|
+
availableSoundsRef.current = availableSounds;
|
|
183
|
+
const sceneRuntime = useMemo(() => ({
|
|
184
|
+
refBridge,
|
|
185
|
+
getRigidBody,
|
|
186
|
+
registerRigidBodyRef,
|
|
187
|
+
editMode,
|
|
188
|
+
getModel: (path) => { var _a; return (_a = availableModelsRef.current[path]) !== null && _a !== void 0 ? _a : null; },
|
|
189
|
+
getTexture: (path) => { var _a; return (_a = availableTexturesRef.current[path]) !== null && _a !== void 0 ? _a : null; },
|
|
190
|
+
getSound: (path) => { var _a; return (_a = availableSoundsRef.current[path]) !== null && _a !== void 0 ? _a : null; },
|
|
191
|
+
getAssetRevision: () => {
|
|
192
|
+
const modelKeys = Object.keys(availableModelsRef.current).sort().join('|');
|
|
193
|
+
const textureKeys = Object.keys(availableTexturesRef.current).sort().join('|');
|
|
194
|
+
return `${textureKeys}::${modelKeys}`;
|
|
195
|
+
},
|
|
196
|
+
}), [refBridge, getRigidBody, registerRigidBodyRef, editMode]);
|
|
197
|
+
const content = (_jsx("group", { ref: rootRef, children: _jsx(GameInstanceProvider, { models: availableModels, selectedId: selectedId, editMode: editMode, onSelect: editMode ? onSelect : undefined, registerRef: registerRef, children: _jsx(StoreRootNode, { selectedId: selectedId, onSelect: editMode ? onSelect : undefined, onClick: onClick, registerRef: registerRef, loadedModels: availableModels, editMode: editMode, parentMatrix: IDENTITY }) }) }));
|
|
159
198
|
if (!shouldProvideStoreContext) {
|
|
160
|
-
return content;
|
|
199
|
+
return _jsx(SceneRuntimeContext.Provider, { value: sceneRuntime, children: content });
|
|
161
200
|
}
|
|
162
|
-
return _jsx(PrefabStoreProvider, { store: resolvedStore, children: content });
|
|
201
|
+
return _jsx(PrefabStoreProvider, { store: resolvedStore, children: _jsx(SceneRuntimeContext.Provider, { value: sceneRuntime, children: content }) });
|
|
163
202
|
});
|
|
164
203
|
function StoreRootNode(props) {
|
|
165
204
|
const rootId = usePrefabRootId();
|
|
@@ -218,7 +257,7 @@ function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef,
|
|
|
218
257
|
}
|
|
219
258
|
return (_jsx(_Fragment, { children: instances.map(instance => (_jsx(GameInstance, { id: instance.id, sourceId: gameObject.id, clickable: clickable, clickEventName: clickEventName, modelUrl: instance.modelUrl, position: instance.position, rotation: instance.rotation, scale: instance.scale, locked: isLocked, physics: instance.physics }, instance.id))) }));
|
|
220
259
|
}
|
|
221
|
-
function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef,
|
|
260
|
+
function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, loadedModels, editMode, parentMatrix = IDENTITY, }) {
|
|
222
261
|
var _a, _b;
|
|
223
262
|
const gameObject = usePrefabNode(nodeId);
|
|
224
263
|
const childIds = usePrefabChildIds(nodeId);
|
|
@@ -246,16 +285,16 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, regi
|
|
|
246
285
|
const physicsDef = hasPhysics ? getComponentDef(physics.type) : null;
|
|
247
286
|
const isInstanced = (_b = (_a = findComponent(gameObject, "Model")) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.instanced;
|
|
248
287
|
const physicsKey = `physics_${nodeId}_${isInstanced ? 'instanced' : 'standard'}`;
|
|
249
|
-
const renderCtx = { loadedModels,
|
|
288
|
+
const renderCtx = { loadedModels, editMode, registerRef };
|
|
250
289
|
const childNodes = getChildHostComponents(gameObject).length > 0
|
|
251
290
|
? _jsx(CompositionChildren, { childIds: childIds, selectedId: selectedId, ctx: renderCtx, parentMatrix: world })
|
|
252
|
-
: _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef,
|
|
291
|
+
: _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
|
|
253
292
|
const inner = (_jsx("group", Object.assign({}, clickHandlers, { children: renderCompositionNode(gameObject, renderCtx, isSelected, parentMatrix, childNodes) })));
|
|
254
293
|
if (editMode) {
|
|
255
|
-
return (_jsxs(_Fragment, { children: [_jsx("group", { ref: groupRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: _jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) }) }), _jsx("group", { ref: helperRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: inner }), hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, { properties: physics.properties, position: transform.position, rotation: transform.rotation, scale: transform.scale, editMode: editMode, nodeId: nodeId,
|
|
294
|
+
return (_jsxs(_Fragment, { children: [_jsx("group", { ref: groupRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: _jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) }) }), _jsx("group", { ref: helperRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: inner }), hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, { properties: physics.properties, position: transform.position, rotation: transform.rotation, scale: transform.scale, editMode: editMode, nodeId: nodeId, children: inner }, physicsKey)) : null] }));
|
|
256
295
|
}
|
|
257
296
|
if (hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View)) {
|
|
258
|
-
return (_jsx(physicsDef.View, { properties: physics.properties, position: transform.position, rotation: transform.rotation, scale: transform.scale, editMode: editMode, nodeId: nodeId,
|
|
297
|
+
return (_jsx(physicsDef.View, { properties: physics.properties, position: transform.position, rotation: transform.rotation, scale: transform.scale, editMode: editMode, nodeId: nodeId, children: inner }, physicsKey));
|
|
259
298
|
}
|
|
260
299
|
return (_jsx("group", { ref: groupRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: inner }));
|
|
261
300
|
}
|
|
@@ -363,17 +402,11 @@ function renderCompositionNode(gameObject, ctx, isSelected, parentMatrix, childN
|
|
|
363
402
|
const ownContent = renderNodeOwnContent(gameObject, ctx, isSelected, parentMatrix);
|
|
364
403
|
return wrapWithChildHosts(gameObject, ctx, isSelected, parentMatrix, _jsxs(_Fragment, { children: [ownContent, childNodes] }));
|
|
365
404
|
}
|
|
366
|
-
function buildContextProps(gameObject,
|
|
405
|
+
function buildContextProps(gameObject, _ctx, isSelected) {
|
|
367
406
|
return {
|
|
368
|
-
|
|
369
|
-
loadedSounds: ctx.loadedSounds,
|
|
370
|
-
loadedTextures: ctx.loadedTextures,
|
|
371
|
-
editMode: ctx.editMode,
|
|
407
|
+
editMode: _ctx.editMode,
|
|
372
408
|
isSelected,
|
|
373
409
|
nodeId: gameObject.id,
|
|
374
|
-
parentMatrix,
|
|
375
|
-
registerRef: ctx.registerRef,
|
|
376
|
-
getRigidBody: ctx.getRigidBody,
|
|
377
410
|
};
|
|
378
411
|
}
|
|
379
412
|
function renderNodeOwnContent(gameObject, ctx, isSelected, parentMatrix) {
|
|
@@ -383,11 +416,11 @@ function renderNodeOwnContent(gameObject, ctx, isSelected, parentMatrix) {
|
|
|
383
416
|
const materialDef = material && getComponentDef(material.type);
|
|
384
417
|
if (!geometry || !(geometryDef === null || geometryDef === void 0 ? void 0 : geometryDef.View))
|
|
385
418
|
return null;
|
|
386
|
-
const contextProps = buildContextProps(gameObject, ctx, isSelected
|
|
419
|
+
const contextProps = buildContextProps(gameObject, ctx, isSelected);
|
|
387
420
|
return (_jsxs("mesh", { castShadow: true, receiveShadow: true, children: [_jsx(geometryDef.View, Object.assign({ properties: geometry.properties }, contextProps)), material && (materialDef === null || materialDef === void 0 ? void 0 : materialDef.View) && (_jsx(materialDef.View, Object.assign({ properties: material.properties }, contextProps), "material"))] }));
|
|
388
421
|
}
|
|
389
422
|
function wrapWithChildHosts(gameObject, ctx, isSelected, parentMatrix, subtree) {
|
|
390
|
-
const contextProps = buildContextProps(gameObject, ctx, isSelected
|
|
423
|
+
const contextProps = buildContextProps(gameObject, ctx, isSelected);
|
|
391
424
|
const childHosts = getChildHostComponents(gameObject);
|
|
392
425
|
return childHosts.reduce((acc, { key, View, properties }) => (_jsx(View, Object.assign({ properties: properties }, contextProps, { children: acc }), key)), subtree);
|
|
393
426
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Object3D } from "three";
|
|
2
|
+
/**
|
|
3
|
+
* RefBridge — O(1) lookup from entity ID to live Three.js Object3D.
|
|
4
|
+
*
|
|
5
|
+
* In play mode the Scene API writes directly to these refs, bypassing
|
|
6
|
+
* React reconciliation. In edit mode the store path is used instead.
|
|
7
|
+
*
|
|
8
|
+
* Component Views register/unregister refs on mount/unmount via
|
|
9
|
+
* `bridge.register(id, obj)` / `bridge.unregister(id)`.
|
|
10
|
+
*/
|
|
11
|
+
export interface RefBridge {
|
|
12
|
+
register: (id: string, obj: Object3D | null) => void;
|
|
13
|
+
unregister: (id: string) => void;
|
|
14
|
+
get: (id: string) => Object3D | null;
|
|
15
|
+
/** Apply a transform component's properties directly to the Object3D. */
|
|
16
|
+
setTransform: (id: string, position?: number[], rotation?: number[], scale?: number[]) => void;
|
|
17
|
+
/** Read current transform from the Object3D back into a properties bag. */
|
|
18
|
+
readTransform: (id: string) => {
|
|
19
|
+
position: [number, number, number];
|
|
20
|
+
rotation: [number, number, number];
|
|
21
|
+
scale: [number, number, number];
|
|
22
|
+
} | null;
|
|
23
|
+
}
|
|
24
|
+
export declare function createRefBridge(): RefBridge;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function createRefBridge() {
|
|
2
|
+
const refs = new Map();
|
|
3
|
+
return {
|
|
4
|
+
register(id, obj) {
|
|
5
|
+
if (obj) {
|
|
6
|
+
refs.set(id, obj);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
refs.delete(id);
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
unregister(id) {
|
|
13
|
+
refs.delete(id);
|
|
14
|
+
},
|
|
15
|
+
get(id) {
|
|
16
|
+
var _a;
|
|
17
|
+
return (_a = refs.get(id)) !== null && _a !== void 0 ? _a : null;
|
|
18
|
+
},
|
|
19
|
+
setTransform(id, position, rotation, scale) {
|
|
20
|
+
const obj = refs.get(id);
|
|
21
|
+
if (!obj)
|
|
22
|
+
return;
|
|
23
|
+
if (position) {
|
|
24
|
+
obj.position.set(position[0], position[1], position[2]);
|
|
25
|
+
}
|
|
26
|
+
if (rotation) {
|
|
27
|
+
obj.rotation.set(rotation[0], rotation[1], rotation[2]);
|
|
28
|
+
}
|
|
29
|
+
if (scale) {
|
|
30
|
+
obj.scale.set(scale[0], scale[1], scale[2]);
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
readTransform(id) {
|
|
34
|
+
const obj = refs.get(id);
|
|
35
|
+
if (!obj)
|
|
36
|
+
return null;
|
|
37
|
+
return {
|
|
38
|
+
position: [obj.position.x, obj.position.y, obj.position.z],
|
|
39
|
+
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
|
40
|
+
scale: [obj.scale.x, obj.scale.y, obj.scale.z],
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { ColorField,
|
|
2
|
+
import { ColorField, NumberField } from "./Input";
|
|
3
|
+
import { LightSection, mergeWithDefaults } from "./lightUtils";
|
|
4
|
+
const ambientLightDefaults = {
|
|
5
|
+
color: '#ffffff',
|
|
6
|
+
intensity: 1,
|
|
7
|
+
};
|
|
3
8
|
function AmbientLightComponentEditor({ component, onUpdate, }) {
|
|
4
|
-
|
|
9
|
+
const values = mergeWithDefaults(ambientLightDefaults, component.properties);
|
|
10
|
+
return (_jsxs(LightSection, { title: "Light", children: [_jsx(ColorField, { name: "color", label: "Color", values: values, onChange: onUpdate }), _jsx(NumberField, { name: "intensity", label: "Intensity", values: values, onChange: onUpdate, min: 0, step: 0.1, fallback: 1 })] }));
|
|
5
11
|
}
|
|
6
12
|
function AmbientLightComponentView({ properties, children }) {
|
|
7
|
-
const { color
|
|
13
|
+
const { color, intensity } = mergeWithDefaults(ambientLightDefaults, properties);
|
|
8
14
|
return (_jsxs(_Fragment, { children: [_jsx("ambientLight", { color: color, intensity: intensity }), children] }));
|
|
9
15
|
}
|
|
10
16
|
const AmbientLightComponent = {
|
|
11
17
|
name: 'AmbientLight',
|
|
12
18
|
Editor: AmbientLightComponentEditor,
|
|
13
19
|
View: AmbientLightComponentView,
|
|
14
|
-
defaultProperties: {
|
|
15
|
-
color: '#ffffff',
|
|
16
|
-
intensity: 1,
|
|
17
|
-
},
|
|
20
|
+
defaultProperties: {},
|
|
18
21
|
};
|
|
19
22
|
export default AmbientLightComponent;
|