UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

122 lines (121 loc) 3.2 kB
import { Asset } from "../../asset/asset.js"; import { GSplatAssetLoaderBase } from "../../../scene/gsplat-unified/gsplat-asset-loader-base.js"; class GSplatAssetLoader extends GSplatAssetLoaderBase { _urlToAsset = /* @__PURE__ */ new Map(); _registry; maxConcurrentLoads = 2; maxRetries = 2; _currentlyLoading = /* @__PURE__ */ new Set(); _loadQueue = []; _retryCount = /* @__PURE__ */ new Map(); _destroyed = false; constructor(registry) { super(); this._registry = registry; } destroy() { this._destroyed = true; for (const asset of this._urlToAsset.values()) { asset.fire("unload", asset); asset.off("load"); asset.off("error"); this._registry.remove(asset); asset.unload(); } this._urlToAsset.clear(); this._loadQueue.length = 0; this._currentlyLoading.clear(); this._retryCount.clear(); } _canLoad() { return !!this._registry.loader?.getHandler("gsplat"); } load(url) { const asset = this._urlToAsset.get(url); if (asset?.loaded || this._currentlyLoading.has(url)) { return; } if (this._loadQueue.includes(url)) { return; } if (this._currentlyLoading.size < this.maxConcurrentLoads) { this._startLoading(url); } else { this._loadQueue.push(url); } } _startLoading(url) { this._currentlyLoading.add(url); let asset = this._urlToAsset.get(url); if (!asset) { asset = new Asset(url, "gsplat", { url }); this._registry.add(asset); this._urlToAsset.set(url, asset); } asset.once("load", () => this._onAssetLoadSuccess(url, asset)); asset.once("error", (err) => this._onAssetLoadError(url, asset, err)); if (!asset.loaded && !asset.loading) { this._registry.load(asset); } } _onAssetLoadSuccess(url, asset) { if (this._destroyed || !this._urlToAsset.has(url)) { return; } this._currentlyLoading.delete(url); this._retryCount.delete(url); this._processQueue(); } _onAssetLoadError(url, asset, err) { if (this._destroyed || !this._canLoad() || !this._urlToAsset.has(url)) { return; } const retryCount = this._retryCount.get(url) || 0; if (retryCount < this.maxRetries) { this._retryCount.set(url, retryCount + 1); asset.loaded = false; asset.loading = false; this._registry.load(asset); } else { this._currentlyLoading.delete(url); this._retryCount.delete(url); this._processQueue(); } } _processQueue() { if (this._destroyed || !this._canLoad()) { return; } while (this._currentlyLoading.size < this.maxConcurrentLoads && this._loadQueue.length > 0) { const url = this._loadQueue.shift(); if (url) { this._startLoading(url); } } } unload(url) { this._currentlyLoading.delete(url); const queueIndex = this._loadQueue.indexOf(url); if (queueIndex !== -1) { this._loadQueue.splice(queueIndex, 1); } this._retryCount.delete(url); const asset = this._urlToAsset.get(url); if (asset) { asset.fire("unload", asset); asset.off("load"); asset.off("error"); this._registry.remove(asset); asset.unload(); this._urlToAsset.delete(url); } this._processQueue(); } getResource(url) { const asset = this._urlToAsset.get(url); return asset?.resource; } } export { GSplatAssetLoader };