react-three-game 0.0.108 → 0.0.110

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 (55) hide show
  1. package/README.md +9 -16
  2. package/dist/editor.d.ts +22 -0
  3. package/dist/editor.js +15 -0
  4. package/dist/plugins/crashcat/CrashcatPhysicsComponent.js +47 -9
  5. package/dist/plugins/crashcat/CrashcatRagdoll.d.ts +1 -1
  6. package/dist/plugins/crashcat/CrashcatRuntime.d.ts +1 -1
  7. package/dist/plugins/crashcat/CrashcatRuntime.js +1 -1
  8. package/dist/shared/ContactShadow.d.ts +1 -1
  9. package/dist/shared/GameCanvas.d.ts +1 -1
  10. package/dist/tools/assetviewer/page.d.ts +10 -10
  11. package/dist/tools/dragdrop/DragDropLoader.d.ts +2 -2
  12. package/dist/tools/prefabeditor/Dropdown.d.ts +1 -1
  13. package/dist/tools/prefabeditor/EditorContext.d.ts +36 -0
  14. package/dist/tools/prefabeditor/EditorContext.js +17 -0
  15. package/dist/tools/prefabeditor/EditorTree.d.ts +1 -1
  16. package/dist/tools/prefabeditor/EditorTree.js +1 -1
  17. package/dist/tools/prefabeditor/EditorTreeMenus.d.ts +2 -2
  18. package/dist/tools/prefabeditor/EditorTreeMenus.js +1 -1
  19. package/dist/tools/prefabeditor/EditorUI.d.ts +1 -1
  20. package/dist/tools/prefabeditor/EditorUI.js +1 -1
  21. package/dist/tools/prefabeditor/InstanceProvider.d.ts +1 -1
  22. package/dist/tools/prefabeditor/PrefabEditor.d.ts +4 -37
  23. package/dist/tools/prefabeditor/PrefabEditor.js +72 -71
  24. package/dist/tools/prefabeditor/PrefabRoot.d.ts +5 -29
  25. package/dist/tools/prefabeditor/PrefabRoot.js +72 -188
  26. package/dist/tools/prefabeditor/SceneContext.d.ts +28 -0
  27. package/dist/tools/prefabeditor/SceneContext.js +14 -0
  28. package/dist/tools/prefabeditor/SceneProvider.d.ts +14 -0
  29. package/dist/tools/prefabeditor/SceneProvider.js +68 -0
  30. package/dist/tools/prefabeditor/assetRuntime.d.ts +29 -2
  31. package/dist/tools/prefabeditor/assetRuntime.js +115 -1
  32. package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +1 -1
  33. package/dist/tools/prefabeditor/components/EnvironmentComponent.js +3 -3
  34. package/dist/tools/prefabeditor/components/Input.d.ts +19 -19
  35. package/dist/tools/prefabeditor/components/MaterialComponent.d.ts +1 -1
  36. package/dist/tools/prefabeditor/components/MaterialComponent.js +13 -14
  37. package/dist/tools/prefabeditor/components/ModelComponent.js +3 -4
  38. package/dist/tools/prefabeditor/components/PrefabRefComponent.js +43 -19
  39. package/dist/tools/prefabeditor/components/SoundComponent.js +6 -2
  40. package/dist/tools/prefabeditor/components/SpotLightComponent.js +2 -5
  41. package/dist/tools/prefabeditor/components/TransformComponent.js +1 -1
  42. package/dist/tools/prefabeditor/components/index.d.ts +1 -0
  43. package/dist/tools/prefabeditor/components/index.js +8 -0
  44. package/dist/tools/prefabeditor/components/lightUtils.d.ts +2 -2
  45. package/dist/tools/prefabeditor/prefabStore.d.ts +2 -1
  46. package/dist/tools/prefabeditor/prefabStore.js +16 -1
  47. package/dist/tools/prefabeditor/runtimeUtils.d.ts +10 -0
  48. package/dist/tools/prefabeditor/runtimeUtils.js +30 -0
  49. package/dist/tools/prefabeditor/utils.d.ts +1 -9
  50. package/dist/tools/prefabeditor/utils.js +3 -28
  51. package/dist/viewer.d.ts +21 -0
  52. package/dist/viewer.js +12 -0
  53. package/package.json +18 -16
  54. package/dist/index.d.ts +0 -40
  55. 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} />;
@@ -153,6 +153,7 @@ interface GameObject {
153
153
  name?: string;
154
154
  disabled?: boolean;
155
155
  locked?: boolean;
156
+ hidden?: boolean;
156
157
  components?: Record<string, { type: string; properties: any }>;
157
158
  children?: GameObject[];
158
159
  }
@@ -164,7 +165,7 @@ Use the editor or root ref for scene-native object access, and the `Scene` mutat
164
165
 
165
166
  ```tsx
166
167
  import { useEffect, useRef } from "react";
167
- import { PrefabEditor, type PrefabEditorRef } from "react-three-game";
168
+ import { PrefabEditor, type PrefabEditorRef } from "react-three-game/editor";
168
169
 
169
170
  function RaiseBall() {
170
171
  const editorRef = useRef<PrefabEditorRef>(null);
@@ -199,7 +200,7 @@ ball?.rotateY(0.5);
199
200
  For runtime integrations that need to react to authored scene changes, subscribe through the prefab store:
200
201
 
201
202
  ```tsx
202
- import { usePrefabStoreApi } from "react-three-game";
203
+ import { usePrefabStoreApi } from "react-three-game/editor";
203
204
 
204
205
  const store = usePrefabStoreApi();
205
206
  const stop = store.subscribe(
@@ -214,7 +215,7 @@ For runtime-owned imperative state, register node-local handles instead of reach
214
215
 
215
216
  ```tsx
216
217
  import { useEffect } from "react";
217
- import { useAssetRuntime, useNode, useNodeHandle } from "react-three-game";
218
+ import { useAssetRuntime, useNode, useNodeHandle } from "react-three-game/viewer";
218
219
 
219
220
  function SpinnerView({ children }: { children?: React.ReactNode }) {
220
221
  const { nodeId } = useNode();
@@ -280,17 +281,9 @@ Custom component `View`s use normal React and R3F behavior — `useFrame`, refs,
280
281
 
281
282
  ## Useful Exports
282
283
 
283
- * `GameCanvas`, `PrefabRoot`, `PrefabEditor`, `PrefabEditorMode`
284
- * `Prefab`, `GameObject`, `ComponentData`, `PrefabNode`, `PrefabEditorRef`, `Scene`
285
- * `registerComponent`, `Component`, `ComponentViewProps`, `FieldDefinition`
286
- * `useScene`, `useEditorRef`, `useEditorContext`
287
- * `useNode`, `useNodeObject`, `useNodeHandle`, `useAssetRuntime`
288
- * `usePrefabStore`, `usePrefabStoreApi`
289
- * `gameEvents`, `useGameEvent`, `useClickEvent`
290
- * `loadJson`, `saveJson`, `loadFiles`, `loadModel`, `loadTexture`, `loadSound`
291
- * `exportGLB`, `exportGLBData`, `regenerateIds`, `computeParentWorldMatrix`
292
- * `ground`, `soundManager`
293
- * `FieldRenderer`, `Vector3Field`, `NumberField`, `StringField`, `BooleanField`, `SelectField`, `ColorField`
284
+ * `react-three-game/viewer`: `GameCanvas`, `PrefabRoot`, `PrefabEditorMode`, `registerComponent`, scene hooks, event hooks, asset/runtime hooks, prefab types, loaders, `ground`, and `soundManager`
285
+ * `react-three-game/editor`: everything from `/viewer`, plus `PrefabEditor`, editor refs/context, prefab store hooks, inspector field components, JSON import/export helpers, GLB export helpers, material overrides, model decomposition, asset viewer components, and `three/tsl` helpers
286
+ * `react-three-game/plugins/crashcat`: `CrashcatRuntime`, `CrashcatPhysicsComponent`, `CrashcatRagdollComponent`, ragdoll helpers, static body helpers, and `useCrashcat`
294
287
 
295
288
  ## Development
296
289
 
@@ -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";
@@ -1,11 +1,12 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useFrame } from "@react-three/fiber";
4
- import { useEffect, useMemo, useRef } from "react";
4
+ import { useCallback, useEffect, useMemo, useRef } from "react";
5
+ import { useStore } from "zustand";
5
6
  import { BooleanField, FieldRenderer, StringField, Vector3Field, } from "../../tools/prefabeditor/components/Input";
6
- import { useAssetRuntime, useNode } from "../../tools/prefabeditor/assetRuntime";
7
+ import { useModelAsset, useNode } from "../../tools/prefabeditor/assetRuntime";
7
8
  import { usePrefabStoreApi } from "../../tools/prefabeditor/prefabStore";
8
- import { PrefabEditorMode, useScene } from "../../tools/prefabeditor/PrefabRoot";
9
+ import { PrefabEditorMode, useScene } from "../../tools/prefabeditor/SceneContext";
9
10
  import { box, capsule, convexHull, MotionQuality, MotionType, rigidBody, sphere, triangleMesh, } from "crashcat";
10
11
  import { Matrix4, Quaternion, Vector3 } from "three";
11
12
  import { useCrashcat } from "./CrashcatRuntime";
@@ -51,7 +52,26 @@ const scratchBoundsSize = new Vector3();
51
52
  const worldQuaternion = new Quaternion();
52
53
  const parentWorldQuaternion = new Quaternion();
53
54
  const localQuaternion = new Quaternion();
55
+ // Extracted collider geometry is keyed by the sequence of geometry UUIDs in the
56
+ // object's subtree. Clones of the same model share geometry instances and have
57
+ // identical model-internal transforms, and the extraction is expressed in
58
+ // object-local space (the object's own world transform is divided out), so the
59
+ // result is identical across every instance/body of that model. Extracting once
60
+ // avoids re-walking thousands of vertices per rigid body.
61
+ const geometryDataCache = new Map();
54
62
  function collectGeometryData(object) {
63
+ let cacheKey = "";
64
+ object.traverse((child) => {
65
+ var _a;
66
+ const geometry = child.geometry;
67
+ if (((_a = geometry === null || geometry === void 0 ? void 0 : geometry.attributes) === null || _a === void 0 ? void 0 : _a.position) && geometry.uuid)
68
+ cacheKey += `${geometry.uuid};`;
69
+ });
70
+ if (cacheKey) {
71
+ const cached = geometryDataCache.get(cacheKey);
72
+ if (cached)
73
+ return cached;
74
+ }
55
75
  const positions = [];
56
76
  const indices = [];
57
77
  let vertexOffset = 0;
@@ -83,7 +103,10 @@ function collectGeometryData(object) {
83
103
  });
84
104
  if (positions.length === 0 || indices.length < 3)
85
105
  return null;
86
- return { positions, indices };
106
+ const result = { positions, indices };
107
+ if (cacheKey)
108
+ geometryDataCache.set(cacheKey, result);
109
+ return result;
87
110
  }
88
111
  function createShapeForObject(object, physics) {
89
112
  var _a, _b;
@@ -246,8 +269,23 @@ function CrashcatPhysicsView({ properties, children }) {
246
269
  const scene = useScene();
247
270
  const store = usePrefabStoreApi();
248
271
  const api = useCrashcat();
249
- const { getAssetRevision } = useAssetRuntime();
250
- const revision = getAssetRevision();
272
+ // Subscribe only to this node's Model filename (not its full node, which would
273
+ // re-render on every transform edit), then to that one model's loaded asset.
274
+ // Colliders rebuild when *this* node's mesh loads, not when any asset loads.
275
+ const modelPath = useStore(store, useCallback((s) => {
276
+ var _a, _b;
277
+ const node = s.nodesById[nodeId];
278
+ if (!node)
279
+ return null;
280
+ for (const key in node.components) {
281
+ const component = node.components[key];
282
+ if ((component === null || component === void 0 ? void 0 : component.type) === "Model") {
283
+ return (_b = (_a = component.properties) === null || _a === void 0 ? void 0 : _a.filename) !== null && _b !== void 0 ? _b : null;
284
+ }
285
+ }
286
+ return null;
287
+ }, [nodeId]));
288
+ const loadedModel = useModelAsset(modelPath);
251
289
  const bodyRef = useRef(null);
252
290
  const motionTypeRef = useRef(MotionType.STATIC);
253
291
  const needsRegistrationRef = useRef(false);
@@ -307,8 +345,8 @@ function CrashcatPhysicsView({ properties, children }) {
307
345
  lastQuaternionRef.current = null;
308
346
  };
309
347
  useEffect(() => {
310
- // Rebuild mesh-derived colliders when referenced assets finish loading.
311
- void revision;
348
+ // Rebuild mesh-derived colliders when this node's referenced model finishes loading.
349
+ void loadedModel;
312
350
  needsRegistrationRef.current = true;
313
351
  if (api) {
314
352
  api.unregister(nodeId);
@@ -325,7 +363,7 @@ function CrashcatPhysicsView({ properties, children }) {
325
363
  getObject,
326
364
  nodeId,
327
365
  physics,
328
- revision,
366
+ loadedModel,
329
367
  ]);
330
368
  useFrame(() => {
331
369
  if (needsRegistrationRef.current) {
@@ -52,7 +52,7 @@ export type CrashcatRagdollProps = {
52
52
  nodeInteractionHandlers?: NodeInteractionHandlers;
53
53
  };
54
54
  export declare function createRagdollSettings(scale?: number, angleA?: number, angleB?: number, twistAngle?: number): RagdollSettings;
55
- export declare function CrashcatRagdoll({ position, scale, swingAngle, shoulderAngle, twistAngle, stabilize, initialLinearVelocity, initialAngularVelocity, color, clickImpulse, nodeInteractionHandlers, }: CrashcatRagdollProps): import("react/jsx-runtime").JSX.Element;
55
+ export declare function CrashcatRagdoll({ position, scale, swingAngle, shoulderAngle, twistAngle, stabilize, initialLinearVelocity, initialAngularVelocity, color, clickImpulse, nodeInteractionHandlers, }: CrashcatRagdollProps): import("react").JSX.Element;
56
56
  declare const CrashcatRagdollComponent: Component;
57
57
  export default CrashcatRagdollComponent;
58
58
  export declare function createStaticBoxBody(world: World, objectLayer: number, halfExtents: Vec3, position: Vec3): rigidBody.RigidBody;
@@ -24,4 +24,4 @@ export declare function useCrashcat(): CrashcatApi | null;
24
24
  export declare function CrashcatRuntime({ debug, children }: {
25
25
  debug?: boolean;
26
26
  children?: React.ReactNode;
27
- }): import("react/jsx-runtime").JSX.Element;
27
+ }): import("react").JSX.Element;
@@ -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/PrefabRoot";
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;
@@ -4,5 +4,5 @@ interface ContactShadowProps {
4
4
  scale?: number;
5
5
  yOffset?: number;
6
6
  }
7
- declare const ContactShadow: ({ opacity, blur, scale, yOffset, }: ContactShadowProps) => import("react/jsx-runtime").JSX.Element;
7
+ declare const ContactShadow: ({ opacity, blur, scale, yOffset, }: ContactShadowProps) => import("react").JSX.Element;
8
8
  export default ContactShadow;
@@ -5,4 +5,4 @@ export interface GameCanvasProps extends Omit<CanvasProps, 'children'> {
5
5
  children: React.ReactNode;
6
6
  glConfig?: WebGPURendererParameters;
7
7
  }
8
- export default function GameCanvas({ loader, children, glConfig, onCreated, style, ...props }: GameCanvasProps): import("react/jsx-runtime").JSX.Element;
8
+ export default function GameCanvas({ loader, children, glConfig, onCreated, style, ...props }: GameCanvasProps): import("react").JSX.Element;
@@ -4,48 +4,48 @@ interface TextureListViewerProps {
4
4
  onSelect: (file: string) => void;
5
5
  basePath?: string;
6
6
  }
7
- export declare function TextureListViewer({ files, selected, onSelect, basePath }: TextureListViewerProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function TextureListViewer({ files, selected, onSelect, basePath }: TextureListViewerProps): import("react").JSX.Element;
8
8
  interface ModelListViewerProps {
9
9
  files: string[];
10
10
  selected?: string;
11
11
  onSelect: (file: string) => void;
12
12
  basePath?: string;
13
13
  }
14
- export declare function ModelListViewer({ files, selected, onSelect, basePath }: ModelListViewerProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function ModelListViewer({ files, selected, onSelect, basePath }: ModelListViewerProps): import("react").JSX.Element;
15
15
  interface SoundListViewerProps {
16
16
  files: string[];
17
17
  selected?: string;
18
18
  onSelect: (file: string) => void;
19
19
  basePath?: string;
20
20
  }
21
- export declare function SoundListViewer({ files, selected, onSelect, basePath }: SoundListViewerProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function SoundListViewer({ files, selected, onSelect, basePath }: SoundListViewerProps): import("react").JSX.Element;
22
22
  export declare function TexturePicker({ value, onChange, basePath }: {
23
23
  value: string | undefined;
24
24
  onChange: (value: string | undefined) => void;
25
25
  basePath?: string;
26
- }): import("react/jsx-runtime").JSX.Element;
26
+ }): import("react").JSX.Element;
27
27
  export declare function ModelPicker({ value, onChange, basePath, pickerKey }: {
28
28
  value: string | undefined;
29
29
  onChange: (value: string | undefined) => void;
30
30
  basePath?: string;
31
31
  pickerKey?: string;
32
- }): import("react/jsx-runtime").JSX.Element;
32
+ }): import("react").JSX.Element;
33
33
  export declare function SoundPicker({ value, onChange, basePath }: {
34
34
  value: string | undefined;
35
35
  onChange: (value: string | undefined) => void;
36
36
  basePath?: string;
37
- }): import("react/jsx-runtime").JSX.Element;
37
+ }): import("react").JSX.Element;
38
38
  export declare function SingleTextureViewer({ file, basePath }: {
39
39
  file?: string;
40
40
  basePath?: string;
41
- }): import("react/jsx-runtime").JSX.Element;
41
+ }): import("react").JSX.Element;
42
42
  export declare function SingleModelViewer({ file, basePath }: {
43
43
  file?: string;
44
44
  basePath?: string;
45
- }): import("react/jsx-runtime").JSX.Element;
45
+ }): import("react").JSX.Element;
46
46
  export declare function SingleSoundViewer({ file, basePath }: {
47
47
  file?: string;
48
48
  basePath?: string;
49
- }): import("react/jsx-runtime").JSX.Element | null;
50
- export declare function SharedCanvas(): import("react/jsx-runtime").JSX.Element;
49
+ }): import("react").JSX.Element | null;
50
+ export declare function SharedCanvas(): import("react").JSX.Element;
51
51
  export {};
@@ -21,6 +21,6 @@ export declare function loadDroppedAssets(dataTransfer: DataTransfer | null, opt
21
21
  export declare function loadUrls(urls: string[], options: AssetLoadOptions): Promise<void>;
22
22
  export declare function loadUrl(url: string, options: AssetLoadOptions): Promise<void>;
23
23
  export declare function loadFiles(files: File[], { onModelLoaded, onTextureLoaded, onSoundLoaded, onUnhandledFile, onFilesLoaded, onLoadError }: AssetLoadOptions): Promise<void>;
24
- export declare function DragDropLoader({ children, ...divProps }: DragDropLoaderProps): import("react/jsx-runtime").JSX.Element;
25
- export declare function FilePicker({ accept, children, multiple, ...divProps }: FilePickerProps): import("react/jsx-runtime").JSX.Element;
24
+ export declare function DragDropLoader({ children, ...divProps }: DragDropLoaderProps): import("react").JSX.Element;
25
+ export declare function FilePicker({ accept, children, multiple, ...divProps }: FilePickerProps): import("react").JSX.Element;
26
26
  export {};
@@ -11,5 +11,5 @@ export declare function Dropdown({ trigger, children, placement, offset, zIndex,
11
11
  placement?: Placement;
12
12
  offset?: number;
13
13
  zIndex?: number;
14
- }): import("react/jsx-runtime").JSX.Element;
14
+ }): import("react").JSX.Element;
15
15
  export {};
@@ -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
+ }
@@ -9,4 +9,4 @@ export default function EditorTree({ selectedId, setSelectedId, getPrefab, onRep
9
9
  onRedo?: () => void;
10
10
  canUndo?: boolean;
11
11
  canRedo?: boolean;
12
- }): import("react/jsx-runtime").JSX.Element;
12
+ }): import("react").JSX.Element;
@@ -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 './PrefabEditor';
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';
@@ -14,7 +14,7 @@ export declare function TreeNodeMenu({ isRoot, nodeId, locked, onAddChild, onFoc
14
14
  onDuplicate?: (nodeId: string) => void;
15
15
  onDelete?: (nodeId: string) => void;
16
16
  onClose: () => void;
17
- }): import("react/jsx-runtime").JSX.Element;
17
+ }): import("react").JSX.Element;
18
18
  export declare function TreeContextMenu({ contextMenu, onClose, children, }: {
19
19
  contextMenu: TreeContextMenuState;
20
20
  onClose: () => void;
@@ -26,4 +26,4 @@ export declare function FileMenu({ getPrefab, onReplacePrefab, onImportPrefab, o
26
26
  onImportPrefab: (prefab: Prefab) => void;
27
27
  onImportPackedPrefab: (url: string) => void;
28
28
  onClose: () => void;
29
- }): import("react/jsx-runtime").JSX.Element;
29
+ }): import("react").JSX.Element;
@@ -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 './PrefabEditor';
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 }));
@@ -10,5 +10,5 @@ declare function EditorUI({ selectedId, setSelectedId, getPrefab, onReplacePrefa
10
10
  onRedo?: () => void;
11
11
  canUndo?: boolean;
12
12
  canRedo?: boolean;
13
- }): import("react/jsx-runtime").JSX.Element;
13
+ }): import("react").JSX.Element;
14
14
  export default EditorUI;
@@ -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 }) {
@@ -29,7 +29,7 @@ export declare function GameInstanceProvider({ children, models, onSelect, onCli
29
29
  registerRef?: (id: string, obj: Object3D | null) => void;
30
30
  selectedId?: string | null;
31
31
  editMode?: boolean;
32
- }): import("react/jsx-runtime").JSX.Element;
32
+ }): import("react").JSX.Element;
33
33
  export declare function useInstanceCheck(id: string): boolean;
34
34
  export declare function GameInstance({ id, sourceId, modelUrl, locked, position, rotation, scale, visible, onClick: _onClick, }: {
35
35
  id: string;
@@ -1,44 +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";
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 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
- 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;