@needle-tools/engine 4.9.3-next.0facab6 → 4.10.0-beta

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/{needle-engine.bundle-DAo7BPxQ.umd.cjs → needle-engine.bundle-42AmEGfk.umd.cjs} +127 -126
  3. package/dist/{needle-engine.bundle-DP2gYtOQ.min.js → needle-engine.bundle-C6zhyLF5.min.js} +128 -127
  4. package/dist/{needle-engine.bundle-TvT7wv7z.js → needle-engine.bundle-Dj6faVbC.js} +4967 -4864
  5. package/dist/needle-engine.js +414 -413
  6. package/dist/needle-engine.min.js +1 -1
  7. package/dist/needle-engine.umd.cjs +1 -1
  8. package/lib/engine/codegen/register_types.js +2 -0
  9. package/lib/engine/codegen/register_types.js.map +1 -1
  10. package/lib/engine-components/Renderer.d.ts +2 -2
  11. package/lib/engine-components/Renderer.js +6 -4
  12. package/lib/engine-components/Renderer.js.map +1 -1
  13. package/lib/engine-components/codegen/components.d.ts +1 -0
  14. package/lib/engine-components/codegen/components.js +1 -0
  15. package/lib/engine-components/codegen/components.js.map +1 -1
  16. package/lib/engine-components/timeline/PlayableDirector.d.ts +28 -6
  17. package/lib/engine-components/timeline/PlayableDirector.js +60 -26
  18. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  19. package/lib/engine-components/timeline/TimelineModels.d.ts +3 -0
  20. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  21. package/lib/engine-components/timeline/TimelineTracks.d.ts +7 -0
  22. package/lib/engine-components/timeline/TimelineTracks.js +19 -0
  23. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  24. package/lib/engine-components/web/ScrollFollow.d.ts +14 -4
  25. package/lib/engine-components/web/ScrollFollow.js +139 -25
  26. package/lib/engine-components/web/ScrollFollow.js.map +1 -1
  27. package/package.json +2 -2
  28. package/src/engine/codegen/register_types.ts +2 -0
  29. package/src/engine-components/Renderer.ts +6 -4
  30. package/src/engine-components/codegen/components.ts +1 -0
  31. package/src/engine-components/timeline/PlayableDirector.ts +79 -34
  32. package/src/engine-components/timeline/TimelineModels.ts +3 -0
  33. package/src/engine-components/timeline/TimelineTracks.ts +22 -0
  34. package/src/engine-components/web/ScrollFollow.ts +177 -24
@@ -8,6 +8,7 @@ import { Object3D } from "three";
8
8
  import { Mathf } from "../../engine/engine_math.js";
9
9
  import { serializable } from "../../engine/engine_serialization.js";
10
10
  import { getBoundingBox } from "../../engine/engine_three_utils.js";
11
+ import { getParam } from "../../engine/engine_utils.js";
11
12
  import { Animation } from "../Animation.js";
12
13
  import { Animator } from "../Animator.js";
13
14
  import { AudioSource } from "../AudioSource.js";
@@ -16,6 +17,7 @@ import { EventList } from "../EventList.js";
16
17
  import { Light } from "../Light.js";
17
18
  import { SplineWalker } from "../splines/SplineWalker.js";
18
19
  import { PlayableDirector } from "../timeline/PlayableDirector.js";
20
+ const debug = getParam("debugscroll");
19
21
  /**
20
22
  * The ScrollFollow component allows you to link the scroll position of the page (or a specific element) to one or more target objects.
21
23
  * This can be used to create scroll-based animations, audio playback, or other effects. For example you can link the scroll position to a timeline (PlayableDirector) to create scroll-based storytelling effects or to an Animator component to change the animation state based on scroll.
@@ -67,6 +69,7 @@ export class ScrollFollow extends Behaviour {
67
69
  */
68
70
  invert = false;
69
71
  /**
72
+ * **Experimental - might change in future updates**
70
73
  * If set, the scroll position will be read from the specified element instead of the window.
71
74
  * Use a CSS selector to specify the element, e.g. `#my-scrollable-div` or `.scroll-container`.
72
75
  * @default null
@@ -81,15 +84,19 @@ export class ScrollFollow extends Behaviour {
81
84
  * Current scroll value in "pages" (0 = top of page, 1 = bottom of page)
82
85
  */
83
86
  get currentValue() {
84
- return this.current_value;
87
+ return this._current_value;
85
88
  }
86
- current_value = 0;
87
- target_value = 0;
88
- applied_value = -1;
89
+ _current_value = 0;
90
+ _target_value = 0;
91
+ _appliedValue = -1;
92
+ _scrollStart = 0;
93
+ _scrollEnd = 0;
94
+ _scrollValue = 0;
95
+ _scrollContainerHeight = 0;
89
96
  /** @internal */
90
97
  onEnable() {
91
98
  window.addEventListener("wheel", this.updateCurrentScrollValue, { passive: true });
92
- this.applied_value = -1;
99
+ this._appliedValue = -1;
93
100
  }
94
101
  /** @internal */
95
102
  onDisable() {
@@ -98,21 +105,25 @@ export class ScrollFollow extends Behaviour {
98
105
  /** @internal */
99
106
  lateUpdate() {
100
107
  this.updateCurrentScrollValue();
101
- // apply damping if any
102
- if (this.damping > 0) {
103
- this.current_value = Mathf.lerp(this.current_value, this.target_value, this.context.time.deltaTime / this.damping);
104
- }
105
- else {
106
- this.current_value = this.target_value;
108
+ if (this._target_value >= 0) {
109
+ if (this.damping > 0) { // apply damping
110
+ this._current_value = Mathf.lerp(this._current_value, this._target_value, this.context.time.deltaTime / this.damping);
111
+ if (Math.abs(this._current_value - this._target_value) < 0.001) {
112
+ this._current_value = this._target_value;
113
+ }
114
+ }
115
+ else {
116
+ this._current_value = this._target_value;
117
+ }
107
118
  }
108
- if (this.current_value !== this.applied_value) {
109
- this.applied_value = this.current_value;
119
+ if (this._current_value !== this._appliedValue) {
120
+ this._appliedValue = this._current_value;
110
121
  let defaultPrevented = false;
111
122
  if (this.changed.listenerCount > 0) {
112
123
  // fire change event
113
124
  const event = {
114
125
  type: "change",
115
- value: this.current_value,
126
+ value: this._current_value,
116
127
  component: this,
117
128
  preventDefault: () => { event.defaultPrevented = true; },
118
129
  defaultPrevented: false,
@@ -122,19 +133,28 @@ export class ScrollFollow extends Behaviour {
122
133
  }
123
134
  // if not prevented apply scroll
124
135
  if (!defaultPrevented) {
125
- const value = this.invert ? 1 - this.current_value : this.current_value;
136
+ const value = this.invert ? 1 - this._current_value : this._current_value;
137
+ const height = this._rangeEndValue - this._rangeStartValue;
138
+ const pixelValue = this._rangeStartValue + value * height;
126
139
  // apply scroll to target(s)
127
140
  if (Array.isArray(this.target)) {
128
- this.target.forEach(t => t && ScrollFollow.applyScroll(t, value));
141
+ this.target.forEach(t => t && this.applyScroll(t, value));
129
142
  }
130
143
  else if (this.target) {
131
- ScrollFollow.applyScroll(this.target, value);
144
+ this.applyScroll(this.target, value);
145
+ }
146
+ if (debug && this.context.time.frame % 30 === 0) {
147
+ console.debug(`[ScrollFollow] ${this._current_value.toFixed(5)} — ${(this._target_value * 100).toFixed(0)}%`);
132
148
  }
133
149
  }
134
150
  }
135
151
  }
136
152
  _lastSelectorValue = null;
137
153
  _lastSelectorElement = null;
154
+ /** Top y */
155
+ _rangeStartValue = 0;
156
+ /** Bottom y */
157
+ _rangeEndValue = 0;
138
158
  updateCurrentScrollValue = () => {
139
159
  switch (this.mode) {
140
160
  case "window":
@@ -145,25 +165,35 @@ export class ScrollFollow extends Behaviour {
145
165
  }
146
166
  if (this._lastSelectorElement) {
147
167
  const rect = this._lastSelectorElement.getBoundingClientRect();
148
- this.target_value = -rect.top / (rect.height - window.innerHeight);
149
- if (isNaN(this.target_value) || !isFinite(this.target_value))
150
- this.target_value = 0;
168
+ this._scrollStart = rect.top + window.scrollY;
169
+ this._scrollEnd = rect.height - window.innerHeight;
170
+ this._scrollValue = -rect.top;
171
+ this._target_value = -rect.top / (rect.height - window.innerHeight);
172
+ this._rangeStartValue = rect.top + window.scrollY;
173
+ this._rangeEndValue = this._rangeStartValue + rect.height - window.innerHeight;
174
+ this._scrollContainerHeight = rect.height;
151
175
  break;
152
176
  }
153
177
  }
154
178
  else {
155
- this.target_value = window.scrollY / (document.body.scrollHeight - window.innerHeight);
179
+ this._scrollStart = 0;
180
+ this._scrollEnd = window.document.body.scrollHeight - window.innerHeight;
181
+ this._scrollValue = window.scrollY;
182
+ this._target_value = this._scrollValue / (this._scrollEnd || 1);
183
+ this._rangeStartValue = 0;
184
+ this._rangeEndValue = document.body.scrollHeight;
185
+ this._scrollContainerHeight = window.innerHeight;
156
186
  }
157
- if (isNaN(this.target_value) || !isFinite(this.target_value))
158
- this.target_value = 0;
159
187
  break;
160
188
  }
189
+ if (isNaN(this._target_value) || !isFinite(this._target_value))
190
+ this._target_value = -1;
161
191
  };
162
- static applyScroll(target, value) {
192
+ applyScroll(target, value) {
163
193
  if (!target)
164
194
  return;
165
195
  if (target instanceof PlayableDirector) {
166
- target.time = value * target.duration;
196
+ this.handleTimelineTarget(target, value);
167
197
  if (!target.isPlaying)
168
198
  target.evaluate();
169
199
  }
@@ -204,6 +234,88 @@ export class ScrollFollow extends Behaviour {
204
234
  }
205
235
  }
206
236
  }
237
+ handleTimelineTarget(director, value) {
238
+ const duration = director.duration;
239
+ let scrollRegionStart = Infinity;
240
+ let scrollRegionEnd = 0;
241
+ markersArray.length = 0;
242
+ for (const marker of director.foreachMarker("ScrollMarker")) {
243
+ // Get marker elements from DOM
244
+ if (marker.selector?.length && (marker.element === undefined || marker.needsUpdate === true || /** element is not in DOM anymore? */ (!marker.element?.parentNode))) {
245
+ marker.needsUpdate = false;
246
+ try {
247
+ marker.element = document.querySelector(marker.selector) || null;
248
+ if (debug)
249
+ console.debug("ScrollMarker found on page", marker.element, marker.selector);
250
+ }
251
+ catch (error) {
252
+ marker.element = null;
253
+ console.error("ScrollMarker selector is not valid: " + marker.selector + "\n", error);
254
+ }
255
+ }
256
+ // skip markers without element (e.g. if the selector didn't return any element)
257
+ if (!marker.element)
258
+ continue;
259
+ markersArray.push(marker);
260
+ const top = marker.element.offsetTop;
261
+ const height = marker.element.offsetHeight;
262
+ const bottom = top + height;
263
+ if (top < scrollRegionStart) {
264
+ scrollRegionStart = top;
265
+ }
266
+ if (bottom > scrollRegionEnd) {
267
+ scrollRegionEnd = bottom;
268
+ }
269
+ }
270
+ const currentTop = this._scrollValue;
271
+ const currentBottom = currentTop + this._scrollContainerHeight;
272
+ weightsArray.length = 0;
273
+ let sum = 0;
274
+ let markerCount = 0;
275
+ for (const marker of markersArray) {
276
+ if (!marker.element)
277
+ continue;
278
+ const top = marker.element.offsetTop;
279
+ const height = marker.element.offsetHeight;
280
+ const bottom = top + height;
281
+ let overlap = 0;
282
+ // TODO: if we have two marker sections where no HTML overlaps (vor example because some large section is between them) we probably want to still virtually interpolate between them slowly in that region
283
+ if (bottom < currentTop) {
284
+ // marker is above scroll region
285
+ overlap = 0;
286
+ }
287
+ else if (top > currentBottom) {
288
+ // marker is below scroll region
289
+ overlap = 0;
290
+ }
291
+ else {
292
+ // calculate overlap in pixels
293
+ const overlapTop = Math.max(top, currentTop);
294
+ const overlapBottom = Math.min(bottom, currentBottom);
295
+ overlap = Math.max(0, overlapBottom - overlapTop);
296
+ // console.log(marker.element.className, overlap)
297
+ }
298
+ markerCount += 1;
299
+ if (overlap > 0) {
300
+ weightsArray.push({ time: marker.time, weight: overlap });
301
+ sum += overlap;
302
+ }
303
+ }
304
+ if (weightsArray.length <= 0 && markerCount <= 0) {
305
+ director.time = value * duration;
306
+ }
307
+ else if (weightsArray.length > 0) {
308
+ // normalize and calculate weighted time
309
+ let time = weightsArray[0].time;
310
+ for (const o of weightsArray) {
311
+ const weight = o.weight / Math.max(0.00001, sum);
312
+ // lerp time based on weight
313
+ const diff = Math.abs(o.time - time);
314
+ time += diff * weight;
315
+ }
316
+ director.time = time;
317
+ }
318
+ }
207
319
  }
208
320
  __decorate([
209
321
  serializable([Behaviour, Object3D])
@@ -223,4 +335,6 @@ __decorate([
223
335
  __decorate([
224
336
  serializable(EventList)
225
337
  ], ScrollFollow.prototype, "changed", void 0);
338
+ const weightsArray = [];
339
+ const markersArray = [];
226
340
  //# sourceMappingURL=ScrollFollow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollFollow.js","sourceRoot":"","sources":["../../../src/engine-components/web/ScrollFollow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScrollFollow.js","sourceRoot":"","sources":["../../../src/engine-components/web/ScrollFollow.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/engine",
3
- "version": "4.9.3-next.0facab6",
3
+ "version": "4.10.0-beta",
4
4
  "description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.",
5
5
  "main": "dist/needle-engine.min.js",
6
6
  "exports": {
@@ -168,4 +168,4 @@
168
168
  "module": "lib/needle-engine.js",
169
169
  "typings": "lib/needle-engine.d.ts",
170
170
  "types": "lib/needle-engine.d.ts"
171
- }
171
+ }
@@ -108,6 +108,7 @@ import { PlayableDirector } from "../../engine-components/timeline/PlayableDirec
108
108
  import { SignalReceiver } from "../../engine-components/timeline/SignalAsset.js";
109
109
  import { AnimationTrackHandler } from "../../engine-components/timeline/TimelineTracks.js";
110
110
  import { AudioTrackHandler } from "../../engine-components/timeline/TimelineTracks.js";
111
+ import { MarkerTrackHandler } from "../../engine-components/timeline/TimelineTracks.js";
111
112
  import { SignalTrackHandler } from "../../engine-components/timeline/TimelineTracks.js";
112
113
  import { ControlTrackHandler } from "../../engine-components/timeline/TimelineTracks.js";
113
114
  import { TransformGizmo } from "../../engine-components/TransformGizmo.js";
@@ -265,6 +266,7 @@ TypeStore.add("PlayableDirector", PlayableDirector);
265
266
  TypeStore.add("SignalReceiver", SignalReceiver);
266
267
  TypeStore.add("AnimationTrackHandler", AnimationTrackHandler);
267
268
  TypeStore.add("AudioTrackHandler", AudioTrackHandler);
269
+ TypeStore.add("MarkerTrackHandler", MarkerTrackHandler);
268
270
  TypeStore.add("SignalTrackHandler", SignalTrackHandler);
269
271
  TypeStore.add("ControlTrackHandler", ControlTrackHandler);
270
272
  TypeStore.add("TransformGizmo", TransformGizmo);
@@ -304,10 +304,12 @@ export class Renderer extends Behaviour implements IRenderer {
304
304
  return this._sharedMeshes;
305
305
  }
306
306
 
307
+ // @ts-ignore
307
308
  get sharedMaterial(): SharedMaterial {
308
- return this.sharedMaterials[0] as SharedMaterial;
309
+ return (this.sharedMaterials?.[0]) as SharedMaterial;
309
310
  }
310
311
 
312
+ // @ts-ignore
311
313
  set sharedMaterial(mat: SharedMaterial) {
312
314
  const cur = this.sharedMaterials[0];
313
315
  if (cur === mat) return;
@@ -315,12 +317,12 @@ export class Renderer extends Behaviour implements IRenderer {
315
317
  this.applyLightmapping();
316
318
  }
317
319
 
318
- /**@deprecated please use sharedMaterial */
320
+ /**@deprecated Use sharedMaterial */
319
321
  get material(): SharedMaterial {
320
- return this.sharedMaterials[0] as SharedMaterial;
322
+ return this.sharedMaterials?.[0] as SharedMaterial;
321
323
  }
322
324
 
323
- /**@deprecated please use sharedMaterial */
325
+ /**@deprecated Use sharedMaterial */
324
326
  set material(mat: SharedMaterial) {
325
327
  this.sharedMaterial = mat;
326
328
  }
@@ -169,6 +169,7 @@ export { SignalReceiverEvent } from "../timeline/SignalAsset.js";
169
169
  export { SignalReceiver } from "../timeline/SignalAsset.js";
170
170
  export { AnimationTrackHandler } from "../timeline/TimelineTracks.js";
171
171
  export { AudioTrackHandler } from "../timeline/TimelineTracks.js";
172
+ export { MarkerTrackHandler } from "../timeline/TimelineTracks.js";
172
173
  export { SignalTrackHandler } from "../timeline/TimelineTracks.js";
173
174
  export { ControlTrackHandler } from "../timeline/TimelineTracks.js";
174
175
  export { TransformGizmo } from "../TransformGizmo.js";
@@ -293,6 +293,41 @@ export class PlayableDirector extends Behaviour {
293
293
  return this._audioTracks;
294
294
  }
295
295
 
296
+ /**
297
+ * @returns all signal tracks of the timeline
298
+ */
299
+ get signalTracks(): Tracks.SignalTrackHandler[] {
300
+ return this._signalTracks;
301
+ }
302
+
303
+ /**
304
+ * @returns all marker tracks of the timeline
305
+ */
306
+ get markerTracks(): Tracks.MarkerTrackHandler[] {
307
+ return this._markerTracks;
308
+ }
309
+
310
+ /**
311
+ * Iterates over all markers of the timeline, optionally filtering by type
312
+ *
313
+ * @example
314
+ * ```ts
315
+ * // Iterate over all ScrollMarkers in the timeline
316
+ * for (const marker of director.foreachMarker<{selector:string}>("ScrollMarker")) {
317
+ * console.log(marker.time, marker.selector);
318
+ * }
319
+ * ```
320
+ *
321
+ */
322
+ *foreachMarker<T extends Record<string, any>>(type: string | null = null): Generator<(T & Models.MarkerModel)> {
323
+ for (const track of this._markerTracks) {
324
+ for (const marker of track.foreachMarker<T>(type)) {
325
+ yield marker as T & Models.MarkerModel;
326
+ }
327
+ }
328
+ }
329
+
330
+
296
331
  private _guidsMap?: GuidsMap;
297
332
  /** @internal */
298
333
  resolveGuids(map: GuidsMap) {
@@ -309,16 +344,18 @@ export class PlayableDirector extends Behaviour {
309
344
  private _time: number = 0;
310
345
  private _duration: number = 0;
311
346
  private _weight: number = 1;
312
- private _animationTracks: Array<Tracks.AnimationTrackHandler> = [];
313
- private _audioTracks: Array<Tracks.AudioTrackHandler> = [];
314
- private _signalTracks: Array<Tracks.SignalTrackHandler> = [];
315
- private _controlTracks: Array<Tracks.ControlTrackHandler> = [];
316
- private _customTracks: Array<Tracks.TrackHandler> = [];
317
-
318
- private _allTracks: Array<Array<Tracks.TrackHandler>> = [
347
+ private readonly _animationTracks: Array<Tracks.AnimationTrackHandler> = [];
348
+ private readonly _audioTracks: Array<Tracks.AudioTrackHandler> = [];
349
+ private readonly _signalTracks: Array<Tracks.SignalTrackHandler> = [];
350
+ private readonly _markerTracks: Array<Tracks.MarkerTrackHandler> = [];
351
+ private readonly _controlTracks: Array<Tracks.ControlTrackHandler> = [];
352
+ private readonly _customTracks: Array<Tracks.TrackHandler> = [];
353
+
354
+ private readonly _allTracks: Array<Array<Tracks.TrackHandler>> = [
319
355
  this._animationTracks,
320
356
  this._audioTracks,
321
357
  this._signalTracks,
358
+ this._markerTracks,
322
359
  this._controlTracks,
323
360
  this._customTracks
324
361
  ];
@@ -335,7 +372,7 @@ export class PlayableDirector extends Behaviour {
335
372
  }
336
373
  }
337
374
 
338
- private *internalUpdate() {
375
+ private * internalUpdate() {
339
376
  while (this._isPlaying && this.activeAndEnabled) {
340
377
  if (!this._isPaused && this._isPlaying) {
341
378
  this._time += this.context.time.deltaTime * this.speed;
@@ -415,26 +452,18 @@ export class PlayableDirector extends Behaviour {
415
452
  }
416
453
  }
417
454
 
418
- // When timeline reaches the end "stop()" is called which is evaluating with time 0
419
- // We don't want to re-evaluate the animation then in case the timeline is blended with the Animator
420
- // e.g then the timeline animation at time 0 is 100% applied on top of the animator animation
421
- if (!this._isStopping) {
422
- for (const handler of this._animationTracks) {
455
+ for (const track of this._allTracks) {
456
+ for (const handler of track) {
457
+ // When timeline reaches the end "stop()" is called which is evaluating with time 0
458
+ // We don't want to re-evaluate the animation then in case the timeline is blended with the Animator
459
+ // e.g then the timeline animation at time 0 is 100% applied on top of the animator animation
460
+
461
+ if (this._isStopping && handler instanceof Tracks.AnimationTrackHandler) {
462
+ continue;
463
+ }
423
464
  handler.evaluate(time);
424
465
  }
425
466
  }
426
- for (const handler of this._audioTracks) {
427
- handler.evaluate(time);
428
- }
429
- for (const sig of this._signalTracks) {
430
- sig.evaluate(time);
431
- }
432
- for (const ctrl of this._controlTracks) {
433
- ctrl.evaluate(time);
434
- }
435
- for (const cust of this._customTracks) {
436
- cust.evaluate(time);
437
- }
438
467
  }
439
468
 
440
469
  private resolveBindings() {
@@ -630,26 +659,42 @@ export class PlayableDirector extends Behaviour {
630
659
  }
631
660
  }
632
661
  else if (track.type === Models.TrackType.Marker) {
633
- const signalHandler: Tracks.SignalTrackHandler = new Tracks.SignalTrackHandler();
634
- signalHandler.director = this;
635
- signalHandler.track = track;
662
+
636
663
  if (track.markers) {
664
+ // For the marker track we create both a signal track handler AND a markertrack handler because a marker track can have signals and markers
665
+ const signalHandler: Tracks.SignalTrackHandler = new Tracks.SignalTrackHandler();
666
+ signalHandler.director = this;
667
+ signalHandler.track = track;
668
+
669
+ const markerHandler: Tracks.MarkerTrackHandler = new Tracks.MarkerTrackHandler();
670
+ markerHandler.director = this;
671
+ markerHandler.track = track;
672
+
637
673
  for (const marker of track.markers) {
638
674
  switch (marker.type) {
639
675
  case Models.MarkerType.Signal:
640
676
  signalHandler.models.push(marker as Models.SignalMarkerModel);
641
677
  signalHandler.didTrigger.push(false);
642
678
  break;
679
+ default:
680
+ markerHandler.models.push(marker);
681
+ break;
643
682
  }
644
683
  }
645
- }
646
- if (signalHandler !== null && signalHandler.models.length > 0) {
647
- const rec = GameObject.getComponent(this.gameObject, SignalReceiver);
648
- if (rec) {
649
- signalHandler.receivers.push(rec);
650
- this._signalTracks.push(signalHandler);
684
+
685
+ if (signalHandler !== null && signalHandler.models.length > 0) {
686
+ const rec = GameObject.getComponent(this.gameObject, SignalReceiver);
687
+ if (rec) {
688
+ signalHandler.receivers.push(rec);
689
+ this._signalTracks.push(signalHandler);
690
+ }
691
+ }
692
+
693
+ if (markerHandler !== null && markerHandler.models.length > 0) {
694
+ this._markerTracks.push(markerHandler);
651
695
  }
652
696
  }
697
+
653
698
  }
654
699
  else if (track.type === Models.TrackType.Signal) {
655
700
  const handler = new Tracks.SignalTrackHandler();
@@ -1,4 +1,5 @@
1
1
  import { AnimationClip, Object3D, Quaternion, Vector3 } from "three";
2
+ import { Behavior } from "three-mesh-ui";
2
3
 
3
4
  export declare type TimelineAssetModel = {
4
5
  name: string;
@@ -90,3 +91,5 @@ export declare class SignalMarkerModel extends MarkerModel {
90
91
  emitOnce: boolean;
91
92
  asset: string;
92
93
  }
94
+
95
+ export type ScrollMarkerModel = MarkerModel & { selector: string };
@@ -830,6 +830,28 @@ export class AudioTrackHandler extends TrackHandler {
830
830
  }
831
831
  }
832
832
 
833
+ export class MarkerTrackHandler extends TrackHandler {
834
+ models: Array<Models.MarkerModel & Record<string, any>> = [];
835
+ isDirty = true;
836
+
837
+ *foreachMarker<T>(type: string | null = null) {
838
+ for (const model of this.models) {
839
+ if (model && model.type === type) yield model as T;
840
+ }
841
+ }
842
+
843
+ onEnable() {
844
+ this.isDirty = true;
845
+ }
846
+
847
+ evaluate(_time: number) {
848
+ if (this.isDirty) {
849
+ this.isDirty = false;
850
+ this.models.sort((a, b) => a.time - b.time);
851
+ }
852
+ }
853
+ }
854
+
833
855
  export class SignalTrackHandler extends TrackHandler {
834
856
  models: Models.SignalMarkerModel[] = [];
835
857
  didTrigger: boolean[] = [];