@needle-tools/engine 4.10.0-beta.1 → 4.10.0-beta.2

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 (46) hide show
  1. package/dist/{needle-engine.bundle-Dj2DYdMY.js → needle-engine.bundle-BTgC7uAm.js} +6867 -6822
  2. package/dist/{needle-engine.bundle-6so_os_w.umd.cjs → needle-engine.bundle-OTBqjiCd.umd.cjs} +131 -131
  3. package/dist/{needle-engine.bundle-Djy6H4lx.min.js → needle-engine.bundle-g2_JEHcF.min.js} +135 -135
  4. package/dist/needle-engine.js +15 -14
  5. package/dist/needle-engine.min.js +1 -1
  6. package/dist/needle-engine.umd.cjs +1 -1
  7. package/lib/engine/engine_camera.js +2 -2
  8. package/lib/engine/engine_camera.js.map +1 -1
  9. package/lib/engine/engine_lightdata.d.ts +3 -3
  10. package/lib/engine/engine_lightdata.js +10 -10
  11. package/lib/engine/engine_lightdata.js.map +1 -1
  12. package/lib/engine/engine_physics_rapier.js +4 -0
  13. package/lib/engine/engine_physics_rapier.js.map +1 -1
  14. package/lib/engine/engine_scenelighting.d.ts +1 -1
  15. package/lib/engine/engine_scenelighting.js +4 -5
  16. package/lib/engine/engine_scenelighting.js.map +1 -1
  17. package/lib/engine/engine_utils.d.ts +3 -1
  18. package/lib/engine/engine_utils.js +11 -0
  19. package/lib/engine/engine_utils.js.map +1 -1
  20. package/lib/engine/extensions/NEEDLE_lightmaps.js +1 -1
  21. package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
  22. package/lib/engine/webcomponents/needle-engine.js +22 -0
  23. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  24. package/lib/engine-components/Renderer.js +2 -0
  25. package/lib/engine-components/Renderer.js.map +1 -1
  26. package/lib/engine-components/Skybox.js +22 -4
  27. package/lib/engine-components/Skybox.js.map +1 -1
  28. package/lib/engine-components/utils/LookAt.js +1 -1
  29. package/lib/engine-components/utils/LookAt.js.map +1 -1
  30. package/lib/engine-components/web/ScrollFollow.js +80 -70
  31. package/lib/engine-components/web/ScrollFollow.js.map +1 -1
  32. package/lib/engine-components/web/ViewBox.js +12 -9
  33. package/lib/engine-components/web/ViewBox.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/engine/engine_camera.ts +2 -2
  36. package/src/engine/engine_lightdata.ts +11 -11
  37. package/src/engine/engine_physics_rapier.ts +3 -0
  38. package/src/engine/engine_scenelighting.ts +5 -6
  39. package/src/engine/engine_utils.ts +12 -0
  40. package/src/engine/extensions/NEEDLE_lightmaps.ts +1 -1
  41. package/src/engine/webcomponents/needle-engine.ts +33 -6
  42. package/src/engine-components/Renderer.ts +2 -0
  43. package/src/engine-components/Skybox.ts +26 -7
  44. package/src/engine-components/utils/LookAt.ts +1 -1
  45. package/src/engine-components/web/ScrollFollow.ts +82 -70
  46. package/src/engine-components/web/ViewBox.ts +12 -9
@@ -4,10 +4,11 @@ import { element } from "three/src/nodes/TSL.js";
4
4
  import { Context } from "../../engine/engine_context.js";
5
5
  import { Mathf } from "../../engine/engine_math.js";
6
6
  import { serializable } from "../../engine/engine_serialization.js";
7
- import { getBoundingBox } from "../../engine/engine_three_utils.js";
7
+ import { getBoundingBox, setVisibleInCustomShadowRendering } from "../../engine/engine_three_utils.js";
8
8
  import { getParam } from "../../engine/engine_utils.js";
9
9
  import { Animation } from "../Animation.js";
10
10
  import { Animator } from "../Animator.js";
11
+ import { MarkerTrackHandler } from "../api.js";
11
12
  import { AudioSource } from "../AudioSource.js";
12
13
  import { Behaviour } from "../Component.js";
13
14
  import { EventList } from "../EventList.js";
@@ -308,17 +309,17 @@ export class ScrollFollow extends Behaviour {
308
309
  try {
309
310
  marker.element = tryGetElementsForSelector(index, marker.name) as HTMLElement | null;
310
311
  if (debug) console.debug("ScrollMarker found on page", marker.element, marker.name);
311
- // if (!marker.element) {
312
- // marker.timeline = undefined;
313
- // continue;
314
- // }
315
- // else {
316
- // /** @ts-ignore */
317
- // marker.timeline = new ViewTimeline({
318
- // subject: marker.element,
319
- // axis: 'block', // https://drafts.csswg.org/scroll-animations/#scroll-notation
320
- // });
321
- // }
312
+ if (!marker.element) {
313
+ marker.timeline = undefined;
314
+ continue;
315
+ }
316
+ else {
317
+ /** @ts-ignore */
318
+ marker.timeline = new ViewTimeline({
319
+ subject: marker.element,
320
+ axis: 'block', // https://drafts.csswg.org/scroll-animations/#scroll-notation
321
+ });
322
+ }
322
323
  }
323
324
  catch (error) {
324
325
  marker.element = null;
@@ -349,57 +350,74 @@ export class ScrollFollow extends Behaviour {
349
350
 
350
351
  weightsArray.length = 0;
351
352
  let sum = 0;
353
+ const oneFrameTime = 1 / 60;
352
354
 
353
355
  // We keep a separate count here in case there are some markers that could not be resolved so point to *invalid* elements - the timeline should fallback to 0-1 scroll behaviour then
354
356
  let markerCount = 0;
355
- for (const marker of markersArray) {
356
-
357
+ for (let i = 0; i < markersArray.length; i++) {
358
+ const marker = markersArray[i];
357
359
  if (!marker.element) continue;
360
+ const nextMarker = markersArray[i + 1];
361
+
362
+ const nextTime = nextMarker
363
+ ? (nextMarker.time - oneFrameTime)
364
+ : duration;
358
365
 
359
366
  markerCount += 1;
360
367
 
361
- // const timeline = marker.timeline;
362
- // if (timeline) {
363
- // const time01 = calculateTimelinePositionNormalized(timeline);
364
- // if (time01 > 0 && time01 <= 1) {
365
- // const overlap = calculateTimelinePositionNormalized(timeline!);
366
- // const weight = overlap;
367
- // // console.log(marker.element.className, time01)
368
- // weightsArray.push({ time: marker.time, weight: weight });
369
- // sum += weight;
370
- // }
371
- // }
372
- // continue;
368
+ const timeline = marker.timeline;
369
+ if (timeline) {
370
+ const time01 = calculateTimelinePositionNormalized(timeline);
371
+ // remap 0-1 to 0 - 1 - 0 (full weight at center)
372
+ const weight = 1 - Math.abs(time01 - 0.5) * 2;
373
+ if (time01 > 0 && time01 <= 1) {
374
+ const lerpTime = marker.time + (nextTime - marker.time) * time01;
375
+ weightsArray.push({ time: lerpTime, weight: weight });
376
+ sum += weight;
377
+ }
378
+ // Before the first marker is reached
379
+ else if (i === 0 && time01 <= 0) {
380
+ weightsArray.push({ time: 0, weight: 1 });
381
+ sum += 1;
382
+ }
383
+ // After the last marker is reached
384
+ else if (i === markersArray.length - 1 && time01 >= 1) {
385
+ weightsArray.push({ time: duration, weight: 1 });
386
+ sum += 1;
387
+ }
388
+ }
389
+ continue;
373
390
  // if(this.context.time.frame % 10 === 0) console.log(marker.element?.className, timeline, calculateTimelinePositionNormalized(timeline!));
374
391
 
375
- const top = marker.element.offsetTop;
376
- const height = marker.element.offsetHeight;
377
- const bottom = top + height;
378
- let overlap = 0;
392
+ // const top = marker.element.offsetTop - this._scrollContainerHeight;
393
+ // const height = marker.element.offsetHeight + this._scrollContainerHeight;
394
+ // const bottom = top + height;
395
+ // let overlap = 0;
379
396
 
380
- // 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
397
+ // // 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
381
398
 
382
- if (bottom < currentTop) {
383
- // marker is above scroll region
384
- overlap = 0;
385
- }
386
- else if (top > currentBottom) {
387
- // marker is below scroll region
388
- overlap = 0;
389
- }
390
- else {
391
- // calculate overlap in pixels
392
- const overlapTop = Math.max(top, currentTop);
393
- const overlapBottom = Math.min(bottom, currentBottom);
394
- overlap = Math.max(0, overlapBottom - overlapTop);
395
- }
399
+ // if (bottom < currentTop) {
400
+ // // marker is above scroll region
401
+ // overlap = 0;
402
+ // }
403
+ // else if (top > currentBottom) {
404
+ // // marker is below scroll region
405
+ // overlap = 0;
406
+ // }
407
+ // else {
408
+ // // calculate overlap in pixels
409
+ // const overlapTop = Math.max(top, currentTop);
410
+ // const overlapBottom = Math.min(bottom, currentBottom);
411
+ // const height = Math.max(1, currentBottom - currentTop);
412
+ // overlap = Math.max(0, overlapBottom - overlapTop);
413
+ // }
396
414
 
397
- markerCount += 1;
415
+ // // if(this.context.time.frame % 20 === 0) console.log(overlap)
398
416
 
399
- if (overlap > 0) {
400
- weightsArray.push({ time: marker.time, weight: overlap });
401
- sum += overlap;
402
- }
417
+ // if (overlap > 0) {
418
+ // weightsArray.push({ time: marker.time, weight: overlap });
419
+ // sum += overlap;
420
+ // }
403
421
  }
404
422
 
405
423
  if (weightsArray.length <= 0 && markerCount <= 0) {
@@ -407,19 +425,23 @@ export class ScrollFollow extends Behaviour {
407
425
  }
408
426
  else if (weightsArray.length > 0) {
409
427
  // normalize and calculate weighted time
410
- let time = 0;
411
- for (const entry of weightsArray) {
412
- const weight = entry.weight / Math.max(0.00001, sum);
413
- // console.log(weight.toFixed(2))
414
- // lerp time based on weight
415
- const diff = Math.abs(entry.time - time);
416
- time += diff * weight;
428
+ let time = weightsArray[0].time; // fallback to first time
429
+ if (weightsArray.length > 1) {
430
+ for (const entry of weightsArray) {
431
+ const weight = entry.weight / Math.max(0.00001, sum);
432
+ // console.log(weight.toFixed(2))
433
+ // lerp time based on weight
434
+ const diff = Math.abs(entry.time - time);
435
+ time += diff * weight;
436
+ }
417
437
  }
418
- // console.log(time.toFixed(2), [...weightsArray])
419
- if (this.damping <= 0)
438
+ if (debug && this.context.time.frame % 20 === 0) console.log(time.toFixed(3), [...weightsArray])
439
+ if (this.damping <= 0) {
420
440
  director.time = time;
421
- else
441
+ }
442
+ else {
422
443
  director.time = Mathf.lerp(director.time, time, this.context.time.deltaTime / this.damping);
444
+ }
423
445
  }
424
446
  }
425
447
 
@@ -506,16 +528,6 @@ function calculateTimelinePositionNormalized(timeline: ViewTimeline) {
506
528
  const t01 = currentTime.unit === "seconds" ? (currentTime.value / durationValue) : (currentTime.value / 100);
507
529
  return t01;
508
530
  }
509
- function calculateNormalizedOverlap(timeline: ViewTimeline) {
510
- if (!timeline.source) return 0;
511
- const start = timeline.startOffset;
512
- const end = timeline.endOffset;
513
- const total = start.value + end.value;
514
- if (total <= 0) return 1;
515
- const startNorm = start.value / total;
516
- const endNorm = end.value / total;
517
- return 1 - (startNorm + endNorm);
518
- }
519
531
 
520
532
 
521
533
  declare global {
@@ -1,10 +1,12 @@
1
1
  import { Camera, PerspectiveCamera, Vector2, Vector3 } from "three";
2
+
3
+ import { isDevEnvironment } from "../../engine/debug/debug.js";
4
+ import { Gizmos } from "../../engine/engine_gizmos.js";
2
5
  import { serializable } from "../../engine/engine_serialization_decorator.js";
3
- import { registerType } from "../../engine/engine_typestore.js";
4
6
  import { getTempVector } from "../../engine/engine_three_utils.js";
5
- import { Behaviour } from "../Component.js";
6
- import { isDevEnvironment } from "../../engine/debug/debug.js";
7
+ import { registerType } from "../../engine/engine_typestore.js";
7
8
  import { getParam } from "../../engine/engine_utils.js";
9
+ import { Behaviour } from "../Component.js";
8
10
 
9
11
  const debugParam = getParam("debugviewbox");
10
12
 
@@ -38,7 +40,11 @@ export class ViewBox extends Behaviour {
38
40
  onBeforeRender() {
39
41
  if (this.context.isInXR) return;
40
42
  const isActive = ViewBox.instances[ViewBox.instances.length - 1] === this;
41
- if (!isActive) return;
43
+ if (!isActive) {
44
+ if (debugParam || this.debug) Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0x333333);
45
+ return;
46
+ }
47
+ if (debugParam || this.debug) Gizmos.DrawWireBox(this.gameObject.worldPosition, this.gameObject.worldScale, 0xdddd00);
42
48
 
43
49
  // calculate box size to fit the camera frustrum size at the current position (just scale)
44
50
  const camera = this.context.mainCamera;
@@ -53,11 +59,8 @@ export class ViewBox extends Behaviour {
53
59
  return;
54
60
  }
55
61
 
56
- const domRect = this.context.domElement.getBoundingClientRect();
57
- const domX = domRect.x;
58
- const domY = domRect.y;
59
- const domWidth = domRect.width;
60
- const domHeight = domRect.height;
62
+ const domWidth = this.context.domWidth;
63
+ const domHeight = this.context.domHeight;
61
64
 
62
65
  let rectPosX = 0;
63
66
  let rectPosY = 0;