UNPKG

bp-cloner

Version:

More info and explanations here - https://doc.babylonjs.com/communityExtensions/clonerSystem

441 lines (440 loc) 20.6 kB
import { c as S, T as _, A as u } from "./index-7uRiSnMV.js"; class d { /** * Creates a new KhronosTextureContainer * @param data contents of the KTX container file * @param facesExpected should be either 1 or 6, based whether a cube texture or or */ constructor(s, e) { if (this.data = s, this.isInvalid = !1, !d.IsValid(s)) { this.isInvalid = !0, S.Error("texture missing KTX identifier"); return; } const i = Uint32Array.BYTES_PER_ELEMENT, r = new DataView(this.data.buffer, this.data.byteOffset + 12, 13 * i), a = r.getUint32(0, !0) === 67305985; if (this.glType = r.getUint32(1 * i, a), this.glTypeSize = r.getUint32(2 * i, a), this.glFormat = r.getUint32(3 * i, a), this.glInternalFormat = r.getUint32(4 * i, a), this.glBaseInternalFormat = r.getUint32(5 * i, a), this.pixelWidth = r.getUint32(6 * i, a), this.pixelHeight = r.getUint32(7 * i, a), this.pixelDepth = r.getUint32(8 * i, a), this.numberOfArrayElements = r.getUint32(9 * i, a), this.numberOfFaces = r.getUint32(10 * i, a), this.numberOfMipmapLevels = r.getUint32(11 * i, a), this.bytesOfKeyValueData = r.getUint32(12 * i, a), this.glType !== 0) { S.Error("only compressed formats currently supported"), this.isInvalid = !0; return; } else this.numberOfMipmapLevels = Math.max(1, this.numberOfMipmapLevels); if (this.pixelHeight === 0 || this.pixelDepth !== 0) { S.Error("only 2D textures currently supported"), this.isInvalid = !0; return; } if (this.numberOfArrayElements !== 0) { S.Error("texture arrays not currently supported"), this.isInvalid = !0; return; } if (this.numberOfFaces !== e) { S.Error("number of faces expected" + e + ", but found " + this.numberOfFaces), this.isInvalid = !0; return; } this.loadType = d.COMPRESSED_2D; } /** * Uploads KTX content to a Babylon Texture. * It is assumed that the texture has already been created & is currently bound * @internal */ uploadLevels(s, e) { switch (this.loadType) { case d.COMPRESSED_2D: this._upload2DCompressedLevels(s, e); break; } } _upload2DCompressedLevels(s, e) { let i = d.HEADER_LEN + this.bytesOfKeyValueData, r = this.pixelWidth, c = this.pixelHeight; const a = e ? this.numberOfMipmapLevels : 1; for (let f = 0; f < a; f++) { const l = new Int32Array(this.data.buffer, this.data.byteOffset + i, 1)[0]; i += 4; for (let R = 0; R < this.numberOfFaces; R++) { const n = new Uint8Array(this.data.buffer, this.data.byteOffset + i, l); s.getEngine()._uploadCompressedDataToTextureDirectly(s, s.format, r, c, n, R, f), i += l, i += 3 - (l + 3) % 4; } r = Math.max(1, r * 0.5), c = Math.max(1, c * 0.5); } } /** * Checks if the given data starts with a KTX file identifier. * @param data the data to check * @returns true if the data is a KTX file or false otherwise */ static IsValid(s) { if (s.byteLength >= 12) { const e = new Uint8Array(s.buffer, s.byteOffset, 12); if (e[0] === 171 && e[1] === 75 && e[2] === 84 && e[3] === 88 && e[4] === 32 && e[5] === 49 && e[6] === 49 && e[7] === 187 && e[8] === 13 && e[9] === 10 && e[10] === 26 && e[11] === 10) return !0; } return !1; } } d.HEADER_LEN = 12 + 13 * 4; d.COMPRESSED_2D = 0; d.COMPRESSED_3D = 1; d.TEX_2D = 2; d.TEX_3D = 3; var h; (function(t) { t[t.ETC1S = 0] = "ETC1S", t[t.UASTC4x4 = 1] = "UASTC4x4"; })(h || (h = {})); var T; (function(t) { t[t.ASTC_4X4_RGBA = 0] = "ASTC_4X4_RGBA", t[t.BC7_RGBA = 1] = "BC7_RGBA", t[t.BC3_RGBA = 2] = "BC3_RGBA", t[t.BC1_RGB = 3] = "BC1_RGB", t[t.PVRTC1_4_RGBA = 4] = "PVRTC1_4_RGBA", t[t.PVRTC1_4_RGB = 5] = "PVRTC1_4_RGB", t[t.ETC2_RGBA = 6] = "ETC2_RGBA", t[t.ETC1_RGB = 7] = "ETC1_RGB", t[t.RGBA32 = 8] = "RGBA32", t[t.R8 = 9] = "R8", t[t.RG8 = 10] = "RG8"; })(T || (T = {})); var D; (function(t) { t[t.COMPRESSED_RGBA_BPTC_UNORM_EXT = 36492] = "COMPRESSED_RGBA_BPTC_UNORM_EXT", t[t.COMPRESSED_RGBA_ASTC_4X4_KHR = 37808] = "COMPRESSED_RGBA_ASTC_4X4_KHR", t[t.COMPRESSED_RGB_S3TC_DXT1_EXT = 33776] = "COMPRESSED_RGB_S3TC_DXT1_EXT", t[t.COMPRESSED_RGBA_S3TC_DXT5_EXT = 33779] = "COMPRESSED_RGBA_S3TC_DXT5_EXT", t[t.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 35842] = "COMPRESSED_RGBA_PVRTC_4BPPV1_IMG", t[t.COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 35840] = "COMPRESSED_RGB_PVRTC_4BPPV1_IMG", t[t.COMPRESSED_RGBA8_ETC2_EAC = 37496] = "COMPRESSED_RGBA8_ETC2_EAC", t[t.COMPRESSED_RGB8_ETC2 = 37492] = "COMPRESSED_RGB8_ETC2", t[t.COMPRESSED_RGB_ETC1_WEBGL = 36196] = "COMPRESSED_RGB_ETC1_WEBGL", t[t.RGBA8Format = 32856] = "RGBA8Format", t[t.R8Format = 33321] = "R8Format", t[t.RG8Format = 33323] = "RG8Format"; })(D || (D = {})); function A(t, s) { const e = (s == null ? void 0 : s.jsDecoderModule) || KTX2DECODER; t && (t.wasmUASTCToASTC && (e.LiteTranscoder_UASTC_ASTC.WasmModuleURL = t.wasmUASTCToASTC), t.wasmUASTCToBC7 && (e.LiteTranscoder_UASTC_BC7.WasmModuleURL = t.wasmUASTCToBC7), t.wasmUASTCToRGBA_UNORM && (e.LiteTranscoder_UASTC_RGBA_UNORM.WasmModuleURL = t.wasmUASTCToRGBA_UNORM), t.wasmUASTCToRGBA_SRGB && (e.LiteTranscoder_UASTC_RGBA_SRGB.WasmModuleURL = t.wasmUASTCToRGBA_SRGB), t.wasmUASTCToR8_UNORM && (e.LiteTranscoder_UASTC_R8_UNORM.WasmModuleURL = t.wasmUASTCToR8_UNORM), t.wasmUASTCToRG8_UNORM && (e.LiteTranscoder_UASTC_RG8_UNORM.WasmModuleURL = t.wasmUASTCToRG8_UNORM), t.jsMSCTranscoder && (e.MSCTranscoder.JSModuleURL = t.jsMSCTranscoder), t.wasmMSCTranscoder && (e.MSCTranscoder.WasmModuleURL = t.wasmMSCTranscoder), t.wasmZSTDDecoder && (e.ZSTDDecoder.WasmModuleURL = t.wasmZSTDDecoder)), s && (s.wasmUASTCToASTC && (e.LiteTranscoder_UASTC_ASTC.WasmBinary = s.wasmUASTCToASTC), s.wasmUASTCToBC7 && (e.LiteTranscoder_UASTC_BC7.WasmBinary = s.wasmUASTCToBC7), s.wasmUASTCToRGBA_UNORM && (e.LiteTranscoder_UASTC_RGBA_UNORM.WasmBinary = s.wasmUASTCToRGBA_UNORM), s.wasmUASTCToRGBA_SRGB && (e.LiteTranscoder_UASTC_RGBA_SRGB.WasmBinary = s.wasmUASTCToRGBA_SRGB), s.wasmUASTCToR8_UNORM && (e.LiteTranscoder_UASTC_R8_UNORM.WasmBinary = s.wasmUASTCToR8_UNORM), s.wasmUASTCToRG8_UNORM && (e.LiteTranscoder_UASTC_RG8_UNORM.WasmBinary = s.wasmUASTCToRG8_UNORM), s.jsMSCTranscoder && (e.MSCTranscoder.JSModule = s.jsMSCTranscoder), s.wasmMSCTranscoder && (e.MSCTranscoder.WasmBinary = s.wasmMSCTranscoder), s.wasmZSTDDecoder && (e.ZSTDDecoder.WasmBinary = s.wasmZSTDDecoder)); } function G(t) { typeof t > "u" && typeof KTX2DECODER < "u" && (t = KTX2DECODER); let s; onmessage = (e) => { if (e.data) switch (e.data.action) { case "init": { const i = e.data.urls; i && (i.jsDecoderModule && typeof t > "u" && (importScripts(i.jsDecoderModule), t = KTX2DECODER), A(i)), e.data.wasmBinaries && A(void 0, { ...e.data.wasmBinaries, jsDecoderModule: t }), s = new t.KTX2Decoder(), postMessage({ action: "init" }); break; } case "setDefaultDecoderOptions": { t.KTX2Decoder.DefaultDecoderOptions = e.data.options; break; } case "decode": s.decode(e.data.data, e.data.caps, e.data.options).then((i) => { const r = []; for (let c = 0; c < i.mipmaps.length; ++c) { const a = i.mipmaps[c]; a && a.data && r.push(a.data.buffer); } postMessage({ action: "decoded", success: !0, decodedData: i }, r); }).catch((i) => { postMessage({ action: "decoded", success: !1, msg: i }); }); break; } }; } function M(t, s, e) { return new Promise((i, r) => { const c = (f) => { t.removeEventListener("error", c), t.removeEventListener("message", a), r(f); }, a = (f) => { f.data.action === "init" && (t.removeEventListener("error", c), t.removeEventListener("message", a), i(t)); }; t.addEventListener("error", c), t.addEventListener("message", a), t.postMessage({ action: "init", urls: e, wasmBinaries: s }); }); } class y { constructor() { this._isDirty = !0, this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC = !0, this._ktx2DecoderOptions = {}; } /** * Gets the dirty flag */ get isDirty() { return this._isDirty; } /** * force a (uncompressed) RGBA transcoded format if transcoding a UASTC source format and ASTC + BC7 are not available as a compressed transcoded format */ get useRGBAIfASTCBC7NotAvailableWhenUASTC() { return this._useRGBAIfASTCBC7NotAvailableWhenUASTC; } set useRGBAIfASTCBC7NotAvailableWhenUASTC(s) { this._useRGBAIfASTCBC7NotAvailableWhenUASTC !== s && (this._useRGBAIfASTCBC7NotAvailableWhenUASTC = s, this._isDirty = !0); } /** * force a (uncompressed) RGBA transcoded format if transcoding a UASTC source format and only BC1 or BC3 are available as a compressed transcoded format. * This property is true by default to favor speed over memory, because currently transcoding from UASTC to BC1/3 is slow because the transcoder transcodes * to uncompressed and then recompresses the texture */ get useRGBAIfOnlyBC1BC3AvailableWhenUASTC() { return this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC; } set useRGBAIfOnlyBC1BC3AvailableWhenUASTC(s) { this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC !== s && (this._useRGBAIfOnlyBC1BC3AvailableWhenUASTC = s, this._isDirty = !0); } /** * force to always use (uncompressed) RGBA for transcoded format */ get forceRGBA() { return this._forceRGBA; } set forceRGBA(s) { this._forceRGBA !== s && (this._forceRGBA = s, this._isDirty = !0); } /** * force to always use (uncompressed) R8 for transcoded format */ get forceR8() { return this._forceR8; } set forceR8(s) { this._forceR8 !== s && (this._forceR8 = s, this._isDirty = !0); } /** * force to always use (uncompressed) RG8 for transcoded format */ get forceRG8() { return this._forceRG8; } set forceRG8(s) { this._forceRG8 !== s && (this._forceRG8 = s, this._isDirty = !0); } /** * list of transcoders to bypass when looking for a suitable transcoder. The available transcoders are: * UniversalTranscoder_UASTC_ASTC * UniversalTranscoder_UASTC_BC7 * UniversalTranscoder_UASTC_RGBA_UNORM * UniversalTranscoder_UASTC_RGBA_SRGB * UniversalTranscoder_UASTC_R8_UNORM * UniversalTranscoder_UASTC_RG8_UNORM * MSCTranscoder */ get bypassTranscoders() { return this._bypassTranscoders; } set bypassTranscoders(s) { this._bypassTranscoders !== s && (this._bypassTranscoders = s, this._isDirty = !0); } /** @internal */ _getKTX2DecoderOptions() { if (!this._isDirty) return this._ktx2DecoderOptions; this._isDirty = !1; const s = { useRGBAIfASTCBC7NotAvailableWhenUASTC: this._useRGBAIfASTCBC7NotAvailableWhenUASTC, forceRGBA: this._forceRGBA, forceR8: this._forceR8, forceRG8: this._forceRG8, bypassTranscoders: this._bypassTranscoders }; return this.useRGBAIfOnlyBC1BC3AvailableWhenUASTC && (s.transcodeFormatDecisionTree = { UASTC: { transcodeFormat: [T.BC1_RGB, T.BC3_RGBA], yes: { transcodeFormat: T.RGBA32, engineFormat: 32856, roundToMultiple4: !1 } } }), this._ktx2DecoderOptions = s, s; } } class o { static GetDefaultNumWorkers() { return typeof navigator != "object" || !navigator.hardwareConcurrency ? 1 : Math.min(Math.floor(navigator.hardwareConcurrency * 0.5), 4); } static _Initialize(s) { if (o._WorkerPoolPromise || o._DecoderModulePromise) return; const e = { jsDecoderModule: _.GetBabylonScriptURL(this.URLConfig.jsDecoderModule, !0), wasmUASTCToASTC: _.GetBabylonScriptURL(this.URLConfig.wasmUASTCToASTC, !0), wasmUASTCToBC7: _.GetBabylonScriptURL(this.URLConfig.wasmUASTCToBC7, !0), wasmUASTCToRGBA_UNORM: _.GetBabylonScriptURL(this.URLConfig.wasmUASTCToRGBA_UNORM, !0), wasmUASTCToRGBA_SRGB: _.GetBabylonScriptURL(this.URLConfig.wasmUASTCToRGBA_SRGB, !0), wasmUASTCToR8_UNORM: _.GetBabylonScriptURL(this.URLConfig.wasmUASTCToR8_UNORM, !0), wasmUASTCToRG8_UNORM: _.GetBabylonScriptURL(this.URLConfig.wasmUASTCToRG8_UNORM, !0), jsMSCTranscoder: _.GetBabylonScriptURL(this.URLConfig.jsMSCTranscoder, !0), wasmMSCTranscoder: _.GetBabylonScriptURL(this.URLConfig.wasmMSCTranscoder, !0), wasmZSTDDecoder: _.GetBabylonScriptURL(this.URLConfig.wasmZSTDDecoder, !0) }; s && typeof Worker == "function" && typeof URL < "u" ? o._WorkerPoolPromise = new Promise((i) => { const r = `${A}(${G})()`, c = URL.createObjectURL(new Blob([r], { type: "application/javascript" })); i(new u(s, () => M(new Worker(c), void 0, e))); }) : typeof o._KTX2DecoderModule > "u" ? o._DecoderModulePromise = _.LoadBabylonScriptAsync(e.jsDecoderModule).then(() => (o._KTX2DecoderModule = KTX2DECODER, o._KTX2DecoderModule.MSCTranscoder.UseFromWorkerThread = !1, o._KTX2DecoderModule.WASMMemoryManager.LoadBinariesFromCurrentThread = !0, A(e, o._KTX2DecoderModule), new o._KTX2DecoderModule.KTX2Decoder())) : (o._KTX2DecoderModule.MSCTranscoder.UseFromWorkerThread = !1, o._KTX2DecoderModule.WASMMemoryManager.LoadBinariesFromCurrentThread = !0, o._DecoderModulePromise = Promise.resolve(new o._KTX2DecoderModule.KTX2Decoder())); } /** * Constructor * @param engine The engine to use * @param numWorkersOrOptions The number of workers for async operations. Specify `0` to disable web workers and run synchronously in the current context. */ constructor(s, e = o.DefaultNumWorkers) { var r; this._engine = s; const i = typeof e == "object" && e.workerPool || o.WorkerPool; if (i) o._WorkerPoolPromise = Promise.resolve(i); else { typeof e == "object" ? o._KTX2DecoderModule = (r = e == null ? void 0 : e.binariesAndModulesContainer) == null ? void 0 : r.jsDecoderModule : typeof KTX2DECODER < "u" && (o._KTX2DecoderModule = KTX2DECODER); const c = typeof e == "number" ? e : e.numWorkers ?? o.DefaultNumWorkers; o._Initialize(c); } } /** * @internal */ _uploadAsync(s, e, i) { const r = this._engine.getCaps(), c = { astc: !!r.astc, bptc: !!r.bptc, s3tc: !!r.s3tc, pvrtc: !!r.pvrtc, etc2: !!r.etc2, etc1: !!r.etc1 }; if (o._WorkerPoolPromise) return o._WorkerPoolPromise.then((a) => new Promise((f, l) => { a.push((R, n) => { const C = (m) => { R.removeEventListener("error", C), R.removeEventListener("message", p), l(m), n(); }, p = (m) => { if (m.data.action === "decoded") { if (R.removeEventListener("error", C), R.removeEventListener("message", p), !m.data.success) l({ message: m.data.msg }); else try { this._createTexture(m.data.decodedData, e, i), f(); } catch (U) { l({ message: U }); } n(); } }; R.addEventListener("error", C), R.addEventListener("message", p), R.postMessage({ action: "setDefaultDecoderOptions", options: o.DefaultDecoderOptions._getKTX2DecoderOptions() }); const B = new Uint8Array(s.byteLength); B.set(new Uint8Array(s.buffer, s.byteOffset, s.byteLength)), R.postMessage({ action: "decode", data: B, caps: c, options: i }, [B.buffer]); }); })); if (o._DecoderModulePromise) return o._DecoderModulePromise.then((a) => (o.DefaultDecoderOptions.isDirty && (o._KTX2DecoderModule.KTX2Decoder.DefaultDecoderOptions = o.DefaultDecoderOptions._getKTX2DecoderOptions()), new Promise((f, l) => { a.decode(s, r).then((R) => { this._createTexture(R, e), f(); }).catch((R) => { l({ message: R }); }); }))); throw new Error("KTX2 decoder module is not available"); } _createTexture(s, e, i) { this._engine._bindTextureDirectly(3553, e), i && (i.transcodedFormat = s.transcodedFormat, i.isInGammaSpace = s.isInGammaSpace, i.hasAlpha = s.hasAlpha, i.transcoderName = s.transcoderName); let c = !0; switch (s.transcodedFormat) { case 32856: e.type = 0, e.format = 5; break; case 33321: e.type = 0, e.format = 6; break; case 33323: e.type = 0, e.format = 7; break; default: e.format = s.transcodedFormat, c = !1; break; } if (e._gammaSpace = s.isInGammaSpace, e.generateMipMaps = s.mipmaps.length > 1, s.errors) throw new Error("KTX2 container - could not transcode the data. " + s.errors); for (let a = 0; a < s.mipmaps.length; ++a) { const f = s.mipmaps[a]; if (!f || !f.data) throw new Error("KTX2 container - could not transcode one of the image"); c ? (e.width = f.width, e.height = f.height, this._engine._uploadDataToTextureDirectly(e, f.data, 0, a, void 0, !0)) : this._engine._uploadCompressedDataToTextureDirectly(e, s.transcodedFormat, f.width, f.height, f.data, 0, a); } e._extension = ".ktx2", e.width = s.mipmaps[0].width, e.height = s.mipmaps[0].height, e.isReady = !0, this._engine._bindTextureDirectly(3553, null); } /** * Checks if the given data starts with a KTX2 file identifier. * @param data the data to check * @returns true if the data is a KTX2 file or false otherwise */ static IsValid(s) { if (s.byteLength >= 12) { const e = new Uint8Array(s.buffer, s.byteOffset, 12); if (e[0] === 171 && e[1] === 75 && e[2] === 84 && e[3] === 88 && e[4] === 32 && e[5] === 50 && e[6] === 48 && e[7] === 187 && e[8] === 13 && e[9] === 10 && e[10] === 26 && e[11] === 10) return !0; } return !1; } } o.URLConfig = { jsDecoderModule: "https://cdn.babylonjs.com/babylon.ktx2Decoder.js", wasmUASTCToASTC: null, wasmUASTCToBC7: null, wasmUASTCToRGBA_UNORM: null, wasmUASTCToRGBA_SRGB: null, wasmUASTCToR8_UNORM: null, wasmUASTCToRG8_UNORM: null, jsMSCTranscoder: null, wasmMSCTranscoder: null, wasmZSTDDecoder: null }; o.DefaultNumWorkers = o.GetDefaultNumWorkers(); o.DefaultDecoderOptions = new y(); function E(t) { switch (t) { case 35916: return 33776; case 35918: return 33778; case 35919: return 33779; case 37493: return 37492; case 37497: return 37496; case 37495: return 37494; case 37840: return 37808; case 36493: return 36492; } return null; } class O { constructor() { this.supportCascades = !1; } /** * Uploads the cube texture data to the WebGL texture. It has already been bound. * @param data contains the texture data * @param texture defines the BabylonJS internal texture * @param createPolynomials will be true if polynomials have been requested * @param onLoad defines the callback to trigger once the texture is ready */ loadCubeData(s, e, i, r) { if (Array.isArray(s)) return; e._invertVScale = !e.invertY; const c = e.getEngine(), a = new d(s, 6), f = a.numberOfMipmapLevels > 1 && e.generateMipMaps; c._unpackFlipY(!0), a.uploadLevels(e, e.generateMipMaps), e.width = a.pixelWidth, e.height = a.pixelHeight, c._setCubeMapTextureParams(e, f, a.numberOfMipmapLevels - 1), e.isReady = !0, e.onLoadedObservable.notifyObservers(e), e.onLoadedObservable.clear(), r && r(); } /** * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback. * @param data contains the texture data * @param texture defines the BabylonJS internal texture * @param callback defines the method to call once ready to upload * @param options */ loadData(s, e, i, r) { if (d.IsValid(s)) { e._invertVScale = !e.invertY; const c = new d(s, 1), a = E(c.glInternalFormat); a ? (e.format = a, e._useSRGBBuffer = e.getEngine()._getUseSRGBBuffer(!0, e.generateMipMaps), e._gammaSpace = !0) : e.format = c.glInternalFormat, i(c.pixelWidth, c.pixelHeight, e.generateMipMaps, !0, () => { c.uploadLevels(e, e.generateMipMaps); }, c.isInvalid); } else o.IsValid(s) ? new o(e.getEngine())._uploadAsync(s, e, r).then(() => { i(e.width, e.height, e.generateMipMaps, !0, () => { }, !1); }, (a) => { S.Warn(`Failed to load KTX2 texture data: ${a.message}`), i(0, 0, !1, !1, () => { }, !0); }) : (S.Error("texture missing KTX identifier"), i(0, 0, !1, !1, () => { }, !0)); } } export { O as _KTXTextureLoader };