@3driseai/3drise-viewer 0.1.29 → 0.1.31
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/animationsV2/ClipPlayer.d.ts.map +1 -1
- package/dist/animationsV2/ClipPlayer.js +14 -12
- package/dist/animationsV2/ClipsRuntime.d.ts +13 -0
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +115 -4
- package/dist/animationsV2/appliers.d.ts.map +1 -1
- package/dist/animationsV2/appliers.js +21 -2
- package/dist/animationsV2/clipUtils.d.ts.map +1 -1
- package/dist/animationsV2/clipUtils.js +5 -1
- package/dist/animationsV2/sequenceUtils.d.ts +5 -0
- package/dist/animationsV2/sequenceUtils.d.ts.map +1 -1
- package/dist/animationsV2/sequenceUtils.js +14 -5
- package/dist/animationsV2/sunSystemLive.d.ts +12 -0
- package/dist/animationsV2/sunSystemLive.d.ts.map +1 -0
- package/dist/animationsV2/sunSystemLive.js +8 -0
- package/dist/animationsV2/types.d.ts +6 -0
- package/dist/animationsV2/types.d.ts.map +1 -1
- package/dist/api/sceneHandle.d.ts +3 -1
- package/dist/api/sceneHandle.d.ts.map +1 -1
- package/dist/api/sceneHandle.js +2 -2
- package/dist/components/AdaptiveResolution.d.ts +9 -0
- package/dist/components/AdaptiveResolution.d.ts.map +1 -0
- package/dist/components/AdaptiveResolution.js +61 -0
- package/dist/components/CameraController.d.ts.map +1 -1
- package/dist/components/CameraController.js +24 -7
- package/dist/components/EffectsGenerator.d.ts.map +1 -1
- package/dist/components/EffectsGenerator.js +43 -38
- package/dist/components/GeometryShape.d.ts.map +1 -1
- package/dist/components/GeometryShape.js +22 -2
- package/dist/components/MoonDisc.d.ts.map +1 -1
- package/dist/components/MoonDisc.js +2 -1
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +6 -17
- package/dist/components/OceanBuilder.d.ts +4 -1
- package/dist/components/OceanBuilder.d.ts.map +1 -1
- package/dist/components/OceanBuilder.js +2 -1
- package/dist/components/ParticlesGenerator.d.ts.map +1 -1
- package/dist/components/ParticlesGenerator.js +46 -24
- package/dist/components/PickVolume.d.ts +17 -0
- package/dist/components/PickVolume.d.ts.map +1 -0
- package/dist/components/PickVolume.js +20 -0
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +5 -2
- package/dist/components/SkyStars.d.ts.map +1 -1
- package/dist/components/SkyStars.js +83 -2
- package/dist/components/Skybox.d.ts.map +1 -1
- package/dist/components/Skybox.js +2 -1
- package/dist/components/SunLight.d.ts.map +1 -1
- package/dist/components/SunLight.js +3 -2
- package/dist/components/TextGenerator.d.ts.map +1 -1
- package/dist/components/TextGenerator.js +3 -2
- package/dist/components/index.d.ts +2 -8
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -4
- package/dist/components/lightBulb/LightBulb.d.ts.map +1 -1
- package/dist/components/lightBulb/LightBulb.js +7 -2
- package/dist/components/particles/BioluminescentWakeParticles.d.ts +5 -0
- package/dist/components/particles/BioluminescentWakeParticles.d.ts.map +1 -1
- package/dist/components/particles/BioluminescentWakeParticles.js +2 -1
- package/dist/components/particles/BrownianDustParticles.d.ts +5 -0
- package/dist/components/particles/BrownianDustParticles.d.ts.map +1 -1
- package/dist/components/particles/BrownianDustParticles.js +2 -0
- package/dist/components/particles/ChladniSandParticles.d.ts +5 -0
- package/dist/components/particles/ChladniSandParticles.d.ts.map +1 -1
- package/dist/components/particles/ChladniSandParticles.js +2 -1
- package/dist/components/particles/ElectronOrbitalsParticles.d.ts +5 -0
- package/dist/components/particles/ElectronOrbitalsParticles.d.ts.map +1 -1
- package/dist/components/particles/ElectronOrbitalsParticles.js +2 -1
- package/dist/components/particles/FaradayPowderParticles.d.ts +5 -0
- package/dist/components/particles/FaradayPowderParticles.d.ts.map +1 -1
- package/dist/components/particles/FaradayPowderParticles.js +2 -1
- package/dist/components/particles/FireworksParticles.d.ts +22 -0
- package/dist/components/particles/FireworksParticles.d.ts.map +1 -0
- package/dist/components/particles/FireworksParticles.js +1649 -0
- package/dist/components/particles/GrinderSparksParticles.d.ts +5 -0
- package/dist/components/particles/GrinderSparksParticles.d.ts.map +1 -1
- package/dist/components/particles/GrinderSparksParticles.js +2 -1
- package/dist/components/particles/MagneticBottleParticles.d.ts +5 -0
- package/dist/components/particles/MagneticBottleParticles.d.ts.map +1 -1
- package/dist/components/particles/MagneticBottleParticles.js +2 -1
- package/dist/components/particles/NeonRainParticles.d.ts +5 -0
- package/dist/components/particles/NeonRainParticles.d.ts.map +1 -1
- package/dist/components/particles/NeonRainParticles.js +2 -1
- package/dist/components/particles/ShapeBurstParticles.d.ts +5 -0
- package/dist/components/particles/ShapeBurstParticles.d.ts.map +1 -1
- package/dist/components/particles/ShapeBurstParticles.js +2 -1
- package/dist/components/particles/ShapeFlowParticles.d.ts +5 -0
- package/dist/components/particles/ShapeFlowParticles.d.ts.map +1 -1
- package/dist/components/particles/ShapeFlowParticles.js +2 -1
- package/dist/components/particles/TidalStreamParticles.d.ts +5 -0
- package/dist/components/particles/TidalStreamParticles.d.ts.map +1 -1
- package/dist/components/particles/TidalStreamParticles.js +2 -0
- package/dist/components/particles/index.d.ts +2 -0
- package/dist/components/particles/index.d.ts.map +1 -1
- package/dist/components/particles/index.js +1 -0
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
- package/dist/components/terrain/TerrainSurface.js +26 -4
- package/dist/components/text/PlainText.d.ts +15 -0
- package/dist/components/text/PlainText.d.ts.map +1 -0
- package/dist/components/text/PlainText.js +4 -0
- package/dist/components/text/TextObjectView.d.ts +3 -1
- package/dist/components/text/TextObjectView.d.ts.map +1 -1
- package/dist/components/text/TextObjectView.js +9 -3
- package/dist/components/text/engine/looks/index.d.ts.map +1 -1
- package/dist/components/text/engine/looks/index.js +2 -1
- package/dist/components/text/engine/looks/plain.d.ts +146 -0
- package/dist/components/text/engine/looks/plain.d.ts.map +1 -0
- package/dist/components/text/engine/looks/plain.js +104 -0
- package/dist/components/text/fonts/bebas-neue.outline.d.ts +3 -0
- package/dist/components/text/fonts/bebas-neue.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/bebas-neue.outline.js +4 -0
- package/dist/components/text/fonts/bebas-neue.strokes.d.ts +3 -0
- package/dist/components/text/fonts/bebas-neue.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/bebas-neue.strokes.js +4 -0
- package/dist/components/text/fonts/index.d.ts +1 -1
- package/dist/components/text/fonts/index.d.ts.map +1 -1
- package/dist/components/text/fonts/index.js +15 -1
- package/dist/components/text/fonts/inter.outline.d.ts +3 -0
- package/dist/components/text/fonts/inter.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/inter.outline.js +4 -0
- package/dist/components/text/fonts/inter.strokes.d.ts +3 -0
- package/dist/components/text/fonts/inter.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/inter.strokes.js +4 -0
- package/dist/components/text/fonts/lora.outline.d.ts +3 -0
- package/dist/components/text/fonts/lora.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/lora.outline.js +4 -0
- package/dist/components/text/fonts/lora.strokes.d.ts +3 -0
- package/dist/components/text/fonts/lora.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/lora.strokes.js +4 -0
- package/dist/components/text/fonts/montserrat.outline.d.ts +3 -0
- package/dist/components/text/fonts/montserrat.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/montserrat.outline.js +4 -0
- package/dist/components/text/fonts/montserrat.strokes.d.ts +3 -0
- package/dist/components/text/fonts/montserrat.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/montserrat.strokes.js +4 -0
- package/dist/components/text/fonts/oswald.outline.d.ts +3 -0
- package/dist/components/text/fonts/oswald.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/oswald.outline.js +4 -0
- package/dist/components/text/fonts/oswald.strokes.d.ts +3 -0
- package/dist/components/text/fonts/oswald.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/oswald.strokes.js +4 -0
- package/dist/components/text/fonts/playfair-display.outline.d.ts +3 -0
- package/dist/components/text/fonts/playfair-display.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/playfair-display.outline.js +4 -0
- package/dist/components/text/fonts/playfair-display.strokes.d.ts +3 -0
- package/dist/components/text/fonts/playfair-display.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/playfair-display.strokes.js +4 -0
- package/dist/components/text/fonts/roboto.outline.d.ts +3 -0
- package/dist/components/text/fonts/roboto.outline.d.ts.map +1 -0
- package/dist/components/text/fonts/roboto.outline.js +4 -0
- package/dist/components/text/fonts/roboto.strokes.d.ts +3 -0
- package/dist/components/text/fonts/roboto.strokes.d.ts.map +1 -0
- package/dist/components/text/fonts/roboto.strokes.js +4 -0
- package/dist/components/text/index.d.ts +2 -0
- package/dist/components/text/index.d.ts.map +1 -1
- package/dist/components/text/index.js +1 -0
- package/dist/components/text/useTextObject.d.ts +1 -0
- package/dist/components/text/useTextObject.d.ts.map +1 -1
- package/dist/components/text/useTextObject.js +23 -11
- package/dist/components/water/OceanSurface.d.ts.map +1 -1
- package/dist/components/water/OceanSurface.js +5 -1
- package/dist/components/water/types.d.ts +3 -1
- package/dist/components/water/types.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/hooks/useOceanMaterial.d.ts +6 -2
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.js +22 -2
- package/dist/hooks/useOrbitTargetFollow.d.ts +10 -0
- package/dist/hooks/useOrbitTargetFollow.d.ts.map +1 -0
- package/dist/hooks/useOrbitTargetFollow.js +194 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/operations/catalogue/flock.d.ts.map +1 -1
- package/dist/operations/catalogue/flock.js +44 -9
- package/dist/operations/catalogue/inkBloom.d.ts.map +1 -1
- package/dist/operations/catalogue/inkBloom.js +46 -9
- package/dist/operations/catalogue/liquidMetal.d.ts.map +1 -1
- package/dist/operations/catalogue/liquidMetal.js +41 -12
- package/dist/operations/catalogue/particleSwarm.d.ts.map +1 -1
- package/dist/operations/catalogue/particleSwarm.js +29 -9
- package/dist/operations/catalogue/petalPeel.d.ts.map +1 -1
- package/dist/operations/catalogue/petalPeel.js +33 -9
- package/dist/operations/catalogue/portal.d.ts.map +1 -1
- package/dist/operations/catalogue/portal.js +33 -11
- package/dist/operations/catalogue/sandErosion.d.ts.map +1 -1
- package/dist/operations/catalogue/sandErosion.js +36 -14
- package/dist/operations/catalogue/teleport.d.ts.map +1 -1
- package/dist/operations/catalogue/teleport.js +43 -12
- package/dist/operations/catalogue/unweave.d.ts.map +1 -1
- package/dist/operations/catalogue/unweave.js +34 -15
- package/dist/operations/catalogue/voxelize.d.ts.map +1 -1
- package/dist/operations/catalogue/voxelize.js +37 -10
- package/dist/shaders/glsl/terrainCore.glsl.d.ts +18 -3
- package/dist/shaders/glsl/terrainCore.glsl.d.ts.map +1 -1
- package/dist/shaders/glsl/terrainCore.glsl.js +42 -21
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +36 -11
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -1
- package/dist/shaders/ocean/OceanSurfaceMaterial.js +96 -5
- package/dist/triggers/engine.d.ts +1 -1
- package/dist/triggers/engine.d.ts.map +1 -1
- package/dist/triggers/engine.js +3 -0
- package/dist/triggers/hosts/actions.d.ts.map +1 -1
- package/dist/triggers/hosts/actions.js +3 -1
- package/dist/triggers/hosts/interactions.d.ts.map +1 -1
- package/dist/triggers/hosts/interactions.js +1 -1
- package/dist/triggers/hosts/timelineCues.js +1 -1
- package/dist/triggers/kinds/change.d.ts +4 -0
- package/dist/triggers/kinds/change.d.ts.map +1 -0
- package/dist/triggers/kinds/change.js +50 -0
- package/dist/triggers/kinds/index.d.ts +1 -0
- package/dist/triggers/kinds/index.d.ts.map +1 -1
- package/dist/triggers/kinds/index.js +1 -0
- package/dist/utils/CameraSingleton.d.ts +4 -0
- package/dist/utils/CameraSingleton.d.ts.map +1 -1
- package/dist/utils/CameraSingleton.js +4 -0
- package/dist/utils/deviceTier.d.ts +2 -0
- package/dist/utils/deviceTier.d.ts.map +1 -0
- package/dist/utils/deviceTier.js +16 -0
- package/dist/utils/environmentDrawOrder.d.ts +23 -0
- package/dist/utils/environmentDrawOrder.d.ts.map +1 -0
- package/dist/utils/environmentDrawOrder.js +22 -0
- package/dist/utils/pickProxy.d.ts +11 -0
- package/dist/utils/pickProxy.d.ts.map +1 -0
- package/dist/utils/pickProxy.js +36 -0
- package/dist/utils/shapes.d.ts +4 -0
- package/dist/utils/shapes.d.ts.map +1 -1
- package/dist/utils/shapes.js +4 -1
- package/dist/utils/terrainUniforms.d.ts +7 -0
- package/dist/utils/terrainUniforms.d.ts.map +1 -1
- package/dist/utils/terrainUniforms.js +15 -2
- package/dist/utils/textShape.d.ts +24 -0
- package/dist/utils/textShape.d.ts.map +1 -0
- package/dist/utils/textShape.js +102 -0
- package/package.json +2 -2
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { useThree } from '@react-three/fiber';
|
|
4
|
+
import { PerformanceMonitor } from '@react-three/drei';
|
|
5
|
+
import { isMobileDevice } from '../utils/deviceTier.js';
|
|
6
|
+
/**
|
|
7
|
+
* Render resolution that follows the frame rate. Mount inside <Canvas>.
|
|
8
|
+
*
|
|
9
|
+
* The terrain (and most of what makes the environment expensive) costs per PIXEL:
|
|
10
|
+
* textures and noise octaves in the fragment shader. Pixel ratio is therefore the
|
|
11
|
+
* biggest single lever — 1.5 is 2.25x the pixels of 1, and a phone's 3 is 9x.
|
|
12
|
+
*
|
|
13
|
+
* - Ceiling: the canvas's configured dpr, capped at MOBILE_MAX_DPR on phones and
|
|
14
|
+
* tablets, where the device ratio is 2-3 and the GPU is a fraction of a desktop's.
|
|
15
|
+
* - Under load: drei's PerformanceMonitor averages the frame rate and steps the
|
|
16
|
+
* ratio down while it stays under ~50 fps, and back up when there is room.
|
|
17
|
+
* After a few flip-flops it freezes where it is, so a scene sitting on the edge
|
|
18
|
+
* does not oscillate between sharp and soft.
|
|
19
|
+
* - Floor: half the ceiling, never below 0.6 — softer, never mush.
|
|
20
|
+
* - Warm-up: the monitor starts WARMUP_MS after mount. Loading a scene compiles
|
|
21
|
+
* shaders and packs textures, and those stalls used to burn the flip-flop
|
|
22
|
+
* budget in the first seconds, freezing the ratio below the ceiling for the
|
|
23
|
+
* whole session (seen in the studio: stuck at 1.42 of 1.5 at a steady 60 fps).
|
|
24
|
+
*/
|
|
25
|
+
const WARMUP_MS = 4000;
|
|
26
|
+
export const MOBILE_MAX_DPR = 1.5;
|
|
27
|
+
const round2 = (v) => Math.round(v * 100) / 100;
|
|
28
|
+
const AdaptiveResolution = ({ max }) => {
|
|
29
|
+
const setDpr = useThree((s) => s.setDpr);
|
|
30
|
+
const ceiling = useMemo(() => {
|
|
31
|
+
const device = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;
|
|
32
|
+
const configured = Array.isArray(max) ? max[1] : (max ?? device);
|
|
33
|
+
return isMobileDevice() ? Math.min(configured, MOBILE_MAX_DPR) : configured;
|
|
34
|
+
}, [max]);
|
|
35
|
+
const floor = Math.max(0.6, ceiling * 0.5);
|
|
36
|
+
const frozen = useRef(false);
|
|
37
|
+
const [watching, setWatching] = useState(false);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
frozen.current = false;
|
|
40
|
+
setDpr(ceiling);
|
|
41
|
+
setWatching(false);
|
|
42
|
+
const t = setTimeout(() => setWatching(true), WARMUP_MS);
|
|
43
|
+
return () => clearTimeout(t);
|
|
44
|
+
}, [ceiling, setDpr]);
|
|
45
|
+
if (!watching)
|
|
46
|
+
return null;
|
|
47
|
+
return (_jsx(PerformanceMonitor
|
|
48
|
+
// 60 Hz: below 45 fps step down, above 55 step up. Not tighter: the
|
|
49
|
+
// studio's own main-thread work makes a GPU-idle frame rate wander
|
|
50
|
+
// between 55 and 60, and a 58 threshold pinned the ratio low for good.
|
|
51
|
+
, {
|
|
52
|
+
// 60 Hz: below 45 fps step down, above 55 step up. Not tighter: the
|
|
53
|
+
// studio's own main-thread work makes a GPU-idle frame rate wander
|
|
54
|
+
// between 55 and 60, and a 58 threshold pinned the ratio low for good.
|
|
55
|
+
bounds: (refresh) => (refresh > 100 ? [70, 100] : [45, 55]), flipflops: 3, onChange: ({ factor }) => {
|
|
56
|
+
if (frozen.current)
|
|
57
|
+
return;
|
|
58
|
+
setDpr(round2(floor + (ceiling - floor) * factor));
|
|
59
|
+
}, onFallback: () => { frozen.current = true; } }));
|
|
60
|
+
};
|
|
61
|
+
export default AdaptiveResolution;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CameraController.d.ts","sourceRoot":"","sources":["../../src/components/CameraController.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAQ7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"CameraController.d.ts","sourceRoot":"","sources":["../../src/components/CameraController.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAQ7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,UAAU,qBAAsB,SAAQ,gBAAgB;IACpD,QAAQ,EAAE,WAAW,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;CAC/C;AAGD,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4H5D,CAAC;AACF,eAAe,gBAAgB,CAAC"}
|
|
@@ -7,6 +7,8 @@ import { cameraManager } from '../utils/CameraSingleton.js';
|
|
|
7
7
|
import { usePathAnimation } from '../hooks/usePathAnimation.js';
|
|
8
8
|
import { OrbitControls } from "@react-three/drei";
|
|
9
9
|
import { useRuntimeSettings } from '../hooks/useRuntimeSettings.js';
|
|
10
|
+
import { orbitAngleLimits } from "@3driseai/3drise-core";
|
|
11
|
+
import { useOrbitTargetFollow } from '../hooks/useOrbitTargetFollow.js';
|
|
10
12
|
export const CameraController = ({ enableAutoAnimation = true, animationDuration = 1, animationEase = "power2.out", settings, onObjectReady, onObjectDispose, onControlsReady, onControlsDispose, }) => {
|
|
11
13
|
// Authored camera + any applied action patch ('camera').
|
|
12
14
|
settings = useRuntimeSettings('camera', settings);
|
|
@@ -19,8 +21,11 @@ export const CameraController = ({ enableAutoAnimation = true, animationDuration
|
|
|
19
21
|
const controls = controlsRef.current;
|
|
20
22
|
if (!controls)
|
|
21
23
|
return;
|
|
24
|
+
cameraManager.setControls(controls);
|
|
22
25
|
onControlsReady && onControlsReady(controls);
|
|
23
26
|
return () => {
|
|
27
|
+
if (cameraManager.getControls() === controls)
|
|
28
|
+
cameraManager.setControls(null);
|
|
24
29
|
onControlsDispose && onControlsDispose(controls);
|
|
25
30
|
};
|
|
26
31
|
}, [controlsRef.current]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
@@ -59,15 +64,27 @@ export const CameraController = ({ enableAutoAnimation = true, animationDuration
|
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
}, [position, orientation]);
|
|
67
|
+
// The stored orbit point is applied only when it (or the object choice) changes: a
|
|
68
|
+
// followed object or a pan moves the live point, and an unrelated edit (a speed, a
|
|
69
|
+
// limit) must not snap it back.
|
|
70
|
+
const appliedTarget = useRef('');
|
|
62
71
|
// Sync controls config changes imperatively via ref (after initial mount)
|
|
63
72
|
useEffect(() => {
|
|
64
73
|
const orbitControls = controlsRef.current;
|
|
65
74
|
if (!orbitControls)
|
|
66
75
|
return;
|
|
67
76
|
orbitControls.enabled = controls.enabled;
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
// Orbiting an object: the follow hook owns the target, and panning is off
|
|
78
|
+
// (a pan would pull the orbit point off the object).
|
|
79
|
+
const lookingAtObject = !!controls.targetObject?.id;
|
|
80
|
+
const targetKey = `${controls.target?.join(',')}|${controls.targetObject?.id ?? ''}|${controls.targetObject?.node ?? ''}`;
|
|
81
|
+
if (!lookingAtObject && targetKey !== appliedTarget.current)
|
|
82
|
+
orbitControls.target.set(controls.target[0], controls.target[1], controls.target[2]);
|
|
83
|
+
appliedTarget.current = targetKey;
|
|
84
|
+
orbitControls.enablePan = lookingAtObject ? false : controls.enablePan;
|
|
70
85
|
orbitControls.enableRotate = controls.enableRotate;
|
|
86
|
+
// ClipPlayer holds zoom off while a wheel-driven sequence runs (it re-asserts every frame).
|
|
87
|
+
orbitControls.enableZoom = controls.enableZoom !== false;
|
|
71
88
|
orbitControls.autoRotate = controls.autoRotate;
|
|
72
89
|
orbitControls.autoRotateSpeed = controls.autoRotateSpeed;
|
|
73
90
|
orbitControls.zoomSpeed = controls.zoomSpeed;
|
|
@@ -75,11 +92,11 @@ export const CameraController = ({ enableAutoAnimation = true, animationDuration
|
|
|
75
92
|
orbitControls.rotateSpeed = controls.rotateSpeed;
|
|
76
93
|
orbitControls.minDistance = controls.minDistance;
|
|
77
94
|
orbitControls.maxDistance = controls.maxDistance;
|
|
78
|
-
|
|
79
|
-
orbitControls
|
|
80
|
-
orbitControls.minAzimuthAngle = controls.minAzimuthAngle ?? -Infinity;
|
|
81
|
-
orbitControls.maxAzimuthAngle = controls.maxAzimuthAngle ?? Infinity;
|
|
95
|
+
// Saved limits may be null (once ±Infinity): the full range then.
|
|
96
|
+
Object.assign(orbitControls, orbitAngleLimits(controls));
|
|
82
97
|
}, [controls]);
|
|
98
|
+
// Look at a scene object (orbit target) and / or travel with one (follow).
|
|
99
|
+
useOrbitTargetFollow(controlsRef, controls.targetObject, controls.followObject, () => isInAnimatedTransition.current || isAnimating() || isPathAnimating(), controls.enabled !== false, controls);
|
|
83
100
|
// Sync camera projection settings from state
|
|
84
101
|
useEffect(() => {
|
|
85
102
|
const cam = cameraRef.current;
|
|
@@ -117,6 +134,6 @@ export const CameraController = ({ enableAutoAnimation = true, animationDuration
|
|
|
117
134
|
const ic = initialControls.current;
|
|
118
135
|
return _jsx(OrbitControls, { ref: controlsRef, makeDefault: true, enabled: ic.enabled,
|
|
119
136
|
// target={new Vector3(...ic.target)}
|
|
120
|
-
enablePan: ic.enablePan, enableRotate: ic.enableRotate, autoRotate: ic.autoRotate, autoRotateSpeed: ic.autoRotateSpeed, zoomSpeed: ic.zoomSpeed, panSpeed: ic.panSpeed, rotateSpeed: ic.rotateSpeed, minDistance: ic.minDistance, maxDistance: ic.maxDistance,
|
|
137
|
+
enablePan: ic.targetObject?.id ? false : ic.enablePan, enableRotate: ic.enableRotate, enableZoom: ic.enableZoom !== false, autoRotate: ic.autoRotate, autoRotateSpeed: ic.autoRotateSpeed, zoomSpeed: ic.zoomSpeed, panSpeed: ic.panSpeed, rotateSpeed: ic.rotateSpeed, minDistance: ic.minDistance, maxDistance: ic.maxDistance, ...orbitAngleLimits(ic) });
|
|
121
138
|
};
|
|
122
139
|
export default CameraController;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EffectsGenerator.d.ts","sourceRoot":"","sources":["../../src/components/EffectsGenerator.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"EffectsGenerator.d.ts","sourceRoot":"","sources":["../../src/components/EffectsGenerator.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAsCtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC3D,QAAQ,EAAE,wBAAwB,CAAC;IACnC,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,mGAAmG;IACnG,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,0FAA0F;IAC1F,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,qFAAqF;IACrF,SAAS,CAAC,EAAE,eAAe,CAAC;CAC/B;AAGD,QAAA,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA2DrD,CAAC;AACF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { Box3, Sphere } from 'three';
|
|
4
|
+
import PickVolume from './PickVolume.js';
|
|
4
5
|
import MoleculesEffect from './effects/MoleculesEffect.js';
|
|
5
6
|
import ShockwaveEffect from './effects/ShockwaveEffect.js';
|
|
6
7
|
import AuraEffect from './effects/AuraEffect.js';
|
|
@@ -52,44 +53,48 @@ const EffectsGenerator = ({ settings, object, id, keyframes, mouseMove, onObject
|
|
|
52
53
|
const ready = { onObjectReady, onObjectDispose };
|
|
53
54
|
// Every effect takes the domain drivers: live drag, keyframes and pointer bindings.
|
|
54
55
|
const driven = { id, keyframes, mouseMove };
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
56
|
+
// A standalone effect is hit on its unit sphere (boundingRadius 1), never on its sparse points; a hosted one is hit through its host.
|
|
57
|
+
return object ? effect() : _jsx(PickVolume, { radius: boundingRadius * 1.05, children: effect() });
|
|
58
|
+
function effect() {
|
|
59
|
+
switch (config.type) {
|
|
60
|
+
case 'molecules': return _jsx(MoleculesEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
61
|
+
case 'shockwave': return _jsx(ShockwaveEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
62
|
+
case 'aura': return _jsx(AuraEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
63
|
+
case 'dataStream': return _jsx(DataStreamEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
64
|
+
case 'constellation': return _jsx(ConstellationEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
65
|
+
case 'hologram': return _jsx(HologramEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
66
|
+
case 'portal': return _jsx(PortalEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
67
|
+
case 'dnaHelix': return _jsx(DnaHelixEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
68
|
+
case 'orb': return _jsx(OrbEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
69
|
+
case 'lightning': return _jsx(LightningEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
70
|
+
case 'aurora': return _jsx(AuroraEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
71
|
+
case 'forcefield': return _jsx(ForcefieldEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
72
|
+
case 'neuralNetwork': return _jsx(NeuralNetworkEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
73
|
+
case 'blackHole': return _jsx(BlackHoleEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
74
|
+
case 'iceCrystals': return _jsx(IceCrystalsEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
75
|
+
case 'smokePlume': return _jsx(SmokePlumeEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
76
|
+
case 'volumetricFog': return _jsx(VolumetricFogEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
77
|
+
case 'smokeRing': return _jsx(SmokeRingEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
78
|
+
case 'fire': return _jsx(Fire, { hostRef: object, config: config, ...driven, ...ready });
|
|
79
|
+
case 'flares': return _jsx(Flares, { hostRef: object, boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
80
|
+
case 'sparklesBurst': return _jsx(SparklesBurst, { boundingRadius: boundingRadius, config: config, ...driven });
|
|
81
|
+
case 'bubbles': return _jsx(Bubbles, { boundingRadius: boundingRadius, config: config, ...driven });
|
|
82
|
+
case 'glyphs': return _jsx(Glyphs, { boundingRadius: boundingRadius, config: config, ...driven });
|
|
83
|
+
case 'smokeRibbon': return _jsx(SmokeRibbon, { config: config, boundingRadius: boundingRadius, ...driven, ...ready });
|
|
84
|
+
case 'fieldLines': return _jsx(FieldLinesEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
85
|
+
case 'strangeAttractor': return _jsx(StrangeAttractorEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
86
|
+
case 'harmonicShell': return _jsx(HarmonicShellEffect, { boundingRadius: boundingRadius, config: config, ...driven, ...ready });
|
|
87
|
+
case 'galaxy': return _jsx(GalaxyEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
88
|
+
case 'fireflySwarm': return _jsx(FireflySwarmEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
89
|
+
case 'murmuration': return _jsx(MurmurationEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
90
|
+
case 'planetaryRings': return _jsx(PlanetaryRingsEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
91
|
+
case 'waterCaustics': return _jsx(WaterCausticsEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
92
|
+
case 'iceHalo': return _jsx(IceHaloEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
93
|
+
case 'fallingLeaves': return _jsx(FallingLeavesEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
94
|
+
case 'lichtenberg': return _jsx(LichtenbergEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
95
|
+
case 'dandelionSeeds': return _jsx(DandelionSeedsEffect, { boundingRadius: boundingRadius, config: config, hasHost: !!object, ...driven, ...ready });
|
|
96
|
+
default: return null;
|
|
97
|
+
}
|
|
93
98
|
}
|
|
94
99
|
};
|
|
95
100
|
export default EffectsGenerator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeometryShape.d.ts","sourceRoot":"","sources":["../../src/components/GeometryShape.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"GeometryShape.d.ts","sourceRoot":"","sources":["../../src/components/GeometryShape.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAK5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQjH,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnC,KAAK,QAAQ,GAAG;IACZ,IAAI,EAAE,MAAM,CAAC;CAChB,GAAG;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,YAAY,CAAC;CAC3B,GAAG;IACA,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,EAAE,EAAE,CAAC;CAChB,GAAG;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,YAAY,CAAC;IACxB,QAAQ,EAAE,EAAE,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACvD,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AA6CD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,CAUhG;AA4BD,wBAAgB,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,YAAY,CAyBpG;AACD,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAiC/E;AACD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAiB9F;AACD,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAgC7F;AACD,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,GAAG,YAAY,CAS9D;AACD,wBAAgB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,EAAE,CAKnE;AACD,wBAAgB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,EAAE,EAAE,CAkBnD;AACD,wBAAgB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,EAAE,EAAE,CAKnD;AACD,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,GAAG,EAAE,EAAE,CAuBzF;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG;IAC7F,SAAS,EAAE,YAAY,CAAC;IACxB,QAAQ,EAAE,EAAE,EAAE,CAAC;CAClB,CAoCJ;AACD,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,CAAC,EAAE,UAAU,GAAG,QAAQ,CAkBxE;AAMD,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAA8B,EAAE,KAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,EAAE,iBAAiB,+BA2BpL;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAY,EAAE,QAAQ,EAAE,EAAE;IACnD,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB,GAQ2E,GAAG,CACtF"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { useObjectReady } from '../hooks/useObjectReady.js';
|
|
4
4
|
import { EdgesGeometry, WireframeGeometry, Mesh, MeshBasicMaterial, Raycaster, Vector3, DoubleSide, } from 'three';
|
|
5
5
|
import { buildSegmentQuadGeometry } from '@3driseai/3drise-core';
|
|
6
6
|
import { shapeGenerators } from '../utils/shapes.js';
|
|
7
|
+
import { DEFAULT_TEXT_SHAPE_FONT, loadOutlineFont } from '../utils/textShape.js';
|
|
7
8
|
import PointCloud from './PointCloud.js';
|
|
8
9
|
/**
|
|
9
10
|
* World-space half-thickness of a line ribbon at `lineWidth: 1`. Line modes are
|
|
@@ -34,13 +35,32 @@ function normalizeModeConfig(config) {
|
|
|
34
35
|
...(config || {}),
|
|
35
36
|
};
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The text shape's font loads lazily: bumps once per font when it has landed, so the geometry rebuilds. Always
|
|
40
|
+
* waits on the load (an inlined font can land in the microtask between the render that started it and this
|
|
41
|
+
* effect, so "already loaded" here does not mean the geometry above was built with it).
|
|
42
|
+
*/
|
|
43
|
+
function useTextShapeFont(cfg) {
|
|
44
|
+
const font = cfg.type === 'text' ? (cfg.font ?? DEFAULT_TEXT_SHAPE_FONT) : null;
|
|
45
|
+
const [tick, setTick] = useState(0);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (font === null)
|
|
48
|
+
return;
|
|
49
|
+
let dead = false;
|
|
50
|
+
loadOutlineFont(font).then(() => { if (!dead)
|
|
51
|
+
setTick((t) => t + 1); });
|
|
52
|
+
return () => { dead = true; };
|
|
53
|
+
}, [font]);
|
|
54
|
+
return font === null ? 0 : tick;
|
|
55
|
+
}
|
|
37
56
|
export function useShapeGeometry(options) {
|
|
38
57
|
const safeOptions = useMemo(() => normalizeShapeConfig(options), [options]);
|
|
39
58
|
const key = JSON.stringify(safeOptions);
|
|
59
|
+
const fontTick = useTextShapeFont(safeOptions);
|
|
40
60
|
const geometry = useMemo(() => {
|
|
41
61
|
const generator = shapeGenerators[safeOptions.type] ?? shapeGenerators.box;
|
|
42
62
|
return generator(safeOptions);
|
|
43
|
-
}, [safeOptions.type, key]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
63
|
+
}, [safeOptions.type, key, fontTick]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
44
64
|
useEffect(() => () => geometry.dispose(), [geometry]);
|
|
45
65
|
return geometry;
|
|
46
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MoonDisc.d.ts","sourceRoot":"","sources":["../../src/components/MoonDisc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"MoonDisc.d.ts","sourceRoot":"","sources":["../../src/components/MoonDisc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAG1D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAKvE,MAAM,WAAW,aAAa;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AA+ED,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAoDrC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -4,6 +4,7 @@ import * as THREE from 'three';
|
|
|
4
4
|
import { useFrame } from '@react-three/fiber';
|
|
5
5
|
import { useCloudSun } from '../hooks/useCloudSun.js';
|
|
6
6
|
import { resolveMoon } from '../utils/skyMoon.js';
|
|
7
|
+
import { sunSystemLive } from '../animationsV2/sunSystemLive.js';
|
|
7
8
|
/**
|
|
8
9
|
* The moon in the sky, for either sky renderer.
|
|
9
10
|
*
|
|
@@ -114,7 +115,7 @@ const MoonDisc = ({ timeSettings, skySettings, size = 1 }) => {
|
|
|
114
115
|
const dist = far * 0.9;
|
|
115
116
|
mesh.position.copy(camera.position).addScaledVector(m.direction, dist);
|
|
116
117
|
mesh.quaternion.copy(camera.quaternion);
|
|
117
|
-
const radius = dist * Math.tan(THREE.MathUtils.degToRad(MOON_ANGULAR_DIAMETER_DEG * size) / 2);
|
|
118
|
+
const radius = dist * Math.tan(THREE.MathUtils.degToRad(MOON_ANGULAR_DIAMETER_DEG * (sunSystemLive.moonSize ?? size)) / 2);
|
|
118
119
|
mesh.scale.setScalar(radius * SPAN);
|
|
119
120
|
// Sun direction in the quad's frame, so the disc is lit from where the sun is.
|
|
120
121
|
scratch.q.copy(camera.quaternion).invert();
|
|
@@ -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":"AAoBA,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,EAA2C,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACzI,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;AAkBF,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8IzC,CAAC;AACF,eAAe,UAAU,CAAC"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useMemo } from "react";
|
|
3
3
|
import CustomPrimitive from "./CustomPrimitive.js";
|
|
4
4
|
import CreatedObject from "./CreatedObject.js";
|
|
5
|
-
import Text3D from './Text3D.js';
|
|
6
|
-
import Text2D from './Text2D.js';
|
|
7
5
|
import PathRenderer from './PathRenderer.js';
|
|
8
6
|
import GalleryLayout from './GalleryLayout.js';
|
|
9
7
|
import EffectsGenerator from './EffectsGenerator.js';
|
|
@@ -20,7 +18,7 @@ import LayoutInstances from "./LayoutInstances.js";
|
|
|
20
18
|
import { useRuntimeSettings } from "../hooks/useRuntimeSettings.js";
|
|
21
19
|
import { usePresentedVisibility } from "../operations/usePresentedVisibility.js";
|
|
22
20
|
import { SELF_MANAGED_MATERIAL } from "../constants.js";
|
|
23
|
-
import { LAYOUT_CAPABLE_TYPES, getObjectLayoutSupport, normalizeObjectLayout, isGenerativeParticlesConfig
|
|
21
|
+
import { LAYOUT_CAPABLE_TYPES, getObjectLayoutSupport, normalizeObjectLayout, isGenerativeParticlesConfig } from "@3driseai/3drise-core";
|
|
24
22
|
// Slots after the first render with no ready callbacks: one object reports once.
|
|
25
23
|
const NO_READY = {};
|
|
26
24
|
// A point light's shadow is six extra renders; only slot 0 keeps it. Cached per settings
|
|
@@ -47,9 +45,7 @@ const GroupWithChildren = ({ createdObject, children, onObjectReady, onObjectDis
|
|
|
47
45
|
const isGroup = createdObject.type === 'group';
|
|
48
46
|
// Generative particle objects own their shaders, like effects do.
|
|
49
47
|
const selfManagedMaterial = SELF_MANAGED_MATERIAL.has(createdObject.type)
|
|
50
|
-
|| (createdObject.type === 'particles' && isGenerativeParticlesConfig(createdObject.config))
|
|
51
|
-
// The animated text looks own their shaders; the legacy 2d / 3d text (same object type) keeps its material.
|
|
52
|
-
|| (createdObject.type === 'text' && isTextObjectConfig(createdObject.config));
|
|
48
|
+
|| (createdObject.type === 'particles' && isGenerativeParticlesConfig(createdObject.config));
|
|
53
49
|
return (_jsxs(CreatedObject, { createdObject: createdObject, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose, handleObjectClick: handleObjectClick, shouldApply3driseMaterial: !isGroup && !selfManagedMaterial, children: [!isGroup && renderObject(createdObject, handleObjectClick), children.map(childNode => (_jsx(ObjectNode, { node: childNode, handleObjectClick: handleObjectClick, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose }, childNode.objectId)))] }, createdObject.id));
|
|
54
50
|
};
|
|
55
51
|
const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick }) => {
|
|
@@ -95,15 +91,8 @@ const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick })
|
|
|
95
91
|
// handleObjectClick={handleObjectClick}
|
|
96
92
|
// />
|
|
97
93
|
// ),
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (isTextObjectConfig(obj.config))
|
|
101
|
-
return (_jsx(TextGenerator, { createdObject: obj, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose }));
|
|
102
|
-
const renderMode = obj.config?.renderMode ?? 'bitmap';
|
|
103
|
-
return (_jsx(_Fragment, { children: renderMode === 'text3d'
|
|
104
|
-
? _jsx(Text3D, { textSettings: obj, ...relabel(obj) })
|
|
105
|
-
: _jsx(Text2D, { textSettings: obj, ...relabel(obj) }) }));
|
|
106
|
-
},
|
|
94
|
+
// Text looks (config.type: plain, handwriting, neonTube, …) render through TextGenerator.
|
|
95
|
+
text: (obj, onObjectReady) => (_jsx(TextGenerator, { createdObject: obj, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose })),
|
|
107
96
|
particles: (obj, onObjectReady) => {
|
|
108
97
|
// Generative particle objects (config.type) render through ParticlesGenerator;
|
|
109
98
|
// the legacy shape particles keep their own path.
|
|
@@ -180,7 +169,7 @@ const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick })
|
|
|
180
169
|
const shouldRenderAsGroup = hasChildren || createdObject.type === 'group' || createdObject.type === 'effect';
|
|
181
170
|
const renderedObject = shouldRenderAsGroup
|
|
182
171
|
? _jsx(GroupWithChildren, { createdObject: createdObject, children: children, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose, handleObjectClick: handleObjectClick, renderObject: renderObject })
|
|
183
|
-
: _jsx(CreatedObject, { createdObject: createdObject, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose, handleObjectClick: handleObjectClick, shouldApply3driseMaterial: !
|
|
172
|
+
: _jsx(CreatedObject, { createdObject: createdObject, onObjectReady: onObjectReady, onObjectDispose: onObjectDispose, handleObjectClick: handleObjectClick, shouldApply3driseMaterial: !SELF_MANAGED_MATERIAL.has(createdObject.type), children: renderObject(createdObject) }, createdObject.id);
|
|
184
173
|
// createdObject.effects
|
|
185
174
|
// ? <>
|
|
186
175
|
// {renderObject(createdObject)}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { SkySettings, TimeSettings } from '@3driseai/3drise-core';
|
|
2
|
+
import type { SkySettings, TerrainConfig, TimeSettings } from '@3driseai/3drise-core';
|
|
3
3
|
import type { ObjectReadyProps } from '../types/objectReady';
|
|
4
4
|
import type { OceanWaterSettings } from '@3driseai/3drise-core';
|
|
5
5
|
export interface OceanBuilderProps extends ObjectReadyProps {
|
|
@@ -11,6 +11,9 @@ export interface OceanBuilderProps extends ObjectReadyProps {
|
|
|
11
11
|
timeSettings?: TimeSettings;
|
|
12
12
|
/** Matches SkySystem's sunIntensity, so water brightens with the scene. */
|
|
13
13
|
sunIntensity?: number;
|
|
14
|
+
/** The environment terrain's config: the world ocean's shoreline and the
|
|
15
|
+
* terrain's shadow on the water. Omit (or disabled) for open water. */
|
|
16
|
+
terrain?: TerrainConfig | null;
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Picks the water body for the scene.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OceanBuilder.d.ts","sourceRoot":"","sources":["../../src/components/OceanBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"OceanBuilder.d.ts","sourceRoot":"","sources":["../../src/components/OceanBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAOhE,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACvD;;uEAEmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;IAC9C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;4EACwE;IACxE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAuC7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -23,7 +23,7 @@ import Shore from './water/Shore.js';
|
|
|
23
23
|
* the nearest type, its plane size onto the host, its Y onto the sea level. See
|
|
24
24
|
* `normalizeOcean`.
|
|
25
25
|
*/
|
|
26
|
-
const OceanBuilder = ({ settings, skySettings, timeSettings, sunIntensity, onObjectReady, onObjectDispose, }) => {
|
|
26
|
+
const OceanBuilder = ({ settings, skySettings, timeSettings, sunIntensity, terrain, onObjectReady, onObjectDispose, }) => {
|
|
27
27
|
// Each block against its own source. Merging them through one object would
|
|
28
28
|
// hand the renderer a new config every time a quality slider moved, which
|
|
29
29
|
// rebuilds every clipmap ring.
|
|
@@ -41,6 +41,7 @@ const OceanBuilder = ({ settings, skySettings, timeSettings, sunIntensity, onObj
|
|
|
41
41
|
meshSettings: settings?.meshSettings,
|
|
42
42
|
animations: settings?.animations,
|
|
43
43
|
mouseMove: settings?.mouseMove,
|
|
44
|
+
terrain,
|
|
44
45
|
onObjectReady,
|
|
45
46
|
onObjectDispose,
|
|
46
47
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParticlesGenerator.d.ts","sourceRoot":"","sources":["../../src/components/ParticlesGenerator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ParticlesGenerator.d.ts","sourceRoot":"","sources":["../../src/components/ParticlesGenerator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA+B7D,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC7D,QAAQ,EAAE,2BAA2B,CAAC;IACtC,uFAAuF;IACvF,SAAS,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,0FAA0F;AAC1F,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAyBzD,CAAC;AACF,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
2
|
+
import PickVolume from './PickVolume.js';
|
|
3
|
+
import TidalStreamParticles, { BOUNDS as TIDALSTREAM_BOUNDS } from './particles/TidalStreamParticles.js';
|
|
4
|
+
import BrownianDustParticles, { BOUNDS as BROWNIANDUST_BOUNDS } from './particles/BrownianDustParticles.js';
|
|
5
|
+
import BioluminescentWakeParticles, { BOUNDS as BIOLUMINESCENTWAKE_BOUNDS } from './particles/BioluminescentWakeParticles.js';
|
|
6
|
+
import ElectronOrbitalsParticles, { BOUNDS as ELECTRONORBITALS_BOUNDS } from './particles/ElectronOrbitalsParticles.js';
|
|
7
|
+
import GrinderSparksParticles, { BOUNDS as GRINDERSPARKS_BOUNDS } from './particles/GrinderSparksParticles.js';
|
|
8
|
+
import ChladniSandParticles, { BOUNDS as CHLADNISAND_BOUNDS } from './particles/ChladniSandParticles.js';
|
|
9
|
+
import FaradayPowderParticles, { BOUNDS as FARADAYPOWDER_BOUNDS } from './particles/FaradayPowderParticles.js';
|
|
10
|
+
import NeonRainParticles, { BOUNDS as NEONRAIN_BOUNDS } from './particles/NeonRainParticles.js';
|
|
11
|
+
import MagneticBottleParticles, { BOUNDS as MAGNETICBOTTLE_BOUNDS } from './particles/MagneticBottleParticles.js';
|
|
12
|
+
import ShapeBurstParticles, { BOUNDS as SHAPEBURST_BOUNDS } from './particles/ShapeBurstParticles.js';
|
|
13
|
+
import ShapeFlowParticles, { BOUNDS as SHAPEFLOW_BOUNDS } from './particles/ShapeFlowParticles.js';
|
|
14
|
+
import FireworksParticles from './particles/FireworksParticles.js';
|
|
15
|
+
/** Each variant's pick volume (sim units, × size): the same sphere it culls itself with. */
|
|
16
|
+
const PICK_BOUNDS = {
|
|
17
|
+
tidalStream: TIDALSTREAM_BOUNDS,
|
|
18
|
+
brownianDust: BROWNIANDUST_BOUNDS,
|
|
19
|
+
bioluminescentWake: BIOLUMINESCENTWAKE_BOUNDS,
|
|
20
|
+
electronOrbitals: ELECTRONORBITALS_BOUNDS,
|
|
21
|
+
grinderSparks: GRINDERSPARKS_BOUNDS,
|
|
22
|
+
chladniSand: CHLADNISAND_BOUNDS,
|
|
23
|
+
faradayPowder: FARADAYPOWDER_BOUNDS,
|
|
24
|
+
neonRain: NEONRAIN_BOUNDS,
|
|
25
|
+
magneticBottle: MAGNETICBOTTLE_BOUNDS,
|
|
26
|
+
shapeBurst: SHAPEBURST_BOUNDS,
|
|
27
|
+
shapeFlow: SHAPEFLOW_BOUNDS,
|
|
28
|
+
};
|
|
13
29
|
/** Standalone generative particle objects (type 'particles'), switched on config.type. */
|
|
14
30
|
const ParticlesGenerator = ({ settings, mouseMove, onObjectReady, onObjectDispose }) => {
|
|
15
31
|
const { config, animations } = settings;
|
|
@@ -17,19 +33,25 @@ const ParticlesGenerator = ({ settings, mouseMove, onObjectReady, onObjectDispos
|
|
|
17
33
|
return null;
|
|
18
34
|
const size = config.size ?? 1;
|
|
19
35
|
const ready = { onObjectReady, onObjectDispose, mouseMove };
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
// Hover / click hit the system's volume (its own culling sphere, × size), never a sprite.
|
|
37
|
+
const b = PICK_BOUNDS[config.type] ?? { center: [0, 0, 0], radius: 1.3 };
|
|
38
|
+
return _jsx(PickVolume, { center: [b.center[0] * size, b.center[1] * size, b.center[2] * size], radius: b.radius * size * 1.05, children: variant() });
|
|
39
|
+
function variant() {
|
|
40
|
+
switch (config.type) {
|
|
41
|
+
case 'tidalStream': return _jsx(TidalStreamParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
42
|
+
case 'brownianDust': return _jsx(BrownianDustParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
43
|
+
case 'bioluminescentWake': return _jsx(BioluminescentWakeParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
44
|
+
case 'electronOrbitals': return _jsx(ElectronOrbitalsParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
45
|
+
case 'grinderSparks': return _jsx(GrinderSparksParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
46
|
+
case 'chladniSand': return _jsx(ChladniSandParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
47
|
+
case 'faradayPowder': return _jsx(FaradayPowderParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
48
|
+
case 'neonRain': return _jsx(NeonRainParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
49
|
+
case 'magneticBottle': return _jsx(MagneticBottleParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
50
|
+
case 'shapeBurst': return _jsx(ShapeBurstParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
51
|
+
case 'shapeFlow': return _jsx(ShapeFlowParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
52
|
+
case 'fireworks': return _jsx(FireworksParticles, { id: settings.id, size: size, config: config, animations: animations, ...ready });
|
|
53
|
+
default: return null;
|
|
54
|
+
}
|
|
33
55
|
}
|
|
34
56
|
};
|
|
35
57
|
export default ParticlesGenerator;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface PickVolumeProps {
|
|
3
|
+
/** Sphere centre and radius in world units of the parent (already multiplied by the object's size). */
|
|
4
|
+
center?: [number, number, number];
|
|
5
|
+
radius: number;
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Hover / click land on one invisible sphere over a generative object's volume, never on what it draws: the
|
|
10
|
+
* sprites of a particle system live on the GPU (the CPU attributes are seeds, not positions), an effect's points
|
|
11
|
+
* are sparse, and a user who clicks a cloud means the cloud. The children are taken out of raycasting as they
|
|
12
|
+
* appear (a build can add meshes after mount), so the sphere is the only hit target. Its geometry also gives the
|
|
13
|
+
* selection gizmo a true bounding box.
|
|
14
|
+
*/
|
|
15
|
+
declare const PickVolume: React.FC<PickVolumeProps>;
|
|
16
|
+
export default PickVolume;
|
|
17
|
+
//# sourceMappingURL=PickVolume.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PickVolume.d.ts","sourceRoot":"","sources":["../../src/components/PickVolume.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAK1D,MAAM,WAAW,eAAe;IAC5B,uGAAuG;IACvG,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAWzC,CAAC;AACF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
import { useFrame } from '@react-three/fiber';
|
|
4
|
+
import { pickSphere, stopRaycast } from '../utils/pickProxy.js';
|
|
5
|
+
/**
|
|
6
|
+
* Hover / click land on one invisible sphere over a generative object's volume, never on what it draws: the
|
|
7
|
+
* sprites of a particle system live on the GPU (the CPU attributes are seeds, not positions), an effect's points
|
|
8
|
+
* are sparse, and a user who clicks a cloud means the cloud. The children are taken out of raycasting as they
|
|
9
|
+
* appear (a build can add meshes after mount), so the sphere is the only hit target. Its geometry also gives the
|
|
10
|
+
* selection gizmo a true bounding box.
|
|
11
|
+
*/
|
|
12
|
+
const PickVolume = ({ center = [0, 0, 0], radius, children }) => {
|
|
13
|
+
const inner = useRef(null);
|
|
14
|
+
const proxy = useMemo(() => pickSphere(), []);
|
|
15
|
+
useEffect(() => () => { proxy.geometry.dispose(); proxy.material.dispose(); }, [proxy]);
|
|
16
|
+
useFrame(() => { if (inner.current)
|
|
17
|
+
stopRaycast(inner.current); });
|
|
18
|
+
return (_jsxs("group", { children: [_jsx("primitive", { object: proxy, position: center, scale: [radius, radius, radius] }), _jsx("group", { ref: inner, children: children })] }));
|
|
19
|
+
};
|
|
20
|
+
export default PickVolume;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneBuilder.d.ts","sourceRoot":"","sources":["../../src/components/SceneBuilder.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SceneBuilder.d.ts","sourceRoot":"","sources":["../../src/components/SceneBuilder.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,WAAW,EAA0B,MAAM,oBAAoB,CAAC;AAGjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAWxE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAM7D,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG;IACzE;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5C,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,oEAAoE;IACpE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,qFAAqF;IACrF,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,YAAY;IAfd;;;OAGG;mBACY,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;IAC3C,mFAAmF;uBAChE,KAAK,CAAC,SAAS;IAClC,oEAAoE;SAC/D,OAAO;IACZ,qFAAqF;eAC1E,OAAO,EAAE;IACpB,2EAA2E;eAChE,MAAM;qCA4LnB,CAAC;AAIH,eAAe,YAAY,CAAC"}
|