react-three-game 0.0.77 → 0.0.79

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.
@@ -1,20 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Canvas } from "@react-three/fiber";
3
3
  import { OrbitControls, View, PerspectiveCamera } from "@react-three/drei";
4
- import { Component as ReactComponent, Suspense, useEffect, useLayoutEffect, useState, useRef } from "react";
4
+ import { Suspense, useEffect, useLayoutEffect, useState, useRef } from "react";
5
5
  import { createPortal } from 'react-dom';
6
6
  import { TextureLoader } from "three";
7
7
  import { loadModel } from "../dragdrop/modelLoader";
8
- class ErrorBoundary extends ReactComponent {
9
- constructor(props) {
10
- super(props);
11
- this.state = { hasError: false };
12
- }
13
- static getDerivedStateFromError() { return { hasError: true }; }
14
- componentDidCatch() { var _a, _b; (_b = (_a = this.props).onError) === null || _b === void 0 ? void 0 : _b.call(_a); }
15
- render() { return this.state.hasError ? null : this.props.children; }
16
- }
17
- // view models and textures in manifest, onselect callback
18
8
  const styles = {
19
9
  errorIcon: { color: '#fca5a5', fontSize: 12 }, // text-red-400 text-xs
20
10
  flexFillRelative: { flex: 1, position: 'relative' },
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  import { MapControls, TransformControls } from "@react-three/drei";
12
12
  import GameCanvas from "../../shared/GameCanvas";
13
- import { useCallback, useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle, createContext, useContext } from "react";
13
+ import { useCallback, useEffect, useMemo, useReducer, useRef, useState, forwardRef, useImperativeHandle, createContext, useContext } from "react";
14
14
  import { findComponentEntry } from "./types";
15
15
  import PrefabRoot from "./PrefabRoot";
16
16
  import { Physics } from "@react-three/rapier";
@@ -21,6 +21,17 @@ import { loadFiles } from "../dragdrop";
21
21
  import { denormalizePrefab, createImageNode, createModelNode, createNode } from './prefab';
22
22
  import { createPrefabStore, PrefabStoreProvider } from "./prefabStore";
23
23
  import { createScene } from "./scene";
24
+ function isObjectAttachedToRoot(root, object) {
25
+ if (!root || !object)
26
+ return false;
27
+ let current = object;
28
+ while (current) {
29
+ if (current === root)
30
+ return true;
31
+ current = current.parent;
32
+ }
33
+ return false;
34
+ }
24
35
  export var PrefabEditorMode;
25
36
  (function (PrefabEditorMode) {
26
37
  PrefabEditorMode["Edit"] = "edit";
@@ -42,6 +53,7 @@ const DEFAULT_PREFAB = {
42
53
  root: createNode('Root', {}, { id: 'root' })
43
54
  };
44
55
  const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode: initialMode = PrefabEditorMode.Edit, onChange, showUI = true, enableWindowDrop = true, canvasProps, uiPlugins, children }, ref) => {
56
+ var _a, _b;
45
57
  const [mode, setMode] = useState(initialMode);
46
58
  const [selectedId, setSelectedId] = useState(null);
47
59
  const [transformMode, setTransformMode] = useState("translate");
@@ -54,7 +66,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
54
66
  const [historyIndex, setHistoryIndex] = useState(0);
55
67
  const changeOriginRef = useRef(null);
56
68
  const historyIndexRef = useRef(0);
57
- const [selectedObject, setSelectedObject] = useState(null);
69
+ const [, bumpSelectedObjectVersion] = useReducer((value) => value + 1, 0);
58
70
  const prefabRootRef = useRef(null);
59
71
  const canvasRef = useRef(null);
60
72
  const controlsRef = useRef(null);
@@ -63,6 +75,11 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
63
75
  const getPrefab = useCallback(() => denormalizePrefab(prefabStore.getState()), [prefabStore]);
64
76
  const getObject = useCallback((nodeId) => { var _a, _b; return (_b = (_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.getObject(nodeId)) !== null && _b !== void 0 ? _b : null; }, []);
65
77
  const getRigidBody = useCallback((nodeId) => { var _a, _b; return (_b = (_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.getRigidBody(nodeId)) !== null && _b !== void 0 ? _b : null; }, []);
78
+ const handleObjectRefChange = useCallback((nodeId) => {
79
+ if (nodeId !== selectedId)
80
+ return;
81
+ bumpSelectedObjectVersion();
82
+ }, [selectedId]);
66
83
  onChangeRef.current = onChange;
67
84
  const setSelection = useCallback((nodeId) => {
68
85
  const nextNode = nodeId ? prefabStore.getState().nodesById[nodeId] : null;
@@ -77,7 +94,6 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
77
94
  return prev;
78
95
  if (nextMode === PrefabEditorMode.Play) {
79
96
  setSelectedId(null);
80
- setSelectedObject(null);
81
97
  }
82
98
  return nextMode;
83
99
  });
@@ -91,7 +107,6 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
91
107
  const loadPrefab = useCallback((prefab, options) => {
92
108
  changeOriginRef.current = (options === null || options === void 0 ? void 0 : options.notifyChange) === false ? "replace-silent" : "replace";
93
109
  prefabStore.getState().replacePrefab(prefab);
94
- setSelectedObject(null);
95
110
  if (options === null || options === void 0 ? void 0 : options.resetHistory) {
96
111
  setSelectedId(null);
97
112
  setHistory([prefab]);
@@ -154,23 +169,13 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
154
169
  if (state.nodesById[selectedId])
155
170
  return;
156
171
  setSelectedId(null);
157
- setSelectedObject(null);
158
172
  });
159
173
  return () => unsubscribe();
160
174
  }, [prefabStore, selectedId]);
161
- useEffect(() => {
162
- if (!selectedId) {
163
- setSelectedObject(null);
164
- return;
165
- }
166
- setSelectedObject(getObject(selectedId));
167
- }, [getObject, selectedId]);
168
- const handleObjectRefChange = useCallback((nodeId, obj) => {
169
- if (nodeId !== selectedId) {
170
- return;
171
- }
172
- setSelectedObject(current => current === obj ? current : obj);
173
- }, [selectedId]);
175
+ const selectedObject = selectedId ? getObject(selectedId) : null;
176
+ const transformObject = isObjectAttachedToRoot((_b = (_a = prefabRootRef.current) === null || _a === void 0 ? void 0 : _a.root) !== null && _b !== void 0 ? _b : null, selectedObject)
177
+ ? selectedObject
178
+ : null;
174
179
  const addNode = useCallback((node, options) => {
175
180
  var _a;
176
181
  const { addChild, rootId } = prefabStore.getState();
@@ -202,7 +207,6 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
202
207
  prefabStore.getState().replacePrefab(history[index]);
203
208
  historyIndexRef.current = index;
204
209
  setHistoryIndex(index);
205
- setSelectedObject(null);
206
210
  setSelectedId(prev => prev && prefabStore.getState().nodesById[prev] ? prev : null);
207
211
  };
208
212
  const undo = () => historyIndex > 0 && applyHistory(historyIndex - 1);
@@ -377,7 +381,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
377
381
  }
378
382
  (_d = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed) === null || _d === void 0 ? void 0 : _d.call(canvasProps, event);
379
383
  }
380
- : canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [physics ? (_jsx(Physics, { debug: isEditMode, paused: isEditMode, children: content })) : content, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), selectedObject && (_jsx(TransformControls, { object: selectedObject, mode: transformMode, space: "local", onObjectChange: handleTransformChange, translationSnap: positionSnap > 0 ? positionSnap : undefined, rotationSnap: rotationSnap > 0 ? rotationSnap : undefined, scaleSnap: scaleSnap > 0 ? scaleSnap : undefined }, `transform-${transformMode}-${positionSnap}-${rotationSnap}-${scaleSnap}`))] }))] })), showUI && (_jsxs(_Fragment, { children: [_jsxs("div", { style: toolbar.panel, children: [_jsx("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 }))] }))] }) });
384
+ : canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onPointerMissed, children: [physics ? (_jsx(Physics, { debug: isEditMode, paused: isEditMode, children: content })) : content, isEditMode && (_jsxs(_Fragment, { children: [_jsx(MapControls, { ref: controlsRef, enableDamping: false, makeDefault: true }), transformObject && (_jsx(TransformControls, { object: transformObject, mode: transformMode, space: "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", { 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 }))] }))] }) });
381
385
  });
382
386
  PrefabEditor.displayName = "PrefabEditor";
383
387
  export default PrefabEditor;
@@ -18,7 +18,7 @@ export interface PrefabRootProps {
18
18
  selectedId?: string | null;
19
19
  onSelect?: (id: string | null) => void;
20
20
  onClick?: (event: ThreeEvent<PointerEvent>, entity: GameObjectType) => void;
21
- onObjectRefChange?: (id: string, obj: Object3D | null) => void;
21
+ onObjectRefChange?: (id: string, object: Object3D | null) => void;
22
22
  basePath?: string;
23
23
  }
24
24
  export declare const PrefabRoot: import("react").ForwardRefExoticComponent<PrefabRootProps & import("react").RefAttributes<PrefabRootRef>>;
@@ -269,22 +269,33 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, load
269
269
  const isInstanced = (_b = (_a = findComponent(gameObject, "Model")) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.instanced;
270
270
  const physicsKey = `physics_${nodeId}_${isInstanced ? 'instanced' : 'standard'}`;
271
271
  const renderCtx = { loadedModels, editMode, registerRef };
272
- const childNodes = getChildHostComponents(gameObject).length > 0
273
- ? _jsx(CompositionChildren, { childIds: childIds, selectedId: selectedId, ctx: renderCtx, parentMatrix: world })
274
- : _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
272
+ const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
275
273
  const inner = (_jsx("group", Object.assign({}, clickHandlers, { children: renderCompositionNode(gameObject, renderCtx, childNodes) })));
276
274
  const physicsInner = editMode ? _jsx("group", { visible: false, children: inner }) : inner;
277
275
  return (_jsx(EntityRuntimeScope, { nodeId: nodeId, editMode: editMode, isSelected: isSelected, children: editMode ? (_jsxs(_Fragment, { children: [_jsx("group", { ref: groupRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: _jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) }) }), _jsx("group", { ref: helperRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: inner }), hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, { properties: physics.properties, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: physicsInner }, physicsKey)) : null] })) : hasPhysics && (physicsDef === null || physicsDef === void 0 ? void 0 : physicsDef.View) ? (_jsx(physicsDef.View, { properties: physics.properties, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: inner }, physicsKey)) : (_jsx("group", { ref: groupRef, position: transform.position, rotation: transform.rotation, scale: transform.scale, children: inner })) }));
278
276
  }
279
- function getChildHostComponents(gameObject) {
277
+ function isRendererHandledComponent(componentType) {
278
+ return componentType === "Transform"
279
+ || componentType === "Geometry"
280
+ || componentType === "Material"
281
+ || componentType === "Physics"
282
+ || componentType === "Model";
283
+ }
284
+ function getCompositionComponents(gameObject) {
280
285
  var _a;
281
286
  return Object.entries((_a = gameObject.components) !== null && _a !== void 0 ? _a : {}).reduce((result, [key, comp]) => {
282
- if (!(comp === null || comp === void 0 ? void 0 : comp.type))
287
+ var _a;
288
+ if (!(comp === null || comp === void 0 ? void 0 : comp.type) || isRendererHandledComponent(comp.type))
283
289
  return result;
284
290
  const def = getComponentDef(comp.type);
285
- if (!(def === null || def === void 0 ? void 0 : def.View) || def.isWrapper)
291
+ if (!(def === null || def === void 0 ? void 0 : def.View))
286
292
  return result;
287
- result.push({ key, View: def.View, properties: comp.properties });
293
+ result.push({
294
+ key,
295
+ View: def.View,
296
+ properties: comp.properties,
297
+ composition: (_a = def.composition) !== null && _a !== void 0 ? _a : "wrap",
298
+ });
288
299
  return result;
289
300
  }, []);
290
301
  }
@@ -357,41 +368,31 @@ function getNodeTransformProps(node) {
357
368
  scale: (_d = t === null || t === void 0 ? void 0 : t.scale) !== null && _d !== void 0 ? _d : [1, 1, 1],
358
369
  };
359
370
  }
360
- function renderCompositionSubtree(gameObject, ctx, isSelected, childIds, parentMatrix = IDENTITY) {
361
- if (!gameObject || gameObject.disabled)
362
- return null;
363
- const transform = getNodeTransformProps(gameObject);
364
- const world = parentMatrix.clone().multiply(compose(gameObject));
365
- const childNodes = _jsx(CompositionChildren, { childIds: childIds, ctx: ctx, parentMatrix: world });
366
- return (_jsx(EntityRuntimeScope, { nodeId: gameObject.id, editMode: ctx.editMode, isSelected: isSelected, children: _jsx("group", { position: transform.position, rotation: transform.rotation, scale: transform.scale, children: renderCompositionNode(gameObject, ctx, childNodes) }, gameObject.id) }));
367
- }
368
- function CompositionChildren({ childIds, selectedId, ctx, parentMatrix, }) {
369
- return childIds.map(childId => (_jsx(CompositionSubtree, { nodeId: childId, selectedId: selectedId, ctx: ctx, parentMatrix: parentMatrix }, childId)));
370
- }
371
- function CompositionSubtree({ nodeId, selectedId, ctx, parentMatrix, }) {
372
- const gameObject = usePrefabNode(nodeId);
373
- const childIds = usePrefabChildIds(nodeId);
374
- const isSelected = selectedId === nodeId;
375
- if (!gameObject)
376
- return null;
377
- return renderCompositionSubtree(gameObject, ctx, isSelected, childIds, parentMatrix);
378
- }
379
371
  function renderCompositionNode(gameObject, ctx, childNodes) {
380
- const ownContent = renderNodeOwnContent(gameObject);
381
- return wrapWithChildHosts(gameObject, _jsxs(_Fragment, { children: [ownContent, childNodes] }));
372
+ const primaryContent = renderNodePrimaryContent(gameObject, ctx);
373
+ return applyNodeComposition(gameObject, _jsxs(_Fragment, { children: [primaryContent, childNodes] }));
382
374
  }
383
- function renderNodeOwnContent(gameObject) {
375
+ function renderNodePrimaryContent(gameObject, ctx) {
376
+ var _a;
384
377
  const geometry = findComponent(gameObject, "Geometry");
385
378
  const material = findComponent(gameObject, "Material");
379
+ const model = findComponent(gameObject, "Model");
386
380
  const geometryDef = geometry && getComponentDef(geometry.type);
387
381
  const materialDef = material && getComponentDef(material.type);
388
- if (!geometry || !(geometryDef === null || geometryDef === void 0 ? void 0 : geometryDef.View))
389
- return null;
390
- return (_jsxs("mesh", { castShadow: true, receiveShadow: true, children: [_jsx(geometryDef.View, { properties: geometry.properties }), material && (materialDef === null || materialDef === void 0 ? void 0 : materialDef.View) && (_jsx(materialDef.View, { properties: material.properties }, "material"))] }));
382
+ const modelDef = model && getComponentDef(model.type);
383
+ if ((geometry === null || geometry === void 0 ? void 0 : geometry.type) && (geometryDef === null || geometryDef === void 0 ? void 0 : geometryDef.View)) {
384
+ return (_jsxs("mesh", { castShadow: true, receiveShadow: true, children: [_jsx(geometryDef.View, { properties: geometry.properties }), material && (materialDef === null || materialDef === void 0 ? void 0 : materialDef.View) && (_jsx(materialDef.View, { properties: material.properties }, "material"))] }));
385
+ }
386
+ if ((model === null || model === void 0 ? void 0 : model.type) && (modelDef === null || modelDef === void 0 ? void 0 : modelDef.View) && !((_a = model.properties) === null || _a === void 0 ? void 0 : _a.instanced) && isNodeReady(gameObject, ctx.loadedModels)) {
387
+ return _jsx(modelDef.View, { properties: model.properties });
388
+ }
389
+ return null;
391
390
  }
392
- function wrapWithChildHosts(gameObject, subtree) {
393
- const childHosts = getChildHostComponents(gameObject);
394
- return childHosts.reduce((acc, { key, View, properties }) => (_jsx(View, { properties: properties, children: acc }, key)), subtree);
391
+ function applyNodeComposition(gameObject, subtree) {
392
+ const components = getCompositionComponents(gameObject);
393
+ return components.reduce((acc, { key, View, properties, composition }) => composition === "sibling"
394
+ ? (_jsxs(_Fragment, { children: [_jsx(View, { properties: properties }, key), acc] }))
395
+ : (_jsx(View, { properties: properties, children: acc }, key)), subtree);
395
396
  }
396
397
  export default PrefabRoot;
397
398
  function missingStoreState() {
@@ -36,6 +36,7 @@ const CameraComponent = {
36
36
  name: 'Camera',
37
37
  Editor: CameraComponentEditor,
38
38
  View: CameraComponentView,
39
+ composition: 'sibling',
39
40
  defaultProperties: cameraDefaults,
40
41
  };
41
42
  export default CameraComponent;
@@ -8,7 +8,7 @@ export type AssetRef = {
8
8
  export interface ComponentViewProps<P = Record<string, any>> {
9
9
  /** This component's own data from the prefab JSON. */
10
10
  properties: P;
11
- /** Children to render (for wrapper / child-host components). */
11
+ /** Children to render for components that wrap the current subtree. */
12
12
  children?: React.ReactNode;
13
13
  /** Entity local position (passed to wrapper components like Physics). */
14
14
  position?: [number, number, number];
@@ -27,8 +27,11 @@ export interface Component {
27
27
  }>;
28
28
  defaultProperties: any;
29
29
  View?: FC<ComponentViewProps>;
30
- /** When true, this component wraps child entities (e.g. Physics wraps children in RigidBody). */
31
- isWrapper?: boolean;
30
+ /**
31
+ * How this component participates in the implicit node composition pipeline.
32
+ * Defaults to `wrap`; `sibling` renders next to the current subtree.
33
+ */
34
+ composition?: "wrap" | "sibling";
32
35
  /** Declare which asset paths this component references (for asset loading). */
33
36
  getAssetRefs?: (properties: Record<string, any>) => AssetRef[];
34
37
  }
@@ -118,7 +118,6 @@ function DirectionalLightView({ properties, children }) {
118
118
  const shadowCameraLeft = merged.shadowCameraLeft;
119
119
  const shadowCameraRight = merged.shadowCameraRight;
120
120
  const targetOffset = merged.targetOffset;
121
- const lightInstanceKey = castShadow ? 'shadow-on' : 'shadow-off';
122
121
  const directionalLightRef = useRef(null);
123
122
  const targetRef = useRef(null);
124
123
  const shadowCameraRef = useRef(null);
@@ -162,7 +161,7 @@ function DirectionalLightView({ properties, children }) {
162
161
  shadowCamera.updateMatrixWorld();
163
162
  }
164
163
  });
165
- return (_jsxs(_Fragment, { children: [_jsx("directionalLight", { ref: directionalLightRef, color: color, intensity: intensity, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar, "shadow-camera-top": shadowCameraTop, "shadow-camera-bottom": shadowCameraBottom, "shadow-camera-left": shadowCameraLeft, "shadow-camera-right": shadowCameraRight, "shadow-bias": shadowBias, "shadow-normalBias": shadowNormalBias, "shadow-autoUpdate": shadowAutoUpdate }, lightInstanceKey), _jsx("object3D", { ref: targetRef, position: targetOffset }), editMode && isSelected && (_jsxs(_Fragment, { children: [_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.3, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] }), _jsxs("mesh", { position: targetOffset, children: [_jsx("sphereGeometry", { args: [0.2, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true, opacity: 0.5, transparent: true })] }), _jsxs("line", { children: [_jsx("bufferGeometry", { onUpdate: (geo) => {
164
+ return (_jsxs(_Fragment, { children: [_jsx("directionalLight", { ref: directionalLightRef, color: color, intensity: intensity, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar, "shadow-camera-top": shadowCameraTop, "shadow-camera-bottom": shadowCameraBottom, "shadow-camera-left": shadowCameraLeft, "shadow-camera-right": shadowCameraRight, "shadow-bias": shadowBias, "shadow-normalBias": shadowNormalBias, "shadow-autoUpdate": shadowAutoUpdate }), _jsx("object3D", { ref: targetRef, position: targetOffset }), editMode && isSelected && (_jsxs(_Fragment, { children: [_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.3, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] }), _jsxs("mesh", { position: targetOffset, children: [_jsx("sphereGeometry", { args: [0.2, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true, opacity: 0.5, transparent: true })] }), _jsxs("line", { children: [_jsx("bufferGeometry", { onUpdate: (geo) => {
166
165
  const points = [
167
166
  new Vector3(0, 0, 0),
168
167
  new Vector3(targetOffset[0], targetOffset[1], targetOffset[2])
@@ -84,7 +84,6 @@ const GeometryComponent = {
84
84
  name: 'Geometry',
85
85
  Editor: GeometryComponentEditor,
86
86
  View: GeometryComponentView,
87
- isWrapper: true,
88
87
  defaultProperties: {
89
88
  geometryType: 'box',
90
89
  args: getDefaultArgs('box'),
@@ -201,7 +201,6 @@ const MaterialComponent = {
201
201
  name: 'Material',
202
202
  Editor: MaterialComponentEditor,
203
203
  View: MaterialComponentView,
204
- isWrapper: true,
205
204
  defaultProperties: {
206
205
  materialType: 'standard',
207
206
  color: '#ffffff',
@@ -270,7 +270,6 @@ const PhysicsComponent = {
270
270
  name: 'Physics',
271
271
  Editor: PhysicsComponentEditor,
272
272
  View: PhysicsComponentView,
273
- isWrapper: true,
274
273
  defaultProperties: {
275
274
  type: 'dynamic',
276
275
  colliders: 'hull',
@@ -36,7 +36,6 @@ function PointLightView({ properties, children }) {
36
36
  const shadowAutoUpdate = merged.shadowAutoUpdate;
37
37
  const shadowCameraNear = merged.shadowCameraNear;
38
38
  const shadowCameraFar = merged.shadowCameraFar;
39
- const lightInstanceKey = castShadow ? 'shadow-on' : 'shadow-off';
40
39
  const lightRef = useRef(null);
41
40
  useHelper(editMode && isSelected ? lightRef : null, PointLightHelper, 0.5, color);
42
41
  useEffect(() => {
@@ -47,7 +46,7 @@ function PointLightView({ properties, children }) {
47
46
  shadow.needsUpdate = true;
48
47
  shadow.camera.updateProjectionMatrix();
49
48
  }, [castShadow, shadowMapSize, shadowBias, shadowNormalBias, shadowAutoUpdate, shadowCameraNear, shadowCameraFar]);
50
- return (_jsxs(_Fragment, { children: [_jsx("pointLight", { ref: lightRef, color: color, intensity: intensity, distance: distance, decay: decay, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-bias": shadowBias, "shadow-normalBias": shadowNormalBias, "shadow-autoUpdate": shadowAutoUpdate, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar }, lightInstanceKey), editMode && isSelected ? (_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.2, 10, 8] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] })) : null, children] }));
49
+ return (_jsxs(_Fragment, { children: [_jsx("pointLight", { ref: lightRef, color: color, intensity: intensity, distance: distance, decay: decay, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-bias": shadowBias, "shadow-normalBias": shadowNormalBias, "shadow-autoUpdate": shadowAutoUpdate, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar }), editMode && isSelected ? (_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.2, 10, 8] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] })) : null, children] }));
51
50
  }
52
51
  const PointLightComponent = {
53
52
  name: 'PointLight',
@@ -212,6 +212,7 @@ const SoundComponent = {
212
212
  name: 'Sound',
213
213
  Editor: SoundComponentEditor,
214
214
  View: SoundComponentView,
215
+ composition: 'sibling',
215
216
  defaultProperties: {
216
217
  eventName: '',
217
218
  clips: [],
@@ -48,7 +48,6 @@ function SpotLightView({ properties, children }) {
48
48
  const shadowCameraFar = merged.shadowCameraFar;
49
49
  const targetOffset = merged.targetOffset;
50
50
  const textureMap = merged.map ? (_a = getTexture(merged.map)) !== null && _a !== void 0 ? _a : undefined : undefined;
51
- const lightInstanceKey = castShadow ? 'shadow-on' : 'shadow-off';
52
51
  const spotLightRef = useRef(null);
53
52
  const targetRef = useRef(null);
54
53
  useHelper(editMode && isSelected ? spotLightRef : null, SpotLightHelper, color);
@@ -71,7 +70,7 @@ function SpotLightView({ properties, children }) {
71
70
  spotLightRef.current.target.updateMatrixWorld();
72
71
  }
73
72
  });
74
- return (_jsxs(_Fragment, { children: [_jsx("spotLight", { ref: spotLightRef, color: color, intensity: intensity, angle: angle, penumbra: penumbra, distance: distance, decay: decay, map: textureMap, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-bias": shadowBias, "shadow-normalBias": shadowNormalBias, "shadow-autoUpdate": shadowAutoUpdate, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar }, lightInstanceKey), _jsx("object3D", { ref: targetRef, position: targetOffset }), editMode && isSelected && (_jsxs(_Fragment, { children: [_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.2, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] }), _jsxs("mesh", { position: targetOffset, children: [_jsx("sphereGeometry", { args: [0.15, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true, opacity: 0.5, transparent: true })] })] })), children] }));
73
+ return (_jsxs(_Fragment, { children: [_jsx("spotLight", { ref: spotLightRef, color: color, intensity: intensity, angle: angle, penumbra: penumbra, distance: distance, decay: decay, map: textureMap, castShadow: castShadow, "shadow-mapSize-width": shadowMapSize, "shadow-mapSize-height": shadowMapSize, "shadow-bias": shadowBias, "shadow-normalBias": shadowNormalBias, "shadow-autoUpdate": shadowAutoUpdate, "shadow-camera-near": shadowCameraNear, "shadow-camera-far": shadowCameraFar }), _jsx("object3D", { ref: targetRef, position: targetOffset }), editMode && isSelected && (_jsxs(_Fragment, { children: [_jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.2, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true })] }), _jsxs("mesh", { position: targetOffset, children: [_jsx("sphereGeometry", { args: [0.15, 8, 6] }), _jsx("meshBasicMaterial", { color: color, wireframe: true, opacity: 0.5, transparent: true })] })] })), children] }));
75
74
  }
76
75
  const SpotLightComponent = {
77
76
  name: 'SpotLight',
@@ -48,7 +48,6 @@ function TransformComponentEditor({ component, onUpdate }) {
48
48
  const TransformComponent = {
49
49
  name: 'Transform',
50
50
  Editor: TransformComponentEditor,
51
- isWrapper: true,
52
51
  defaultProperties: {
53
52
  position: [0, 0, 0],
54
53
  rotation: [0, 0, 0],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "description": "high performance 3D game engine built in React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -48,7 +48,6 @@
48
48
  "vite": "^7.3.1"
49
49
  },
50
50
  "dependencies": {
51
- "react-error-boundary": "^6.1.0",
52
51
  "zustand": "^5.0.12"
53
52
  }
54
53
  }