@3driseai/3drise-viewer 0.1.32 → 0.1.34
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/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +11 -1
- package/dist/animationsV2/animationLive.d.ts +7 -0
- package/dist/animationsV2/animationLive.d.ts.map +1 -0
- package/dist/animationsV2/animationLive.js +26 -0
- package/dist/animationsV2/appliers.d.ts +8 -0
- package/dist/animationsV2/appliers.d.ts.map +1 -1
- package/dist/animationsV2/appliers.js +61 -0
- package/dist/animationsV2/index.d.ts +1 -0
- package/dist/animationsV2/index.d.ts.map +1 -1
- package/dist/animationsV2/index.js +1 -0
- package/dist/components/AnimatedObject.d.ts.map +1 -1
- package/dist/components/AnimatedObject.js +2 -0
- package/dist/components/CameraController.d.ts.map +1 -1
- package/dist/components/CameraController.js +9 -0
- package/dist/components/CreatedObject.d.ts.map +1 -1
- package/dist/components/CreatedObject.js +4 -1
- package/dist/components/GroupMaterialContext.d.ts +25 -0
- package/dist/components/GroupMaterialContext.d.ts.map +1 -0
- package/dist/components/GroupMaterialContext.js +21 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +13 -2
- package/dist/components/ObjectsRenderer.d.ts.map +1 -1
- package/dist/components/ObjectsRenderer.js +26 -19
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +7 -4
- package/dist/components/land/LandPatch.d.ts.map +1 -1
- package/dist/components/land/LandPatch.js +15 -1
- package/dist/hooks/useContinuousEffects.d.ts.map +1 -1
- package/dist/hooks/useContinuousEffects.js +24 -3
- package/dist/hooks/useMaterialApplication.d.ts.map +1 -1
- package/dist/hooks/useMaterialApplication.js +2 -1
- package/dist/hooks/useMaterialUniforms.d.ts +2 -8
- package/dist/hooks/useMaterialUniforms.d.ts.map +1 -1
- package/dist/hooks/useMaterialUniforms.js +18 -6
- package/dist/hooks/useOrbitTargetFollow.d.ts.map +1 -1
- package/dist/hooks/useOrbitTargetFollow.js +6 -4
- package/dist/operations/bake.d.ts +36 -0
- package/dist/operations/bake.d.ts.map +1 -0
- package/dist/operations/bake.js +113 -0
- package/dist/operations/catalogue/physicalHeld.d.ts.map +1 -1
- package/dist/operations/catalogue/physicalHeld.js +6 -0
- package/dist/operations/catalogue/shaderLayers.js +2 -2
- package/dist/operations/catalogue/warmup.d.ts +23 -1
- package/dist/operations/catalogue/warmup.d.ts.map +1 -1
- package/dist/operations/catalogue/warmup.js +200 -12
- package/dist/operations/index.d.ts +3 -1
- package/dist/operations/index.d.ts.map +1 -1
- package/dist/operations/index.js +3 -1
- package/dist/operations/objectEffects.d.ts +15 -1
- package/dist/operations/objectEffects.d.ts.map +1 -1
- package/dist/operations/objectEffects.js +49 -1
- package/dist/operations/runtime.d.ts +17 -9
- package/dist/operations/runtime.d.ts.map +1 -1
- package/dist/operations/runtime.js +71 -18
- package/dist/operations/types.d.ts +5 -0
- package/dist/operations/types.d.ts.map +1 -1
- package/dist/triggers/readiness.d.ts +2 -0
- package/dist/triggers/readiness.d.ts.map +1 -1
- package/dist/triggers/readiness.js +28 -3
- package/dist/utils/stallLog.d.ts +4 -0
- package/dist/utils/stallLog.d.ts.map +1 -0
- package/dist/utils/stallLog.js +88 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClipsRuntime.d.ts","sourceRoot":"","sources":["../../src/animationsV2/ClipsRuntime.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,
|
|
1
|
+
{"version":3,"file":"ClipsRuntime.d.ts","sourceRoot":"","sources":["../../src/animationsV2/ClipsRuntime.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
import { SceneActions, expandMaterialVariant } from '@3driseai/3drise-core';
|
|
43
43
|
import { logTrigger } from '../triggers/log.js';
|
|
44
44
|
import { getAtPath, sampleTrack } from './clipUtils.js';
|
|
45
|
-
import { applyValue, clearApplierCaches, isApplicable, isTargetMounted } from './appliers.js';
|
|
45
|
+
import { applyValue, clearApplierCaches, isApplicable, isTargetMounted, releaseLive } from './appliers.js';
|
|
46
46
|
import { readNodeValue, restoreNodeTrack } from './nodeTracks.js';
|
|
47
47
|
import { cueStatesAt, entryLocalTime, isEntryActive, resolveSequence, cueCommand, clipCueSchedule, firedBetween, } from './sequenceUtils.js';
|
|
48
48
|
/** Longest an autoplaying sequence waits for its targets. */
|
|
@@ -181,6 +181,12 @@ class ClipsRuntime {
|
|
|
181
181
|
*/
|
|
182
182
|
reset() {
|
|
183
183
|
this.dlog('reset', { clips: this.clips.size, sequences: [...this.sequences.values()].map(i => i.seq.name) }, this.caller());
|
|
184
|
+
// effect params a clip was driving live on the effects' controllers, not in settings: hand them back
|
|
185
|
+
const driven = [...this.clips.values()].flatMap(i => i.clip.tracks)
|
|
186
|
+
.concat([...this.sequences.values()].flatMap(i => i.schedule.entries.flatMap(e => e.clip.tracks)));
|
|
187
|
+
for (const t of driven)
|
|
188
|
+
if (!t.node)
|
|
189
|
+
releaseLive(t.state, t.path);
|
|
184
190
|
this.clips.clear();
|
|
185
191
|
this.sequences.clear();
|
|
186
192
|
this.pendingRestore = [];
|
|
@@ -780,6 +786,10 @@ class ClipsRuntime {
|
|
|
780
786
|
restoreNodeTrack(track.state, node, track.path, (path) => this.isDriven(track.state, node, path));
|
|
781
787
|
continue;
|
|
782
788
|
}
|
|
789
|
+
// Live-only values (an effect's param, an animation row's value): the object's own comes back
|
|
790
|
+
// (another driver re-writes it this frame).
|
|
791
|
+
if (releaseLive(track.state, track.path))
|
|
792
|
+
continue;
|
|
783
793
|
// Another driver may still own this property; it re-writes this frame.
|
|
784
794
|
const authored = getAtPath(ctx.getSettings(track.state), track.path);
|
|
785
795
|
if (authored !== undefined)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Vector3Array } from '@3driseai/3drise-core';
|
|
2
|
+
/** `animations.transform.animations.<n>.to` → n (null for any other path). */
|
|
3
|
+
export declare function transformAnimationIndex(path: string): number | null;
|
|
4
|
+
export declare function setAnimationLive(objectId: string, index: number, value: Vector3Array | undefined): void;
|
|
5
|
+
/** The transform runner's reader for one object (undefined = no live values on it). */
|
|
6
|
+
export declare function animationLiveReader(objectId: string | undefined): ((index: number) => Vector3Array | undefined) | undefined;
|
|
7
|
+
//# sourceMappingURL=animationLive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animationLive.d.ts","sourceRoot":"","sources":["../../src/animationsV2/animationLive.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAI1D,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGnE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CASvG;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,CAAC,GAAG,SAAS,CAG3H"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const live = new Map();
|
|
2
|
+
/** `animations.transform.animations.<n>.to` → n (null for any other path). */
|
|
3
|
+
export function transformAnimationIndex(path) {
|
|
4
|
+
const m = /^animations\.transform\.animations\.(\d+)\.to$/.exec(path);
|
|
5
|
+
return m ? Number(m[1]) : null;
|
|
6
|
+
}
|
|
7
|
+
export function setAnimationLive(objectId, index, value) {
|
|
8
|
+
let rows = live.get(objectId);
|
|
9
|
+
if (value === undefined) {
|
|
10
|
+
rows?.delete(index);
|
|
11
|
+
if (rows && !rows.size)
|
|
12
|
+
live.delete(objectId);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!rows) {
|
|
16
|
+
rows = new Map();
|
|
17
|
+
live.set(objectId, rows);
|
|
18
|
+
}
|
|
19
|
+
rows.set(index, value);
|
|
20
|
+
}
|
|
21
|
+
/** The transform runner's reader for one object (undefined = no live values on it). */
|
|
22
|
+
export function animationLiveReader(objectId) {
|
|
23
|
+
if (!objectId)
|
|
24
|
+
return undefined;
|
|
25
|
+
return (index) => live.get(objectId)?.get(index);
|
|
26
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ActionSequence } from '@3driseai/3drise-core';
|
|
2
2
|
import type { PerspectiveCamera } from 'three';
|
|
3
3
|
import type { KeyValue } from './types';
|
|
4
|
+
/** `effects.<effectId>.<param>` → [effectId, param] (null for any other path). */
|
|
5
|
+
export declare function effectParamPath(path: string): [string, string] | null;
|
|
4
6
|
export interface ApplyContext {
|
|
5
7
|
camera: PerspectiveCamera | null;
|
|
6
8
|
/** drei OrbitControls (makeDefault), when present */
|
|
@@ -11,6 +13,12 @@ export interface ApplyContext {
|
|
|
11
13
|
getAction?: (id: string) => ActionSequence | undefined;
|
|
12
14
|
}
|
|
13
15
|
export declare function clearApplierCaches(): void;
|
|
16
|
+
/**
|
|
17
|
+
* A live-only track stops (an object's effect param, an animation row's value — values laid over
|
|
18
|
+
* what the object runs, never in its settings): the object's own value comes back. False for any
|
|
19
|
+
* other path (those restore from the authored settings).
|
|
20
|
+
*/
|
|
21
|
+
export declare function releaseLive(state: string, path: string): boolean;
|
|
14
22
|
/** Write one value. Unknown paths are ignored (the track picker never offers them). */
|
|
15
23
|
/** Write one value to the live scene. False when its target is not mounted yet. */
|
|
16
24
|
export declare function applyValue(ctx: ApplyContext, state: string, path: string, value: KeyValue, node?: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appliers.d.ts","sourceRoot":"","sources":["../../src/animationsV2/appliers.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAiB/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"appliers.d.ts","sourceRoot":"","sources":["../../src/animationsV2/appliers.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAiB/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKxC,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAKrE;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,qDAAqD;IACrD,QAAQ,EAAE,GAAG,CAAC;IACd,yFAAyF;IACzF,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC;IACpC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;CACxD;AAWD,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAsOD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMhE;AAED,uFAAuF;AACvF,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAIlH;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAKxF;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE"}
|
|
@@ -8,6 +8,16 @@ import { sunAnglesFromDirection, skySystemManager } from '@3driseai/3drise-core'
|
|
|
8
8
|
import { sunSystemLive, SUN_SYSTEM_LIVE_PATHS, TIME_PATHS } from './sunSystemLive.js';
|
|
9
9
|
import { publishRenderedSky, sceneOf } from '../utils/renderedSky.js';
|
|
10
10
|
import { applyNodeValue, clearNodeCaches, nodesFor } from './nodeTracks.js';
|
|
11
|
+
import { setObjectEffectParam } from '../operations/objectEffects.js';
|
|
12
|
+
import { setAnimationLive, transformAnimationIndex } from './animationLive.js';
|
|
13
|
+
/** `effects.<effectId>.<param>` → [effectId, param] (null for any other path). */
|
|
14
|
+
export function effectParamPath(path) {
|
|
15
|
+
if (!path.startsWith('effects.'))
|
|
16
|
+
return null;
|
|
17
|
+
const rest = path.slice('effects.'.length);
|
|
18
|
+
const dot = rest.lastIndexOf('.');
|
|
19
|
+
return dot > 0 ? [rest.slice(0, dot), rest.slice(dot + 1)] : null;
|
|
20
|
+
}
|
|
11
21
|
// --- live-target caches (cleared when the scene changes under us) -------------
|
|
12
22
|
const objectCache = new Map();
|
|
13
23
|
const handleCache = new Map();
|
|
@@ -193,6 +203,37 @@ const applyOcean = (ctx, _state, path, value) => {
|
|
|
193
203
|
return false;
|
|
194
204
|
handle.config(path.slice('config.'.length), value);
|
|
195
205
|
};
|
|
206
|
+
/**
|
|
207
|
+
* One of an object's effects (its Effects tab): a param of a running effect — the rotation's speed,
|
|
208
|
+
* a float's height. Only effects the object already has; the effect is not replayed.
|
|
209
|
+
*/
|
|
210
|
+
const applyEffectParam = (_ctx, state, path, value) => {
|
|
211
|
+
const at = effectParamPath(path);
|
|
212
|
+
if (!at || (typeof value !== 'number' && typeof value !== 'boolean' && typeof value !== 'string'))
|
|
213
|
+
return;
|
|
214
|
+
return setObjectEffectParam(objectFor(state), at[0], at[1], value);
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* One of an object's own animations (its Animation tab): a transform row's `to`, live over its
|
|
218
|
+
* authored value. Only rows the object has — a track whose row is gone (removed, reordered into
|
|
219
|
+
* something else) does nothing and is reported once.
|
|
220
|
+
*/
|
|
221
|
+
const warnedRows = new Set();
|
|
222
|
+
const applyAnimationTo = (ctx, state, path, value) => {
|
|
223
|
+
const i = transformAnimationIndex(path);
|
|
224
|
+
if (i === null || !Array.isArray(value) || value.length !== 3)
|
|
225
|
+
return;
|
|
226
|
+
const row = ctx.getSettings(state)?.animations?.transform?.animations?.[i];
|
|
227
|
+
if (!row || !['position', 'rotation', 'scale'].includes(row.property)) {
|
|
228
|
+
const k = `${state}|${i}`;
|
|
229
|
+
if (!warnedRows.has(k)) {
|
|
230
|
+
warnedRows.add(k);
|
|
231
|
+
console.warn(`[3drise] timeline: a track drives transform animation #${i + 1} of ${state}, which is not there any more — it does nothing.`);
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
setAnimationLive(state, i, [Number(value[0]), Number(value[1]), Number(value[2])]);
|
|
236
|
+
};
|
|
196
237
|
/** Procedural terrain: its live handle — `config.*`. */
|
|
197
238
|
const applyTerrain = (ctx, _state, path, value) => {
|
|
198
239
|
if (typeof value !== 'number' && typeof value !== 'boolean' && typeof value !== 'string')
|
|
@@ -232,7 +273,27 @@ const APPLIERS = [
|
|
|
232
273
|
{ match: (_s, p) => p.startsWith('materialSettings.'), apply: applyMaterial },
|
|
233
274
|
{ match: (_s, p) => p.startsWith('edgesSettings.materialSettings.'), apply: applyEdgesMaterial },
|
|
234
275
|
{ match: (_s, p) => p.startsWith('config.'), apply: applyConfig },
|
|
276
|
+
{ match: (_s, p) => p.startsWith('effects.'), apply: applyEffectParam },
|
|
277
|
+
{ match: (_s, p) => transformAnimationIndex(p) !== null, apply: applyAnimationTo },
|
|
235
278
|
];
|
|
279
|
+
/**
|
|
280
|
+
* A live-only track stops (an object's effect param, an animation row's value — values laid over
|
|
281
|
+
* what the object runs, never in its settings): the object's own value comes back. False for any
|
|
282
|
+
* other path (those restore from the authored settings).
|
|
283
|
+
*/
|
|
284
|
+
export function releaseLive(state, path) {
|
|
285
|
+
const at = effectParamPath(path);
|
|
286
|
+
if (at) {
|
|
287
|
+
setObjectEffectParam(objectFor(state), at[0], at[1], undefined);
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
const i = transformAnimationIndex(path);
|
|
291
|
+
if (i !== null) {
|
|
292
|
+
setAnimationLive(state, i, undefined);
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
236
297
|
/** Write one value. Unknown paths are ignored (the track picker never offers them). */
|
|
237
298
|
/** Write one value to the live scene. False when its target is not mounted yet. */
|
|
238
299
|
export function applyValue(ctx, state, path, value, node) {
|
|
@@ -13,4 +13,5 @@ export type { ElementSources } from './elementSettings';
|
|
|
13
13
|
export type { AnimationClip, Track as ClipTrack, Keyframe as ClipKeyframe, KeyValue as ClipKeyValue, EaseName as ClipEaseName, SequenceStep, StepClip, SequenceCue, TimelineCue, AnimationSequence as ClipSequence, SequenceDriver, SequenceDriverSettings, } from './types';
|
|
14
14
|
export { DEFAULT_DRIVER_SETTINGS } from './types';
|
|
15
15
|
export { DEFAULT_EASE as CLIP_DEFAULT_EASE, FPS_PRESETS as CLIP_FPS_PRESETS } from './types';
|
|
16
|
+
export { setAnimationLive, transformAnimationIndex } from './animationLive';
|
|
16
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/animationsV2/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC9H,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACR,aAAa,EAAE,KAAK,IAAI,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,QAAQ,IAAI,YAAY,EAC/G,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,IAAI,YAAY,EAAE,cAAc,EAAE,sBAAsB,GAC9H,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,YAAY,IAAI,iBAAiB,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/animationsV2/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC5D,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC9H,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACR,aAAa,EAAE,KAAK,IAAI,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,QAAQ,IAAI,YAAY,EAC/G,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,IAAI,YAAY,EAAE,cAAc,EAAE,sBAAsB,GAC9H,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,YAAY,IAAI,iBAAiB,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -10,3 +10,4 @@ export { readNodeValue, NODE_TRANSFORM_PATHS, NODE_MATERIAL_KEYS } from './nodeT
|
|
|
10
10
|
export { resolveElementSettings, isEnvironmentState, ENVIRONMENT_STATES as CLIP_ENVIRONMENT_STATES } from './elementSettings.js';
|
|
11
11
|
export { DEFAULT_DRIVER_SETTINGS } from './types.js';
|
|
12
12
|
export { DEFAULT_EASE as CLIP_DEFAULT_EASE, FPS_PRESETS as CLIP_FPS_PRESETS } from './types.js';
|
|
13
|
+
export { setAnimationLive, transformAnimationIndex } from './animationLive.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimatedObject.d.ts","sourceRoot":"","sources":["../../src/components/AnimatedObject.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACtG,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,aAAa,EAAE,qBAAqB,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACjH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAGD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"AnimatedObject.d.ts","sourceRoot":"","sources":["../../src/components/AnimatedObject.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAO7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACtG,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,aAAa,EAAE,qBAAqB,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACjH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAGD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAyFvD,CAAC;AAEH,eAAe,cAAc,CAAC"}
|
|
@@ -52,6 +52,8 @@ visible = true, children, parentRef, handleObjectClick, onPointerEnter, onPointe
|
|
|
52
52
|
if (!obj)
|
|
53
53
|
return;
|
|
54
54
|
baseRef.current = { position: [...position], scale: [...scale], rotation: [...rotation] };
|
|
55
|
+
// The object's authored transform: the rest a parent group's each / targets animation moves it from.
|
|
56
|
+
obj.userData.baseTransform = { position: [...position], scale: [...scale], rotation: [...rotation] };
|
|
55
57
|
targetRef.current = {
|
|
56
58
|
position: targetPosition ? [...targetPosition] : [...position],
|
|
57
59
|
scale: targetScale ? [...targetScale] : [...scale],
|
|
@@ -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;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,
|
|
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,CAqI5D,CAAC;AACF,eAAe,gBAAgB,CAAC"}
|
|
@@ -94,6 +94,15 @@ export const CameraController = ({ enableAutoAnimation = true, animationDuration
|
|
|
94
94
|
orbitControls.maxDistance = controls.maxDistance;
|
|
95
95
|
// Saved limits may be null (once ±Infinity): the full range then.
|
|
96
96
|
Object.assign(orbitControls, orbitAngleLimits(controls));
|
|
97
|
+
// The authored limits, kept on the live instance: controllers drag them directly
|
|
98
|
+
// (setLive), the follow hook widens from them and clamps the height with them,
|
|
99
|
+
// and the limits helper draws them.
|
|
100
|
+
orbitControls.authoredLimits = {
|
|
101
|
+
minDistance: controls.minDistance, maxDistance: controls.maxDistance,
|
|
102
|
+
...orbitAngleLimits(controls),
|
|
103
|
+
minHeight: typeof controls.minHeight === 'number' ? controls.minHeight : null,
|
|
104
|
+
maxHeight: typeof controls.maxHeight === 'number' ? controls.maxHeight : null,
|
|
105
|
+
};
|
|
97
106
|
}, [controls]);
|
|
98
107
|
// Look at a scene object (orbit target) and / or travel with one (follow).
|
|
99
108
|
useOrbitTargetFollow(controlsRef, controls.targetObject, controls.followObject, () => isInAnimatedTransition.current || isAnimating() || isPathAnimating(), controls.enabled !== false, controls);
|
|
@@ -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":"AAKA,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,CAwG9C,CAAC;AAEH,eAAe,aAAa,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useRef, useEffect, useState, useReducer, memo, useContext } from "react";
|
|
3
3
|
import { ObjectHoverContext } from "../interactions/runner.js";
|
|
4
4
|
import { ModelMaterialPassContext } from "./ModelMaterialPassContext.js";
|
|
5
|
+
import { GroupMaterialContext, coveredBy } from "./GroupMaterialContext.js";
|
|
5
6
|
import { DEFAULT_EDGES_SETTINGS } from "@3driseai/3drise-core";
|
|
6
7
|
import { useMaterialApplication } from "../hooks/useMaterialApplication.js";
|
|
7
8
|
import { useShadowApplication } from "../hooks/useShadowApplication.js";
|
|
@@ -40,7 +41,9 @@ const CreatedObject = memo(({ createdObject, children, shouldApply3driseMaterial
|
|
|
40
41
|
// Bumped when the model-level material pass lands, so per-mesh overrides
|
|
41
42
|
// (useNodeOverrides in ModelPrimitive) re-apply on top of it.
|
|
42
43
|
const [materialPass, bumpMaterialPass] = useReducer((n) => n + 1, 0);
|
|
43
|
-
|
|
44
|
+
// Inside a group whose material is on, the group's material wins; off, the object's own comes back.
|
|
45
|
+
const groupMaterial = coveredBy(createdObject, useContext(GroupMaterialContext));
|
|
46
|
+
useMaterialApplication(meshRef, groupMaterial ?? createdObject.materialSettings, shouldApply3driseMaterial, bumpMaterialPass);
|
|
44
47
|
// An object with no explicit flags takes its type's defaults (core's
|
|
45
48
|
// resolveShadowFlags): saved objects carry none, and reading them as false
|
|
46
49
|
// switched every shadow in every project off.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CreatedObjectSettings, MaterialSettings } from '@3driseai/3drise-core';
|
|
2
|
+
/**
|
|
3
|
+
* A group's material, handed down to the objects inside it.
|
|
4
|
+
*
|
|
5
|
+
* A group has no surface: like its visual effects, its material goes to the objects inside it that
|
|
6
|
+
* take one — meshes and models, any depth (core groupMaterialTargets is the same rule). It is a
|
|
7
|
+
* layer, like the model's "Apply material": while the group's `materialSettings.apply` is on, a
|
|
8
|
+
* covered child renders with the group's material instead of its own; switched off, every child
|
|
9
|
+
* goes back to its own material (its settings were never touched).
|
|
10
|
+
*
|
|
11
|
+
* targets the group's `materialSettings.objectIds` — child object ids (any depth); a chosen
|
|
12
|
+
* nested group stands for everything inside it. None = every child.
|
|
13
|
+
* nearest an inner group whose own material is on wins inside it.
|
|
14
|
+
*/
|
|
15
|
+
export interface GroupMaterial {
|
|
16
|
+
settings: MaterialSettings;
|
|
17
|
+
/** null = every object inside. */
|
|
18
|
+
targets: ReadonlySet<string> | null;
|
|
19
|
+
}
|
|
20
|
+
export declare const GroupMaterialContext: import("react").Context<GroupMaterial>;
|
|
21
|
+
/** What a group (or a parent object) hands to the objects inside it. */
|
|
22
|
+
export declare function groupMaterialFor(obj: CreatedObjectSettings, parent: GroupMaterial | null): GroupMaterial | null;
|
|
23
|
+
/** The group material this object renders with, or null (it keeps its own). */
|
|
24
|
+
export declare function coveredBy(obj: CreatedObjectSettings, ctx: GroupMaterial | null): MaterialSettings | null;
|
|
25
|
+
//# sourceMappingURL=GroupMaterialContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GroupMaterialContext.d.ts","sourceRoot":"","sources":["../../src/components/GroupMaterialContext.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAErF;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,kCAAkC;IAClC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,oBAAoB,wCAA4C,CAAC;AAE9E,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAS/G;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,GAAG,gBAAgB,GAAG,IAAI,CAGxG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import { objectTakesVisualEffects } from '@3driseai/3drise-core';
|
|
3
|
+
export const GroupMaterialContext = createContext(null);
|
|
4
|
+
/** What a group (or a parent object) hands to the objects inside it. */
|
|
5
|
+
export function groupMaterialFor(obj, parent) {
|
|
6
|
+
const own = obj.materialSettings;
|
|
7
|
+
if (obj.type === 'group' && own?.apply === true && own.materialType) {
|
|
8
|
+
const { objectIds, ...settings } = own;
|
|
9
|
+
return { settings: settings, targets: objectIds?.length ? new Set(objectIds) : null };
|
|
10
|
+
}
|
|
11
|
+
// a chosen nested group (or object) stands for everything inside it
|
|
12
|
+
if (obj.type === 'group' && parent?.targets?.has(obj.id))
|
|
13
|
+
return { settings: parent.settings, targets: null };
|
|
14
|
+
return parent;
|
|
15
|
+
}
|
|
16
|
+
/** The group material this object renders with, or null (it keeps its own). */
|
|
17
|
+
export function coveredBy(obj, ctx) {
|
|
18
|
+
if (!ctx || obj.type === 'group' || !objectTakesVisualEffects(obj))
|
|
19
|
+
return null;
|
|
20
|
+
return !ctx.targets || ctx.targets.has(obj.id) ? ctx.settings : null;
|
|
21
|
+
}
|
|
@@ -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":"AAqBA,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;AA4BF,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8IzC,CAAC;AACF,eAAe,UAAU,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useMemo } from "react";
|
|
2
|
+
import { useCallback, useContext, useMemo } from "react";
|
|
3
|
+
import { GroupMaterialContext, groupMaterialFor } from "./GroupMaterialContext.js";
|
|
3
4
|
import CustomPrimitive from "./CustomPrimitive.js";
|
|
4
5
|
import CreatedObject from "./CreatedObject.js";
|
|
5
6
|
import PathRenderer from './PathRenderer.js';
|
|
@@ -46,7 +47,17 @@ const GroupWithChildren = ({ createdObject, children, onObjectReady, onObjectDis
|
|
|
46
47
|
// Generative particle objects own their shaders, like effects do.
|
|
47
48
|
const selfManagedMaterial = SELF_MANAGED_MATERIAL.has(createdObject.type)
|
|
48
49
|
|| (createdObject.type === 'particles' && isGenerativeParticlesConfig(createdObject.config));
|
|
49
|
-
|
|
50
|
+
// A group's material (Apply on) goes to the objects inside it — see GroupMaterialContext.
|
|
51
|
+
const parentMaterial = useContext(GroupMaterialContext);
|
|
52
|
+
const ms = createdObject.materialSettings;
|
|
53
|
+
const handed = useMemo(() => groupMaterialFor(createdObject, parentMaterial),
|
|
54
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
55
|
+
[createdObject.id, createdObject.type, ms, parentMaterial]);
|
|
56
|
+
const body = (_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));
|
|
57
|
+
// Always the Provider (even when it hands the parent's value on): wrapping only when a material is
|
|
58
|
+
// on would change the element type here and remount the whole subtree whenever Apply is toggled —
|
|
59
|
+
// new Object3Ds for every child (the studio's live preview kept writing to the old ones).
|
|
60
|
+
return _jsx(GroupMaterialContext.Provider, { value: handed, children: body });
|
|
50
61
|
};
|
|
51
62
|
const ObjectNode = ({ node, onObjectReady, onObjectDispose, handleObjectClick }) => {
|
|
52
63
|
const { children } = node;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAU9E,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,CAgGlD,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { memo, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
3
|
-
import { buildObjectTree } from '@3driseai/3drise-core';
|
|
2
|
+
import { memo, useRef, useCallback, useMemo, useEffect, useState } from 'react';
|
|
3
|
+
import { buildObjectTree, SceneStore } from '@3driseai/3drise-core';
|
|
4
4
|
import ObjectNode from './ObjectNode.js';
|
|
5
5
|
import useInteraction from '../hooks/useInteraction.js';
|
|
6
6
|
import { ObjectHoverContext, setEffectPrewarmer, setEffectPreviewer, setInteractionRunner } from '../interactions/runner.js';
|
|
7
7
|
import { prewarmEffect, previewEffect, previewEffects } from '../operations/runtime.js';
|
|
8
|
+
import { bakeProject, setBakeSource } from '../operations/bake.js';
|
|
9
|
+
import { installStallLog } from '../utils/stallLog.js';
|
|
8
10
|
import { findById } from '../utils/sceneQuery.js';
|
|
9
|
-
import {
|
|
11
|
+
import { commandsOf, sceneReadiness } from '../triggers/index.js';
|
|
10
12
|
import { useObjectReady } from '../hooks/useObjectReady.js';
|
|
11
13
|
const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSettings, onObjectsReady, onObjectReady, onObjectDispose, handleObjectClick, sequences = [], clips = [], actionSequences = [], }) => {
|
|
12
14
|
const groupRef = useRef(null);
|
|
13
15
|
const objectsTree = useMemo(() => buildObjectTree(createdObjects), [createdObjects]);
|
|
14
16
|
const readyObjectsCount = useRef(0);
|
|
17
|
+
const bumpBakeRef = useRef(() => { });
|
|
15
18
|
// Count for the aggregate onObjectsReady signal, then forward the event up.
|
|
16
19
|
// Previously this callback counted and dropped the (object, ref) pair, which
|
|
17
20
|
// is why nothing above ObjectsRenderer ever received an object ref.
|
|
@@ -21,6 +24,7 @@ const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSet
|
|
|
21
24
|
onObjectsReady && onObjectsReady();
|
|
22
25
|
}
|
|
23
26
|
onObjectReady && onObjectReady(object, ref);
|
|
27
|
+
bumpBakeRef.current();
|
|
24
28
|
}, [objectsTree.length, onObjectsReady, onObjectReady]);
|
|
25
29
|
const handleObjectDispose = useCallback((object, ref) => {
|
|
26
30
|
readyObjectsCount.current = Math.max(0, readyObjectsCount.current - 1);
|
|
@@ -72,24 +76,27 @@ const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSet
|
|
|
72
76
|
const ref = findById(objectId);
|
|
73
77
|
return ref ? prewarmEffect(effect, ref) : Promise.resolve();
|
|
74
78
|
}), []);
|
|
75
|
-
//
|
|
76
|
-
//
|
|
79
|
+
// Bake everything this project can play (operations/bake.ts): every effect of its interactions,
|
|
80
|
+
// actions, clip / sequence cues, effect clips and objects' own Effects tabs is compiled and
|
|
81
|
+
// prepared ahead of time, so no first play stalls. A published scene bakes inside its readiness,
|
|
82
|
+
// under the loading cover; here it re-bakes in the background when the lists change or an object
|
|
83
|
+
// reports ready (a model landed — only what is new is warmed).
|
|
84
|
+
const [bakeTick, setBakeTick] = useState(0);
|
|
77
85
|
useEffect(() => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
continue;
|
|
83
|
-
for (const ix of (o.actions ?? []))
|
|
84
|
-
for (const e of effectsOf(ix))
|
|
85
|
-
void prewarmEffect(e, ref);
|
|
86
|
-
}
|
|
87
|
-
for (const a of actionSequences ?? [])
|
|
88
|
-
for (const e of actionEffectsOf(a))
|
|
89
|
-
void prewarmEffect(e, null);
|
|
90
|
-
}, 1500);
|
|
86
|
+
setBakeSource({ objects: createdObjects, actions: actionSequences, clips, sequences });
|
|
87
|
+
if (!sceneReadiness.isReady())
|
|
88
|
+
return; // the readiness bake does it
|
|
89
|
+
const t = setTimeout(() => { void bakeProject(); }, 400);
|
|
91
90
|
return () => clearTimeout(t);
|
|
92
|
-
}, [createdObjects, actionSequences]);
|
|
91
|
+
}, [createdObjects, actionSequences, clips, sequences, bakeTick]);
|
|
92
|
+
const bumpBake = useCallback(() => setBakeTick(n => n + 1), []);
|
|
93
|
+
bumpBakeRef.current = bumpBake;
|
|
94
|
+
// dev: log frames that stall and why (localStorage '3drise:stalls' = '1' — utils/stallLog)
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const t = setTimeout(() => { const gl = SceneStore.gl; if (gl)
|
|
97
|
+
installStallLog(gl); }, 500);
|
|
98
|
+
return () => clearTimeout(t);
|
|
99
|
+
}, []);
|
|
93
100
|
const handleObjectClickHandler = (createdObject, ref, event) => {
|
|
94
101
|
const clickInteractions = filterInteractionsByEvent(createdObject.actions, "click");
|
|
95
102
|
clickInteractions.forEach((interaction) => {
|
|
@@ -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":"AAKA,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;qCA6LnB,CAAC;AAIH,eAAe,YAAY,CAAC"}
|
|
@@ -2,6 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import AdaptiveResolution from './AdaptiveResolution.js';
|
|
3
3
|
import { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { EFFECT_CLIP_ASSET, effectClipFromAsset, setEffectClipTemplates } from "../operations/runtime.js";
|
|
5
|
+
import { compileScene, uploadTextures } from "../operations/catalogue/warmup.js";
|
|
6
|
+
import { bakeProject } from "../operations/bake.js";
|
|
5
7
|
import { createSceneHandle } from "../api/sceneHandle.js";
|
|
6
8
|
import { Canvas } from "@react-three/fiber";
|
|
7
9
|
import { LIGHTING_PRESETS, SceneStore } from "@3driseai/3drise-core";
|
|
@@ -81,10 +83,11 @@ const SceneBuilder = forwardRef(({ project, width = "100%", height = "100vh", st
|
|
|
81
83
|
const [started, setStarted] = useState(false);
|
|
82
84
|
useLayoutEffect(() => {
|
|
83
85
|
sceneReadiness.begin([CANVAS_READY, ...(modelKey ? modelKey.split(',') : [])], {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
// as the frame draws it (render target included — see warmup), then every texture uploaded
|
|
87
|
+
// (objects hidden at load would upload theirs in the frame they appear in)
|
|
88
|
+
compile: () => compileScene(threeRef.current).then(() => { uploadTextures(); }),
|
|
89
|
+
// every effect the project can play, compiled and prepared (operations/bake)
|
|
90
|
+
bake: () => bakeProject(),
|
|
88
91
|
});
|
|
89
92
|
if (threeRef.current)
|
|
90
93
|
sceneReadiness.report(CANVAS_READY); // remount with the canvas already there
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LandPatch.d.ts","sourceRoot":"","sources":["../../../src/components/land/LandPatch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAExF,OAAO,EAGH,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"LandPatch.d.ts","sourceRoot":"","sources":["../../../src/components/land/LandPatch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAExF,OAAO,EAGH,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAoDhE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACpD,MAAM,EAAE,gBAAgB,CAAC;IACzB,4DAA4D;IAC5D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,eAAe,CAAC;CAC/B;AASD,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAgJvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -11,6 +11,13 @@ import { TerrainMaterial } from '../../shaders/terrain/TerrainMaterial.js';
|
|
|
11
11
|
import { applySunUniforms } from '../../utils/cloudUniforms.js';
|
|
12
12
|
import { applyTerrainAmbient, applyTerrainTextures, applyTerrainUniforms } from '../../utils/terrainUniforms.js';
|
|
13
13
|
import { withConfigDefaults } from '../../utils/configAnimations.js';
|
|
14
|
+
import { isMobileDevice } from '../../utils/deviceTier.js';
|
|
15
|
+
/**
|
|
16
|
+
* Phone / tablet tier, at render time only — the saved object keeps its numbers.
|
|
17
|
+
* The same caps as the environment terrain (TerrainSurface), plus the low grid:
|
|
18
|
+
* per-pixel cost (octaves, texture distance) is what dominates, measured on desktop.
|
|
19
|
+
*/
|
|
20
|
+
const MOBILE = { quality: 'low', maxOctaves: 5, maxTextureDistance: 400 };
|
|
14
21
|
import { resolveTerrainTextureSets, useTerrainTextureResolverVersion } from '../../utils/terrainTextureResolver.js';
|
|
15
22
|
import { LAND_SEGMENTS, applyLandPatchUniforms, landFrame, landHeightAt, landQuality, landToTerrainConfig, } from '../../utils/landPatch.js';
|
|
16
23
|
// =============================================================================
|
|
@@ -47,7 +54,8 @@ const LandPatch = ({ config, id, keyframes, mouseMove, onObjectReady, onObjectDi
|
|
|
47
54
|
const type = DEFAULT_LAND_OBJECTS[config.type] ? config.type : 'hills';
|
|
48
55
|
const base = useMemo(() => withConfigDefaults(DEFAULT_LAND_OBJECTS[type], config), [config, type]);
|
|
49
56
|
const allowed = useMemo(() => new Set(LAND_OBJECTS_ANIMATABLE[type].map((p) => p.value)), [type]);
|
|
50
|
-
const
|
|
57
|
+
const mobile = isMobileDevice();
|
|
58
|
+
const segments = LAND_SEGMENTS[mobile ? MOBILE.quality : base.quality] ?? 256;
|
|
51
59
|
const geometry = useMemo(() => {
|
|
52
60
|
const g = new THREE.PlaneGeometry(1, 1, segments, segments);
|
|
53
61
|
g.rotateX(-Math.PI / 2);
|
|
@@ -78,6 +86,12 @@ const LandPatch = ({ config, id, keyframes, mouseMove, onObjectReady, onObjectDi
|
|
|
78
86
|
if (!mesh)
|
|
79
87
|
return;
|
|
80
88
|
const cfg = { ...current.current, textures: current.current.textures ?? base.textures };
|
|
89
|
+
if (mobile) {
|
|
90
|
+
// quality must match the grid built above: the shader's cell size comes from it.
|
|
91
|
+
cfg.quality = MOBILE.quality;
|
|
92
|
+
cfg.octaves = Math.min(cfg.octaves, MOBILE.maxOctaves);
|
|
93
|
+
cfg.textureDistance = Math.min(cfg.textureDistance ?? 4000, MOBILE.maxTextureDistance);
|
|
94
|
+
}
|
|
81
95
|
const t = landToTerrainConfig(cfg);
|
|
82
96
|
const s = sun.update();
|
|
83
97
|
const m = material;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContinuousEffects.d.ts","sourceRoot":"","sources":["../../src/hooks/useContinuousEffects.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useContinuousEffects.d.ts","sourceRoot":"","sources":["../../src/hooks/useContinuousEffects.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGhF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,MAAM,WAAW,2BAA2B;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IACvC,eAAe,EAAE,MAAM,OAAO,CAAC;IAC/B,cAAc,EAAE,KAAK,CAAC,gBAAgB,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC9D;AAGD,eAAO,MAAM,oBAAoB,GAEjC,gBAAgB,qBAAqB,GAAG,IAAI,EAAE,UAAS,2BAAgC,EAAE,eAAe,cAAc,KAAG,0BA0IxH,CAAC;AACF,eAAe,oBAAoB,CAAC"}
|