react-three-game 0.0.96 → 0.0.97
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.
- package/dist/tools/prefabeditor/InstanceProvider.js +1 -22
- package/dist/tools/prefabeditor/PrefabEditor.js +4 -1
- package/dist/tools/prefabeditor/PrefabRoot.js +6 -7
- package/dist/tools/prefabeditor/components/CameraComponent.d.ts +1 -1
- package/dist/tools/prefabeditor/components/CameraComponent.js +7 -4
- package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +9 -7
- package/dist/tools/prefabeditor/components/ComponentRegistry.js +6 -0
- package/dist/tools/prefabeditor/components/DirectionalLightComponent.d.ts +1 -1
- package/dist/tools/prefabeditor/components/DirectionalLightComponent.js +6 -15
- package/dist/tools/prefabeditor/components/MaterialComponent.js +2 -8
- package/dist/tools/prefabeditor/components/ModelComponent.js +2 -5
- package/dist/tools/prefabeditor/components/PointLightComponent.d.ts +1 -1
- package/dist/tools/prefabeditor/components/PointLightComponent.js +5 -2
- package/dist/tools/prefabeditor/components/SpotLightComponent.d.ts +1 -1
- package/dist/tools/prefabeditor/components/SpotLightComponent.js +8 -8
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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] })));
|
|
@@ -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
|
|
43
|
-
? orthographicCameraRef
|
|
44
|
-
: perspectiveCameraRef;
|
|
45
|
-
|
|
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,
|
|
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:
|
|
27
|
+
onUpdate: (newComp: Record<string, unknown>) => void;
|
|
26
28
|
basePath?: string;
|
|
27
29
|
}>;
|
|
28
|
-
defaultProperties:
|
|
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,
|
|
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,
|
|
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;
|
|
@@ -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
|
-
|
|
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
|
-
}
|
|
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,6 +13,7 @@ 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';
|
|
@@ -284,13 +285,6 @@ const MaterialComponent = {
|
|
|
284
285
|
metalness: 0,
|
|
285
286
|
roughness: 1
|
|
286
287
|
},
|
|
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
|
-
},
|
|
288
|
+
getAssetRefs: (properties) => assetRefs(assetRef('texture', properties.texture), assetRef('texture', properties.normalMapTexture)),
|
|
295
289
|
};
|
|
296
290
|
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;
|
|
@@ -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
|
-
|
|
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
|
-
}
|
|
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,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
|
-
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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;
|