@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
|
@@ -1,283 +1,102 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* useInteraction.
|
|
2
|
+
* useInteraction — runs an object's interactions.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* An interaction (core `Interaction`) is a trigger plus three kinds of reaction,
|
|
5
|
+
* run in this order:
|
|
6
|
+
*
|
|
7
|
+
* effects operations on their targets, through the shared operations runtime
|
|
8
|
+
* (../operations) — a triggered interaction toggles an operation that
|
|
9
|
+
* can be undone, and applies one that can't. 'self' = the object the
|
|
10
|
+
* interaction is on.
|
|
11
|
+
* animations play / pause / stop / toggle a clip or a sequence (ClipsRuntime).
|
|
12
|
+
* play starts from the beginning, or resumes if paused; toggle plays
|
|
13
|
+
* forward, then back — "back" is the opposite of a sequence's own
|
|
14
|
+
* reverse.
|
|
15
|
+
* actions apply / revert / toggle an action (SceneActions; its own effects
|
|
16
|
+
* run through the same runtime).
|
|
9
17
|
*/
|
|
10
|
-
import { useCallback, useRef } from 'react';
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const { animateCamera } = useCameraAnimation({
|
|
32
|
-
autoAnimate: false,
|
|
33
|
-
defaultDuration: 1,
|
|
34
|
-
defaultEase: "power2.out"
|
|
35
|
-
});
|
|
36
|
-
const { moveToFront, zoomToFrame, restoreOriginalTransform, restoreCamera } = useFrameAnimations(cameraSettings);
|
|
37
|
-
const { vanishObject, restoreVanishedObject, animateGlowEffect, removeGlow, isVanished, isGlowing, glowingObjects, vanishedObjects, } = useObjectEffects();
|
|
38
|
-
// ===========================================================================
|
|
39
|
-
// UTILITY: Resolve Target Objects
|
|
40
|
-
// ===========================================================================
|
|
41
|
-
const resolveTargets = useCallback((interaction, currentRef) => {
|
|
42
|
-
const { targetIds, targetMode } = interaction;
|
|
43
|
-
// If no targetIds specified, return current object only
|
|
44
|
-
if (!targetIds || targetIds.length === 0) {
|
|
45
|
-
return [currentRef];
|
|
46
|
-
}
|
|
47
|
-
const targetRefs = [];
|
|
48
|
-
// Add current object if mode is 'add'
|
|
49
|
-
if (targetMode === 'add') {
|
|
50
|
-
targetRefs.push(currentRef);
|
|
51
|
-
}
|
|
52
|
-
// Lookup targets from scene
|
|
53
|
-
targetIds.forEach(id => {
|
|
54
|
-
const obj = findById(id);
|
|
55
|
-
if (obj) {
|
|
56
|
-
targetRefs.push(obj);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
return targetRefs.length > 0 ? targetRefs : [currentRef];
|
|
18
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
19
|
+
import { SceneActions } from '@3driseai/3drise-core';
|
|
20
|
+
import ClipsRuntime from '../animationsV2/ClipsRuntime.js';
|
|
21
|
+
import { clipMap } from '../animationsV2/sequenceUtils.js';
|
|
22
|
+
import { runEffect } from '../operations/runtime.js';
|
|
23
|
+
import { useOperationsRuntime } from '../operations/useOperationsRuntime.js';
|
|
24
|
+
export function useInteraction({ cameraSettings, sequences = [], clips = [], actionSequences = [], }) {
|
|
25
|
+
// The scene's operation tools (camera, bring-to-front…) for the shared runtime.
|
|
26
|
+
useOperationsRuntime(cameraSettings);
|
|
27
|
+
// Toggle state: animation ids whose last toggle went "forward".
|
|
28
|
+
const toggledRef = useRef(new Set());
|
|
29
|
+
const clipsById = useMemo(() => clipMap(clips), [clips]);
|
|
30
|
+
/** First trigger → forward (false), next → back (true), … per key. */
|
|
31
|
+
const nextIsBack = useCallback((key) => {
|
|
32
|
+
const toggled = toggledRef.current;
|
|
33
|
+
const back = toggled.has(key);
|
|
34
|
+
if (back)
|
|
35
|
+
toggled.delete(key);
|
|
36
|
+
else
|
|
37
|
+
toggled.add(key);
|
|
38
|
+
return back;
|
|
60
39
|
}, []);
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// it makes that interaction's animations and actions two-state. Animations play
|
|
66
|
-
// forward then reversed; actions apply then revert (their patches are removed).
|
|
67
|
-
const triggerAnimations = useCallback((animationIds, toggle = false) => {
|
|
68
|
-
if (!animationIds || animationIds.length === 0)
|
|
40
|
+
// ---------------------------------------------------------------- run
|
|
41
|
+
const executeInteraction = useCallback((params) => {
|
|
42
|
+
const { interaction, ref } = params;
|
|
43
|
+
if (!interaction?.enabled)
|
|
69
44
|
return;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
45
|
+
// 1. Effects — each on its own targets.
|
|
46
|
+
for (const effect of interaction.effects ?? [])
|
|
47
|
+
runEffect(effect, 'trigger', ref);
|
|
48
|
+
// 2. Animations.
|
|
49
|
+
for (const a of interaction.animations ?? []) {
|
|
50
|
+
if (a.kind === 'clip') {
|
|
51
|
+
const clip = clipsById.get(a.ref);
|
|
52
|
+
if (!clip)
|
|
53
|
+
continue;
|
|
54
|
+
if (a.command === 'pause')
|
|
55
|
+
ClipsRuntime.pause(clip.id);
|
|
56
|
+
else if (a.command === 'stop')
|
|
57
|
+
ClipsRuntime.stop(clip.id);
|
|
58
|
+
else if (a.command === 'toggle')
|
|
59
|
+
ClipsRuntime.play(clip, { reverse: nextIsBack(`clip:${clip.id}`) });
|
|
60
|
+
else if (ClipsRuntime.isActive(clip.id) && !ClipsRuntime.isPlaying(clip.id) && ClipsRuntime.getTime(clip.id) < clip.duration)
|
|
61
|
+
ClipsRuntime.resume(clip.id);
|
|
62
|
+
else
|
|
63
|
+
ClipsRuntime.play(clip, { from: 0 });
|
|
77
64
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// ===========================================================================
|
|
90
|
-
const triggerActions = useCallback((actionIds, toggle = false) => {
|
|
91
|
-
if (!actionIds || actionIds.length === 0)
|
|
92
|
-
return;
|
|
93
|
-
actionIds.forEach(actionId => {
|
|
94
|
-
const action = actionSequences.find(a => a.id === actionId);
|
|
95
|
-
if (!action)
|
|
96
|
-
return;
|
|
97
|
-
if (toggle)
|
|
98
|
-
SceneActions.toggleAction(action);
|
|
99
|
-
else
|
|
100
|
-
SceneActions.applyAction(action);
|
|
101
|
-
});
|
|
102
|
-
}, [actionSequences]);
|
|
103
|
-
// ===========================================================================
|
|
104
|
-
// UTILITY: Execute Single Operation
|
|
105
|
-
// ===========================================================================
|
|
106
|
-
const executeOperation = useCallback(async (operation, ref, createdObject, textureUrl) => {
|
|
107
|
-
if (!operation || operation === 'none')
|
|
108
|
-
return;
|
|
109
|
-
const defaultDuration = 1.0;
|
|
110
|
-
const defaultEase = "power2.out";
|
|
111
|
-
const defaultDistance = 2.0;
|
|
112
|
-
const isCurrentlySelected = currentAnimatedRef.current !== null;
|
|
113
|
-
const isSameObject = currentAnimatedRef.current?.uuid === ref.uuid;
|
|
114
|
-
switch (operation) {
|
|
115
|
-
case 'vanish': {
|
|
116
|
-
if (isVanished(ref.uuid)) {
|
|
117
|
-
restoreVanishedObject(ref, defaultDuration, defaultEase);
|
|
65
|
+
else {
|
|
66
|
+
const seq = sequences.find(s => s.id === a.ref);
|
|
67
|
+
if (!seq)
|
|
68
|
+
continue;
|
|
69
|
+
if (a.command === 'pause')
|
|
70
|
+
ClipsRuntime.pauseSequence(seq.id);
|
|
71
|
+
else if (a.command === 'stop')
|
|
72
|
+
ClipsRuntime.stopSequence(seq.id);
|
|
73
|
+
else if (a.command === 'toggle') {
|
|
74
|
+
const back = nextIsBack(`seq:${seq.id}`);
|
|
75
|
+
ClipsRuntime.playSequence(seq, clipsById, { reverse: back ? !seq.reverse : seq.reverse });
|
|
118
76
|
}
|
|
119
|
-
else {
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
case 'glow': {
|
|
125
|
-
if (isGlowing(ref.uuid)) {
|
|
126
|
-
removeGlow(ref);
|
|
77
|
+
else if (ClipsRuntime.isSequenceActive(seq.id) && !ClipsRuntime.isSequencePlaying(seq.id) && ClipsRuntime.getSequenceProgress(seq.id) < 1) {
|
|
78
|
+
ClipsRuntime.resumeSequence(seq.id);
|
|
127
79
|
}
|
|
128
80
|
else {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
case 'focus': {
|
|
134
|
-
animateCamera({}, defaultDuration, defaultEase, createdObject.meshSettings.position);
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
case 'moveToFront': {
|
|
138
|
-
// Toggle: if clicking the same object, restore it
|
|
139
|
-
if (isCurrentlySelected && isSameObject) {
|
|
140
|
-
restoreOriginalTransform(currentAnimatedRef.current, {
|
|
141
|
-
duration: defaultDuration,
|
|
142
|
-
ease: defaultEase
|
|
143
|
-
});
|
|
144
|
-
currentAnimatedRef.current = null;
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
// Restore previous object if different
|
|
148
|
-
if (isCurrentlySelected && !isSameObject) {
|
|
149
|
-
restoreOriginalTransform(currentAnimatedRef.current, {
|
|
150
|
-
duration: defaultDuration,
|
|
151
|
-
ease: defaultEase
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
// Apply new animation
|
|
155
|
-
moveToFront(ref, {
|
|
156
|
-
distance: defaultDistance,
|
|
157
|
-
scale: [6, 4],
|
|
158
|
-
duration: defaultDuration,
|
|
159
|
-
ease: defaultEase
|
|
160
|
-
});
|
|
161
|
-
currentAnimatedRef.current = ref;
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
case 'zoom': {
|
|
165
|
-
// Toggle: if clicking the same object, restore camera
|
|
166
|
-
if (isCurrentlySelected && isSameObject) {
|
|
167
|
-
restoreCamera({ duration: defaultDuration, ease: defaultEase });
|
|
168
|
-
currentAnimatedRef.current = null;
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
// Restore previous camera if different object
|
|
172
|
-
if (isCurrentlySelected && !isSameObject) {
|
|
173
|
-
restoreCamera({ duration: defaultDuration, ease: defaultEase });
|
|
174
|
-
}
|
|
175
|
-
// Apply new zoom
|
|
176
|
-
zoomToFrame(ref, {
|
|
177
|
-
distance: defaultDistance,
|
|
178
|
-
duration: defaultDuration,
|
|
179
|
-
ease: defaultEase
|
|
180
|
-
});
|
|
181
|
-
currentAnimatedRef.current = ref;
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
case 'playAnimation':
|
|
185
|
-
// Handled by triggerAnimations
|
|
186
|
-
break;
|
|
187
|
-
case 'displayImage': {
|
|
188
|
-
if (!textureUrl)
|
|
189
|
-
break;
|
|
190
|
-
let applier;
|
|
191
|
-
let meshWithMap = null;
|
|
192
|
-
ref.traverse((child) => {
|
|
193
|
-
if (!applier && typeof child.userData?.applyTexture === 'function') {
|
|
194
|
-
applier = child.userData.applyTexture;
|
|
195
|
-
}
|
|
196
|
-
else if (!meshWithMap && child.material) {
|
|
197
|
-
meshWithMap = child;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
if (applier) {
|
|
201
|
-
applier(textureUrl);
|
|
81
|
+
// From the start edge of its own direction.
|
|
82
|
+
const total = ClipsRuntime.getSequenceDuration(seq.id);
|
|
83
|
+
ClipsRuntime.playSequence(seq, clipsById, { from: seq.reverse && total > 0 ? total : 0 });
|
|
202
84
|
}
|
|
203
|
-
else if (meshWithMap) {
|
|
204
|
-
const name = textureUrl.split('/').pop()?.split('.')[0] || `texture-${Date.now()}`;
|
|
205
|
-
try {
|
|
206
|
-
const loaded = await texturesManager.loadTexture(name, textureUrl, 'images');
|
|
207
|
-
const mat = meshWithMap.material;
|
|
208
|
-
mat.map = loaded;
|
|
209
|
-
mat.needsUpdate = true;
|
|
210
|
-
}
|
|
211
|
-
catch (err) {
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
break;
|
|
215
85
|
}
|
|
216
|
-
case 'toggle':
|
|
217
|
-
// Modifier for animationIds/actionIds — handled in executeInteraction.
|
|
218
|
-
break;
|
|
219
|
-
case 'create':
|
|
220
|
-
case 'update':
|
|
221
|
-
case 'delete':
|
|
222
|
-
case 'loadProject':
|
|
223
|
-
break;
|
|
224
86
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
restoreCamera,
|
|
237
|
-
]);
|
|
238
|
-
// ===========================================================================
|
|
239
|
-
// UTILITY: Execute Multiple Operations
|
|
240
|
-
// ===========================================================================
|
|
241
|
-
const executeOperations = useCallback((operations, ref, createdObject, textureUrl) => {
|
|
242
|
-
if (!operations || operations.length === 0)
|
|
243
|
-
return;
|
|
244
|
-
operations.forEach(operation => {
|
|
245
|
-
executeOperation(operation, ref, createdObject, textureUrl);
|
|
246
|
-
});
|
|
247
|
-
}, [executeOperation]);
|
|
248
|
-
// ===========================================================================
|
|
249
|
-
// MAIN: Execute Interaction
|
|
250
|
-
// ===========================================================================
|
|
251
|
-
const executeInteraction = useCallback((params) => {
|
|
252
|
-
const { interaction, ref, createdObject } = params;
|
|
253
|
-
if (!interaction.enabled)
|
|
254
|
-
return;
|
|
255
|
-
let textureUrl = undefined;
|
|
256
|
-
if (interaction.operations?.includes('displayImage')) {
|
|
257
|
-
textureUrl = ref.userData?.url;
|
|
87
|
+
// 3. Actions.
|
|
88
|
+
for (const a of interaction.actions ?? []) {
|
|
89
|
+
const action = actionSequences.find(x => x.id === a.ref);
|
|
90
|
+
if (!action)
|
|
91
|
+
continue;
|
|
92
|
+
if (a.command === 'revert')
|
|
93
|
+
SceneActions.revertAction(action);
|
|
94
|
+
else if (a.command === 'toggle')
|
|
95
|
+
SceneActions.toggleAction(action);
|
|
96
|
+
else
|
|
97
|
+
SceneActions.applyAction(action);
|
|
258
98
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
// 2. Execute operations on each target
|
|
262
|
-
targets.forEach(targetRef => {
|
|
263
|
-
// Find the createdObject for this target (if different from original)
|
|
264
|
-
// For now, use the original createdObject for position data
|
|
265
|
-
executeOperations(interaction.operations, targetRef, createdObject, textureUrl);
|
|
266
|
-
});
|
|
267
|
-
// 3. Trigger animations and actions ('toggle' makes both two-state)
|
|
268
|
-
const toggle = interaction.operations?.includes('toggle') ?? false;
|
|
269
|
-
triggerAnimations(interaction.animationIds, toggle);
|
|
270
|
-
triggerActions(interaction.actionIds, toggle);
|
|
271
|
-
}, [resolveTargets, executeOperations, triggerAnimations, triggerActions]);
|
|
272
|
-
// ===========================================================================
|
|
273
|
-
// RETURN
|
|
274
|
-
// ===========================================================================
|
|
275
|
-
return {
|
|
276
|
-
executeInteraction,
|
|
277
|
-
// Expose refs for context to share
|
|
278
|
-
currentAnimatedRef,
|
|
279
|
-
glowingObjects,
|
|
280
|
-
vanishedObjects,
|
|
281
|
-
};
|
|
99
|
+
}, [clipsById, sequences, actionSequences, nextIsBack]);
|
|
100
|
+
return { executeInteraction };
|
|
282
101
|
}
|
|
283
102
|
export default useInteraction;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useObjectAnimation.d.ts","sourceRoot":"","sources":["../../src/hooks/useObjectAnimation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"useObjectAnimation.d.ts","sourceRoot":"","sources":["../../src/hooks/useObjectAnimation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,UAAU,yBAAyB;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,wBAAyB,SAAQ,0BAA0B,EAAE,2BAA2B;CACjG;AAGD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,gBAAgB,qBAAqB,GAAG,IAAI,EAAE,iBAAiB,OAAO,EAAE,UAAS,yBAA8B,EAAE,SAAS,cAAc,KAAG,wBAAwB,GAAG,IAcxM,CAAC"}
|
|
@@ -3,7 +3,6 @@ import { useFrame } from '@react-three/fiber';
|
|
|
3
3
|
import { findById } from '@3driseai/3drise-core';
|
|
4
4
|
import { useContinuousEffects } from "./useContinuousEffects.js";
|
|
5
5
|
import { useMouseMove } from "./useInteractionEffects.js";
|
|
6
|
-
import { useSequenceAnimation } from "./useSequenceAnimation.js";
|
|
7
6
|
/**
|
|
8
7
|
* Drive every continuous animation for one scene object.
|
|
9
8
|
*
|
|
@@ -28,6 +27,5 @@ export const useObjectAnimation = (objectSettings, animateMaterial, options = {}
|
|
|
28
27
|
const source = object ?? fallbackRef;
|
|
29
28
|
const continuousResult = useContinuousEffects(objectSettings, { enabled, animateMaterial, hovered }, source);
|
|
30
29
|
const mouseMoveResult = useMouseMove(objectSettings, { enabled, animateMaterial }, source);
|
|
31
|
-
useSequenceAnimation(objectSettings?.id, source);
|
|
32
30
|
return { ...continuousResult, ...mouseMoveResult };
|
|
33
31
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOceanMaterial.d.ts","sourceRoot":"","sources":["../../src/hooks/useOceanMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"useOceanMaterial.d.ts","sourceRoot":"","sources":["../../src/hooks/useOceanMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAI7E,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE7E;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,uBAAuB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;gFAE4E;IAC5E,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACtF;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B;0DACsD;IACtD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;CAChD;AAED,wBAAgB,gBAAgB,CAAC,EAC7B,EAAE,EACF,MAAM,EACN,OAAO,EACP,WAAW,EACX,YAAY,EACZ,YAAgB,EAChB,OAAO,GACV,EAAE,uBAAuB,GAAG,mBAAmB,CAkE/C;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { useFrame } from '@react-three/fiber';
|
|
3
3
|
import { useCloudSun } from './useCloudSun.js';
|
|
4
|
-
import { useLiveTransitionEvents } from './useLiveTransitionEvents.js';
|
|
5
4
|
import { OCEAN_LIVE_KEY } from './useOceanLive.js';
|
|
6
5
|
import { OceanSurfaceMaterial } from '../shaders/ocean/OceanSurfaceMaterial.js';
|
|
7
6
|
import { applySunUniforms } from '../utils/cloudUniforms.js';
|
|
@@ -36,10 +35,6 @@ export function useOceanMaterial({ id, config, quality, skySettings, timeSetting
|
|
|
36
35
|
root.userData[OCEAN_LIVE_KEY] = liveHandle;
|
|
37
36
|
return () => { delete root.userData[OCEAN_LIVE_KEY]; };
|
|
38
37
|
}, [id, liveHandle]);
|
|
39
|
-
// Sequence-authored transitions (`transition.state === 'ocean'`) — shared by
|
|
40
|
-
// both hosts (OceanSurface, WaterBody), the same way the material and the
|
|
41
|
-
// live handle already are.
|
|
42
|
-
useLiveTransitionEvents('ocean', liveConfig, config, rootRef);
|
|
43
38
|
useFrame((state) => {
|
|
44
39
|
const shader = material;
|
|
45
40
|
updateSun();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* An element's settings with any applied action patches laid over them.
|
|
3
3
|
*
|
|
4
4
|
* `state` is the element's action address: its object id, or 'camera' | 'sky' |
|
|
5
|
-
* 'ocean' | 'clouds'. Subscribes to that one element only, so applying an action
|
|
5
|
+
* 'ocean' | 'clouds' | 'terrain'. Subscribes to that one element only, so applying an action
|
|
6
6
|
* re-renders the elements it touches and nothing else. With no patch applied this
|
|
7
7
|
* returns `base` itself — no copy, no identity change.
|
|
8
8
|
*
|
|
@@ -5,7 +5,7 @@ const noopUnsubscribe = () => { };
|
|
|
5
5
|
* An element's settings with any applied action patches laid over them.
|
|
6
6
|
*
|
|
7
7
|
* `state` is the element's action address: its object id, or 'camera' | 'sky' |
|
|
8
|
-
* 'ocean' | 'clouds'. Subscribes to that one element only, so applying an action
|
|
8
|
+
* 'ocean' | 'clouds' | 'terrain'. Subscribes to that one element only, so applying an action
|
|
9
9
|
* re-renders the elements it touches and nothing else. With no patch applied this
|
|
10
10
|
* returns `base` itself — no copy, no identity change.
|
|
11
11
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { FontInfo } from '@3driseai/3drise-core';
|
|
2
2
|
export { AnimationsManager as animationsManager, fontManager } from '@3driseai/3drise-core';
|
|
3
3
|
export * from './types';
|
|
4
4
|
export * from './components';
|
|
5
5
|
export * from './hooks';
|
|
6
6
|
export { createSceneHandle } from './api/sceneHandle';
|
|
7
|
-
export
|
|
7
|
+
export * from './animationsV2';
|
|
8
|
+
export * from './interactions';
|
|
9
|
+
export * from './operations';
|
|
10
|
+
export type { SceneHandle, SceneHandleEvent, SceneHandleEventType, SceneActionInfo, SceneClipInfo, SceneSequenceInfo, ScenePlayOptions, ScenePlayback } from './api/sceneHandle';
|
|
8
11
|
export type { PathAnimationOptions as PathAnimationHookOptions } from './hooks/usePathAnimation';
|
|
9
12
|
export { cameraManager } from './utils/CameraSingleton';
|
|
10
13
|
export { applyAnchorSettings, createCurves, createSunPosition, randomRange, } from './utils/utils3d';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,9 @@ export * from './components/index.js';
|
|
|
8
8
|
export * from './hooks/index.js';
|
|
9
9
|
// External control of a loaded project (ProjectLoader ref / onSceneReady)
|
|
10
10
|
export { createSceneHandle } from './api/sceneHandle.js';
|
|
11
|
+
export * from './animationsV2/index.js';
|
|
12
|
+
export * from './interactions/index.js';
|
|
13
|
+
export * from './operations/index.js';
|
|
11
14
|
// Utils
|
|
12
15
|
export { cameraManager } from './utils/CameraSingleton.js';
|
|
13
16
|
export { applyAnchorSettings, createCurves, createSunPosition, randomRange, } from './utils/utils3d.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interactions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACpF,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { runInteraction, setInteractionRunner, ObjectHoverContext } from './runner.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CreatedObjectSettings, Interaction } from '@3driseai/3drise-core';
|
|
2
|
+
type Runner = (objectId: string, interaction: Interaction) => boolean;
|
|
3
|
+
export declare function setInteractionRunner(next: Runner): () => void;
|
|
4
|
+
/** Run an interaction now. False when no scene is mounted or the object is not there. */
|
|
5
|
+
export declare function runInteraction(objectId: string, interaction: Interaction): boolean;
|
|
6
|
+
export type ObjectHoverHandler = (createdObject: CreatedObjectSettings, ref: any, trigger: 'mouseEnter' | 'mouseLeave') => void;
|
|
7
|
+
export declare const ObjectHoverContext: import("react").Context<ObjectHoverHandler>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/interactions/runner.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEhF,KAAK,MAAM,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC;AAGtE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CAG7D;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAElF;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY,KAAK,IAAI,CAAC;AAChI,eAAO,MAAM,kBAAkB,6CAAiD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Interaction runner + hover bridge
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// runInteraction(objectId, interaction) — run an interaction as if it were
|
|
6
|
+
// triggered (the studio's "Try it"). ObjectsRenderer registers the runner.
|
|
7
|
+
//
|
|
8
|
+
// ObjectHoverContext — ObjectsRenderer hands CreatedObject the hover handler, so
|
|
9
|
+
// 'mouseEnter' / 'mouseLeave' interactions fire without threading a prop through
|
|
10
|
+
// every renderer.
|
|
11
|
+
//
|
|
12
|
+
import { createContext } from 'react';
|
|
13
|
+
let runner = null;
|
|
14
|
+
export function setInteractionRunner(next) {
|
|
15
|
+
runner = next;
|
|
16
|
+
return () => { if (runner === next)
|
|
17
|
+
runner = null; };
|
|
18
|
+
}
|
|
19
|
+
/** Run an interaction now. False when no scene is mounted or the object is not there. */
|
|
20
|
+
export function runInteraction(objectId, interaction) {
|
|
21
|
+
return runner ? runner(objectId, interaction) : false;
|
|
22
|
+
}
|
|
23
|
+
export const ObjectHoverContext = createContext(null);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayImage.d.ts","sourceRoot":"","sources":["../../../src/operations/catalogue/displayImage.ts"],"names":[],"mappings":";AAGA,wBA4BG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { texturesManager } from '@3driseai/3drise-core';
|
|
2
|
+
import { defineOperation } from '../types.js';
|
|
3
|
+
export default defineOperation({
|
|
4
|
+
value: 'displayImage',
|
|
5
|
+
label: 'Show image',
|
|
6
|
+
description: "Show the clicked frame's image on the target",
|
|
7
|
+
multi: false,
|
|
8
|
+
toggles: false,
|
|
9
|
+
usableIn: ['interaction'],
|
|
10
|
+
galleryOnly: true,
|
|
11
|
+
async apply(target, _p, ctx) {
|
|
12
|
+
const url = ctx.self?.userData?.url;
|
|
13
|
+
if (!url)
|
|
14
|
+
return;
|
|
15
|
+
let applier;
|
|
16
|
+
let meshWithMap = null;
|
|
17
|
+
target.traverse((child) => {
|
|
18
|
+
if (!applier && typeof child.userData?.applyTexture === 'function')
|
|
19
|
+
applier = child.userData.applyTexture;
|
|
20
|
+
else if (!meshWithMap && child.material)
|
|
21
|
+
meshWithMap = child;
|
|
22
|
+
});
|
|
23
|
+
if (applier) {
|
|
24
|
+
applier(url);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!meshWithMap)
|
|
28
|
+
return;
|
|
29
|
+
const name = url.split('/').pop()?.split('.')[0] || `texture-${Date.now()}`;
|
|
30
|
+
try {
|
|
31
|
+
const loaded = await texturesManager.loadTexture(name, url, 'images');
|
|
32
|
+
meshWithMap.material.map = loaded;
|
|
33
|
+
meshWithMap.material.needsUpdate = true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// a missing image leaves the target as it was
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fade.d.ts","sourceRoot":"","sources":["../../../src/operations/catalogue/fade.ts"],"names":[],"mappings":";AAMA,wBAoCG"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { gsap } from 'gsap';
|
|
2
|
+
import { defineOperation } from '../types.js';
|
|
3
|
+
import { forEachMaterial } from './materialFx.js';
|
|
4
|
+
const KEY = '__opFade';
|
|
5
|
+
export default defineOperation({
|
|
6
|
+
value: 'fade',
|
|
7
|
+
label: 'Fade out',
|
|
8
|
+
description: 'Fade the targets away (to a set opacity)',
|
|
9
|
+
multi: true,
|
|
10
|
+
toggles: true,
|
|
11
|
+
usableIn: ['interaction', 'action'],
|
|
12
|
+
params: {
|
|
13
|
+
opacity: { type: 'number', label: 'To opacity', default: 0, min: 0, max: 1, step: 0.05, hint: '0 hides the object when the fade ends' },
|
|
14
|
+
duration: { type: 'number', label: 'Duration', default: 1, min: 0, max: 10, step: 0.05, unit: 's' },
|
|
15
|
+
},
|
|
16
|
+
apply(target, p) {
|
|
17
|
+
const to = Number(p.opacity);
|
|
18
|
+
forEachMaterial(target, (mat) => {
|
|
19
|
+
if (!mat.userData[KEY])
|
|
20
|
+
mat.userData[KEY] = { opacity: mat.opacity, transparent: mat.transparent };
|
|
21
|
+
mat.transparent = true;
|
|
22
|
+
mat.needsUpdate = true;
|
|
23
|
+
gsap.killTweensOf(mat, 'opacity');
|
|
24
|
+
gsap.to(mat, {
|
|
25
|
+
opacity: to, duration: Number(p.duration), ease: 'power2.inOut',
|
|
26
|
+
onComplete: () => { if (to <= 0)
|
|
27
|
+
target.visible = false; },
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
revert(target, p) {
|
|
32
|
+
target.visible = true;
|
|
33
|
+
forEachMaterial(target, (mat) => {
|
|
34
|
+
const orig = mat.userData[KEY];
|
|
35
|
+
if (!orig)
|
|
36
|
+
return;
|
|
37
|
+
gsap.killTweensOf(mat, 'opacity');
|
|
38
|
+
gsap.to(mat, {
|
|
39
|
+
opacity: orig.opacity, duration: Number(p.duration), ease: 'power2.inOut',
|
|
40
|
+
onComplete: () => { mat.transparent = orig.transparent; mat.needsUpdate = true; delete mat.userData[KEY]; },
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
});
|