react-three-game 0.0.107 → 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.
Files changed (49) hide show
  1. package/README.md +12 -5
  2. package/dist/editor.d.ts +22 -0
  3. package/dist/editor.js +15 -0
  4. package/dist/plugins/crashcat/CrashcatPhysicsComponent.js +75 -47
  5. package/dist/plugins/crashcat/CrashcatRagdoll.d.ts +58 -0
  6. package/dist/plugins/crashcat/CrashcatRagdoll.js +410 -0
  7. package/dist/plugins/crashcat/CrashcatRuntime.js +19 -15
  8. package/dist/plugins/crashcat/index.d.ts +1 -0
  9. package/dist/plugins/crashcat/index.js +1 -0
  10. package/dist/tools/assetviewer/page.js +4 -4
  11. package/dist/tools/prefabeditor/EditorContext.d.ts +36 -0
  12. package/dist/tools/prefabeditor/EditorContext.js +17 -0
  13. package/dist/tools/prefabeditor/EditorTree.js +6 -3
  14. package/dist/tools/prefabeditor/EditorTreeMenus.d.ts +2 -1
  15. package/dist/tools/prefabeditor/EditorTreeMenus.js +18 -6
  16. package/dist/tools/prefabeditor/EditorUI.js +1 -1
  17. package/dist/tools/prefabeditor/GameEvents.d.ts +1 -0
  18. package/dist/tools/prefabeditor/PrefabEditor.d.ts +5 -37
  19. package/dist/tools/prefabeditor/PrefabEditor.js +41 -43
  20. package/dist/tools/prefabeditor/PrefabRoot.d.ts +5 -27
  21. package/dist/tools/prefabeditor/PrefabRoot.js +133 -78
  22. package/dist/tools/prefabeditor/SceneContext.d.ts +28 -0
  23. package/dist/tools/prefabeditor/SceneContext.js +14 -0
  24. package/dist/tools/prefabeditor/assetRuntime.d.ts +4 -0
  25. package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +16 -1
  26. package/dist/tools/prefabeditor/components/ModelComponent.js +1 -1
  27. package/dist/tools/prefabeditor/components/PrefabRefComponent.d.ts +3 -0
  28. package/dist/tools/prefabeditor/components/PrefabRefComponent.js +72 -0
  29. package/dist/tools/prefabeditor/components/TextComponent.js +8 -5
  30. package/dist/tools/prefabeditor/components/TransformComponent.js +1 -1
  31. package/dist/tools/prefabeditor/components/index.d.ts +1 -0
  32. package/dist/tools/prefabeditor/components/index.js +10 -0
  33. package/dist/tools/prefabeditor/components/runtime.d.ts +4 -0
  34. package/dist/tools/prefabeditor/components/runtime.js +372 -0
  35. package/dist/tools/prefabeditor/modelPrefab.d.ts +3 -0
  36. package/dist/tools/prefabeditor/modelPrefab.js +44 -11
  37. package/dist/tools/prefabeditor/prefab.d.ts +5 -4
  38. package/dist/tools/prefabeditor/prefab.js +47 -29
  39. package/dist/tools/prefabeditor/prefabStore.d.ts +1 -1
  40. package/dist/tools/prefabeditor/prefabStore.js +5 -1
  41. package/dist/tools/prefabeditor/runtimeUtils.d.ts +10 -0
  42. package/dist/tools/prefabeditor/runtimeUtils.js +30 -0
  43. package/dist/tools/prefabeditor/utils.d.ts +7 -8
  44. package/dist/tools/prefabeditor/utils.js +63 -36
  45. package/dist/viewer.d.ts +22 -0
  46. package/dist/viewer.js +14 -0
  47. package/package.json +22 -20
  48. package/dist/index.d.ts +0 -40
  49. package/dist/index.js +0 -32
@@ -12,8 +12,8 @@ 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 './PrefabEditor';
16
- import { loadJson, saveJson } from './utils';
15
+ import { useEditorContext } from './EditorContext';
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 }));
19
19
  }
@@ -80,8 +80,8 @@ export function TreeContextMenu({ contextMenu, onClose, children, }) {
80
80
  zIndex: 1000,
81
81
  }, onMouseLeave: onClose, onContextMenu: (e) => e.preventDefault(), children: children(contextMenu.nodeId, onClose) }), document.body);
82
82
  }
83
- export function FileMenu({ getPrefab, onReplacePrefab, onImportPrefab, onClose }) {
84
- const { onScreenshot, onExportGLB } = useEditorContext();
83
+ export function FileMenu({ getPrefab, onReplacePrefab, onImportPrefab, onImportPackedPrefab, onClose }) {
84
+ const { basePath, onScreenshot, onExportGLB } = useEditorContext();
85
85
  const handleNew = () => {
86
86
  onReplacePrefab(createEmptyPrefab());
87
87
  onClose();
@@ -98,10 +98,22 @@ export function FileMenu({ getPrefab, onReplacePrefab, onImportPrefab, onClose }
98
98
  onClose();
99
99
  };
100
100
  const handleImport = () => __awaiter(this, void 0, void 0, function* () {
101
- const loaded = yield loadJson();
101
+ const loaded = yield loadJsonFile();
102
102
  if (!loaded)
103
103
  return;
104
- onImportPrefab(loaded);
104
+ try {
105
+ const manifest = yield fetch(withBasePath(basePath, '/prefabs/manifest.json')).then(r => r.json());
106
+ const matched = manifest.find(entry => entry.endsWith(`/${loaded.filename}`) || entry === `/${loaded.filename}`);
107
+ if (matched) {
108
+ onImportPackedPrefab(matched);
109
+ onClose();
110
+ return;
111
+ }
112
+ }
113
+ catch (_a) {
114
+ // manifest not available, fall through to full import
115
+ }
116
+ onImportPrefab(loaded.prefab);
105
117
  onClose();
106
118
  });
107
119
  return (_jsxs(MenuPanel, { style: { overflow: 'visible' }, children: [_jsxs(MenuSubmenu, { label: "File", children: [_jsx(MenuItemButton, { onClick: handleNew, children: "New Prefab" }), _jsx(MenuItemButton, { onClick: handleOpen, children: "Open Prefab" }), _jsx(MenuItemButton, { onClick: handleImport, children: "Import Prefab" }), _jsx(MenuItemButton, { onClick: handleSave, children: "Save Prefab" })] }), _jsxs(MenuSubmenu, { label: "Export", children: [_jsx(MenuItemButton, { onClick: () => { onExportGLB === null || onExportGLB === void 0 ? void 0 : onExportGLB(); onClose(); }, children: "GLB" }), _jsx(MenuItemButton, { onClick: () => { onScreenshot === null || onScreenshot === void 0 ? void 0 : onScreenshot(); onClose(); }, children: "PNG" })] })] }));
@@ -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 './PrefabEditor';
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 }) {
@@ -6,6 +6,7 @@ export type ContactEventPayload = {
6
6
  targetEntityId?: string | null;
7
7
  targetNodeId?: string | null;
8
8
  targetObject?: unknown;
9
+ collisionNormal?: [number, number, number];
9
10
  event?: unknown;
10
11
  };
11
12
  export type ClickEventPayload = {
@@ -1,43 +1,11 @@
1
- import GameCanvas from "../../shared/GameCanvas";
2
1
  import type { Prefab } from "./types";
3
- import { PrefabEditorMode, type Scene } from "./PrefabRoot";
4
- import type { ExportGLBOptions } from "./utils";
5
- export declare function isAbsoluteAssetPath(path: string): boolean;
2
+ import { GameCanvas, PrefabEditorMode } from "../../viewer";
3
+ import { type PrefabEditorRef } from "./EditorContext";
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 interface PrefabEditorRef extends Scene {
9
- save: () => Prefab;
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
- setMode: (mode: PrefabEditorMode) => void;
25
- transformMode: "translate" | "rotate" | "scale";
26
- setTransformMode: (mode: "translate" | "rotate" | "scale") => void;
27
- scaleSnap: number;
28
- setScaleSnap: (resolution: number) => void;
29
- positionSnap: number;
30
- setPositionSnap: (resolution: number) => void;
31
- rotationSnap: number;
32
- setRotationSnap: (resolution: number) => void;
33
- onFocusNode?: (nodeId: string) => void;
34
- onScreenshot?: () => void;
35
- onExportGLB?: () => void;
36
- }
37
- export declare const EditorContext: import("react").Context<EditorContextType | null>;
38
- export declare const EditorRefContext: import("react").Context<PrefabEditorRef | null>;
39
- export declare function useEditorContext(): EditorContextType;
40
- export declare function useEditorRef(): PrefabEditorRef;
7
+ export type { EditorContextType, PrefabEditorRef } from "./EditorContext";
8
+ export { EditorContext, EditorRefContext, useEditorContext, useEditorRef } from "./EditorContext";
41
9
  export interface PrefabEditorProps {
42
10
  basePath?: string;
43
11
  initialPrefab?: Prefab;
@@ -9,17 +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 GameCanvas from "../../shared/GameCanvas";
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 { PrefabEditorMode, PrefabRoot } from "./PrefabRoot";
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
- import { computeParentWorldMatrix, decompose, exportGLB as exportGLBFile, exportGLBData, focusCameraOnObject, regenerateIds } from "./utils";
18
+ import { computeParentWorldMatrix, decompose, exportGLB as exportGLBFile, exportGLBData, focusCameraOnObject, isExternalPath, regenerateIds, withBasePath } from "./utils";
20
19
  import { loadDroppedAssets } from "../dragdrop";
21
- import { denormalizePrefab, createImageNode, createModelNode, createNode } from './prefab';
20
+ import { createNode } from './prefab';
22
21
  import { createPrefabStore, PrefabStoreProvider } from "./prefabStore";
22
+ import { decomposeModelToPrefabNodes, hasCollisionMeshConventions } from "./modelPrefab";
23
+ import { EditorContext, EditorRefContext } from "./EditorContext";
23
24
  function isObjectAttachedToRoot(root, object) {
24
25
  if (!root || !object)
25
26
  return false;
@@ -31,18 +32,12 @@ function isObjectAttachedToRoot(root, object) {
31
32
  }
32
33
  return false;
33
34
  }
34
- export function isAbsoluteAssetPath(path) {
35
- return (path.startsWith("data:") ||
36
- path.startsWith("http://") ||
37
- path.startsWith("https://"));
38
- }
35
+ export { isExternalPath as isAbsoluteAssetPath } from "./utils";
39
36
  export function resolvePrefabAssetPath(basePath, file) {
40
- if (isAbsoluteAssetPath(file))
41
- return file;
42
- return file.startsWith("/") ? `${basePath}${file}` : `${basePath}/${file}`;
37
+ return withBasePath(basePath, file);
43
38
  }
44
39
  export function getPrefabAssetRef(assetRef, folder) {
45
- return isAbsoluteAssetPath(assetRef) ? assetRef : `${folder}/${assetRef}`;
40
+ return isExternalPath(assetRef) ? assetRef : `${folder}/${assetRef}`;
46
41
  }
47
42
  function SelectionHelper({ object }) {
48
43
  const objectRef = useRef(null);
@@ -53,22 +48,7 @@ function SelectionHelper({ object }) {
53
48
  useHelper(helperTarget, BoxHelper, "cyan");
54
49
  return null;
55
50
  }
56
- export const EditorContext = createContext(null);
57
- export const EditorRefContext = createContext(null);
58
- export function useEditorContext() {
59
- const context = useContext(EditorContext);
60
- if (!context) {
61
- throw new Error("useEditorContext must be used within EditorContext.Provider");
62
- }
63
- return context;
64
- }
65
- export function useEditorRef() {
66
- const editorRef = useContext(EditorRefContext);
67
- if (!editorRef) {
68
- throw new Error("useEditorRef must be used within PrefabEditor");
69
- }
70
- return editorRef;
71
- }
51
+ export { EditorContext, EditorRefContext, useEditorContext, useEditorRef } from "./EditorContext";
72
52
  const MAX_HISTORY_LENGTH = 50;
73
53
  const HISTORY_DEBOUNCE_MS = 500;
74
54
  const DEFAULT_PREFAB = {
@@ -76,7 +56,7 @@ const DEFAULT_PREFAB = {
76
56
  name: "New Prefab",
77
57
  root: createNode('Root', {}, { id: 'root' })
78
58
  };
79
- const PrefabEditor = forwardRef(({ basePath, initialPrefab, mode: initialMode = PrefabEditorMode.Edit, onChange, showUI = true, enableWindowDrop = true, canvasProps, uiPlugins, children }, ref) => {
59
+ const PrefabEditor = forwardRef(({ basePath = "", initialPrefab, mode: initialMode = PrefabEditorMode.Edit, onChange, showUI = true, enableWindowDrop = true, canvasProps, uiPlugins, children }, ref) => {
80
60
  const [mode, setMode] = useState(initialMode);
81
61
  const [selectedId, setSelectedId] = useState(null);
82
62
  const [transformMode, setTransformMode] = useState("translate");
@@ -344,7 +324,23 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, mode: initialMode =
344
324
  onModelLoaded: (model, filename, file) => {
345
325
  const path = getPrefabAssetRef(filename, 'models');
346
326
  scene === null || scene === void 0 ? void 0 : scene.addModel(path, model);
347
- add(createModelNode(path, file.name.replace(/\.[^.]+$/, '')));
327
+ const modelName = file.name.replace(/\.[^.]+$/, '');
328
+ const modelIdPrefix = modelName.replace(/[^\w-]+/g, '-') || 'model';
329
+ if (hasCollisionMeshConventions(model)) {
330
+ const textureRefs = new Map();
331
+ const decomposed = decomposeModelToPrefabNodes(model, {
332
+ idPrefix: modelIdPrefix,
333
+ getTexturePath: (texture, usage) => {
334
+ const key = `embedded/${modelIdPrefix}/${usage}/${texture.uuid}`;
335
+ textureRefs.set(key, texture);
336
+ return key;
337
+ },
338
+ });
339
+ textureRefs.forEach((texture, path) => scene === null || scene === void 0 ? void 0 : scene.addTexture(path, texture));
340
+ add(Object.assign(Object.assign({}, decomposed), { name: modelName || decomposed.name }));
341
+ return;
342
+ }
343
+ add(createModelNode(path, modelName));
348
344
  },
349
345
  onTextureLoaded: (texture, filename, file) => {
350
346
  const path = getPrefabAssetRef(filename, 'textures');
@@ -368,6 +364,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, mode: initialMode =
368
364
  return getRoot();
369
365
  },
370
366
  mode,
367
+ basePath,
371
368
  get: getNode,
372
369
  getObject,
373
370
  getHandle,
@@ -382,7 +379,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, mode: initialMode =
382
379
  addModel: (path, model) => { var _a; return (_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.addModel(path, model); },
383
380
  addTexture: (path, texture) => { var _a; return (_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.addTexture(path, texture); },
384
381
  addSound: (path, sound) => { var _a; return (_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.addSound(path, sound); },
385
- }), [add, duplicate, getHandle, getModel, getNode, getObject, getRoot, mode, move, remove, replace, replaceNode, update]);
382
+ }), [add, basePath, duplicate, getHandle, getModel, getNode, getObject, getRoot, mode, move, remove, replace, replaceNode, update]);
386
383
  const editorRefValue = useMemo(() => (Object.assign(Object.assign({}, sceneValue), { save: getPrefab, load: loadPrefab, undo,
387
384
  redo, screenshot: handleScreenshot, exportGLB: handleExportGLB, exportGLBData: handleExportGLBData, clearSelection })), [clearSelection, getPrefab, handleExportGLB, handleExportGLBData, handleScreenshot, loadPrefab, redo, sceneValue, undo]);
388
385
  useImperativeHandle(ref, () => editorRefValue, [editorRefValue]);
@@ -392,8 +389,9 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, mode: initialMode =
392
389
  canvasRef.current = state.gl.domElement;
393
390
  (_a = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onCreated) === null || _a === void 0 ? void 0 : _a.call(canvasProps, state);
394
391
  }, [canvasProps]);
395
- return _jsx(PrefabStoreProvider, { store: prefabStore, children: _jsx(EditorRefContext.Provider, { value: editorRefValue, children: _jsxs(EditorContext.Provider, { value: {
392
+ return _jsx(PrefabStoreProvider, { store: prefabStore, children: _jsx(EditorRefContext.Provider, { value: editorRefValue, children: _jsx(EditorContext.Provider, { value: {
396
393
  mode,
394
+ basePath,
397
395
  setMode: updateMode,
398
396
  transformMode,
399
397
  setTransformMode,
@@ -406,16 +404,16 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, mode: initialMode =
406
404
  onFocusNode: isEditMode ? handleFocusNode : undefined,
407
405
  onScreenshot: handleScreenshot,
408
406
  onExportGLB: handleExportGLB
409
- }, children: [_jsxs(GameCanvas, Object.assign({ camera: { position: [0, 5, 15] } }, canvasProps, { onCreated: handleCanvasCreated, onPointerMissed: isEditMode
410
- ? (event) => {
411
- var _a, _b, _c, _d;
412
- 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;
413
- if (button === 0 && selectedId) {
414
- setSelection(null);
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);
415
415
  }
416
- (_d = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed) === null || _d === void 0 ? void 0 : _d.call(canvasProps, event);
417
- }
418
- : 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 }))] }))] }) }) }) });
419
417
  });
420
418
  PrefabEditor.displayName = "PrefabEditor";
421
419
  export default PrefabEditor;
@@ -1,34 +1,11 @@
1
1
  import { Matrix4 } from "three";
2
- import type { Object3D, Texture } from "three";
3
- import type { ThreeEvent } from "@react-three/fiber";
2
+ import type { Object3D } from "three";
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
- export declare enum PrefabEditorMode {
8
- Edit = "edit",
9
- Play = "play"
10
- }
11
- export type PrefabNode = Omit<GameObjectType, "children">;
12
- export interface Scene {
13
- root: Object3D | null;
14
- mode: PrefabEditorMode;
15
- get(id: string): GameObjectType | null;
16
- getObject(id: string): Object3D | null;
17
- getHandle<T = unknown>(id: string, kind: string): T | null;
18
- getModel(path: string): Object3D | null;
19
- add(node: GameObjectType, parentId?: string): GameObjectType;
20
- update(id: string, fn: (node: PrefabNode) => PrefabNode): void;
21
- replaceNode(id: string, node: GameObjectType): void;
22
- remove(id: string): void;
23
- duplicate(id: string): string | null;
24
- move(draggedId: string, targetId: string, position: "before" | "inside"): void;
25
- replace(prefab: Prefab): void;
26
- addModel(path: string, model: Object3D): void;
27
- addTexture(path: string, texture: Texture): void;
28
- addSound(path: string, sound: AudioBuffer): void;
29
- }
30
- export declare const SceneContext: import("react").Context<Scene | null>;
31
- export declare function useScene(): Scene;
7
+ import { type Scene } from "./SceneContext";
8
+ export type { Scene };
32
9
  export interface PrefabRootProps {
33
10
  editMode?: boolean;
34
11
  data?: Prefab;
@@ -53,5 +30,6 @@ interface RendererProps {
53
30
  editMode?: boolean;
54
31
  parentMatrix?: Matrix4;
55
32
  isVisible?: boolean;
33
+ basePath?: string;
56
34
  }
57
35
  export default PrefabRoot;