react-three-game 0.0.92 → 0.0.94
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 +81 -88
- package/dist/helpers/index.d.ts +0 -3
- package/dist/helpers/index.js +1 -8
- package/dist/index.d.ts +10 -10
- package/dist/index.js +7 -6
- package/dist/tools/prefabeditor/EditorTree.js +10 -14
- package/dist/tools/prefabeditor/EditorUI.js +4 -4
- 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 +12 -21
- package/dist/tools/prefabeditor/PrefabEditor.js +138 -146
- package/dist/tools/prefabeditor/PrefabRoot.d.ts +30 -11
- package/dist/tools/prefabeditor/PrefabRoot.js +182 -139
- package/dist/tools/prefabeditor/assetRuntime.d.ts +9 -13
- package/dist/tools/prefabeditor/assetRuntime.js +13 -13
- 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 +2 -2
- package/dist/tools/prefabeditor/components/Input.js +5 -9
- package/dist/tools/prefabeditor/components/ModelComponent.js +4 -6
- 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/prefab.d.ts +1 -2
- package/dist/tools/prefabeditor/prefab.js +2 -3
- package/dist/tools/prefabeditor/prefabStore.d.ts +0 -6
- package/dist/tools/prefabeditor/prefabStore.js +1 -33
- 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 +49 -51
- package/dist/tools/prefabeditor/components/PhysicsComponent.d.ts +0 -26
- package/dist/tools/prefabeditor/components/PhysicsComponent.js +0 -302
- package/dist/tools/prefabeditor/scene.d.ts +0 -70
- package/dist/tools/prefabeditor/scene.js +0 -237
|
@@ -9,8 +9,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx,
|
|
13
|
-
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
+
import { createContext, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
14
14
|
import { Euler, Matrix4, } from "three";
|
|
15
15
|
import { useStore } from "zustand";
|
|
16
16
|
import { useClickValid } from "./useClickValid";
|
|
@@ -20,9 +20,8 @@ import { builtinComponents } from "./components";
|
|
|
20
20
|
import { loadModel, loadSound, loadTexture } from "../dragdrop";
|
|
21
21
|
import { GameInstance, GameInstanceProvider, getRepeatAxesFromModelProperties, useInstanceCheck } from "./InstanceProvider";
|
|
22
22
|
import { composeTransform, decompose } from "./utils";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { AssetRuntimeContext, EntityRuntimeScope } from "./assetRuntime";
|
|
23
|
+
import { createPrefabStore, PrefabStoreProvider, usePrefabChildIds, usePrefabNode, usePrefabRootId } from "./prefabStore";
|
|
24
|
+
import { AssetRuntimeContext, NodeScope } from "./assetRuntime";
|
|
26
25
|
import { gameEvents } from "./GameEvents";
|
|
27
26
|
import { sound as soundManager } from "../../helpers/SoundManager";
|
|
28
27
|
builtinComponents.forEach(registerComponent);
|
|
@@ -36,30 +35,13 @@ function resolveAssetPath(basePath, file) {
|
|
|
36
35
|
return file;
|
|
37
36
|
return file.startsWith("/") ? `${basePath}${file}` : `${basePath}/${file}`;
|
|
38
37
|
}
|
|
39
|
-
/** Check if
|
|
40
|
-
function isNodeReady(
|
|
38
|
+
/** Check if a model component's assets are loaded. */
|
|
39
|
+
function isNodeReady(model, loadedModels) {
|
|
41
40
|
var _a;
|
|
42
|
-
const model = findComponent(node, "Model");
|
|
43
41
|
if (!((_a = model === null || model === void 0 ? void 0 : model.properties) === null || _a === void 0 ? void 0 : _a.filename))
|
|
44
42
|
return true;
|
|
45
43
|
return Boolean(loadedModels[model.properties.filename]);
|
|
46
44
|
}
|
|
47
|
-
function getNodeClickEventName(node) {
|
|
48
|
-
var _a;
|
|
49
|
-
const clickComponents = [
|
|
50
|
-
findComponent(node, 'BufferGeometry'),
|
|
51
|
-
findComponent(node, 'Geometry'),
|
|
52
|
-
];
|
|
53
|
-
for (const component of clickComponents) {
|
|
54
|
-
if (!((_a = component === null || component === void 0 ? void 0 : component.properties) === null || _a === void 0 ? void 0 : _a.emitClickEvent))
|
|
55
|
-
continue;
|
|
56
|
-
const eventName = component.properties.clickEventName;
|
|
57
|
-
if (typeof eventName === 'string' && eventName.trim()) {
|
|
58
|
-
return eventName.trim();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
45
|
function getNodeMetadataProps(node) {
|
|
64
46
|
var _a, _b;
|
|
65
47
|
const nodeName = (_b = (_a = node.name) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
|
|
@@ -68,8 +50,20 @@ function getNodeMetadataProps(node) {
|
|
|
68
50
|
userData: Object.assign(Object.assign({ prefabNodeId: node.id }, (nodeName ? { prefabNodeName: nodeName } : {})), getNodeUserData(node)),
|
|
69
51
|
};
|
|
70
52
|
}
|
|
71
|
-
export
|
|
72
|
-
|
|
53
|
+
export var PrefabEditorMode;
|
|
54
|
+
(function (PrefabEditorMode) {
|
|
55
|
+
PrefabEditorMode["Edit"] = "edit";
|
|
56
|
+
PrefabEditorMode["Play"] = "play";
|
|
57
|
+
})(PrefabEditorMode || (PrefabEditorMode = {}));
|
|
58
|
+
export const SceneContext = createContext(null);
|
|
59
|
+
export function useScene() {
|
|
60
|
+
const scene = useContext(SceneContext);
|
|
61
|
+
if (!scene) {
|
|
62
|
+
throw new Error("useScene must be used within a PrefabRoot or PrefabEditor scene provider");
|
|
63
|
+
}
|
|
64
|
+
return scene;
|
|
65
|
+
}
|
|
66
|
+
export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick, onEditNodeClick, basePath = "", children }, ref) => {
|
|
73
67
|
const [models, setModels] = useState({});
|
|
74
68
|
const [textures, setTextures] = useState({});
|
|
75
69
|
const [sounds, setSounds] = useState({});
|
|
@@ -81,19 +75,17 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
81
75
|
const failedTextures = useRef(new Set());
|
|
82
76
|
const failedSounds = useRef(new Set());
|
|
83
77
|
const objectRefs = useRef({});
|
|
84
|
-
const
|
|
85
|
-
const rootRef = useRef(null);
|
|
86
|
-
const parentStore = useOptionalPrefabStoreApi();
|
|
78
|
+
const nodeHandles = useRef(new Map());
|
|
87
79
|
const [ownedStore] = useState(() => {
|
|
80
|
+
if (store)
|
|
81
|
+
return null;
|
|
88
82
|
if (data)
|
|
89
83
|
return createPrefabStore(data);
|
|
90
|
-
if (store || parentStore)
|
|
91
|
-
return null;
|
|
92
84
|
throw new Error("PrefabRoot requires either a `data` or `store` prop");
|
|
93
85
|
});
|
|
94
|
-
const resolvedStore =
|
|
86
|
+
const resolvedStore = store !== null && store !== void 0 ? store : ownedStore;
|
|
95
87
|
const usesOwnedStore = resolvedStore === ownedStore;
|
|
96
|
-
const
|
|
88
|
+
const rootId = useStore(resolvedStore, state => state.rootId);
|
|
97
89
|
const assetManifestKey = useStore(resolvedStore, state => state.assetManifestKey);
|
|
98
90
|
const availableModels = useMemo(() => (Object.assign(Object.assign({}, models), injectedModels)), [models, injectedModels]);
|
|
99
91
|
const availableTextures = useMemo(() => (Object.assign(Object.assign({}, textures), injectedTextures)), [textures, injectedTextures]);
|
|
@@ -102,27 +94,61 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
102
94
|
var _a;
|
|
103
95
|
return (_a = objectRefs.current[id]) !== null && _a !== void 0 ? _a : null;
|
|
104
96
|
}, []);
|
|
105
|
-
const
|
|
97
|
+
const getHandle = useCallback((id, kind) => {
|
|
98
|
+
var _a, _b;
|
|
99
|
+
return (_b = (_a = nodeHandles.current.get(id)) === null || _a === void 0 ? void 0 : _a.get(kind)) !== null && _b !== void 0 ? _b : null;
|
|
100
|
+
}, []);
|
|
101
|
+
const getNode = useCallback((nodeId) => {
|
|
106
102
|
var _a;
|
|
107
|
-
return (_a =
|
|
103
|
+
return (_a = resolvedStore.getState().nodesById[nodeId]) !== null && _a !== void 0 ? _a : null;
|
|
104
|
+
}, [resolvedStore]);
|
|
105
|
+
const registerHandle = useCallback((id, kind, handle) => {
|
|
106
|
+
const current = nodeHandles.current.get(id);
|
|
107
|
+
if (handle == null) {
|
|
108
|
+
if (!current)
|
|
109
|
+
return;
|
|
110
|
+
current.delete(kind);
|
|
111
|
+
if (current.size === 0) {
|
|
112
|
+
nodeHandles.current.delete(id);
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (current) {
|
|
117
|
+
current.set(kind, handle);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
nodeHandles.current.set(id, new Map([[kind, handle]]));
|
|
108
121
|
}, []);
|
|
109
|
-
|
|
110
|
-
root
|
|
122
|
+
const sceneValue = useMemo(() => ({
|
|
123
|
+
get root() {
|
|
124
|
+
var _a;
|
|
125
|
+
return (_a = objectRefs.current[rootId]) !== null && _a !== void 0 ? _a : null;
|
|
126
|
+
},
|
|
127
|
+
mode: editMode ? PrefabEditorMode.Edit : PrefabEditorMode.Play,
|
|
128
|
+
get: getNode,
|
|
111
129
|
getObject,
|
|
112
|
-
|
|
130
|
+
getHandle,
|
|
131
|
+
add: (node, parentId) => {
|
|
132
|
+
const state = resolvedStore.getState();
|
|
133
|
+
state.addChild(parentId !== null && parentId !== void 0 ? parentId : state.rootId, node);
|
|
134
|
+
return node;
|
|
135
|
+
},
|
|
136
|
+
update: (id, fn) => resolvedStore.getState().updateNode(id, fn),
|
|
137
|
+
remove: (id) => resolvedStore.getState().deleteNode(id),
|
|
138
|
+
duplicate: (id) => resolvedStore.getState().duplicateNode(id),
|
|
139
|
+
move: (draggedId, targetId, position) => resolvedStore.getState().moveNode(draggedId, targetId, position),
|
|
140
|
+
replace: (prefab) => resolvedStore.getState().replacePrefab(prefab),
|
|
113
141
|
addModel: (path, model) => setInjectedModels(prev => (Object.assign(Object.assign({}, prev), { [path]: model }))),
|
|
114
142
|
addTexture: (path, texture) => setInjectedTextures(prev => (Object.assign(Object.assign({}, prev), { [path]: texture }))),
|
|
115
143
|
addSound: (path, sound) => {
|
|
116
144
|
soundManager.setBuffer(path, sound);
|
|
117
145
|
setInjectedSounds(prev => (Object.assign(Object.assign({}, prev), { [path]: sound })));
|
|
118
146
|
},
|
|
119
|
-
}), [getObject]);
|
|
147
|
+
}), [editMode, getHandle, getNode, getObject, resolvedStore, rootId]);
|
|
148
|
+
useImperativeHandle(ref, () => sceneValue, [sceneValue]);
|
|
120
149
|
const registerRef = useCallback((id, obj) => {
|
|
121
150
|
objectRefs.current[id] = obj;
|
|
122
151
|
}, []);
|
|
123
|
-
const registerRigidBodyRef = useCallback((id, rb) => {
|
|
124
|
-
rigidBodyRefs.current.set(id, rb);
|
|
125
|
-
}, []);
|
|
126
152
|
useEffect(() => {
|
|
127
153
|
if (usesOwnedStore && data) {
|
|
128
154
|
resolvedStore.getState().replacePrefab(data);
|
|
@@ -154,31 +180,27 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
154
180
|
return;
|
|
155
181
|
loading.current.add(file);
|
|
156
182
|
void loader(resolveAssetPath(basePath, file)).then(result => {
|
|
183
|
+
loading.current.delete(file);
|
|
157
184
|
if (!result.success) {
|
|
158
185
|
console.warn(`Failed to load asset: ${file}`, result.error);
|
|
159
|
-
loading.current.delete(file);
|
|
160
186
|
failed.add(file);
|
|
161
187
|
}
|
|
162
188
|
});
|
|
163
189
|
};
|
|
164
|
-
modelsToLoad.forEach(file => loadAsset(file, models, injectedModels, failedModels.current,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
setModels(m => (Object.assign(Object.assign({}, m), { [file]: model })));
|
|
168
|
-
}
|
|
190
|
+
modelsToLoad.forEach(file => loadAsset(file, models, injectedModels, failedModels.current, path => loadModel(path).then(result => {
|
|
191
|
+
if (result.success && result.model)
|
|
192
|
+
setModels(m => (Object.assign(Object.assign({}, m), { [file]: result.model })));
|
|
169
193
|
return result;
|
|
170
194
|
})));
|
|
171
|
-
texturesToLoad.forEach(file => loadAsset(file, textures, injectedTextures, failedTextures.current,
|
|
172
|
-
if (result.success && result.texture)
|
|
195
|
+
texturesToLoad.forEach(file => loadAsset(file, textures, injectedTextures, failedTextures.current, path => loadTexture(path).then(result => {
|
|
196
|
+
if (result.success && result.texture)
|
|
173
197
|
setTextures(t => (Object.assign(Object.assign({}, t), { [file]: result.texture })));
|
|
174
|
-
}
|
|
175
198
|
return result;
|
|
176
199
|
})));
|
|
177
|
-
soundsToLoad.forEach(file => loadAsset(file, sounds, injectedSounds, failedSounds.current,
|
|
200
|
+
soundsToLoad.forEach(file => loadAsset(file, sounds, injectedSounds, failedSounds.current, path => loadSound(path).then(result => {
|
|
178
201
|
if (result.success && result.sound) {
|
|
179
202
|
soundManager.setBuffer(file, result.sound);
|
|
180
|
-
setSounds(
|
|
181
|
-
loading.current.delete(file);
|
|
203
|
+
setSounds(s => (Object.assign(Object.assign({}, s), { [file]: result.sound })));
|
|
182
204
|
}
|
|
183
205
|
return result;
|
|
184
206
|
})));
|
|
@@ -186,25 +208,83 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
186
208
|
syncAssets();
|
|
187
209
|
}, [resolvedStore, assetManifestKey, basePath, injectedModels, injectedSounds, injectedTextures, models, sounds, textures]);
|
|
188
210
|
const assetRuntime = useMemo(() => ({
|
|
211
|
+
registerHandle,
|
|
212
|
+
getHandle,
|
|
189
213
|
getObject,
|
|
190
|
-
getRigidBody,
|
|
191
|
-
registerRigidBodyRef,
|
|
192
214
|
getModel: (path) => { var _a; return (_a = availableModels[path]) !== null && _a !== void 0 ? _a : null; },
|
|
193
215
|
getTexture: (path) => { var _a; return (_a = availableTextures[path]) !== null && _a !== void 0 ? _a : null; },
|
|
194
216
|
getSound: (path) => { var _a; return (_a = availableSounds[path]) !== null && _a !== void 0 ? _a : null; },
|
|
195
217
|
getAssetRevision: () => `${Object.keys(availableTextures).sort().join('|')}::${Object.keys(availableModels).sort().join('|')}`,
|
|
196
|
-
}), [
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
218
|
+
}), [registerHandle, getHandle, getObject, availableModels, availableTextures, availableSounds]);
|
|
219
|
+
const handleNodeClick = useCallback((event, nodeId, fallbackObject) => {
|
|
220
|
+
const node = resolvedStore.getState().nodesById[nodeId];
|
|
221
|
+
if (!node)
|
|
222
|
+
return;
|
|
223
|
+
const { clickEventName } = analyzeNodeComponents(node);
|
|
224
|
+
emitNodePointerEvent(clickEventName, event, nodeId, node, fallbackObject);
|
|
225
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event, node);
|
|
226
|
+
}, [onClick, resolvedStore]);
|
|
227
|
+
const content = (_jsxs(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 }), children] }));
|
|
228
|
+
const runtimeContent = (_jsx(SceneContext.Provider, { value: sceneValue, children: _jsx(AssetRuntimeContext.Provider, { value: assetRuntime, children: content }) }));
|
|
202
229
|
return _jsx(PrefabStoreProvider, { store: resolvedStore, children: runtimeContent });
|
|
203
230
|
});
|
|
204
231
|
function StoreRootNode(props) {
|
|
205
232
|
const rootId = usePrefabRootId();
|
|
206
233
|
return _jsx(GameObjectRenderer, Object.assign({}, props, { nodeId: rootId }));
|
|
207
234
|
}
|
|
235
|
+
function getClickEventName(component) {
|
|
236
|
+
var _a;
|
|
237
|
+
if (!((_a = component === null || component === void 0 ? void 0 : component.properties) === null || _a === void 0 ? void 0 : _a.emitClickEvent))
|
|
238
|
+
return null;
|
|
239
|
+
const eventName = component.properties.clickEventName;
|
|
240
|
+
return typeof eventName === 'string' && eventName.trim() ? eventName.trim() : null;
|
|
241
|
+
}
|
|
242
|
+
function analyzeNodeComponents(node) {
|
|
243
|
+
var _a, _b, _c;
|
|
244
|
+
let bufferGeometry;
|
|
245
|
+
let geometry;
|
|
246
|
+
let material;
|
|
247
|
+
let model;
|
|
248
|
+
const composition = [];
|
|
249
|
+
for (const [key, component] of Object.entries((_a = node.components) !== null && _a !== void 0 ? _a : {})) {
|
|
250
|
+
if (!(component === null || component === void 0 ? void 0 : component.type))
|
|
251
|
+
continue;
|
|
252
|
+
switch (component.type) {
|
|
253
|
+
case "Transform":
|
|
254
|
+
break;
|
|
255
|
+
case "BufferGeometry":
|
|
256
|
+
bufferGeometry = component;
|
|
257
|
+
break;
|
|
258
|
+
case "Geometry":
|
|
259
|
+
geometry = component;
|
|
260
|
+
break;
|
|
261
|
+
case "Material":
|
|
262
|
+
material = component;
|
|
263
|
+
break;
|
|
264
|
+
case "Model":
|
|
265
|
+
model = component;
|
|
266
|
+
break;
|
|
267
|
+
default: {
|
|
268
|
+
const def = getComponentDef(component.type);
|
|
269
|
+
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
270
|
+
break;
|
|
271
|
+
composition.push({
|
|
272
|
+
key,
|
|
273
|
+
View: def.View,
|
|
274
|
+
properties: component.properties,
|
|
275
|
+
});
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
geometry: bufferGeometry !== null && bufferGeometry !== void 0 ? bufferGeometry : geometry,
|
|
282
|
+
material,
|
|
283
|
+
model,
|
|
284
|
+
clickEventName: (_c = (_b = getClickEventName(bufferGeometry)) !== null && _b !== void 0 ? _b : getClickEventName(geometry)) !== null && _c !== void 0 ? _c : getClickEventName(model),
|
|
285
|
+
composition,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
208
288
|
function emitNodePointerEvent(eventName, event, nodeId, node, fallbackObject) {
|
|
209
289
|
var _a;
|
|
210
290
|
const trimmedEventName = eventName === null || eventName === void 0 ? void 0 : eventName.trim();
|
|
@@ -247,21 +327,19 @@ export function GameObjectRenderer(props) {
|
|
|
247
327
|
? _jsx(InstancedNode, Object.assign({}, props), key)
|
|
248
328
|
: _jsx(StandardNode, Object.assign({}, props), key);
|
|
249
329
|
}
|
|
250
|
-
function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef, onSelect, onClick }) {
|
|
330
|
+
function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef, onSelect, onEditNodeClick, onClick, isVisible = true }) {
|
|
251
331
|
var _a, _b;
|
|
252
332
|
const gameObject = usePrefabNode(nodeId);
|
|
253
333
|
if (!gameObject)
|
|
254
334
|
return null;
|
|
335
|
+
const analyzedComponents = useMemo(() => analyzeNodeComponents(gameObject), [gameObject]);
|
|
255
336
|
const localTransform = getNodeTransformProps(gameObject);
|
|
256
337
|
const isLocked = Boolean(gameObject.locked);
|
|
338
|
+
const nodeVisible = isVisible && !gameObject.hidden;
|
|
257
339
|
const metadataProps = getNodeMetadataProps(gameObject);
|
|
258
|
-
const groupProps = Object.assign(Object.assign({}, metadataProps), { position: localTransform.position, rotation: localTransform.rotation, scale: localTransform.scale });
|
|
259
|
-
const
|
|
260
|
-
const
|
|
261
|
-
? physicsData === null || physicsData === void 0 ? void 0 : physicsData.properties
|
|
262
|
-
: undefined;
|
|
263
|
-
const modelUrl = (_b = (_a = findComponent(gameObject, "Model")) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.filename;
|
|
264
|
-
const instances = useMemo(() => buildRepeatedInstances(gameObject, parentMatrix, modelUrl, physicsProps), [gameObject, modelUrl, parentMatrix, physicsProps]);
|
|
340
|
+
const groupProps = Object.assign(Object.assign({}, metadataProps), { visible: nodeVisible, position: localTransform.position, rotation: localTransform.rotation, scale: localTransform.scale });
|
|
341
|
+
const modelUrl = (_b = (_a = analyzedComponents.model) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.filename;
|
|
342
|
+
const instances = useMemo(() => buildRepeatedInstances(gameObject, parentMatrix, modelUrl), [gameObject, modelUrl, parentMatrix]);
|
|
265
343
|
const groupRef = useRef(null);
|
|
266
344
|
const handleGroupRef = useCallback((object) => {
|
|
267
345
|
groupRef.current = object;
|
|
@@ -271,24 +349,24 @@ function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef,
|
|
|
271
349
|
}, [editMode, nodeId, registerRef]);
|
|
272
350
|
const editClickHandlers = useClickValid(!!editMode && !isLocked, (event) => {
|
|
273
351
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(nodeId);
|
|
274
|
-
|
|
352
|
+
onEditNodeClick === null || onEditNodeClick === void 0 ? void 0 : onEditNodeClick(event, gameObject);
|
|
275
353
|
});
|
|
276
|
-
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,
|
|
354
|
+
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)));
|
|
277
355
|
if (editMode) {
|
|
278
356
|
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] }));
|
|
279
357
|
}
|
|
280
358
|
return _jsx(_Fragment, { children: renderedInstances });
|
|
281
359
|
}
|
|
282
|
-
function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, loadedModels, editMode, parentMatrix = IDENTITY, }) {
|
|
283
|
-
var _a, _b;
|
|
360
|
+
function StandardNode({ nodeId, selectedId, onSelect, onClick, onEditNodeClick, registerRef, loadedModels, editMode, parentMatrix = IDENTITY, isVisible = true, }) {
|
|
284
361
|
const gameObject = usePrefabNode(nodeId);
|
|
285
362
|
const childIds = usePrefabChildIds(nodeId);
|
|
286
363
|
if (!gameObject)
|
|
287
364
|
return null;
|
|
365
|
+
const analyzedComponents = useMemo(() => analyzeNodeComponents(gameObject), [gameObject]);
|
|
288
366
|
const isSelected = selectedId === nodeId;
|
|
289
367
|
const isLocked = Boolean(gameObject.locked);
|
|
368
|
+
const nodeVisible = isVisible && !gameObject.hidden;
|
|
290
369
|
const stillInstanced = useInstanceCheck(nodeId);
|
|
291
|
-
const clickEventName = getNodeClickEventName(gameObject);
|
|
292
370
|
const metadataProps = getNodeMetadataProps(gameObject);
|
|
293
371
|
const groupRef = useRef(null);
|
|
294
372
|
const handleGroupRef = useCallback((object) => {
|
|
@@ -297,21 +375,18 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, load
|
|
|
297
375
|
}, [nodeId, registerRef]);
|
|
298
376
|
const editClickHandlers = useClickValid(!!editMode && !isLocked, (event) => {
|
|
299
377
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(nodeId);
|
|
300
|
-
|
|
378
|
+
onEditNodeClick === null || onEditNodeClick === void 0 ? void 0 : onEditNodeClick(event, gameObject);
|
|
301
379
|
});
|
|
302
|
-
const primaryClickHandlers = !editMode &&
|
|
380
|
+
const primaryClickHandlers = !editMode && onClick
|
|
303
381
|
? {
|
|
304
382
|
onClick: (event) => {
|
|
305
383
|
event.stopPropagation();
|
|
306
|
-
|
|
307
|
-
onClick === null || onClick === void 0 ? void 0 : onClick(event, gameObject);
|
|
384
|
+
onClick(event, nodeId, groupRef.current);
|
|
308
385
|
},
|
|
309
386
|
}
|
|
310
387
|
: undefined;
|
|
311
388
|
const world = parentMatrix.clone().multiply(compose(gameObject));
|
|
312
|
-
const
|
|
313
|
-
const ready = isNodeReady(gameObject, loadedModels);
|
|
314
|
-
const hasPhysics = physics && ready && !stillInstanced;
|
|
389
|
+
const ready = isNodeReady(analyzedComponents.model, loadedModels);
|
|
315
390
|
const transform = getNodeTransformProps(gameObject);
|
|
316
391
|
const transformProps = {
|
|
317
392
|
position: transform.position,
|
|
@@ -319,40 +394,11 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, load
|
|
|
319
394
|
scale: transform.scale,
|
|
320
395
|
};
|
|
321
396
|
const groupProps = Object.assign(Object.assign({}, metadataProps), transformProps);
|
|
322
|
-
const
|
|
323
|
-
const
|
|
324
|
-
const physicsKey = `physics_${nodeId}_${isInstanced ? 'instanced' : 'standard'}`;
|
|
325
|
-
const renderCtx = { loadedModels, editMode, registerRef };
|
|
326
|
-
const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
|
|
327
|
-
const inner = renderCompositionNode(gameObject, renderCtx, primaryClickHandlers, childNodes);
|
|
397
|
+
const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, onEditNodeClick: onEditNodeClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode, isVisible: nodeVisible });
|
|
398
|
+
const inner = renderNodeContent(analyzedComponents, loadedModels, primaryClickHandlers, childNodes);
|
|
328
399
|
const editAnchor = editMode ? (_jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) })) : null;
|
|
329
|
-
const standardNode = (_jsxs("group", Object.assign({ ref: handleGroupRef }, groupProps, (editMode ? editClickHandlers : undefined), { children: [editAnchor, inner] })));
|
|
330
|
-
|
|
331
|
-
return (_jsx(EntityRuntimeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: physicsNode !== null && physicsNode !== void 0 ? physicsNode : standardNode }));
|
|
332
|
-
}
|
|
333
|
-
function isRendererHandledComponent(componentType) {
|
|
334
|
-
return componentType === "Transform"
|
|
335
|
-
|| componentType === "BufferGeometry"
|
|
336
|
-
|| componentType === "Geometry"
|
|
337
|
-
|| componentType === "Material"
|
|
338
|
-
|| componentType === "Physics"
|
|
339
|
-
|| componentType === "Model";
|
|
340
|
-
}
|
|
341
|
-
function getCompositionComponents(gameObject) {
|
|
342
|
-
var _a;
|
|
343
|
-
return Object.entries((_a = gameObject.components) !== null && _a !== void 0 ? _a : {}).reduce((result, [key, comp]) => {
|
|
344
|
-
if (!(comp === null || comp === void 0 ? void 0 : comp.type) || isRendererHandledComponent(comp.type))
|
|
345
|
-
return result;
|
|
346
|
-
const def = getComponentDef(comp.type);
|
|
347
|
-
if (!(def === null || def === void 0 ? void 0 : def.View))
|
|
348
|
-
return result;
|
|
349
|
-
result.push({
|
|
350
|
-
key,
|
|
351
|
-
View: def.View,
|
|
352
|
-
properties: comp.properties,
|
|
353
|
-
});
|
|
354
|
-
return result;
|
|
355
|
-
}, []);
|
|
400
|
+
const standardNode = (_jsxs("group", Object.assign({ ref: handleGroupRef }, groupProps, { visible: nodeVisible }, (editMode ? editClickHandlers : undefined), { children: [editAnchor, inner] })));
|
|
401
|
+
return (_jsx(NodeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: standardNode }));
|
|
356
402
|
}
|
|
357
403
|
function ChildNodes(_a) {
|
|
358
404
|
var { childIds, parentMatrix } = _a, props = __rest(_a, ["childIds", "parentMatrix"]);
|
|
@@ -370,7 +416,7 @@ function getModelRepeatSettings(node) {
|
|
|
370
416
|
repeatAxes: getRepeatAxesFromModelProperties(properties),
|
|
371
417
|
};
|
|
372
418
|
}
|
|
373
|
-
function buildRepeatedInstances(gameObject, parentMatrix, modelUrl
|
|
419
|
+
function buildRepeatedInstances(gameObject, parentMatrix, modelUrl) {
|
|
374
420
|
if (!modelUrl)
|
|
375
421
|
return [];
|
|
376
422
|
const transform = getNodeTransformProps(gameObject);
|
|
@@ -407,7 +453,6 @@ function buildRepeatedInstances(gameObject, parentMatrix, modelUrl, physics) {
|
|
|
407
453
|
position,
|
|
408
454
|
rotation,
|
|
409
455
|
scale,
|
|
410
|
-
physics,
|
|
411
456
|
});
|
|
412
457
|
}
|
|
413
458
|
}
|
|
@@ -423,32 +468,30 @@ function getNodeTransformProps(node) {
|
|
|
423
468
|
scale: (_d = t === null || t === void 0 ? void 0 : t.scale) !== null && _d !== void 0 ? _d : [1, 1, 1],
|
|
424
469
|
};
|
|
425
470
|
}
|
|
426
|
-
function
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const
|
|
433
|
-
const material = findComponent(gameObject, "Material");
|
|
434
|
-
const model = findComponent(gameObject, "Model");
|
|
435
|
-
const geometryDef = geometry && getComponentDef(geometry.type);
|
|
436
|
-
const materialDef = material && getComponentDef(material.type);
|
|
437
|
-
const modelDef = model && getComponentDef(model.type);
|
|
438
|
-
const geometryProperties = (_b = geometry === null || geometry === void 0 ? void 0 : geometry.properties) !== null && _b !== void 0 ? _b : {};
|
|
471
|
+
function renderNodeContent(analyzedComponents, loadedModels, primaryClickHandlers, childNodes) {
|
|
472
|
+
var _a, _b, _c, _d;
|
|
473
|
+
const geometry = analyzedComponents.geometry;
|
|
474
|
+
const geometryDef = analyzedComponents.geometry && getComponentDef(analyzedComponents.geometry.type);
|
|
475
|
+
const materialDef = analyzedComponents.material && getComponentDef(analyzedComponents.material.type);
|
|
476
|
+
const modelDef = analyzedComponents.model && getComponentDef(analyzedComponents.model.type);
|
|
477
|
+
const geometryProperties = (_a = geometry === null || geometry === void 0 ? void 0 : geometry.properties) !== null && _a !== void 0 ? _a : {};
|
|
439
478
|
const meshVisible = geometryProperties.visible !== false;
|
|
440
479
|
const meshCastShadow = meshVisible && geometryProperties.castShadow !== false;
|
|
441
480
|
const meshReceiveShadow = meshVisible && geometryProperties.receiveShadow !== false;
|
|
442
|
-
|
|
443
|
-
|
|
481
|
+
let primaryContent = null;
|
|
482
|
+
if (((_b = analyzedComponents.geometry) === null || _b === void 0 ? void 0 : _b.type) && (geometryDef === null || geometryDef === void 0 ? void 0 : geometryDef.View)) {
|
|
483
|
+
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"))] })));
|
|
444
484
|
}
|
|
445
|
-
if ((
|
|
446
|
-
|
|
485
|
+
else if (((_c = analyzedComponents.model) === null || _c === void 0 ? void 0 : _c.type)
|
|
486
|
+
&& (modelDef === null || modelDef === void 0 ? void 0 : modelDef.View)
|
|
487
|
+
&& !((_d = analyzedComponents.model.properties) === null || _d === void 0 ? void 0 : _d.instanced)
|
|
488
|
+
&& isNodeReady(analyzedComponents.model, loadedModels)) {
|
|
489
|
+
primaryContent = primaryClickHandlers ? (_jsx("group", Object.assign({}, primaryClickHandlers, { children: _jsx(modelDef.View, { properties: analyzedComponents.model.properties }) }))) : (_jsx(modelDef.View, { properties: analyzedComponents.model.properties }));
|
|
447
490
|
}
|
|
448
|
-
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
return
|
|
491
|
+
let content = _jsxs(_Fragment, { children: [primaryContent, childNodes] });
|
|
492
|
+
for (const { key, View, properties } of analyzedComponents.composition) {
|
|
493
|
+
content = (_jsx(View, { properties: properties, children: content }, key));
|
|
494
|
+
}
|
|
495
|
+
return content;
|
|
453
496
|
}
|
|
454
497
|
export default PrefabRoot;
|
|
@@ -1,34 +1,30 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import type { Object3D, Texture } from "three";
|
|
3
3
|
export interface AssetRuntime {
|
|
4
|
-
|
|
4
|
+
registerHandle: (id: string, kind: string, handle: unknown) => void;
|
|
5
|
+
getHandle: <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
|
getObject: (id: string) => Object3D | null;
|
|
10
|
-
getRigidBody: (id: string) => any;
|
|
11
11
|
}
|
|
12
|
-
export interface
|
|
13
|
-
}
|
|
14
|
-
export interface EntityRuntime {
|
|
12
|
+
export interface NodeApi {
|
|
15
13
|
nodeId: string;
|
|
16
14
|
editMode?: boolean;
|
|
17
15
|
isSelected?: boolean;
|
|
18
16
|
getObject: <T extends Object3D = Object3D>() => T | null;
|
|
19
|
-
|
|
17
|
+
getHandle: <T = unknown>(kind: string) => T | null;
|
|
20
18
|
}
|
|
21
19
|
export interface LiveRef<T> {
|
|
22
20
|
readonly current: T | null;
|
|
23
21
|
}
|
|
24
|
-
export
|
|
25
|
-
export type LiveRigidBodyRef<T = any> = LiveRef<T>;
|
|
26
|
-
export declare const AssetRuntimeContext: import("react").Context<AssetRuntimeContextValue | null>;
|
|
22
|
+
export declare const AssetRuntimeContext: import("react").Context<AssetRuntime | null>;
|
|
27
23
|
export declare function useAssetRuntime(): AssetRuntime;
|
|
28
|
-
export declare function
|
|
29
|
-
export declare function
|
|
30
|
-
export declare function
|
|
31
|
-
export declare function
|
|
24
|
+
export declare function useNode(): NodeApi;
|
|
25
|
+
export declare function useNodeObject<T extends Object3D = Object3D>(): LiveRef<T>;
|
|
26
|
+
export declare function useNodeHandle<T = unknown>(kind: string): LiveRef<T>;
|
|
27
|
+
export declare function NodeScope({ nodeId, editMode, isSelected, children, }: {
|
|
32
28
|
nodeId: string;
|
|
33
29
|
editMode?: boolean;
|
|
34
30
|
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 NodeContext = 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 useNode() {
|
|
12
|
+
const ctx = useContext(NodeContext);
|
|
13
13
|
if (!ctx)
|
|
14
|
-
throw new Error("
|
|
14
|
+
throw new Error("useNode must be used inside a component View rendered by <PrefabRoot>");
|
|
15
15
|
return ctx;
|
|
16
16
|
}
|
|
17
|
-
export function
|
|
18
|
-
const { getObject } =
|
|
17
|
+
export function useNodeObject() {
|
|
18
|
+
const { getObject } = useNode();
|
|
19
19
|
return useMemo(() => ({ get current() { return getObject(); } }), [getObject]);
|
|
20
20
|
}
|
|
21
|
-
export function
|
|
22
|
-
const {
|
|
23
|
-
return useMemo(() => ({ get current() { return
|
|
21
|
+
export function useNodeHandle(kind) {
|
|
22
|
+
const { getHandle } = useNode();
|
|
23
|
+
return useMemo(() => ({ get current() { return getHandle(kind); } }), [getHandle, kind]);
|
|
24
24
|
}
|
|
25
|
-
export function
|
|
25
|
+
export function NodeScope({ nodeId, editMode, isSelected, children, }) {
|
|
26
26
|
const asset = useContext(AssetRuntimeContext);
|
|
27
27
|
if (!asset)
|
|
28
|
-
throw new Error("
|
|
28
|
+
throw new Error("NodeScope must be used inside <PrefabRoot>");
|
|
29
29
|
const value = useMemo(() => ({
|
|
30
30
|
nodeId,
|
|
31
31
|
editMode,
|
|
32
32
|
isSelected,
|
|
33
33
|
getObject: () => asset.getObject(nodeId),
|
|
34
|
-
|
|
34
|
+
getHandle: (kind) => asset.getHandle(nodeId, kind),
|
|
35
35
|
}), [asset, editMode, isSelected, nodeId]);
|
|
36
|
-
return _jsx(
|
|
36
|
+
return _jsx(NodeContext.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 { useNode } 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 } = useNode();
|
|
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;
|