@needle-tools/engine 5.1.0-alpha.3 → 5.1.0-alpha.5
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/CHANGELOG.md +68 -0
- package/SKILL.md +4 -1
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-DF01sSGQ.js → needle-engine.bundle-C-LG00ZZ.js} +10681 -10100
- package/dist/needle-engine.bundle-D7tzaiYE.min.js +1733 -0
- package/dist/{needle-engine.bundle-C-ixARur.umd.cjs → needle-engine.bundle-OPkPmdUM.umd.cjs} +161 -161
- package/dist/needle-engine.d.ts +1349 -317
- package/dist/needle-engine.js +556 -555
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/three.js +1 -0
- package/dist/three.min.js +21 -21
- package/dist/three.umd.cjs +16 -16
- package/lib/engine/api.d.ts +5 -0
- package/lib/engine/api.js +4 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/codegen/register_types.js +10 -18
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_camera.fit.js +16 -4
- package/lib/engine/engine_camera.fit.js.map +1 -1
- package/lib/engine/engine_context.d.ts +20 -7
- package/lib/engine/engine_context.js +31 -15
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_eventbus.d.ts +47 -0
- package/lib/engine/engine_context_eventbus.js +47 -0
- package/lib/engine/engine_context_eventbus.js.map +1 -0
- package/lib/engine/engine_disposable.d.ts +172 -0
- package/lib/engine/engine_disposable.js +136 -0
- package/lib/engine/engine_disposable.js.map +1 -0
- package/lib/engine/engine_gameobject.d.ts +1 -10
- package/lib/engine/engine_gameobject.js +20 -118
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +7 -69
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/engine_input.d.ts +23 -4
- package/lib/engine/engine_input.js +2 -1
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
- package/lib/engine/engine_instantiate_resolve.js +372 -0
- package/lib/engine/engine_instantiate_resolve.js.map +1 -0
- package/lib/engine/engine_mainloop_utils.js +2 -2
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_networking.d.ts +51 -37
- package/lib/engine/engine_networking.js +132 -82
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
- package/lib/engine/engine_networking.transport.websocket.js +38 -0
- package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
- package/lib/engine/engine_networking_instantiate.js +2 -2
- package/lib/engine/engine_networking_instantiate.js.map +1 -1
- package/lib/engine/engine_networking_types.d.ts +39 -1
- package/lib/engine/engine_networking_types.js +7 -0
- package/lib/engine/engine_networking_types.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +21 -3
- package/lib/engine/engine_physics_rapier.js +94 -25
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js +1 -5
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_serialization_core.d.ts +1 -0
- package/lib/engine/engine_serialization_core.js +7 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_types.d.ts +29 -11
- package/lib/engine/engine_types.js +1 -1
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_util_decorator.js +7 -2
- package/lib/engine/engine_util_decorator.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +19 -5
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine-components/AnimationBuilder.d.ts +158 -0
- package/lib/engine-components/AnimationBuilder.js +305 -0
- package/lib/engine-components/AnimationBuilder.js.map +1 -0
- package/lib/engine-components/Animator.d.ts +6 -0
- package/lib/engine-components/Animator.js +23 -13
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.builder.d.ts +191 -0
- package/lib/engine-components/AnimatorController.builder.js +263 -0
- package/lib/engine-components/AnimatorController.builder.js.map +1 -0
- package/lib/engine-components/AnimatorController.d.ts +2 -119
- package/lib/engine-components/AnimatorController.js +33 -232
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/Collider.d.ts +18 -9
- package/lib/engine-components/Collider.js +61 -14
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/Component.d.ts +72 -9
- package/lib/engine-components/Component.js +114 -10
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/ContactShadows.d.ts +1 -0
- package/lib/engine-components/ContactShadows.js +14 -1
- package/lib/engine-components/ContactShadows.js.map +1 -1
- package/lib/engine-components/DragControls.js +0 -7
- package/lib/engine-components/DragControls.js.map +1 -1
- package/lib/engine-components/DropListener.js +3 -0
- package/lib/engine-components/DropListener.js.map +1 -1
- package/lib/engine-components/EventList.d.ts +31 -9
- package/lib/engine-components/EventList.js +37 -76
- package/lib/engine-components/EventList.js.map +1 -1
- package/lib/engine-components/Joints.d.ts +4 -2
- package/lib/engine-components/Joints.js +19 -3
- package/lib/engine-components/Joints.js.map +1 -1
- package/lib/engine-components/Light.js +9 -1
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/OrbitControls.d.ts +0 -2
- package/lib/engine-components/OrbitControls.js +14 -1
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +12 -4
- package/lib/engine-components/RigidBody.js +18 -4
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +3 -0
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/api.d.ts +2 -1
- package/lib/engine-components/api.js +2 -1
- package/lib/engine-components/api.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +7 -13
- package/lib/engine-components/codegen/components.js +7 -13
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +21 -11
- package/lib/engine-components/timeline/PlayableDirector.js +75 -67
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
- package/lib/engine-components/timeline/SignalAsset.js +1 -0
- package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
- package/lib/engine-components/timeline/TimelineBuilder.d.ts +413 -0
- package/lib/engine-components/timeline/TimelineBuilder.js +506 -0
- package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
- package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
- package/lib/engine-components/timeline/TimelineModels.js +3 -0
- package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +37 -6
- package/lib/engine-components/timeline/TimelineTracks.js +92 -26
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/timeline/index.d.ts +2 -1
- package/lib/engine-components/timeline/index.js +2 -0
- package/lib/engine-components/timeline/index.js.map +1 -1
- package/lib/engine-components/web/CursorFollow.d.ts +0 -1
- package/lib/engine-components/web/CursorFollow.js +0 -1
- package/lib/engine-components/web/CursorFollow.js.map +1 -1
- package/package.json +2 -83
- package/plugins/common/cloud.js +6 -1
- package/plugins/common/license.js +5 -2
- package/plugins/common/worker.js +9 -4
- package/plugins/vite/dependencies.js +1 -11
- package/plugins/vite/dependency-watcher.js +2 -2
- package/plugins/vite/editor-connection.js +3 -3
- package/plugins/vite/license.js +19 -1
- package/plugins/vite/reload.js +1 -1
- package/plugins/vite/server.js +2 -1
- package/src/engine/api.ts +7 -0
- package/src/engine/codegen/register_types.ts +10 -18
- package/src/engine/engine_camera.fit.ts +15 -4
- package/src/engine/engine_context.ts +32 -16
- package/src/engine/engine_context_eventbus.ts +73 -0
- package/src/engine/engine_disposable.ts +214 -0
- package/src/engine/engine_gameobject.ts +52 -157
- package/src/engine/engine_gltf_builtin_components.ts +7 -76
- package/src/engine/engine_input.ts +27 -6
- package/src/engine/engine_instantiate_resolve.ts +407 -0
- package/src/engine/engine_mainloop_utils.ts +2 -2
- package/src/engine/engine_networking.transport.websocket.ts +45 -0
- package/src/engine/engine_networking.ts +161 -137
- package/src/engine/engine_networking_instantiate.ts +2 -2
- package/src/engine/engine_networking_types.ts +41 -1
- package/src/engine/engine_physics_rapier.ts +102 -33
- package/src/engine/engine_serialization_builtin_serializer.ts +1 -6
- package/src/engine/engine_serialization_core.ts +9 -0
- package/src/engine/engine_types.ts +46 -27
- package/src/engine/engine_util_decorator.ts +7 -2
- package/src/engine/engine_utils.ts +16 -5
- package/src/engine-components/AnimationBuilder.ts +472 -0
- package/src/engine-components/Animator.ts +24 -12
- package/src/engine-components/AnimatorController.builder.ts +387 -0
- package/src/engine-components/AnimatorController.ts +20 -291
- package/src/engine-components/Collider.ts +66 -18
- package/src/engine-components/Component.ts +118 -20
- package/src/engine-components/ContactShadows.ts +15 -1
- package/src/engine-components/DragControls.ts +0 -9
- package/src/engine-components/DropListener.ts +3 -0
- package/src/engine-components/EventList.ts +45 -83
- package/src/engine-components/Joints.ts +20 -4
- package/src/engine-components/Light.ts +10 -2
- package/src/engine-components/OrbitControls.ts +16 -5
- package/src/engine-components/RigidBody.ts +18 -4
- package/src/engine-components/SceneSwitcher.ts +3 -0
- package/src/engine-components/api.ts +2 -1
- package/src/engine-components/codegen/components.ts +7 -13
- package/src/engine-components/timeline/PlayableDirector.ts +83 -81
- package/src/engine-components/timeline/SignalAsset.ts +4 -1
- package/src/engine-components/timeline/TimelineBuilder.ts +824 -0
- package/src/engine-components/timeline/TimelineModels.ts +5 -1
- package/src/engine-components/timeline/TimelineTracks.ts +96 -27
- package/src/engine-components/timeline/index.ts +2 -1
- package/src/engine-components/web/CursorFollow.ts +0 -1
- package/dist/needle-engine.bundle-CHmXdnE1.min.js +0 -1733
- package/lib/engine-components/AvatarLoader.d.ts +0 -80
- package/lib/engine-components/AvatarLoader.js +0 -232
- package/lib/engine-components/AvatarLoader.js.map +0 -1
- package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
- package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
- package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
- package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
- package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
- package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
- package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
- package/src/engine-components/AvatarLoader.ts +0 -264
- package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
- package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
- package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
- package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
- package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
|
@@ -42,7 +42,7 @@ export enum ClipExtrapolation {
|
|
|
42
42
|
* @category Animation and Sequencing
|
|
43
43
|
* @see {@link PlayableDirector} for the main component to control timelines in Needle Engine.
|
|
44
44
|
*/
|
|
45
|
-
export
|
|
45
|
+
export type TrackModel = {
|
|
46
46
|
name: string;
|
|
47
47
|
type: TrackType;
|
|
48
48
|
muted: boolean;
|
|
@@ -53,6 +53,10 @@ export declare type TrackModel = {
|
|
|
53
53
|
volume?: number;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
export function isTrackModel(obj:unknown): obj is TrackModel {
|
|
57
|
+
return typeof obj === "object" && obj !== null && "name" in obj && "type" in obj && "outputs" in obj && "muted" in obj;
|
|
58
|
+
}
|
|
59
|
+
|
|
56
60
|
declare type Vec3 = { x: number, y: number, z: number };
|
|
57
61
|
declare type Quat = { x: number, y: number, z: number, w: number };
|
|
58
62
|
|
|
@@ -4,13 +4,14 @@ import { isDevEnvironment } from "../../engine/debug/index.js";
|
|
|
4
4
|
import { Context } from "../../engine/engine_setup.js";
|
|
5
5
|
import type { Constructor } from "../../engine/engine_types.js";
|
|
6
6
|
import { getParam, resolveUrl } from "../../engine/engine_utils.js";
|
|
7
|
-
import { setObjectAnimated } from "../AnimationUtils.js";
|
|
8
7
|
import { Animator } from "../Animator.js"
|
|
9
8
|
import { AudioSource } from "../AudioSource.js";
|
|
10
9
|
import { GameObject } from "../Component.js";
|
|
11
10
|
import type { PlayableDirector } from "./PlayableDirector.js";
|
|
12
11
|
import { SignalReceiver } from "./SignalAsset.js";
|
|
13
12
|
import * as Models from "./TimelineModels.js";
|
|
13
|
+
import type { TimelineBuilder } from "./TimelineBuilder.js";
|
|
14
|
+
import { AnimationUtils } from "../../engine/engine_animation.js";
|
|
14
15
|
|
|
15
16
|
const debug = getParam("debugtimeline");
|
|
16
17
|
|
|
@@ -18,7 +19,7 @@ const debug = getParam("debugtimeline");
|
|
|
18
19
|
* A TrackHandler is responsible for evaluating a specific type of timeline track.
|
|
19
20
|
* A timeline track can be an animation track, audio track, signal track, control track etc and is controlled by a {@link PlayableDirector}.
|
|
20
21
|
*/
|
|
21
|
-
export abstract class
|
|
22
|
+
export abstract class TimelineTrackHandler {
|
|
22
23
|
director!: PlayableDirector;
|
|
23
24
|
track!: Models.TrackModel;
|
|
24
25
|
|
|
@@ -136,7 +137,7 @@ class AnimationClipOffsetData {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
// TODO: add support for clip clamp modes (loop, pingpong, clamp)
|
|
139
|
-
export class
|
|
140
|
+
export class TimelineAnimationTrack extends TimelineTrackHandler {
|
|
140
141
|
/** @internal */
|
|
141
142
|
models: Array<Models.ClipModel> = [];
|
|
142
143
|
/** @internal */
|
|
@@ -178,7 +179,7 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
178
179
|
onStateChanged() {
|
|
179
180
|
if (this._animator) {
|
|
180
181
|
// We can not check the *isPlaying* state here because the timeline might be paused and evaluated by e.g. ScrollFollow
|
|
181
|
-
setObjectAnimated(this._animator.gameObject, this, this.director.enabled && this.director.weight > 0);
|
|
182
|
+
AnimationUtils.setObjectAnimated(this._animator.gameObject, this, this.director.enabled && this.director.weight > 0);
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
185
|
|
|
@@ -262,7 +263,7 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
262
263
|
// which overrides the timeline
|
|
263
264
|
this._animator = GameObject.getComponent(this.target, Animator) ?? null;
|
|
264
265
|
if (this._animator) {
|
|
265
|
-
setObjectAnimated(this._animator.gameObject, this, true);
|
|
266
|
+
AnimationUtils.setObjectAnimated(this._animator.gameObject, this, true);
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -591,7 +592,21 @@ const muteAudioTracks = getParam("mutetimeline");
|
|
|
591
592
|
|
|
592
593
|
declare type AudioClipModel = Models.ClipModel & { _didTriggerPlay: boolean };
|
|
593
594
|
|
|
594
|
-
|
|
595
|
+
/**
|
|
596
|
+
* Handles audio playback for a timeline audio track.
|
|
597
|
+
*
|
|
598
|
+
* **Runtime mutation:** The track model is read fresh every frame during `evaluate()`.
|
|
599
|
+
* You can mutate `track.volume`, `clip.start`, `clip.end`, `clip.asset.volume` etc.
|
|
600
|
+
* at any time — changes take effect on the next frame without rebuilding the timeline.
|
|
601
|
+
*
|
|
602
|
+
* **Audio stopping:** Audio clips are automatically stopped when:
|
|
603
|
+
* - Timeline time moves outside a clip's `[start, end]` range (e.g. jumping or normal playback advancing past a clip)
|
|
604
|
+
* - The track is muted (via `muted = true`)
|
|
605
|
+
* - The director is stopped (`director.stop()`)
|
|
606
|
+
* - The director is paused (`director.pause()`)
|
|
607
|
+
* - The director is disabled or destroyed
|
|
608
|
+
*/
|
|
609
|
+
export class TimelineAudioTrack extends TimelineTrackHandler {
|
|
595
610
|
|
|
596
611
|
models: Array<AudioClipModel> = [];
|
|
597
612
|
listener!: AudioListener;
|
|
@@ -600,6 +615,10 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
600
615
|
lastTime: number = 0;
|
|
601
616
|
audioSource?: AudioSource;
|
|
602
617
|
|
|
618
|
+
/** Track-level volume multiplier (0–1). Applied on top of per-clip volume each frame. */
|
|
619
|
+
get volume(): number { return this.track.volume ?? 1; }
|
|
620
|
+
set volume(val: number) { this.track.volume = val; }
|
|
621
|
+
|
|
603
622
|
private _audioLoader: AudioLoader | null = null;
|
|
604
623
|
|
|
605
624
|
private getAudioFilePath(path: string) {
|
|
@@ -796,7 +815,7 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
796
815
|
private static _audioBuffers: Map<string, Promise<AudioBuffer | null>> = new Map();
|
|
797
816
|
|
|
798
817
|
public static dispose() {
|
|
799
|
-
|
|
818
|
+
TimelineAudioTrack._audioBuffers.clear();
|
|
800
819
|
}
|
|
801
820
|
|
|
802
821
|
private handleAudioLoading(model: Models.ClipModel, audio: Audio): Promise<AudioBuffer | null> | null {
|
|
@@ -806,8 +825,8 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
806
825
|
// TODO: maybe we should cache the loaders / buffers here by path
|
|
807
826
|
const path = this.getAudioFilePath(model.asset.clip);
|
|
808
827
|
|
|
809
|
-
if (
|
|
810
|
-
const promise =
|
|
828
|
+
if (TimelineAudioTrack._audioBuffers.get(path)) {
|
|
829
|
+
const promise = TimelineAudioTrack._audioBuffers.get(path)!
|
|
811
830
|
promise.then((buffer) => {
|
|
812
831
|
if (buffer) audio.setBuffer(buffer);
|
|
813
832
|
});
|
|
@@ -827,17 +846,17 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
827
846
|
resolve(null);
|
|
828
847
|
});
|
|
829
848
|
});
|
|
830
|
-
|
|
849
|
+
TimelineAudioTrack._audioBuffers.set(path, loadingPromise);
|
|
831
850
|
return loadingPromise;
|
|
832
851
|
}
|
|
833
852
|
}
|
|
834
853
|
|
|
835
|
-
export class
|
|
854
|
+
export class TimelineMarkerTrack extends TimelineTrackHandler {
|
|
836
855
|
models: Array<Models.MarkerModel & Record<string, any>> = [];
|
|
837
856
|
needsSorting = true;
|
|
838
857
|
|
|
839
858
|
*foreachMarker<T>(type: string | null = null) {
|
|
840
|
-
if(this.needsSorting) this.sort();
|
|
859
|
+
if (this.needsSorting) this.sort();
|
|
841
860
|
for (const model of this.models) {
|
|
842
861
|
if (model && model.type === type) yield model as T;
|
|
843
862
|
}
|
|
@@ -858,26 +877,34 @@ export class MarkerTrackHandler extends TrackHandler {
|
|
|
858
877
|
}
|
|
859
878
|
}
|
|
860
879
|
|
|
861
|
-
export class SignalTrackHandler extends
|
|
880
|
+
export class SignalTrackHandler extends TimelineTrackHandler {
|
|
862
881
|
models: Models.SignalMarkerModel[] = [];
|
|
863
882
|
didTrigger: boolean[] = [];
|
|
864
883
|
receivers: Array<SignalReceiver | null> = [];
|
|
865
884
|
|
|
866
|
-
|
|
867
|
-
// onEnable() {
|
|
868
|
-
// for (let i = 0; i < this.didTrigger?.length; i++) {
|
|
869
|
-
// this.didTrigger[i] = false;
|
|
870
|
-
// }
|
|
871
|
-
// }
|
|
885
|
+
private _lastTime: number = -1;
|
|
872
886
|
|
|
873
|
-
|
|
887
|
+
onEnable() {
|
|
888
|
+
// Reset state so signals fire fresh on replay
|
|
889
|
+
this._lastTime = -1;
|
|
890
|
+
for (let i = 0; i < this.didTrigger.length; i++) {
|
|
891
|
+
this.didTrigger[i] = false;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
onMuteChanged() {
|
|
896
|
+
// When unmuted, sync _lastTime to avoid stale comparisons
|
|
897
|
+
if (!this.track.muted) {
|
|
898
|
+
this._lastTime = -1;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
874
901
|
|
|
875
902
|
evaluate(time: number) {
|
|
876
903
|
if (this.track.muted) return;
|
|
877
904
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
905
|
+
let lastTime = this._lastTime;
|
|
906
|
+
if (lastTime === -1) lastTime = time;
|
|
907
|
+
this._lastTime = time;
|
|
881
908
|
|
|
882
909
|
const estimatedFrameLengthWithPadding = this.director.context.time.deltaTime * 1.5;
|
|
883
910
|
|
|
@@ -899,7 +926,6 @@ export class SignalTrackHandler extends TrackHandler {
|
|
|
899
926
|
isActive = true;
|
|
900
927
|
}
|
|
901
928
|
}
|
|
902
|
-
// console.log(time, td, isActive);
|
|
903
929
|
if (isActive) {
|
|
904
930
|
if (!wasTriggered) {
|
|
905
931
|
if (debug)
|
|
@@ -917,16 +943,59 @@ export class SignalTrackHandler extends TrackHandler {
|
|
|
917
943
|
}
|
|
918
944
|
}
|
|
919
945
|
}
|
|
920
|
-
else {
|
|
921
|
-
|
|
946
|
+
else if (!model.emitOnce) {
|
|
947
|
+
// Only reset didTrigger when time has moved backward past the signal
|
|
948
|
+
// (e.g. timeline looped or was scrubbed back). Don't reset just because
|
|
949
|
+
// the deltaTime-based activation window shrank on a fast frame.
|
|
950
|
+
if (time < model.time && lastTime >= model.time) {
|
|
922
951
|
this.didTrigger[i] = false;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Handles activation (visibility) of bound objects for a timeline activation track.
|
|
960
|
+
*
|
|
961
|
+
* Each clip on the track defines a time range during which the bound objects should be active (visible).
|
|
962
|
+
* @see TimelineTrackHandler for details on how tracks and clips work in general, and how to mutate them at runtime.
|
|
963
|
+
* @see PlayableDirector for how to control timeline playback and time.
|
|
964
|
+
* @see TimelineBuilder for how to create and configure timelines and tracks in the editor.
|
|
965
|
+
*/
|
|
966
|
+
export class TimelineActivationTrack extends TimelineTrackHandler {
|
|
967
|
+
|
|
968
|
+
evaluate(time: number) {
|
|
969
|
+
if (this.track.muted) return;
|
|
970
|
+
// NE-3241 / NE-3737: Don't evaluate when stopped (preserves "Leave as is" post-playback).
|
|
971
|
+
// But DO evaluate if the user explicitly called director.evaluate().
|
|
972
|
+
if (!this.director.isPlaying && !this.director._isUserEvaluation) return;
|
|
973
|
+
|
|
974
|
+
for (let i = 0; i < this.track.outputs.length; i++) {
|
|
975
|
+
const binding = this.track.outputs[i];
|
|
976
|
+
if (typeof binding !== "object" || binding === null) continue;
|
|
977
|
+
|
|
978
|
+
let isActive = false;
|
|
979
|
+
if (this.track.clips) {
|
|
980
|
+
for (const clip of this.track.clips) {
|
|
981
|
+
if (clip.start <= time && time <= clip.end) {
|
|
982
|
+
isActive = true;
|
|
983
|
+
break;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
const obj = binding as Object3D;
|
|
989
|
+
if (obj.visible !== undefined && obj.visible !== isActive) {
|
|
990
|
+
obj.visible = isActive;
|
|
991
|
+
if (debug) console.warn(this.director.name, "ActivationTrack-" + i, obj.name, isActive, time);
|
|
923
992
|
}
|
|
924
993
|
}
|
|
925
994
|
}
|
|
926
995
|
}
|
|
927
996
|
|
|
928
997
|
|
|
929
|
-
export class
|
|
998
|
+
export class TimelineControlTrack extends TimelineTrackHandler {
|
|
930
999
|
models: Array<Models.ClipModel> = [];
|
|
931
1000
|
timelines: Array<PlayableDirector | null> = [];
|
|
932
1001
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { type ITimelineAnimationCallbacks as ITimelineAnimationOverride } from "./PlayableDirector.js"
|
|
1
|
+
export { DirectorWrapMode, type ITimelineAnimationCallbacks as ITimelineAnimationOverride } from "./PlayableDirector.js"
|
|
2
2
|
export * from "./SignalAsset.js"
|
|
3
|
+
export * from "./TimelineBuilder.js"
|
|
3
4
|
export * from "./TimelineModels.js"
|
|
4
5
|
export * from "./TimelineTracks.js"
|
|
@@ -178,7 +178,6 @@ export class CursorFollow extends Behaviour {
|
|
|
178
178
|
* - Cursor that follows terrain or mesh surfaces
|
|
179
179
|
*
|
|
180
180
|
* **Important notes:**
|
|
181
|
-
* - Requires objects in the scene to have colliders for raycasting to work
|
|
182
181
|
* - Works best with {@link keepDistance} set to `false` to allow depth changes
|
|
183
182
|
* - Can be combined with {@link damping} for smooth surface following
|
|
184
183
|
* - The raycast uses the physics system's raycast functionality
|