react-three-game 0.0.108 → 0.0.109
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 +5 -5
- package/dist/editor.d.ts +22 -0
- package/dist/editor.js +15 -0
- package/dist/plugins/crashcat/CrashcatPhysicsComponent.js +1 -1
- package/dist/plugins/crashcat/CrashcatRuntime.js +1 -1
- package/dist/tools/prefabeditor/EditorContext.d.ts +36 -0
- package/dist/tools/prefabeditor/EditorContext.js +17 -0
- package/dist/tools/prefabeditor/EditorTree.js +1 -1
- package/dist/tools/prefabeditor/EditorTreeMenus.js +1 -1
- package/dist/tools/prefabeditor/EditorUI.js +1 -1
- package/dist/tools/prefabeditor/PrefabEditor.d.ts +4 -37
- package/dist/tools/prefabeditor/PrefabEditor.js +15 -30
- package/dist/tools/prefabeditor/PrefabRoot.d.ts +3 -27
- package/dist/tools/prefabeditor/PrefabRoot.js +79 -60
- package/dist/tools/prefabeditor/SceneContext.d.ts +28 -0
- package/dist/tools/prefabeditor/SceneContext.js +14 -0
- package/dist/tools/prefabeditor/assetRuntime.d.ts +4 -0
- package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +1 -1
- package/dist/tools/prefabeditor/components/ModelComponent.js +1 -1
- package/dist/tools/prefabeditor/components/PrefabRefComponent.js +4 -4
- package/dist/tools/prefabeditor/components/TransformComponent.js +1 -1
- package/dist/tools/prefabeditor/components/index.d.ts +1 -0
- package/dist/tools/prefabeditor/components/index.js +8 -0
- package/dist/tools/prefabeditor/components/runtime.d.ts +4 -0
- package/dist/tools/prefabeditor/components/runtime.js +372 -0
- package/dist/tools/prefabeditor/prefabStore.d.ts +1 -1
- package/dist/tools/prefabeditor/prefabStore.js +5 -1
- package/dist/tools/prefabeditor/runtimeUtils.d.ts +10 -0
- package/dist/tools/prefabeditor/runtimeUtils.js +30 -0
- package/dist/tools/prefabeditor/utils.d.ts +1 -9
- package/dist/tools/prefabeditor/utils.js +3 -28
- package/dist/viewer.d.ts +22 -0
- package/dist/viewer.js +14 -0
- package/package.json +10 -8
- package/dist/index.d.ts +0 -40
- package/dist/index.js +0 -32
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ npm install react-three-game @react-three/drei @react-three/fiber three
|
|
|
29
29
|
Here is a minimal example that renders a prefab inside a normal R3F app:
|
|
30
30
|
|
|
31
31
|
```tsx
|
|
32
|
-
import { GameCanvas, PrefabRoot, ground } from "react-three-game";
|
|
32
|
+
import { GameCanvas, PrefabRoot, ground } from "react-three-game/viewer";
|
|
33
33
|
|
|
34
34
|
const prefab = {
|
|
35
35
|
id: "starter-scene",
|
|
@@ -80,7 +80,7 @@ This example renders a simple authored prefab with a ground plane and mesh conte
|
|
|
80
80
|
In addition to the runtime renderer, there is a visual editor for authoring prefabs.
|
|
81
81
|
|
|
82
82
|
```tsx
|
|
83
|
-
import { PrefabEditor } from "react-three-game";
|
|
83
|
+
import { PrefabEditor } from "react-three-game/editor";
|
|
84
84
|
|
|
85
85
|
export default function App() {
|
|
86
86
|
return <PrefabEditor initialPrefab={prefab} onChange={console.log} />;
|
|
@@ -164,7 +164,7 @@ Use the editor or root ref for scene-native object access, and the `Scene` mutat
|
|
|
164
164
|
|
|
165
165
|
```tsx
|
|
166
166
|
import { useEffect, useRef } from "react";
|
|
167
|
-
import { PrefabEditor, type PrefabEditorRef } from "react-three-game";
|
|
167
|
+
import { PrefabEditor, type PrefabEditorRef } from "react-three-game/editor";
|
|
168
168
|
|
|
169
169
|
function RaiseBall() {
|
|
170
170
|
const editorRef = useRef<PrefabEditorRef>(null);
|
|
@@ -199,7 +199,7 @@ ball?.rotateY(0.5);
|
|
|
199
199
|
For runtime integrations that need to react to authored scene changes, subscribe through the prefab store:
|
|
200
200
|
|
|
201
201
|
```tsx
|
|
202
|
-
import { usePrefabStoreApi } from "react-three-game";
|
|
202
|
+
import { usePrefabStoreApi } from "react-three-game/editor";
|
|
203
203
|
|
|
204
204
|
const store = usePrefabStoreApi();
|
|
205
205
|
const stop = store.subscribe(
|
|
@@ -214,7 +214,7 @@ For runtime-owned imperative state, register node-local handles instead of reach
|
|
|
214
214
|
|
|
215
215
|
```tsx
|
|
216
216
|
import { useEffect } from "react";
|
|
217
|
-
import { useAssetRuntime, useNode, useNodeHandle } from "react-three-game";
|
|
217
|
+
import { useAssetRuntime, useNode, useNodeHandle } from "react-three-game/viewer";
|
|
218
218
|
|
|
219
219
|
function SpinnerView({ children }: { children?: React.ReactNode }) {
|
|
220
220
|
const { nodeId } = useNode();
|
package/dist/editor.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { registerBuiltinComponents } from "./tools/prefabeditor/components";
|
|
2
|
+
import "./viewer";
|
|
3
|
+
export { registerBuiltinComponents };
|
|
4
|
+
export * from "./viewer";
|
|
5
|
+
export { default as PrefabEditor } from "./tools/prefabeditor/PrefabEditor";
|
|
6
|
+
export type { PrefabEditorProps, PrefabEditorRef } from "./tools/prefabeditor/PrefabEditor";
|
|
7
|
+
export { useEditorContext, useEditorRef } from "./tools/prefabeditor/EditorContext";
|
|
8
|
+
export type { EditorContextType } from "./tools/prefabeditor/EditorContext";
|
|
9
|
+
export { usePrefabStore, usePrefabStoreApi } from "./tools/prefabeditor/prefabStore";
|
|
10
|
+
export type { PrefabStoreApi, PrefabStoreState } from "./tools/prefabeditor/prefabStore";
|
|
11
|
+
export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from "./tools/prefabeditor/components/Input";
|
|
12
|
+
export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from "./tools/prefabeditor/utils";
|
|
13
|
+
export type { ExportGLBOptions } from "./tools/prefabeditor/utils";
|
|
14
|
+
export { decomposeModelToPrefabNodes } from "./tools/prefabeditor/modelPrefab";
|
|
15
|
+
export type { DecomposeModelOptions } from "./tools/prefabeditor/modelPrefab";
|
|
16
|
+
export type { FieldDefinition, FieldType } from "./tools/prefabeditor/components/Input";
|
|
17
|
+
export { MaterialOverridesProvider, useMaterialOverrides } from "./tools/prefabeditor/components/MaterialComponent";
|
|
18
|
+
export type { MaterialOverrides } from "./tools/prefabeditor/components/MaterialComponent";
|
|
19
|
+
export { float, positionLocal, sin, time, uniform, vec3, } from "three/tsl";
|
|
20
|
+
export { loadFiles } from "./tools/dragdrop/DragDropLoader";
|
|
21
|
+
export type { AssetLoadOptions } from "./tools/dragdrop/DragDropLoader";
|
|
22
|
+
export { ModelListViewer, SoundListViewer, ModelPicker, SoundPicker, TextureListViewer, TexturePicker, SingleModelViewer, SingleSoundViewer, SingleTextureViewer, SharedCanvas, } from "./tools/assetviewer/page";
|
package/dist/editor.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { registerBuiltinComponents } from "./tools/prefabeditor/components";
|
|
2
|
+
import "./viewer";
|
|
3
|
+
registerBuiltinComponents();
|
|
4
|
+
export { registerBuiltinComponents };
|
|
5
|
+
export * from "./viewer";
|
|
6
|
+
export { default as PrefabEditor } from "./tools/prefabeditor/PrefabEditor";
|
|
7
|
+
export { useEditorContext, useEditorRef } from "./tools/prefabeditor/EditorContext";
|
|
8
|
+
export { usePrefabStore, usePrefabStoreApi } from "./tools/prefabeditor/prefabStore";
|
|
9
|
+
export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from "./tools/prefabeditor/components/Input";
|
|
10
|
+
export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from "./tools/prefabeditor/utils";
|
|
11
|
+
export { decomposeModelToPrefabNodes } from "./tools/prefabeditor/modelPrefab";
|
|
12
|
+
export { MaterialOverridesProvider, useMaterialOverrides } from "./tools/prefabeditor/components/MaterialComponent";
|
|
13
|
+
export { float, positionLocal, sin, time, uniform, vec3, } from "three/tsl";
|
|
14
|
+
export { loadFiles } from "./tools/dragdrop/DragDropLoader";
|
|
15
|
+
export { ModelListViewer, SoundListViewer, ModelPicker, SoundPicker, TextureListViewer, TexturePicker, SingleModelViewer, SingleSoundViewer, SingleTextureViewer, SharedCanvas, } from "./tools/assetviewer/page";
|
|
@@ -5,7 +5,7 @@ import { useEffect, useMemo, useRef } from "react";
|
|
|
5
5
|
import { BooleanField, FieldRenderer, StringField, Vector3Field, } from "../../tools/prefabeditor/components/Input";
|
|
6
6
|
import { useAssetRuntime, useNode } from "../../tools/prefabeditor/assetRuntime";
|
|
7
7
|
import { usePrefabStoreApi } from "../../tools/prefabeditor/prefabStore";
|
|
8
|
-
import { PrefabEditorMode, useScene } from "../../tools/prefabeditor/
|
|
8
|
+
import { PrefabEditorMode, useScene } from "../../tools/prefabeditor/SceneContext";
|
|
9
9
|
import { box, capsule, convexHull, MotionQuality, MotionType, rigidBody, sphere, triangleMesh, } from "crashcat";
|
|
10
10
|
import { Matrix4, Quaternion, Vector3 } from "three";
|
|
11
11
|
import { useCrashcat } from "./CrashcatRuntime";
|
|
@@ -5,7 +5,7 @@ import { addBroadphaseLayer, addObjectLayer, createWorld, createWorldSettings, e
|
|
|
5
5
|
import { debugRenderer } from "crashcat/three";
|
|
6
6
|
import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
7
7
|
import { gameEvents } from "../../tools/prefabeditor/GameEvents";
|
|
8
|
-
import { PrefabEditorMode, useScene } from "../../tools/prefabeditor/
|
|
8
|
+
import { PrefabEditorMode, useScene } from "../../tools/prefabeditor/SceneContext";
|
|
9
9
|
const SLEEP_TIME_BEFORE_REST = 0.1;
|
|
10
10
|
const SLEEP_POINT_VELOCITY_THRESHOLD = 0.06;
|
|
11
11
|
const MAX_PHYSICS_STEP_DELTA = 1 / 60;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { PrefabEditorMode, Scene } from "./SceneContext";
|
|
2
|
+
import type { Prefab } from "./types";
|
|
3
|
+
import type { ExportGLBOptions } from "./utils";
|
|
4
|
+
export interface PrefabEditorRef extends Scene {
|
|
5
|
+
save: () => Prefab;
|
|
6
|
+
load: (prefab: Prefab, options?: {
|
|
7
|
+
resetHistory?: boolean;
|
|
8
|
+
notifyChange?: boolean;
|
|
9
|
+
}) => void;
|
|
10
|
+
undo: () => void;
|
|
11
|
+
redo: () => void;
|
|
12
|
+
screenshot: () => void;
|
|
13
|
+
exportGLB: (options?: ExportGLBOptions) => Promise<ArrayBuffer | undefined>;
|
|
14
|
+
exportGLBData: () => Promise<ArrayBuffer | undefined>;
|
|
15
|
+
clearSelection: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export interface EditorContextType {
|
|
18
|
+
mode: PrefabEditorMode;
|
|
19
|
+
basePath: string;
|
|
20
|
+
setMode: (mode: PrefabEditorMode) => void;
|
|
21
|
+
transformMode: "translate" | "rotate" | "scale";
|
|
22
|
+
setTransformMode: (mode: "translate" | "rotate" | "scale") => void;
|
|
23
|
+
scaleSnap: number;
|
|
24
|
+
setScaleSnap: (resolution: number) => void;
|
|
25
|
+
positionSnap: number;
|
|
26
|
+
setPositionSnap: (resolution: number) => void;
|
|
27
|
+
rotationSnap: number;
|
|
28
|
+
setRotationSnap: (resolution: number) => void;
|
|
29
|
+
onFocusNode?: (nodeId: string) => void;
|
|
30
|
+
onScreenshot?: () => void;
|
|
31
|
+
onExportGLB?: () => void;
|
|
32
|
+
}
|
|
33
|
+
export declare const EditorContext: import("react").Context<EditorContextType | null>;
|
|
34
|
+
export declare const EditorRefContext: import("react").Context<PrefabEditorRef | null>;
|
|
35
|
+
export declare function useEditorContext(): EditorContextType;
|
|
36
|
+
export declare function useEditorRef(): PrefabEditorRef;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
export const EditorContext = createContext(null);
|
|
3
|
+
export const EditorRefContext = createContext(null);
|
|
4
|
+
export function useEditorContext() {
|
|
5
|
+
const context = useContext(EditorContext);
|
|
6
|
+
if (!context) {
|
|
7
|
+
throw new Error("useEditorContext must be used within EditorContext.Provider");
|
|
8
|
+
}
|
|
9
|
+
return context;
|
|
10
|
+
}
|
|
11
|
+
export function useEditorRef() {
|
|
12
|
+
const editorRef = useContext(EditorRefContext);
|
|
13
|
+
if (!editorRef) {
|
|
14
|
+
throw new Error("useEditorRef must be used within PrefabEditor");
|
|
15
|
+
}
|
|
16
|
+
return editorRef;
|
|
17
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useCallback, useState } from 'react';
|
|
3
3
|
import { base, colors, tree } from './styles';
|
|
4
|
-
import { useEditorContext, useEditorRef } from './
|
|
4
|
+
import { useEditorContext, useEditorRef } from './EditorContext';
|
|
5
5
|
import { Dropdown } from './Dropdown';
|
|
6
6
|
import { FileMenu, TreeContextMenu, TreeNodeMenu } from './EditorTreeMenus';
|
|
7
7
|
import { createEmptyNode, createPackedPrefabNode } from './prefab';
|
|
@@ -12,7 +12,7 @@ import { useEffect, useRef, useState } from 'react';
|
|
|
12
12
|
import { createPortal } from 'react-dom';
|
|
13
13
|
import { createEmptyPrefab } from './prefab';
|
|
14
14
|
import { menu } from './styles';
|
|
15
|
-
import { useEditorContext } from './
|
|
15
|
+
import { useEditorContext } from './EditorContext';
|
|
16
16
|
import { loadJson, loadJsonFile, saveJson, withBasePath } from './utils';
|
|
17
17
|
function MenuPanel({ children, style, }) {
|
|
18
18
|
return (_jsx("div", { style: Object.assign(Object.assign(Object.assign({}, menu.container), { position: 'static' }), style), onClick: (e) => e.stopPropagation(), children: children }));
|
|
@@ -14,7 +14,7 @@ import { useState } from 'react';
|
|
|
14
14
|
import EditorTree from './EditorTree';
|
|
15
15
|
import { canAddComponentToNode, getAllComponentDefs, getNextComponentKey } from './components/ComponentRegistry';
|
|
16
16
|
import { createComponentData } from './prefab';
|
|
17
|
-
import { useEditorRef } from './
|
|
17
|
+
import { useEditorRef } from './EditorContext';
|
|
18
18
|
import { base, colors, inspector, componentCard } from './styles';
|
|
19
19
|
import { usePrefabStore } from './prefabStore';
|
|
20
20
|
function EditorUI({ selectedId, setSelectedId, getPrefab, onReplacePrefab, onImportPrefab, basePath, onUndo, onRedo, canUndo, canRedo }) {
|
|
@@ -1,44 +1,11 @@
|
|
|
1
|
-
import GameCanvas from "../../shared/GameCanvas";
|
|
2
1
|
import type { Prefab } from "./types";
|
|
3
|
-
import {
|
|
4
|
-
import type
|
|
2
|
+
import { GameCanvas, PrefabEditorMode } from "../../viewer";
|
|
3
|
+
import { type PrefabEditorRef } from "./EditorContext";
|
|
5
4
|
export { isExternalPath as isAbsoluteAssetPath } from "./utils";
|
|
6
5
|
export declare function resolvePrefabAssetPath(basePath: string, file: string): string;
|
|
7
6
|
export declare function getPrefabAssetRef(assetRef: string, folder: "models" | "textures" | "sound"): string;
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
load: (prefab: Prefab, options?: {
|
|
11
|
-
resetHistory?: boolean;
|
|
12
|
-
notifyChange?: boolean;
|
|
13
|
-
}) => void;
|
|
14
|
-
undo: () => void;
|
|
15
|
-
redo: () => void;
|
|
16
|
-
screenshot: () => void;
|
|
17
|
-
exportGLB: (options?: ExportGLBOptions) => Promise<ArrayBuffer | undefined>;
|
|
18
|
-
exportGLBData: () => Promise<ArrayBuffer | undefined>;
|
|
19
|
-
clearSelection: () => Promise<void>;
|
|
20
|
-
}
|
|
21
|
-
export type { PrefabNode } from "./PrefabRoot";
|
|
22
|
-
export interface EditorContextType {
|
|
23
|
-
mode: PrefabEditorMode;
|
|
24
|
-
basePath: string;
|
|
25
|
-
setMode: (mode: PrefabEditorMode) => void;
|
|
26
|
-
transformMode: "translate" | "rotate" | "scale";
|
|
27
|
-
setTransformMode: (mode: "translate" | "rotate" | "scale") => void;
|
|
28
|
-
scaleSnap: number;
|
|
29
|
-
setScaleSnap: (resolution: number) => void;
|
|
30
|
-
positionSnap: number;
|
|
31
|
-
setPositionSnap: (resolution: number) => void;
|
|
32
|
-
rotationSnap: number;
|
|
33
|
-
setRotationSnap: (resolution: number) => void;
|
|
34
|
-
onFocusNode?: (nodeId: string) => void;
|
|
35
|
-
onScreenshot?: () => void;
|
|
36
|
-
onExportGLB?: () => void;
|
|
37
|
-
}
|
|
38
|
-
export declare const EditorContext: import("react").Context<EditorContextType | null>;
|
|
39
|
-
export declare const EditorRefContext: import("react").Context<PrefabEditorRef | null>;
|
|
40
|
-
export declare function useEditorContext(): EditorContextType;
|
|
41
|
-
export declare function useEditorRef(): PrefabEditorRef;
|
|
7
|
+
export type { EditorContextType, PrefabEditorRef } from "./EditorContext";
|
|
8
|
+
export { EditorContext, EditorRefContext, useEditorContext, useEditorRef } from "./EditorContext";
|
|
42
9
|
export interface PrefabEditorProps {
|
|
43
10
|
basePath?: string;
|
|
44
11
|
initialPrefab?: Prefab;
|
|
@@ -9,18 +9,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
11
|
import { MapControls, TransformControls, useHelper } from "@react-three/drei";
|
|
12
|
-
import
|
|
13
|
-
import { useCallback, useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle, createContext, useContext } from "react";
|
|
12
|
+
import { useCallback, useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle } from "react";
|
|
14
13
|
import { BoxHelper } from "three";
|
|
15
14
|
import { findComponentEntry } from "./types";
|
|
16
|
-
import {
|
|
15
|
+
import { GameCanvas, PrefabRoot, PrefabEditorMode, SceneContext, createImageNode, createModelNode, denormalizePrefab } from "../../viewer";
|
|
17
16
|
import EditorUI from "./EditorUI";
|
|
18
17
|
import { base, toolbar } from "./styles";
|
|
19
18
|
import { computeParentWorldMatrix, decompose, exportGLB as exportGLBFile, exportGLBData, focusCameraOnObject, isExternalPath, regenerateIds, withBasePath } from "./utils";
|
|
20
19
|
import { loadDroppedAssets } from "../dragdrop";
|
|
21
|
-
import {
|
|
20
|
+
import { createNode } from './prefab';
|
|
22
21
|
import { createPrefabStore, PrefabStoreProvider } from "./prefabStore";
|
|
23
22
|
import { decomposeModelToPrefabNodes, hasCollisionMeshConventions } from "./modelPrefab";
|
|
23
|
+
import { EditorContext, EditorRefContext } from "./EditorContext";
|
|
24
24
|
function isObjectAttachedToRoot(root, object) {
|
|
25
25
|
if (!root || !object)
|
|
26
26
|
return false;
|
|
@@ -48,22 +48,7 @@ function SelectionHelper({ object }) {
|
|
|
48
48
|
useHelper(helperTarget, BoxHelper, "cyan");
|
|
49
49
|
return null;
|
|
50
50
|
}
|
|
51
|
-
export
|
|
52
|
-
export const EditorRefContext = createContext(null);
|
|
53
|
-
export function useEditorContext() {
|
|
54
|
-
const context = useContext(EditorContext);
|
|
55
|
-
if (!context) {
|
|
56
|
-
throw new Error("useEditorContext must be used within EditorContext.Provider");
|
|
57
|
-
}
|
|
58
|
-
return context;
|
|
59
|
-
}
|
|
60
|
-
export function useEditorRef() {
|
|
61
|
-
const editorRef = useContext(EditorRefContext);
|
|
62
|
-
if (!editorRef) {
|
|
63
|
-
throw new Error("useEditorRef must be used within PrefabEditor");
|
|
64
|
-
}
|
|
65
|
-
return editorRef;
|
|
66
|
-
}
|
|
51
|
+
export { EditorContext, EditorRefContext, useEditorContext, useEditorRef } from "./EditorContext";
|
|
67
52
|
const MAX_HISTORY_LENGTH = 50;
|
|
68
53
|
const HISTORY_DEBOUNCE_MS = 500;
|
|
69
54
|
const DEFAULT_PREFAB = {
|
|
@@ -404,7 +389,7 @@ const PrefabEditor = forwardRef(({ basePath = "", initialPrefab, mode: initialMo
|
|
|
404
389
|
canvasRef.current = state.gl.domElement;
|
|
405
390
|
(_a = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onCreated) === null || _a === void 0 ? void 0 : _a.call(canvasProps, state);
|
|
406
391
|
}, [canvasProps]);
|
|
407
|
-
return _jsx(PrefabStoreProvider, { store: prefabStore, children: _jsx(EditorRefContext.Provider, { value: editorRefValue, children:
|
|
392
|
+
return _jsx(PrefabStoreProvider, { store: prefabStore, children: _jsx(EditorRefContext.Provider, { value: editorRefValue, children: _jsx(EditorContext.Provider, { value: {
|
|
408
393
|
mode,
|
|
409
394
|
basePath,
|
|
410
395
|
setMode: updateMode,
|
|
@@ -419,16 +404,16 @@ const PrefabEditor = forwardRef(({ basePath = "", initialPrefab, mode: initialMo
|
|
|
419
404
|
onFocusNode: isEditMode ? handleFocusNode : undefined,
|
|
420
405
|
onScreenshot: handleScreenshot,
|
|
421
406
|
onExportGLB: handleExportGLB
|
|
422
|
-
}, children: [_jsxs(GameCanvas, Object.assign({ camera: { position: [0, 5, 15] } }, canvasProps, { onCreated: handleCanvasCreated, onPointerMissed: isEditMode
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
407
|
+
}, children: _jsxs(SceneContext.Provider, { value: sceneValue, children: [_jsxs(GameCanvas, Object.assign({ camera: { position: [0, 5, 15] } }, canvasProps, { onCreated: handleCanvasCreated, onPointerMissed: isEditMode
|
|
408
|
+
? (event) => {
|
|
409
|
+
var _a, _b, _c, _d;
|
|
410
|
+
const button = (_c = (_a = event.button) !== null && _a !== void 0 ? _a : (_b = event.sourceEvent) === null || _b === void 0 ? void 0 : _b.button) !== null && _c !== void 0 ? _c : 0;
|
|
411
|
+
if (button === 0 && selectedId) {
|
|
412
|
+
setSelection(null);
|
|
413
|
+
}
|
|
414
|
+
(_d = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed) === null || _d === void 0 ? void 0 : _d.call(canvasProps, event);
|
|
428
415
|
}
|
|
429
|
-
|
|
430
|
-
}
|
|
431
|
-
: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [content, isEditMode ? _jsx(SelectionHelper, { object: transformObject }) : null, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { ref: transformControlsRef, object: transformObject, mode: transformMode, space: transformMode === "translate" ? "world" : "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${selectedId}-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("button", { type: "button", style: base.btn, onClick: toggleMode, children: isEditMode ? "▶" : "⏸" }), uiPlugins] }), isEditMode && (_jsx(EditorUI, { selectedId: selectedId, setSelectedId: setSelection, getPrefab: getPrefab, onReplacePrefab: (prefab) => loadPrefab(prefab, { resetHistory: true }), onImportPrefab: importPrefab, basePath: basePath, onUndo: undo, onRedo: redo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1 }))] }))] }) }) });
|
|
416
|
+
: canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [content, isEditMode ? _jsx(SelectionHelper, { object: transformObject }) : null, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { ref: transformControlsRef, object: transformObject, mode: transformMode, space: transformMode === "translate" ? "world" : "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${selectedId}-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("button", { type: "button", style: base.btn, onClick: toggleMode, children: isEditMode ? "▶" : "⏸" }), uiPlugins] }), isEditMode && (_jsx(EditorUI, { selectedId: selectedId, setSelectedId: setSelection, getPrefab: getPrefab, onReplacePrefab: (prefab) => loadPrefab(prefab, { resetHistory: true }), onImportPrefab: importPrefab, basePath: basePath, onUndo: undo, onRedo: redo, canUndo: historyIndex > 0, canRedo: historyIndex < history.length - 1 }))] }))] }) }) }) });
|
|
432
417
|
});
|
|
433
418
|
PrefabEditor.displayName = "PrefabEditor";
|
|
434
419
|
export default PrefabEditor;
|
|
@@ -1,35 +1,11 @@
|
|
|
1
1
|
import { Matrix4 } from "three";
|
|
2
|
-
import type { Object3D
|
|
2
|
+
import type { Object3D } from "three";
|
|
3
3
|
import { type ThreeEvent } from "@react-three/fiber";
|
|
4
4
|
import type { GameObject as GameObjectType, Prefab } from "./types";
|
|
5
5
|
import type { LoadedModels } from "../dragdrop";
|
|
6
6
|
import type { PrefabStoreApi } from "./prefabStore";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Play = "play"
|
|
10
|
-
}
|
|
11
|
-
export type PrefabNode = Omit<GameObjectType, "children">;
|
|
12
|
-
export interface Scene {
|
|
13
|
-
root: Object3D | null;
|
|
14
|
-
mode: PrefabEditorMode;
|
|
15
|
-
basePath: string;
|
|
16
|
-
get(id: string): GameObjectType | null;
|
|
17
|
-
getObject(id: string): Object3D | null;
|
|
18
|
-
getHandle<T = unknown>(id: string, kind: string): T | null;
|
|
19
|
-
getModel(path: string): Object3D | null;
|
|
20
|
-
add(node: GameObjectType, parentId?: string): GameObjectType;
|
|
21
|
-
update(id: string, fn: (node: PrefabNode) => PrefabNode): void;
|
|
22
|
-
replaceNode(id: string, node: GameObjectType): void;
|
|
23
|
-
remove(id: string): void;
|
|
24
|
-
duplicate(id: string): string | null;
|
|
25
|
-
move(draggedId: string, targetId: string, position: "before" | "inside"): void;
|
|
26
|
-
replace(prefab: Prefab): void;
|
|
27
|
-
addModel(path: string, model: Object3D): void;
|
|
28
|
-
addTexture(path: string, texture: Texture): void;
|
|
29
|
-
addSound(path: string, sound: AudioBuffer): void;
|
|
30
|
-
}
|
|
31
|
-
export declare const SceneContext: import("react").Context<Scene | null>;
|
|
32
|
-
export declare function useScene(): Scene;
|
|
7
|
+
import { type Scene } from "./SceneContext";
|
|
8
|
+
export type { Scene };
|
|
33
9
|
export interface PrefabRootProps {
|
|
34
10
|
editMode?: boolean;
|
|
35
11
|
data?: Prefab;
|
|
@@ -19,26 +19,22 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
19
19
|
return t;
|
|
20
20
|
};
|
|
21
21
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
22
|
-
import {
|
|
22
|
+
import { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
23
23
|
import { Euler, Matrix4 } from "three";
|
|
24
24
|
import { useThree } from "@react-three/fiber";
|
|
25
25
|
import { useStore } from "zustand";
|
|
26
26
|
import { useClickValid } from "./useClickValid";
|
|
27
27
|
import { findComponent, getNodeUserData } from "./types";
|
|
28
|
-
import { getComponentDef
|
|
29
|
-
import { builtinComponents } from "./components";
|
|
28
|
+
import { getComponentDef } from "./components/ComponentRegistry";
|
|
30
29
|
import { loadModel, loadSound, loadTexture } from "../dragdrop";
|
|
31
30
|
import { GameInstance, GameInstanceProvider, getRepeatAxesFromModelProperties } from "./InstanceProvider";
|
|
32
|
-
import { composeTransform, decompose, withBasePath } from "./
|
|
31
|
+
import { composeTransform, decompose, withBasePath } from "./runtimeUtils";
|
|
33
32
|
import { createPrefabStore, PrefabStoreProvider, usePrefabChildIds, usePrefabNode, usePrefabRootId } from "./prefabStore";
|
|
34
33
|
import { AssetRuntimeContext, NodeScope } from "./assetRuntime";
|
|
35
34
|
import { gameEvents } from "./GameEvents";
|
|
36
35
|
import { sound as soundManager } from "../../helpers/SoundManager";
|
|
37
|
-
|
|
36
|
+
import { PrefabEditorMode, SceneContext } from "./SceneContext";
|
|
38
37
|
const IDENTITY = new Matrix4();
|
|
39
|
-
const EMPTY_MODELS = {};
|
|
40
|
-
const EMPTY_TEXTURES = {};
|
|
41
|
-
const EMPTY_SOUNDS = {};
|
|
42
38
|
const EMPTY_NODE_COMPONENTS = {
|
|
43
39
|
geometry: undefined,
|
|
44
40
|
materials: [],
|
|
@@ -76,28 +72,14 @@ function getNodeMetadataProps(node) {
|
|
|
76
72
|
userData: Object.assign(Object.assign({ prefabNodeId: node.id }, (nodeName ? { prefabNodeName: nodeName } : {})), getNodeUserData(node)),
|
|
77
73
|
};
|
|
78
74
|
}
|
|
79
|
-
export var PrefabEditorMode;
|
|
80
|
-
(function (PrefabEditorMode) {
|
|
81
|
-
PrefabEditorMode["Edit"] = "edit";
|
|
82
|
-
PrefabEditorMode["Play"] = "play";
|
|
83
|
-
})(PrefabEditorMode || (PrefabEditorMode = {}));
|
|
84
|
-
export const SceneContext = createContext(null);
|
|
85
|
-
export function useScene() {
|
|
86
|
-
const scene = useContext(SceneContext);
|
|
87
|
-
if (!scene) {
|
|
88
|
-
throw new Error("useScene must be used within a PrefabRoot or PrefabEditor scene provider");
|
|
89
|
-
}
|
|
90
|
-
return scene;
|
|
91
|
-
}
|
|
92
75
|
export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick, onEditNodeClick, basePath = "", children }, ref) => {
|
|
76
|
+
const parentScene = useContext(SceneContext);
|
|
77
|
+
const parentAssetRuntime = useContext(AssetRuntimeContext);
|
|
93
78
|
const renderer = useThree(state => state.gl);
|
|
94
79
|
const camera = useThree(state => state.camera);
|
|
95
80
|
const [models, setModels] = useState({});
|
|
96
81
|
const [textures, setTextures] = useState({});
|
|
97
82
|
const [sounds, setSounds] = useState({});
|
|
98
|
-
const [injectedModels, setInjectedModels] = useState(EMPTY_MODELS);
|
|
99
|
-
const [injectedTextures, setInjectedTextures] = useState(EMPTY_TEXTURES);
|
|
100
|
-
const [injectedSounds, setInjectedSounds] = useState(EMPTY_SOUNDS);
|
|
101
83
|
const loading = useRef(new Set());
|
|
102
84
|
const failedModels = useRef(new Set());
|
|
103
85
|
const failedTextures = useRef(new Set());
|
|
@@ -119,19 +101,18 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
119
101
|
const usesOwnedStore = resolvedStore === ownedStore;
|
|
120
102
|
const rootId = useStore(resolvedStore, state => state.rootId);
|
|
121
103
|
const assetRefCounts = useStore(resolvedStore, state => state.assetRefCounts);
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
const assetRevision = useMemo(() => `${Object.keys(textures).concat(Object.keys(injectedTextures)).sort().join('|')}::${Object.keys(availableModels).sort().join('|')}`, [availableModels, injectedTextures, textures]);
|
|
104
|
+
const getModel = useCallback((path) => { var _a, _b; return (_b = (_a = models[path]) !== null && _a !== void 0 ? _a : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getModel(path)) !== null && _b !== void 0 ? _b : null; }, [models, parentAssetRuntime]);
|
|
105
|
+
const getTexture = useCallback((path) => { var _a, _b; return (_b = (_a = textures[path]) !== null && _a !== void 0 ? _a : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getTexture(path)) !== null && _b !== void 0 ? _b : null; }, [parentAssetRuntime, textures]);
|
|
106
|
+
const getSound = useCallback((path) => { var _a, _b; return (_b = (_a = sounds[path]) !== null && _a !== void 0 ? _a : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getSound(path)) !== null && _b !== void 0 ? _b : null; }, [parentAssetRuntime, sounds]);
|
|
107
|
+
const assetRevision = useMemo(() => { var _a; return `${(_a = parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getAssetRevision()) !== null && _a !== void 0 ? _a : ""}::${Object.keys(textures).sort().join('|')}::${Object.keys(models).sort().join('|')}`; }, [models, parentAssetRuntime, textures]);
|
|
127
108
|
const getObject = useCallback((id) => {
|
|
128
|
-
var _a;
|
|
129
|
-
return (_a = objectRefs.current[id]) !== null && _a !== void 0 ? _a : null;
|
|
130
|
-
}, []);
|
|
131
|
-
const getHandle = useCallback((id, kind) => {
|
|
132
109
|
var _a, _b;
|
|
133
|
-
return (_b = (_a =
|
|
134
|
-
}, []);
|
|
110
|
+
return (_b = (_a = objectRefs.current[id]) !== null && _a !== void 0 ? _a : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getObject(id)) !== null && _b !== void 0 ? _b : null;
|
|
111
|
+
}, [parentAssetRuntime]);
|
|
112
|
+
const getHandle = useCallback((id, kind) => {
|
|
113
|
+
var _a, _b, _c;
|
|
114
|
+
return (_c = (_b = (_a = nodeHandles.current.get(id)) === null || _a === void 0 ? void 0 : _a.get(kind)) !== null && _b !== void 0 ? _b : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getHandle(id, kind)) !== null && _c !== void 0 ? _c : null;
|
|
115
|
+
}, [parentAssetRuntime]);
|
|
135
116
|
const getNode = useCallback((nodeId) => {
|
|
136
117
|
var _a;
|
|
137
118
|
return (_a = resolvedStore.getState().nodesById[nodeId]) !== null && _a !== void 0 ? _a : null;
|
|
@@ -139,6 +120,7 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
139
120
|
const registerHandle = useCallback((id, kind, handle) => {
|
|
140
121
|
const current = nodeHandles.current.get(id);
|
|
141
122
|
if (handle == null) {
|
|
123
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerHandle(id, kind, null);
|
|
142
124
|
if (!current)
|
|
143
125
|
return;
|
|
144
126
|
current.delete(kind);
|
|
@@ -149,10 +131,34 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
149
131
|
}
|
|
150
132
|
if (current) {
|
|
151
133
|
current.set(kind, handle);
|
|
134
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerHandle(id, kind, handle);
|
|
152
135
|
return;
|
|
153
136
|
}
|
|
154
137
|
nodeHandles.current.set(id, new Map([[kind, handle]]));
|
|
155
|
-
|
|
138
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerHandle(id, kind, handle);
|
|
139
|
+
}, [parentAssetRuntime]);
|
|
140
|
+
const registerObject = useCallback((id, obj) => {
|
|
141
|
+
if (obj) {
|
|
142
|
+
objectRefs.current[id] = obj;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
delete objectRefs.current[id];
|
|
146
|
+
}
|
|
147
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerObject(id, obj);
|
|
148
|
+
}, [parentAssetRuntime]);
|
|
149
|
+
const registerModel = useCallback((path, model) => {
|
|
150
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerModel(path, model);
|
|
151
|
+
setModels(prev => prev[path] === model ? prev : Object.assign(Object.assign({}, prev), { [path]: model }));
|
|
152
|
+
}, [parentAssetRuntime]);
|
|
153
|
+
const registerTexture = useCallback((path, texture) => {
|
|
154
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerTexture(path, texture);
|
|
155
|
+
setTextures(prev => prev[path] === texture ? prev : Object.assign(Object.assign({}, prev), { [path]: texture }));
|
|
156
|
+
}, [parentAssetRuntime]);
|
|
157
|
+
const registerSound = useCallback((path, sound) => {
|
|
158
|
+
parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.registerSound(path, sound);
|
|
159
|
+
soundManager.setBuffer(path, sound);
|
|
160
|
+
setSounds(prev => prev[path] === sound ? prev : Object.assign(Object.assign({}, prev), { [path]: sound }));
|
|
161
|
+
}, [parentAssetRuntime]);
|
|
156
162
|
const sceneValue = useMemo(() => ({
|
|
157
163
|
get root() {
|
|
158
164
|
var _a;
|
|
@@ -182,27 +188,21 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
182
188
|
void precompileModel(model, renderer, camera).then(() => {
|
|
183
189
|
if (injectedModelVersions.current[path] !== version)
|
|
184
190
|
return;
|
|
185
|
-
|
|
191
|
+
registerModel(path, model);
|
|
186
192
|
});
|
|
187
193
|
},
|
|
188
|
-
addTexture:
|
|
189
|
-
addSound:
|
|
190
|
-
|
|
191
|
-
setInjectedSounds(prev => (Object.assign(Object.assign({}, prev), { [path]: sound })));
|
|
192
|
-
},
|
|
193
|
-
}), [basePath, camera, editMode, getHandle, getModel, getNode, getObject, renderer, resolvedStore, rootId]);
|
|
194
|
+
addTexture: registerTexture,
|
|
195
|
+
addSound: registerSound,
|
|
196
|
+
}), [basePath, camera, editMode, getHandle, getModel, getNode, getObject, registerModel, registerSound, registerTexture, renderer, resolvedStore, rootId]);
|
|
194
197
|
useImperativeHandle(ref, () => sceneValue, [sceneValue]);
|
|
195
|
-
const registerRef = useCallback((id, obj) => {
|
|
196
|
-
objectRefs.current[id] = obj;
|
|
197
|
-
}, []);
|
|
198
198
|
useEffect(() => {
|
|
199
199
|
if (usesOwnedStore && data) {
|
|
200
200
|
resolvedStore.getState().replacePrefab(data);
|
|
201
201
|
}
|
|
202
202
|
}, [data, resolvedStore, usesOwnedStore]);
|
|
203
203
|
useEffect(() => {
|
|
204
|
-
const loadAsset = (file, loaded,
|
|
205
|
-
if (loaded[file] ||
|
|
204
|
+
const loadAsset = (file, loaded, failed, loader) => {
|
|
205
|
+
if (loaded[file] || loading.current.has(file) || failed.has(file))
|
|
206
206
|
return;
|
|
207
207
|
loading.current.add(file);
|
|
208
208
|
void loader(withBasePath(basePath, file)).then(result => {
|
|
@@ -218,45 +218,63 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
218
218
|
const type = entry.slice(0, separator);
|
|
219
219
|
const file = entry.slice(separator + 1);
|
|
220
220
|
if (type === 'model') {
|
|
221
|
-
|
|
221
|
+
const inheritedModel = models[file] ? null : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getModel(file);
|
|
222
|
+
if (inheritedModel) {
|
|
223
|
+
registerModel(file, inheritedModel);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
loadAsset(file, models, failedModels.current, path => loadModel(path).then((result) => __awaiter(void 0, void 0, void 0, function* () {
|
|
222
227
|
const loadedModel = result.model;
|
|
223
228
|
if (result.success && loadedModel) {
|
|
224
229
|
yield precompileModel(loadedModel, renderer, camera);
|
|
225
|
-
|
|
230
|
+
registerModel(file, loadedModel);
|
|
226
231
|
}
|
|
227
232
|
return result;
|
|
228
233
|
})));
|
|
229
234
|
}
|
|
230
235
|
else if (type === 'texture') {
|
|
231
|
-
|
|
236
|
+
const inheritedTexture = textures[file] ? null : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getTexture(file);
|
|
237
|
+
if (inheritedTexture) {
|
|
238
|
+
registerTexture(file, inheritedTexture);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
loadAsset(file, textures, failedTextures.current, path => loadTexture(path).then(result => {
|
|
232
242
|
const loadedTexture = result.texture;
|
|
233
243
|
if (result.success && loadedTexture) {
|
|
234
|
-
|
|
244
|
+
registerTexture(file, loadedTexture);
|
|
235
245
|
}
|
|
236
246
|
return result;
|
|
237
247
|
}));
|
|
238
248
|
}
|
|
239
249
|
else if (type === 'sound') {
|
|
240
|
-
|
|
250
|
+
const inheritedSound = sounds[file] ? null : parentAssetRuntime === null || parentAssetRuntime === void 0 ? void 0 : parentAssetRuntime.getSound(file);
|
|
251
|
+
if (inheritedSound) {
|
|
252
|
+
registerSound(file, inheritedSound);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
loadAsset(file, sounds, failedSounds.current, path => loadSound(path).then(result => {
|
|
241
256
|
const loadedSound = result.sound;
|
|
242
257
|
if (result.success && loadedSound) {
|
|
243
|
-
|
|
244
|
-
setSounds(currentSounds => (Object.assign(Object.assign({}, currentSounds), { [file]: loadedSound })));
|
|
258
|
+
registerSound(file, loadedSound);
|
|
245
259
|
}
|
|
246
260
|
return result;
|
|
247
261
|
}));
|
|
248
262
|
}
|
|
249
263
|
});
|
|
250
|
-
}, [assetRefCounts, basePath, camera,
|
|
264
|
+
}, [assetRefCounts, basePath, camera, models, parentAssetRuntime, registerModel, registerSound, registerTexture, renderer, sounds, textures]);
|
|
251
265
|
const assetRuntime = useMemo(() => ({
|
|
266
|
+
registerObject,
|
|
252
267
|
registerHandle,
|
|
268
|
+
registerModel,
|
|
269
|
+
registerTexture,
|
|
270
|
+
registerSound,
|
|
253
271
|
getHandle,
|
|
254
272
|
getObject,
|
|
255
273
|
getModel,
|
|
256
274
|
getTexture,
|
|
257
275
|
getSound,
|
|
258
276
|
getAssetRevision: () => assetRevision,
|
|
259
|
-
}), [registerHandle, getHandle, getObject, getModel, getTexture, getSound, assetRevision]);
|
|
277
|
+
}), [registerObject, registerHandle, registerModel, registerTexture, registerSound, getHandle, getObject, getModel, getTexture, getSound, assetRevision]);
|
|
260
278
|
const handleNodeClick = useCallback((event, nodeId, fallbackObject) => {
|
|
261
279
|
const node = resolvedStore.getState().nodesById[nodeId];
|
|
262
280
|
if (!node)
|
|
@@ -265,9 +283,10 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
|
|
|
265
283
|
emitNodePointerEvent(clickEventName, event, nodeId, node, fallbackObject);
|
|
266
284
|
onClick === null || onClick === void 0 ? void 0 : onClick(event, node);
|
|
267
285
|
}, [onClick, resolvedStore]);
|
|
268
|
-
const content = (_jsxs(GameInstanceProvider, { models:
|
|
269
|
-
const runtimeContent =
|
|
270
|
-
|
|
286
|
+
const content = (_jsxs(GameInstanceProvider, { models: models, selectedId: selectedId, editMode: editMode, onSelect: editMode ? onSelect : undefined, onClick: editMode ? undefined : handleNodeClick, registerRef: registerObject, children: [_jsx(StoreRootNode, { selectedId: selectedId, onSelect: editMode ? onSelect : undefined, onClick: editMode ? undefined : handleNodeClick, onEditNodeClick: editMode ? onEditNodeClick : undefined, registerRef: registerObject, loadedModels: models, editMode: editMode, parentMatrix: IDENTITY, basePath: basePath }), children] }));
|
|
287
|
+
const runtimeContent = parentAssetRuntime ? content : (_jsx(AssetRuntimeContext.Provider, { value: assetRuntime, children: content }));
|
|
288
|
+
const sceneContent = parentScene ? runtimeContent : (_jsx(SceneContext.Provider, { value: sceneValue, children: runtimeContent }));
|
|
289
|
+
return _jsx(PrefabStoreProvider, { store: resolvedStore, children: sceneContent });
|
|
271
290
|
});
|
|
272
291
|
function StoreRootNode(props) {
|
|
273
292
|
const rootId = usePrefabRootId();
|