@needle-tools/engine 5.0.4 → 5.0.6-next.56fe65a

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 (95) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/components.needle.json +1 -1
  3. package/dist/{needle-engine.bundle-CYrPktak.umd.cjs → needle-engine.bundle-BakND7HQ.umd.cjs} +140 -139
  4. package/dist/{needle-engine.bundle-B3Km2VZ4.js → needle-engine.bundle-CsY10n4y.js} +8183 -7957
  5. package/dist/{needle-engine.bundle-CX-SJZzp.min.js → needle-engine.bundle-Drz4zRYf.min.js} +142 -141
  6. package/dist/needle-engine.d.ts +139 -14
  7. package/dist/needle-engine.js +560 -557
  8. package/dist/needle-engine.min.js +1 -1
  9. package/dist/needle-engine.umd.cjs +1 -1
  10. package/dist/{vendor-vHLk8sXu.js → vendor-CAcsI0eU.js} +116 -115
  11. package/dist/{vendor-CntUvmJu.umd.cjs → vendor-CEM38hLE.umd.cjs} +2 -2
  12. package/dist/{vendor-DPbfJJ4d.min.js → vendor-HRlxIBga.min.js} +2 -2
  13. package/lib/engine/api.d.ts +2 -0
  14. package/lib/engine/api.js +2 -0
  15. package/lib/engine/api.js.map +1 -1
  16. package/lib/engine/debug/debug_spatial_console.d.ts +2 -0
  17. package/lib/engine/debug/debug_spatial_console.js +10 -7
  18. package/lib/engine/debug/debug_spatial_console.js.map +1 -1
  19. package/lib/engine/engine_addressables.d.ts +2 -0
  20. package/lib/engine/engine_addressables.js +6 -3
  21. package/lib/engine/engine_addressables.js.map +1 -1
  22. package/lib/engine/engine_audio.d.ts +68 -0
  23. package/lib/engine/engine_audio.js +172 -0
  24. package/lib/engine/engine_audio.js.map +1 -1
  25. package/lib/engine/engine_gameobject.js +2 -2
  26. package/lib/engine/engine_gameobject.js.map +1 -1
  27. package/lib/engine/engine_init.js +8 -0
  28. package/lib/engine/engine_init.js.map +1 -1
  29. package/lib/engine/engine_mainloop_utils.js +5 -2
  30. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  31. package/lib/engine/engine_serialization_builtin_serializer.js +27 -0
  32. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  33. package/lib/engine/webcomponents/needle-engine.d.ts +9 -3
  34. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  35. package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
  36. package/lib/engine/xr/NeedleXRSession.js +50 -14
  37. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  38. package/lib/engine-components/Animation.js +17 -16
  39. package/lib/engine-components/Animation.js.map +1 -1
  40. package/lib/engine-components/AnimatorController.d.ts +2 -0
  41. package/lib/engine-components/AnimatorController.js +4 -1
  42. package/lib/engine-components/AnimatorController.js.map +1 -1
  43. package/lib/engine-components/AudioSource.d.ts +19 -3
  44. package/lib/engine-components/AudioSource.js +121 -68
  45. package/lib/engine-components/AudioSource.js.map +1 -1
  46. package/lib/engine-components/DragControls.d.ts +7 -0
  47. package/lib/engine-components/DragControls.js +19 -0
  48. package/lib/engine-components/DragControls.js.map +1 -1
  49. package/lib/engine-components/NestedGltf.d.ts +19 -3
  50. package/lib/engine-components/NestedGltf.js +19 -3
  51. package/lib/engine-components/NestedGltf.js.map +1 -1
  52. package/lib/engine-components/Networking.d.ts +1 -1
  53. package/lib/engine-components/Networking.js +1 -1
  54. package/lib/engine-components/OrbitControls.js +16 -11
  55. package/lib/engine-components/OrbitControls.js.map +1 -1
  56. package/lib/engine-components/postprocessing/VolumeParameter.d.ts +2 -0
  57. package/lib/engine-components/postprocessing/VolumeParameter.js +4 -1
  58. package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -1
  59. package/lib/engine-components/ui/Canvas.d.ts +1 -1
  60. package/lib/engine-components/ui/Canvas.js +2 -8
  61. package/lib/engine-components/ui/Canvas.js.map +1 -1
  62. package/lib/engine-components/ui/Text.d.ts +8 -1
  63. package/lib/engine-components/ui/Text.js +29 -14
  64. package/lib/engine-components/ui/Text.js.map +1 -1
  65. package/lib/engine-components/web/CursorFollow.js +21 -12
  66. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  67. package/lib/engine-components/webxr/WebXRImageTracking.js +4 -0
  68. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  69. package/package.json +2 -2
  70. package/plugins/vite/asap.js +17 -8
  71. package/plugins/vite/local-files-core.js +3 -3
  72. package/plugins/vite/local-files-utils.d.ts +3 -1
  73. package/plugins/vite/local-files-utils.js +29 -5
  74. package/src/engine/api.ts +3 -0
  75. package/src/engine/debug/debug_spatial_console.ts +10 -7
  76. package/src/engine/engine_addressables.ts +6 -3
  77. package/src/engine/engine_audio.ts +184 -0
  78. package/src/engine/engine_gameobject.ts +2 -2
  79. package/src/engine/engine_init.ts +8 -0
  80. package/src/engine/engine_mainloop_utils.ts +5 -2
  81. package/src/engine/engine_serialization_builtin_serializer.ts +31 -3
  82. package/src/engine/webcomponents/needle-engine.ts +9 -3
  83. package/src/engine/xr/NeedleXRSession.ts +48 -13
  84. package/src/engine-components/Animation.ts +19 -16
  85. package/src/engine-components/AnimatorController.ts +4 -1
  86. package/src/engine-components/AudioSource.ts +130 -79
  87. package/src/engine-components/DragControls.ts +18 -2
  88. package/src/engine-components/NestedGltf.ts +20 -4
  89. package/src/engine-components/Networking.ts +1 -1
  90. package/src/engine-components/OrbitControls.ts +18 -9
  91. package/src/engine-components/postprocessing/VolumeParameter.ts +4 -1
  92. package/src/engine-components/ui/Canvas.ts +2 -8
  93. package/src/engine-components/ui/Text.ts +43 -18
  94. package/src/engine-components/web/CursorFollow.ts +21 -13
  95. package/src/engine-components/webxr/WebXRImageTracking.ts +2 -0
@@ -81,7 +81,24 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
81
81
  @serializable()
82
82
  supportRichText: boolean = false;
83
83
  @serializable(URL)
84
- font?: string;
84
+ set font(val: string | null) {
85
+ if (val !== this._font) {
86
+ this._font = val;
87
+ // If the font is assigned during deserialization it means the font URL MUST be resolved with the style suffix. If it's assigned at runtime by a user invocation and is absolute then we assume the user is prividing a full path to the font asset json or png
88
+ this._assignedAtRuntime = this.__didAwake;
89
+ }
90
+ }
91
+ get font(): string | null {
92
+ return this._font;
93
+ }
94
+ private _font: string | null = null;
95
+ private _assignedAtRuntime: boolean = true;
96
+
97
+
98
+ /**
99
+ * Whether to support basic rich text tags in the `text` property. Supported tags include `<b>`, `<i>`, and `<color=hex>`. For example: `Hello <b>World</b>` or `Score: <color=#ff0000>100</color>`
100
+ * @default false
101
+ */
85
102
  @serializable()
86
103
  fontStyle: FontStyle = FontStyle.Normal;
87
104
 
@@ -224,8 +241,15 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
224
241
  // fontSize /= this.canvas?.scaleFactor;
225
242
  // }
226
243
 
227
-
228
- const textOpts = {
244
+ const textOpts: {
245
+ color: Color,
246
+ fontOpacity: number,
247
+ fontSize: number,
248
+ fontKerning: string,
249
+ whiteSpace?: string,
250
+ overflow?: string,
251
+ lineHeight?: number
252
+ } = {
229
253
  color: this.color,
230
254
  fontOpacity: this.color.alpha,
231
255
  fontSize: fontSize,
@@ -486,15 +510,16 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
486
510
  * @private
487
511
  */
488
512
  private setFont(opts: ThreeMeshUIEveryOptions, fontStyle: FontStyle) {
513
+
514
+ if (!this.font) {
515
+ if(debug) console.warn("No font set for Text component, skipping font setup");
516
+ return;
517
+ }
489
518
 
490
- // @TODO : THH could be useful to uniformize font family name :
491
- // This would ease possible html/vr matching
492
- // - Arial instead of assets/arial
493
- // - Arial should stay Arial instead of arial
494
- if (!this.font) return;
495
519
  const fontName = this.font;
496
520
  const familyName = this.getFamilyNameWithCorrectSuffix(fontName, fontStyle);
497
- if (debug) console.log("Selected font family:" + familyName);
521
+
522
+ if (debug) console.log("Selected font family:" + familyName, this.font);
498
523
 
499
524
  // ensure a font family is register under this name
500
525
  let fontFamily = ThreeMeshUI.FontLibrary.getFontFamily(familyName as string);
@@ -527,9 +552,7 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
527
552
  opts.fontWeight = 400;
528
553
  }
529
554
 
530
-
531
555
  // Ensure a fontVariant is registered
532
- //@TODO: @swingingtom add type for fontWeight
533
556
  let fontVariant = fontFamily.getVariant(opts.fontWeight as any as string, opts.fontStyle);
534
557
  if (!fontVariant) {
535
558
  let jsonPath = familyName;
@@ -550,13 +573,7 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
550
573
 
551
574
  private getFamilyNameWithCorrectSuffix(familyName: string, style: FontStyle): string {
552
575
 
553
-
554
- // the URL decorator resolves the URL to absolute URLs - we need to remove the domain part since we're only interested in the path
555
- if (familyName.startsWith("https:") || familyName.startsWith("http:")) {
556
- const url = new URL(familyName);
557
- familyName = url.pathname;
558
- }
559
-
576
+ const isAbsolute = familyName.startsWith("https:") || familyName.startsWith("http:");
560
577
 
561
578
  // we can only change the style for the family if the name has a suffix (e.g. Arial-Bold)
562
579
  const styleSeparator = familyName.lastIndexOf('-');
@@ -580,8 +597,16 @@ export class Text extends Graphic implements IHasAlphaFactor, ICanvasEventReceiv
580
597
  }
581
598
  const isUpperCase = fontBaseName[0] === fontBaseName[0].toUpperCase();
582
599
  const fontNameWithoutSuffix = familyName.substring(0, styleSeparator > pathSeparatorIndex ? styleSeparator : familyName.length);
600
+
583
601
  if (debug) console.log("Select font: ", familyName, FontStyle[style], fontBaseName, isUpperCase, fontNameWithoutSuffix);
584
602
 
603
+ /**
604
+ * If a user provides a font with an absolute URL AND the font name does not end with "-msdf.json" or ".png" (e.g. "https://example.com/fonts/Arial-Bold"), we will assume that the user is providing the full path to the font files and we will not try to modify the font name based on the style. This allows users to have more control over the font files they are using, especially if they are hosting their own fonts or using a custom font provider that does not follow the same naming conventions as our default fonts.
605
+ */
606
+ if (isAbsolute && this._assignedAtRuntime && !(familyName.endsWith("-msdf.json") || familyName.endsWith(".png"))) {
607
+ return fontNameWithoutSuffix;
608
+ }
609
+
585
610
  switch (style) {
586
611
  case FontStyle.Normal:
587
612
  if (isUpperCase) return fontNameWithoutSuffix + "-Regular";
@@ -289,20 +289,28 @@ export class CursorFollow extends Behaviour {
289
289
 
290
290
 
291
291
  if (this.snapToSurface) {
292
- ray.origin = _position;
293
- ray.direction = rayDirection.multiplyScalar(-1);
294
- const hits = this.context.physics.raycastFromRay(ray);
295
- if (hits?.length) {
296
- const hit = hits[0];
297
- if (this.damping > 0) {
298
- this.gameObject.worldPosition = _position.lerp(hit.point, this.context.time.deltaTime / this.damping);
299
- }
300
- else {
301
- this.gameObject.worldPosition = hit.point;
292
+ ray.origin = cameraPosition;
293
+ ray.direction = rayDirection;
294
+ const hits = this.context.physics.raycastFromRay(ray, {
295
+ testObject: obj => {
296
+ return obj !== this.gameObject && !this.gameObject.contains(obj) ? true : false
302
297
  }
303
-
304
- if(debug) {
305
- Gizmos.DrawLine(hit.point, hit.normal!.add(hit.point), 0x00FF00);
298
+ });
299
+ if (hits?.length) {
300
+ // Get the first hit that is not a child of *this* object. Because we do not want to lerp to a surface that is part of the object itself, since that would result in *this* object moving closer and closer to the camera as it tries to snap to itself
301
+ const hit = hits[0];//.find(h => !this.gameObject.contains(h.object));
302
+ if (hit) {
303
+ if (this.damping > 0) {
304
+ this.gameObject.worldPosition = _position.lerp(hit.point, this.context.time.deltaTime / this.damping);
305
+ // this._distance = this.gameObject.worldPosition.distanceTo(cameraPosition);
306
+ }
307
+ else {
308
+ this.gameObject.worldPosition = hit.point;
309
+ // this._distance = hit.point.distanceTo(cameraPosition);
310
+ }
311
+ if (debug) {
312
+ Gizmos.DrawLine(hit.point, hit.normal!.add(hit.point), 0x00FF00);
313
+ }
306
314
  }
307
315
  }
308
316
  }
@@ -886,9 +886,11 @@ async function loadImage(url: string) {
886
886
  }
887
887
  const promise = new Promise<boolean>(res => {
888
888
  _imageElements.set(url, null);
889
+ if(isDevEnvironment() || debug) console.debug(`[WebXRImageTracking] Start loading image for tracking: ${url}`);
889
890
  const imageElement = document.createElement("img") as HTMLImageElement;
890
891
  imageElement.src = url;
891
892
  imageElement.addEventListener("load", async () => {
893
+ if(isDevEnvironment() || debug) console.debug(`[WebXRImageTracking] Loaded image for tracking: ${url}`);
892
894
  const img = await createImageBitmap(imageElement);
893
895
  _imageElements.set(url, img);
894
896
  res(true);