@needle-tools/engine 4.8.6 → 4.8.7-next.c5a1d5a

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 (73) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/components.needle.json +1 -1
  3. package/dist/{gltf-progressive-DXRy9EQz.js → gltf-progressive-BcHT3Nyo.js} +1 -1
  4. package/dist/{gltf-progressive-C-U_onhf.umd.cjs → gltf-progressive-CH3Q4H06.umd.cjs} +1 -1
  5. package/dist/{gltf-progressive-DViD_J_l.min.js → gltf-progressive-DR6HqF_h.min.js} +1 -1
  6. package/dist/{needle-engine.bundle-CQIq7Zg-.min.js → needle-engine.bundle-B8uN1t53.min.js} +124 -124
  7. package/dist/{needle-engine.bundle-BTJDRZkJ.js → needle-engine.bundle-BSEPqN_G.js} +4354 -4337
  8. package/dist/{needle-engine.bundle-CaNItSG7.umd.cjs → needle-engine.bundle-izSBbBnF.umd.cjs} +131 -131
  9. package/dist/needle-engine.js +402 -400
  10. package/dist/needle-engine.min.js +1 -1
  11. package/dist/needle-engine.umd.cjs +1 -1
  12. package/dist/{postprocessing-61aXdqNz.umd.cjs → postprocessing-CVb_x9YY.umd.cjs} +1 -1
  13. package/dist/{postprocessing-D9jDHD0U.js → postprocessing-ORx-0eCx.js} +1 -1
  14. package/dist/{postprocessing-Be9Ds4NK.min.js → postprocessing-Ywv5oKkX.min.js} +1 -1
  15. package/dist/three-examples-BX_Sktc9.min.js +501 -0
  16. package/dist/{three-examples-BihZ_R96.js → three-examples-CNexix3E.js} +2436 -2781
  17. package/dist/{three-examples-Ce6Th3bv.umd.cjs → three-examples-DWxXVnws.umd.cjs} +21 -21
  18. package/dist/{vendor-BRpzuoJE.min.js → vendor-C43vobGc.min.js} +37 -37
  19. package/dist/{vendor-p_xp9KuJ.js → vendor-Z4SPrTcP.js} +2402 -2047
  20. package/dist/vendor-xfQ8tKF3.umd.cjs +1121 -0
  21. package/lib/engine/api.d.ts +2 -0
  22. package/lib/engine/api.js +2 -0
  23. package/lib/engine/api.js.map +1 -1
  24. package/lib/engine/engine_addressables.d.ts +12 -12
  25. package/lib/engine/engine_addressables.js +30 -23
  26. package/lib/engine/engine_addressables.js.map +1 -1
  27. package/lib/engine/engine_animation.d.ts +1 -3
  28. package/lib/engine/engine_animation.js +15 -9
  29. package/lib/engine/engine_animation.js.map +1 -1
  30. package/lib/engine/engine_feature_flags.d.ts +3 -0
  31. package/lib/engine/engine_feature_flags.js +6 -0
  32. package/lib/engine/engine_feature_flags.js.map +1 -0
  33. package/lib/engine/engine_gameobject.js +0 -4
  34. package/lib/engine/engine_gameobject.js.map +1 -1
  35. package/lib/engine/engine_loaders.js +15 -11
  36. package/lib/engine/engine_loaders.js.map +1 -1
  37. package/lib/engine/engine_mainloop_utils.d.ts +2 -1
  38. package/lib/engine/engine_mainloop_utils.js +18 -6
  39. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  40. package/lib/engine/engine_pmrem.d.ts +6 -0
  41. package/lib/engine/engine_pmrem.js +9 -40
  42. package/lib/engine/engine_pmrem.js.map +1 -1
  43. package/lib/engine/extensions/extensions.js +2 -2
  44. package/lib/engine/extensions/extensions.js.map +1 -1
  45. package/lib/engine/js-extensions/Object3D.js +19 -0
  46. package/lib/engine/js-extensions/Object3D.js.map +1 -1
  47. package/lib/engine-components/Animation.js +2 -1
  48. package/lib/engine-components/Animation.js.map +1 -1
  49. package/lib/engine-components/AnimationUtilsAutoplay.js +1 -6
  50. package/lib/engine-components/AnimationUtilsAutoplay.js.map +1 -1
  51. package/lib/engine-components/DropListener.d.ts +17 -12
  52. package/lib/engine-components/DropListener.js +34 -31
  53. package/lib/engine-components/DropListener.js.map +1 -1
  54. package/lib/engine-components/Skybox.js +9 -3
  55. package/lib/engine-components/Skybox.js.map +1 -1
  56. package/package.json +4 -3
  57. package/plugins/vite/alias.js +45 -23
  58. package/src/engine/api.ts +3 -1
  59. package/src/engine/engine_addressables.ts +44 -33
  60. package/src/engine/engine_animation.ts +17 -9
  61. package/src/engine/engine_feature_flags.ts +8 -0
  62. package/src/engine/engine_gameobject.ts +0 -4
  63. package/src/engine/engine_loaders.ts +18 -13
  64. package/src/engine/engine_mainloop_utils.ts +24 -8
  65. package/src/engine/engine_pmrem.ts +9 -45
  66. package/src/engine/extensions/extensions.ts +2 -2
  67. package/src/engine/js-extensions/Object3D.ts +25 -2
  68. package/src/engine-components/Animation.ts +1 -1
  69. package/src/engine-components/AnimationUtilsAutoplay.ts +1 -6
  70. package/src/engine-components/DropListener.ts +40 -31
  71. package/src/engine-components/Skybox.ts +8 -4
  72. package/dist/three-examples-DKY9Nfge.min.js +0 -501
  73. package/dist/vendor-Ja-vKV-a.umd.cjs +0 -1121
@@ -143,13 +143,6 @@ const blobKeyName = "blob";
143
143
  */
144
144
  export class DropListener extends Behaviour {
145
145
 
146
- /**
147
- * When enabled, the DropListener will automatically synchronize dropped files to other connected clients.
148
- * When a file is dropped locally, it will be uploaded to blob storage and the URL will be shared with other clients.
149
- */
150
- @serializable()
151
- useNetworking: boolean = true;
152
-
153
146
  /**
154
147
  * When assigned, the DropListener will only accept files that are dropped on this specific object.
155
148
  * This allows creating designated drop zones in your scene.
@@ -159,7 +152,10 @@ export class DropListener extends Behaviour {
159
152
 
160
153
  /**
161
154
  * When enabled, dropped objects will be automatically scaled to fit within the volume defined by fitVolumeSize.
162
- * Useful for ensuring dropped models appear at an appropriate scale.
155
+ * Useful for ensuring dropped models appear at an appropriate scale.
156
+ *
157
+ * **Tip**: Use the handy `fitObjectIntoVolume` function (`import { fitObjectIntoVolume } from "@needle-tools/engine"`) for custom fitting needs.
158
+ *
163
159
  * @default false
164
160
  */
165
161
  @serializable()
@@ -180,6 +176,14 @@ export class DropListener extends Behaviour {
180
176
  @serializable()
181
177
  placeAtHitPosition: boolean = true;
182
178
 
179
+ /**
180
+ * When enabled, the DropListener will automatically synchronize dropped files to other connected clients.
181
+ * When a file is dropped locally, it will be uploaded to blob storage and the URL will be shared with other clients.
182
+ * @default false
183
+ */
184
+ @serializable()
185
+ useNetworking: boolean = false;
186
+
183
187
  /**
184
188
  * Event list that gets invoked after a file has been successfully added to the scene.
185
189
  * Receives {@link DropListenerOnDropArguments} containing the added object and related information.
@@ -193,6 +197,27 @@ export class DropListener extends Behaviour {
193
197
  @serializable(EventList)
194
198
  onDropped: EventList<DropListenerOnDropArguments> = new EventList();
195
199
 
200
+ /**
201
+ * Loads a file from the given URL and adds it to the scene.
202
+ * @returns A promise that resolves to the loaded object or null if loading failed.
203
+ */
204
+ loadFromURL(url: string, data?: { point?: Vec3, size?: Vec3 }): Promise<Object3D | null> {
205
+ return this.addFromUrl(url, { screenposition: new Vector2(), point: data?.point, size: data?.size, }, false);
206
+ }
207
+
208
+ /**
209
+ * Forgets all previously added objects.
210
+ * The droplistener will then not be able to remove previously added objects.
211
+ */
212
+ forgetObjects() {
213
+ this.removePreviouslyAddedObjects(false);
214
+ }
215
+
216
+
217
+
218
+
219
+ // #region internals
220
+
196
221
  /** @internal */
197
222
  onEnable(): void {
198
223
  this.context.renderer.domElement.addEventListener("dragover", this.onDrag);
@@ -208,21 +233,6 @@ export class DropListener extends Behaviour {
208
233
  this.context.connection.stopListen("droplistener", this.onNetworkEvent);
209
234
  }
210
235
 
211
- /**
212
- * Loads a file from the given URL and adds it to the scene.
213
- */
214
- loadFromURL(url: string, data?: { point?: Vec3, size?: Vec3 }) {
215
- this.addFromUrl(url, { screenposition: new Vector2(), point: data?.point, size: data?.size, }, true);
216
- }
217
-
218
- /**
219
- * Forgets all previously added objects.
220
- * The droplistener will then not be able to remove previously added objects.
221
- */
222
- forgetObjects() {
223
- this.removePreviouslyAddedObjects(false);
224
- }
225
-
226
236
  /**
227
237
  * Handles network events received from other clients containing information about dropped objects
228
238
  * @param evt Network event data containing object information, position, and content URL
@@ -326,7 +336,7 @@ export class DropListener extends Behaviour {
326
336
  }
327
337
  }
328
338
  if (files.length > 0) {
329
- await this.addDroppedFiles(files, ctx);
339
+ await this.addFromFiles(files, ctx);
330
340
  }
331
341
  }
332
342
 
@@ -359,6 +369,7 @@ export class DropListener extends Behaviour {
359
369
  // Ignore dropped images
360
370
  const lowercaseUrl = url.toLowerCase();
361
371
  if (lowercaseUrl.endsWith(".hdr") || lowercaseUrl.endsWith(".hdri") || lowercaseUrl.endsWith(".exr") || lowercaseUrl.endsWith(".png") || lowercaseUrl.endsWith(".jpg") || lowercaseUrl.endsWith(".jpeg")) {
372
+ console.warn(`Fileformat is not supported: ${lowercaseUrl}`);
362
373
  return null;
363
374
  }
364
375
 
@@ -374,7 +385,7 @@ export class DropListener extends Behaviour {
374
385
  });
375
386
  if (res && this._addedObjects.length <= 0) {
376
387
  ctx.url = url;
377
- const obj = this.addObject(res, ctx, isRemote);
388
+ const obj = this.onObjectLoaded(res, ctx, isRemote);
378
389
  return obj;
379
390
  }
380
391
  }
@@ -393,7 +404,7 @@ export class DropListener extends Behaviour {
393
404
  * @param fileList Array of dropped files
394
405
  * @param ctx Context information about where the drop occurred
395
406
  */
396
- private async addDroppedFiles(fileList: Array<File>, ctx: DropContext) {
407
+ private async addFromFiles(fileList: Array<File>, ctx: DropContext) {
397
408
  if (debug) console.log("Add files", fileList)
398
409
  if (!Array.isArray(fileList)) return;
399
410
  if (!fileList.length) return;
@@ -427,7 +438,7 @@ export class DropListener extends Behaviour {
427
438
  if (res) {
428
439
  this.dispatchEvent(new CustomEvent(DropListenerEvents.FileDropped, { detail: file }));
429
440
  ctx.file = file;
430
- const obj = this.addObject(res, ctx, false);
441
+ const obj = this.onObjectLoaded(res, ctx, false);
431
442
 
432
443
  // handle uploading the dropped object and networking the event
433
444
  if (obj && this.context.connection.isConnected && this.useNetworking) {
@@ -478,7 +489,7 @@ export class DropListener extends Behaviour {
478
489
  * @param isRemote Whether this object was shared from a remote client
479
490
  * @returns The added object or null if adding failed
480
491
  */
481
- private addObject(data: { model: Model, contentMD5: string }, ctx: DropContext, isRemote: boolean): Object3D | null {
492
+ private onObjectLoaded(data: { model: Model, contentMD5: string }, ctx: DropContext, isRemote: boolean): Object3D | null {
482
493
 
483
494
  const { model, contentMD5 } = data;
484
495
 
@@ -522,9 +533,7 @@ export class DropListener extends Behaviour {
522
533
  }
523
534
  }
524
535
 
525
- AnimationUtils.assignAnimationsFromFile(model, {
526
- createAnimationComponent: obj => addComponent(obj, Animation)
527
- });
536
+ AnimationUtils.autoplayAnimations(model);
528
537
 
529
538
  const evt = new DropListenerAddedEvent({
530
539
  sender: this,
@@ -217,9 +217,9 @@ export class RemoteSkybox extends Behaviour {
217
217
  if (debug) console.warn("RemoteSkybox: Failed to load texture from url", url);
218
218
  return false;
219
219
  }
220
- // Check if we're still enabled
221
- if (!this.enabled) {
222
- if (debug) console.warn("RemoteSkybox: Component is not enabled, aborting setSkybox");
220
+ // Check if we're not disabled or destroyed
221
+ if (!this.enabled || this.destroyed) {
222
+ if (debug) console.warn("RemoteSkybox: Component is disabled or destroyed");
223
223
  return false;
224
224
  }
225
225
  // Check if the url has changed while loading
@@ -239,7 +239,6 @@ export class RemoteSkybox extends Behaviour {
239
239
  const envMap = this._prevLoadedEnvironment;
240
240
  if (!envMap) return;
241
241
 
242
-
243
242
  if ((envMap instanceof CubeTexture || envMap instanceof CompressedCubeTexture) || envMap.mapping == CubeUVReflectionMapping) {
244
243
  // Nothing to do
245
244
  }
@@ -248,6 +247,11 @@ export class RemoteSkybox extends Behaviour {
248
247
  envMap.needsUpdate = true;
249
248
  }
250
249
 
250
+ if(this.destroyed) return;
251
+ if(!this.context) {
252
+ console.warn("RemoteSkybox: Context is not available - can not apply skybox.");
253
+ return;
254
+ }
251
255
 
252
256
  // capture state
253
257
  if (this.context.scene.background !== envMap)