react-three-game 0.0.91 → 0.0.93
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 +68 -33
- package/dist/helpers/index.d.ts +0 -3
- package/dist/helpers/index.js +1 -8
- package/dist/index.d.ts +5 -8
- package/dist/index.js +3 -4
- package/dist/tools/assetviewer/page.js +38 -10
- package/dist/tools/prefabeditor/EditorTree.js +2 -2
- package/dist/tools/prefabeditor/GameEvents.d.ts +6 -12
- package/dist/tools/prefabeditor/GameEvents.js +0 -8
- package/dist/tools/prefabeditor/InstanceProvider.d.ts +6 -4
- package/dist/tools/prefabeditor/InstanceProvider.js +84 -199
- package/dist/tools/prefabeditor/PrefabEditor.d.ts +18 -6
- package/dist/tools/prefabeditor/PrefabEditor.js +67 -30
- package/dist/tools/prefabeditor/PrefabRoot.d.ts +15 -9
- package/dist/tools/prefabeditor/PrefabRoot.js +142 -129
- package/dist/tools/prefabeditor/assetRuntime.d.ts +13 -11
- package/dist/tools/prefabeditor/assetRuntime.js +15 -15
- package/dist/tools/prefabeditor/components/BufferGeometryComponent.js +1 -1
- package/dist/tools/prefabeditor/components/CameraComponent.js +2 -2
- package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +3 -3
- package/dist/tools/prefabeditor/components/DirectionalLightComponent.js +3 -3
- package/dist/tools/prefabeditor/components/ModelComponent.js +1 -1
- package/dist/tools/prefabeditor/components/PointLightComponent.js +2 -2
- package/dist/tools/prefabeditor/components/SoundComponent.js +2 -2
- package/dist/tools/prefabeditor/components/SpotLightComponent.js +2 -2
- package/dist/tools/prefabeditor/components/index.js +0 -2
- package/dist/tools/prefabeditor/types.d.ts +1 -0
- package/dist/tools/prefabeditor/usePointerEvents.d.ts +3 -3
- package/dist/tools/prefabeditor/usePointerEvents.js +5 -5
- package/package.json +1 -3
- package/dist/tools/prefabeditor/components/PhysicsComponent.d.ts +0 -26
- package/dist/tools/prefabeditor/components/PhysicsComponent.js +0 -287
- package/dist/tools/prefabeditor/scene.d.ts +0 -70
- package/dist/tools/prefabeditor/scene.js +0 -237
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type ForwardRefExoticComponent, type RefAttributes } from "react";
|
|
2
|
+
import { Matrix4, Object3D, Texture } from "three";
|
|
2
3
|
import { ThreeEvent } from "@react-three/fiber";
|
|
3
4
|
import { GameObject as GameObjectType, Prefab } from "./types";
|
|
4
5
|
import { LoadedModels } from "../dragdrop";
|
|
5
6
|
import { PrefabStoreApi } from "./prefabStore";
|
|
6
7
|
export interface PrefabRootRef {
|
|
7
|
-
root:
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
root: Object3D | null;
|
|
9
|
+
getNodeObject: (nodeId: string) => Object3D | null;
|
|
10
|
+
getNodeHandle: <T = unknown>(nodeId: string, kind: string) => T | null;
|
|
10
11
|
addModel: (path: string, model: Object3D) => void;
|
|
11
12
|
addTexture: (path: string, texture: Texture) => void;
|
|
12
13
|
addSound: (path: string, sound: AudioBuffer) => void;
|
|
@@ -14,23 +15,28 @@ export interface PrefabRootRef {
|
|
|
14
15
|
export interface PrefabRootProps {
|
|
15
16
|
editMode?: boolean;
|
|
16
17
|
data?: Prefab;
|
|
17
|
-
store?: PrefabStoreApi;
|
|
18
18
|
selectedId?: string | null;
|
|
19
19
|
onSelect?: (id: string | null) => void;
|
|
20
|
-
onClick?: (event: ThreeEvent<PointerEvent>,
|
|
21
|
-
|
|
20
|
+
onClick?: (event: ThreeEvent<PointerEvent>, node: GameObjectType) => void;
|
|
21
|
+
onEditNodeClick?: (event: ThreeEvent<PointerEvent>, node: GameObjectType) => void;
|
|
22
22
|
basePath?: string;
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
interface PrefabRootInternalProps extends PrefabRootProps {
|
|
25
|
+
store?: PrefabStoreApi;
|
|
26
|
+
}
|
|
27
|
+
export declare const PrefabRootInternal: ForwardRefExoticComponent<PrefabRootInternalProps & RefAttributes<PrefabRootRef>>;
|
|
28
|
+
export declare const PrefabRoot: ForwardRefExoticComponent<PrefabRootProps & RefAttributes<PrefabRootRef>>;
|
|
25
29
|
export declare function GameObjectRenderer(props: RendererProps): import("react/jsx-runtime").JSX.Element | null;
|
|
26
30
|
interface RendererProps {
|
|
27
31
|
nodeId: string;
|
|
28
32
|
selectedId?: string | null;
|
|
29
33
|
onSelect?: (id: string) => void;
|
|
30
|
-
onClick?: (event: ThreeEvent<PointerEvent>,
|
|
34
|
+
onClick?: (event: ThreeEvent<PointerEvent>, nodeId: string, object: Object3D | null) => void;
|
|
35
|
+
onEditNodeClick?: (event: ThreeEvent<PointerEvent>, node: GameObjectType) => void;
|
|
31
36
|
registerRef: (id: string, obj: Object3D | null) => void;
|
|
32
37
|
loadedModels: LoadedModels;
|
|
33
38
|
editMode?: boolean;
|
|
34
39
|
parentMatrix?: Matrix4;
|
|
40
|
+
isVisible?: boolean;
|
|
35
41
|
}
|
|
36
42
|
export default PrefabRoot;
|
|
@@ -10,9 +10,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { useHelper } from "@react-three/drei";
|
|
14
13
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
15
|
-
import {
|
|
14
|
+
import { Euler, Matrix4, } from "three";
|
|
16
15
|
import { useStore } from "zustand";
|
|
17
16
|
import { useClickValid } from "./useClickValid";
|
|
18
17
|
import { findComponent, getNodeUserData } from "./types";
|
|
@@ -21,9 +20,8 @@ import { builtinComponents } from "./components";
|
|
|
21
20
|
import { loadModel, loadSound, loadTexture } from "../dragdrop";
|
|
22
21
|
import { GameInstance, GameInstanceProvider, getRepeatAxesFromModelProperties, useInstanceCheck } from "./InstanceProvider";
|
|
23
22
|
import { composeTransform, decompose } from "./utils";
|
|
24
|
-
import { isPhysicsProps } from "./components/PhysicsComponent";
|
|
25
23
|
import { createPrefabStore, PrefabStoreProvider, useOptionalPrefabStoreApi, usePrefabChildIds, usePrefabNode, usePrefabRootId } from "./prefabStore";
|
|
26
|
-
import { AssetRuntimeContext,
|
|
24
|
+
import { AssetRuntimeContext, CurrentNodeScope } from "./assetRuntime";
|
|
27
25
|
import { gameEvents } from "./GameEvents";
|
|
28
26
|
import { sound as soundManager } from "../../helpers/SoundManager";
|
|
29
27
|
builtinComponents.forEach(registerComponent);
|
|
@@ -37,30 +35,13 @@ function resolveAssetPath(basePath, file) {
|
|
|
37
35
|
return file;
|
|
38
36
|
return file.startsWith("/") ? `${basePath}${file}` : `${basePath}/${file}`;
|
|
39
37
|
}
|
|
40
|
-
/** Check if
|
|
41
|
-
function isNodeReady(
|
|
38
|
+
/** Check if a model component's assets are loaded. */
|
|
39
|
+
function isNodeReady(model, loadedModels) {
|
|
42
40
|
var _a;
|
|
43
|
-
const model = findComponent(node, "Model");
|
|
44
41
|
if (!((_a = model === null || model === void 0 ? void 0 : model.properties) === null || _a === void 0 ? void 0 : _a.filename))
|
|
45
42
|
return true;
|
|
46
43
|
return Boolean(loadedModels[model.properties.filename]);
|
|
47
44
|
}
|
|
48
|
-
function getNodeClickEventName(node) {
|
|
49
|
-
var _a;
|
|
50
|
-
const clickComponents = [
|
|
51
|
-
findComponent(node, 'BufferGeometry'),
|
|
52
|
-
findComponent(node, 'Geometry'),
|
|
53
|
-
];
|
|
54
|
-
for (const component of clickComponents) {
|
|
55
|
-
if (!((_a = component === null || component === void 0 ? void 0 : component.properties) === null || _a === void 0 ? void 0 : _a.emitClickEvent))
|
|
56
|
-
continue;
|
|
57
|
-
const eventName = component.properties.clickEventName;
|
|
58
|
-
if (typeof eventName === 'string' && eventName.trim()) {
|
|
59
|
-
return eventName.trim();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
45
|
function getNodeMetadataProps(node) {
|
|
65
46
|
var _a, _b;
|
|
66
47
|
const nodeName = (_b = (_a = node.name) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
|
|
@@ -69,7 +50,7 @@ function getNodeMetadataProps(node) {
|
|
|
69
50
|
userData: Object.assign(Object.assign({ prefabNodeId: node.id }, (nodeName ? { prefabNodeName: nodeName } : {})), getNodeUserData(node)),
|
|
70
51
|
};
|
|
71
52
|
}
|
|
72
|
-
export const
|
|
53
|
+
export const PrefabRootInternal = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick, onEditNodeClick, basePath = "" }, ref) => {
|
|
73
54
|
var _a;
|
|
74
55
|
const [models, setModels] = useState({});
|
|
75
56
|
const [textures, setTextures] = useState({});
|
|
@@ -82,8 +63,7 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
82
63
|
const failedTextures = useRef(new Set());
|
|
83
64
|
const failedSounds = useRef(new Set());
|
|
84
65
|
const objectRefs = useRef({});
|
|
85
|
-
const
|
|
86
|
-
const rootRef = useRef(null);
|
|
66
|
+
const nodeHandles = useRef(new Map());
|
|
87
67
|
const parentStore = useOptionalPrefabStoreApi();
|
|
88
68
|
const [ownedStore] = useState(() => {
|
|
89
69
|
if (data)
|
|
@@ -95,35 +75,52 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
95
75
|
const resolvedStore = (_a = store !== null && store !== void 0 ? store : parentStore) !== null && _a !== void 0 ? _a : ownedStore;
|
|
96
76
|
const usesOwnedStore = resolvedStore === ownedStore;
|
|
97
77
|
const shouldProvideStoreContext = !parentStore || parentStore !== resolvedStore;
|
|
78
|
+
const rootId = useStore(resolvedStore, state => state.rootId);
|
|
98
79
|
const assetManifestKey = useStore(resolvedStore, state => state.assetManifestKey);
|
|
99
80
|
const availableModels = useMemo(() => (Object.assign(Object.assign({}, models), injectedModels)), [models, injectedModels]);
|
|
100
81
|
const availableTextures = useMemo(() => (Object.assign(Object.assign({}, textures), injectedTextures)), [textures, injectedTextures]);
|
|
101
82
|
const availableSounds = useMemo(() => (Object.assign(Object.assign({}, sounds), injectedSounds)), [sounds, injectedSounds]);
|
|
102
|
-
const
|
|
83
|
+
const getNodeObject = useCallback((id) => {
|
|
103
84
|
var _a;
|
|
104
85
|
return (_a = objectRefs.current[id]) !== null && _a !== void 0 ? _a : null;
|
|
105
86
|
}, []);
|
|
106
|
-
const
|
|
107
|
-
var _a;
|
|
108
|
-
return (_a =
|
|
87
|
+
const getNodeHandle = useCallback((id, kind) => {
|
|
88
|
+
var _a, _b;
|
|
89
|
+
return (_b = (_a = nodeHandles.current.get(id)) === null || _a === void 0 ? void 0 : _a.get(kind)) !== null && _b !== void 0 ? _b : null;
|
|
90
|
+
}, []);
|
|
91
|
+
const registerNodeHandle = useCallback((id, kind, handle) => {
|
|
92
|
+
const current = nodeHandles.current.get(id);
|
|
93
|
+
if (handle == null) {
|
|
94
|
+
if (!current)
|
|
95
|
+
return;
|
|
96
|
+
current.delete(kind);
|
|
97
|
+
if (current.size === 0) {
|
|
98
|
+
nodeHandles.current.delete(id);
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (current) {
|
|
103
|
+
current.set(kind, handle);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
nodeHandles.current.set(id, new Map([[kind, handle]]));
|
|
109
107
|
}, []);
|
|
110
108
|
useImperativeHandle(ref, () => ({
|
|
111
|
-
root
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
get root() {
|
|
110
|
+
var _a;
|
|
111
|
+
return (_a = objectRefs.current[rootId]) !== null && _a !== void 0 ? _a : null;
|
|
112
|
+
},
|
|
113
|
+
getNodeObject,
|
|
114
|
+
getNodeHandle,
|
|
114
115
|
addModel: (path, model) => setInjectedModels(prev => (Object.assign(Object.assign({}, prev), { [path]: model }))),
|
|
115
116
|
addTexture: (path, texture) => setInjectedTextures(prev => (Object.assign(Object.assign({}, prev), { [path]: texture }))),
|
|
116
117
|
addSound: (path, sound) => {
|
|
117
118
|
soundManager.setBuffer(path, sound);
|
|
118
119
|
setInjectedSounds(prev => (Object.assign(Object.assign({}, prev), { [path]: sound })));
|
|
119
120
|
},
|
|
120
|
-
}), [
|
|
121
|
+
}), [getNodeHandle, getNodeObject, rootId]);
|
|
121
122
|
const registerRef = useCallback((id, obj) => {
|
|
122
123
|
objectRefs.current[id] = obj;
|
|
123
|
-
onObjectRefChange === null || onObjectRefChange === void 0 ? void 0 : onObjectRefChange(id, obj);
|
|
124
|
-
}, [onObjectRefChange]);
|
|
125
|
-
const registerRigidBodyRef = useCallback((id, rb) => {
|
|
126
|
-
rigidBodyRefs.current.set(id, rb);
|
|
127
124
|
}, []);
|
|
128
125
|
useEffect(() => {
|
|
129
126
|
if (usesOwnedStore && data) {
|
|
@@ -188,25 +185,87 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
188
185
|
syncAssets();
|
|
189
186
|
}, [resolvedStore, assetManifestKey, basePath, injectedModels, injectedSounds, injectedTextures, models, sounds, textures]);
|
|
190
187
|
const assetRuntime = useMemo(() => ({
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
registerNodeHandle,
|
|
189
|
+
getNodeHandle,
|
|
190
|
+
getNodeObject,
|
|
194
191
|
getModel: (path) => { var _a; return (_a = availableModels[path]) !== null && _a !== void 0 ? _a : null; },
|
|
195
192
|
getTexture: (path) => { var _a; return (_a = availableTextures[path]) !== null && _a !== void 0 ? _a : null; },
|
|
196
193
|
getSound: (path) => { var _a; return (_a = availableSounds[path]) !== null && _a !== void 0 ? _a : null; },
|
|
197
194
|
getAssetRevision: () => `${Object.keys(availableTextures).sort().join('|')}::${Object.keys(availableModels).sort().join('|')}`,
|
|
198
|
-
}), [
|
|
199
|
-
const
|
|
195
|
+
}), [registerNodeHandle, getNodeHandle, getNodeObject, availableModels, availableTextures, availableSounds]);
|
|
196
|
+
const handleNodeClick = useCallback((event, nodeId, fallbackObject) => {
|
|
197
|
+
const node = resolvedStore.getState().nodesById[nodeId];
|
|
198
|
+
if (!node)
|
|
199
|
+
return;
|
|
200
|
+
const { clickEventName } = analyzeNodeComponents(node);
|
|
201
|
+
emitNodePointerEvent(clickEventName, event, nodeId, node, fallbackObject);
|
|
202
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event, node);
|
|
203
|
+
}, [onClick, resolvedStore]);
|
|
204
|
+
const content = (_jsx(GameInstanceProvider, { models: availableModels, selectedId: selectedId, editMode: editMode, onSelect: editMode ? onSelect : undefined, onClick: editMode ? undefined : handleNodeClick, registerRef: registerRef, children: _jsx(StoreRootNode, { selectedId: selectedId, onSelect: editMode ? onSelect : undefined, onClick: editMode ? undefined : handleNodeClick, onEditNodeClick: editMode ? onEditNodeClick : undefined, registerRef: registerRef, loadedModels: availableModels, editMode: editMode, parentMatrix: IDENTITY }) }));
|
|
200
205
|
const runtimeContent = _jsx(AssetRuntimeContext.Provider, { value: assetRuntime, children: content });
|
|
201
206
|
if (!shouldProvideStoreContext) {
|
|
202
207
|
return runtimeContent;
|
|
203
208
|
}
|
|
204
209
|
return _jsx(PrefabStoreProvider, { store: resolvedStore, children: runtimeContent });
|
|
205
210
|
});
|
|
211
|
+
export const PrefabRoot = PrefabRootInternal;
|
|
206
212
|
function StoreRootNode(props) {
|
|
207
213
|
const rootId = usePrefabRootId();
|
|
208
214
|
return _jsx(GameObjectRenderer, Object.assign({}, props, { nodeId: rootId }));
|
|
209
215
|
}
|
|
216
|
+
function getClickEventName(component) {
|
|
217
|
+
var _a;
|
|
218
|
+
if (!((_a = component === null || component === void 0 ? void 0 : component.properties) === null || _a === void 0 ? void 0 : _a.emitClickEvent))
|
|
219
|
+
return null;
|
|
220
|
+
const eventName = component.properties.clickEventName;
|
|
221
|
+
return typeof eventName === 'string' && eventName.trim() ? eventName.trim() : null;
|
|
222
|
+
}
|
|
223
|
+
function analyzeNodeComponents(node) {
|
|
224
|
+
var _a, _b, _c;
|
|
225
|
+
let bufferGeometry;
|
|
226
|
+
let geometry;
|
|
227
|
+
let material;
|
|
228
|
+
let model;
|
|
229
|
+
const composition = [];
|
|
230
|
+
for (const [key, component] of Object.entries((_a = node.components) !== null && _a !== void 0 ? _a : {})) {
|
|
231
|
+
if (!(component === null || component === void 0 ? void 0 : component.type))
|
|
232
|
+
continue;
|
|
233
|
+
switch (component.type) {
|
|
234
|
+
case "Transform":
|
|
235
|
+
break;
|
|
236
|
+
case "BufferGeometry":
|
|
237
|
+
bufferGeometry = component;
|
|
238
|
+
break;
|
|
239
|
+
case "Geometry":
|
|
240
|
+
geometry = component;
|
|
241
|
+
break;
|
|
242
|
+
case "Material":
|
|
243
|
+
material = component;
|
|
244
|
+
break;
|
|
245
|
+
case "Model":
|
|
246
|
+
model = component;
|
|
247
|
+
break;
|
|
248
|
+
default: {
|
|
249
|
+
const def = getComponentDef(component.type);
|
|
250
|
+
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
251
|
+
break;
|
|
252
|
+
composition.push({
|
|
253
|
+
key,
|
|
254
|
+
View: def.View,
|
|
255
|
+
properties: component.properties,
|
|
256
|
+
});
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
geometry: bufferGeometry !== null && bufferGeometry !== void 0 ? bufferGeometry : geometry,
|
|
263
|
+
material,
|
|
264
|
+
model,
|
|
265
|
+
clickEventName: (_c = (_b = getClickEventName(bufferGeometry)) !== null && _b !== void 0 ? _b : getClickEventName(geometry)) !== null && _c !== void 0 ? _c : getClickEventName(model),
|
|
266
|
+
composition,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
210
269
|
function emitNodePointerEvent(eventName, event, nodeId, node, fallbackObject) {
|
|
211
270
|
var _a;
|
|
212
271
|
const trimmedEventName = eventName === null || eventName === void 0 ? void 0 : eventName.trim();
|
|
@@ -249,21 +308,19 @@ export function GameObjectRenderer(props) {
|
|
|
249
308
|
? _jsx(InstancedNode, Object.assign({}, props), key)
|
|
250
309
|
: _jsx(StandardNode, Object.assign({}, props), key);
|
|
251
310
|
}
|
|
252
|
-
function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef, onSelect, onClick }) {
|
|
311
|
+
function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef, onSelect, onEditNodeClick, onClick, isVisible = true }) {
|
|
253
312
|
var _a, _b;
|
|
254
313
|
const gameObject = usePrefabNode(nodeId);
|
|
255
314
|
if (!gameObject)
|
|
256
315
|
return null;
|
|
316
|
+
const analyzedComponents = useMemo(() => analyzeNodeComponents(gameObject), [gameObject]);
|
|
257
317
|
const localTransform = getNodeTransformProps(gameObject);
|
|
258
318
|
const isLocked = Boolean(gameObject.locked);
|
|
319
|
+
const nodeVisible = isVisible && !gameObject.hidden;
|
|
259
320
|
const metadataProps = getNodeMetadataProps(gameObject);
|
|
260
|
-
const groupProps = Object.assign(Object.assign({}, metadataProps), { position: localTransform.position, rotation: localTransform.rotation, scale: localTransform.scale });
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
? physicsData === null || physicsData === void 0 ? void 0 : physicsData.properties
|
|
264
|
-
: undefined;
|
|
265
|
-
const modelUrl = (_b = (_a = findComponent(gameObject, "Model")) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.filename;
|
|
266
|
-
const instances = useMemo(() => buildRepeatedInstances(gameObject, parentMatrix, modelUrl, physicsProps), [gameObject, modelUrl, parentMatrix, physicsProps]);
|
|
321
|
+
const groupProps = Object.assign(Object.assign({}, metadataProps), { visible: nodeVisible, position: localTransform.position, rotation: localTransform.rotation, scale: localTransform.scale });
|
|
322
|
+
const modelUrl = (_b = (_a = analyzedComponents.model) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.filename;
|
|
323
|
+
const instances = useMemo(() => buildRepeatedInstances(gameObject, parentMatrix, modelUrl), [gameObject, modelUrl, parentMatrix]);
|
|
267
324
|
const groupRef = useRef(null);
|
|
268
325
|
const handleGroupRef = useCallback((object) => {
|
|
269
326
|
groupRef.current = object;
|
|
@@ -273,56 +330,44 @@ function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef,
|
|
|
273
330
|
}, [editMode, nodeId, registerRef]);
|
|
274
331
|
const editClickHandlers = useClickValid(!!editMode && !isLocked, (event) => {
|
|
275
332
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(nodeId);
|
|
276
|
-
|
|
333
|
+
onEditNodeClick === null || onEditNodeClick === void 0 ? void 0 : onEditNodeClick(event, gameObject);
|
|
277
334
|
});
|
|
278
|
-
const renderedInstances = instances.map(instance => (_jsx(GameInstance, { id: instance.id, sourceId: gameObject.id, modelUrl: instance.modelUrl, position: instance.position, rotation: instance.rotation, scale: instance.scale, locked: isLocked,
|
|
335
|
+
const renderedInstances = instances.map(instance => (_jsx(GameInstance, { id: instance.id, sourceId: gameObject.id, modelUrl: instance.modelUrl, position: instance.position, rotation: instance.rotation, scale: instance.scale, visible: nodeVisible, locked: isLocked, onClick: onClick }, instance.id)));
|
|
279
336
|
if (editMode) {
|
|
280
337
|
return (_jsxs(_Fragment, { children: [_jsx("group", Object.assign({ ref: handleGroupRef }, groupProps, editClickHandlers, { children: _jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) }) })), renderedInstances] }));
|
|
281
338
|
}
|
|
282
339
|
return _jsx(_Fragment, { children: renderedInstances });
|
|
283
340
|
}
|
|
284
|
-
function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, loadedModels, editMode, parentMatrix = IDENTITY, }) {
|
|
285
|
-
var _a, _b;
|
|
341
|
+
function StandardNode({ nodeId, selectedId, onSelect, onClick, onEditNodeClick, registerRef, loadedModels, editMode, parentMatrix = IDENTITY, isVisible = true, }) {
|
|
286
342
|
const gameObject = usePrefabNode(nodeId);
|
|
287
343
|
const childIds = usePrefabChildIds(nodeId);
|
|
288
344
|
if (!gameObject)
|
|
289
345
|
return null;
|
|
346
|
+
const analyzedComponents = useMemo(() => analyzeNodeComponents(gameObject), [gameObject]);
|
|
290
347
|
const isSelected = selectedId === nodeId;
|
|
291
348
|
const isLocked = Boolean(gameObject.locked);
|
|
349
|
+
const nodeVisible = isVisible && !gameObject.hidden;
|
|
292
350
|
const stillInstanced = useInstanceCheck(nodeId);
|
|
293
|
-
const clickEventName = getNodeClickEventName(gameObject);
|
|
294
351
|
const metadataProps = getNodeMetadataProps(gameObject);
|
|
295
352
|
const groupRef = useRef(null);
|
|
296
|
-
const helperRef = useRef(null);
|
|
297
353
|
const handleGroupRef = useCallback((object) => {
|
|
298
354
|
groupRef.current = object;
|
|
299
355
|
registerRef(nodeId, object);
|
|
300
356
|
}, [nodeId, registerRef]);
|
|
301
|
-
const handleHelperRef = useCallback((object) => {
|
|
302
|
-
helperRef.current = object;
|
|
303
|
-
}, []);
|
|
304
|
-
const handleEditGroupRef = useCallback((object) => {
|
|
305
|
-
handleGroupRef(object);
|
|
306
|
-
handleHelperRef(object);
|
|
307
|
-
}, [handleGroupRef, handleHelperRef]);
|
|
308
357
|
const editClickHandlers = useClickValid(!!editMode && !isLocked, (event) => {
|
|
309
358
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(nodeId);
|
|
310
|
-
|
|
359
|
+
onEditNodeClick === null || onEditNodeClick === void 0 ? void 0 : onEditNodeClick(event, gameObject);
|
|
311
360
|
});
|
|
312
|
-
const primaryClickHandlers = !editMode &&
|
|
361
|
+
const primaryClickHandlers = !editMode && onClick
|
|
313
362
|
? {
|
|
314
363
|
onClick: (event) => {
|
|
315
364
|
event.stopPropagation();
|
|
316
|
-
|
|
317
|
-
onClick === null || onClick === void 0 ? void 0 : onClick(event, gameObject);
|
|
365
|
+
onClick(event, nodeId, groupRef.current);
|
|
318
366
|
},
|
|
319
367
|
}
|
|
320
368
|
: undefined;
|
|
321
|
-
useHelper(editMode && isSelected ? helperRef : null, BoxHelper, "cyan");
|
|
322
369
|
const world = parentMatrix.clone().multiply(compose(gameObject));
|
|
323
|
-
const
|
|
324
|
-
const ready = isNodeReady(gameObject, loadedModels);
|
|
325
|
-
const hasPhysics = physics && ready && !stillInstanced;
|
|
370
|
+
const ready = isNodeReady(analyzedComponents.model, loadedModels);
|
|
326
371
|
const transform = getNodeTransformProps(gameObject);
|
|
327
372
|
const transformProps = {
|
|
328
373
|
position: transform.position,
|
|
@@ -330,40 +375,11 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, load
|
|
|
330
375
|
scale: transform.scale,
|
|
331
376
|
};
|
|
332
377
|
const groupProps = Object.assign(Object.assign({}, metadataProps), transformProps);
|
|
333
|
-
const
|
|
334
|
-
const
|
|
335
|
-
const physicsKey = `physics_${nodeId}_${isInstanced ? 'instanced' : 'standard'}`;
|
|
336
|
-
const renderCtx = { loadedModels, editMode, registerRef };
|
|
337
|
-
const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
|
|
338
|
-
const inner = renderCompositionNode(gameObject, renderCtx, primaryClickHandlers, childNodes);
|
|
378
|
+
const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, onEditNodeClick: onEditNodeClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode, isVisible: nodeVisible });
|
|
379
|
+
const inner = renderNodeContent(analyzedComponents, loadedModels, primaryClickHandlers, childNodes);
|
|
339
380
|
const editAnchor = editMode ? (_jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) })) : null;
|
|
340
|
-
const standardNode = (_jsxs("group", Object.assign({ ref:
|
|
341
|
-
|
|
342
|
-
return (_jsx(EntityRuntimeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: physicsNode !== null && physicsNode !== void 0 ? physicsNode : standardNode }));
|
|
343
|
-
}
|
|
344
|
-
function isRendererHandledComponent(componentType) {
|
|
345
|
-
return componentType === "Transform"
|
|
346
|
-
|| componentType === "BufferGeometry"
|
|
347
|
-
|| componentType === "Geometry"
|
|
348
|
-
|| componentType === "Material"
|
|
349
|
-
|| componentType === "Physics"
|
|
350
|
-
|| componentType === "Model";
|
|
351
|
-
}
|
|
352
|
-
function getCompositionComponents(gameObject) {
|
|
353
|
-
var _a;
|
|
354
|
-
return Object.entries((_a = gameObject.components) !== null && _a !== void 0 ? _a : {}).reduce((result, [key, comp]) => {
|
|
355
|
-
if (!(comp === null || comp === void 0 ? void 0 : comp.type) || isRendererHandledComponent(comp.type))
|
|
356
|
-
return result;
|
|
357
|
-
const def = getComponentDef(comp.type);
|
|
358
|
-
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
359
|
-
return result;
|
|
360
|
-
result.push({
|
|
361
|
-
key,
|
|
362
|
-
View: def.View,
|
|
363
|
-
properties: comp.properties,
|
|
364
|
-
});
|
|
365
|
-
return result;
|
|
366
|
-
}, []);
|
|
381
|
+
const standardNode = (_jsxs("group", Object.assign({ ref: handleGroupRef }, groupProps, { visible: nodeVisible }, (editMode ? editClickHandlers : undefined), { children: [editAnchor, inner] })));
|
|
382
|
+
return (_jsx(CurrentNodeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: standardNode }));
|
|
367
383
|
}
|
|
368
384
|
function ChildNodes(_a) {
|
|
369
385
|
var { childIds, parentMatrix } = _a, props = __rest(_a, ["childIds", "parentMatrix"]);
|
|
@@ -381,7 +397,7 @@ function getModelRepeatSettings(node) {
|
|
|
381
397
|
repeatAxes: getRepeatAxesFromModelProperties(properties),
|
|
382
398
|
};
|
|
383
399
|
}
|
|
384
|
-
function buildRepeatedInstances(gameObject, parentMatrix, modelUrl
|
|
400
|
+
function buildRepeatedInstances(gameObject, parentMatrix, modelUrl) {
|
|
385
401
|
if (!modelUrl)
|
|
386
402
|
return [];
|
|
387
403
|
const transform = getNodeTransformProps(gameObject);
|
|
@@ -418,7 +434,6 @@ function buildRepeatedInstances(gameObject, parentMatrix, modelUrl, physics) {
|
|
|
418
434
|
position,
|
|
419
435
|
rotation,
|
|
420
436
|
scale,
|
|
421
|
-
physics,
|
|
422
437
|
});
|
|
423
438
|
}
|
|
424
439
|
}
|
|
@@ -434,32 +449,30 @@ function getNodeTransformProps(node) {
|
|
|
434
449
|
scale: (_d = t === null || t === void 0 ? void 0 : t.scale) !== null && _d !== void 0 ? _d : [1, 1, 1],
|
|
435
450
|
};
|
|
436
451
|
}
|
|
437
|
-
function
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
const material = findComponent(gameObject, "Material");
|
|
445
|
-
const model = findComponent(gameObject, "Model");
|
|
446
|
-
const geometryDef = geometry && getComponentDef(geometry.type);
|
|
447
|
-
const materialDef = material && getComponentDef(material.type);
|
|
448
|
-
const modelDef = model && getComponentDef(model.type);
|
|
449
|
-
const geometryProperties = (_b = geometry === null || geometry === void 0 ? void 0 : geometry.properties) !== null && _b !== void 0 ? _b : {};
|
|
452
|
+
function renderNodeContent(analyzedComponents, loadedModels, primaryClickHandlers, childNodes) {
|
|
453
|
+
var _a, _b, _c, _d;
|
|
454
|
+
const geometry = analyzedComponents.geometry;
|
|
455
|
+
const geometryDef = analyzedComponents.geometry && getComponentDef(analyzedComponents.geometry.type);
|
|
456
|
+
const materialDef = analyzedComponents.material && getComponentDef(analyzedComponents.material.type);
|
|
457
|
+
const modelDef = analyzedComponents.model && getComponentDef(analyzedComponents.model.type);
|
|
458
|
+
const geometryProperties = (_a = geometry === null || geometry === void 0 ? void 0 : geometry.properties) !== null && _a !== void 0 ? _a : {};
|
|
450
459
|
const meshVisible = geometryProperties.visible !== false;
|
|
451
460
|
const meshCastShadow = meshVisible && geometryProperties.castShadow !== false;
|
|
452
461
|
const meshReceiveShadow = meshVisible && geometryProperties.receiveShadow !== false;
|
|
453
|
-
|
|
454
|
-
|
|
462
|
+
let primaryContent = null;
|
|
463
|
+
if (((_b = analyzedComponents.geometry) === null || _b === void 0 ? void 0 : _b.type) && (geometryDef === null || geometryDef === void 0 ? void 0 : geometryDef.View)) {
|
|
464
|
+
primaryContent = (_jsxs("mesh", Object.assign({ visible: meshVisible, castShadow: meshCastShadow, receiveShadow: meshReceiveShadow }, primaryClickHandlers, { children: [_jsx(geometryDef.View, { properties: analyzedComponents.geometry.properties }), analyzedComponents.material && (materialDef === null || materialDef === void 0 ? void 0 : materialDef.View) && (_jsx(materialDef.View, { properties: analyzedComponents.material.properties }, "material"))] })));
|
|
455
465
|
}
|
|
456
|
-
if ((
|
|
457
|
-
|
|
466
|
+
else if (((_c = analyzedComponents.model) === null || _c === void 0 ? void 0 : _c.type)
|
|
467
|
+
&& (modelDef === null || modelDef === void 0 ? void 0 : modelDef.View)
|
|
468
|
+
&& !((_d = analyzedComponents.model.properties) === null || _d === void 0 ? void 0 : _d.instanced)
|
|
469
|
+
&& isNodeReady(analyzedComponents.model, loadedModels)) {
|
|
470
|
+
primaryContent = primaryClickHandlers ? (_jsx("group", Object.assign({}, primaryClickHandlers, { children: _jsx(modelDef.View, { properties: analyzedComponents.model.properties }) }))) : (_jsx(modelDef.View, { properties: analyzedComponents.model.properties }));
|
|
458
471
|
}
|
|
459
|
-
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
return
|
|
472
|
+
let content = _jsxs(_Fragment, { children: [primaryContent, childNodes] });
|
|
473
|
+
for (const { key, View, properties } of analyzedComponents.composition) {
|
|
474
|
+
content = (_jsx(View, { properties: properties, children: content }, key));
|
|
475
|
+
}
|
|
476
|
+
return content;
|
|
464
477
|
}
|
|
465
478
|
export default PrefabRoot;
|
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import type { Object3D, Texture } from "three";
|
|
3
3
|
export interface AssetRuntime {
|
|
4
|
-
|
|
4
|
+
registerNodeHandle: (id: string, kind: string, handle: unknown) => void;
|
|
5
|
+
getNodeHandle: <T = unknown>(id: string, kind: string) => T | null;
|
|
5
6
|
getModel: (path: string) => Object3D | null;
|
|
6
7
|
getTexture: (path: string) => Texture | null;
|
|
7
8
|
getSound: (path: string) => AudioBuffer | null;
|
|
8
9
|
getAssetRevision: () => string;
|
|
9
|
-
|
|
10
|
-
getRigidBody: (id: string) => any;
|
|
10
|
+
getNodeObject: (id: string) => Object3D | null;
|
|
11
11
|
}
|
|
12
12
|
export interface AssetRuntimeContextValue extends AssetRuntime {
|
|
13
13
|
}
|
|
14
|
-
export interface
|
|
14
|
+
export interface CurrentNodeRuntime {
|
|
15
15
|
nodeId: string;
|
|
16
16
|
editMode?: boolean;
|
|
17
17
|
isSelected?: boolean;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
getCurrentNodeObject: <T extends Object3D = Object3D>() => T | null;
|
|
19
|
+
getCurrentNodeHandle: <T = unknown>(kind: string) => T | null;
|
|
20
20
|
}
|
|
21
21
|
export interface LiveRef<T> {
|
|
22
22
|
readonly current: T | null;
|
|
23
23
|
}
|
|
24
24
|
export type LiveObjectRef<T extends Object3D = Object3D> = LiveRef<T>;
|
|
25
|
-
export type
|
|
25
|
+
export type LiveHandleRef<T = unknown> = LiveRef<T>;
|
|
26
|
+
export type CurrentNodeObjectRef<T extends Object3D = Object3D> = LiveObjectRef<T>;
|
|
27
|
+
export type CurrentNodeHandleRef<T = unknown> = LiveHandleRef<T>;
|
|
26
28
|
export declare const AssetRuntimeContext: import("react").Context<AssetRuntimeContextValue | null>;
|
|
27
29
|
export declare function useAssetRuntime(): AssetRuntime;
|
|
28
|
-
export declare function
|
|
29
|
-
export declare function
|
|
30
|
-
export declare function
|
|
31
|
-
export declare function
|
|
30
|
+
export declare function useCurrentNode(): CurrentNodeRuntime;
|
|
31
|
+
export declare function useCurrentNodeObject<T extends Object3D = Object3D>(): LiveRef<T>;
|
|
32
|
+
export declare function useCurrentNodeHandle<T = unknown>(kind: string): LiveRef<T>;
|
|
33
|
+
export declare function CurrentNodeScope({ nodeId, editMode, isSelected, children, }: {
|
|
32
34
|
nodeId: string;
|
|
33
35
|
editMode?: boolean;
|
|
34
36
|
isSelected?: boolean;
|
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useContext, useMemo } from "react";
|
|
3
3
|
export const AssetRuntimeContext = createContext(null);
|
|
4
|
-
const
|
|
4
|
+
const CurrentNodeRuntimeContext = createContext(null);
|
|
5
5
|
export function useAssetRuntime() {
|
|
6
6
|
const ctx = useContext(AssetRuntimeContext);
|
|
7
7
|
if (!ctx)
|
|
8
8
|
throw new Error("useAssetRuntime must be used inside <PrefabRoot>");
|
|
9
9
|
return ctx;
|
|
10
10
|
}
|
|
11
|
-
export function
|
|
12
|
-
const ctx = useContext(
|
|
11
|
+
export function useCurrentNode() {
|
|
12
|
+
const ctx = useContext(CurrentNodeRuntimeContext);
|
|
13
13
|
if (!ctx)
|
|
14
|
-
throw new Error("
|
|
14
|
+
throw new Error("useCurrentNode must be used inside a component View rendered by <PrefabRoot>");
|
|
15
15
|
return ctx;
|
|
16
16
|
}
|
|
17
|
-
export function
|
|
18
|
-
const {
|
|
19
|
-
return useMemo(() => ({ get current() { return
|
|
17
|
+
export function useCurrentNodeObject() {
|
|
18
|
+
const { getCurrentNodeObject } = useCurrentNode();
|
|
19
|
+
return useMemo(() => ({ get current() { return getCurrentNodeObject(); } }), [getCurrentNodeObject]);
|
|
20
20
|
}
|
|
21
|
-
export function
|
|
22
|
-
const {
|
|
23
|
-
return useMemo(() => ({ get current() { return
|
|
21
|
+
export function useCurrentNodeHandle(kind) {
|
|
22
|
+
const { getCurrentNodeHandle } = useCurrentNode();
|
|
23
|
+
return useMemo(() => ({ get current() { return getCurrentNodeHandle(kind); } }), [getCurrentNodeHandle, kind]);
|
|
24
24
|
}
|
|
25
|
-
export function
|
|
25
|
+
export function CurrentNodeScope({ nodeId, editMode, isSelected, children, }) {
|
|
26
26
|
const asset = useContext(AssetRuntimeContext);
|
|
27
27
|
if (!asset)
|
|
28
|
-
throw new Error("
|
|
28
|
+
throw new Error("CurrentNodeScope must be used inside <PrefabRoot>");
|
|
29
29
|
const value = useMemo(() => ({
|
|
30
30
|
nodeId,
|
|
31
31
|
editMode,
|
|
32
32
|
isSelected,
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
getCurrentNodeObject: () => asset.getNodeObject(nodeId),
|
|
34
|
+
getCurrentNodeHandle: (kind) => asset.getNodeHandle(nodeId, kind),
|
|
35
35
|
}), [asset, editMode, isSelected, nodeId]);
|
|
36
|
-
return _jsx(
|
|
36
|
+
return _jsx(CurrentNodeRuntimeContext.Provider, { value: value, children: children });
|
|
37
37
|
}
|
|
@@ -52,7 +52,7 @@ function BufferArrayField({ label, value, fallback, onChange, rows = 4, }) {
|
|
|
52
52
|
function BufferGeometryComponentEditor({ component, onUpdate, }) {
|
|
53
53
|
var _a;
|
|
54
54
|
const properties = (_a = component.properties) !== null && _a !== void 0 ? _a : {};
|
|
55
|
-
return (_jsxs(FieldGroup, { children: [_jsx(BufferArrayField, { label: "Positions", value: properties.positions, fallback: DEFAULT_TRIANGLE_POSITIONS, rows: 5, onChange: (positions) => onUpdate({ positions }) }), _jsx(BufferArrayField, { label: "Indices", value: properties.indices, fallback: DEFAULT_TRIANGLE_INDICES, onChange: (indices) => onUpdate({ indices }) }), _jsx(BufferArrayField, { label: "Normals", value: properties.normals, fallback: [], onChange: (normals) => onUpdate({ normals }) }), _jsx(BufferArrayField, { label: "UVs", value: properties.uvs, fallback: DEFAULT_TRIANGLE_UVS, onChange: (uvs) => onUpdate({ uvs }) }), _jsx(BooleanField, { name: "computeVertexNormals", label: "Compute Normals", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "visible", label: "Visible", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "castShadow", label: "Cast Shadow", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "receiveShadow", label: "Receive Shadow", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "emitClickEvent", label: "Emit Click Event", values: properties, onChange: onUpdate, fallback: false }), properties.emitClickEvent ? (_jsx(StringField, { name: "clickEventName", label: "Click Event Name", values: properties, onChange: onUpdate, placeholder: "
|
|
55
|
+
return (_jsxs(FieldGroup, { children: [_jsx(BufferArrayField, { label: "Positions", value: properties.positions, fallback: DEFAULT_TRIANGLE_POSITIONS, rows: 5, onChange: (positions) => onUpdate({ positions }) }), _jsx(BufferArrayField, { label: "Indices", value: properties.indices, fallback: DEFAULT_TRIANGLE_INDICES, onChange: (indices) => onUpdate({ indices }) }), _jsx(BufferArrayField, { label: "Normals", value: properties.normals, fallback: [], onChange: (normals) => onUpdate({ normals }) }), _jsx(BufferArrayField, { label: "UVs", value: properties.uvs, fallback: DEFAULT_TRIANGLE_UVS, onChange: (uvs) => onUpdate({ uvs }) }), _jsx(BooleanField, { name: "computeVertexNormals", label: "Compute Normals", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "visible", label: "Visible", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "castShadow", label: "Cast Shadow", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "receiveShadow", label: "Receive Shadow", values: properties, onChange: onUpdate, fallback: true }), _jsx(BooleanField, { name: "emitClickEvent", label: "Emit Click Event", values: properties, onChange: onUpdate, fallback: false }), properties.emitClickEvent ? (_jsx(StringField, { name: "clickEventName", label: "Click Event Name", values: properties, onChange: onUpdate, placeholder: "node:click" })) : null] }));
|
|
56
56
|
}
|
|
57
57
|
function BufferGeometryComponentView({ properties }) {
|
|
58
58
|
const positions = normalizeNumberArray(properties.positions, DEFAULT_TRIANGLE_POSITIONS);
|
|
@@ -3,7 +3,7 @@ import { OrthographicCamera, PerspectiveCamera, useHelper } from '@react-three/d
|
|
|
3
3
|
import { useRef } from 'react';
|
|
4
4
|
import { CameraHelper } from 'three';
|
|
5
5
|
import { useFrame, useThree } from '@react-three/fiber';
|
|
6
|
-
import {
|
|
6
|
+
import { useCurrentNode } from '../assetRuntime';
|
|
7
7
|
import { FieldGroup, NumberField, SelectField } from './Input';
|
|
8
8
|
const CAMERA_PROJECTION_OPTIONS = [
|
|
9
9
|
{ value: 'perspective', label: 'Perspective' },
|
|
@@ -25,7 +25,7 @@ function CameraComponentEditor({ component, onUpdate }) {
|
|
|
25
25
|
}
|
|
26
26
|
function CameraComponentView({ properties, children }) {
|
|
27
27
|
var _a;
|
|
28
|
-
const { editMode, isSelected } =
|
|
28
|
+
const { editMode, isSelected } = useCurrentNode();
|
|
29
29
|
const { size } = useThree();
|
|
30
30
|
const merged = Object.assign(Object.assign({}, cameraDefaults), properties);
|
|
31
31
|
const projection = (_a = merged.projection) !== null && _a !== void 0 ? _a : cameraDefaults.projection;
|