react-three-game 0.0.92 → 0.0.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +68 -33
  2. package/dist/helpers/index.d.ts +0 -3
  3. package/dist/helpers/index.js +1 -8
  4. package/dist/index.d.ts +5 -8
  5. package/dist/index.js +3 -4
  6. package/dist/tools/prefabeditor/EditorTree.js +2 -2
  7. package/dist/tools/prefabeditor/GameEvents.d.ts +6 -12
  8. package/dist/tools/prefabeditor/GameEvents.js +0 -8
  9. package/dist/tools/prefabeditor/InstanceProvider.d.ts +6 -4
  10. package/dist/tools/prefabeditor/InstanceProvider.js +84 -199
  11. package/dist/tools/prefabeditor/PrefabEditor.d.ts +18 -6
  12. package/dist/tools/prefabeditor/PrefabEditor.js +55 -39
  13. package/dist/tools/prefabeditor/PrefabRoot.d.ts +15 -8
  14. package/dist/tools/prefabeditor/PrefabRoot.js +141 -117
  15. package/dist/tools/prefabeditor/assetRuntime.d.ts +13 -11
  16. package/dist/tools/prefabeditor/assetRuntime.js +15 -15
  17. package/dist/tools/prefabeditor/components/BufferGeometryComponent.js +1 -1
  18. package/dist/tools/prefabeditor/components/CameraComponent.js +2 -2
  19. package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +3 -3
  20. package/dist/tools/prefabeditor/components/DirectionalLightComponent.js +2 -2
  21. package/dist/tools/prefabeditor/components/ModelComponent.js +1 -1
  22. package/dist/tools/prefabeditor/components/PointLightComponent.js +2 -2
  23. package/dist/tools/prefabeditor/components/SoundComponent.js +2 -2
  24. package/dist/tools/prefabeditor/components/SpotLightComponent.js +2 -2
  25. package/dist/tools/prefabeditor/components/index.js +0 -2
  26. package/dist/tools/prefabeditor/types.d.ts +1 -0
  27. package/dist/tools/prefabeditor/usePointerEvents.d.ts +3 -3
  28. package/dist/tools/prefabeditor/usePointerEvents.js +5 -5
  29. package/package.json +1 -3
  30. package/dist/tools/prefabeditor/components/PhysicsComponent.d.ts +0 -26
  31. package/dist/tools/prefabeditor/components/PhysicsComponent.js +0 -302
  32. package/dist/tools/prefabeditor/scene.d.ts +0 -70
  33. package/dist/tools/prefabeditor/scene.js +0 -237
package/README.md CHANGED
@@ -1,16 +1,15 @@
1
1
  # react-three-game
2
2
 
3
- ![Scene Editor](assets/editor.gif)
3
+ ![Prefab Editor](assets/editor.gif)
4
4
 
5
- JSON-first scene mounting and authoring for React Three Fiber.
5
+ JSON-first prefab mounting and authoring for React Three Fiber.
6
6
 
7
- Built on top of [three.js](https://github.com/mrdoob/three.js), [@react-three/fiber](https://github.com/pmndrs/react-three-fiber), and [@react-three/rapier](https://github.com/pmndrs/react-three-rapier).
7
+ Built on top of [three.js](https://github.com/mrdoob/three.js), [@react-three/fiber](https://github.com/pmndrs/react-three-fiber), and [@react-three/drei](https://github.com/pmndrs/drei).
8
8
 
9
- * **🧱 Prefabs** - Save scenes as serializable JSON and load them on their own or inside other scenes.
10
- * **🎬 Scene Editor** - Edit prefabs visually with hierarchy, inspector, transform gizmos, and play mode.
11
- * **⚛️ Physics** - Author rigid bodies directly in prefab data and run them through Rapier.
12
- * **🧩 Components** - Build scenes from reusable `GameObject` + component composition.
13
- * **🔧 Direct Runtime Access** - Get native `Object3D`, Rapier rigid body, and prefab store access without a parallel engine API.
9
+ * **🧱 Prefabs** - Save prefabs as serializable JSON and load them on their own or inside larger app worlds.
10
+ * **🎬 Prefab Editor** - Edit prefabs visually with hierarchy, inspector, transform gizmos, and play mode.
11
+ * **🧩 Components** - Build prefabs from reusable `GameObject` + component composition.
12
+ * **🔧 Direct Runtime Access** - Get native `Object3D`, runtime handles, and authored prefab mutation APIs without a parallel engine API.
14
13
  * **⚡ R3F Native** - Use normal React Three Fiber components whenever runtime behavior is clearer in code.
15
14
 
16
15
  ## Documentation
@@ -21,7 +20,7 @@ Built on top of [three.js](https://github.com/mrdoob/three.js), [@react-three/fi
21
20
  ## Install
22
21
 
23
22
  ```bash
24
- npm install react-three-game @react-three/drei @react-three/fiber @react-three/rapier three
23
+ npm install react-three-game @react-three/drei @react-three/fiber three
25
24
  ```
26
25
 
27
26
  ## Usage
@@ -29,12 +28,11 @@ npm install react-three-game @react-three/drei @react-three/fiber @react-three/r
29
28
  Here is a minimal example that renders a prefab inside a normal R3F app:
30
29
 
31
30
  ```tsx
32
- import { Physics } from "@react-three/rapier";
33
31
  import { GameCanvas, PrefabRoot, ground } from "react-three-game";
34
32
 
35
33
  const prefab = {
36
34
  id: "starter-scene",
37
- name: "Starter Scene",
35
+ name: "Starter Prefab",
38
36
  root: {
39
37
  id: "root",
40
38
  children: [
@@ -58,10 +56,6 @@ const prefab = {
58
56
  type: "Material",
59
57
  properties: { color: "#f66" },
60
58
  },
61
- physics: {
62
- type: "Physics",
63
- properties: { type: "dynamic" },
64
- },
65
59
  },
66
60
  },
67
61
  ],
@@ -71,16 +65,14 @@ const prefab = {
71
65
  export default function App() {
72
66
  return (
73
67
  <GameCanvas>
74
- <Physics>
75
- <ambientLight intensity={0.8} />
76
- <PrefabRoot data={prefab} />
77
- </Physics>
68
+ <ambientLight intensity={0.8} />
69
+ <PrefabRoot data={prefab} />
78
70
  </GameCanvas>
79
71
  );
80
72
  }
81
73
  ```
82
74
 
83
- This example renders a falling sphere above a ground plane.
75
+ This example renders a simple authored prefab with a ground plane and mesh content.
84
76
 
85
77
  ## Prefab Editor
86
78
 
@@ -98,22 +90,21 @@ Open the hosted editor here:
98
90
 
99
91
  * https://prnth.com/react-three-game/editor
100
92
 
101
- ## Prefabs And Mounted Scenes
93
+ ## Prefabs And Mounted Objects
102
94
 
103
95
  `Prefab` is the serializable pure data format.
104
96
 
105
- That means a saved scene is just a prefab, and the same prefab can be:
97
+ That means authored content stays as a prefab, and the same prefab can be:
106
98
 
107
99
  * edited directly in `PrefabEditor`
108
100
  * rendered directly with `PrefabRoot`
109
- * loaded inside another scene as reusable content
101
+ * loaded inside another prefab or app scene as reusable content
110
102
 
111
103
  `PrefabRoot` keeps the rendering model narrow and compositional:
112
104
 
113
105
  * `Transform` is the renderer-owned outer transform
114
106
  * `Geometry` or `BufferGeometry` + `Material` become the primary mesh content
115
107
  * non-instanced `Model` becomes the node's primary content
116
- * `Physics` is a renderer-owned outer wrapper
117
108
  * every other component `View` wraps the current subtree
118
109
 
119
110
  Custom component `View`s use normal React Three Fiber composition with `children`.
@@ -161,7 +152,7 @@ interface GameObject {
161
152
 
162
153
  ## Runtime Mutation
163
154
 
164
- Use native object access for Three.js behavior and the prefab store for authored data changes.
155
+ Use editor or root refs for scene-native object access, and use the editor mutation methods for authored data changes.
165
156
 
166
157
  ```tsx
167
158
  import { useEffect, useRef } from "react";
@@ -171,7 +162,7 @@ function RaiseBall() {
171
162
  const editorRef = useRef<PrefabEditorRef>(null);
172
163
 
173
164
  useEffect(() => {
174
- editorRef.current?.store.getState().updateNode("ball", (node) => ({
165
+ editorRef.current?.updateNode("ball", (node) => ({
175
166
  ...node,
176
167
  components: {
177
168
  ...node.components,
@@ -193,10 +184,55 @@ function RaiseBall() {
193
184
  For live Three.js access, use mounted objects directly:
194
185
 
195
186
  ```tsx
196
- const ball = editorRef.current?.getObject("ball");
187
+ const ball = editorRef.current?.getNodeObject("ball");
197
188
  ball?.rotateY(0.5);
198
189
  ```
199
190
 
191
+ For runtime integrations that need edit-time re-sync, subscribe to authored scene changes:
192
+
193
+ ```tsx
194
+ const stop = editorRef.current?.onSceneChange((revision) => {
195
+ console.log("scene changed", revision);
196
+ });
197
+
198
+ stop?.();
199
+ ```
200
+
201
+ For runtime-owned imperative state, use node-local handles instead of reaching for ad hoc globals:
202
+
203
+ ```tsx
204
+ import { useEffect } from "react";
205
+ import { useAssetRuntime, useCurrentNode, useCurrentNodeHandle } from "react-three-game";
206
+
207
+ function SpinnerView({ children }: { children?: React.ReactNode }) {
208
+ const { nodeId } = useCurrentNode();
209
+ const { registerNodeHandle } = useAssetRuntime();
210
+
211
+ useEffect(() => {
212
+ const handle = {
213
+ setSpeed(next: number) {
214
+ console.log("speed", next);
215
+ },
216
+ };
217
+
218
+ registerNodeHandle(nodeId, "spinner", handle);
219
+ return () => registerNodeHandle(nodeId, "spinner", null);
220
+ }, [nodeId, registerNodeHandle]);
221
+
222
+ return <>{children}</>;
223
+ }
224
+
225
+ function SpinnerStatus() {
226
+ const spinnerRef = useCurrentNodeHandle<{ setSpeed: (next: number) => void }>("spinner");
227
+
228
+ useEffect(() => {
229
+ spinnerRef.current?.setSpeed(2);
230
+ }, [spinnerRef]);
231
+
232
+ return null;
233
+ }
234
+ ```
235
+
200
236
  Mounted node metadata is mirrored onto the canonical Three.js wrapper object:
201
237
 
202
238
  * `GameObject.id` -> `object.userData.prefabNodeId`
@@ -213,7 +249,7 @@ const playerById = editorRef.current?.root?.getObjectByProperty("userData.prefab
213
249
  Treat names as a convenience surface, not the primary lookup key:
214
250
 
215
251
  * names are not guaranteed unique
216
- * `getObject(id)` is still the stable authored-node lookup
252
+ * `getNodeObject(id)` is the clearest stable authored-node lookup
217
253
  * traversal metadata is applied to the prefab node transform object, not necessarily the inner mesh or model child
218
254
 
219
255
  You can author extra `userData` from the editor with a `Data` component:
@@ -231,7 +267,7 @@ You can author extra `userData` from the editor with a `Data` component:
231
267
  For batched authored updates, write through the store once:
232
268
 
233
269
  ```tsx
234
- editorRef.current?.store.getState().updateNodes([
270
+ editorRef.current?.updateNodes([
235
271
  {
236
272
  id: "orb1",
237
273
  update: (node) => ({
@@ -280,11 +316,10 @@ Custom component `View`s should use normal React and R3F behavior, such as `useF
280
316
  * `Prefab`
281
317
  * `GameObject`
282
318
  * `registerComponent`
283
- * `createPrefabStore`
284
- * `usePrefabStoreApi`
285
- * `useAssetRuntime()` / `useEntityRuntime()`
286
- * `useEntityObjectRef()` / `useEntityRigidBodyRef()`
319
+ * `useAssetRuntime()` / `useCurrentNode()`
320
+ * `useCurrentNodeObject()` / `useCurrentNodeHandle()`
287
321
  * `ground(...)`
322
+ * `gameEvents` / `useGameEvent()` / `useClickEvent()`
288
323
  * `loadJson()` / `saveJson()`
289
324
  * `loadModel()` / `loadTexture()`
290
325
  * `loadSound()` / `loadFiles()`
@@ -16,8 +16,6 @@ export interface GroundOptions {
16
16
  repeat?: boolean;
17
17
  /** Texture repeat counts when repeat=true. Defaults to [25,25]. */
18
18
  repeatCount?: [number, number];
19
- /** Physics body type. Defaults to "fixed". */
20
- physicsType?: "fixed" | "dynamic" | "kinematic";
21
19
  /** Set true to disable the node. */
22
20
  disabled?: boolean;
23
21
  }
@@ -28,6 +26,5 @@ export interface GroundOptions {
28
26
  * - Transform (rotated to lie flat)
29
27
  * - Geometry (plane)
30
28
  * - Material (optional texture + repeat)
31
- * - Physics (fixed by default)
32
29
  */
33
30
  export declare function ground(options?: GroundOptions): GameObject;
@@ -5,10 +5,9 @@
5
5
  * - Transform (rotated to lie flat)
6
6
  * - Geometry (plane)
7
7
  * - Material (optional texture + repeat)
8
- * - Physics (fixed by default)
9
8
  */
10
9
  export function ground(options = {}) {
11
- const { id = "ground", size = 50, position = [0, 0, 0], rotation = [-Math.PI / 2, 0, 0], scale = [1, 1, 1], color = "#eeeeee", texture, repeat = texture ? true : false, repeatCount = [25, 25], physicsType = "fixed", disabled = false, } = options;
10
+ const { id = "ground", size = 50, position = [0, 0, 0], rotation = [-Math.PI / 2, 0, 0], scale = [1, 1, 1], color = "#eeeeee", texture, repeat = texture ? true : false, repeatCount = [25, 25], disabled = false, } = options;
12
11
  return {
13
12
  id,
14
13
  disabled,
@@ -32,12 +31,6 @@ export function ground(options = {}) {
32
31
  type: "Material",
33
32
  properties: Object.assign(Object.assign({ color }, (texture ? { texture } : {})), (repeat ? { repeat: true, repeatCount } : {})),
34
33
  },
35
- physics: {
36
- type: "Physics",
37
- properties: {
38
- type: physicsType,
39
- },
40
- },
41
34
  },
42
35
  };
43
36
  }
package/dist/index.d.ts CHANGED
@@ -8,21 +8,18 @@ export { PrefabEditorMode } from './tools/prefabeditor/PrefabEditor';
8
8
  export { default as PrefabRoot } from './tools/prefabeditor/PrefabRoot';
9
9
  export { useEditorContext } from './tools/prefabeditor/PrefabEditor';
10
10
  export type { EditorContextType } from './tools/prefabeditor/PrefabEditor';
11
- export { createPrefabStore, prefabStoreToPrefab, usePrefabStoreApi } from './tools/prefabeditor/prefabStore';
12
- export type { PrefabStoreApi, PrefabStoreState } from './tools/prefabeditor/prefabStore';
13
11
  export { denormalizePrefab } from './tools/prefabeditor/prefab';
14
- export { gameEvents, getEntityIdFromRigidBody, useClickEvent, useGameEvent, usePhysicsEvent } from './tools/prefabeditor/GameEvents';
15
- export type { ClickEventPayload, GameEventHandler, GameEventMap, PhysicsEventPayload } from './tools/prefabeditor/GameEvents';
12
+ export { gameEvents, useClickEvent, useGameEvent } from './tools/prefabeditor/GameEvents';
13
+ export type { ClickEventPayload, ContactEventPayload, GameEventHandler, GameEventMap } from './tools/prefabeditor/GameEvents';
16
14
  export { registerComponent } from './tools/prefabeditor/components/ComponentRegistry';
17
15
  export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from './tools/prefabeditor/components/Input';
18
16
  export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from './tools/prefabeditor/utils';
19
17
  export type { ExportGLBOptions } from './tools/prefabeditor/utils';
20
18
  export { createModelNode, createImageNode, } from './tools/prefabeditor/prefab';
21
- export type { PrefabEditorProps, PrefabEditorRef, } from './tools/prefabeditor/PrefabEditor';
22
- export type { Entity, EntityComponent, EntityData, EntityUpdate, PropertyPath, Scene, SceneUpdates, SpawnOptions, } from './tools/prefabeditor/scene';
19
+ export type { PrefabEditorProps, PrefabNode, PrefabEditorRef, SpawnOptions, } from './tools/prefabeditor/PrefabEditor';
23
20
  export type { PrefabRootProps } from './tools/prefabeditor/PrefabRoot';
24
- export type { AssetRuntime, EntityRuntime, LiveObjectRef, LiveRigidBodyRef } from './tools/prefabeditor/assetRuntime';
25
- export { useAssetRuntime, useEntityRuntime, useEntityObjectRef, useEntityRigidBodyRef } from './tools/prefabeditor/assetRuntime';
21
+ export type { AssetRuntime, CurrentNodeRuntime, LiveHandleRef, LiveObjectRef, CurrentNodeHandleRef, CurrentNodeObjectRef } from './tools/prefabeditor/assetRuntime';
22
+ export { useAssetRuntime, useCurrentNode, useCurrentNodeHandle, useCurrentNodeObject } from './tools/prefabeditor/assetRuntime';
26
23
  export type { Component, ComponentViewProps } from './tools/prefabeditor/components/ComponentRegistry';
27
24
  export type { FieldDefinition, FieldType } from './tools/prefabeditor/components/Input';
28
25
  export { MaterialOverridesProvider, useMaterialOverrides } from './tools/prefabeditor/components/MaterialComponent';
package/dist/index.js CHANGED
@@ -8,10 +8,9 @@ export { default as PrefabEditor } from './tools/prefabeditor/PrefabEditor';
8
8
  export { PrefabEditorMode } from './tools/prefabeditor/PrefabEditor';
9
9
  export { default as PrefabRoot } from './tools/prefabeditor/PrefabRoot';
10
10
  export { useEditorContext } from './tools/prefabeditor/PrefabEditor';
11
- // Prefab Editor - Store & Scene API
12
- export { createPrefabStore, prefabStoreToPrefab, usePrefabStoreApi } from './tools/prefabeditor/prefabStore';
11
+ // Prefab Editor - Data API
13
12
  export { denormalizePrefab } from './tools/prefabeditor/prefab';
14
- export { gameEvents, getEntityIdFromRigidBody, useClickEvent, useGameEvent, usePhysicsEvent } from './tools/prefabeditor/GameEvents';
13
+ export { gameEvents, useClickEvent, useGameEvent } from './tools/prefabeditor/GameEvents';
15
14
  // Prefab Editor - Component Registry
16
15
  export { registerComponent } from './tools/prefabeditor/components/ComponentRegistry';
17
16
  // Prefab Editor - Input Components
@@ -19,7 +18,7 @@ export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Fiel
19
18
  // Prefab Editor - Utils
20
19
  export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from './tools/prefabeditor/utils';
21
20
  export { createModelNode, createImageNode, } from './tools/prefabeditor/prefab';
22
- export { useAssetRuntime, useEntityRuntime, useEntityObjectRef, useEntityRigidBodyRef } from './tools/prefabeditor/assetRuntime';
21
+ export { useAssetRuntime, useCurrentNode, useCurrentNodeHandle, useCurrentNodeObject } from './tools/prefabeditor/assetRuntime';
23
22
  export { MaterialOverridesProvider, useMaterialOverrides } from './tools/prefabeditor/components/MaterialComponent';
24
23
  export { findComponent, findComponentEntry, hasComponent } from './tools/prefabeditor/types';
25
24
  export { float, positionLocal, sin, time, uniform, vec3, } from 'three/tsl';
@@ -104,7 +104,7 @@ export default function EditorTree({ selectedId, setSelectedId, getPrefab, onRep
104
104
  setDropTarget(null);
105
105
  };
106
106
  const visibleIds = usePrefabStore(useCallback(state => searchQuery ? buildVisibleIds(state, rootId, searchQuery) : null, [rootId, searchQuery]));
107
- return (_jsxs(_Fragment, { children: [_jsxs("div", { style: Object.assign(Object.assign({}, tree.panel), { width: collapsed ? 'auto' : 224 }), children: [_jsxs("div", { style: base.header, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }, onClick: () => setCollapsed(!collapsed), children: [_jsx("span", { children: collapsed ? '▶' : '▼' }), _jsx("span", { children: "Scene" })] }), !collapsed && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4 }, children: [_jsx("button", { style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px', fontSize: 10, opacity: canUndo ? 1 : 0.4 }), onClick: (e) => { e.stopPropagation(); onUndo === null || onUndo === void 0 ? void 0 : onUndo(); }, disabled: !canUndo, title: "Undo", children: "\u21B6" }), _jsx("button", { style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px', fontSize: 10, opacity: canRedo ? 1 : 0.4 }), onClick: (e) => { e.stopPropagation(); onRedo === null || onRedo === void 0 ? void 0 : onRedo(); }, disabled: !canRedo, title: "Redo", children: "\u21B7" }), _jsx(Dropdown, { placement: "bottom-end", trigger: ({ ref, toggle }) => (_jsx("button", { ref: ref, title: "Menu", style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px', fontSize: 10 }), onClick: (e) => {
107
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { style: Object.assign(Object.assign({}, tree.panel), { width: collapsed ? 'auto' : 224 }), children: [_jsxs("div", { style: base.header, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer' }, onClick: () => setCollapsed(!collapsed), children: [_jsx("span", { children: collapsed ? '▶' : '▼' }), _jsx("span", { children: "Prefab" })] }), !collapsed && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4 }, children: [_jsx("button", { style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px', fontSize: 10, opacity: canUndo ? 1 : 0.4 }), onClick: (e) => { e.stopPropagation(); onUndo === null || onUndo === void 0 ? void 0 : onUndo(); }, disabled: !canUndo, title: "Undo", children: "\u21B6" }), _jsx("button", { style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px', fontSize: 10, opacity: canRedo ? 1 : 0.4 }), onClick: (e) => { e.stopPropagation(); onRedo === null || onRedo === void 0 ? void 0 : onRedo(); }, disabled: !canRedo, title: "Redo", children: "\u21B7" }), _jsx(Dropdown, { placement: "bottom-end", trigger: ({ ref, toggle }) => (_jsx("button", { ref: ref, title: "Menu", style: Object.assign(Object.assign({}, base.btn), { padding: '2px 6px', fontSize: 10 }), onClick: (e) => {
108
108
  e.stopPropagation();
109
109
  toggle();
110
110
  }, children: "\u22EE" })), children: (close) => (_jsx(FileMenu, { getPrefab: getPrefab, onReplacePrefab: onReplacePrefab, onImportPrefab: onImportPrefab, onClose: close })) })] }))] }), !collapsed && (_jsxs(_Fragment, { children: [_jsx("div", { style: { padding: '4px 4px', borderBottom: `1px solid ${colors.borderLight}` }, children: _jsx("input", { type: "text", placeholder: "Search nodes...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onClick: (e) => e.stopPropagation(), style: Object.assign(Object.assign({}, base.input), { padding: '4px 8px' }) }) }), _jsx("div", { style: tree.scroll, children: _jsx(TreeNode, { nodeId: rootId, depth: 0, rootId: rootId, visibleIds: visibleIds, collapsedIds: collapsedIds, dropTarget: dropTarget, selectedNodeId: selectedId, onToggleCollapse: toggleCollapse, onOpenContextMenu: openContextMenu, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, onDragEnd: () => { setDraggedId(null); setDropTarget(null); }, renderTreeNodeMenu: renderTreeNodeMenu, onToggleDisabled: handleToggleDisabled, setSelectedId: setSelectedId }) })] }))] }), _jsx(TreeContextMenu, { contextMenu: contextMenu, onClose: closeContextMenu, children: (nodeId, close) => renderTreeNodeMenu(nodeId, nodeId === rootId, close) })] }));
@@ -138,7 +138,7 @@ const TreeNode = memo(function TreeNode({ nodeId, depth, rootId, visibleIds, col
138
138
  }, children: "\u22EF" })), children: (close) => renderTreeNodeMenu(nodeId, false, close) }), _jsx("button", { style: Object.assign(Object.assign({}, tree.iconButton), { opacity: node.disabled ? 0.5 : 0.7 }), onClick: (e) => {
139
139
  e.stopPropagation();
140
140
  onToggleDisabled(nodeId);
141
- }, title: node.disabled ? 'Enable' : 'Disable', children: node.disabled ? '◎' : '◉' })] })), isRoot && (_jsx(Dropdown, { placement: "bottom-end", trigger: ({ ref, toggle }) => (_jsx("button", { ref: ref, title: "Scene Actions", style: tree.iconButton, onClick: (e) => {
141
+ }, title: node.disabled ? 'Enable' : 'Disable', children: node.disabled ? '◎' : '◉' })] })), isRoot && (_jsx(Dropdown, { placement: "bottom-end", trigger: ({ ref, toggle }) => (_jsx("button", { ref: ref, title: "Prefab Actions", style: tree.iconButton, onClick: (e) => {
142
142
  e.stopPropagation();
143
143
  toggle();
144
144
  }, children: "\u22EF" })), children: (close) => renderTreeNodeMenu(nodeId, true, close) }))] }), !isCollapsed && childIds.map(childId => (_jsx(TreeNode, { nodeId: childId, depth: depth + 1, rootId: rootId, visibleIds: visibleIds, collapsedIds: collapsedIds, dropTarget: dropTarget, selectedNodeId: selectedNodeId, onToggleCollapse: onToggleCollapse, onOpenContextMenu: onOpenContextMenu, onDragStart: onDragStart, onDragOver: onDragOver, onDragLeave: onDragLeave, onDrop: onDrop, onDragEnd: onDragEnd, renderTreeNodeMenu: renderTreeNodeMenu, onToggleDisabled: onToggleDisabled, setSelectedId: setSelectedId }, childId)))] }));
@@ -1,14 +1,12 @@
1
1
  export type GameEventHandler<TPayload = unknown> = (payload: TPayload) => void;
2
- export type PhysicsEventPayload = {
2
+ export type ContactEventPayload = {
3
3
  sourceEntityId?: string;
4
4
  sourceNodeId?: string;
5
5
  sourceObject?: unknown;
6
- sourceRigidBody?: unknown;
7
6
  targetEntityId?: string | null;
8
7
  targetNodeId?: string | null;
9
8
  targetObject?: unknown;
10
- targetRigidBody?: unknown;
11
- rapierEvent?: unknown;
9
+ event?: unknown;
12
10
  };
13
11
  export type ClickEventPayload = {
14
12
  sourceEntityId?: string;
@@ -26,10 +24,10 @@ export type ClickEventPayload = {
26
24
  r3fEvent?: unknown;
27
25
  };
28
26
  export interface GameEventMap {
29
- 'sensor:enter': PhysicsEventPayload;
30
- 'sensor:exit': PhysicsEventPayload;
31
- 'collision:enter': PhysicsEventPayload;
32
- 'collision:exit': PhysicsEventPayload;
27
+ 'sensor:enter': ContactEventPayload;
28
+ 'sensor:exit': ContactEventPayload;
29
+ 'collision:enter': ContactEventPayload;
30
+ 'collision:exit': ContactEventPayload;
33
31
  click: ClickEventPayload;
34
32
  [eventType: string]: unknown;
35
33
  }
@@ -40,8 +38,4 @@ export declare const gameEvents: {
40
38
  hasListeners(type: string): boolean;
41
39
  };
42
40
  export declare function useGameEvent<TType extends string>(type: TType, handler: GameEventHandler<TType extends keyof GameEventMap ? GameEventMap[TType] : unknown>, deps?: React.DependencyList): void;
43
- export declare function usePhysicsEvent<TType extends string>(type: TType, handler: GameEventHandler<TType extends keyof GameEventMap ? GameEventMap[TType] : unknown>, deps?: React.DependencyList): void;
44
41
  export declare function useClickEvent<TType extends string>(type: TType, handler: GameEventHandler<TType extends keyof GameEventMap ? GameEventMap[TType] : unknown>, deps?: React.DependencyList): void;
45
- export declare function getEntityIdFromRigidBody(rigidBody: {
46
- userData?: unknown;
47
- } | null | undefined): string | null;
@@ -53,14 +53,6 @@ export function useGameEvent(type, handler, deps = []) {
53
53
  return gameEvents.on(type, stableHandler);
54
54
  }, [type, stableHandler]);
55
55
  }
56
- export function usePhysicsEvent(type, handler, deps = []) {
57
- useGameEvent(type, handler, deps);
58
- }
59
56
  export function useClickEvent(type, handler, deps = []) {
60
57
  useGameEvent(type, handler, deps);
61
58
  }
62
- export function getEntityIdFromRigidBody(rigidBody) {
63
- var _a;
64
- const entityId = (_a = rigidBody === null || rigidBody === void 0 ? void 0 : rigidBody.userData) === null || _a === void 0 ? void 0 : _a.entityId;
65
- return typeof entityId === 'string' ? entityId : null;
66
- }
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
+ import { ThreeEvent } from '@react-three/fiber';
2
3
  import { Object3D, Group } from "three";
3
- import { PhysicsProps } from "./components/PhysicsComponent";
4
4
  export type RepeatAxisConfig = {
5
5
  axis: 'x' | 'y' | 'z';
6
6
  count: number;
@@ -13,18 +13,19 @@ export type InstanceData = {
13
13
  id: string;
14
14
  sourceId: string;
15
15
  locked?: boolean;
16
+ visible?: boolean;
16
17
  position: [number, number, number];
17
18
  rotation: [number, number, number];
18
19
  scale: [number, number, number];
19
20
  meshPath: string;
20
- physics?: PhysicsProps | undefined;
21
21
  };
22
- export declare function GameInstanceProvider({ children, models, onSelect, registerRef, selectedId, editMode }: {
22
+ export declare function GameInstanceProvider({ children, models, onSelect, onClick, registerRef, selectedId, editMode }: {
23
23
  children: React.ReactNode;
24
24
  models: {
25
25
  [filename: string]: Object3D;
26
26
  };
27
27
  onSelect?: (id: string | null) => void;
28
+ onClick?: (event: ThreeEvent<PointerEvent>, nodeId: string, object: Object3D | null) => void;
28
29
  registerRef?: (id: string, obj: Object3D | null) => void;
29
30
  selectedId?: string | null;
30
31
  editMode?: boolean;
@@ -38,5 +39,6 @@ export declare const GameInstance: React.ForwardRefExoticComponent<{
38
39
  position: [number, number, number];
39
40
  rotation: [number, number, number];
40
41
  scale: [number, number, number];
41
- physics?: PhysicsProps | undefined;
42
+ visible?: boolean;
43
+ onClick?: (event: ThreeEvent<PointerEvent>, nodeId: string, object: Object3D | null) => void;
42
44
  } & React.RefAttributes<Group<import("three").Object3DEventMap>>>;