@3driseai/3drise-viewer 0.1.25 → 0.1.26
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 +13 -0
- package/dist/animationsV2/ClipPlayer.d.ts.map +1 -0
- package/dist/animationsV2/ClipPlayer.js +140 -0
- package/dist/animationsV2/ClipsRuntime.d.ts +111 -0
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -0
- package/dist/animationsV2/ClipsRuntime.js +476 -0
- package/dist/animationsV2/appliers.d.ts +16 -0
- package/dist/animationsV2/appliers.d.ts.map +1 -0
- package/dist/animationsV2/appliers.js +204 -0
- package/dist/animationsV2/clipUtils.d.ts +33 -0
- package/dist/animationsV2/clipUtils.d.ts.map +1 -0
- package/dist/animationsV2/clipUtils.js +164 -0
- package/dist/animationsV2/elementSettings.d.ts +15 -0
- package/dist/animationsV2/elementSettings.d.ts.map +1 -0
- package/dist/animationsV2/elementSettings.js +16 -0
- package/dist/animationsV2/index.d.ts +16 -0
- package/dist/animationsV2/index.d.ts.map +1 -0
- package/dist/animationsV2/index.js +12 -0
- package/dist/animationsV2/nodeTracks.d.ts +13 -0
- package/dist/animationsV2/nodeTracks.d.ts.map +1 -0
- package/dist/animationsV2/nodeTracks.js +165 -0
- package/dist/animationsV2/normalize.d.ts +4 -0
- package/dist/animationsV2/normalize.d.ts.map +1 -0
- package/dist/animationsV2/normalize.js +49 -0
- package/dist/animationsV2/sequenceUtils.d.ts +57 -0
- package/dist/animationsV2/sequenceUtils.d.ts.map +1 -0
- package/dist/animationsV2/sequenceUtils.js +120 -0
- package/dist/animationsV2/types.d.ts +95 -0
- package/dist/animationsV2/types.d.ts.map +1 -0
- package/dist/animationsV2/types.js +8 -0
- package/dist/api/sceneHandle.d.ts +56 -17
- package/dist/api/sceneHandle.d.ts.map +1 -1
- package/dist/api/sceneHandle.js +154 -77
- package/dist/components/CameraController.d.ts.map +1 -1
- package/dist/components/CameraController.js +0 -44
- package/dist/components/Clouds.d.ts.map +1 -1
- package/dist/components/Clouds.js +0 -34
- package/dist/components/CreatedObject.d.ts.map +1 -1
- package/dist/components/CreatedObject.js +19 -1
- package/dist/components/EnvironmentManager.js +1 -1
- package/dist/components/ObjectsRenderer.d.ts +4 -1
- package/dist/components/ObjectsRenderer.d.ts.map +1 -1
- package/dist/components/ObjectsRenderer.js +23 -3
- package/dist/components/Ocean.d.ts.map +1 -1
- package/dist/components/Ocean.js +0 -63
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +19 -4
- package/dist/components/SkyController.d.ts.map +1 -1
- package/dist/components/SkyController.js +0 -39
- package/dist/components/Stars.d.ts.map +1 -1
- package/dist/components/Stars.js +3 -47
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
- package/dist/components/terrain/TerrainSurface.js +0 -5
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
- package/dist/components/volumetricClouds/VolumetricCloudsPass.js +0 -6
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -2
- package/dist/hooks/useInteraction.d.ts +6 -7
- package/dist/hooks/useInteraction.d.ts.map +1 -1
- package/dist/hooks/useInteraction.js +87 -268
- package/dist/hooks/useObjectAnimation.d.ts.map +1 -1
- package/dist/hooks/useObjectAnimation.js +0 -2
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.js +0 -5
- package/dist/hooks/useRuntimeSettings.d.ts +1 -1
- package/dist/hooks/useRuntimeSettings.js +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/interactions/index.d.ts +3 -0
- package/dist/interactions/index.d.ts.map +1 -0
- package/dist/interactions/index.js +1 -0
- package/dist/interactions/runner.d.ts +9 -0
- package/dist/interactions/runner.d.ts.map +1 -0
- package/dist/interactions/runner.js +23 -0
- package/dist/operations/catalogue/displayImage.d.ts +3 -0
- package/dist/operations/catalogue/displayImage.d.ts.map +1 -0
- package/dist/operations/catalogue/displayImage.js +39 -0
- package/dist/operations/catalogue/fade.d.ts +3 -0
- package/dist/operations/catalogue/fade.d.ts.map +1 -0
- package/dist/operations/catalogue/fade.js +44 -0
- package/dist/operations/catalogue/focus.d.ts +3 -0
- package/dist/operations/catalogue/focus.d.ts.map +1 -0
- package/dist/operations/catalogue/focus.js +22 -0
- package/dist/operations/catalogue/glow.d.ts +3 -0
- package/dist/operations/catalogue/glow.d.ts.map +1 -0
- package/dist/operations/catalogue/glow.js +49 -0
- package/dist/operations/catalogue/materialFx.d.ts +6 -0
- package/dist/operations/catalogue/materialFx.d.ts.map +1 -0
- package/dist/operations/catalogue/materialFx.js +13 -0
- package/dist/operations/catalogue/moveToFront.d.ts +3 -0
- package/dist/operations/catalogue/moveToFront.d.ts.map +1 -0
- package/dist/operations/catalogue/moveToFront.js +25 -0
- package/dist/operations/catalogue/visibility.d.ts +3 -0
- package/dist/operations/catalogue/visibility.d.ts.map +1 -0
- package/dist/operations/catalogue/visibility.js +24 -0
- package/dist/operations/catalogue/zoom.d.ts +3 -0
- package/dist/operations/catalogue/zoom.d.ts.map +1 -0
- package/dist/operations/catalogue/zoom.js +32 -0
- package/dist/operations/index.d.ts +5 -0
- package/dist/operations/index.d.ts.map +1 -0
- package/dist/operations/index.js +4 -0
- package/dist/operations/registry.d.ts +11 -0
- package/dist/operations/registry.d.ts.map +1 -0
- package/dist/operations/registry.js +21 -0
- package/dist/operations/runtime.d.ts +22 -0
- package/dist/operations/runtime.d.ts.map +1 -0
- package/dist/operations/runtime.js +161 -0
- package/dist/operations/types.d.ts +96 -0
- package/dist/operations/types.d.ts.map +1 -0
- package/dist/operations/types.js +3 -0
- package/dist/operations/useOperationsRuntime.d.ts +3 -0
- package/dist/operations/useOperationsRuntime.d.ts.map +1 -0
- package/dist/operations/useOperationsRuntime.js +31 -0
- package/package.json +2 -2
package/dist/api/sceneHandle.js
CHANGED
|
@@ -3,21 +3,24 @@
|
|
|
3
3
|
// =============================================================================
|
|
4
4
|
//
|
|
5
5
|
// What a developer extending a project gets from <ProjectLoader ref={…} /> or
|
|
6
|
-
// onSceneReady(handle): trigger the project's actions and
|
|
7
|
-
// own UI, and hear when they run.
|
|
6
|
+
// onSceneReady(handle): trigger the project's actions, clips and sequences from
|
|
7
|
+
// their own UI, and hear when they run.
|
|
8
8
|
//
|
|
9
9
|
// scene.current?.actions.toggle('open-door');
|
|
10
|
-
// scene.current?.
|
|
11
|
-
//
|
|
10
|
+
// scene.current?.clips.play('spin'); // one clip, its own loop / yoyo / end
|
|
11
|
+
// scene.current?.sequences.play('intro', { speed: 1.5 });
|
|
12
|
+
// const off = scene.current?.on('animationEnd', (e) => console.log(e.kind, e.key));
|
|
12
13
|
//
|
|
13
|
-
// Addressing (`ref`):
|
|
14
|
-
// copies — prefer it), then its id, then its exact name.
|
|
15
|
-
//
|
|
14
|
+
// Addressing (`ref`): the item's `key` first (stable across renames and project
|
|
15
|
+
// copies — prefer it), then its id, then its exact name. An ambiguous name warns
|
|
16
|
+
// and uses the first match. Clip and sequence keys are separate namespaces.
|
|
16
17
|
//
|
|
17
18
|
// This is a thin layer: object clicks go through the same SceneActions /
|
|
18
|
-
//
|
|
19
|
+
// ClipsRuntime calls, so a button and a click behave identically.
|
|
19
20
|
//
|
|
20
|
-
import {
|
|
21
|
+
import { SceneActions } from '@3driseai/3drise-core';
|
|
22
|
+
import ClipsRuntime from '../animationsV2/ClipsRuntime.js';
|
|
23
|
+
import { clipMap, resolveSequence } from '../animationsV2/sequenceUtils.js';
|
|
21
24
|
function resolve(items, ref, kind) {
|
|
22
25
|
if (!ref)
|
|
23
26
|
return undefined;
|
|
@@ -29,25 +32,146 @@ function resolve(items, ref, kind) {
|
|
|
29
32
|
return byId;
|
|
30
33
|
const byName = items.filter(i => i.name === ref);
|
|
31
34
|
if (byName.length > 1) {
|
|
32
|
-
console.warn(`[3drise] ${byName.length} ${kind}s are named "${ref}"; using the first
|
|
35
|
+
console.warn(`[3drise] ${byName.length} ${kind}s are named "${ref}"; using the first. Address it by its key instead.`);
|
|
33
36
|
}
|
|
34
37
|
if (byName.length === 0) {
|
|
35
|
-
console.warn(`[3drise] No ${kind} "${ref}" in this project. Known: ${items.map(i => i.key
|
|
38
|
+
console.warn(`[3drise] No ${kind} "${ref}" in this project. Known: ${items.map(i => i.key || i.name).join(', ') || 'none'}`);
|
|
36
39
|
}
|
|
37
40
|
return byName[0];
|
|
38
41
|
}
|
|
39
|
-
|
|
40
|
-
return (seq.steps ?? []).reduce((sum, s) => sum + (s.delay || 0) + (s.duration || 0), 0);
|
|
41
|
-
}
|
|
42
|
+
const clamp01 = (n) => Math.min(1, Math.max(0, Number.isFinite(n) ? n : 0));
|
|
42
43
|
/**
|
|
43
|
-
* Build a handle over one project's actions and
|
|
44
|
-
* every call, so the handle stays valid if the project data is replaced.
|
|
44
|
+
* Build a handle over one project's actions, clips and sequences. `getSource` is
|
|
45
|
+
* read on every call, so the handle stays valid if the project data is replaced.
|
|
45
46
|
*/
|
|
46
47
|
export function createSceneHandle(getSource) {
|
|
47
48
|
const actions = () => getSource().actions ?? [];
|
|
48
|
-
const
|
|
49
|
+
const clips = () => getSource().clips ?? [];
|
|
50
|
+
const sequences = () => getSource().sequences ?? [];
|
|
51
|
+
const clipsById = () => clipMap(clips());
|
|
49
52
|
const findAction = (ref) => resolve(actions(), ref, 'action');
|
|
50
|
-
const
|
|
53
|
+
const findClip = (ref) => resolve(clips(), ref, 'clip');
|
|
54
|
+
const findSequence = (ref) => resolve(sequences(), ref, 'sequence');
|
|
55
|
+
const sequenceDuration = (s) => resolveSequence(s, clipsById()).duration;
|
|
56
|
+
const clipControls = {
|
|
57
|
+
list: () => clips().map(c => ({
|
|
58
|
+
id: c.id, key: c.key, name: c.name, description: c.description,
|
|
59
|
+
duration: c.duration, loop: c.loop, yoyo: c.yoyo, endMode: c.endMode,
|
|
60
|
+
playing: ClipsRuntime.isPlaying(c.id),
|
|
61
|
+
})),
|
|
62
|
+
play(ref, options = {}) {
|
|
63
|
+
const c = findClip(ref);
|
|
64
|
+
if (!c)
|
|
65
|
+
return false;
|
|
66
|
+
ClipsRuntime.play(c, {
|
|
67
|
+
speed: options.speed,
|
|
68
|
+
reverse: options.reverse,
|
|
69
|
+
from: options.from !== undefined ? clamp01(options.from) * c.duration : undefined,
|
|
70
|
+
});
|
|
71
|
+
return true;
|
|
72
|
+
},
|
|
73
|
+
pause(ref) {
|
|
74
|
+
const c = findClip(ref);
|
|
75
|
+
if (!c)
|
|
76
|
+
return false;
|
|
77
|
+
ClipsRuntime.pause(c.id);
|
|
78
|
+
return true;
|
|
79
|
+
},
|
|
80
|
+
resume(ref) {
|
|
81
|
+
const c = findClip(ref);
|
|
82
|
+
if (!c)
|
|
83
|
+
return false;
|
|
84
|
+
ClipsRuntime.resume(c.id);
|
|
85
|
+
return true;
|
|
86
|
+
},
|
|
87
|
+
stop(ref) {
|
|
88
|
+
const c = findClip(ref);
|
|
89
|
+
if (!c)
|
|
90
|
+
return false;
|
|
91
|
+
ClipsRuntime.stop(c.id);
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
seek(ref, progress) {
|
|
95
|
+
const c = findClip(ref);
|
|
96
|
+
if (!c)
|
|
97
|
+
return false;
|
|
98
|
+
ClipsRuntime.pose(c, clamp01(progress) * c.duration);
|
|
99
|
+
return true;
|
|
100
|
+
},
|
|
101
|
+
isPlaying(ref) {
|
|
102
|
+
const c = findClip(ref);
|
|
103
|
+
return c ? ClipsRuntime.isPlaying(c.id) : false;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const sequenceControls = {
|
|
107
|
+
list: () => sequences().map(s => ({
|
|
108
|
+
id: s.id, key: s.key, name: s.name, description: s.description,
|
|
109
|
+
duration: sequenceDuration(s), steps: s.steps.length,
|
|
110
|
+
loop: s.loop, yoyo: s.yoyo, reverse: s.reverse, endMode: s.endMode,
|
|
111
|
+
driver: s.driver, autoplay: s.autoplay,
|
|
112
|
+
playing: ClipsRuntime.isSequencePlaying(s.id),
|
|
113
|
+
})),
|
|
114
|
+
play(ref, options = {}) {
|
|
115
|
+
const s = findSequence(ref);
|
|
116
|
+
if (!s)
|
|
117
|
+
return false;
|
|
118
|
+
ClipsRuntime.playSequence(s, clipsById(), {
|
|
119
|
+
speed: options.speed,
|
|
120
|
+
reverse: options.reverse,
|
|
121
|
+
from: options.from !== undefined ? clamp01(options.from) * sequenceDuration(s) : undefined,
|
|
122
|
+
});
|
|
123
|
+
return true;
|
|
124
|
+
},
|
|
125
|
+
pause(ref) {
|
|
126
|
+
const s = findSequence(ref);
|
|
127
|
+
if (!s)
|
|
128
|
+
return false;
|
|
129
|
+
ClipsRuntime.pauseSequence(s.id);
|
|
130
|
+
return true;
|
|
131
|
+
},
|
|
132
|
+
resume(ref) {
|
|
133
|
+
const s = findSequence(ref);
|
|
134
|
+
if (!s)
|
|
135
|
+
return false;
|
|
136
|
+
ClipsRuntime.resumeSequence(s.id);
|
|
137
|
+
return true;
|
|
138
|
+
},
|
|
139
|
+
stop(ref) {
|
|
140
|
+
const s = findSequence(ref);
|
|
141
|
+
if (!s)
|
|
142
|
+
return false;
|
|
143
|
+
ClipsRuntime.stopSequence(s.id);
|
|
144
|
+
return true;
|
|
145
|
+
},
|
|
146
|
+
seek(ref, progress) {
|
|
147
|
+
const s = findSequence(ref);
|
|
148
|
+
if (!s)
|
|
149
|
+
return false;
|
|
150
|
+
const lookup = clipsById();
|
|
151
|
+
ClipsRuntime.poseSequence(s, lookup, clamp01(progress) * resolveSequence(s, lookup).duration);
|
|
152
|
+
return true;
|
|
153
|
+
},
|
|
154
|
+
isPlaying(ref) {
|
|
155
|
+
const s = findSequence(ref);
|
|
156
|
+
return s ? ClipsRuntime.isSequencePlaying(s.id) : false;
|
|
157
|
+
},
|
|
158
|
+
setProgress(ref, progress) {
|
|
159
|
+
const s = findSequence(ref);
|
|
160
|
+
if (!s)
|
|
161
|
+
return false;
|
|
162
|
+
if (ClipsRuntime.isSequenceActive(s.id))
|
|
163
|
+
return ClipsRuntime.setSequenceProgress(s.id, progress);
|
|
164
|
+
const lookup = clipsById();
|
|
165
|
+
const total = resolveSequence(s, lookup).duration;
|
|
166
|
+
const p = clamp01(progress);
|
|
167
|
+
ClipsRuntime.poseSequence(s, lookup, (s.reverse ? 1 - p : p) * total);
|
|
168
|
+
return true;
|
|
169
|
+
},
|
|
170
|
+
getProgress(ref) {
|
|
171
|
+
const s = findSequence(ref);
|
|
172
|
+
return s ? ClipsRuntime.getSequenceProgress(s.id) : 0;
|
|
173
|
+
},
|
|
174
|
+
};
|
|
51
175
|
return {
|
|
52
176
|
actions: {
|
|
53
177
|
list: () => actions().map(a => ({
|
|
@@ -85,56 +209,8 @@ export function createSceneHandle(getSource) {
|
|
|
85
209
|
SceneActions.revertAction(a.id);
|
|
86
210
|
},
|
|
87
211
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
id: s.id,
|
|
91
|
-
name: s.name,
|
|
92
|
-
description: s.description,
|
|
93
|
-
duration: animationDuration(s),
|
|
94
|
-
loop: !!s.loop,
|
|
95
|
-
yoyo: !!s.yoyo,
|
|
96
|
-
playing: AnimationsManager.isSequencePlaying(s.id),
|
|
97
|
-
})),
|
|
98
|
-
play(ref, options = {}) {
|
|
99
|
-
const s = findAnimation(ref);
|
|
100
|
-
if (!s)
|
|
101
|
-
return false;
|
|
102
|
-
AnimationsManager.playSequence(s, { speed: options.speed, reverse: options.reverse });
|
|
103
|
-
return true;
|
|
104
|
-
},
|
|
105
|
-
pause(ref) {
|
|
106
|
-
const s = findAnimation(ref);
|
|
107
|
-
if (!s)
|
|
108
|
-
return false;
|
|
109
|
-
AnimationsManager.pauseSequence(s.id);
|
|
110
|
-
return true;
|
|
111
|
-
},
|
|
112
|
-
resume(ref) {
|
|
113
|
-
const s = findAnimation(ref);
|
|
114
|
-
if (!s)
|
|
115
|
-
return false;
|
|
116
|
-
AnimationsManager.resumeSequence(s.id);
|
|
117
|
-
return true;
|
|
118
|
-
},
|
|
119
|
-
stop(ref) {
|
|
120
|
-
const s = findAnimation(ref);
|
|
121
|
-
if (!s)
|
|
122
|
-
return false;
|
|
123
|
-
AnimationsManager.stopSequence(s.id);
|
|
124
|
-
return true;
|
|
125
|
-
},
|
|
126
|
-
seek(ref, progress) {
|
|
127
|
-
const s = findAnimation(ref);
|
|
128
|
-
if (!s)
|
|
129
|
-
return false;
|
|
130
|
-
AnimationsManager.seekToProgress(s.id, progress);
|
|
131
|
-
return true;
|
|
132
|
-
},
|
|
133
|
-
isPlaying(ref) {
|
|
134
|
-
const s = findAnimation(ref);
|
|
135
|
-
return s ? AnimationsManager.isSequencePlaying(s.id) : false;
|
|
136
|
-
},
|
|
137
|
-
},
|
|
212
|
+
clips: clipControls,
|
|
213
|
+
sequences: sequenceControls,
|
|
138
214
|
on(type, listener) {
|
|
139
215
|
if (type === 'actionApplied' || type === 'actionReverted') {
|
|
140
216
|
return SceneActions.onEvent((e) => {
|
|
@@ -144,17 +220,18 @@ export function createSceneHandle(getSource) {
|
|
|
144
220
|
return;
|
|
145
221
|
const a = actions().find(x => x.id === e.actionId);
|
|
146
222
|
if (a)
|
|
147
|
-
listener({ type, id: a.id, key: a.key, name: a.name });
|
|
223
|
+
listener({ type, kind: 'action', id: a.id, key: a.key, name: a.name });
|
|
148
224
|
});
|
|
149
225
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
226
|
+
const wanted = type === 'animationStart' ? 'start' : type === 'animationEnd' ? 'end' : 'loop';
|
|
227
|
+
return ClipsRuntime.on((e) => {
|
|
228
|
+
if (e.type !== wanted)
|
|
229
|
+
return;
|
|
230
|
+
// Only this project's items — another scene on the page shares the runtime.
|
|
231
|
+
const item = e.kind === 'clip' ? clips().find(c => c.id === e.id) : sequences().find(s => s.id === e.id);
|
|
232
|
+
if (item)
|
|
233
|
+
listener({ type, kind: e.kind, id: item.id, key: item.key, name: item.name });
|
|
234
|
+
});
|
|
158
235
|
},
|
|
159
236
|
};
|
|
160
237
|
}
|
|
@@ -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;
|
|
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;AACzD,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,CA+G5D,CAAC;AACF,eAAe,gBAAgB,CAAC"}
|
|
@@ -4,7 +4,6 @@ import { useEffect, useRef } from 'react';
|
|
|
4
4
|
import { useFrame, useThree } from '@react-three/fiber';
|
|
5
5
|
import { useCameraAnimation } from '../hooks/useCameraAnimation.js';
|
|
6
6
|
import { cameraManager } from '../utils/CameraSingleton.js';
|
|
7
|
-
import { useAnimationEvents } from '../hooks/useAnimationEvents.js';
|
|
8
7
|
import { usePathAnimation } from '../hooks/usePathAnimation.js';
|
|
9
8
|
import { OrbitControls } from "@react-three/drei";
|
|
10
9
|
import { useRuntimeSettings } from '../hooks/useRuntimeSettings.js';
|
|
@@ -103,49 +102,6 @@ export const CameraController = ({ enableAutoAnimation = true, animationDuration
|
|
|
103
102
|
cam.updateProjectionMatrix();
|
|
104
103
|
}
|
|
105
104
|
}, [fov, near, far]);
|
|
106
|
-
// Handle animation events (step-based animations)
|
|
107
|
-
useAnimationEvents({
|
|
108
|
-
onStepStart: (event) => {
|
|
109
|
-
if (event.step?.transitions) {
|
|
110
|
-
const stepDuration = event.step.duration ?? 1; // 0 = instant (actions)
|
|
111
|
-
event.step.transitions.forEach((transition) => {
|
|
112
|
-
const { state, properties, pathId } = transition;
|
|
113
|
-
if (state === 'camera') {
|
|
114
|
-
isInAnimatedTransition.current = true;
|
|
115
|
-
if (pathId) {
|
|
116
|
-
const offset = camera
|
|
117
|
-
? [camera.position.x, camera.position.y, camera.position.z]
|
|
118
|
-
: [0, 0, 0];
|
|
119
|
-
startPathAnimation(pathId, stepDuration, {
|
|
120
|
-
offset,
|
|
121
|
-
applyRotation: false
|
|
122
|
-
});
|
|
123
|
-
transformAnimationProgress.current = 0;
|
|
124
|
-
}
|
|
125
|
-
const startSettings = properties.from ?
|
|
126
|
-
{
|
|
127
|
-
position: properties.from.position,
|
|
128
|
-
// orientation: properties.from.orientation,
|
|
129
|
-
} : {
|
|
130
|
-
position: camera.position,
|
|
131
|
-
// orientation: camera.rotation,
|
|
132
|
-
};
|
|
133
|
-
const targetSettings = properties.to;
|
|
134
|
-
// startSettings.position && camera.position.set(startSettings.position[0], startSettings.position[1], startSettings.position[2]);
|
|
135
|
-
// camera.rotation.set(startSettings.orientation[0], startSettings.orientation[1], startSettings.orientation[2]);
|
|
136
|
-
animateCamera(targetSettings, stepDuration, event.step?.ease, properties.to.target)
|
|
137
|
-
.then(() => {
|
|
138
|
-
isInAnimatedTransition.current = false;
|
|
139
|
-
if (properties.to.target) {
|
|
140
|
-
controlsRef.current?.target.set(properties.to.target[0], properties.to.target[1], properties.to.target[2]);
|
|
141
|
-
}
|
|
142
|
-
;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
105
|
// Frame loop for path animations and mouse handlers
|
|
150
106
|
useFrame((state, delta) => {
|
|
151
107
|
if (isPathAnimating()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Clouds.d.ts","sourceRoot":"","sources":["../../src/components/Clouds.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"Clouds.d.ts","sourceRoot":"","sources":["../../src/components/Clouds.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACjD,QAAQ,EAAE,qBAAqB,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;AAmFD,QAAA,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAoJjC,CAAC;AACF,eAAe,MAAM,CAAC"}
|
|
@@ -4,7 +4,6 @@ import { useRef, useCallback } from 'react';
|
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { useThree, useFrame } from '@react-three/fiber';
|
|
6
6
|
import { useSkySystem } from '../hooks/useSkySystem.js';
|
|
7
|
-
import { useAnimationEvents } from '../hooks/useAnimationEvents.js';
|
|
8
7
|
import { useNumericAnimation } from '../hooks/useNumericAnimation.js';
|
|
9
8
|
import { calculateTimeProgress, applyEasing, gsapEasingMap, interpolateValue, interpolateMouseMoveProperty, } from '@3driseai/3drise-core';
|
|
10
9
|
const CLOUD_COLORS = {
|
|
@@ -142,39 +141,6 @@ const Clouds = ({ settings, timeSettings = defaultTimeSettings, onObjectReady, o
|
|
|
142
141
|
onTimeUpdate: handleTimeUpdate,
|
|
143
142
|
enabled: visible,
|
|
144
143
|
});
|
|
145
|
-
// Legacy sequence-driven `speed`/`scale` anims via `useAnimationEvents`
|
|
146
|
-
useAnimationEvents({
|
|
147
|
-
onStepStart: (event) => {
|
|
148
|
-
if (!event.step?.transitions)
|
|
149
|
-
return;
|
|
150
|
-
for (const transition of event.step.transitions) {
|
|
151
|
-
if (transition.state !== 'clouds' || !meshRef.current)
|
|
152
|
-
continue;
|
|
153
|
-
const toProps = transition.properties.to || {};
|
|
154
|
-
const fromProps = transition.properties.from || {};
|
|
155
|
-
if (toProps.visible !== undefined)
|
|
156
|
-
meshRef.current.visible = toProps.visible;
|
|
157
|
-
const KEYS = ['speed', 'scale'];
|
|
158
|
-
const from = {};
|
|
159
|
-
const to = {};
|
|
160
|
-
for (const k of KEYS) {
|
|
161
|
-
const toVal = toProps[k];
|
|
162
|
-
if (toVal === undefined)
|
|
163
|
-
continue;
|
|
164
|
-
to[k] = toVal;
|
|
165
|
-
const sourceFallback = k === 'speed' ? baseSpeed : scale;
|
|
166
|
-
from[k] = fromProps[k] ?? sourceFallback;
|
|
167
|
-
}
|
|
168
|
-
if (Object.keys(to).length > 0) {
|
|
169
|
-
animateNumeric(from, to, (updated) => {
|
|
170
|
-
numericOverrideRef.current = { ...numericOverrideRef.current, ...updated };
|
|
171
|
-
}, () => {
|
|
172
|
-
numericOverrideRef.current = null;
|
|
173
|
-
}, event.step?.duration);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
144
|
useFrame((state) => {
|
|
179
145
|
const mesh = meshRef.current;
|
|
180
146
|
if (!mesh || !mesh.visible || !mesh.material)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreatedObject.d.ts","sourceRoot":"","sources":["../../src/components/CreatedObject.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CreatedObject.d.ts","sourceRoot":"","sources":["../../src/components/CreatedObject.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAWnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,UAAU,kBAAmB,SAAQ,gBAAgB;IACjD,aAAa,EAAE,qBAAqB,CAAC;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CACpH;AAKD,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsG9C,CAAC;AAEH,eAAe,aAAa,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useEffect, useState, useReducer, memo } from "react";
|
|
2
|
+
import { useRef, useEffect, useState, useReducer, memo, useContext } from "react";
|
|
3
|
+
import { ObjectHoverContext } from "../interactions/runner.js";
|
|
3
4
|
import { ModelMaterialPassContext } from "./ModelMaterialPassContext.js";
|
|
4
5
|
import { DEFAULT_EDGES_SETTINGS } from "@3driseai/3drise-core";
|
|
5
6
|
import { useMaterialApplication } from "../hooks/useMaterialApplication.js";
|
|
@@ -12,11 +13,16 @@ import AnimatedObject from "./AnimatedObject.js";
|
|
|
12
13
|
import { useFrameEffects } from "../hooks/useFrameEffects.js";
|
|
13
14
|
import { useObjectEdges } from "../hooks/useObjectEdges.js";
|
|
14
15
|
import { useObjectReady } from "../hooks/useObjectReady.js";
|
|
16
|
+
/** One hovered part of an object: the intersected mesh (+ instance). */
|
|
17
|
+
const hoverKey = (e) => `${e.object?.uuid}/${e.instanceId ?? ''}`;
|
|
15
18
|
const CreatedObject = memo(({ createdObject, children, shouldApply3driseMaterial = true, onObjectReady, onObjectDispose, handleObjectClick, }) => {
|
|
16
19
|
const isSelected = false;
|
|
17
20
|
// const isSelected = useObjectSelection(createdObject.id);
|
|
18
21
|
// const { handleObjectClick: contextHandleObjectClick } = useSceneClick();
|
|
19
22
|
const meshRef = useRef(null);
|
|
23
|
+
// 'mouseEnter' / 'mouseLeave' interactions (ObjectsRenderer).
|
|
24
|
+
const onHover = useContext(ObjectHoverContext);
|
|
25
|
+
const hoveredPartsRef = useRef(new Set());
|
|
20
26
|
const transformRef = useRef(null);
|
|
21
27
|
// const baseColorRef = useRef<string>(("color" in createdObject.materialSettings && createdObject.materialSettings.color) || '#ffffff');
|
|
22
28
|
// const [hovered, setHovered] = useState(false);
|
|
@@ -67,6 +73,14 @@ const CreatedObject = memo(({ createdObject, children, shouldApply3driseMaterial
|
|
|
67
73
|
// Only handle if this is the actual mesh group, not a child
|
|
68
74
|
if (e.eventObject !== meshRef.current)
|
|
69
75
|
return;
|
|
76
|
+
// R3F fires enter / leave on this group once per hovered DESCENDANT (and per
|
|
77
|
+
// intersection), so a model with overlapping meshes fires several at once.
|
|
78
|
+
// Track the hovered parts and report only the first enter / last leave —
|
|
79
|
+
// otherwise two-state effects (glow, fade…) toggle on and straight back off.
|
|
80
|
+
const wasHovered = hoveredPartsRef.current.size > 0;
|
|
81
|
+
hoveredPartsRef.current.add(hoverKey(e));
|
|
82
|
+
if (!wasHovered)
|
|
83
|
+
onHover?.(createdObject, meshRef.current, 'mouseEnter');
|
|
70
84
|
if (createdObject.type === 'particles' || createdObject.type === 'gallery')
|
|
71
85
|
return;
|
|
72
86
|
// e.stopPropagation();
|
|
@@ -79,6 +93,10 @@ const CreatedObject = memo(({ createdObject, children, shouldApply3driseMaterial
|
|
|
79
93
|
// Only handle if this is the actual mesh group, not a child
|
|
80
94
|
if (e.eventObject !== meshRef.current)
|
|
81
95
|
return;
|
|
96
|
+
hoveredPartsRef.current.delete(hoverKey(e));
|
|
97
|
+
if (hoveredPartsRef.current.size > 0)
|
|
98
|
+
return; // still over another part of this object
|
|
99
|
+
onHover?.(createdObject, meshRef.current, 'mouseLeave');
|
|
82
100
|
if (createdObject.type === 'particles' || createdObject.type === 'gallery')
|
|
83
101
|
return;
|
|
84
102
|
handlePointerLeave();
|
|
@@ -29,7 +29,7 @@ const EnvironmentManager = forwardRef(({ timeSettings, environment, hdrSettings,
|
|
|
29
29
|
// Authored settings + applied action patches (runtime only).
|
|
30
30
|
const sky = useRuntimeSettings('sky', skySettings ?? environment?.sky);
|
|
31
31
|
const clouds = useRuntimeSettings('clouds', cloudsSettings ?? environment?.clouds);
|
|
32
|
-
const terrain = terrainSettings ?? environment?.terrain;
|
|
32
|
+
const terrain = useRuntimeSettings('terrain', terrainSettings ?? environment?.terrain);
|
|
33
33
|
const landscape = landscapeSettings ?? environment?.landscape;
|
|
34
34
|
const ocean = useRuntimeSettings('ocean', oceanSettings ?? environment?.ocean);
|
|
35
35
|
const fog = fogSettings ?? environment?.fog;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ActionSequence,
|
|
1
|
+
import type { ActionSequence, GeneralObjectSettings, CameraState, CreatedObjectSettings } from '@3driseai/3drise-core';
|
|
2
|
+
import type { AnimationClip, AnimationSequence } from '../animationsV2/types';
|
|
2
3
|
import type { ObjectReadyProps } from '../types/objectReady';
|
|
3
4
|
import React from "react";
|
|
4
5
|
import { Object3D } from "three";
|
|
@@ -9,7 +10,9 @@ interface ObjectsRendererProps extends ObjectReadyProps {
|
|
|
9
10
|
createdObjects: CreatedObjectSettings[];
|
|
10
11
|
onObjectsReady?: () => void;
|
|
11
12
|
handleObjectClick?: (object: CreatedObjectSettings, ref: Object3D, event: ThreeEvent<MouseEvent>) => void;
|
|
13
|
+
/** Animations V2 sequences and clips, for interaction triggers. */
|
|
12
14
|
sequences?: AnimationSequence[];
|
|
15
|
+
clips?: AnimationClip[];
|
|
13
16
|
actionSequences?: ActionSequence[];
|
|
14
17
|
}
|
|
15
18
|
declare const ObjectsRenderer: React.FC<ObjectsRendererProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectsRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ObjectsRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"ObjectsRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ObjectsRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,UAAU,oBAAqB,SAAQ,gBAAgB;IACnD,cAAc,EAAE,WAAW,CAAC;IAC5B,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC1G,mEAAmE;IACnE,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;CACtC;AAGD,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4DlD,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { memo, useRef, useCallback, useMemo } from 'react';
|
|
2
|
+
import { memo, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
3
3
|
import { buildObjectTree } from '@3driseai/3drise-core';
|
|
4
4
|
import ObjectNode from './ObjectNode.js';
|
|
5
5
|
import useInteraction from '../hooks/useInteraction.js';
|
|
6
|
+
import { ObjectHoverContext, setInteractionRunner } from '../interactions/runner.js';
|
|
7
|
+
import { findById } from '../utils/sceneQuery.js';
|
|
6
8
|
import { useObjectReady } from '../hooks/useObjectReady.js';
|
|
7
|
-
const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSettings, onObjectsReady, onObjectReady, onObjectDispose, handleObjectClick, sequences = [], actionSequences = [], }) => {
|
|
9
|
+
const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSettings, onObjectsReady, onObjectReady, onObjectDispose, handleObjectClick, sequences = [], clips = [], actionSequences = [], }) => {
|
|
8
10
|
const groupRef = useRef(null);
|
|
9
11
|
const objectsTree = useMemo(() => buildObjectTree(createdObjects), [createdObjects]);
|
|
10
12
|
const readyObjectsCount = useRef(0);
|
|
@@ -32,8 +34,26 @@ const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSet
|
|
|
32
34
|
const { executeInteraction } = useInteraction({
|
|
33
35
|
cameraSettings,
|
|
34
36
|
sequences,
|
|
37
|
+
clips,
|
|
35
38
|
actionSequences,
|
|
36
39
|
});
|
|
40
|
+
// Hover triggers: CreatedObject reports enter / leave through ObjectHoverContext.
|
|
41
|
+
const handleObjectHover = useCallback((createdObject, ref, trigger) => {
|
|
42
|
+
filterInteractionsByEvent(createdObject.actions, trigger).forEach((interaction) => {
|
|
43
|
+
executeInteraction({ interaction, ref, createdObject });
|
|
44
|
+
});
|
|
45
|
+
}, [executeInteraction]);
|
|
46
|
+
// "Try it" in the studio: run an interaction as if its trigger fired.
|
|
47
|
+
const objectsRef = useRef(createdObjects);
|
|
48
|
+
objectsRef.current = createdObjects;
|
|
49
|
+
useEffect(() => setInteractionRunner((objectId, interaction) => {
|
|
50
|
+
const ref = findById(objectId);
|
|
51
|
+
const createdObject = objectsRef.current?.find(o => o.id === objectId);
|
|
52
|
+
if (!ref || !createdObject)
|
|
53
|
+
return false;
|
|
54
|
+
executeInteraction({ interaction, ref, createdObject });
|
|
55
|
+
return true;
|
|
56
|
+
}), [executeInteraction]);
|
|
37
57
|
const handleObjectClickHandler = (createdObject, ref, event) => {
|
|
38
58
|
const clickInteractions = filterInteractionsByEvent(createdObject.actions, "click");
|
|
39
59
|
clickInteractions.forEach((interaction) => {
|
|
@@ -43,7 +63,7 @@ const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSet
|
|
|
43
63
|
handleObjectClick(createdObject, ref, event);
|
|
44
64
|
}
|
|
45
65
|
};
|
|
46
|
-
return (_jsx("group", { ref: groupRef, name: "main-objects", position: generalObjectSettings.meshSettings.position, rotation: generalObjectSettings.meshSettings.rotation, scale: generalObjectSettings.meshSettings.scale, children: objectsTree.map(node => (_jsx(ObjectNode, { node: node, onObjectReady: handleObjectReady, onObjectDispose: handleObjectDispose, handleObjectClick: handleObjectClickHandler }, node.objectId))) }));
|
|
66
|
+
return (_jsx(ObjectHoverContext.Provider, { value: handleObjectHover, children: _jsx("group", { ref: groupRef, name: "main-objects", position: generalObjectSettings.meshSettings.position, rotation: generalObjectSettings.meshSettings.rotation, scale: generalObjectSettings.meshSettings.scale, children: objectsTree.map(node => (_jsx(ObjectNode, { node: node, onObjectReady: handleObjectReady, onObjectDispose: handleObjectDispose, handleObjectClick: handleObjectClickHandler }, node.objectId))) }) }));
|
|
47
67
|
});
|
|
48
68
|
ObjectsRenderer.displayName = 'ObjectsRenderer';
|
|
49
69
|
export default ObjectsRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Ocean.d.ts","sourceRoot":"","sources":["../../src/components/Ocean.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"Ocean.d.ts","sourceRoot":"","sources":["../../src/components/Ocean.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAS7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,MAAM,WAAW,UAAW,SAAQ,gBAAgB;IAChD,QAAQ,EAAE,qBAAqB,CAAC;CACnC;AAGD,QAAA,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA+F/B,CAAC;AACF,eAAe,KAAK,CAAC"}
|
package/dist/components/Ocean.js
CHANGED
|
@@ -6,7 +6,6 @@ import { useFrame } from '@react-three/fiber';
|
|
|
6
6
|
import { useMaterialApplication } from '../hooks/useMaterialApplication.js';
|
|
7
7
|
import { useWaterEnvironment } from '../hooks/useWaterEnvironment.js';
|
|
8
8
|
import { useWaterReflections } from '../hooks/useWaterReflections.js';
|
|
9
|
-
import { useAnimationEvents } from '../hooks/useAnimationEvents.js';
|
|
10
9
|
import { useNumericAnimation } from '../hooks/useNumericAnimation.js';
|
|
11
10
|
import { handleTransformAnimations, handleMaterialAnimations, handleTransformMouseMove, handleMaterialMouseMove, } from '@3driseai/3drise-core';
|
|
12
11
|
const Ocean = ({ settings, onObjectReady, onObjectDispose }) => {
|
|
@@ -34,68 +33,6 @@ const Ocean = ({ settings, onObjectReady, onObjectDispose }) => {
|
|
|
34
33
|
updateFrequency: 1,
|
|
35
34
|
enabled: meshSettings.visible,
|
|
36
35
|
});
|
|
37
|
-
useAnimationEvents({
|
|
38
|
-
onStepStart: (event) => {
|
|
39
|
-
if (!event.step?.transitions)
|
|
40
|
-
return;
|
|
41
|
-
for (const transition of event.step.transitions) {
|
|
42
|
-
if (transition.state !== 'ocean' || !meshRef.current)
|
|
43
|
-
continue;
|
|
44
|
-
const toProps = transition.properties.to || {};
|
|
45
|
-
const fromProps = transition.properties.from || {};
|
|
46
|
-
// visible — update state so JSX visible prop re-renders
|
|
47
|
-
if (toProps.visible !== undefined) {
|
|
48
|
-
setMeshVisible(toProps.visible);
|
|
49
|
-
}
|
|
50
|
-
// numeric uniforms: animate any key in `to` that maps to a shader uniform
|
|
51
|
-
const material = meshRef.current.material;
|
|
52
|
-
const uniforms = material?.uniforms;
|
|
53
|
-
if (!uniforms)
|
|
54
|
-
continue;
|
|
55
|
-
const from = {};
|
|
56
|
-
const to = {};
|
|
57
|
-
for (const key of Object.keys(toProps)) {
|
|
58
|
-
if (key === 'visible')
|
|
59
|
-
continue;
|
|
60
|
-
const toVal = toProps[key];
|
|
61
|
-
if (toVal === undefined)
|
|
62
|
-
continue;
|
|
63
|
-
to[key] = toVal;
|
|
64
|
-
const fromExplicit = fromProps[key];
|
|
65
|
-
if (fromExplicit !== undefined) {
|
|
66
|
-
from[key] = fromExplicit;
|
|
67
|
-
}
|
|
68
|
-
else if (uniforms[key]?.value !== undefined) {
|
|
69
|
-
const liveVal = uniforms[key].value;
|
|
70
|
-
if (typeof liveVal === 'number') {
|
|
71
|
-
from[key] = liveVal;
|
|
72
|
-
}
|
|
73
|
-
else if (liveVal?.toArray) {
|
|
74
|
-
from[key] = liveVal.toArray();
|
|
75
|
-
}
|
|
76
|
-
else if (Array.isArray(liveVal)) {
|
|
77
|
-
from[key] = [...liveVal];
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
from[key] = toVal;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
from[key] = toVal;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (Object.keys(to).length > 0) {
|
|
88
|
-
animateNumeric(from, to, (updated) => {
|
|
89
|
-
uniformOverrideRef.current = { ...uniformOverrideRef.current, ...updated };
|
|
90
|
-
}, () => {
|
|
91
|
-
uniformOverrideRef.current = null;
|
|
92
|
-
if (toProps.visible !== undefined)
|
|
93
|
-
setMeshVisible(null);
|
|
94
|
-
}, event.step?.duration);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
36
|
useFrame((state) => {
|
|
100
37
|
const mesh = meshRef.current;
|
|
101
38
|
if (!mesh?.material || !(meshVisible ?? meshSettings.visible))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneBuilder.d.ts","sourceRoot":"","sources":["../../src/components/SceneBuilder.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,WAAW,EAA0B,MAAM,oBAAoB,CAAC;AAGjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"SceneBuilder.d.ts","sourceRoot":"","sources":["../../src/components/SceneBuilder.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,WAAW,EAA0B,MAAM,oBAAoB,CAAC;AAGjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAW/D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG;IACzE,wGAAwG;IACxG,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC/C,CAAC;AAEF,QAAA,MAAM,YAAY;IAJd,wGAAwG;mBACzF,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;qCAgK7C,CAAC;AAEH,eAAe,YAAY,CAAC"}
|