react-three-game 0.0.56 → 0.0.58
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/README.md +16 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/shared/GameCanvas.js +1 -3
- package/dist/tools/assetviewer/page.js +35 -14
- package/dist/tools/prefabeditor/Dropdown.d.ts +15 -0
- package/dist/tools/prefabeditor/Dropdown.js +82 -0
- package/dist/tools/prefabeditor/EditorContext.d.ts +5 -0
- package/dist/tools/prefabeditor/EditorTree.js +149 -91
- package/dist/tools/prefabeditor/EditorTreeMenus.d.ts +33 -0
- package/dist/tools/prefabeditor/EditorTreeMenus.js +136 -0
- package/dist/tools/prefabeditor/EditorUI.js +1 -1
- package/dist/tools/prefabeditor/PrefabEditor.d.ts +1 -0
- package/dist/tools/prefabeditor/PrefabEditor.js +13 -2
- package/dist/tools/prefabeditor/PrefabRoot.d.ts +1 -0
- package/dist/tools/prefabeditor/PrefabRoot.js +120 -34
- package/dist/tools/prefabeditor/components/AmbientLightComponent.js +3 -7
- package/dist/tools/prefabeditor/components/CameraComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/CameraComponent.js +45 -0
- package/dist/tools/prefabeditor/components/DirectionalLightComponent.js +50 -24
- package/dist/tools/prefabeditor/components/EnvironmentComponent.d.ts +3 -0
- package/dist/tools/prefabeditor/components/EnvironmentComponent.js +15 -0
- package/dist/tools/prefabeditor/components/GeometryComponent.js +46 -46
- package/dist/tools/prefabeditor/components/Input.d.ts +51 -1
- package/dist/tools/prefabeditor/components/Input.js +73 -21
- package/dist/tools/prefabeditor/components/MaterialComponent.d.ts +16 -2
- package/dist/tools/prefabeditor/components/MaterialComponent.js +129 -15
- package/dist/tools/prefabeditor/components/ModelComponent.js +44 -3
- package/dist/tools/prefabeditor/components/PhysicsComponent.js +16 -81
- package/dist/tools/prefabeditor/components/SpotLightComponent.js +36 -23
- package/dist/tools/prefabeditor/components/TextComponent.js +7 -53
- package/dist/tools/prefabeditor/components/TransformComponent.js +18 -8
- package/dist/tools/prefabeditor/components/index.js +5 -1
- package/dist/tools/prefabeditor/styles.d.ts +5 -2
- package/dist/tools/prefabeditor/styles.js +7 -3
- package/dist/tools/prefabeditor/utils.d.ts +4 -3
- package/dist/tools/prefabeditor/utils.js +53 -5
- package/package.json +1 -1
- package/react-three-game-skill/react-three-game/SKILL.md +4 -1
- package/src/index.ts +7 -0
- package/src/shared/GameCanvas.tsx +0 -3
- package/src/tools/assetviewer/page.tsx +77 -45
- package/src/tools/prefabeditor/Dropdown.tsx +112 -0
- package/src/tools/prefabeditor/EditorContext.tsx +5 -0
- package/src/tools/prefabeditor/EditorTree.tsx +242 -178
- package/src/tools/prefabeditor/EditorTreeMenus.tsx +307 -0
- package/src/tools/prefabeditor/EditorUI.tsx +1 -1
- package/src/tools/prefabeditor/PrefabEditor.tsx +17 -4
- package/src/tools/prefabeditor/PrefabRoot.tsx +208 -58
- package/src/tools/prefabeditor/components/AmbientLightComponent.tsx +5 -11
- package/src/tools/prefabeditor/components/CameraComponent.tsx +117 -0
- package/src/tools/prefabeditor/components/DirectionalLightComponent.tsx +61 -30
- package/src/tools/prefabeditor/components/EnvironmentComponent.tsx +47 -0
- package/src/tools/prefabeditor/components/GeometryComponent.tsx +69 -63
- package/src/tools/prefabeditor/components/Input.tsx +220 -27
- package/src/tools/prefabeditor/components/MaterialComponent.tsx +189 -18
- package/src/tools/prefabeditor/components/ModelComponent.tsx +51 -4
- package/src/tools/prefabeditor/components/PhysicsComponent.tsx +44 -85
- package/src/tools/prefabeditor/components/SpotLightComponent.tsx +52 -27
- package/src/tools/prefabeditor/components/TextComponent.tsx +58 -57
- package/src/tools/prefabeditor/components/TransformComponent.tsx +61 -9
- package/src/tools/prefabeditor/components/index.ts +5 -1
- package/src/tools/prefabeditor/styles.ts +7 -3
- package/src/tools/prefabeditor/utils.ts +55 -4
|
@@ -15,24 +15,28 @@ import { getComponent, registerComponent, getNonComposableKeys } from "./compone
|
|
|
15
15
|
import components from "./components";
|
|
16
16
|
import { loadModel } from "../dragdrop/modelLoader";
|
|
17
17
|
import { GameInstance, GameInstanceProvider, useInstanceCheck } from "./InstanceProvider";
|
|
18
|
-
import { updateNode } from "./utils";
|
|
18
|
+
import { focusCameraOnObject, updateNode } from "./utils";
|
|
19
19
|
import { EditorContext } from "./EditorContext";
|
|
20
20
|
components.forEach(registerComponent);
|
|
21
21
|
const IDENTITY = new Matrix4();
|
|
22
22
|
export const PrefabRoot = forwardRef(({ editMode, data, onPrefabChange, selectedId, onSelect, onClick, basePath = "" }, ref) => {
|
|
23
|
-
var _a, _b;
|
|
23
|
+
var _a, _b, _c, _d;
|
|
24
24
|
// optional editor context
|
|
25
25
|
const editorContext = useContext(EditorContext);
|
|
26
26
|
const transformMode = (_a = editorContext === null || editorContext === void 0 ? void 0 : editorContext.transformMode) !== null && _a !== void 0 ? _a : "translate";
|
|
27
27
|
const snapResolution = (_b = editorContext === null || editorContext === void 0 ? void 0 : editorContext.snapResolution) !== null && _b !== void 0 ? _b : 0;
|
|
28
|
+
const positionSnap = (_c = editorContext === null || editorContext === void 0 ? void 0 : editorContext.positionSnap) !== null && _c !== void 0 ? _c : 0.5;
|
|
29
|
+
const rotationSnap = (_d = editorContext === null || editorContext === void 0 ? void 0 : editorContext.rotationSnap) !== null && _d !== void 0 ? _d : Math.PI / 4;
|
|
28
30
|
// prefab root state
|
|
29
31
|
const [models, setModels] = useState({});
|
|
30
32
|
const [textures, setTextures] = useState({});
|
|
31
33
|
const loading = useRef(new Set());
|
|
34
|
+
const failedTextures = useRef(new Set());
|
|
32
35
|
const objectRefs = useRef({});
|
|
33
36
|
const rigidBodyRefs = useRef(new Map());
|
|
34
37
|
const [selectedObject, setSelectedObject] = useState(null);
|
|
35
38
|
const rootRef = useRef(null);
|
|
39
|
+
const controlsRef = useRef(null);
|
|
36
40
|
const injectModel = useCallback((filename, model) => {
|
|
37
41
|
setModels(m => (Object.assign(Object.assign({}, m), { [filename]: model })));
|
|
38
42
|
}, []);
|
|
@@ -50,7 +54,15 @@ export const PrefabRoot = forwardRef(({ editMode, data, onPrefabChange, selected
|
|
|
50
54
|
root: rootRef.current,
|
|
51
55
|
rigidBodyRefs: rigidBodyRefs.current,
|
|
52
56
|
injectModel,
|
|
53
|
-
injectTexture
|
|
57
|
+
injectTexture,
|
|
58
|
+
focusNode: (nodeId) => {
|
|
59
|
+
const object = objectRefs.current[nodeId];
|
|
60
|
+
const controls = controlsRef.current;
|
|
61
|
+
const camera = controls === null || controls === void 0 ? void 0 : controls.object;
|
|
62
|
+
if (!object || !controls || !camera)
|
|
63
|
+
return;
|
|
64
|
+
focusCameraOnObject(object, camera, controls.target, () => { var _a; return (_a = controls.update) === null || _a === void 0 ? void 0 : _a.call(controls); });
|
|
65
|
+
}
|
|
54
66
|
}), [injectModel, injectTexture]);
|
|
55
67
|
const registerRef = useCallback((id, obj) => {
|
|
56
68
|
objectRefs.current[id] = obj;
|
|
@@ -92,11 +104,13 @@ export const PrefabRoot = forwardRef(({ editMode, data, onPrefabChange, selected
|
|
|
92
104
|
const modelsToLoad = new Set();
|
|
93
105
|
const texturesToLoad = new Set();
|
|
94
106
|
walk(data.root, node => {
|
|
95
|
-
var _a, _b, _c, _d, _e, _f;
|
|
107
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
96
108
|
((_c = (_b = (_a = node.components) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.properties) === null || _c === void 0 ? void 0 : _c.filename) &&
|
|
97
109
|
modelsToLoad.add(node.components.model.properties.filename);
|
|
98
110
|
((_f = (_e = (_d = node.components) === null || _d === void 0 ? void 0 : _d.material) === null || _e === void 0 ? void 0 : _e.properties) === null || _f === void 0 ? void 0 : _f.texture) &&
|
|
99
111
|
texturesToLoad.add(node.components.material.properties.texture);
|
|
112
|
+
((_j = (_h = (_g = node.components) === null || _g === void 0 ? void 0 : _g.material) === null || _h === void 0 ? void 0 : _h.properties) === null || _j === void 0 ? void 0 : _j.normalMapTexture) &&
|
|
113
|
+
texturesToLoad.add(node.components.material.properties.normalMapTexture);
|
|
100
114
|
});
|
|
101
115
|
modelsToLoad.forEach((file) => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
116
|
if (models[file] || loading.current.has(file))
|
|
@@ -111,7 +125,7 @@ export const PrefabRoot = forwardRef(({ editMode, data, onPrefabChange, selected
|
|
|
111
125
|
}));
|
|
112
126
|
const loader = new TextureLoader();
|
|
113
127
|
texturesToLoad.forEach(file => {
|
|
114
|
-
if (textures[file] || loading.current.has(file))
|
|
128
|
+
if (textures[file] || loading.current.has(file) || failedTextures.current.has(file))
|
|
115
129
|
return;
|
|
116
130
|
loading.current.add(file);
|
|
117
131
|
// Handle full URLs (http/https) or regular paths
|
|
@@ -124,12 +138,13 @@ export const PrefabRoot = forwardRef(({ editMode, data, onPrefabChange, selected
|
|
|
124
138
|
tex.colorSpace = SRGBColorSpace;
|
|
125
139
|
setTextures(t => (Object.assign(Object.assign({}, t), { [file]: tex })));
|
|
126
140
|
}, undefined, (err) => {
|
|
127
|
-
console.
|
|
141
|
+
console.warn(`Failed to load texture: ${path}`, err);
|
|
128
142
|
loading.current.delete(file);
|
|
143
|
+
failedTextures.current.add(file);
|
|
129
144
|
});
|
|
130
145
|
});
|
|
131
146
|
}, [data, models, textures]);
|
|
132
|
-
return (_jsxs("group", { ref: rootRef, children: [_jsx(GameInstanceProvider, { models: models, selectedId: selectedId, editMode: editMode, onSelect: editMode ? onSelect : undefined, registerRef: registerRef, children: _jsx(GameObjectRenderer, { gameObject: data.root, selectedId: selectedId, onSelect: editMode ? onSelect : undefined, onClick: onClick, registerRef: registerRef, registerRigidBodyRef: registerRigidBodyRef, loadedModels: models, loadedTextures: textures, editMode: editMode, parentMatrix: IDENTITY }) }), editMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { makeDefault: true }), selectedObject && (_jsx(TransformControls, { object: selectedObject, mode: transformMode, space: "local", onObjectChange: onTransformChange, translationSnap:
|
|
147
|
+
return (_jsxs("group", { ref: rootRef, children: [_jsx(GameInstanceProvider, { models: models, selectedId: selectedId, editMode: editMode, onSelect: editMode ? onSelect : undefined, registerRef: registerRef, children: _jsx(GameObjectRenderer, { gameObject: data.root, selectedId: selectedId, onSelect: editMode ? onSelect : undefined, onClick: onClick, registerRef: registerRef, registerRigidBodyRef: registerRigidBodyRef, loadedModels: models, loadedTextures: textures, editMode: editMode, parentMatrix: IDENTITY }) }), editMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, makeDefault: true }), selectedObject && (_jsx(TransformControls, { object: selectedObject, mode: transformMode, space: "local", onObjectChange: onTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: snapResolution > 0 ? snapResolution : undefined }, `transform-${transformMode}-${positionSnap}-${rotationSnap}-${snapResolution}`))] }))] }));
|
|
133
148
|
});
|
|
134
149
|
export function GameObjectRenderer(props) {
|
|
135
150
|
var _a, _b, _c;
|
|
@@ -187,7 +202,7 @@ function InstancedNode({ gameObject, parentMatrix = IDENTITY, editMode, register
|
|
|
187
202
|
return (_jsx(GameInstance, { id: gameObject.id, modelUrl: (_k = (_j = (_h = gameObject.components) === null || _h === void 0 ? void 0 : _h.model) === null || _j === void 0 ? void 0 : _j.properties) === null || _k === void 0 ? void 0 : _k.filename, position: worldPosition, rotation: worldRotation, scale: worldScale, physics: physicsProps }));
|
|
188
203
|
}
|
|
189
204
|
function StandardNode({ gameObject, selectedId, onSelect, onClick, registerRef, registerRigidBodyRef, loadedModels, loadedTextures, editMode, parentMatrix = IDENTITY, }) {
|
|
190
|
-
var _a, _b, _c, _d, _e
|
|
205
|
+
var _a, _b, _c, _d, _e;
|
|
191
206
|
const groupRef = useRef(null);
|
|
192
207
|
const helperRef = useRef(null);
|
|
193
208
|
const clickValid = useRef(false);
|
|
@@ -219,7 +234,20 @@ function StandardNode({ gameObject, selectedId, onSelect, onClick, registerRef,
|
|
|
219
234
|
const physicsDef = hasPhysics ? getComponent("Physics") : null;
|
|
220
235
|
const isInstanced = (_e = (_d = (_c = gameObject.components) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.properties) === null || _e === void 0 ? void 0 : _e.instanced;
|
|
221
236
|
const physicsKey = `physics_${gameObject.id}_${isInstanced ? 'instanced' : 'standard'}`;
|
|
222
|
-
const
|
|
237
|
+
const renderCtx = createRenderContext(loadedModels, loadedTextures, editMode, selectedId, registerRef);
|
|
238
|
+
const childNodes = getChildHostComponents(gameObject).length > 0
|
|
239
|
+
? renderHostedChildren(gameObject, renderCtx, world)
|
|
240
|
+
: renderSceneChildren(gameObject, world, {
|
|
241
|
+
selectedId,
|
|
242
|
+
onSelect,
|
|
243
|
+
onClick,
|
|
244
|
+
registerRef,
|
|
245
|
+
registerRigidBodyRef,
|
|
246
|
+
loadedModels,
|
|
247
|
+
loadedTextures,
|
|
248
|
+
editMode,
|
|
249
|
+
});
|
|
250
|
+
const inner = (_jsx("group", { onPointerDown: editMode ? onDown : undefined, onPointerMove: editMode ? () => (clickValid.current = false) : undefined, onPointerUp: editMode ? onUp : undefined, children: renderCompositionNode(gameObject, renderCtx, parentMatrix, childNodes) }));
|
|
223
251
|
if (editMode) {
|
|
224
252
|
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: gameObject.id, registerRigidBodyRef: registerRigidBodyRef, children: inner }, physicsKey)) : null] }));
|
|
225
253
|
}
|
|
@@ -228,6 +256,28 @@ function StandardNode({ gameObject, selectedId, onSelect, onClick, registerRef,
|
|
|
228
256
|
}
|
|
229
257
|
return (_jsx("group", { ref: groupRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, onPointerDown: onDown, onPointerMove: () => (clickValid.current = false), onPointerUp: onUp, children: inner }));
|
|
230
258
|
}
|
|
259
|
+
const CHILD_HOST_COMPONENT_TYPES = new Set(["Environment"]);
|
|
260
|
+
function isChildHostType(type) {
|
|
261
|
+
return CHILD_HOST_COMPONENT_TYPES.has(type);
|
|
262
|
+
}
|
|
263
|
+
function getChildHostComponents(gameObject) {
|
|
264
|
+
var _a;
|
|
265
|
+
return Object.entries((_a = gameObject.components) !== null && _a !== void 0 ? _a : {}).flatMap(([key, comp]) => {
|
|
266
|
+
if (!(comp === null || comp === void 0 ? void 0 : comp.type) || !isChildHostType(comp.type))
|
|
267
|
+
return [];
|
|
268
|
+
const def = getComponent(comp.type);
|
|
269
|
+
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
270
|
+
return [];
|
|
271
|
+
return { key, View: def.View, properties: comp.properties };
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function createRenderContext(loadedModels, loadedTextures, editMode, selectedId, registerRef) {
|
|
275
|
+
return { loadedModels, loadedTextures, editMode, selectedId, registerRef };
|
|
276
|
+
}
|
|
277
|
+
function renderSceneChildren(gameObject, parentMatrix, props) {
|
|
278
|
+
var _a;
|
|
279
|
+
return (_a = gameObject.children) === null || _a === void 0 ? void 0 : _a.map(child => _jsx(GameObjectRenderer, { gameObject: child, selectedId: props.selectedId, onSelect: props.onSelect, onClick: props.onClick, registerRef: props.registerRef, registerRigidBodyRef: props.registerRigidBodyRef, loadedModels: props.loadedModels, loadedTextures: props.loadedTextures, editMode: props.editMode, parentMatrix: parentMatrix }, child.id));
|
|
280
|
+
}
|
|
231
281
|
function walk(node, fn) {
|
|
232
282
|
var _a;
|
|
233
283
|
fn(node);
|
|
@@ -270,7 +320,25 @@ function computeParentWorldMatrix(root, targetId) {
|
|
|
270
320
|
visit(root, IDENTITY);
|
|
271
321
|
return result !== null && result !== void 0 ? result : IDENTITY;
|
|
272
322
|
}
|
|
273
|
-
function
|
|
323
|
+
function renderCompositionSubtree(gameObject, ctx, parentMatrix = IDENTITY) {
|
|
324
|
+
if (!gameObject || gameObject.disabled)
|
|
325
|
+
return null;
|
|
326
|
+
const transform = getNodeTransformProps(gameObject);
|
|
327
|
+
const world = parentMatrix.clone().multiply(compose(gameObject));
|
|
328
|
+
const childNodes = renderHostedChildren(gameObject, ctx, world);
|
|
329
|
+
return (_jsx("group", { position: transform.position, rotation: transform.rotation, scale: transform.scale, children: renderCompositionNode(gameObject, ctx, parentMatrix, childNodes) }, gameObject.id));
|
|
330
|
+
}
|
|
331
|
+
function renderHostedChildren(gameObject, ctx, parentMatrix) {
|
|
332
|
+
var _a;
|
|
333
|
+
return (_a = gameObject.children) === null || _a === void 0 ? void 0 : _a.map(child => renderCompositionSubtree(child, ctx, parentMatrix));
|
|
334
|
+
}
|
|
335
|
+
function renderCompositionNode(gameObject, ctx, parentMatrix, childNodes) {
|
|
336
|
+
const ownContent = renderNodeOwnContent(gameObject, ctx, parentMatrix);
|
|
337
|
+
const siblingContent = renderNodeSiblingComponents(gameObject, ctx, parentMatrix);
|
|
338
|
+
const subtree = _jsxs(_Fragment, { children: [ownContent, siblingContent, childNodes] });
|
|
339
|
+
return wrapWithChildHosts(gameObject, ctx, parentMatrix, subtree);
|
|
340
|
+
}
|
|
341
|
+
function renderNodeOwnContent(gameObject, ctx, parentMatrix) {
|
|
274
342
|
var _a, _b, _c, _d;
|
|
275
343
|
const geometry = (_a = gameObject.components) === null || _a === void 0 ? void 0 : _a.geometry;
|
|
276
344
|
const material = (_b = gameObject.components) === null || _b === void 0 ? void 0 : _b.material;
|
|
@@ -284,41 +352,59 @@ function renderCoreNode(gameObject, ctx, parentMatrix) {
|
|
|
284
352
|
loadedModels: ctx.loadedModels,
|
|
285
353
|
loadedTextures: ctx.loadedTextures,
|
|
286
354
|
editMode: ctx.editMode,
|
|
355
|
+
isSelected: ctx.selectedId === gameObject.id,
|
|
356
|
+
nodeId: gameObject.id,
|
|
287
357
|
parentMatrix,
|
|
288
358
|
registerRef: ctx.registerRef,
|
|
289
359
|
};
|
|
290
|
-
const wrappers = [];
|
|
291
|
-
const leaves = [];
|
|
292
|
-
if (gameObject.components) {
|
|
293
|
-
Object.entries(gameObject.components)
|
|
294
|
-
.filter(([k]) => !getNonComposableKeys().includes(k))
|
|
295
|
-
.forEach(([key, comp]) => {
|
|
296
|
-
if (!(comp === null || comp === void 0 ? void 0 : comp.type))
|
|
297
|
-
return;
|
|
298
|
-
const def = getComponent(comp.type);
|
|
299
|
-
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
300
|
-
return;
|
|
301
|
-
if (def.View.toString().includes("children")) {
|
|
302
|
-
wrappers.push({ key, View: def.View, properties: comp.properties });
|
|
303
|
-
}
|
|
304
|
-
else {
|
|
305
|
-
leaves.push(_jsx(def.View, Object.assign({ properties: comp.properties }, contextProps), key));
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
360
|
let core;
|
|
310
361
|
if (model && (modelDef === null || modelDef === void 0 ? void 0 : modelDef.View)) {
|
|
311
|
-
core = (
|
|
362
|
+
core = (_jsx(modelDef.View, Object.assign({ properties: model.properties }, contextProps, { children: material && (materialDef === null || materialDef === void 0 ? void 0 : materialDef.View) && (_jsx(materialDef.View, Object.assign({ properties: material.properties }, contextProps), "material")) })));
|
|
312
363
|
}
|
|
313
364
|
else if (geometry && (geometryDef === null || geometryDef === void 0 ? void 0 : geometryDef.View)) {
|
|
314
|
-
core = (_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"))
|
|
365
|
+
core = (_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"))] }));
|
|
315
366
|
}
|
|
316
367
|
else if (text && (textDef === null || textDef === void 0 ? void 0 : textDef.View)) {
|
|
317
|
-
core = (
|
|
368
|
+
core = (_jsx(_Fragment, { children: _jsx(textDef.View, Object.assign({ properties: text.properties }, contextProps)) }));
|
|
318
369
|
}
|
|
319
370
|
else {
|
|
320
|
-
core =
|
|
371
|
+
core = null;
|
|
321
372
|
}
|
|
322
|
-
return
|
|
373
|
+
return core;
|
|
374
|
+
}
|
|
375
|
+
function renderNodeSiblingComponents(gameObject, ctx, parentMatrix) {
|
|
376
|
+
var _a;
|
|
377
|
+
const contextProps = {
|
|
378
|
+
loadedModels: ctx.loadedModels,
|
|
379
|
+
loadedTextures: ctx.loadedTextures,
|
|
380
|
+
editMode: ctx.editMode,
|
|
381
|
+
isSelected: ctx.selectedId === gameObject.id,
|
|
382
|
+
nodeId: gameObject.id,
|
|
383
|
+
parentMatrix,
|
|
384
|
+
registerRef: ctx.registerRef,
|
|
385
|
+
};
|
|
386
|
+
return Object.entries((_a = gameObject.components) !== null && _a !== void 0 ? _a : {})
|
|
387
|
+
.filter(([key]) => !getNonComposableKeys().includes(key))
|
|
388
|
+
.flatMap(([key, comp]) => {
|
|
389
|
+
if (!(comp === null || comp === void 0 ? void 0 : comp.type) || isChildHostType(comp.type))
|
|
390
|
+
return [];
|
|
391
|
+
const def = getComponent(comp.type);
|
|
392
|
+
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
393
|
+
return [];
|
|
394
|
+
return _jsx(def.View, Object.assign({ properties: comp.properties }, contextProps), key);
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
function wrapWithChildHosts(gameObject, ctx, parentMatrix, subtree) {
|
|
398
|
+
const contextProps = {
|
|
399
|
+
loadedModels: ctx.loadedModels,
|
|
400
|
+
loadedTextures: ctx.loadedTextures,
|
|
401
|
+
editMode: ctx.editMode,
|
|
402
|
+
isSelected: ctx.selectedId === gameObject.id,
|
|
403
|
+
nodeId: gameObject.id,
|
|
404
|
+
parentMatrix,
|
|
405
|
+
registerRef: ctx.registerRef,
|
|
406
|
+
};
|
|
407
|
+
const childHosts = getChildHostComponents(gameObject);
|
|
408
|
+
return childHosts.reduce((acc, { key, View, properties }) => (_jsx(View, Object.assign({ properties: properties }, contextProps, { children: acc }), key)), subtree);
|
|
323
409
|
}
|
|
324
410
|
export default PrefabRoot;
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
const ambientLightFields = [
|
|
4
|
-
{ name: 'color', type: 'color', label: 'Color' },
|
|
5
|
-
{ name: 'intensity', type: 'number', label: 'Intensity', step: 0.1, min: 0 },
|
|
6
|
-
];
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ColorField, FieldGroup, NumberField } from "./Input";
|
|
7
3
|
function AmbientLightComponentEditor({ component, onUpdate, }) {
|
|
8
|
-
return (_jsx(
|
|
4
|
+
return (_jsxs(FieldGroup, { children: [_jsx(ColorField, { name: "color", label: "Color", values: component.properties, onChange: onUpdate }), _jsx(NumberField, { name: "intensity", label: "Intensity", values: component.properties, onChange: onUpdate, min: 0, step: 0.1, fallback: 1 })] }));
|
|
9
5
|
}
|
|
10
6
|
function AmbientLightComponentView({ properties }) {
|
|
11
7
|
const { color = '#ffffff', intensity = 1 } = properties;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { PerspectiveCamera } from '@react-three/drei';
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { CameraHelper } from 'three';
|
|
5
|
+
import { useFrame } from '@react-three/fiber';
|
|
6
|
+
import { FieldGroup, NumberField } from './Input';
|
|
7
|
+
const cameraDefaults = {
|
|
8
|
+
fov: 50,
|
|
9
|
+
near: 0.1,
|
|
10
|
+
zoom: 1,
|
|
11
|
+
far: 1000,
|
|
12
|
+
};
|
|
13
|
+
function CameraComponentEditor({ component, onUpdate }) {
|
|
14
|
+
const values = Object.assign(Object.assign({}, cameraDefaults), component.properties);
|
|
15
|
+
return (_jsxs(FieldGroup, { children: [_jsx(NumberField, { name: "fov", label: "FOV", values: values, onChange: onUpdate, fallback: 50, min: 1, max: 179, step: 1 }), _jsx(NumberField, { name: "near", label: "Near", values: values, onChange: onUpdate, fallback: 0.1, min: 0.001, step: 0.1 }), _jsx(NumberField, { name: "zoom", label: "Zoom", values: values, onChange: onUpdate, fallback: 1, min: 0.01, step: 0.1 }), _jsx(NumberField, { name: "far", label: "Far", values: values, onChange: onUpdate, fallback: 1000, min: 0.1, step: 1 })] }));
|
|
16
|
+
}
|
|
17
|
+
function CameraComponentView({ properties, editMode, isSelected }) {
|
|
18
|
+
const merged = Object.assign(Object.assign({}, cameraDefaults), properties);
|
|
19
|
+
const fov = merged.fov;
|
|
20
|
+
const near = merged.near;
|
|
21
|
+
const zoom = merged.zoom;
|
|
22
|
+
const far = merged.far;
|
|
23
|
+
const [camera, setCamera] = useState(null);
|
|
24
|
+
const cameraHelper = useMemo(() => camera ? new CameraHelper(camera) : null, [camera]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
return () => {
|
|
27
|
+
cameraHelper === null || cameraHelper === void 0 ? void 0 : cameraHelper.dispose();
|
|
28
|
+
};
|
|
29
|
+
}, [cameraHelper]);
|
|
30
|
+
useFrame(() => {
|
|
31
|
+
if (camera && cameraHelper && editMode && isSelected) {
|
|
32
|
+
camera.updateProjectionMatrix();
|
|
33
|
+
camera.updateMatrixWorld();
|
|
34
|
+
cameraHelper.update();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return (_jsxs(_Fragment, { children: [_jsx(PerspectiveCamera, { ref: (instance) => setCamera(instance), makeDefault: !editMode, fov: fov, near: near, zoom: zoom, far: far }), editMode && isSelected && cameraHelper && (_jsx("primitive", { object: cameraHelper })), editMode && !isSelected ? (_jsxs("mesh", { children: [_jsx("boxGeometry", { args: [0.34, 0.22, 0.18] }), _jsx("meshBasicMaterial", { color: "#22d3ee", wireframe: true })] })) : null] }));
|
|
38
|
+
}
|
|
39
|
+
const CameraComponent = {
|
|
40
|
+
name: 'Camera',
|
|
41
|
+
Editor: CameraComponentEditor,
|
|
42
|
+
View: CameraComponentView,
|
|
43
|
+
defaultProperties: cameraDefaults,
|
|
44
|
+
};
|
|
45
|
+
export default CameraComponent;
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useEffect } from "react";
|
|
2
|
+
import { useRef, useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { useFrame } from "@react-three/fiber";
|
|
4
|
-
import { Vector3 } from "three";
|
|
4
|
+
import { CameraHelper, Vector3 } from "three";
|
|
5
5
|
import { FieldRenderer, Input } from "./Input";
|
|
6
6
|
const smallLabel = { display: 'block', fontSize: '8px', color: 'rgba(34, 211, 238, 0.5)', marginBottom: 2 };
|
|
7
|
+
const directionalLightDefaults = {
|
|
8
|
+
color: '#ffffff',
|
|
9
|
+
intensity: 1,
|
|
10
|
+
castShadow: true,
|
|
11
|
+
shadowMapSize: 1024,
|
|
12
|
+
shadowCameraNear: 0.1,
|
|
13
|
+
shadowCameraFar: 100,
|
|
14
|
+
shadowCameraTop: 30,
|
|
15
|
+
shadowCameraBottom: -30,
|
|
16
|
+
shadowCameraLeft: -30,
|
|
17
|
+
shadowCameraRight: 30,
|
|
18
|
+
targetOffset: [0, -5, 0],
|
|
19
|
+
};
|
|
7
20
|
const directionalLightFields = [
|
|
8
21
|
{ name: 'color', type: 'color', label: 'Color' },
|
|
9
22
|
{ name: 'intensity', type: 'number', label: 'Intensity', step: 0.1, min: 0 },
|
|
@@ -29,39 +42,52 @@ const directionalLightFields = [
|
|
|
29
42
|
},
|
|
30
43
|
];
|
|
31
44
|
function DirectionalLightComponentEditor({ component, onUpdate }) {
|
|
32
|
-
|
|
45
|
+
const values = Object.assign(Object.assign({}, directionalLightDefaults), component.properties);
|
|
46
|
+
const fields = values.castShadow
|
|
47
|
+
? directionalLightFields
|
|
48
|
+
: directionalLightFields.filter(field => field.name !== '_shadowCamera');
|
|
49
|
+
return (_jsx(FieldRenderer, { fields: fields, values: values, onChange: onUpdate }));
|
|
33
50
|
}
|
|
34
|
-
function DirectionalLightView({ properties, editMode }) {
|
|
35
|
-
|
|
36
|
-
const color =
|
|
37
|
-
const intensity =
|
|
38
|
-
const castShadow =
|
|
39
|
-
const shadowMapSize =
|
|
40
|
-
const shadowCameraNear =
|
|
41
|
-
const shadowCameraFar =
|
|
42
|
-
const shadowCameraTop =
|
|
43
|
-
const shadowCameraBottom =
|
|
44
|
-
const shadowCameraLeft =
|
|
45
|
-
const shadowCameraRight =
|
|
46
|
-
const targetOffset =
|
|
51
|
+
function DirectionalLightView({ properties, editMode, isSelected }) {
|
|
52
|
+
const merged = Object.assign(Object.assign({}, directionalLightDefaults), properties);
|
|
53
|
+
const color = merged.color;
|
|
54
|
+
const intensity = merged.intensity;
|
|
55
|
+
const castShadow = merged.castShadow;
|
|
56
|
+
const shadowMapSize = merged.shadowMapSize;
|
|
57
|
+
const shadowCameraNear = merged.shadowCameraNear;
|
|
58
|
+
const shadowCameraFar = merged.shadowCameraFar;
|
|
59
|
+
const shadowCameraTop = merged.shadowCameraTop;
|
|
60
|
+
const shadowCameraBottom = merged.shadowCameraBottom;
|
|
61
|
+
const shadowCameraLeft = merged.shadowCameraLeft;
|
|
62
|
+
const shadowCameraRight = merged.shadowCameraRight;
|
|
63
|
+
const targetOffset = merged.targetOffset;
|
|
47
64
|
const directionalLightRef = useRef(null);
|
|
48
65
|
const targetRef = useRef(null);
|
|
49
|
-
|
|
66
|
+
const [shadowCamera, setShadowCamera] = useState(null);
|
|
67
|
+
const shadowCameraHelper = useMemo(() => shadowCamera ? new CameraHelper(shadowCamera) : null, [shadowCamera]);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
return () => {
|
|
70
|
+
shadowCameraHelper === null || shadowCameraHelper === void 0 ? void 0 : shadowCameraHelper.dispose();
|
|
71
|
+
};
|
|
72
|
+
}, [shadowCameraHelper]);
|
|
73
|
+
// Use a local target object so node transforms rotate the light direction naturally.
|
|
50
74
|
useEffect(() => {
|
|
51
75
|
if (directionalLightRef.current && targetRef.current) {
|
|
52
76
|
directionalLightRef.current.target = targetRef.current;
|
|
77
|
+
setShadowCamera(directionalLightRef.current.shadow.camera);
|
|
53
78
|
}
|
|
54
79
|
}, []);
|
|
55
|
-
// Update target world position based on light position + offset
|
|
56
80
|
useFrame(() => {
|
|
57
81
|
if (!directionalLightRef.current || !targetRef.current)
|
|
58
82
|
return;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
83
|
+
directionalLightRef.current.target.updateMatrixWorld();
|
|
84
|
+
if (shadowCamera && shadowCameraHelper && castShadow) {
|
|
85
|
+
shadowCamera.updateProjectionMatrix();
|
|
86
|
+
shadowCamera.updateMatrixWorld();
|
|
87
|
+
shadowCameraHelper.update();
|
|
88
|
+
}
|
|
63
89
|
});
|
|
64
|
-
return (_jsxs(_Fragment, { children: [_jsx("directionalLight", { ref: directionalLightRef, color: color, intensity: intensity, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar, "shadow-camera-top": shadowCameraTop, "shadow-camera-bottom": shadowCameraBottom, "shadow-camera-left": shadowCameraLeft, "shadow-camera-right": shadowCameraRight, "shadow-bias": -0.001, "shadow-normalBias": 0.02 }), _jsx("object3D", { ref: targetRef }), editMode && (_jsxs(_Fragment, { children: [_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.3, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] }), _jsxs("mesh", { position: targetOffset, children: [_jsx("sphereGeometry", { args: [0.2, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true, opacity: 0.5, transparent: true })] }), _jsxs("line", { children: [_jsx("bufferGeometry", { onUpdate: (geo) => {
|
|
90
|
+
return (_jsxs(_Fragment, { children: [_jsx("directionalLight", { ref: directionalLightRef, color: color, intensity: intensity, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar, "shadow-camera-top": shadowCameraTop, "shadow-camera-bottom": shadowCameraBottom, "shadow-camera-left": shadowCameraLeft, "shadow-camera-right": shadowCameraRight, "shadow-bias": -0.001, "shadow-normalBias": 0.02 }), _jsx("object3D", { ref: targetRef, position: targetOffset }), editMode && isSelected && castShadow && shadowCameraHelper && (_jsx("primitive", { object: shadowCameraHelper })), editMode && isSelected && (_jsxs(_Fragment, { children: [_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.3, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] }), _jsxs("mesh", { position: targetOffset, children: [_jsx("sphereGeometry", { args: [0.2, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true, opacity: 0.5, transparent: true })] }), _jsxs("line", { children: [_jsx("bufferGeometry", { onUpdate: (geo) => {
|
|
65
91
|
const points = [
|
|
66
92
|
new Vector3(0, 0, 0),
|
|
67
93
|
new Vector3(targetOffset[0], targetOffset[1], targetOffset[2])
|
|
@@ -73,6 +99,6 @@ const DirectionalLightComponent = {
|
|
|
73
99
|
name: 'DirectionalLight',
|
|
74
100
|
Editor: DirectionalLightComponentEditor,
|
|
75
101
|
View: DirectionalLightView,
|
|
76
|
-
defaultProperties:
|
|
102
|
+
defaultProperties: directionalLightDefaults
|
|
77
103
|
};
|
|
78
104
|
export default DirectionalLightComponent;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Environment } from '@react-three/drei';
|
|
3
|
+
import { FieldGroup, NumberField } from './Input';
|
|
4
|
+
function EnvironmentView({ properties, children, editMode, loadedTextures, loadedModels, }) {
|
|
5
|
+
const { intensity = 1, resolution = 256 } = properties;
|
|
6
|
+
const assetRevision = `${Object.keys(loadedTextures !== null && loadedTextures !== void 0 ? loadedTextures : {}).sort().join('|')}::${Object.keys(loadedModels !== null && loadedModels !== void 0 ? loadedModels : {}).sort().join('|')}`;
|
|
7
|
+
return (_jsx(Environment, { background: true, environmentIntensity: intensity, resolution: resolution, frames: editMode ? undefined : 1, children: children }, assetRevision));
|
|
8
|
+
}
|
|
9
|
+
const EnvironmentComponent = {
|
|
10
|
+
name: 'Environment',
|
|
11
|
+
Editor: ({ component, onUpdate }) => (_jsxs(FieldGroup, { children: [_jsx(NumberField, { name: "intensity", label: "Intensity", values: component.properties, onChange: onUpdate, min: 0, step: 0.1, fallback: 1 }), _jsx(NumberField, { name: "resolution", label: "Resolution", values: component.properties, onChange: onUpdate, min: 64, step: 64, fallback: 256 })] })),
|
|
12
|
+
View: EnvironmentView,
|
|
13
|
+
defaultProperties: {},
|
|
14
|
+
};
|
|
15
|
+
export default EnvironmentComponent;
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FieldGroup, NumberField, SelectField } from "./Input";
|
|
3
3
|
const GEOMETRY_ARGS = {
|
|
4
4
|
box: {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
fields: [
|
|
6
|
+
{ name: 'width', label: 'Width', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
7
|
+
{ name: 'height', label: 'Height', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
8
|
+
{ name: 'depth', label: 'Depth', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
9
|
+
],
|
|
7
10
|
},
|
|
8
11
|
sphere: {
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
fields: [
|
|
13
|
+
{ name: 'radius', label: 'Radius', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
14
|
+
{ name: 'widthSegments', label: 'Width Segments', defaultValue: 32, min: 3, step: 1 },
|
|
15
|
+
{ name: 'heightSegments', label: 'Height Segments', defaultValue: 16, min: 2, step: 1 },
|
|
16
|
+
],
|
|
11
17
|
},
|
|
12
18
|
plane: {
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
fields: [
|
|
20
|
+
{ name: 'width', label: 'Width', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
21
|
+
{ name: 'height', label: 'Height', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
22
|
+
],
|
|
15
23
|
},
|
|
16
24
|
cylinder: {
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
fields: [
|
|
26
|
+
{ name: 'radiusTop', label: 'Radius Top', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
27
|
+
{ name: 'radiusBottom', label: 'Radius Bottom', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
28
|
+
{ name: 'height', label: 'Height', defaultValue: 1, min: 0.01, step: 0.1 },
|
|
29
|
+
{ name: 'radialSegments', label: 'Radial Segments', defaultValue: 32, min: 3, step: 1 },
|
|
30
|
+
],
|
|
19
31
|
},
|
|
20
32
|
};
|
|
33
|
+
function getDefaultArgs(geometryType) {
|
|
34
|
+
var _a, _b;
|
|
35
|
+
return ((_b = (_a = GEOMETRY_ARGS[geometryType]) === null || _a === void 0 ? void 0 : _a.fields) !== null && _b !== void 0 ? _b : []).map(field => field.defaultValue);
|
|
36
|
+
}
|
|
21
37
|
function GeometryComponentEditor({ component, onUpdate, }) {
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
name: 'geometryType',
|
|
27
|
-
type: 'select',
|
|
28
|
-
label: 'Type',
|
|
29
|
-
options: [
|
|
30
|
-
{ value: 'box', label: 'Box' },
|
|
31
|
-
{ value: 'sphere', label: 'Sphere' },
|
|
32
|
-
{ value: 'plane', label: 'Plane' },
|
|
33
|
-
{ value: 'cylinder', label: 'Cylinder' },
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: 'args',
|
|
38
|
-
type: 'custom',
|
|
39
|
-
label: '',
|
|
40
|
-
render: ({ values, onChangeMultiple }) => {
|
|
41
|
-
const currentType = values.geometryType;
|
|
42
|
-
const currentSchema = GEOMETRY_ARGS[currentType];
|
|
43
|
-
const currentArgs = values.args || currentSchema.defaults;
|
|
44
|
-
return (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: currentSchema.labels.map((label, i) => {
|
|
45
|
-
var _a;
|
|
46
|
-
return (_jsx(Input, { label: label, value: (_a = currentArgs[i]) !== null && _a !== void 0 ? _a : currentSchema.defaults[i], step: 0.1, min: 0.01, onChange: value => {
|
|
47
|
-
const next = [...currentArgs];
|
|
48
|
-
next[i] = value;
|
|
49
|
-
onChangeMultiple({ args: next });
|
|
50
|
-
} }, label));
|
|
51
|
-
}) }));
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
];
|
|
38
|
+
var _a, _b, _c;
|
|
39
|
+
const geometryType = (_a = component.properties.geometryType) !== null && _a !== void 0 ? _a : 'box';
|
|
40
|
+
const schema = (_b = GEOMETRY_ARGS[geometryType]) !== null && _b !== void 0 ? _b : GEOMETRY_ARGS.box;
|
|
41
|
+
const args = (_c = component.properties.args) !== null && _c !== void 0 ? _c : getDefaultArgs(geometryType);
|
|
55
42
|
// Handle geometry type change to reset args
|
|
56
43
|
const handleChange = (newValues) => {
|
|
57
44
|
if ('geometryType' in newValues && newValues.geometryType !== geometryType) {
|
|
58
|
-
onUpdate({ geometryType: newValues.geometryType, args:
|
|
45
|
+
onUpdate({ geometryType: newValues.geometryType, args: getDefaultArgs(newValues.geometryType) });
|
|
59
46
|
}
|
|
60
47
|
else {
|
|
61
48
|
onUpdate(newValues);
|
|
62
49
|
}
|
|
63
50
|
};
|
|
64
|
-
|
|
51
|
+
const updateArg = (index, value) => {
|
|
52
|
+
const next = [...args];
|
|
53
|
+
next[index] = value;
|
|
54
|
+
onUpdate({ args: next });
|
|
55
|
+
};
|
|
56
|
+
return (_jsxs(FieldGroup, { children: [_jsx(SelectField, { name: "geometryType", label: "Type", values: component.properties, onChange: handleChange, options: [
|
|
57
|
+
{ value: 'box', label: 'Box' },
|
|
58
|
+
{ value: 'sphere', label: 'Sphere' },
|
|
59
|
+
{ value: 'plane', label: 'Plane' },
|
|
60
|
+
{ value: 'cylinder', label: 'Cylinder' },
|
|
61
|
+
] }), schema.fields.map((field, index) => {
|
|
62
|
+
var _a;
|
|
63
|
+
return (_jsx(NumberField, { name: field.name, label: field.label, values: { [field.name]: (_a = args[index]) !== null && _a !== void 0 ? _a : field.defaultValue }, onChange: (next) => updateArg(index, next[field.name]), fallback: field.defaultValue, min: field.min, step: field.step }, field.name));
|
|
64
|
+
})] }));
|
|
65
65
|
}
|
|
66
66
|
// View for Geometry component
|
|
67
67
|
function GeometryComponentView({ properties, children }) {
|
|
@@ -87,7 +87,7 @@ const GeometryComponent = {
|
|
|
87
87
|
nonComposable: true,
|
|
88
88
|
defaultProperties: {
|
|
89
89
|
geometryType: 'box',
|
|
90
|
-
args:
|
|
90
|
+
args: getDefaultArgs('box'),
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
export default GeometryComponent;
|