react-three-game 0.0.75 → 0.0.77

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.
@@ -4,6 +4,5 @@ export interface GameCanvasProps extends Omit<CanvasProps, 'children'> {
4
4
  loader?: boolean;
5
5
  children: React.ReactNode;
6
6
  glConfig?: WebGPURendererParameters;
7
- canvasRef?: React.RefObject<HTMLCanvasElement | null>;
8
7
  }
9
- export default function GameCanvas({ loader, children, glConfig, canvasRef, 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-runtime").JSX.Element;
@@ -28,18 +28,12 @@ extend({
28
28
  MeshStandardNodeMaterial: MeshStandardNodeMaterial,
29
29
  SpriteNodeMaterial: SpriteNodeMaterial,
30
30
  });
31
- function applyCanvasInteractionGuards(canvas) {
32
- canvas.style.touchAction = 'none';
33
- canvas.style.userSelect = 'none';
34
- canvas.style.setProperty('-webkit-touch-callout', 'none');
35
- canvas.style.setProperty('-webkit-user-drag', 'none');
36
- canvas.style.setProperty('-webkit-tap-highlight-color', 'transparent');
37
- }
38
31
  export default function GameCanvas(_a) {
39
- var { loader = false, children, glConfig, canvasRef, onCreated, style } = _a, props = __rest(_a, ["loader", "children", "glConfig", "canvasRef", "onCreated", "style"]);
32
+ var { loader = false, children, glConfig, onCreated, style } = _a, props = __rest(_a, ["loader", "children", "glConfig", "onCreated", "style"]);
40
33
  const [frameloop, setFrameloop] = useState("never");
41
- return _jsx(_Fragment, { children: _jsxs(Canvas, Object.assign({ style: Object.assign({ touchAction: 'none', userSelect: 'none' }, style), shadows: { type: PCFShadowMap }, dpr: [1, 1.5], frameloop: frameloop, gl: (_a) => __awaiter(this, [_a], void 0, function* ({ canvas }) {
42
- const renderer = new WebGPURenderer(Object.assign({ canvas: canvas,
34
+ return _jsx(_Fragment, { children: _jsxs(Canvas, Object.assign({ style: Object.assign({ touchAction: 'none', userSelect: 'none', WebkitUserSelect: 'none', WebkitTouchCallout: 'none', WebkitTapHighlightColor: 'transparent' }, style), shadows: { type: PCFShadowMap }, dpr: [1, 1.5], frameloop: frameloop, gl: (_a) => __awaiter(this, [_a], void 0, function* ({ canvas }) {
35
+ const canvasElement = canvas;
36
+ const renderer = new WebGPURenderer(Object.assign({ canvas: canvasElement,
43
37
  // @ts-expect-error futuristic
44
38
  shadowMap: true, antialias: true }, glConfig));
45
39
  yield renderer.init().then(() => {
@@ -47,10 +41,6 @@ export default function GameCanvas(_a) {
47
41
  });
48
42
  return renderer;
49
43
  }), onCreated: (state) => {
50
- applyCanvasInteractionGuards(state.gl.domElement);
51
- if (canvasRef) {
52
- canvasRef.current = state.gl.domElement;
53
- }
54
44
  onCreated === null || onCreated === void 0 ? void 0 : onCreated(state);
55
45
  } }, props, { children: [_jsx(Suspense, { children: children }), loader ? _jsx(Loader, {}) : null] })) });
56
46
  }
@@ -46,7 +46,7 @@ export interface PrefabEditorProps {
46
46
  onChange?: (prefab: Prefab) => void;
47
47
  showUI?: boolean;
48
48
  enableWindowDrop?: boolean;
49
- canvasProps?: Omit<React.ComponentProps<typeof GameCanvas>, 'children' | 'canvasRef'>;
49
+ canvasProps?: Omit<React.ComponentProps<typeof GameCanvas>, 'children'>;
50
50
  uiPlugins?: React.ReactNode[] | React.ReactNode;
51
51
  children?: React.ReactNode;
52
52
  }
@@ -165,6 +165,12 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
165
165
  }
166
166
  setSelectedObject(getObject(selectedId));
167
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]);
168
174
  const addNode = useCallback((node, options) => {
169
175
  var _a;
170
176
  const { addChild, rootId } = prefabStore.getState();
@@ -342,7 +348,12 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
342
348
  addModel,
343
349
  addTexture
344
350
  }), [addModel, addTexture, clearSelection, getPrefab, handleExportGLB, handleExportGLBData, handleScreenshot, loadPrefab, scene]);
345
- const content = (_jsxs(_Fragment, { children: [isEditMode ? _jsx("gridHelper", { args: [10, 10], position: [0, -1, 0] }) : null, _jsx(PrefabRoot, { ref: prefabRootRef, store: prefabStore, editMode: isEditMode, selectedId: selectedId, onSelect: setSelection, basePath: basePath }), children] }));
351
+ const content = (_jsxs(_Fragment, { children: [isEditMode ? _jsx("gridHelper", { args: [10, 10], position: [0, -1, 0] }) : null, _jsx(PrefabRoot, { ref: prefabRootRef, store: prefabStore, editMode: isEditMode, selectedId: selectedId, onSelect: setSelection, onObjectRefChange: handleObjectRefChange, basePath: basePath }), children] }));
352
+ const handleCanvasCreated = useCallback((state) => {
353
+ var _a;
354
+ canvasRef.current = state.gl.domElement;
355
+ (_a = canvasProps === null || canvasProps === void 0 ? void 0 : canvasProps.onCreated) === null || _a === void 0 ? void 0 : _a.call(canvasProps, state);
356
+ }, [canvasProps]);
346
357
  return _jsx(PrefabStoreProvider, { store: prefabStore, children: _jsxs(EditorContext.Provider, { value: {
347
358
  mode,
348
359
  setMode: updateMode,
@@ -357,7 +368,7 @@ const PrefabEditor = forwardRef(({ basePath, initialPrefab, physics = true, mode
357
368
  onFocusNode: isEditMode ? handleFocusNode : undefined,
358
369
  onScreenshot: handleScreenshot,
359
370
  onExportGLB: handleExportGLB
360
- }, children: [_jsxs(GameCanvas, Object.assign({ camera: { position: [0, 5, 15] }, canvasRef: canvasRef }, canvasProps, { onPointerMissed: isEditMode
371
+ }, children: [_jsxs(GameCanvas, Object.assign({ camera: { position: [0, 5, 15] } }, canvasProps, { onCreated: handleCanvasCreated, onPointerMissed: isEditMode
361
372
  ? (event) => {
362
373
  var _a, _b, _c, _d;
363
374
  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;
@@ -18,6 +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
22
  basePath?: string;
22
23
  }
23
24
  export declare const PrefabRoot: import("react").ForwardRefExoticComponent<PrefabRootProps & import("react").RefAttributes<PrefabRootRef>>;
@@ -45,7 +45,7 @@ function isNodeReady(node, loadedModels) {
45
45
  return true;
46
46
  return Boolean(loadedModels[model.properties.filename]);
47
47
  }
48
- export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick, basePath = "" }, ref) => {
48
+ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSelect, onClick, onObjectRefChange, basePath = "" }, ref) => {
49
49
  var _a;
50
50
  const [models, setModels] = useState({});
51
51
  const [textures, setTextures] = useState({});
@@ -86,7 +86,8 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
86
86
  }), [getObject]);
87
87
  const registerRef = useCallback((id, obj) => {
88
88
  objectRefs.current[id] = obj;
89
- }, []);
89
+ onObjectRefChange === null || onObjectRefChange === void 0 ? void 0 : onObjectRefChange(id, obj);
90
+ }, [onObjectRefChange]);
90
91
  const registerRigidBodyRef = useCallback((id, rb) => {
91
92
  rigidBodyRefs.current.set(id, rb);
92
93
  }, []);
@@ -94,15 +95,6 @@ export const PrefabRoot = forwardRef(({ editMode, data, store, selectedId, onSel
94
95
  var _a;
95
96
  return (_a = rigidBodyRefs.current.get(id)) !== null && _a !== void 0 ? _a : null;
96
97
  }, []);
97
- useEffect(() => {
98
- const originalError = console.error;
99
- console.error = (...args) => {
100
- if (typeof args[0] === 'string' && args[0].includes('TransformControls') && args[0].includes('scene graph'))
101
- return;
102
- originalError.apply(console, args);
103
- };
104
- return () => { console.error = originalError; };
105
- }, []);
106
98
  useEffect(() => {
107
99
  if (usesOwnedStore && data) {
108
100
  resolvedStore.getState().replacePrefab(data);
@@ -281,7 +273,8 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, registerRef, load
281
273
  ? _jsx(CompositionChildren, { childIds: childIds, selectedId: selectedId, ctx: renderCtx, parentMatrix: world })
282
274
  : _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode });
283
275
  const inner = (_jsx("group", Object.assign({}, clickHandlers, { children: renderCompositionNode(gameObject, renderCtx, childNodes) })));
284
- 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: inner }, 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 })) }));
276
+ const physicsInner = editMode ? _jsx("group", { visible: false, children: inner }) : inner;
277
+ 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 })) }));
285
278
  }
286
279
  function getChildHostComponents(gameObject) {
287
280
  var _a;
@@ -118,6 +118,7 @@ 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';
121
122
  const directionalLightRef = useRef(null);
122
123
  const targetRef = useRef(null);
123
124
  const shadowCameraRef = useRef(null);
@@ -129,9 +130,9 @@ function DirectionalLightView({ properties, children }) {
129
130
  directionalLightRef.current.target = targetRef.current;
130
131
  const nextShadowCamera = directionalLightRef.current.shadow.camera;
131
132
  shadowCameraRef.current = nextShadowCamera;
132
- setShadowCamera(nextShadowCamera);
133
+ setShadowCamera(castShadow ? nextShadowCamera : null);
133
134
  }
134
- }, []);
135
+ }, [castShadow]);
135
136
  useEffect(() => {
136
137
  var _a;
137
138
  const shadow = (_a = directionalLightRef.current) === null || _a === void 0 ? void 0 : _a.shadow;
@@ -161,7 +162,7 @@ function DirectionalLightView({ properties, children }) {
161
162
  shadowCamera.updateMatrixWorld();
162
163
  }
163
164
  });
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) => {
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) => {
165
166
  const points = [
166
167
  new Vector3(0, 0, 0),
167
168
  new Vector3(targetOffset[0], targetOffset[1], targetOffset[2])
@@ -36,6 +36,7 @@ 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';
39
40
  const lightRef = useRef(null);
40
41
  useHelper(editMode && isSelected ? lightRef : null, PointLightHelper, 0.5, color);
41
42
  useEffect(() => {
@@ -46,7 +47,7 @@ function PointLightView({ properties, children }) {
46
47
  shadow.needsUpdate = true;
47
48
  shadow.camera.updateProjectionMatrix();
48
49
  }, [castShadow, shadowMapSize, shadowBias, shadowNormalBias, shadowAutoUpdate, shadowCameraNear, shadowCameraFar]);
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] }));
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] }));
50
51
  }
51
52
  const PointLightComponent = {
52
53
  name: 'PointLight',
@@ -48,6 +48,7 @@ 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';
51
52
  const spotLightRef = useRef(null);
52
53
  const targetRef = useRef(null);
53
54
  useHelper(editMode && isSelected ? spotLightRef : null, SpotLightHelper, color);
@@ -55,7 +56,7 @@ function SpotLightView({ properties, children }) {
55
56
  if (spotLightRef.current && targetRef.current) {
56
57
  spotLightRef.current.target = targetRef.current;
57
58
  }
58
- }, []);
59
+ }, [castShadow]);
59
60
  useEffect(() => {
60
61
  var _a;
61
62
  const shadow = (_a = spotLightRef.current) === null || _a === void 0 ? void 0 : _a.shadow;
@@ -70,7 +71,7 @@ function SpotLightView({ properties, children }) {
70
71
  spotLightRef.current.target.updateMatrixWorld();
71
72
  }
72
73
  });
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] }));
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] }));
74
75
  }
75
76
  const SpotLightComponent = {
76
77
  name: 'SpotLight',