@needle-tools/engine 4.11.5-next.b4a2f9e → 4.11.5-next.d9019e4

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 (94) hide show
  1. package/CHANGELOG.md +7 -5
  2. package/components.needle.json +1 -1
  3. package/dist/generateMeshBVH.worker-mO20N_b8.js +21 -0
  4. package/dist/{gltf-progressive-GwdQV1Qx.umd.cjs → gltf-progressive-DWcmTMCh.umd.cjs} +1 -1
  5. package/dist/{gltf-progressive-CftVUJy3.min.js → gltf-progressive-DZrY8VT6.min.js} +2 -2
  6. package/dist/{gltf-progressive-BvlZQAkt.js → gltf-progressive-DgYz5BYa.js} +19 -19
  7. package/dist/loader.worker-Dip-PthR.js +23 -0
  8. package/dist/{needle-engine.bundle-DnJ3q6Oa.js → needle-engine.bundle-D4DKOVeW.js} +4309 -4228
  9. package/dist/{needle-engine.bundle-DG38kMjs.umd.cjs → needle-engine.bundle-DbRanrPL.umd.cjs} +138 -143
  10. package/dist/{needle-engine.bundle-D2_8tEN0.min.js → needle-engine.bundle-GILPT50v.min.js} +130 -135
  11. package/dist/needle-engine.js +336 -335
  12. package/dist/needle-engine.min.js +1 -1
  13. package/dist/needle-engine.umd.cjs +1 -1
  14. package/dist/{postprocessing-CJC0Npcd.js → postprocessing-BTW9pD_s.js} +1822 -1723
  15. package/dist/{postprocessing-DrM4PWU3.umd.cjs → postprocessing-CMgoN5t5.umd.cjs} +229 -158
  16. package/dist/{postprocessing-l7zsdO_Q.min.js → postprocessing-DYDtB188.min.js} +227 -156
  17. package/dist/rapier-B3oL1ap-.js +5217 -0
  18. package/dist/rapier-DJ-luMxr.min.js +1 -0
  19. package/dist/rapier-DQltNJbN.umd.cjs +1 -0
  20. package/dist/{three-BDW9I486.min.js → three-B7CT31Bt.min.js} +1 -5
  21. package/dist/{three-MHVqtJYj.js → three-DfMvBzXi.js} +0 -5
  22. package/dist/{three-examples-CgwGHSgz.umd.cjs → three-examples-CsW4_6LI.umd.cjs} +2 -7
  23. package/dist/{three-examples-fvEPSC8L.min.js → three-examples-D1P7eEhn.min.js} +2 -7
  24. package/dist/{three-examples-C5Ht-QFN.js → three-examples-D1SK93ek.js} +1 -7
  25. package/dist/{three-mesh-ui-BjWTTk1R.js → three-mesh-ui-C_uSB5dD.js} +1 -1
  26. package/dist/{three-mesh-ui-Bm32sS2a.umd.cjs → three-mesh-ui-DpATDXwU.umd.cjs} +1 -1
  27. package/dist/{three-mesh-ui-CLdkp21K.min.js → three-mesh-ui-LQ44s0AL.min.js} +1 -1
  28. package/dist/{three-iFaDq9U3.umd.cjs → three-qj71I7J3.umd.cjs} +2 -6
  29. package/dist/{vendor-CsyK1CFs.min.js → vendor-BKGa4GE0.min.js} +34 -39
  30. package/dist/{vendor-petGQl0N.js → vendor-D0zoswDa.js} +1626 -1605
  31. package/dist/{vendor-6kAXU6fm.umd.cjs → vendor-UCpFAwt1.umd.cjs} +30 -35
  32. package/lib/engine/debug/debug_spector.d.ts +16 -0
  33. package/lib/engine/debug/debug_spector.js +28 -0
  34. package/lib/engine/debug/debug_spector.js.map +1 -0
  35. package/lib/engine/engine_application.d.ts +7 -0
  36. package/lib/engine/engine_application.js +8 -1
  37. package/lib/engine/engine_application.js.map +1 -1
  38. package/lib/engine/engine_context.js +4 -1
  39. package/lib/engine/engine_context.js.map +1 -1
  40. package/lib/engine/engine_physics.js +6 -2
  41. package/lib/engine/engine_physics.js.map +1 -1
  42. package/lib/engine/engine_physics_rapier.d.ts +11 -2
  43. package/lib/engine/engine_physics_rapier.js +9 -0
  44. package/lib/engine/engine_physics_rapier.js.map +1 -1
  45. package/lib/engine/engine_types.d.ts +16 -0
  46. package/lib/engine/engine_typestore.d.ts +1 -0
  47. package/lib/engine/engine_typestore.js +5 -6
  48. package/lib/engine/engine_typestore.js.map +1 -1
  49. package/lib/engine/webcomponents/needle-engine.d.ts +1 -0
  50. package/lib/engine/webcomponents/needle-engine.js +3 -0
  51. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  52. package/lib/engine/xr/NeedleXRSession.js +2 -1
  53. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  54. package/lib/engine-components/Component.d.ts +5 -0
  55. package/lib/engine-components/Component.js +7 -0
  56. package/lib/engine-components/Component.js.map +1 -1
  57. package/lib/engine-components/RendererInstancing.d.ts +5 -3
  58. package/lib/engine-components/RendererInstancing.js +64 -31
  59. package/lib/engine-components/RendererInstancing.js.map +1 -1
  60. package/lib/engine-components/Skybox.d.ts +15 -5
  61. package/lib/engine-components/Skybox.js +37 -25
  62. package/lib/engine-components/Skybox.js.map +1 -1
  63. package/lib/engine-components/export/usdz/USDZExporter.d.ts +24 -3
  64. package/lib/engine-components/export/usdz/USDZExporter.js +36 -2
  65. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  66. package/lib/engine-components/web/CursorFollow.d.ts +1 -0
  67. package/lib/engine-components/web/CursorFollow.js +2 -0
  68. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  69. package/lib/engine-components/webxr/WebXR.js +4 -0
  70. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  71. package/lib/needle-engine.js +2 -1
  72. package/lib/needle-engine.js.map +1 -1
  73. package/package.json +1 -1
  74. package/src/engine/debug/debug_spector.ts +43 -0
  75. package/src/engine/engine_application.ts +16 -1
  76. package/src/engine/engine_context.ts +5 -1
  77. package/src/engine/engine_physics.ts +6 -2
  78. package/src/engine/engine_physics_rapier.ts +11 -2
  79. package/src/engine/engine_types.ts +17 -0
  80. package/src/engine/engine_typestore.ts +5 -6
  81. package/src/engine/webcomponents/needle-engine.ts +4 -0
  82. package/src/engine/xr/NeedleXRSession.ts +3 -1
  83. package/src/engine-components/Component.ts +9 -1
  84. package/src/engine-components/RendererInstancing.ts +69 -33
  85. package/src/engine-components/Skybox.ts +47 -36
  86. package/src/engine-components/export/usdz/USDZExporter.ts +52 -5
  87. package/src/engine-components/web/CursorFollow.ts +3 -0
  88. package/src/engine-components/webxr/WebXR.ts +4 -0
  89. package/src/needle-engine.ts +4 -2
  90. package/dist/generateMeshBVH.worker-B9bjdr6J.js +0 -25
  91. package/dist/loader.worker-CiTwpNPW.js +0 -27
  92. package/dist/rapier-BqdcSmKY.umd.cjs +0 -1
  93. package/dist/rapier-Cg3w3nFI.min.js +0 -1
  94. package/dist/rapier-sU12SWAs.js +0 -5217
@@ -1,16 +1,14 @@
1
- import { CompressedCubeTexture, CubeRefractionMapping, CubeTexture, CubeUVReflectionMapping, EquirectangularRefractionMapping, SRGBColorSpace, Texture, TextureLoader } from "three"
2
- import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader.js";
3
- import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader.js";
4
- import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
1
+ import { CompressedCubeTexture, CubeTexture, CubeUVReflectionMapping, EquirectangularRefractionMapping, Texture } from "three"
5
2
 
3
+ import { isDevEnvironment } from "../engine/debug/debug.js";
6
4
  import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
7
5
  import { syncField } from "../engine/engine_networking_auto.js";
8
6
  import { loadPMREM } from "../engine/engine_pmrem.js";
9
7
  import { serializable } from "../engine/engine_serialization_decorator.js";
10
8
  import { type IContext } from "../engine/engine_types.js";
11
- import { addAttributeChangeCallback, getParam, PromiseAllWithErrors, removeAttributeChangeCallback, toSourceId } from "../engine/engine_utils.js";
9
+ import { addAttributeChangeCallback, getParam, removeAttributeChangeCallback, toSourceId } from "../engine/engine_utils.js";
12
10
  import { registerObservableAttribute } from "../engine/webcomponents/needle-engine.extras.js";
13
- import { Camera, ClearFlags } from "./Camera.js";
11
+ import { Camera } from "./Camera.js";
14
12
  import { Behaviour, GameObject } from "./Component.js";
15
13
 
16
14
  const debug = getParam("debugskybox");
@@ -18,6 +16,29 @@ const debug = getParam("debugskybox");
18
16
  registerObservableAttribute("background-image");
19
17
  registerObservableAttribute("environment-image");
20
18
 
19
+
20
+ type MagicSkyboxName = "studio" | "blurred-skybox" | "quicklook-ar" | "quicklook";
21
+ const MagicSkyboxNames: Record<MagicSkyboxName, { url: string, url_low: string }> = {
22
+ "studio": {
23
+ url: "https://cdn.needle.tools/static/skybox/modelviewer-Neutral.pmrem4x4.ktx2?pmrem",
24
+ url_low: "https://cdn.needle.tools/static/skybox/modelviewer-Neutral-small.pmrem4x4.ktx2?pmrem"
25
+ },
26
+ "blurred-skybox": {
27
+ url: "https://cdn.needle.tools/static/skybox/blurred-skybox.pmrem4x4.ktx2?pmrem",
28
+ url_low: "https://cdn.needle.tools/static/skybox/blurred-skybox-small.pmrem4x4.ktx2?pmrem"
29
+ },
30
+ "quicklook-ar": {
31
+ url: "https://cdn.needle.tools/static/skybox/QuickLook-ARMode.pmrem4x4.ktx2?pmrem",
32
+ url_low: "https://cdn.needle.tools/static/skybox/QuickLook-ARMode-small.pmrem4x4.ktx2?pmrem"
33
+ },
34
+ "quicklook": {
35
+ url: "https://cdn.needle.tools/static/skybox/QuickLook-ObjectMode.pmrem4x4.ktx2?pmrem",
36
+ url_low: "https://cdn.needle.tools/static/skybox/QuickLook-ObjectMode-small.pmrem4x4.ktx2?pmrem"
37
+ }
38
+ } as const;
39
+ type AnyString = string & { _brand?: never };
40
+
41
+
21
42
  function createRemoteSkyboxComponent(context: IContext, url: string, skybox: boolean, environment: boolean, attribute: "background-image" | "environment-image") {
22
43
 
23
44
  // when the user sets the attribute to a color we can not handle it as a skybox url.
@@ -91,8 +112,9 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreationStart, () => {
91
112
  });
92
113
 
93
114
 
115
+
94
116
  /**
95
- * RemoteSkybox is a component that allows you to set the skybox of a scene from a URL or a local file.
117
+ * RemoteSkybox is a component that allows you to set the skybox or environment texture of a scene from a URL, a local file or a static skybox name.
96
118
  * It supports .hdr, .exr, .jpg, .png files.
97
119
  *
98
120
  * ### Events
@@ -127,8 +149,13 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreationStart, () => {
127
149
  export class RemoteSkybox extends Behaviour {
128
150
 
129
151
  /**
130
- * URL to a remote skybox. This value can also use a magic skybox name. Options are "quicklook", "quicklook-ar", "studio", "blurred-skybox".
131
- * To update the skybox/environment map use `setSkybox(url)`
152
+ * URL to a remote skybox.
153
+ * To update the skybox/environment map use `setSkybox(url)`.
154
+ *
155
+ * The url can also be set to a magic skybox name.
156
+ * Magic name options are: "quicklook", "quicklook-ar", "studio", "blurred-skybox".
157
+ * These will resolve to built-in skyboxes hosted on the Needle CDN that are static, optimized for the web and will never change.
158
+ *
132
159
  * @example
133
160
  * ```ts
134
161
  * skybox.url = "https://example.com/skybox.hdr";
@@ -136,7 +163,7 @@ export class RemoteSkybox extends Behaviour {
136
163
  */
137
164
  @syncField(RemoteSkybox.prototype.urlChangedSyncField)
138
165
  @serializable(URL)
139
- url?: string;
166
+ url: MagicSkyboxName | AnyString = "studio";
140
167
 
141
168
  /**
142
169
  * When enabled a user can drop a link to a skybox image on the scene to set the skybox.
@@ -208,7 +235,7 @@ export class RemoteSkybox extends Behaviour {
208
235
  * @param name Define name of the file with extension if it isn't apart of the url
209
236
  * @returns Whether the skybox was successfully set
210
237
  */
211
- async setSkybox(url: string | undefined | null, name?: string) {
238
+ async setSkybox(url: MagicSkyboxName | AnyString | undefined | null, name?: string) {
212
239
  if (!this.activeAndEnabled) return false;
213
240
 
214
241
  url = tryParseMagicSkyboxName(url, this.environment, this.background);
@@ -404,38 +431,22 @@ export class RemoteSkybox extends Behaviour {
404
431
 
405
432
 
406
433
 
407
-
408
434
  function tryParseMagicSkyboxName(str: string | null | undefined, environment: boolean, background: boolean): string | null {
409
435
 
410
436
  if (str === null || str === undefined) return null;
411
437
 
412
438
  const useLowRes = environment && !background;
413
439
 
414
- switch (str.toLowerCase()) {
415
- case "studio":
416
- if (useLowRes) {
417
- return "https://cdn.needle.tools/static/skybox/modelviewer-Neutral-small.pmrem4x4.ktx2?pmrem";
418
- }
419
- return "https://cdn.needle.tools/static/skybox/modelviewer-Neutral.pmrem4x4.ktx2?pmrem";
420
-
421
- case "blurred-skybox":
422
- if (useLowRes) {
423
- return "https://cdn.needle.tools/static/skybox/blurred-skybox-small.pmrem4x4.ktx2?pmrem";
424
- }
425
- return "https://cdn.needle.tools/static/skybox/blurred-skybox.pmrem4x4.ktx2?pmrem";
426
- case "quicklook-ar":
427
- if (useLowRes) {
428
- return "https://cdn.needle.tools/static/skybox/QuickLook-ARMode-small.pmrem4x4.ktx2?pmrem";
429
- }
430
- return "https://cdn.needle.tools/static/skybox/QuickLook-ARMode.pmrem4x4.ktx2?pmrem";
431
- case "quicklook":
432
- if (useLowRes) {
433
- return "https://cdn.needle.tools/static/skybox/QuickLook-ObjectMode-small.pmrem4x4.ktx2?pmrem";
434
- }
435
- return "https://cdn.needle.tools/static/skybox/QuickLook-ObjectMode.pmrem4x4.ktx2?pmrem";
440
+ const value = MagicSkyboxNames[str.toLowerCase() as MagicSkyboxName];
441
+ if (value) {
442
+ return useLowRes ? value.url_low : value.url;
443
+ }
444
+ else if (typeof str === "string" && str?.length && (isDevEnvironment() || debug)) {
445
+ const noUrlOrFile = !str.startsWith("http") && !str.startsWith("file:") && !str.startsWith("blob:") && !str.startsWith("data:");
446
+ if(noUrlOrFile) {
447
+ console.warn(`RemoteSkybox: Unknown magic skybox name "${str}". Valid names are: ${Object.keys(MagicSkyboxNames).map(n => `"${n}"`).join(", ")}`);
448
+ }
436
449
  }
437
-
438
-
439
450
 
440
451
  return str;
441
452
  }
@@ -1,5 +1,5 @@
1
1
  import { NEEDLE_progressive } from "@needle-tools/gltf-progressive";
2
- import { Euler, EventDispatcher, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
2
+ import { Euler, Material, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
3
3
 
4
4
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../../engine/debug/index.js";
5
5
  import { hasProLicense } from "../../../engine/engine_license.js";
@@ -53,6 +53,23 @@ export class CustomBranding {
53
53
  callToActionURL?: string;
54
54
  }
55
55
 
56
+ type BeforeLODExportArguments = {
57
+ readonly exporter: USDZExporter;
58
+ /** The type of LOD being exported, either a texture or a mesh */
59
+ readonly type: "texture" | "mesh";
60
+ /** The Renderer gameobject */
61
+ readonly object: Object3D;
62
+ /** The mesh being exported, if applicable */
63
+ readonly mesh?: Mesh;
64
+ /** The material being exported, if applicable */
65
+ readonly material?: Material;
66
+ /** By default LOD 0 will be exported (highest quality).
67
+ * Set to a different LOD level if needed.
68
+ * Set to -1 to disable LOD export and simply export the current version.
69
+ */
70
+ overrideLevel?: number;
71
+ }
72
+
56
73
  /**
57
74
  * Exports the current scene or a specific object as USDZ file and opens it in QuickLook on iOS/iPadOS/visionOS.
58
75
  * The USDZ file is generated using the Needle Engine ThreeUSDZExporter.
@@ -72,8 +89,12 @@ export class CustomBranding {
72
89
  */
73
90
  export class USDZExporter extends Behaviour {
74
91
 
75
- static readonly beforeExport = new EventList<{ exporter: USDZExporter }>();
76
- static readonly afterExport = new EventList<{ exporter: USDZExporter }>();
92
+ /** Called before the USDZ file is exported */
93
+ static readonly beforeExport = new EventList<{ readonly exporter: USDZExporter }>();
94
+ /** Called after the USDZ file has been exported */
95
+ static readonly afterExport = new EventList<{ readonly exporter: USDZExporter }>();
96
+ /** Called before LOD level are exported. Can be used to override the LOD export settings */
97
+ static readonly beforeLODExport = new EventList<BeforeLODExportArguments>();
77
98
 
78
99
  /**
79
100
  * Assign the object to export as USDZ file. If undefined or null, the whole scene will be exported.
@@ -329,7 +350,20 @@ export class USDZExporter extends Behaviour {
329
350
  for (const rend of renderers) {
330
351
  for (const mesh of rend.sharedMeshes) {
331
352
  if (mesh) {
332
- const task = NEEDLE_progressive.assignMeshLOD(mesh, 0);
353
+ let lodLevel = 0;
354
+ const args: BeforeLODExportArguments = { exporter: this, type: "mesh" as const, object: rend.gameObject, mesh: mesh, };
355
+ USDZExporter.beforeLODExport.invoke(args);
356
+ if (args.overrideLevel !== undefined) {
357
+ if (args.overrideLevel === -1) {
358
+ if (debug) console.warn("Skipping LOD export for mesh due to overrideLevel -1", rend.gameObject, mesh);
359
+ continue; // skip LOD assignment
360
+ }
361
+ else if (args.overrideLevel >= 0) {
362
+ lodLevel = args.overrideLevel;
363
+ if (debug) console.log("Overriding LOD level for mesh export to level " + lodLevel + " " + mesh.name);
364
+ }
365
+ }
366
+ const task = NEEDLE_progressive.assignMeshLOD(mesh, lodLevel);
333
367
  if (task instanceof Promise)
334
368
  progressiveLoading.push(new Promise<void>((resolve, reject) => {
335
369
  task.then(() => {
@@ -342,7 +376,20 @@ export class USDZExporter extends Behaviour {
342
376
  }
343
377
  for (const mat of rend.sharedMaterials) {
344
378
  if (mat) {
345
- const task = NEEDLE_progressive.assignTextureLOD(mat, 0);
379
+ let lodLevel = 0;
380
+ const args: BeforeLODExportArguments = { exporter: this, type: "texture" as const, object: rend.gameObject, material: mat };
381
+ USDZExporter.beforeLODExport.invoke(args);
382
+ if (args.overrideLevel !== undefined) {
383
+ if (args.overrideLevel === -1) {
384
+ if (debug) console.warn("Skipping LOD assignment due to overrideLevel -1", rend.gameObject, mat);
385
+ continue; // skip LOD assignment
386
+ }
387
+ else if (args.overrideLevel >= 0) {
388
+ lodLevel = args.overrideLevel;
389
+ if (debug) console.log("Overriding LOD level for texture export to level " + lodLevel + " " + mat.name);
390
+ }
391
+ }
392
+ const task = NEEDLE_progressive.assignTextureLOD(mat, lodLevel);
346
393
  if (task instanceof Promise)
347
394
  progressiveLoading.push(new Promise<void>((resolve, reject) => {
348
395
  task.then(() => {
@@ -20,6 +20,9 @@ const debug = getParam("debugcursor");
20
20
  */
21
21
  export class CursorFollow extends Behaviour {
22
22
 
23
+ // testing this for compilation
24
+ static readonly NAME = "CursorFollow";
25
+
23
26
  /**
24
27
  * Damping for the movement, set to 0 for instant movement
25
28
  * @default 0
@@ -331,6 +331,10 @@ export class WebXR extends Behaviour {
331
331
  console.warn(`WebXR: another WebXR component is already active (${WebXR.activeWebXRComponent?.name}). This is ignored: ${this.name}`);
332
332
  return;
333
333
  }
334
+ if (this.activeAndEnabled === false || this.destroyed) {
335
+ console.debug("[WebXR] onBeforeXR called on disabled or destroyed component");
336
+ return;
337
+ }
334
338
  WebXR.activeWebXRComponent = this;
335
339
 
336
340
  if (_mode == "immersive-ar" && this.useDepthSensing) {
@@ -7,7 +7,7 @@ export * from "./engine-components-experimental/api.js";
7
7
  export * from "./engine-schemes/api.js";
8
8
 
9
9
  // make accessible for external javascript
10
- import { Context, loadAsset, NeedleXRSession, onAfterRender, onBeforeRender, onClear, onDestroy, onInitialized, onStart, onUpdate, VERSION } from "./engine/api.js";
10
+ import { Context, loadAsset, NeedleXRSession, onAfterRender, onBeforeRender, onClear, onDestroy, onInitialized, onStart, onUpdate, TypeStore, VERSION } from "./engine/api.js";
11
11
  const Needle = {
12
12
  VERSION: VERSION,
13
13
  Context: Context,
@@ -15,6 +15,7 @@ const Needle = {
15
15
  assets: {
16
16
  loadFromURL: loadAsset,
17
17
  },
18
+ types: TypeStore,
18
19
  onStart: onStart,
19
20
  onUpdate: onUpdate,
20
21
  onBeforeRender: onBeforeRender,
@@ -22,7 +23,8 @@ const Needle = {
22
23
  onInitializedContext: onInitialized,
23
24
  onDestroyContext: onDestroy,
24
25
  onClearContext: onClear,
25
- };
26
+ } as const;
27
+
26
28
  if (globalThis["Needle"]?.VERSION !== undefined) {
27
29
  console.warn(`Needle Engine is already imported: ${globalThis["Needle"].VERSION}`);
28
30
  }