@needle-tools/engine 5.1.3 → 5.1.4

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 (67) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/{needle-engine.bundle-CTHxmSih.min.js → needle-engine.bundle-BvxvjlSN.min.js} +170 -164
  3. package/dist/{needle-engine.bundle-BAT9_opF.js → needle-engine.bundle-CEba8eTv.js} +5956 -5899
  4. package/dist/{needle-engine.bundle-BiLCbb4D.umd.cjs → needle-engine.bundle-GUaSFX8u.umd.cjs} +142 -136
  5. package/dist/needle-engine.d.ts +33 -28
  6. package/dist/needle-engine.js +282 -282
  7. package/dist/needle-engine.min.js +1 -1
  8. package/dist/needle-engine.umd.cjs +1 -1
  9. package/lib/engine/api.d.ts +1 -1
  10. package/lib/engine/api.js +1 -1
  11. package/lib/engine/api.js.map +1 -1
  12. package/lib/engine/engine_camera.fit.js +25 -2
  13. package/lib/engine/engine_camera.fit.js.map +1 -1
  14. package/lib/engine/engine_init.js +2 -2
  15. package/lib/engine/engine_init.js.map +1 -1
  16. package/lib/engine/engine_license.d.ts +7 -7
  17. package/lib/engine/engine_license.js +71 -71
  18. package/lib/engine/engine_license.js.map +1 -1
  19. package/lib/engine/engine_networking_blob.js +3 -3
  20. package/lib/engine/engine_networking_blob.js.map +1 -1
  21. package/lib/engine/engine_utils_qrcode.js +2 -2
  22. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  23. package/lib/engine/engine_utils_screenshot.d.ts +3 -1
  24. package/lib/engine/engine_utils_screenshot.js +103 -19
  25. package/lib/engine/engine_utils_screenshot.js.map +1 -1
  26. package/lib/engine/engine_utils_screenshot.needlego.d.ts +44 -0
  27. package/lib/engine/engine_utils_screenshot.needlego.js +22 -0
  28. package/lib/engine/engine_utils_screenshot.needlego.js.map +1 -0
  29. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  30. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  31. package/lib/engine/webcomponents/needle menu/needle-menu.js +5 -5
  32. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  33. package/lib/engine/webcomponents/needle-engine.js +2 -2
  34. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  35. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  36. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  37. package/lib/engine/xr/NeedleXRSession.d.ts +3 -0
  38. package/lib/engine/xr/NeedleXRSession.js +41 -40
  39. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  40. package/lib/engine/xr/TempXRContext.js +2 -2
  41. package/lib/engine/xr/TempXRContext.js.map +1 -1
  42. package/lib/engine/xr/init.js +4 -5
  43. package/lib/engine/xr/init.js.map +1 -1
  44. package/lib/engine-components/GroundProjection.js +36 -16
  45. package/lib/engine-components/GroundProjection.js.map +1 -1
  46. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  47. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  48. package/package.json +1 -1
  49. package/plugins/common/license.js +4 -4
  50. package/plugins/vite/license.js +4 -4
  51. package/src/engine/api.ts +1 -1
  52. package/src/engine/engine_camera.fit.ts +19 -2
  53. package/src/engine/engine_init.ts +2 -2
  54. package/src/engine/engine_license.ts +68 -68
  55. package/src/engine/engine_networking_blob.ts +3 -3
  56. package/src/engine/engine_utils_qrcode.ts +2 -2
  57. package/src/engine/engine_utils_screenshot.needlego.ts +53 -0
  58. package/src/engine/engine_utils_screenshot.ts +107 -20
  59. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  60. package/src/engine/webcomponents/needle menu/needle-menu.ts +5 -5
  61. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  62. package/src/engine/webcomponents/needle-engine.ts +2 -2
  63. package/src/engine/xr/NeedleXRSession.ts +39 -45
  64. package/src/engine/xr/TempXRContext.ts +2 -2
  65. package/src/engine/xr/init.ts +4 -5
  66. package/src/engine-components/GroundProjection.ts +38 -17
  67. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
@@ -180,11 +180,15 @@ ${needleGroundProjectionFragmentPars}
180
180
  const cubeUvSize = texture.mapping === CubeUVReflectionMapping ? getCubeUvSize(texture) : null;
181
181
 
182
182
  if (cubeUvSize) {
183
+ // These are consumed as floats in three's cube_uv_reflection_fragment. GLSL ES has no
184
+ // implicit int→float conversion, so integer-valued numbers must be emitted as float
185
+ // literals (e.g. "1.0", not "1") or the shader fails to compile.
186
+ const glslFloat = (n: number) => Number.isInteger(n) ? `${n}.0` : `${n}`;
183
187
  defines.NEEDLE_USE_CUBE_UV_MAP = 1;
184
188
  defines.ENVMAP_TYPE_CUBE_UV = 1;
185
- defines.CUBEUV_TEXEL_WIDTH = cubeUvSize.texelWidth;
186
- defines.CUBEUV_TEXEL_HEIGHT = cubeUvSize.texelHeight;
187
- defines.CUBEUV_MAX_MIP = `${cubeUvSize.maxMip}.0`;
189
+ defines.CUBEUV_TEXEL_WIDTH = glslFloat(cubeUvSize.texelWidth);
190
+ defines.CUBEUV_TEXEL_HEIGHT = glslFloat(cubeUvSize.texelHeight);
191
+ defines.CUBEUV_MAX_MIP = glslFloat(cubeUvSize.maxMip);
188
192
  }
189
193
  else {
190
194
  delete defines.NEEDLE_USE_CUBE_UV_MAP;
@@ -379,10 +383,19 @@ export class GroundProjectedEnv extends Behaviour {
379
383
  );
380
384
  }
381
385
 
382
- if (this._projection && this.context.scene.background instanceof Texture) {
383
- const blurriness = this.context.scene.backgroundBlurriness ?? 0;
384
- const blurrinessChanged = this._lastBlurriness !== blurriness;
385
- this.updateProjectionMaterial(this.context.scene.background, blurrinessChanged || this._needsTextureUpdate);
386
+ if (this._projection) {
387
+ // Same fallback as updateProjection: in AR/passthrough the camera clears
388
+ // scene.background with arBlending > 0 keep updating the material (transparency +
389
+ // blending uniform) from the last projected texture so the blending actually renders.
390
+ const inXRPassthrough = this.context.xr?.isPassThrough === true || this.context.xr?.isAR === true;
391
+ const background = this.context.scene.background instanceof Texture
392
+ ? this.context.scene.background
393
+ : (inXRPassthrough && this.arBlending > 0 ? this._lastBackground : undefined);
394
+ if (background) {
395
+ const blurriness = this.context.scene.backgroundBlurriness ?? 0;
396
+ const blurrinessChanged = this._lastBlurriness !== blurriness;
397
+ this.updateProjectionMaterial(background, blurrinessChanged || this._needsTextureUpdate);
398
+ }
386
399
  }
387
400
  }
388
401
 
@@ -398,21 +411,29 @@ export class GroundProjectedEnv extends Behaviour {
398
411
  * Updates the ground projection. This is called automatically when the environment or settings change.
399
412
  */
400
413
  updateProjection() {
401
- if (!this.context.scene.background) {
402
- this._projection?.removeFromParent();
403
- return;
414
+ const inXRPassthrough = this.context.xr?.isPassThrough === true || this.context.xr?.isAR === true;
415
+
416
+ // In AR/passthrough the camera clears scene.background so the real world shows through
417
+ // (Camera.applyClearFlags → backgroundShouldBeTransparent). With arBlending > 0 the
418
+ // projection must survive that: fall back to the texture we last projected instead of
419
+ // tearing the projection down — the projection is a scene mesh with its own material,
420
+ // so it blends over the camera feed while the background itself stays cleared.
421
+ let backgroundTexture: Texture;
422
+ const sceneBackground = this.context.scene.background;
423
+ if (sceneBackground instanceof Texture) {
424
+ backgroundTexture = sceneBackground;
404
425
  }
405
- const backgroundTexture = this.context.scene.background;
406
- if (!(backgroundTexture instanceof Texture)) {
426
+ else if (inXRPassthrough && this.arBlending > 0 && this._lastBackground) {
427
+ backgroundTexture = this._lastBackground;
428
+ }
429
+ else {
407
430
  this._projection?.removeFromParent();
408
431
  return;
409
432
  }
410
433
 
411
- if (this.context.xr?.isPassThrough || this.context.xr?.isAR) {
412
- if (this.arBlending === 0) {
413
- this._projection?.removeFromParent();
414
- return;
415
- }
434
+ if (inXRPassthrough && this.arBlending === 0) {
435
+ this._projection?.removeFromParent();
436
+ return;
416
437
  }
417
438
  // If this is called from a setter during initialization
418
439
  if (!this.gameObject || this.destroyed) {
@@ -3,7 +3,7 @@ import { Euler, Material, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "t
3
3
 
4
4
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../../engine/debug/index.js";
5
5
  import { findObjectOfType } from "../../../engine/engine_components.js";
6
- import { __OBvkie } from "../../../engine/engine_license.js";
6
+ import { KLaEb } from "../../../engine/engine_license.js";
7
7
  import { serializable } from "../../../engine/engine_serialization.js";
8
8
  import { getFormattedDate, Progress } from "../../../engine/engine_time_utils.js";
9
9
  import { DeviceUtilities, getParam } from "../../../engine/engine_utils.js";
@@ -277,7 +277,7 @@ export class USDZExporter extends Behaviour {
277
277
  let name = this.exportFileName ?? this.objectToExport?.name ?? this.name;
278
278
  name += "-" + getFormattedDate(); // seems iOS caches the file in some cases, this ensures we always have a fresh file
279
279
 
280
- if (!__OBvkie()) {
280
+ if (!KLaEb()) {
281
281
  if (name !== "") name += "-";
282
282
  name += "MadeWithNeedle";
283
283
  }
@@ -682,7 +682,7 @@ export class USDZExporter extends Behaviour {
682
682
  if (debug)
683
683
  showBalloonMessage("Quicklook url: " + callToActionURL);
684
684
  if (callToActionURL) {
685
- if (!__OBvkie()) {
685
+ if (!KLaEb()) {
686
686
  console.warn("Quicklook closed: custom redirects require a Needle Engine Pro license: https://needle.tools/pricing", callToActionURL)
687
687
  }
688
688
  else {
@@ -697,7 +697,7 @@ export class USDZExporter extends Behaviour {
697
697
  private buildQuicklookOverlay(): CustomBranding {
698
698
  const obj: CustomBranding = {};
699
699
  if (this.customBranding) Object.assign(obj, this.customBranding);
700
- if (!__OBvkie()) {
700
+ if (!KLaEb()) {
701
701
  console.log("Custom Quicklook banner text requires pro license: https://needle.tools/pricing");
702
702
  obj.callToAction = "Close";
703
703
  obj.checkoutTitle = "🌵 Made with Needle";