react-three-game 0.0.96 → 0.0.98

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.
@@ -33,32 +33,11 @@ export function normalizeRepeatAxes(value) {
33
33
  }, []);
34
34
  return normalized.length > 0 ? normalized : DEFAULT_REPEAT_AXES;
35
35
  }
36
- function toVector3Tuple(value, fallback) {
37
- if (!Array.isArray(value) || value.length !== 3)
38
- return fallback;
39
- return value.map((entry, index) => {
40
- const next = typeof entry === 'number' ? entry : Number(entry);
41
- return Number.isFinite(next) ? next : fallback[index];
42
- });
43
- }
44
36
  export function getRepeatAxesFromModelProperties(properties) {
45
- var _a;
46
37
  if (Array.isArray(properties.repeatAxes)) {
47
38
  return normalizeRepeatAxes(properties.repeatAxes);
48
39
  }
49
- const repeatCount = toVector3Tuple(properties.repeatCount, [1, 1, 1]).map(value => Math.max(1, Math.floor(value)));
50
- const repeatOffset = toVector3Tuple(properties.repeatOffset, [1, 1, 1]);
51
- const legacyAxes = [];
52
- if ((_a = properties.repeatX) !== null && _a !== void 0 ? _a : true) {
53
- legacyAxes.push({ axis: 'x', count: repeatCount[0], offset: repeatOffset[0] });
54
- }
55
- if (properties.repeatY) {
56
- legacyAxes.push({ axis: 'y', count: repeatCount[1], offset: repeatOffset[1] });
57
- }
58
- if (properties.repeatZ) {
59
- legacyAxes.push({ axis: 'z', count: repeatCount[2], offset: repeatOffset[2] });
60
- }
61
- return legacyAxes.length > 0 ? legacyAxes : DEFAULT_REPEAT_AXES;
40
+ return DEFAULT_REPEAT_AXES;
62
41
  }
63
42
  // Helper functions for comparison
64
43
  function arrayEquals(a, b) {
@@ -34,7 +34,10 @@ function isObjectAttachedToRoot(root, object) {
34
34
  function SelectionHelper({ object }) {
35
35
  const objectRef = useRef(null);
36
36
  objectRef.current = object;
37
- useHelper(object ? objectRef : null, BoxHelper, "cyan");
37
+ const helperTarget = objectRef.current
38
+ ? { current: objectRef.current }
39
+ : null;
40
+ useHelper(helperTarget, BoxHelper, "cyan");
38
41
  return null;
39
42
  }
40
43
  export const EditorContext = createContext(null);
@@ -361,9 +361,6 @@ function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef,
361
361
  const analyzedComponents = useMemo(() => gameObject ? analyzeNodeComponents(gameObject) : EMPTY_NODE_COMPONENTS, [gameObject]);
362
362
  const localTransform = getNodeTransformProps(gameObject);
363
363
  const isLocked = Boolean(gameObject === null || gameObject === void 0 ? void 0 : gameObject.locked);
364
- const nodeVisible = isVisible && !(gameObject === null || gameObject === void 0 ? void 0 : gameObject.hidden);
365
- const metadataProps = gameObject ? getNodeMetadataProps(gameObject) : { name: '', userData: {} };
366
- const groupProps = Object.assign(Object.assign({}, metadataProps), { visible: nodeVisible, position: localTransform.position, rotation: localTransform.rotation, scale: localTransform.scale });
367
364
  const modelUrl = (_b = (_a = analyzedComponents.model) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.filename;
368
365
  const instances = useMemo(() => buildRepeatedInstances(gameObject, parentMatrix, modelUrl), [gameObject, modelUrl, parentMatrix]);
369
366
  const groupRef = useRef(null);
@@ -381,6 +378,8 @@ function InstancedNode({ nodeId, parentMatrix = IDENTITY, editMode, registerRef,
381
378
  });
382
379
  if (!gameObject)
383
380
  return null;
381
+ const nodeVisible = isVisible && !gameObject.hidden;
382
+ const groupProps = Object.assign(Object.assign({}, getNodeMetadataProps(gameObject)), { visible: nodeVisible, position: localTransform.position, rotation: localTransform.rotation, scale: localTransform.scale });
384
383
  const renderedInstances = instances.map(instance => (_jsx(GameInstance, { id: instance.id, sourceId: gameObject.id, modelUrl: instance.modelUrl, position: instance.position, rotation: instance.rotation, scale: instance.scale, visible: nodeVisible, locked: isLocked, onClick: onClick }, instance.id)));
385
384
  if (editMode) {
386
385
  return (_jsxs(_Fragment, { children: [_jsx("group", Object.assign({ ref: handleGroupRef }, groupProps, editClickHandlers, { children: _jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) }) })), renderedInstances] }));
@@ -393,8 +392,6 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, onEditNodeClick,
393
392
  const analyzedComponents = useMemo(() => gameObject ? analyzeNodeComponents(gameObject) : EMPTY_NODE_COMPONENTS, [gameObject]);
394
393
  const isSelected = selectedId === nodeId;
395
394
  const isLocked = Boolean(gameObject === null || gameObject === void 0 ? void 0 : gameObject.locked);
396
- const nodeVisible = isVisible && !(gameObject === null || gameObject === void 0 ? void 0 : gameObject.hidden);
397
- const metadataProps = gameObject ? getNodeMetadataProps(gameObject) : { name: '', userData: {} };
398
395
  const groupRef = useRef(null);
399
396
  const handleGroupRef = useCallback((object) => {
400
397
  groupRef.current = object;
@@ -415,6 +412,10 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, onEditNodeClick,
415
412
  }
416
413
  : undefined;
417
414
  const world = parentMatrix.clone().multiply(compose(gameObject));
415
+ if (!gameObject)
416
+ return null;
417
+ const nodeVisible = isVisible && !gameObject.hidden;
418
+ const metadataProps = getNodeMetadataProps(gameObject);
418
419
  const transform = getNodeTransformProps(gameObject);
419
420
  const transformProps = {
420
421
  position: transform.position,
@@ -423,8 +424,6 @@ function StandardNode({ nodeId, selectedId, onSelect, onClick, onEditNodeClick,
423
424
  };
424
425
  const groupProps = Object.assign(Object.assign({}, metadataProps), transformProps);
425
426
  const childNodes = _jsx(ChildNodes, { childIds: childIds, parentMatrix: world, selectedId: selectedId, onSelect: onSelect, onClick: onClick, onEditNodeClick: onEditNodeClick, registerRef: registerRef, loadedModels: loadedModels, editMode: editMode, isVisible: nodeVisible });
426
- if (!gameObject)
427
- return null;
428
427
  const inner = renderNodeContent(analyzedComponents, loadedModels, primaryClickHandlers, childNodes);
429
428
  const editAnchor = editMode ? (_jsx("mesh", { visible: false, children: _jsx("boxGeometry", { args: [0.01, 0.01, 0.01] }) })) : null;
430
429
  const standardNode = (_jsxs("group", Object.assign({ ref: handleGroupRef }, groupProps, { visible: nodeVisible }, (editMode ? editClickHandlers : undefined), { children: [editAnchor, inner] })));
@@ -1,3 +1,3 @@
1
- import { Component } from './ComponentRegistry';
1
+ import type { Component } from './ComponentRegistry';
2
2
  declare const CameraComponent: Component;
3
3
  export default CameraComponent;
@@ -39,10 +39,13 @@ function CameraComponentView({ properties, children }) {
39
39
  const halfWidth = halfHeight * aspect;
40
40
  const perspectiveCameraRef = useRef(null);
41
41
  const orthographicCameraRef = useRef(null);
42
- const activeCameraRef = projection === 'orthographic'
43
- ? orthographicCameraRef
44
- : perspectiveCameraRef;
45
- useHelper(editMode && isSelected ? activeCameraRef : null, CameraHelper);
42
+ const activeCamera = projection === 'orthographic'
43
+ ? orthographicCameraRef.current
44
+ : perspectiveCameraRef.current;
45
+ const helperTarget = editMode && isSelected && activeCamera
46
+ ? { current: activeCamera }
47
+ : null;
48
+ useHelper(helperTarget, CameraHelper);
46
49
  useFrame(() => {
47
50
  if (!editMode || !isSelected)
48
51
  return;
@@ -1,11 +1,13 @@
1
- import { FC } from "react";
2
- import { ComponentData, GameObject } from "../types";
1
+ import type { FC } from "react";
2
+ import type { ComponentData, GameObject } from "../types";
3
3
  export type AssetRef = {
4
4
  type: "model" | "texture" | "sound";
5
5
  path: string;
6
6
  };
7
+ export declare function assetRef(type: AssetRef["type"], path: unknown): AssetRef | null;
8
+ export declare function assetRefs(...refs: Array<AssetRef | null | undefined>): AssetRef[];
7
9
  /** Props every component View receives from the renderer. */
8
- export interface ComponentViewProps<P = Record<string, any>> {
10
+ export interface ComponentViewProps<P = Record<string, unknown>> {
9
11
  /** This component's own data from the prefab JSON. */
10
12
  properties: P;
11
13
  /** Children to render for components that wrap the current subtree. */
@@ -22,15 +24,15 @@ export interface Component {
22
24
  Editor: FC<{
23
25
  node?: GameObject;
24
26
  component: ComponentData;
25
- onUpdate: (newComp: any) => void;
27
+ onUpdate: (newComp: Record<string, unknown>) => void;
26
28
  basePath?: string;
27
29
  }>;
28
- defaultProperties: any;
30
+ defaultProperties: Record<string, unknown>;
29
31
  View?: FC<ComponentViewProps>;
30
32
  /** Declare which asset paths this component references (for asset loading). */
31
- getAssetRefs?: (properties: Record<string, any>) => AssetRef[];
33
+ getAssetRefs?: (properties: Record<string, unknown>) => AssetRef[];
32
34
  }
33
35
  export declare function registerComponent(component: Component): void;
34
36
  export declare function getComponentDef(name: string): Component | undefined;
35
37
  export declare function getAllComponentDefs(): Record<string, Component>;
36
- export declare function getComponentAssetRefs(componentType: string, properties: Record<string, any>): AssetRef[];
38
+ export declare function getComponentAssetRefs(componentType: string, properties: Record<string, unknown>): AssetRef[];
@@ -1,3 +1,9 @@
1
+ export function assetRef(type, path) {
2
+ return typeof path === "string" ? { type, path } : null;
3
+ }
4
+ export function assetRefs(...refs) {
5
+ return refs.filter((ref) => ref != null);
6
+ }
1
7
  const REGISTRY = {};
2
8
  export function registerComponent(component) {
3
9
  REGISTRY[component.name] = component;
@@ -1,3 +1,3 @@
1
- import { Component } from "./ComponentRegistry";
1
+ import type { Component } from "./ComponentRegistry";
2
2
  declare const DirectionalLightComponent: Component;
3
3
  export default DirectionalLightComponent;
@@ -122,7 +122,10 @@ function DirectionalLightView({ properties, children }) {
122
122
  const targetRef = useRef(null);
123
123
  const shadowCameraRef = useRef(null);
124
124
  const [shadowCamera, setShadowCamera] = useState(null);
125
- useHelper(editMode && isSelected && castShadow ? shadowCameraRef : null, CameraHelper);
125
+ const helperTarget = editMode && isSelected && castShadow && shadowCameraRef.current
126
+ ? { current: shadowCameraRef.current }
127
+ : null;
128
+ useHelper(helperTarget, CameraHelper);
126
129
  // Use a local target object so node transforms rotate the light direction naturally.
127
130
  useEffect(() => {
128
131
  if (directionalLightRef.current && targetRef.current) {
@@ -131,7 +134,7 @@ function DirectionalLightView({ properties, children }) {
131
134
  shadowCameraRef.current = nextShadowCamera;
132
135
  setShadowCamera(castShadow ? nextShadowCamera : null);
133
136
  }
134
- }, [castShadow]);
137
+ });
135
138
  useEffect(() => {
136
139
  var _a;
137
140
  const shadow = (_a = directionalLightRef.current) === null || _a === void 0 ? void 0 : _a.shadow;
@@ -139,19 +142,7 @@ function DirectionalLightView({ properties, children }) {
139
142
  return;
140
143
  shadow.needsUpdate = true;
141
144
  shadow.camera.updateProjectionMatrix();
142
- }, [
143
- castShadow,
144
- shadowMapSize,
145
- shadowBias,
146
- shadowNormalBias,
147
- shadowAutoUpdate,
148
- shadowCameraNear,
149
- shadowCameraFar,
150
- shadowCameraTop,
151
- shadowCameraBottom,
152
- shadowCameraLeft,
153
- shadowCameraRight,
154
- ]);
145
+ });
155
146
  useFrame(() => {
156
147
  if (!directionalLightRef.current || !targetRef.current)
157
148
  return;
@@ -13,11 +13,12 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
13
13
  import { createContext, useContext, useMemo, useRef } from 'react';
14
14
  import { extend } from '@react-three/fiber';
15
15
  import { useFrame } from '@react-three/fiber';
16
+ import { assetRef, assetRefs } from './ComponentRegistry';
16
17
  import { FieldRenderer, Label, NumberInput } from './Input';
17
18
  import { useAssetRuntime } from '../assetRuntime';
18
19
  import { MeshBasicNodeMaterial, MeshStandardNodeMaterial, SpriteNodeMaterial } from 'three/webgpu';
19
20
  import { TexturePicker } from '../../assetviewer/page';
20
- import { RepeatWrapping, ClampToEdgeWrapping, SRGBColorSpace, LinearSRGBColorSpace, NearestFilter, LinearFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, LinearMipmapNearestFilter, LinearMipmapLinearFilter, FrontSide, BackSide, DoubleSide, } from 'three';
21
+ import { RepeatWrapping, ClampToEdgeWrapping, NoColorSpace, SRGBColorSpace, NearestFilter, LinearFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, LinearMipmapNearestFilter, LinearMipmapLinearFilter, FrontSide, BackSide, DoubleSide, } from 'three';
21
22
  function Vector2Editor({ label, value, onChange, min, max, step, }) {
22
23
  var _a, _b;
23
24
  return (_jsxs("div", { style: { display: 'flex', gap: 2 }, children: [_jsxs("div", { style: { flex: 1 }, children: [_jsxs(Label, { children: [label, " X"] }), _jsx(NumberInput, { value: (_a = value === null || value === void 0 ? void 0 : value[0]) !== null && _a !== void 0 ? _a : 0, onChange: x => { var _a; return onChange([x, (_a = value === null || value === void 0 ? void 0 : value[1]) !== null && _a !== void 0 ? _a : 0]); }, min: min, max: max, step: step, style: { width: '100%', minWidth: 0, boxSizing: 'border-box' } })] }), _jsxs("div", { style: { flex: 1 }, children: [_jsxs(Label, { children: [label, " Y"] }), _jsx(NumberInput, { value: (_b = value === null || value === void 0 ? void 0 : value[1]) !== null && _b !== void 0 ? _b : 0, onChange: y => { var _a; return onChange([(_a = value === null || value === void 0 ? void 0 : value[0]) !== null && _a !== void 0 ? _a : 0, y]); }, min: min, max: max, step: step, style: { width: '100%', minWidth: 0, boxSizing: 'border-box' } })] })] }));
@@ -188,7 +189,7 @@ function MaterialComponentEditor({ component, onUpdate, basePath = "", }) {
188
189
  }
189
190
  // View for Material component
190
191
  function MaterialComponentView({ properties: rawProps }) {
191
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
192
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
192
193
  const { getTexture } = useAssetRuntime();
193
194
  const properties = rawProps;
194
195
  const materialSource = properties !== null && properties !== void 0 ? properties : {};
@@ -234,7 +235,7 @@ function MaterialComponentView({ properties: rawProps }) {
234
235
  repeat,
235
236
  repeatCount,
236
237
  offset,
237
- colorSpace: LinearSRGBColorSpace,
238
+ colorSpace: NoColorSpace,
238
239
  generateMipmaps,
239
240
  minFilter: resolvedMinFilter,
240
241
  magFilter: resolvedMagFilter,
@@ -255,16 +256,22 @@ function MaterialComponentView({ properties: rawProps }) {
255
256
  if (!properties) {
256
257
  return _jsx("meshStandardNodeMaterial", { attach: "material", color: "red", wireframe: true });
257
258
  }
258
- const materialKey = `${materialType}:${textureName !== null && textureName !== void 0 ? textureName : 'none'}:${normalMapTextureName !== null && normalMapTextureName !== void 0 ? normalMapTextureName : 'none'}`;
259
+ const materialKey = [
260
+ materialType,
261
+ textureName !== null && textureName !== void 0 ? textureName : 'none',
262
+ (_l = texture === null || texture === void 0 ? void 0 : texture.uuid) !== null && _l !== void 0 ? _l : 'texture-pending',
263
+ normalMapTextureName !== null && normalMapTextureName !== void 0 ? normalMapTextureName : 'none',
264
+ (_m = normalMapTexture === null || normalMapTexture === void 0 ? void 0 : normalMapTexture.uuid) !== null && _m !== void 0 ? _m : 'normal-pending',
265
+ ].join(':');
259
266
  const sharedProps = Object.assign(Object.assign({ map: finalTexture, side: resolvedSide }, materialProps), overrides);
260
267
  if (materialType === 'basic') {
261
268
  return _jsx("meshBasicNodeMaterial", Object.assign({ attach: "material" }, sharedProps), materialKey);
262
269
  }
263
270
  if (materialType === 'sprite') {
264
271
  const spriteTransparent = materialSource.transparent !== false;
265
- return (_jsx("spriteNodeMaterial", Object.assign({ attach: "material", map: finalTexture, color: (_l = materialSource.color) !== null && _l !== void 0 ? _l : '#ffffff', opacity: (_m = materialSource.opacity) !== null && _m !== void 0 ? _m : 1, transparent: spriteTransparent, alphaTest: (_o = materialSource.alphaTest) !== null && _o !== void 0 ? _o : 0, depthTest: (_p = materialSource.depthTest) !== null && _p !== void 0 ? _p : false, depthWrite: (_q = materialSource.depthWrite) !== null && _q !== void 0 ? _q : false, toneMapped: (_r = materialSource.toneMapped) !== null && _r !== void 0 ? _r : true }, overrides, { rotation: rotation !== null && rotation !== void 0 ? rotation : 0, sizeAttenuation: sizeAttenuation !== null && sizeAttenuation !== void 0 ? sizeAttenuation : true }), materialKey));
272
+ return (_jsx("spriteNodeMaterial", Object.assign({ attach: "material", map: finalTexture, color: (_o = materialSource.color) !== null && _o !== void 0 ? _o : '#ffffff', opacity: (_p = materialSource.opacity) !== null && _p !== void 0 ? _p : 1, transparent: spriteTransparent, alphaTest: (_q = materialSource.alphaTest) !== null && _q !== void 0 ? _q : 0, depthTest: (_r = materialSource.depthTest) !== null && _r !== void 0 ? _r : false, depthWrite: (_s = materialSource.depthWrite) !== null && _s !== void 0 ? _s : false, toneMapped: (_t = materialSource.toneMapped) !== null && _t !== void 0 ? _t : true }, overrides, { rotation: rotation !== null && rotation !== void 0 ? rotation : 0, sizeAttenuation: sizeAttenuation !== null && sizeAttenuation !== void 0 ? sizeAttenuation : true }), materialKey));
266
273
  }
267
- return (_jsx("meshStandardNodeMaterial", Object.assign({ attach: "material" }, sharedProps, { normalMap: finalNormalMap, normalScale: finalNormalMap ? [(_s = normalScaleProp === null || normalScaleProp === void 0 ? void 0 : normalScaleProp[0]) !== null && _s !== void 0 ? _s : 1, (_t = normalScaleProp === null || normalScaleProp === void 0 ? void 0 : normalScaleProp[1]) !== null && _t !== void 0 ? _t : 1] : undefined }), materialKey));
274
+ return (_jsx("meshStandardNodeMaterial", Object.assign({ attach: "material" }, sharedProps, { normalMap: finalNormalMap, normalScale: finalNormalMap ? [(_u = normalScaleProp === null || normalScaleProp === void 0 ? void 0 : normalScaleProp[0]) !== null && _u !== void 0 ? _u : 1, (_v = normalScaleProp === null || normalScaleProp === void 0 ? void 0 : normalScaleProp[1]) !== null && _v !== void 0 ? _v : 1] : undefined }), materialKey));
268
275
  }
269
276
  const MaterialComponent = {
270
277
  name: 'Material',
@@ -284,13 +291,6 @@ const MaterialComponent = {
284
291
  metalness: 0,
285
292
  roughness: 1
286
293
  },
287
- getAssetRefs: (properties) => {
288
- const refs = [];
289
- if (properties.texture)
290
- refs.push({ type: 'texture', path: properties.texture });
291
- if (properties.normalMapTexture)
292
- refs.push({ type: 'texture', path: properties.normalMapTexture });
293
- return refs;
294
- },
294
+ getAssetRefs: (properties) => assetRefs(assetRef('texture', properties.texture), assetRef('texture', properties.normalMapTexture)),
295
295
  };
296
296
  export default MaterialComponent;
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { ModelPicker } from '../../assetviewer/page';
3
3
  import { useMemo } from 'react';
4
4
  import { Mesh } from 'three';
5
+ import { assetRef, assetRefs } from './ComponentRegistry';
5
6
  import { BooleanField, FieldGroup, Label, ListEditor, NumberInput, SelectInput, StringField } from './Input';
6
7
  import { useAssetRuntime } from '../assetRuntime';
7
8
  import { useEditorContext } from '../PrefabEditor';
@@ -70,10 +71,6 @@ const ModelComponent = {
70
71
  Editor: ModelComponentEditor,
71
72
  View: ModelComponentView,
72
73
  defaultProperties: {},
73
- getAssetRefs: (properties) => {
74
- if (properties.filename)
75
- return [{ type: 'model', path: properties.filename }];
76
- return [];
77
- },
74
+ getAssetRefs: (properties) => assetRefs(assetRef('model', properties.filename)),
78
75
  };
79
76
  export default ModelComponent;
@@ -1,3 +1,3 @@
1
- import { Component } from './ComponentRegistry';
1
+ import type { Component } from './ComponentRegistry';
2
2
  declare const PointLightComponent: Component;
3
3
  export default PointLightComponent;
@@ -37,7 +37,10 @@ function PointLightView({ properties, children }) {
37
37
  const shadowCameraNear = merged.shadowCameraNear;
38
38
  const shadowCameraFar = merged.shadowCameraFar;
39
39
  const lightRef = useRef(null);
40
- useHelper(editMode && isSelected ? lightRef : null, PointLightHelper, 0.5, color);
40
+ const helperTarget = editMode && isSelected && lightRef.current
41
+ ? { current: lightRef.current }
42
+ : null;
43
+ useHelper(helperTarget, PointLightHelper, 0.5, color);
41
44
  useEffect(() => {
42
45
  var _a;
43
46
  const shadow = (_a = lightRef.current) === null || _a === void 0 ? void 0 : _a.shadow;
@@ -45,7 +48,7 @@ function PointLightView({ properties, children }) {
45
48
  return;
46
49
  shadow.needsUpdate = true;
47
50
  shadow.camera.updateProjectionMatrix();
48
- }, [castShadow, shadowMapSize, shadowBias, shadowNormalBias, shadowAutoUpdate, shadowCameraNear, shadowCameraFar]);
51
+ });
49
52
  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
53
  }
51
54
  const PointLightComponent = {
@@ -1,3 +1,3 @@
1
- import { Component } from "./ComponentRegistry";
1
+ import type { Component } from "./ComponentRegistry";
2
2
  declare const SpotLightComponent: Component;
3
3
  export default SpotLightComponent;
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { assetRef, assetRefs } from "./ComponentRegistry";
2
3
  import { useHelper } from "@react-three/drei";
3
4
  import { useRef, useEffect } from "react";
4
5
  import { BooleanField, ColorField, Label, NumberField, Vector3Input } from "./Input";
@@ -50,12 +51,15 @@ function SpotLightView({ properties, children }) {
50
51
  const textureMap = merged.map ? (_a = getTexture(merged.map)) !== null && _a !== void 0 ? _a : undefined : undefined;
51
52
  const spotLightRef = useRef(null);
52
53
  const targetRef = useRef(null);
53
- useHelper(editMode && isSelected ? spotLightRef : null, SpotLightHelper, color);
54
+ const helperTarget = editMode && isSelected && spotLightRef.current
55
+ ? { current: spotLightRef.current }
56
+ : null;
57
+ useHelper(helperTarget, SpotLightHelper, color);
54
58
  useEffect(() => {
55
59
  if (spotLightRef.current && targetRef.current) {
56
60
  spotLightRef.current.target = targetRef.current;
57
61
  }
58
- }, [castShadow]);
62
+ });
59
63
  useEffect(() => {
60
64
  var _a;
61
65
  const shadow = (_a = spotLightRef.current) === null || _a === void 0 ? void 0 : _a.shadow;
@@ -63,7 +67,7 @@ function SpotLightView({ properties, children }) {
63
67
  return;
64
68
  shadow.needsUpdate = true;
65
69
  shadow.camera.updateProjectionMatrix();
66
- }, [castShadow, shadowMapSize, shadowBias, shadowNormalBias, shadowAutoUpdate, shadowCameraNear, shadowCameraFar]);
70
+ });
67
71
  useFrame(() => {
68
72
  var _a;
69
73
  if ((_a = spotLightRef.current) === null || _a === void 0 ? void 0 : _a.target) {
@@ -77,10 +81,6 @@ const SpotLightComponent = {
77
81
  Editor: SpotLightComponentEditor,
78
82
  View: SpotLightView,
79
83
  defaultProperties: {},
80
- getAssetRefs: (properties) => {
81
- if (properties.map)
82
- return [{ type: 'texture', path: properties.map }];
83
- return [];
84
- },
84
+ getAssetRefs: (properties) => assetRefs(assetRef('texture', properties.map)),
85
85
  };
86
86
  export default SpotLightComponent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.96",
3
+ "version": "0.0.98",
4
4
  "description": "high performance 3D game engine built in React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",