@3driseai/3drise-viewer 0.1.15 → 0.1.17
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/README.md +4 -3
- package/dist/components/ChladniGrid.d.ts +15 -0
- package/dist/components/ChladniGrid.d.ts.map +1 -0
- package/dist/components/ChladniGrid.js +62 -0
- package/dist/components/CustomPrimitive.d.ts +2 -0
- package/dist/components/CustomPrimitive.d.ts.map +1 -1
- package/dist/components/CustomPrimitive.js +10 -16
- package/dist/components/EffectsGenerator.d.ts.map +1 -1
- package/dist/components/EffectsGenerator.js +26 -2
- package/dist/components/FlowNetGrid.d.ts +15 -0
- package/dist/components/FlowNetGrid.d.ts.map +1 -0
- package/dist/components/FlowNetGrid.js +61 -0
- package/dist/components/GirihGrid.d.ts +15 -0
- package/dist/components/GirihGrid.d.ts.map +1 -0
- package/dist/components/GirihGrid.js +62 -0
- package/dist/components/GravWaveGrid.d.ts +15 -0
- package/dist/components/GravWaveGrid.d.ts.map +1 -0
- package/dist/components/GravWaveGrid.js +62 -0
- package/dist/components/GridsGenerator.d.ts +2 -2
- package/dist/components/GridsGenerator.d.ts.map +1 -1
- package/dist/components/GridsGenerator.js +21 -0
- package/dist/components/HyperbolicGrid.d.ts +15 -0
- package/dist/components/HyperbolicGrid.d.ts.map +1 -0
- package/dist/components/HyperbolicGrid.js +61 -0
- package/dist/components/LayoutInstances.d.ts +13 -0
- package/dist/components/LayoutInstances.d.ts.map +1 -0
- package/dist/components/LayoutInstances.js +39 -0
- package/dist/components/ModelBoundary.d.ts +28 -0
- package/dist/components/ModelBoundary.d.ts.map +1 -0
- package/dist/components/ModelBoundary.js +25 -0
- package/dist/components/ModelPrimitive.d.ts +40 -0
- package/dist/components/ModelPrimitive.d.ts.map +1 -0
- package/dist/components/ModelPrimitive.js +52 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +36 -8
- package/dist/components/ObjectNodeApi.d.ts.map +1 -1
- package/dist/components/ObjectNodeApi.js +6 -1
- package/dist/components/ProjectLoader.d.ts.map +1 -1
- package/dist/components/ProjectLoader.js +1 -0
- package/dist/components/ReactionDiffusionGrid.d.ts +15 -0
- package/dist/components/ReactionDiffusionGrid.d.ts.map +1 -0
- package/dist/components/ReactionDiffusionGrid.js +376 -0
- package/dist/components/WallpaperGrid.d.ts +15 -0
- package/dist/components/WallpaperGrid.d.ts.map +1 -0
- package/dist/components/WallpaperGrid.js +555 -0
- package/dist/components/cursor/CursorController.d.ts.map +1 -1
- package/dist/components/effects/BlackHoleEffect.d.ts +3 -3
- package/dist/components/effects/BlackHoleEffect.d.ts.map +1 -1
- package/dist/components/effects/BlackHoleEffect.js +293 -163
- package/dist/components/effects/DandelionSeedsEffect.d.ts +13 -0
- package/dist/components/effects/DandelionSeedsEffect.d.ts.map +1 -0
- package/dist/components/effects/DandelionSeedsEffect.js +510 -0
- package/dist/components/effects/FallingLeavesEffect.d.ts +13 -0
- package/dist/components/effects/FallingLeavesEffect.d.ts.map +1 -0
- package/dist/components/effects/FallingLeavesEffect.js +446 -0
- package/dist/components/effects/FieldLinesEffect.d.ts +11 -0
- package/dist/components/effects/FieldLinesEffect.d.ts.map +1 -0
- package/dist/components/effects/FieldLinesEffect.js +260 -0
- package/dist/components/effects/FireflySwarmEffect.d.ts +13 -0
- package/dist/components/effects/FireflySwarmEffect.d.ts.map +1 -0
- package/dist/components/effects/FireflySwarmEffect.js +408 -0
- package/dist/components/effects/GalaxyEffect.d.ts +13 -0
- package/dist/components/effects/GalaxyEffect.d.ts.map +1 -0
- package/dist/components/effects/GalaxyEffect.js +374 -0
- package/dist/components/effects/HarmonicShellEffect.d.ts +11 -0
- package/dist/components/effects/HarmonicShellEffect.d.ts.map +1 -0
- package/dist/components/effects/HarmonicShellEffect.js +209 -0
- package/dist/components/effects/IceCrystalsEffect.d.ts +3 -3
- package/dist/components/effects/IceCrystalsEffect.d.ts.map +1 -1
- package/dist/components/effects/IceCrystalsEffect.js +286 -166
- package/dist/components/effects/IceHaloEffect.d.ts +13 -0
- package/dist/components/effects/IceHaloEffect.d.ts.map +1 -0
- package/dist/components/effects/IceHaloEffect.js +306 -0
- package/dist/components/effects/LichtenbergEffect.d.ts +13 -0
- package/dist/components/effects/LichtenbergEffect.d.ts.map +1 -0
- package/dist/components/effects/LichtenbergEffect.js +517 -0
- package/dist/components/effects/MoleculesEffect.d.ts +3 -3
- package/dist/components/effects/MoleculesEffect.d.ts.map +1 -1
- package/dist/components/effects/MoleculesEffect.js +322 -164
- package/dist/components/effects/MurmurationEffect.d.ts +13 -0
- package/dist/components/effects/MurmurationEffect.d.ts.map +1 -0
- package/dist/components/effects/MurmurationEffect.js +539 -0
- package/dist/components/effects/PlanetaryRingsEffect.d.ts +13 -0
- package/dist/components/effects/PlanetaryRingsEffect.d.ts.map +1 -0
- package/dist/components/effects/PlanetaryRingsEffect.js +458 -0
- package/dist/components/effects/PortalEffect.d.ts +3 -3
- package/dist/components/effects/PortalEffect.d.ts.map +1 -1
- package/dist/components/effects/PortalEffect.js +240 -163
- package/dist/components/effects/ShockwaveEffect.d.ts +5 -3
- package/dist/components/effects/ShockwaveEffect.d.ts.map +1 -1
- package/dist/components/effects/ShockwaveEffect.js +538 -142
- package/dist/components/effects/SmokePlumeEffect.d.ts +3 -3
- package/dist/components/effects/SmokePlumeEffect.d.ts.map +1 -1
- package/dist/components/effects/SmokePlumeEffect.js +180 -116
- package/dist/components/effects/SmokeRingEffect.d.ts +3 -3
- package/dist/components/effects/SmokeRingEffect.d.ts.map +1 -1
- package/dist/components/effects/SmokeRingEffect.js +260 -135
- package/dist/components/effects/StrangeAttractorEffect.d.ts +11 -0
- package/dist/components/effects/StrangeAttractorEffect.d.ts.map +1 -0
- package/dist/components/effects/StrangeAttractorEffect.js +229 -0
- package/dist/components/effects/VolumetricFogEffect.d.ts +5 -3
- package/dist/components/effects/VolumetricFogEffect.d.ts.map +1 -1
- package/dist/components/effects/VolumetricFogEffect.js +211 -93
- package/dist/components/effects/WaterCausticsEffect.d.ts +13 -0
- package/dist/components/effects/WaterCausticsEffect.d.ts.map +1 -0
- package/dist/components/effects/WaterCausticsEffect.js +308 -0
- package/dist/components/effects/index.d.ts +9 -0
- package/dist/components/effects/index.d.ts.map +1 -1
- package/dist/components/effects/index.js +9 -0
- package/dist/components/index.d.ts +18 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +10 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useModelObject.d.ts +30 -0
- package/dist/hooks/useModelObject.d.ts.map +1 -0
- package/dist/hooks/useModelObject.js +86 -0
- package/dist/types/gridConfigs.d.ts +98 -0
- package/dist/types/gridConfigs.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useRef } from 'react';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { useObjectReady } from '../hooks/useObjectReady.js';
|
|
5
|
+
import { useGridSurface } from '../hooks/useGridSurface.js';
|
|
6
|
+
import { HyperbolicGridMaterial } from '@3driseai/3drise-core';
|
|
7
|
+
// Side-effect import registers <hyperbolicGridMaterial> via extend().
|
|
8
|
+
void HyperbolicGridMaterial;
|
|
9
|
+
/** HyperbolicGridConfig defaults. Must match the catalog entry in grid-defaults.json exactly. */
|
|
10
|
+
export const defaultHyperbolicGridConfig = {
|
|
11
|
+
cellSize: 22,
|
|
12
|
+
size: 50,
|
|
13
|
+
flat: true,
|
|
14
|
+
segments: undefined,
|
|
15
|
+
lineMode: 1,
|
|
16
|
+
cellMode: 2,
|
|
17
|
+
lineWidth: 1.4,
|
|
18
|
+
sectionSize: 3,
|
|
19
|
+
sectionWidth: 1,
|
|
20
|
+
animSpeed: 1,
|
|
21
|
+
animScale: 1.2,
|
|
22
|
+
animIntensity: 0.7,
|
|
23
|
+
fadeDistance: undefined,
|
|
24
|
+
fadeStrength: 0.2,
|
|
25
|
+
displace: 0,
|
|
26
|
+
sides: 7,
|
|
27
|
+
valence: 3,
|
|
28
|
+
drift: 0.5,
|
|
29
|
+
lineColor: '#c9a4ff',
|
|
30
|
+
sectionColor: '#ffd9f2',
|
|
31
|
+
cellColor: '#2a1446',
|
|
32
|
+
glowColor: '#b07cff',
|
|
33
|
+
bgColor: '#07030c',
|
|
34
|
+
bgOpacity: 0,
|
|
35
|
+
followMouse: false,
|
|
36
|
+
reveal: 1,
|
|
37
|
+
revealDuration: 0,
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* An Escher-style {p,q} tiling of the Poincare disk. A slow Mobius translation glides the tiling through itself, and the tiles shrink without end toward the rim.
|
|
41
|
+
*/
|
|
42
|
+
export function HyperbolicGrid({ config = defaultHyperbolicGridConfig, groupProps, onObjectReady, onObjectDispose }) {
|
|
43
|
+
const matRef = useRef(null);
|
|
44
|
+
const rootRef = useRef(null);
|
|
45
|
+
const meshRef = useRef(null);
|
|
46
|
+
useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
|
|
47
|
+
const { cellSize, size, segments, flat, lineMode, cellMode, lineWidth, sectionSize, sectionWidth, animSpeed, animScale, animIntensity, fadeDistance, fadeStrength, displace, sides, valence, drift, lineColor, sectionColor, cellColor, glowColor, bgColor, bgOpacity, followMouse, reveal, revealDuration, } = config;
|
|
48
|
+
// the ripple is fine-grained relative to the disk
|
|
49
|
+
const segs = segments ?? (displace > 0 ? Math.min(512, Math.max(96, Math.ceil(size / Math.max(cellSize, 1e-4)) * 64)) : 1);
|
|
50
|
+
const fade = fadeDistance ?? size * 0.5;
|
|
51
|
+
const colors = useMemo(() => ({
|
|
52
|
+
line: new THREE.Color(lineColor),
|
|
53
|
+
section: new THREE.Color(sectionColor),
|
|
54
|
+
cell: new THREE.Color(cellColor),
|
|
55
|
+
glow: new THREE.Color(glowColor),
|
|
56
|
+
bg: new THREE.Color(bgColor),
|
|
57
|
+
}), [lineColor, sectionColor, cellColor, glowColor, bgColor]);
|
|
58
|
+
useGridSurface(matRef, meshRef, { followMouse, reveal, revealDuration });
|
|
59
|
+
return (_jsx("group", { ref: rootRef, ...groupProps, children: _jsxs("mesh", { ref: meshRef, rotation: flat ? [-Math.PI / 2, 0, 0] : [0, 0, 0], children: [_jsx("planeGeometry", { args: [size, size, segs, segs] }), _jsx("hyperbolicGridMaterial", { ref: matRef, transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, side: THREE.DoubleSide, u_cellSize: cellSize, u_lineWidth: lineWidth, u_sectionSize: sectionSize, u_sectionWidth: sectionWidth, u_lineMode: lineMode, u_cellMode: cellMode, u_animSpeed: animSpeed, u_animScale: animScale, u_animIntensity: animIntensity, u_fadeDistance: fade, u_fadeStrength: fadeStrength, u_displace: displace, u_sides: sides, u_valence: valence, u_drift: drift, u_lineColor: colors.line, u_sectionColor: colors.section, u_cellColor: colors.cell, u_glowColor: colors.glow, u_bgColor: colors.bg, u_bgOpacity: bgOpacity }, HyperbolicGridMaterial.key)] }) }));
|
|
60
|
+
}
|
|
61
|
+
export default HyperbolicGrid;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Object3D } from 'three';
|
|
3
|
+
import type { ThreeEvent } from '@react-three/fiber';
|
|
4
|
+
import type { CreatedObjectSettings, ObjectLayoutSettings } from '@3driseai/3drise-core';
|
|
5
|
+
export interface LayoutInstancesProps {
|
|
6
|
+
createdObject: CreatedObjectSettings;
|
|
7
|
+
layout: ObjectLayoutSettings;
|
|
8
|
+
render: (slot: number) => ReactNode;
|
|
9
|
+
handleObjectClick?: (createdObject: CreatedObjectSettings, ref: Object3D, event: ThreeEvent<MouseEvent>) => void;
|
|
10
|
+
}
|
|
11
|
+
declare const LayoutInstances: import("react").MemoExoticComponent<({ createdObject, layout, render, handleObjectClick }: LayoutInstancesProps) => import("react").JSX.Element>;
|
|
12
|
+
export default LayoutInstances;
|
|
13
|
+
//# sourceMappingURL=LayoutInstances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutInstances.d.ts","sourceRoot":"","sources":["../../src/components/LayoutInstances.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAS,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,qBAAqB,EAAc,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAErG,MAAM,WAAW,oBAAoB;IACjC,aAAa,EAAE,qBAAqB,CAAC;IACrC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IACpC,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CACpH;AAmCD,QAAA,MAAM,eAAe,6FAA+D,oBAAoB,iCAmBtG,CAAC;AAGH,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// LayoutInstances — repeat one scene object across a gallery layout
|
|
4
|
+
// =============================================================================
|
|
5
|
+
//
|
|
6
|
+
// ObjectNode hands this the object's own renderer; each slot is a plain group at the
|
|
7
|
+
// transform LayoutCreator computed for it, and the renderer output goes inside.
|
|
8
|
+
//
|
|
9
|
+
// Rules (see the project doc claude/object-layout-plan.md):
|
|
10
|
+
// - Only slot 0 reports readiness. The render callback receives the slot index and
|
|
11
|
+
// ObjectNode passes no ready callbacks for the others, so one object still reports
|
|
12
|
+
// once and ObjectsRenderer's aggregate count stays right.
|
|
13
|
+
// - Slot groups never set userData.id, so findById(id) keeps returning the
|
|
14
|
+
// CreatedObject group that owns the transform.
|
|
15
|
+
// - Clicks are per slot: zoom / glow / vanish target the copy that was clicked, the
|
|
16
|
+
// same way gallery frames behave.
|
|
17
|
+
// - Motion stays on the CreatedObject group, so the whole layout animates as one.
|
|
18
|
+
import { memo, useMemo, useRef } from 'react';
|
|
19
|
+
import { generateLayoutSlots } from '@3driseai/3drise-core';
|
|
20
|
+
const LayoutSlotGroup = ({ slot, index, createdObject, handleObjectClick, children }) => {
|
|
21
|
+
const ref = useRef(null);
|
|
22
|
+
const onClick = handleObjectClick
|
|
23
|
+
? (e) => {
|
|
24
|
+
if (!ref.current)
|
|
25
|
+
return;
|
|
26
|
+
e.stopPropagation();
|
|
27
|
+
handleObjectClick(createdObject, ref.current, e);
|
|
28
|
+
}
|
|
29
|
+
: undefined;
|
|
30
|
+
return (_jsx("group", { ref: ref, name: `layout-slot-${index}`, position: slot.position, rotation: slot.rotation ?? [0, 0, 0], scale: slot.scale ?? [1, 1, 1], userData: { layoutSlot: index }, onClick: onClick, children: children }));
|
|
31
|
+
};
|
|
32
|
+
const LayoutInstances = memo(({ createdObject, layout, render, handleObjectClick }) => {
|
|
33
|
+
// ObjectNode normalises the block on every render, so key on its contents.
|
|
34
|
+
const layoutKey = JSON.stringify(layout);
|
|
35
|
+
const slots = useMemo(() => generateLayoutSlots(layout.count, layout), [layoutKey]);
|
|
36
|
+
return (_jsx(_Fragment, { children: slots.map((slot, index) => (_jsx(LayoutSlotGroup, { slot: slot, index: index, createdObject: createdObject, handleObjectClick: handleObjectClick, children: render(index) }, index))) }));
|
|
37
|
+
});
|
|
38
|
+
LayoutInstances.displayName = 'LayoutInstances';
|
|
39
|
+
export default LayoutInstances;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Component } from 'react';
|
|
2
|
+
import type { ErrorInfo, ReactNode } from 'react';
|
|
3
|
+
interface ModelBoundaryProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** Rendered while the model's GLTF is in flight. Null keeps the scene from jumping. */
|
|
6
|
+
fallback?: ReactNode;
|
|
7
|
+
/** Identifies the offending object in the console when a load fails. */
|
|
8
|
+
label?: string;
|
|
9
|
+
}
|
|
10
|
+
interface ModelBoundaryState {
|
|
11
|
+
failed: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Suspense + error boundary around a single model leaf.
|
|
15
|
+
*
|
|
16
|
+
* Both halves are required. The cache re-throws a rejected load on every subsequent read,
|
|
17
|
+
* and a throw that reaches a bare `<Suspense>` unmounts everything under it — one model
|
|
18
|
+
* behind a dead URL would blank the rest of the scene. Here a failed model renders nothing
|
|
19
|
+
* and its siblings carry on.
|
|
20
|
+
*/
|
|
21
|
+
declare class ModelBoundary extends Component<ModelBoundaryProps, ModelBoundaryState> {
|
|
22
|
+
state: ModelBoundaryState;
|
|
23
|
+
static getDerivedStateFromError(): ModelBoundaryState;
|
|
24
|
+
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
25
|
+
render(): ReactNode;
|
|
26
|
+
}
|
|
27
|
+
export default ModelBoundary;
|
|
28
|
+
//# sourceMappingURL=ModelBoundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelBoundary.d.ts","sourceRoot":"","sources":["../../src/components/ModelBoundary.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElD,UAAU,kBAAkB;IACxB,QAAQ,EAAE,SAAS,CAAC;IACpB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,kBAAkB;IACxB,MAAM,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,cAAM,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACzE,KAAK,EAAE,kBAAkB,CAAqB;IAE9C,MAAM,CAAC,wBAAwB,IAAI,kBAAkB;IAIrD,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAQtD,MAAM,IAAI,SAAS;CAItB;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Component, Suspense } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Suspense + error boundary around a single model leaf.
|
|
5
|
+
*
|
|
6
|
+
* Both halves are required. The cache re-throws a rejected load on every subsequent read,
|
|
7
|
+
* and a throw that reaches a bare `<Suspense>` unmounts everything under it — one model
|
|
8
|
+
* behind a dead URL would blank the rest of the scene. Here a failed model renders nothing
|
|
9
|
+
* and its siblings carry on.
|
|
10
|
+
*/
|
|
11
|
+
class ModelBoundary extends Component {
|
|
12
|
+
state = { failed: false };
|
|
13
|
+
static getDerivedStateFromError() {
|
|
14
|
+
return { failed: true };
|
|
15
|
+
}
|
|
16
|
+
componentDidCatch(error, info) {
|
|
17
|
+
console.error(`[ModelBoundary] Model failed to load${this.props.label ? `: ${this.props.label}` : ''}`, error, info.componentStack);
|
|
18
|
+
}
|
|
19
|
+
render() {
|
|
20
|
+
if (this.state.failed)
|
|
21
|
+
return null;
|
|
22
|
+
return _jsx(Suspense, { fallback: this.props.fallback ?? null, children: this.props.children });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export default ModelBoundary;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import type { CreatedObjectSettings } from '@3driseai/3drise-core';
|
|
4
|
+
import type { ObjectReadyProps } from '../types/objectReady';
|
|
5
|
+
interface ModelPrimitiveProps extends ObjectReadyProps {
|
|
6
|
+
createdObject: CreatedObjectSettings;
|
|
7
|
+
/** Layout slot. Slot 0 is the object itself; the rest are unregistered clones. */
|
|
8
|
+
slot?: number;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Mounts the Object3D behind a `type: 'model'` scene object, and hands it to the host
|
|
13
|
+
* application.
|
|
14
|
+
*
|
|
15
|
+
* Split out of CustomPrimitive because this is the component that suspends: it must sit
|
|
16
|
+
* under its own boundary so one slow or broken model does not hold up its siblings.
|
|
17
|
+
*
|
|
18
|
+
* ## Readiness
|
|
19
|
+
*
|
|
20
|
+
* `onObjectReady` fires here, with the loaded model root - that Object3D is the whole point
|
|
21
|
+
* of the object API, so it has to arrive on both paths: preloaded (mounts in the same
|
|
22
|
+
* commit as its parent) and suspended (mounts whenever the GLTF lands, which may be several
|
|
23
|
+
* frames later).
|
|
24
|
+
*
|
|
25
|
+
* CustomPrimitive cannot report it any more. When this component suspends, CustomPrimitive
|
|
26
|
+
* commits first with its ref still empty, its layout effect finds nothing to report, and it
|
|
27
|
+
* never re-renders once the asset resolves. Its `meshRef` now stays null for a model, so its
|
|
28
|
+
* own call is a no-op rather than a second, conflicting report.
|
|
29
|
+
*
|
|
30
|
+
* The report is driven by a callback ref rather than a layout effect: R3F runs it the moment
|
|
31
|
+
* it attaches the object and again with null when it detaches, so the pair fires exactly on
|
|
32
|
+
* attach/detach no matter how many renders the suspension cost.
|
|
33
|
+
*
|
|
34
|
+
* `dispose={null}` is not optional. Geometry and textures here are shared with the cache
|
|
35
|
+
* master and every other instance of the same URL; letting R3F free them on unmount breaks
|
|
36
|
+
* all of them.
|
|
37
|
+
*/
|
|
38
|
+
declare const ModelPrimitive: React.FC<ModelPrimitiveProps>;
|
|
39
|
+
export default ModelPrimitive;
|
|
40
|
+
//# sourceMappingURL=ModelPrimitive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelPrimitive.d.ts","sourceRoot":"","sources":["../../src/components/ModelPrimitive.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,UAAU,mBAAoB,SAAQ,gBAAgB;IAClD,aAAa,EAAE,qBAAqB,CAAC;IACrC,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,QAAA,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA8BhD,CAAC;AAIH,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useCallback, useRef } from 'react';
|
|
3
|
+
import { useModelObject } from '../hooks/useModelObject.js';
|
|
4
|
+
import { useObjectReadyReporter } from '../hooks/useObjectReady.js';
|
|
5
|
+
/**
|
|
6
|
+
* Mounts the Object3D behind a `type: 'model'` scene object, and hands it to the host
|
|
7
|
+
* application.
|
|
8
|
+
*
|
|
9
|
+
* Split out of CustomPrimitive because this is the component that suspends: it must sit
|
|
10
|
+
* under its own boundary so one slow or broken model does not hold up its siblings.
|
|
11
|
+
*
|
|
12
|
+
* ## Readiness
|
|
13
|
+
*
|
|
14
|
+
* `onObjectReady` fires here, with the loaded model root - that Object3D is the whole point
|
|
15
|
+
* of the object API, so it has to arrive on both paths: preloaded (mounts in the same
|
|
16
|
+
* commit as its parent) and suspended (mounts whenever the GLTF lands, which may be several
|
|
17
|
+
* frames later).
|
|
18
|
+
*
|
|
19
|
+
* CustomPrimitive cannot report it any more. When this component suspends, CustomPrimitive
|
|
20
|
+
* commits first with its ref still empty, its layout effect finds nothing to report, and it
|
|
21
|
+
* never re-renders once the asset resolves. Its `meshRef` now stays null for a model, so its
|
|
22
|
+
* own call is a no-op rather than a second, conflicting report.
|
|
23
|
+
*
|
|
24
|
+
* The report is driven by a callback ref rather than a layout effect: R3F runs it the moment
|
|
25
|
+
* it attaches the object and again with null when it detaches, so the pair fires exactly on
|
|
26
|
+
* attach/detach no matter how many renders the suspension cost.
|
|
27
|
+
*
|
|
28
|
+
* `dispose={null}` is not optional. Geometry and textures here are shared with the cache
|
|
29
|
+
* master and every other instance of the same URL; letting R3F free them on unmount breaks
|
|
30
|
+
* all of them.
|
|
31
|
+
*/
|
|
32
|
+
const ModelPrimitive = memo(({ createdObject, slot = 0, onObjectReady, onObjectDispose, children }) => {
|
|
33
|
+
const attachedRef = useRef(null);
|
|
34
|
+
const object = useModelObject(createdObject, slot);
|
|
35
|
+
const { report, reportDisposed } = useObjectReadyReporter(createdObject, onObjectReady, onObjectDispose);
|
|
36
|
+
const setObjectRef = useCallback((instance) => {
|
|
37
|
+
if (instance) {
|
|
38
|
+
attachedRef.current = instance;
|
|
39
|
+
report(instance);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (attachedRef.current) {
|
|
43
|
+
reportDisposed(attachedRef.current);
|
|
44
|
+
attachedRef.current = null;
|
|
45
|
+
}
|
|
46
|
+
}, [report, reportDisposed]);
|
|
47
|
+
if (!object)
|
|
48
|
+
return null;
|
|
49
|
+
return (_jsx("primitive", { ref: setObjectRef, name: createdObject.name, object: object, dispose: null, children: children }, `${createdObject.id}:${slot}`));
|
|
50
|
+
});
|
|
51
|
+
ModelPrimitive.displayName = 'ModelPrimitive';
|
|
52
|
+
export default ModelPrimitive;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectNode.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNode.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ObjectNode.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNode.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAe,qBAAqB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAiBrD,KAAK,eAAe,GAAG,gBAAgB,GAAG;IACtC,IAAI,EAAE,cAAc,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAC7G,CAAC;AAgBF,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAiIzC,CAAC;AACF,eAAe,UAAU,CAAC"}
|
|
@@ -15,7 +15,23 @@ import Galaxy from "./Galaxy.js";
|
|
|
15
15
|
import GridGenerator from "./GridsGenerator.js";
|
|
16
16
|
import OceanBuilder from "./OceanBuilder.js";
|
|
17
17
|
import LandscapeObject from "./LandscapeObject.js";
|
|
18
|
+
import LayoutInstances from "./LayoutInstances.js";
|
|
18
19
|
import { SELF_MANAGED_MATERIAL } from "../constants.js";
|
|
20
|
+
import { LAYOUT_CAPABLE_TYPES, getObjectLayoutSupport, normalizeObjectLayout } from "@3driseai/3drise-core";
|
|
21
|
+
// Slots after the first render with no ready callbacks: one object reports once.
|
|
22
|
+
const NO_READY = {};
|
|
23
|
+
// A point light's shadow is six extra renders; only slot 0 keeps it. Cached per settings
|
|
24
|
+
// object so the copies do not re-run their shadow effect on every render.
|
|
25
|
+
const noShadowCache = new WeakMap();
|
|
26
|
+
const withoutShadow = (obj) => {
|
|
27
|
+
let copy = noShadowCache.get(obj);
|
|
28
|
+
if (!copy) {
|
|
29
|
+
const config = (obj.config ?? {});
|
|
30
|
+
copy = { ...obj, config: { ...config, shadow: { ...config.shadow, enabled: false } } };
|
|
31
|
+
noShadowCache.set(obj, copy);
|
|
32
|
+
}
|
|
33
|
+
return copy;
|
|
34
|
+
};
|
|
19
35
|
// const EffectsLayer: React.FC<{ effects: CreatedObjectSettings['effects'] }> = ({ effects }) =>
|
|
20
36
|
// effects?.length ? (
|
|
21
37
|
// <>
|
|
@@ -40,7 +56,9 @@ const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick })
|
|
|
40
56
|
// Specialized renderers for each object type
|
|
41
57
|
const renderers = useMemo(() => ({
|
|
42
58
|
group: () => null,
|
|
43
|
-
mesh
|
|
59
|
+
// mesh / model / effect / light take a layout slot as the third argument
|
|
60
|
+
// (see LayoutInstances); slot 0 is also the no-layout case.
|
|
61
|
+
mesh: (obj, _onObjectReady, slot = 0) => (_jsx(CustomPrimitive, { createdObject: obj, ...(slot === 0 ? { onObjectReady, onObjectDispose } : NO_READY), handleObjectClick: handleObjectClick }, obj.id)),
|
|
44
62
|
// water: (obj: CreatedObjectSettings, cameraSettings: CameraState, onObjectReady?: (object: CreatedObjectSettings, ref: Object3D) => void) => (
|
|
45
63
|
// <Ocean
|
|
46
64
|
// settings={obj}
|
|
@@ -56,7 +74,7 @@ const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick })
|
|
|
56
74
|
// settings={obj}
|
|
57
75
|
// />
|
|
58
76
|
// ),
|
|
59
|
-
model: (obj,
|
|
77
|
+
model: (obj, _onObjectReady, slot = 0) => (_jsx(CustomPrimitive, { createdObject: obj, slot: slot, ...(slot === 0 ? { onObjectReady, onObjectDispose } : NO_READY), handleObjectClick: handleObjectClick }, obj.id)),
|
|
60
78
|
// custom_primitive: (obj: CreatedObjectSettings, cameraSettings: CameraState, onObjectReady?: (object: CreatedObjectSettings, ref: Object3D) => void) => (
|
|
61
79
|
// <CustomPrimitive
|
|
62
80
|
// key={obj.id}
|
|
@@ -87,11 +105,11 @@ const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick })
|
|
|
87
105
|
// LandscapeConnector instead; this one is a diorama, a floating island or
|
|
88
106
|
// a game tile, and gets its transform from the CreatedObject wrapper.
|
|
89
107
|
landscape: (obj, onObjectReady) => (_jsx(LandscapeObject, { settings: obj, ...relabel(obj) }, obj.id)),
|
|
90
|
-
effect: (obj) => (_jsx(EffectsGenerator, { settings: {
|
|
108
|
+
effect: (obj, _onObjectReady, slot = 0) => (_jsx(EffectsGenerator, { settings: {
|
|
91
109
|
config: obj.config,
|
|
92
|
-
}, ...relabel(obj) }, obj.id)),
|
|
110
|
+
}, ...(slot === 0 ? relabel(obj) : NO_READY) }, obj.id)),
|
|
93
111
|
gallery: (obj, onObjectReady) => (_jsx(GalleryLayout, { createdObject: obj, handleObjectClick: handleObjectClick, ...relabel(obj) })),
|
|
94
|
-
light: (obj,
|
|
112
|
+
light: (obj, _onObjectReady, slot = 0) => (_jsx(LightObject, { createdObject: slot === 0 ? obj : withoutShadow(obj), ...(slot === 0 ? relabel(obj) : NO_READY) })),
|
|
95
113
|
environment: (obj, onObjectReady) => (_jsx(EnvironmentObject, { createdObject: obj, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose })),
|
|
96
114
|
space: (obj, onObjectReady) => (_jsx(Galaxy, { createdObject: obj, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose })),
|
|
97
115
|
// rain: (obj: CreatedObjectSettings, cameraSettings: CameraState, onObjectReady?: (object: CreatedObjectSettings, ref: Object3D) => void) => (
|
|
@@ -115,10 +133,20 @@ const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick })
|
|
|
115
133
|
// />
|
|
116
134
|
// ),
|
|
117
135
|
}), [handleObjectClick, onObjectReady, onObjectDispose, relabel]);
|
|
118
|
-
const renderObject = useCallback((obj,
|
|
136
|
+
const renderObject = useCallback((obj, _handleObjectClick) => {
|
|
119
137
|
const renderer = renderers[obj.type];
|
|
120
|
-
|
|
121
|
-
|
|
138
|
+
if (!renderer)
|
|
139
|
+
return null;
|
|
140
|
+
// meshSettings.layout: repeat the renderer output across a gallery layout.
|
|
141
|
+
// Absent on every object saved before layouts existed, which renders as before.
|
|
142
|
+
const layout = LAYOUT_CAPABLE_TYPES.has(obj.type) ? normalizeObjectLayout(obj.meshSettings?.layout) : null;
|
|
143
|
+
const support = layout?.enabled ? getObjectLayoutSupport(obj) : null;
|
|
144
|
+
if (layout && support?.allowed) {
|
|
145
|
+
const capped = layout.count > support.maxCount ? { ...layout, count: support.maxCount } : layout;
|
|
146
|
+
return (_jsx(LayoutInstances, { createdObject: obj, layout: capped, handleObjectClick: handleObjectClick, render: (slot) => renderer(obj, onObjectReady, slot) }));
|
|
147
|
+
}
|
|
148
|
+
return renderer(obj, onObjectReady) ?? null;
|
|
149
|
+
}, [onObjectReady, renderers, handleObjectClick]);
|
|
122
150
|
if (!createdObject) {
|
|
123
151
|
return null;
|
|
124
152
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectNodeApi.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNodeApi.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAe,qBAAqB,EAAkB,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,KAAK,kBAAkB,GAAG,gBAAgB,GAAG;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAC7G,CAAC;AAGF,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"ObjectNodeApi.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNodeApi.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAe,qBAAqB,EAAkB,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,KAAK,kBAAkB,GAAG,gBAAgB,GAAG;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAC7G,CAAC;AAGF,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAmB/C,CAAC;AACF,eAAe,aAAa,CAAC"}
|
|
@@ -9,11 +9,16 @@ const ObjectNodeApi = ({ objectId, onObjectReady, onObjectDispose, handleObjectC
|
|
|
9
9
|
// too — SceneBuilder is not in this tree to do it.
|
|
10
10
|
useRegisterScene();
|
|
11
11
|
const [node, setNode] = useState(null);
|
|
12
|
+
// No asset pre-pass here on purpose. Every model leaf under this tree loads itself
|
|
13
|
+
// through the shared URL cache under its own Suspense boundary (see useModelObject),
|
|
14
|
+
// however deeply it is nested, so this component only has to fetch the tree.
|
|
12
15
|
useEffect(() => {
|
|
13
16
|
fetch(`${dataCenterServer}scene-objects/${objectId}/tree`)
|
|
14
17
|
.then(res => res.ok ? res.json() : Promise.reject(res.status))
|
|
15
18
|
.then(({ tree }) => setNode(tree))
|
|
16
|
-
.catch(
|
|
19
|
+
.catch(error => {
|
|
20
|
+
console.error(`[ObjectNodeApi] Failed to load object tree ${objectId}:`, error);
|
|
21
|
+
});
|
|
17
22
|
}, [objectId]);
|
|
18
23
|
if (!node)
|
|
19
24
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectLoader.d.ts","sourceRoot":"","sources":["../../src/components/ProjectLoader.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGhF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,KAAK,YAAY,GAAG,gBAAgB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACtG,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC,CAAC;AAGF,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"ProjectLoader.d.ts","sourceRoot":"","sources":["../../src/components/ProjectLoader.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGhF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,KAAK,YAAY,GAAG,gBAAgB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACtG,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC,CAAC;AAGF,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAsDzC,CAAC;AACF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ThreeElements } from '@react-three/fiber';
|
|
2
|
+
import type { ObjectReadyProps } from '../types/objectReady';
|
|
3
|
+
import type { ReactionDiffusionGridConfig } from '../types/gridConfigs';
|
|
4
|
+
export interface ReactionDiffusionGridProps extends ObjectReadyProps {
|
|
5
|
+
config?: ReactionDiffusionGridConfig;
|
|
6
|
+
groupProps?: ThreeElements['group'];
|
|
7
|
+
}
|
|
8
|
+
/** ReactionDiffusionGridConfig defaults. Must match the catalog entry in grid-defaults.json exactly. */
|
|
9
|
+
export declare const defaultReactionDiffusionGridConfig: ReactionDiffusionGridConfig;
|
|
10
|
+
/**
|
|
11
|
+
* A Gray-Scott reaction-diffusion field simulated on the GPU and sampled by the plane: coral, labyrinths and dividing spots grow, merge and keep evolving, wrapped seamlessly as a torus.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ReactionDiffusionGrid({ config, groupProps, onObjectReady, onObjectDispose }: ReactionDiffusionGridProps): import("react").JSX.Element;
|
|
14
|
+
export default ReactionDiffusionGrid;
|
|
15
|
+
//# sourceMappingURL=ReactionDiffusionGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactionDiffusionGrid.d.ts","sourceRoot":"","sources":["../../src/components/ReactionDiffusionGrid.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAGxE,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAChE,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC,UAAU,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACvC;AAKD,wGAAwG;AACxG,eAAO,MAAM,kCAAkC,EAAE,2BA6BhD,CAAC;AAuTF;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,MAA2C,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,EAAE,0BAA0B,+BAgF5J;AAED,eAAe,qBAAqB,CAAC"}
|