@needle-tools/gltf-progressive 3.4.0-beta.2 → 3.4.0-beta.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.
package/lib/extension.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BufferGeometry, Mesh, Texture, TextureLoader } from "three";
2
2
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
3
3
  import { addDracoAndKTX2Loaders } from "./loaders.js";
4
- import { determineTextureMemoryInBytes, getParam, PromiseQueue, resolveUrl } from "./utils.internal.js";
4
+ import { determineTextureMemoryInBytes, getParam, isMobileDevice, PromiseQueue, resolveUrl } from "./utils.internal.js";
5
5
  import { getRaycastMesh, registerRaycastMesh } from "./utils.js";
6
6
  // All of this has to be removed
7
7
  // import { getRaycastMesh, setRaycastMesh } from "../../engine_physics.js";
@@ -312,7 +312,7 @@ export class NEEDLE_progressive {
312
312
  }
313
313
  /**
314
314
  * Set the maximum number of concurrent loading tasks for LOD resources. This limits how many LOD resources (meshes or textures) can be loaded at the same time to prevent overloading the network or GPU. If the limit is reached, additional loading requests will be queued and processed as previous ones finish.
315
- * @default 50
315
+ * @default 50 on desktop, 20 on mobile devices
316
316
  */
317
317
  static set maxConcurrentLoadingTasks(value) {
318
318
  NEEDLE_progressive.queue.maxConcurrent = value;
@@ -582,6 +582,8 @@ export class NEEDLE_progressive {
582
582
  }
583
583
  }
584
584
  else {
585
+ // Invalidate requests waiting for a queue slot as well as active loads.
586
+ this.cacheGeneration++;
585
587
  this.lodInfos.clear();
586
588
  for (const [, entryRef] of this.lowresCache) {
587
589
  const entry = entryRef.deref();
@@ -622,6 +624,7 @@ export class NEEDLE_progressive {
622
624
  else {
623
625
  // Promise — may be in-flight or already resolved.
624
626
  // Attach disposal to run after resolution.
627
+ this.disposedRequests.add(entry);
625
628
  entry.then(resource => {
626
629
  if (resource) {
627
630
  if (Array.isArray(resource)) {
@@ -721,8 +724,11 @@ export class NEEDLE_progressive {
721
724
  }
722
725
  }
723
726
  static workers = [];
727
+ static cacheGeneration = 0;
728
+ static disposedRequests = new WeakSet();
724
729
  static _workersIndex = 0;
725
730
  static async getOrLoadLOD(current, level) {
731
+ const generation = this.cacheGeneration;
726
732
  const debugverbose = debug == "verbose";
727
733
  /** this key is used to lookup the LOD information */
728
734
  const LOD = this.getAssignedLODInformation(current);
@@ -792,6 +798,8 @@ export class NEEDLE_progressive {
792
798
  // check if the requested file has already been loaded
793
799
  const KEY = lod_url + "_" + lodInfo.guid;
794
800
  const slot = await this.queue.slot(lod_url);
801
+ if (generation !== this.cacheGeneration)
802
+ return null;
795
803
  // check if the requested file is currently being loaded or was previously loaded
796
804
  const existing = this.cache.get(KEY);
797
805
  if (existing !== undefined) {
@@ -831,6 +839,8 @@ export class NEEDLE_progressive {
831
839
  console.error(`Error loading LOD ${level} from ${lod_url}\n`, err);
832
840
  return null;
833
841
  });
842
+ if (generation !== this.cacheGeneration || this.disposedRequests.has(existing))
843
+ return null;
834
844
  let resouceIsDisposed = false;
835
845
  if (res == null) {
836
846
  // if the resource is null the last loading result didnt succeed (maybe because the url doesnt exist)
@@ -1008,6 +1018,10 @@ export class NEEDLE_progressive {
1008
1018
  this.cache.set(KEY, request);
1009
1019
  slot.use(request);
1010
1020
  const res = await request;
1021
+ // dispose() cleans up removed pending entries when they resolve. Do not
1022
+ // return those resources or overwrite a newer request for this key.
1023
+ if (generation !== this.cacheGeneration || this.cache.get(KEY) !== request)
1024
+ return null;
1011
1025
  // Optimize cache entry: replace loading promise with lightweight reference.
1012
1026
  // This releases closure variables captured during the loading function.
1013
1027
  if (res != null) {
@@ -1040,6 +1054,10 @@ export class NEEDLE_progressive {
1040
1054
  console.log("Load texture from uri: " + lod_url);
1041
1055
  const loader = new TextureLoader();
1042
1056
  const tex = await loader.loadAsync(lod_url);
1057
+ if (generation !== this.cacheGeneration) {
1058
+ tex?.dispose();
1059
+ return null;
1060
+ }
1043
1061
  if (tex) {
1044
1062
  tex.guid = lodInfo.guid;
1045
1063
  tex.flipY = false;
@@ -1056,7 +1074,7 @@ export class NEEDLE_progressive {
1056
1074
  }
1057
1075
  return null;
1058
1076
  }
1059
- static queue = new PromiseQueue(50, { debug: debug != false });
1077
+ static queue = new PromiseQueue(isMobileDevice() ? 20 : 50, { debug: debug != false });
1060
1078
  static assignLODInformation(url, res, key, level, index) {
1061
1079
  if (!res)
1062
1080
  return;
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // replaced at build time
2
- export const version = "3.4.0-beta.2";
2
+ export const version = "3.4.0-beta.4";
3
3
  globalThis["GLTF_PROGRESSIVE_VERSION"] = version;
4
4
  console.debug(`[gltf-progressive] version ${version || "-"}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-progressive",
3
- "version": "3.4.0-beta.2",
3
+ "version": "3.4.0-beta.4",
4
4
  "description": "three.js support for loading glTF or GLB files that contain progressive loading data",
5
5
  "homepage": "https://needle.tools",
6
6
  "author": {