react-three-game 0.0.78 → 0.0.80

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.
@@ -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() {
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { PerspectiveCamera, useHelper } from '@react-three/drei';
3
3
  import { useRef } from 'react';
4
4
  import { CameraHelper } from 'three';
@@ -30,12 +30,13 @@ function CameraComponentView({ properties, children }) {
30
30
  cameraRef.current.updateMatrixWorld();
31
31
  }
32
32
  });
33
- return (_jsxs(_Fragment, { children: [_jsx(PerspectiveCamera, { ref: cameraRef, makeDefault: !editMode, fov: fov, near: near, zoom: zoom, far: far }), editMode ? (_jsxs("group", { children: [_jsxs("mesh", { children: [_jsx("boxGeometry", { args: [0.3, 0.3, 0.5] }), _jsx("meshBasicMaterial", { color: '#22d3ee', wireframe: true })] }), _jsxs("mesh", { position: [0, 0, -0.25], rotation: [Math.PI / 2, 0, 0], children: [_jsx("coneGeometry", { args: [0.08, 0.16, 16] }), _jsx("meshBasicMaterial", { color: '#22d3ee', wireframe: true })] })] })) : null, children] }));
33
+ return (_jsxs(PerspectiveCamera, { ref: cameraRef, makeDefault: !editMode, fov: fov, near: near, zoom: zoom, far: far, children: [editMode ? (_jsxs("group", { children: [_jsxs("mesh", { children: [_jsx("boxGeometry", { args: [0.3, 0.3, 0.5] }), _jsx("meshBasicMaterial", { color: '#22d3ee', wireframe: true })] }), _jsxs("mesh", { position: [0, 0, -0.25], rotation: [Math.PI / 2, 0, 0], children: [_jsx("coneGeometry", { args: [0.08, 0.16, 16] }), _jsx("meshBasicMaterial", { color: '#22d3ee', wireframe: true })] })] })) : null, children] }));
34
34
  }
35
35
  const CameraComponent = {
36
36
  name: 'Camera',
37
37
  Editor: CameraComponentEditor,
38
38
  View: CameraComponentView,
39
+ composition: 'wrap',
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
  }
@@ -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',
@@ -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 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.78",
3
+ "version": "0.0.80",
4
4
  "description": "high performance 3D game engine built in React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",