gaussian-splat-lite 0.1.11 → 0.1.13
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/CHANGELOG.md +20 -1
- package/README.md +4 -3
- package/dist/assets/worker-C26a7h-J.js.map +1 -0
- package/dist/assets/worker-Cx-xVLFg.js.map +1 -0
- package/dist/gaussian-splat-lite.cjs +536 -255
- package/dist/gaussian-splat-lite.cjs.map +1 -1
- package/dist/gaussian-splat-lite.min.cjs +7 -7
- package/dist/gaussian-splat-lite.min.cjs.map +1 -1
- package/dist/gaussian-splat-lite.module.js +536 -255
- package/dist/gaussian-splat-lite.module.js.map +1 -1
- package/dist/gaussian-splat-lite.module.min.js +1234 -1038
- package/dist/gaussian-splat-lite.module.min.js.map +1 -1
- package/dist/types/postDecode.d.cts +52 -10
- package/dist/types/postDecode.d.ts +52 -10
- package/dist/types/postDecodeRuntime.d.cts +2 -1
- package/dist/types/postDecodeRuntime.d.ts +2 -1
- package/docs/PostDecode.md +9 -2
- package/docs/SplatMesh.md +1 -1
- package/docs/Splats.md +1 -1
- package/package.json +1 -1
- package/dist/assets/worker-BjNOf79T.js.map +0 -1
- package/dist/assets/worker-sy3s-ARA.js.map +0 -1
|
@@ -2446,7 +2446,7 @@ const QUAD_VERTICES = new Float32Array([
|
|
|
2446
2446
|
0
|
|
2447
2447
|
]);
|
|
2448
2448
|
const QUAD_INDICES = new Uint16Array([0, 1, 2, 0, 2, 3]);
|
|
2449
|
-
const jsContent = '(function() {\n "use strict";\n class ChunkDecoder {\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ChunkDecoder.prototype);\n obj.__wbg_ptr = ptr;\n ChunkDecoderFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ChunkDecoderFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_chunkdecoder_free(ptr, 0);\n }\n /**\n * @returns {any}\n */\n finish() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.chunkdecoder_finish(ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * @param {Uint8Array} bytes\n */\n push(bytes) {\n const ret = wasm.chunkdecoder_push(this.__wbg_ptr, bytes);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {number} size\n */\n set_expected_input_size(size) {\n const ret = wasm.chunkdecoder_set_expected_input_size(this.__wbg_ptr, size);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n }\n if (Symbol.dispose) ChunkDecoder.prototype[Symbol.dispose] = ChunkDecoder.prototype.free;\n function decode_to_splats(file_type, path_name) {\n var ptr0 = isLikeNone(file_type) ? 0 : passStringToWasm0(file_type, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len0 = WASM_VECTOR_LEN;\n var ptr1 = isLikeNone(path_name) ? 0 : passStringToWasm0(path_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len1 = WASM_VECTOR_LEN;\n const ret = wasm.decode_to_splats(ptr0, len0, ptr1, len1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ChunkDecoder.__wrap(ret[0]);\n }\n function set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts) {\n wasm.set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts);\n }\n function sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, ordering) {\n const ret = wasm.sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, ordering);\n return ret >>> 0;\n }\n function __wbg_get_imports() {\n const import0 = {\n __proto__: null,\n __wbg___wbindgen_debug_string_dd5d2d07ce9e6c57: function(arg0, arg1) {\n const ret = debugString(arg1);\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg___wbindgen_throw_81fc77679af83bc6: function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n },\n __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {\n let deferred0_0;\n let deferred0_1;\n try {\n deferred0_0 = arg0;\n deferred0_1 = arg1;\n console.error(getStringFromWasm0(arg0, arg1));\n } finally {\n wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);\n }\n },\n __wbg_get_index_983d655608220248: function(arg0, arg1) {\n const ret = arg0[arg1 >>> 0];\n return ret;\n },\n __wbg_length_0c32cb8543c8e4c8: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_1e701798fdcaa3b4: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_526c0f6e4ebae15d: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_fd4646b401926788: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_new_227d7c05414eb861: function() {\n const ret = new Error();\n return ret;\n },\n __wbg_new_4f9fafbb3909af72: function() {\n const ret = new Object();\n return ret;\n },\n __wbg_new_with_length_26bffbe236bf73f9: function(arg0) {\n const ret = new Float32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_new_with_length_41a22191b9bdfd66: function(arg0) {\n const ret = new Uint32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_prototypesetcall_021fd89d67217368: function(arg0, arg1, arg2) {\n Float64Array.prototype.set.call(getArrayF64FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_3e05eb9545565046: function(arg0, arg1, arg2) {\n Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_66c8e1fb820946be: function(arg0, arg1, arg2) {\n Float32Array.prototype.set.call(getArrayF32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_e42275e601e14eeb: function(arg0, arg1, arg2) {\n Uint32Array.prototype.set.call(getArrayU32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_set_448126769bf7c181: function(arg0, arg1, arg2) {\n arg0.set(getArrayU32FromWasm0(arg1, arg2));\n },\n __wbg_set_8ee2d34facb8466e: function() {\n return handleError(function(arg0, arg1, arg2) {\n const ret = Reflect.set(arg0, arg1, arg2);\n return ret;\n }, arguments);\n },\n __wbg_set_a98c8da6557e63de: function(arg0, arg1, arg2) {\n arg0.set(getArrayF32FromWasm0(arg1, arg2));\n },\n __wbg_set_index_a561936dd7004b5a: function(arg0, arg1, arg2) {\n arg0[arg1 >>> 0] = arg2;\n },\n __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {\n const ret = arg1.stack;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg_subarray_0f98d3fb634508ad: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_1230568a23d546e8: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_4342405c1ffc86d6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_d51e89458b3fdbf6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbindgen_cast_0000000000000001: function(arg0) {\n const ret = arg0;\n return ret;\n },\n __wbindgen_cast_0000000000000002: function(arg0, arg1) {\n const ret = getArrayF32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000003: function(arg0, arg1) {\n const ret = getArrayU32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000004: function(arg0, arg1) {\n const ret = getStringFromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_init_externref_table: function() {\n const table = wasm.__wbindgen_externrefs;\n const offset = table.grow(4);\n table.set(0, void 0);\n table.set(offset + 0, void 0);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n }\n };\n return {\n __proto__: null,\n "./gaussian_splat_rs_bg.js": import0\n };\n }\n const ChunkDecoderFinalization = typeof FinalizationRegistry === "undefined" ? { register: () => {\n }, unregister: () => {\n } } : new FinalizationRegistry((ptr) => wasm.__wbg_chunkdecoder_free(ptr >>> 0, 1));\n function addToExternrefTable0(obj) {\n const idx = wasm.__externref_table_alloc();\n wasm.__wbindgen_externrefs.set(idx, obj);\n return idx;\n }\n function debugString(val) {\n const type = typeof val;\n if (type == "number" || type == "boolean" || val == null) {\n return `${val}`;\n }\n if (type == "string") {\n return `"${val}"`;\n }\n if (type == "symbol") {\n const description = val.description;\n if (description == null) {\n return "Symbol";\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == "function") {\n const name = val.name;\n if (typeof name == "string" && name.length > 0) {\n return `Function(${name})`;\n } else {\n return "Function";\n }\n }\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = "[";\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for (let i = 1; i < length; i++) {\n debug += ", " + debugString(val[i]);\n }\n debug += "]";\n return debug;\n }\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n return toString.call(val);\n }\n if (className == "Object") {\n try {\n return "Object(" + JSON.stringify(val) + ")";\n } catch (_) {\n return "Object";\n }\n }\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\n${val.stack}`;\n }\n return className;\n }\n function getArrayF32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n }\n function getArrayF64FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);\n }\n function getArrayU32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n }\n function getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n }\n let cachedDataViewMemory0 = null;\n function getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === void 0 && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n }\n let cachedFloat32ArrayMemory0 = null;\n function getFloat32ArrayMemory0() {\n if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {\n cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);\n }\n return cachedFloat32ArrayMemory0;\n }\n let cachedFloat64ArrayMemory0 = null;\n function getFloat64ArrayMemory0() {\n if (cachedFloat64ArrayMemory0 === null || cachedFloat64ArrayMemory0.byteLength === 0) {\n cachedFloat64ArrayMemory0 = new Float64Array(wasm.memory.buffer);\n }\n return cachedFloat64ArrayMemory0;\n }\n function getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return decodeText(ptr, len);\n }\n let cachedUint32ArrayMemory0 = null;\n function getUint32ArrayMemory0() {\n if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {\n cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);\n }\n return cachedUint32ArrayMemory0;\n }\n let cachedUint8ArrayMemory0 = null;\n function getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n }\n function handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n const idx = addToExternrefTable0(e);\n wasm.__wbindgen_exn_store(idx);\n }\n }\n function isLikeNone(x) {\n return x === void 0 || x === null;\n }\n function passStringToWasm0(arg, malloc, realloc) {\n if (realloc === void 0) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr2 = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr2, ptr2 + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr2;\n }\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n const mem = getUint8ArrayMemory0();\n let offset = 0;\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 127) break;\n mem[ptr + offset] = code;\n }\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n WASM_VECTOR_LEN = offset;\n return ptr;\n }\n function takeFromExternrefTable0(idx) {\n const value = wasm.__wbindgen_externrefs.get(idx);\n wasm.__externref_table_dealloc(idx);\n return value;\n }\n let cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n const MAX_SAFARI_DECODE_BYTES = 2146435072;\n let numBytesDecoded = 0;\n function decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n }\n const cachedTextEncoder = new TextEncoder();\n if (!("encodeInto" in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function(arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n };\n }\n let WASM_VECTOR_LEN = 0;\n let wasm;\n function __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n cachedDataViewMemory0 = null;\n cachedFloat32ArrayMemory0 = null;\n cachedFloat64ArrayMemory0 = null;\n cachedUint32ArrayMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n wasm.__wbindgen_start();\n return wasm;\n }\n async function __wbg_load(module, imports) {\n if (typeof Response === "function" && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === "function") {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n const validResponse = module.ok && expectedResponseType(module.type);\n if (validResponse && module.headers.get("Content-Type") !== "application/wasm") {\n console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);\n } else {\n throw e;\n }\n }\n }\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n function expectedResponseType(type) {\n switch (type) {\n case "basic":\n case "cors":\n case "default":\n return true;\n }\n return false;\n }\n }\n async function __wbg_init(module_or_path) {\n if (wasm !== void 0) return wasm;\n if (module_or_path !== void 0) {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({ module_or_path } = module_or_path);\n } else {\n console.warn("using deprecated parameters for the initialization function; pass a single object instead");\n }\n }\n const imports = __wbg_get_imports();\n if (typeof module_or_path === "string" || typeof Request === "function" && module_or_path instanceof Request || typeof URL === "function" && module_or_path instanceof URL) {\n module_or_path = fetch(module_or_path);\n }\n const { instance } = await __wbg_load(await module_or_path, imports);\n return __wbg_finalize_init(instance);\n }\n const f32 = new Float32Array(1);\n const u32 = new Uint32Array(f32.buffer);\n const supportsFloat16Array = "Float16Array" in globalThis;\n const f16 = supportsFloat16Array ? new globalThis["Float16Array"](1) : null;\n const u16 = new Uint16Array(f16 == null ? void 0 : f16.buffer);\n function toHalfNative(value) {\n f16[0] = value;\n return u16[0];\n }\n function toHalfJs(value) {\n f32[0] = value;\n const bits = u32[0];\n const sign = bits >>> 16 & 32768;\n const exponent = bits >>> 23 & 255;\n const fraction = bits & 8388607;\n if (exponent === 255) {\n return sign | (fraction === 0 ? 31744 : 32767);\n }\n const halfExponent = exponent - 127 + 15;\n if (halfExponent >= 31) return sign | 31744;\n if (halfExponent <= 0) {\n if (halfExponent < -10) return sign;\n return sign | (fraction | 8388608) >>> 1 - halfExponent + 13;\n }\n return sign | halfExponent << 10 | fraction >>> 13;\n }\n function fromHalfNative(value) {\n u16[0] = value;\n return f16[0];\n }\n function fromHalfJs(value) {\n const sign = value >>> 15 & 1;\n const exponent = value >>> 10 & 31;\n const fraction = value & 1023;\n let bits;\n if (exponent === 0) {\n if (fraction === 0) {\n bits = sign << 31;\n } else {\n let mantissa = fraction;\n let adjustedExponent = -14;\n while ((mantissa & 1024) === 0) {\n mantissa <<= 1;\n adjustedExponent -= 1;\n }\n bits = sign << 31 | adjustedExponent + 127 << 23 | (mantissa & 1023) << 13;\n }\n } else if (exponent === 31) {\n bits = sign << 31 | (fraction === 0 ? 2139095040 : 2143289344);\n } else {\n bits = sign << 31 | exponent - 15 + 127 << 23 | fraction << 13;\n }\n u32[0] = bits;\n return f32[0];\n }\n const toHalf = supportsFloat16Array ? toHalfNative : toHalfJs;\n const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJs;\n var Opcode = /* @__PURE__ */ ((Opcode2) => {\n Opcode2[Opcode2["Constant"] = 1] = "Constant";\n Opcode2[Opcode2["InputField"] = 2] = "InputField";\n Opcode2[Opcode2["InputAttribute"] = 3] = "InputAttribute";\n Opcode2[Opcode2["Negate"] = 10] = "Negate";\n Opcode2[Opcode2["Abs"] = 11] = "Abs";\n Opcode2[Opcode2["Sqrt"] = 12] = "Sqrt";\n Opcode2[Opcode2["Log"] = 13] = "Log";\n Opcode2[Opcode2["Exp"] = 14] = "Exp";\n Opcode2[Opcode2["Floor"] = 15] = "Floor";\n Opcode2[Opcode2["Ceil"] = 16] = "Ceil";\n Opcode2[Opcode2["Round"] = 17] = "Round";\n Opcode2[Opcode2["Normalize"] = 18] = "Normalize";\n Opcode2[Opcode2["Length"] = 19] = "Length";\n Opcode2[Opcode2["IsFinite"] = 20] = "IsFinite";\n Opcode2[Opcode2["Not"] = 22] = "Not";\n Opcode2[Opcode2["Sin"] = 23] = "Sin";\n Opcode2[Opcode2["Cos"] = 24] = "Cos";\n Opcode2[Opcode2["Acos"] = 25] = "Acos";\n Opcode2[Opcode2["Add"] = 30] = "Add";\n Opcode2[Opcode2["Subtract"] = 31] = "Subtract";\n Opcode2[Opcode2["Multiply"] = 32] = "Multiply";\n Opcode2[Opcode2["Divide"] = 33] = "Divide";\n Opcode2[Opcode2["Min"] = 34] = "Min";\n Opcode2[Opcode2["Max"] = 35] = "Max";\n Opcode2[Opcode2["Pow"] = 36] = "Pow";\n Opcode2[Opcode2["Dot"] = 37] = "Dot";\n Opcode2[Opcode2["Cross"] = 38] = "Cross";\n Opcode2[Opcode2["Equal"] = 39] = "Equal";\n Opcode2[Opcode2["NotEqual"] = 40] = "NotEqual";\n Opcode2[Opcode2["Less"] = 41] = "Less";\n Opcode2[Opcode2["LessEqual"] = 42] = "LessEqual";\n Opcode2[Opcode2["Greater"] = 43] = "Greater";\n Opcode2[Opcode2["GreaterEqual"] = 44] = "GreaterEqual";\n Opcode2[Opcode2["And"] = 45] = "And";\n Opcode2[Opcode2["Or"] = 46] = "Or";\n Opcode2[Opcode2["QuaternionMultiply"] = 47] = "QuaternionMultiply";\n Opcode2[Opcode2["RotateVector"] = 48] = "RotateVector";\n Opcode2[Opcode2["Select"] = 60] = "Select";\n Opcode2[Opcode2["Clamp"] = 61] = "Clamp";\n Opcode2[Opcode2["Mix"] = 62] = "Mix";\n Opcode2[Opcode2["Vec2"] = 70] = "Vec2";\n Opcode2[Opcode2["Vec3"] = 71] = "Vec3";\n Opcode2[Opcode2["Vec4"] = 72] = "Vec4";\n Opcode2[Opcode2["Component"] = 74] = "Component";\n Opcode2[Opcode2["MaxComponentIndex"] = 75] = "MaxComponentIndex";\n return Opcode2;\n })(Opcode || {});\n var InputField = /* @__PURE__ */ ((InputField2) => {\n InputField2[InputField2["Position"] = 1] = "Position";\n InputField2[InputField2["Scale"] = 2] = "Scale";\n InputField2[InputField2["Quaternion"] = 3] = "Quaternion";\n InputField2[InputField2["Opacity"] = 4] = "Opacity";\n InputField2[InputField2["Alpha"] = 5] = "Alpha";\n InputField2[InputField2["Color"] = 6] = "Color";\n InputField2[InputField2["Sh0"] = 7] = "Sh0";\n return InputField2;\n })(InputField || {});\n const SH_COEFFICIENT_COUNT = 15;\n const TYPE_WIDTHS = {\n float: 1,\n bool: 1,\n vec2: 2,\n vec3: 3,\n vec4: 4,\n quaternion: 4\n };\n const ATTRIBUTE_FORMAT_BYTES = {\n f32: 4,\n f16: 2,\n u8: 1,\n unorm8: 1,\n i8: 1,\n snorm8: 1,\n u16: 2,\n unorm16: 2,\n i16: 2,\n snorm16: 2,\n u32: 4,\n i32: 4\n };\n const MAX_SPLAT_OPACITY = 1e3;\n const F32_EPSILON = 11920928955078125e-23;\n const ENCODED_IDENTITY_QUATERNION = 512 << 10 | 1023;\n function clamp$1(value, min, max) {\n return Math.min(max, Math.max(min, value));\n }\n function decodeSplatOpacity(word) {\n const shapeAmount = fromHalf(word >>> 16);\n if (shapeAmount > 0) {\n const kernelShape = shapeAmount * 4 + 1;\n return Math.min(\n MAX_SPLAT_OPACITY,\n Math.exp((kernelShape * kernelShape - 1) / Math.E)\n );\n }\n return fromHalf(word & 65535);\n }\n function encodeSplatOpacity(opacity) {\n if (opacity > 0 && opacity <= 1) return toHalf(opacity);\n const value = clamp$1(opacity, 0, MAX_SPLAT_OPACITY);\n if (value > 1) {\n const shapeAmount = 0.25 * (Math.sqrt(Math.log(value) * Math.E + 1) - 1);\n return (toHalf(1) | toHalf(shapeAmount) << 16) >>> 0;\n }\n return toHalf(value);\n }\n function decodeQuatOctXy1010R12ToArray(word, output, base = 0, stride = 1) {\n const u = word & 1023;\n const v = word >>> 10 & 1023;\n const angle = word >>> 20;\n let x = u / 1023 * 2 - 1;\n let y = v / 1023 * 2 - 1;\n const z = 1 - Math.abs(x) - Math.abs(y);\n const fold = Math.max(-z, 0);\n x += x >= 0 ? -fold : fold;\n y += y >= 0 ? -fold : fold;\n const inverseLength = 1 / Math.sqrt(x * x + y * y + z * z);\n const halfTheta = angle / 4095 * 0.5 * Math.PI;\n const sine = Math.sin(halfTheta);\n output[base] = x * inverseLength * sine;\n output[base + stride] = y * inverseLength * sine;\n output[base + stride * 2] = z * inverseLength * sine;\n output[base + stride * 3] = Math.cos(halfTheta);\n }\n function encodeQuaternion$1(qx, qy, qz, qw, minimumLengthSquared) {\n const lengthSquared = qx * qx + qy * qy + qz * qz + qw * qw;\n if (!Number.isFinite(lengthSquared) || lengthSquared <= minimumLengthSquared) {\n return void 0;\n }\n if (qx === 0 && qy === 0 && qz === 0) {\n return ENCODED_IDENTITY_QUATERNION;\n }\n const inverseLength = 1 / Math.sqrt(lengthSquared);\n let x = qx * inverseLength;\n let y = qy * inverseLength;\n let z = qz * inverseLength;\n let w = qw * inverseLength;\n if (w < 0) {\n x = -x;\n y = -y;\n z = -z;\n w = -w;\n }\n const theta = 2 * Math.acos(clamp$1(w, 0, 1));\n const sine = Math.sin(theta * 0.5);\n const axisX = Math.abs(sine) < 1e-6 ? 1 : x / sine;\n const axisY = Math.abs(sine) < 1e-6 ? 0 : y / sine;\n const axisZ = Math.abs(sine) < 1e-6 ? 0 : z / sine;\n const sum = Math.abs(axisX) + Math.abs(axisY) + Math.abs(axisZ);\n let octX = axisX / sum;\n let octY = axisY / sum;\n if (axisZ < 0) {\n const previousX = octX;\n octX = (1 - Math.abs(octY)) * (octX >= 0 ? 1 : -1);\n octY = (1 - Math.abs(previousX)) * (octY >= 0 ? 1 : -1);\n }\n const u = Math.round(clamp$1((octX * 0.5 + 0.5) * 1023, 0, 1023));\n const v = Math.round(clamp$1((octY * 0.5 + 0.5) * 1023, 0, 1023));\n const angle = Math.round(clamp$1(theta / Math.PI * 4095, 0, 4095));\n return (angle << 20 | v << 10 | u) >>> 0;\n }\n function tryEncodeQuatOctXy1010R12(qx, qy, qz, qw) {\n return encodeQuaternion$1(qx, qy, qz, qw, F32_EPSILON);\n }\n const MAX_BLOCK_SIZE = 512;\n const MAX_REGISTER_BYTES = 4 * 1024 * 1024;\n function getBlockSize(registerValueCount, processCount) {\n const bytesPerSplat = registerValueCount * Float32Array.BYTES_PER_ELEMENT;\n return Math.min(\n processCount,\n MAX_BLOCK_SIZE,\n Math.max(1, Math.floor(MAX_REGISTER_BYTES / bytesPerSplat))\n );\n }\n function allocateSplatPostDecodeRegisters(program) {\n const { instructions, outputs } = program;\n const instructionCount = instructions.length;\n const lastUses = new Uint32Array(instructionCount);\n for (let index = 0; index < instructionCount; index += 1) {\n lastUses[index] = index;\n for (const argument of instructions[index].args) {\n lastUses[argument] = index;\n }\n }\n const programEnd = instructionCount;\n for (const output of [\n outputs.position,\n outputs.scale,\n outputs.quaternion,\n outputs.opacity,\n outputs.alpha,\n outputs.color,\n ...outputs.sh ?? []\n ]) {\n if (output !== void 0) lastUses[output] = programEnd;\n }\n const registerOffsets = new Uint32Array(instructionCount);\n const constantRegisters = new Uint8Array(instructionCount);\n let registerValueCount = 0;\n for (let index = 0; index < instructionCount; index += 1) {\n if (instructions[index].opcode === Opcode.Constant) {\n constantRegisters[index] = 1;\n lastUses[index] = programEnd;\n registerOffsets[index] = registerValueCount;\n registerValueCount += TYPE_WIDTHS[instructions[index].type];\n }\n }\n const releases = Array.from(\n { length: instructionCount },\n () => []\n );\n const freeRanges = [];\n const release = (released) => {\n let insertIndex = 0;\n while (insertIndex < freeRanges.length && freeRanges[insertIndex].offset < released.offset) {\n insertIndex += 1;\n }\n let offset = released.offset;\n let width = released.width;\n const previous = freeRanges[insertIndex - 1];\n if (previous && previous.offset + previous.width === offset) {\n offset = previous.offset;\n width += previous.width;\n freeRanges.splice(insertIndex - 1, 1);\n insertIndex -= 1;\n }\n const next = freeRanges[insertIndex];\n if (next && offset + width === next.offset) {\n width += next.width;\n freeRanges.splice(insertIndex, 1);\n }\n freeRanges.splice(insertIndex, 0, { offset, width });\n };\n const allocate = (width) => {\n let bestIndex = -1;\n for (let index = 0; index < freeRanges.length; index += 1) {\n const range2 = freeRanges[index];\n if (range2.width >= width && (bestIndex === -1 || range2.width < freeRanges[bestIndex].width)) {\n bestIndex = index;\n }\n }\n if (bestIndex === -1) {\n const offset2 = registerValueCount;\n registerValueCount += width;\n return offset2;\n }\n const range = freeRanges[bestIndex];\n const offset = range.offset;\n if (range.width === width) {\n freeRanges.splice(bestIndex, 1);\n } else {\n range.offset += width;\n range.width -= width;\n }\n return offset;\n };\n for (let index = 0; index < instructionCount; index += 1) {\n for (const range of releases[index]) release(range);\n if (constantRegisters[index]) continue;\n const width = TYPE_WIDTHS[instructions[index].type];\n const offset = allocate(width);\n registerOffsets[index] = offset;\n const releaseIndex = lastUses[index] + 1;\n if (releaseIndex < instructionCount) {\n releases[releaseIndex].push({ offset, width });\n }\n }\n const conditionCarryOffsets = [];\n const conditionEnd = outputs.when === void 0 ? 0 : outputs.when + 1;\n for (let index = 0; index < conditionEnd; index += 1) {\n if (constantRegisters[index] || lastUses[index] < conditionEnd) continue;\n const offset = registerOffsets[index];\n const width = TYPE_WIDTHS[instructions[index].type];\n for (let lane = 0; lane < width; lane += 1) {\n conditionCarryOffsets.push(offset + lane);\n }\n }\n return {\n registerOffsets,\n registerValueCount,\n conditionCarryOffsets: new Uint32Array(conditionCarryOffsets)\n };\n }\n function rustMin(left, right) {\n if (Number.isNaN(left)) return right;\n if (Number.isNaN(right)) return left;\n return Math.min(left, right);\n }\n function rustMax(left, right) {\n if (Number.isNaN(left)) return right;\n if (Number.isNaN(right)) return left;\n return Math.max(left, right);\n }\n function roundAwayFromZero(value) {\n return value < 0 ? -Math.round(-value) : Math.round(value);\n }\n function clamp(value, min, max) {\n return Math.min(max, Math.max(min, value));\n }\n const ATTRIBUTE_READERS = {\n f32: (data, offset) => data.getFloat32(offset, true),\n f16: (data, offset) => fromHalf(data.getUint16(offset, true)),\n u8: (data, offset) => data.getUint8(offset),\n unorm8: (data, offset) => data.getUint8(offset) / 255,\n i8: (data, offset) => data.getInt8(offset),\n snorm8: (data, offset) => Math.max(-1, data.getInt8(offset) / 127),\n u16: (data, offset) => data.getUint16(offset, true),\n unorm16: (data, offset) => data.getUint16(offset, true) / 65535,\n i16: (data, offset) => data.getInt16(offset, true),\n snorm16: (data, offset) => Math.max(-1, data.getInt16(offset, true) / 32767),\n u32: (data, offset) => data.getUint32(offset, true),\n i32: (data, offset) => data.getInt32(offset, true)\n };\n function readAttributeBlock(data, attribute, blockStart, blockCount, blockSize, registers, outputBase, sourceIndices) {\n const componentBytes = ATTRIBUTE_FORMAT_BYTES[attribute.format];\n const read = ATTRIBUTE_READERS[attribute.format];\n for (let component = 0; component < attribute.components; component += 1) {\n const componentOutput = outputBase + component * blockSize;\n if (sourceIndices) {\n for (let index = 0; index < blockCount; index += 1) {\n const inputOffset = attribute.byteOffset + (blockStart + sourceIndices[index]) * attribute.byteStride + component * componentBytes;\n registers[componentOutput + index] = read(data, inputOffset);\n }\n } else {\n let inputOffset = attribute.byteOffset + blockStart * attribute.byteStride + component * componentBytes;\n for (let index = 0; index < blockCount; index += 1) {\n registers[componentOutput + index] = read(data, inputOffset);\n inputOffset += attribute.byteStride;\n }\n }\n }\n }\n function encodeQuaternion(registers, base, stride) {\n return tryEncodeQuatOctXy1010R12(\n registers[base],\n registers[base + stride],\n registers[base + stride * 2],\n registers[base + stride * 3]\n );\n }\n function decodeSh(word, output, base, stride) {\n const exponentAndSigns = word >>> 24;\n const multiplier = 2 ** ((exponentAndSigns >>> 3) - 15) / 255;\n for (let component = 0; component < 3; component += 1) {\n const magnitude = (word >>> component * 8 & 255) * multiplier;\n output[base + component * stride] = exponentAndSigns & 1 << component ? -magnitude : magnitude;\n }\n }\n function encodeSh(registers, base, stride) {\n const red = registers[base];\n const green = registers[base + stride];\n const blue = registers[base + stride * 2];\n const maxAbsolute = rustMax(\n Math.abs(red),\n rustMax(Math.abs(green), Math.abs(blue))\n );\n const exponent = roundAwayFromZero(\n clamp(Math.floor(Math.log2(maxAbsolute)) + 15, 0, 31)\n );\n const divisor = 2 ** (exponent - 15) / 255;\n const encodeComponent = (value) => roundAwayFromZero(clamp(Math.abs(value) / divisor, 0, 255));\n const signs = (red < 0 ? 1 : 0) | (green < 0 ? 2 : 0) | (blue < 0 ? 4 : 0);\n return (encodeComponent(red) | encodeComponent(green) << 8 | encodeComponent(blue) << 16 | (exponent << 3 | signs) << 24) >>> 0;\n }\n function shWord(data, coefficient) {\n if (coefficient <= 2 && data.sh1) return [data.sh1, coefficient];\n if (coefficient === 3 && data.sh1 && data.sh2) return [data.sh1, 3];\n if (coefficient <= 7 && data.sh2) return [data.sh2, coefficient - 4];\n if (coefficient <= 11 && data.sh3a) return [data.sh3a, coefficient - 8];\n if (coefficient <= 14 && data.sh3b) return [data.sh3b, coefficient - 12];\n return void 0;\n }\n function evaluateInputFieldBlock(field, blockStart, blockCount, blockSize, data, splat0Float, registers, outputBase, sourceIndices) {\n switch (field) {\n case InputField.Position:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n registers[outputBase + index] = splat0Float[wordBase];\n registers[outputBase + blockSize + index] = splat0Float[wordBase + 1];\n registers[outputBase + blockSize * 2 + index] = splat0Float[wordBase + 2];\n }\n break;\n case InputField.Scale:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n const word1 = data.splat1[wordBase + 1];\n const word2 = data.splat1[wordBase + 2];\n registers[outputBase + index] = Math.exp(fromHalf(word1 >>> 16));\n registers[outputBase + blockSize + index] = Math.exp(\n fromHalf(word2 & 65535)\n );\n registers[outputBase + blockSize * 2 + index] = Math.exp(\n fromHalf(word2 >>> 16)\n );\n }\n break;\n case InputField.Quaternion:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n decodeQuatOctXy1010R12ToArray(\n data.splat1[wordBase + 3],\n registers,\n outputBase + index,\n blockSize\n );\n }\n break;\n case InputField.Opacity:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n registers[outputBase + index] = decodeSplatOpacity(\n data.splat0[(blockStart + sourceIndex) * 4 + 3]\n );\n }\n break;\n case InputField.Alpha:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n registers[outputBase + index] = fromHalf(\n data.splat0[(blockStart + sourceIndex) * 4 + 3] & 65535\n );\n }\n break;\n case InputField.Color:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n const word0 = data.splat1[wordBase];\n const word1 = data.splat1[wordBase + 1];\n registers[outputBase + index] = fromHalf(word0 & 65535);\n registers[outputBase + blockSize + index] = fromHalf(word0 >>> 16);\n registers[outputBase + blockSize * 2 + index] = fromHalf(\n word1 & 65535\n );\n }\n break;\n default: {\n const coefficient = field - InputField.Sh0;\n const location = shWord(data, coefficient);\n if (location) {\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n decodeSh(\n location[0][(blockStart + sourceIndex) * 4 + location[1]],\n registers,\n outputBase + index,\n blockSize\n );\n }\n } else {\n registers.fill(0, outputBase, outputBase + blockCount);\n registers.fill(\n 0,\n outputBase + blockSize,\n outputBase + blockSize + blockCount\n );\n registers.fill(\n 0,\n outputBase + blockSize * 2,\n outputBase + blockSize * 2 + blockCount\n );\n }\n }\n }\n }\n function filterConditionBlock(registers, conditionBase, carryOffsets, sourceIndices, blockCount, blockSize) {\n let activeCount = 0;\n for (let index = 0; index < blockCount; index += 1) {\n if (registers[conditionBase + index] !== 0) {\n sourceIndices[activeCount++] = index;\n }\n }\n if (activeCount === 0 || activeCount === blockCount) return activeCount;\n for (const offset of carryOffsets) {\n const base = offset * blockSize;\n for (let index = 0; index < activeCount; index += 1) {\n registers[base + index] = registers[base + sourceIndices[index]];\n }\n }\n return activeCount;\n }\n function evaluateProgram(data, program, attributeData, splat0Float, registers, registerOffsets, conditionCarryOffsets, processCount, blockSize) {\n const { attributes, constants, instructions, outputs } = program;\n const whenRegister = outputs.when;\n const activeIndices = whenRegister === void 0 ? void 0 : new Uint16Array(blockSize);\n for (let instructionIndex = 0; instructionIndex < instructions.length; instructionIndex += 1) {\n const instruction = instructions[instructionIndex];\n if (instruction.opcode !== Opcode.Constant) continue;\n const outputBase = registerOffsets[instructionIndex] * blockSize;\n const width = TYPE_WIDTHS[instruction.type];\n for (let lane = 0; lane < width; lane += 1) {\n registers.fill(\n constants[instruction.immediate + lane],\n outputBase + lane * blockSize,\n outputBase + (lane + 1) * blockSize\n );\n }\n }\n for (let blockStart = 0; blockStart < processCount; blockStart += blockSize) {\n let blockCount = Math.min(blockSize, processCount - blockStart);\n let sourceIndices;\n for (let instructionIndex = 0; instructionIndex < instructions.length; instructionIndex += 1) {\n const instruction = instructions[instructionIndex];\n const { args, immediate, opcode, type } = instruction;\n if (opcode === Opcode.Constant) continue;\n const outputBase = registerOffsets[instructionIndex] * blockSize;\n const width = TYPE_WIDTHS[type];\n const arg0 = registerOffsets[args[0] ?? 0] * blockSize;\n const arg1 = registerOffsets[args[1] ?? 0] * blockSize;\n const arg2 = registerOffsets[args[2] ?? 0] * blockSize;\n const arg0Width = args[0] === void 0 ? 0 : TYPE_WIDTHS[instructions[args[0]].type];\n const arg1Width = args[1] === void 0 ? 0 : TYPE_WIDTHS[instructions[args[1]].type];\n const arg2Width = args[2] === void 0 ? 0 : TYPE_WIDTHS[instructions[args[2]].type];\n switch (opcode) {\n case Opcode.InputField:\n evaluateInputFieldBlock(\n immediate,\n blockStart,\n blockCount,\n blockSize,\n data,\n splat0Float,\n registers,\n outputBase,\n sourceIndices\n );\n break;\n case Opcode.InputAttribute:\n readAttributeBlock(\n attributeData,\n attributes[immediate],\n blockStart,\n blockCount,\n blockSize,\n registers,\n outputBase,\n sourceIndices\n );\n break;\n case Opcode.Negate:\n case Opcode.Abs:\n case Opcode.Log:\n case Opcode.Exp:\n case Opcode.Floor:\n case Opcode.Ceil:\n case Opcode.Round:\n case Opcode.Sin:\n case Opcode.Cos:\n case Opcode.Acos:\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const input = arg0 + lane * blockSize;\n for (let index = 0; index < blockCount; index += 1) {\n const value = registers[input + index];\n let result;\n switch (opcode) {\n case Opcode.Negate:\n result = -value;\n break;\n case Opcode.Abs:\n result = Math.abs(value);\n break;\n case Opcode.Log:\n result = Math.log(value);\n break;\n case Opcode.Exp:\n result = Math.exp(value);\n break;\n case Opcode.Floor:\n result = Math.floor(value);\n break;\n case Opcode.Ceil:\n result = Math.ceil(value);\n break;\n case Opcode.Round:\n result = roundAwayFromZero(value);\n break;\n case Opcode.Sin:\n result = Math.sin(value);\n break;\n case Opcode.Cos:\n result = Math.cos(value);\n break;\n default:\n result = Math.acos(value);\n }\n registers[output + index] = result;\n }\n }\n break;\n case Opcode.Sqrt:\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const input = arg0 + lane * blockSize;\n for (let index = 0; index < blockCount; index += 1) {\n registers[output + index] = Math.sqrt(registers[input + index]);\n }\n }\n break;\n case Opcode.Normalize: {\n for (let index = 0; index < blockCount; index += 1) {\n let lengthSquared = 0;\n for (let lane = 0; lane < width; lane += 1) {\n const value = registers[arg0 + lane * blockSize + index];\n lengthSquared += value * value;\n }\n const length = Math.sqrt(lengthSquared);\n for (let lane = 0; lane < width; lane += 1) {\n const input = registers[arg0 + lane * blockSize + index];\n registers[outputBase + lane * blockSize + index] = length === 0 || !Number.isFinite(length) ? input : input / length;\n }\n }\n break;\n }\n case Opcode.Length: {\n const inputWidth = arg0Width;\n for (let index = 0; index < blockCount; index += 1) {\n let lengthSquared = 0;\n for (let lane = 0; lane < inputWidth; lane += 1) {\n const value = registers[arg0 + lane * blockSize + index];\n lengthSquared += value * value;\n }\n registers[outputBase + index] = Math.sqrt(lengthSquared);\n }\n break;\n }\n case Opcode.IsFinite: {\n const inputWidth = arg0Width;\n for (let index = 0; index < blockCount; index += 1) {\n let finite = true;\n for (let lane = 0; lane < inputWidth; lane += 1) {\n finite && (finite = Number.isFinite(\n registers[arg0 + lane * blockSize + index]\n ));\n }\n registers[outputBase + index] = finite ? 1 : 0;\n }\n break;\n }\n case Opcode.Not:\n for (let index = 0; index < blockCount; index += 1) {\n registers[outputBase + index] = registers[arg0 + index] === 0 ? 1 : 0;\n }\n break;\n case Opcode.Add:\n case Opcode.Subtract:\n case Opcode.Multiply:\n case Opcode.Divide:\n case Opcode.Pow:\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const left = arg0 + lane * blockSize;\n const right = arg1 + (arg1Width === 1 ? 0 : lane * blockSize);\n for (let index = 0; index < blockCount; index += 1) {\n const leftValue = registers[left + index];\n const rightValue = registers[right + index];\n let result;\n switch (opcode) {\n case Opcode.Add:\n result = leftValue + rightValue;\n break;\n case Opcode.Subtract:\n result = leftValue - rightValue;\n break;\n case Opcode.Multiply:\n result = leftValue * rightValue;\n break;\n case Opcode.Divide:\n result = leftValue / rightValue;\n break;\n default:\n result = leftValue ** rightValue;\n }\n registers[output + index] = result;\n }\n }\n break;\n case Opcode.Min:\n case Opcode.Max:\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const left = arg0 + lane * blockSize;\n const right = arg1 + (arg1Width === 1 ? 0 : lane * blockSize);\n for (let index = 0; index < blockCount; index += 1) {\n registers[output + index] = opcode === Opcode.Min ? rustMin(registers[left + index], registers[right + index]) : rustMax(registers[left + index], registers[right + index]);\n }\n }\n break;\n case Opcode.Dot: {\n const inputWidth = arg0Width;\n for (let index = 0; index < blockCount; index += 1) {\n let dot = 0;\n for (let lane = 0; lane < inputWidth; lane += 1) {\n dot += registers[arg0 + lane * blockSize + index] * registers[arg1 + lane * blockSize + index];\n }\n registers[outputBase + index] = dot;\n }\n break;\n }\n case Opcode.Cross:\n for (let index = 0; index < blockCount; index += 1) {\n registers[outputBase + index] = registers[arg0 + blockSize + index] * registers[arg1 + blockSize * 2 + index] - registers[arg0 + blockSize * 2 + index] * registers[arg1 + blockSize + index];\n registers[outputBase + blockSize + index] = registers[arg0 + blockSize * 2 + index] * registers[arg1 + index] - registers[arg0 + index] * registers[arg1 + blockSize * 2 + index];\n registers[outputBase + blockSize * 2 + index] = registers[arg0 + index] * registers[arg1 + blockSize + index] - registers[arg0 + blockSize + index] * registers[arg1 + index];\n }\n break;\n case Opcode.Equal:\n case Opcode.NotEqual: {\n const inputWidth = arg0Width;\n for (let index = 0; index < blockCount; index += 1) {\n let equal = true;\n for (let lane = 0; lane < inputWidth; lane += 1) {\n equal && (equal = registers[arg0 + lane * blockSize + index] === registers[arg1 + lane * blockSize + index]);\n }\n registers[outputBase + index] = (opcode === Opcode.Equal ? equal : !equal) ? 1 : 0;\n }\n break;\n }\n case Opcode.Less:\n case Opcode.LessEqual:\n case Opcode.Greater:\n case Opcode.GreaterEqual:\n for (let index = 0; index < blockCount; index += 1) {\n const left = registers[arg0 + index];\n const right = registers[arg1 + index];\n registers[outputBase + index] = (opcode === Opcode.Less ? left < right : opcode === Opcode.LessEqual ? left <= right : opcode === Opcode.Greater ? left > right : left >= right) ? 1 : 0;\n }\n break;\n case Opcode.And:\n case Opcode.Or:\n for (let index = 0; index < blockCount; index += 1) {\n registers[outputBase + index] = (opcode === Opcode.And ? registers[arg0 + index] !== 0 && registers[arg1 + index] !== 0 : registers[arg0 + index] !== 0 || registers[arg1 + index] !== 0) ? 1 : 0;\n }\n break;\n case Opcode.QuaternionMultiply:\n for (let index = 0; index < blockCount; index += 1) {\n const leftX = registers[arg0 + index];\n const leftY = registers[arg0 + blockSize + index];\n const leftZ = registers[arg0 + blockSize * 2 + index];\n const leftW = registers[arg0 + blockSize * 3 + index];\n const rightX = registers[arg1 + index];\n const rightY = registers[arg1 + blockSize + index];\n const rightZ = registers[arg1 + blockSize * 2 + index];\n const rightW = registers[arg1 + blockSize * 3 + index];\n registers[outputBase + index] = leftW * rightX + leftX * rightW + leftY * rightZ - leftZ * rightY;\n registers[outputBase + blockSize + index] = leftW * rightY - leftX * rightZ + leftY * rightW + leftZ * rightX;\n registers[outputBase + blockSize * 2 + index] = leftW * rightZ + leftX * rightY - leftY * rightX + leftZ * rightW;\n registers[outputBase + blockSize * 3 + index] = leftW * rightW - leftX * rightX - leftY * rightY - leftZ * rightZ;\n }\n break;\n case Opcode.RotateVector:\n for (let index = 0; index < blockCount; index += 1) {\n const quaternionX = registers[arg0 + index];\n const quaternionY = registers[arg0 + blockSize + index];\n const quaternionZ = registers[arg0 + blockSize * 2 + index];\n const quaternionW = registers[arg0 + blockSize * 3 + index];\n const vectorX = registers[arg1 + index];\n const vectorY = registers[arg1 + blockSize + index];\n const vectorZ = registers[arg1 + blockSize * 2 + index];\n const crossX = 2 * (quaternionY * vectorZ - quaternionZ * vectorY);\n const crossY = 2 * (quaternionZ * vectorX - quaternionX * vectorZ);\n const crossZ = 2 * (quaternionX * vectorY - quaternionY * vectorX);\n registers[outputBase + index] = vectorX + quaternionW * crossX + quaternionY * crossZ - quaternionZ * crossY;\n registers[outputBase + blockSize + index] = vectorY + quaternionW * crossY + quaternionZ * crossX - quaternionX * crossZ;\n registers[outputBase + blockSize * 2 + index] = vectorZ + quaternionW * crossZ + quaternionX * crossY - quaternionY * crossX;\n }\n break;\n case Opcode.Select: {\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const whenTrue = arg1 + lane * blockSize;\n const whenFalse = arg2 + lane * blockSize;\n for (let index = 0; index < blockCount; index += 1) {\n registers[output + index] = registers[arg0 + index] !== 0 ? registers[whenTrue + index] : registers[whenFalse + index];\n }\n }\n break;\n }\n case Opcode.Clamp: {\n const secondWidth = arg1Width;\n const thirdWidth = arg2Width;\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const value = arg0 + lane * blockSize;\n const min = arg1 + (secondWidth === 1 ? 0 : lane * blockSize);\n const max = arg2 + (thirdWidth === 1 ? 0 : lane * blockSize);\n for (let index = 0; index < blockCount; index += 1) {\n registers[output + index] = rustMin(\n rustMax(registers[value + index], registers[min + index]),\n registers[max + index]\n );\n }\n }\n break;\n }\n case Opcode.Mix: {\n const secondWidth = arg1Width;\n const thirdWidth = arg2Width;\n for (let lane = 0; lane < width; lane += 1) {\n const output = outputBase + lane * blockSize;\n const left = arg0 + lane * blockSize;\n const right = arg1 + (secondWidth === 1 ? 0 : lane * blockSize);\n const amount = arg2 + (thirdWidth === 1 ? 0 : lane * blockSize);\n for (let index = 0; index < blockCount; index += 1) {\n const leftValue = registers[left + index];\n registers[output + index] = leftValue + (registers[right + index] - leftValue) * registers[amount + index];\n }\n }\n break;\n }\n case Opcode.Vec2:\n case Opcode.Vec3:\n case Opcode.Vec4:\n for (let index = 0; index < blockCount; index += 1) {\n registers[outputBase + index] = registers[arg0 + index];\n registers[outputBase + blockSize + index] = registers[arg1 + index];\n if (width >= 3) {\n registers[outputBase + blockSize * 2 + index] = registers[arg2 + index];\n }\n if (width === 4) {\n registers[outputBase + blockSize * 3 + index] = registers[registerOffsets[args[3] ?? 0] * blockSize + index];\n }\n }\n break;\n case Opcode.Component:\n for (let index = 0; index < blockCount; index += 1) {\n registers[outputBase + index] = registers[arg0 + immediate * blockSize + index];\n }\n break;\n case Opcode.MaxComponentIndex: {\n const inputWidth = arg0Width;\n for (let index = 0; index < blockCount; index += 1) {\n let largest = 0;\n let largestValue = registers[arg0 + index];\n for (let lane = 1; lane < inputWidth; lane += 1) {\n const value = registers[arg0 + lane * blockSize + index];\n if (value > largestValue) {\n largest = lane;\n largestValue = value;\n }\n }\n registers[outputBase + index] = largest;\n }\n }\n }\n if (instructionIndex === whenRegister && activeIndices) {\n const conditionBase = registerOffsets[whenRegister] * blockSize;\n const activeCount = filterConditionBlock(\n registers,\n conditionBase,\n conditionCarryOffsets,\n activeIndices,\n blockCount,\n blockSize\n );\n if (activeCount !== blockCount) {\n if (activeCount !== 0) sourceIndices = activeIndices;\n blockCount = activeCount;\n if (blockCount === 0) break;\n }\n }\n }\n for (let index = 0; index < blockCount; index += 1) {\n writeOutputs(\n data,\n splat0Float,\n program,\n registers,\n registerOffsets,\n blockSize,\n index,\n blockStart + ((sourceIndices == null ? void 0 : sourceIndices[index]) ?? index)\n );\n }\n }\n }\n function writeOutputs(data, splat0Float, program, registers, registerOffsets, blockSize, blockIndex, splatIndex) {\n const { outputs } = program;\n const wordBase = splatIndex * 4;\n if (outputs.position !== void 0) {\n const base = registerOffsets[outputs.position] * blockSize + blockIndex;\n splat0Float[wordBase] = registers[base];\n splat0Float[wordBase + 1] = registers[base + blockSize];\n splat0Float[wordBase + 2] = registers[base + blockSize * 2];\n }\n if (outputs.scale !== void 0) {\n const base = registerOffsets[outputs.scale] * blockSize + blockIndex;\n const first = data.splat1[wordBase + 1] & 65535;\n data.splat1[wordBase + 1] = (first | toHalf(Math.log(registers[base])) << 16) >>> 0;\n data.splat1[wordBase + 2] = (toHalf(Math.log(registers[base + blockSize])) | toHalf(Math.log(registers[base + blockSize * 2])) << 16) >>> 0;\n }\n if (outputs.quaternion !== void 0) {\n const base = registerOffsets[outputs.quaternion] * blockSize + blockIndex;\n const encoded = encodeQuaternion(registers, base, blockSize);\n if (encoded !== void 0) data.splat1[wordBase + 3] = encoded;\n }\n if (outputs.opacity !== void 0) {\n const base = registerOffsets[outputs.opacity] * blockSize + blockIndex;\n data.splat0[wordBase + 3] = encodeSplatOpacity(registers[base]);\n }\n if (outputs.alpha !== void 0) {\n const base = registerOffsets[outputs.alpha] * blockSize + blockIndex;\n data.splat0[wordBase + 3] = (data.splat0[wordBase + 3] & 4294901760 | toHalf(clamp(registers[base], 0, 1))) >>> 0;\n }\n if (outputs.color !== void 0) {\n const base = registerOffsets[outputs.color] * blockSize + blockIndex;\n data.splat1[wordBase] = (toHalf(registers[base]) | toHalf(registers[base + blockSize]) << 16) >>> 0;\n data.splat1[wordBase + 1] = (data.splat1[wordBase + 1] & 4294901760 | toHalf(registers[base + blockSize * 2])) >>> 0;\n }\n if (outputs.sh) {\n for (let coefficient = 0; coefficient < SH_COEFFICIENT_COUNT; coefficient += 1) {\n const location = shWord(data, coefficient);\n if (location) {\n const base = registerOffsets[outputs.sh[coefficient]] * blockSize + blockIndex;\n location[0][wordBase + location[1]] = encodeSh(\n registers,\n base,\n blockSize\n );\n }\n }\n }\n if (outputs.position !== void 0 || outputs.scale !== void 0) {\n const disabled = data.splat1[wordBase + 1] >>> 16 === 64512 && (data.splat1[wordBase + 2] & 65535) === 64512 && data.splat1[wordBase + 2] >>> 16 === 64512;\n const centerBase = splatIndex * 3;\n if (disabled) {\n data.sortCenters[centerBase] = Number.NaN;\n data.sortCenters[centerBase + 1] = Number.NaN;\n data.sortCenters[centerBase + 2] = Number.NaN;\n } else {\n data.sortCenters[centerBase] = splat0Float[wordBase];\n data.sortCenters[centerBase + 1] = splat0Float[wordBase + 1];\n data.sortCenters[centerBase + 2] = splat0Float[wordBase + 2];\n }\n }\n }\n function applySplatPostDecode(data, program) {\n let processCount = data.numSplats;\n for (const attribute of program.attributes) {\n processCount = Math.min(processCount, attribute.count);\n }\n if (processCount === 0 || program.instructions.length === 0) return;\n const { registerOffsets, registerValueCount, conditionCarryOffsets } = allocateSplatPostDecodeRegisters(program);\n const blockSize = getBlockSize(registerValueCount, processCount);\n const registers = new Float32Array(registerValueCount * blockSize);\n const attributeData = new DataView(\n program.attributeData.buffer,\n program.attributeData.byteOffset,\n program.attributeData.byteLength\n );\n const splat0Float = new Float32Array(\n data.splat0.buffer,\n data.splat0.byteOffset,\n data.splat0.length\n );\n evaluateProgram(\n data,\n program,\n attributeData,\n splat0Float,\n registers,\n registerOffsets,\n conditionCarryOffsets,\n processCount,\n blockSize\n );\n }\n function getTransferable(ctx) {\n const buffers = /* @__PURE__ */ new Set();\n const seen = /* @__PURE__ */ new Set();\n function traverse(obj) {\n if (!obj || typeof obj !== "object" || seen.has(obj)) return;\n seen.add(obj);\n if (obj instanceof ArrayBuffer) {\n buffers.add(obj);\n } else if (ArrayBuffer.isView(obj)) {\n buffers.add(obj.buffer);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n traverse(ctx);\n return [...buffers];\n }\n const rpcHandlers = {\n setSortCenterState,\n sortCenters32,\n loadSplats,\n nextChunk\n };\n let wasmMemory;\n function getWasmMemoryBytes() {\n return (wasmMemory == null ? void 0 : wasmMemory.buffer.byteLength) ?? 0;\n }\n function setSortCenterState({\n centerUpdateRangeIndices,\n updateCenters,\n matrixUpdateRangeIndices,\n updateMatrices,\n rangeMeshIds,\n rangeBases,\n rangeCounts\n }) {\n set_sort_center_state(\n centerUpdateRangeIndices,\n updateCenters,\n matrixUpdateRangeIndices,\n updateMatrices,\n rangeMeshIds,\n rangeBases,\n rangeCounts\n );\n }\n function sortCenters32({\n numSplats,\n cameraPosition,\n direction,\n radial,\n ordering\n }) {\n const activeSplats = sort32_centers(\n numSplats,\n cameraPosition[0],\n cameraPosition[1],\n cameraPosition[2],\n direction[0],\n direction[1],\n direction[2],\n radial,\n ordering\n );\n return { activeSplats, ordering };\n }\n async function onMessage(event) {\n const {\n id,\n name,\n args\n } = event.data;\n try {\n const handler = rpcHandlers[name];\n if (!handler) {\n throw new Error(`Unknown worker RPC: ${name}`);\n }\n const sendStatus = (data) => {\n self.postMessage(\n { id, status: data },\n { transfer: getTransferable(data) }\n );\n };\n const result = await handler(args, { sendStatus });\n self.postMessage(\n { id, result, wasmMemoryBytes: getWasmMemoryBytes() },\n { transfer: getTransferable(result) }\n );\n } catch (error) {\n console.warn(`Worker error: ${error}`);\n self.postMessage(\n { id, error, wasmMemoryBytes: getWasmMemoryBytes() },\n { transfer: getTransferable(error) }\n );\n }\n }\n async function decodeBytesUrl({\n decoder,\n fileBytes,\n url,\n requestHeader,\n withCredentials,\n chunked,\n chunkedLength,\n sendStatus\n }) {\n if (fileBytes) {\n const byteLength = fileBytes.length;\n if (byteLength > 0) {\n decoder.set_expected_input_size(byteLength);\n }\n sendStatus({ loaded: byteLength, total: byteLength });\n decoder.push(fileBytes);\n return decoder.finish();\n }\n const suppliedInputLength = chunkedLength ?? 0;\n if (!Number.isSafeInteger(suppliedInputLength) || suppliedInputLength < 0) {\n throw new Error("streamLength must be a non-negative integer");\n }\n let streamLength = suppliedInputLength;\n let expectedInputLength = 0;\n let responseBody;\n if (url) {\n const request = new Request(url, {\n headers: requestHeader ? new Headers(requestHeader) : void 0,\n credentials: withCredentials ? "include" : "same-origin"\n });\n const response = await fetch(request);\n if (!response.ok || !response.body) {\n throw new Error(\n `Failed to fetch "${url}": ${response.status} ${response.statusText}`\n );\n }\n responseBody = response.body;\n const contentLength = Number(response.headers.get("Content-Length") || "0");\n const responseLength = Number.isSafeInteger(contentLength) && contentLength > 0 ? contentLength : 0;\n streamLength || (streamLength = responseLength);\n const contentEncoding = response.headers.get("Content-Encoding");\n const hasIdentityEncoding = !contentEncoding || contentEncoding.toLowerCase() === "identity";\n if (response.type === "basic" && hasIdentityEncoding) {\n expectedInputLength = responseLength;\n }\n } else if (!chunked) {\n throw new Error("No url or fileBytes provided");\n }\n const streamReader = responseBody == null ? void 0 : responseBody.getReader();\n const readInputChunk = async () => {\n if (streamReader) {\n const { done, value } = await streamReader.read();\n return done ? void 0 : value;\n }\n const chunk = await new Promise((resolve) => {\n nextChunkWaiter = resolve;\n sendStatus({ nextChunk: true });\n });\n return chunk.length === 0 ? void 0 : chunk;\n };\n let loaded = 0;\n try {\n if (expectedInputLength > 0) {\n decoder.set_expected_input_size(expectedInputLength);\n }\n while (true) {\n const value = await readInputChunk();\n if (!value) break;\n loaded += value.length;\n if (expectedInputLength > 0 && loaded > expectedInputLength) {\n throw new Error(\n `Input length exceeds the expected ${expectedInputLength} bytes`\n );\n }\n sendStatus({ loaded, total: streamLength });\n decoder.push(value);\n }\n if (expectedInputLength > 0 && loaded !== expectedInputLength) {\n throw new Error(\n `Input length mismatch: expected ${expectedInputLength} bytes, received ${loaded}`\n );\n }\n if (chunked && streamLength === 0) {\n sendStatus({ loaded, total: loaded });\n }\n return decoder.finish();\n } catch (error) {\n try {\n await (streamReader == null ? void 0 : streamReader.cancel(error));\n } catch {\n }\n throw error;\n } finally {\n streamReader == null ? void 0 : streamReader.releaseLock();\n }\n }\n function toSplatResult(decoded) {\n return {\n numSplats: decoded.numSplats,\n splatArrays: [decoded.splat0, decoded.splat1],\n sortCenters: decoded.sortCenters,\n extra: {\n sh1: decoded.sh1,\n sh2: decoded.sh2,\n sh3a: decoded.sh3a,\n sh3b: decoded.sh3b\n }\n };\n }\n async function loadSplats({\n url,\n requestHeader,\n withCredentials,\n fileBytes,\n fileType,\n pathName,\n chunked,\n chunkedLength,\n postDecode\n }, { sendStatus }) {\n const decoder = decode_to_splats(fileType, pathName ?? url);\n const decoded = await decodeBytesUrl({\n decoder,\n fileBytes,\n url,\n requestHeader,\n withCredentials,\n chunked,\n chunkedLength,\n sendStatus\n });\n if (postDecode) applySplatPostDecode(decoded, postDecode);\n return toSplatResult(decoded);\n }\n let nextChunkWaiter = (_chunk) => {\n };\n async function nextChunk({ chunk }) {\n nextChunkWaiter(chunk);\n }\n async function initialize() {\n let resolveWaitForModule;\n const waitForModule = new Promise((resolve) => {\n resolveWaitForModule = resolve;\n });\n const pending = [];\n const bufferMessage = (event) => {\n if (event.data.name === "init-wasm") {\n resolveWaitForModule(event.data.module);\n return;\n }\n pending.push(event);\n };\n self.addEventListener("message", bufferMessage);\n const wasm2 = await __wbg_init({ module_or_path: await waitForModule });\n wasmMemory = wasm2.memory;\n self.removeEventListener("message", bufferMessage);\n self.addEventListener("message", onMessage);\n for (const event of pending) {\n onMessage(event);\n }\n pending.length = 0;\n }\n initialize().catch(console.error);\n})();\n//# sourceMappingURL=worker-BjNOf79T.js.map\n';
|
|
2449
|
+
const jsContent = '(function() {\n "use strict";\n class ChunkDecoder {\n static __wrap(ptr) {\n ptr = ptr >>> 0;\n const obj = Object.create(ChunkDecoder.prototype);\n obj.__wbg_ptr = ptr;\n ChunkDecoderFinalization.register(obj, obj.__wbg_ptr, obj);\n return obj;\n }\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ChunkDecoderFinalization.unregister(this);\n return ptr;\n }\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_chunkdecoder_free(ptr, 0);\n }\n /**\n * @returns {any}\n */\n finish() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.chunkdecoder_finish(ptr);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return takeFromExternrefTable0(ret[0]);\n }\n /**\n * @param {Uint8Array} bytes\n */\n push(bytes) {\n const ret = wasm.chunkdecoder_push(this.__wbg_ptr, bytes);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n /**\n * @param {number} size\n */\n set_expected_input_size(size) {\n const ret = wasm.chunkdecoder_set_expected_input_size(this.__wbg_ptr, size);\n if (ret[1]) {\n throw takeFromExternrefTable0(ret[0]);\n }\n }\n }\n if (Symbol.dispose) ChunkDecoder.prototype[Symbol.dispose] = ChunkDecoder.prototype.free;\n function decode_to_splats(file_type, path_name) {\n var ptr0 = isLikeNone(file_type) ? 0 : passStringToWasm0(file_type, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len0 = WASM_VECTOR_LEN;\n var ptr1 = isLikeNone(path_name) ? 0 : passStringToWasm0(path_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n var len1 = WASM_VECTOR_LEN;\n const ret = wasm.decode_to_splats(ptr0, len0, ptr1, len1);\n if (ret[2]) {\n throw takeFromExternrefTable0(ret[1]);\n }\n return ChunkDecoder.__wrap(ret[0]);\n }\n function set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts) {\n wasm.set_sort_center_state(center_update_range_indices, update_centers, matrix_update_range_indices, update_matrices, range_mesh_ids, range_bases, range_counts);\n }\n function sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, ordering) {\n const ret = wasm.sort32_centers(num_splats, camera_x, camera_y, camera_z, direction_x, direction_y, direction_z, radial, ordering);\n return ret >>> 0;\n }\n function __wbg_get_imports() {\n const import0 = {\n __proto__: null,\n __wbg___wbindgen_debug_string_dd5d2d07ce9e6c57: function(arg0, arg1) {\n const ret = debugString(arg1);\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg___wbindgen_throw_81fc77679af83bc6: function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n },\n __wbg_error_a6fa202b58aa1cd3: function(arg0, arg1) {\n let deferred0_0;\n let deferred0_1;\n try {\n deferred0_0 = arg0;\n deferred0_1 = arg1;\n console.error(getStringFromWasm0(arg0, arg1));\n } finally {\n wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);\n }\n },\n __wbg_get_index_983d655608220248: function(arg0, arg1) {\n const ret = arg0[arg1 >>> 0];\n return ret;\n },\n __wbg_length_0c32cb8543c8e4c8: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_1e701798fdcaa3b4: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_526c0f6e4ebae15d: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_length_fd4646b401926788: function(arg0) {\n const ret = arg0.length;\n return ret;\n },\n __wbg_new_227d7c05414eb861: function() {\n const ret = new Error();\n return ret;\n },\n __wbg_new_4f9fafbb3909af72: function() {\n const ret = new Object();\n return ret;\n },\n __wbg_new_with_length_26bffbe236bf73f9: function(arg0) {\n const ret = new Float32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_new_with_length_41a22191b9bdfd66: function(arg0) {\n const ret = new Uint32Array(arg0 >>> 0);\n return ret;\n },\n __wbg_prototypesetcall_021fd89d67217368: function(arg0, arg1, arg2) {\n Float64Array.prototype.set.call(getArrayF64FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_3e05eb9545565046: function(arg0, arg1, arg2) {\n Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_66c8e1fb820946be: function(arg0, arg1, arg2) {\n Float32Array.prototype.set.call(getArrayF32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_prototypesetcall_e42275e601e14eeb: function(arg0, arg1, arg2) {\n Uint32Array.prototype.set.call(getArrayU32FromWasm0(arg0, arg1), arg2);\n },\n __wbg_set_448126769bf7c181: function(arg0, arg1, arg2) {\n arg0.set(getArrayU32FromWasm0(arg1, arg2));\n },\n __wbg_set_8ee2d34facb8466e: function() {\n return handleError(function(arg0, arg1, arg2) {\n const ret = Reflect.set(arg0, arg1, arg2);\n return ret;\n }, arguments);\n },\n __wbg_set_a98c8da6557e63de: function(arg0, arg1, arg2) {\n arg0.set(getArrayF32FromWasm0(arg1, arg2));\n },\n __wbg_set_index_a561936dd7004b5a: function(arg0, arg1, arg2) {\n arg0[arg1 >>> 0] = arg2;\n },\n __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {\n const ret = arg1.stack;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n },\n __wbg_subarray_0f98d3fb634508ad: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_1230568a23d546e8: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_4342405c1ffc86d6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbg_subarray_d51e89458b3fdbf6: function(arg0, arg1, arg2) {\n const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);\n return ret;\n },\n __wbindgen_cast_0000000000000001: function(arg0) {\n const ret = arg0;\n return ret;\n },\n __wbindgen_cast_0000000000000002: function(arg0, arg1) {\n const ret = getArrayF32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000003: function(arg0, arg1) {\n const ret = getArrayU32FromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_cast_0000000000000004: function(arg0, arg1) {\n const ret = getStringFromWasm0(arg0, arg1);\n return ret;\n },\n __wbindgen_init_externref_table: function() {\n const table = wasm.__wbindgen_externrefs;\n const offset = table.grow(4);\n table.set(0, void 0);\n table.set(offset + 0, void 0);\n table.set(offset + 1, null);\n table.set(offset + 2, true);\n table.set(offset + 3, false);\n }\n };\n return {\n __proto__: null,\n "./gaussian_splat_rs_bg.js": import0\n };\n }\n const ChunkDecoderFinalization = typeof FinalizationRegistry === "undefined" ? { register: () => {\n }, unregister: () => {\n } } : new FinalizationRegistry((ptr) => wasm.__wbg_chunkdecoder_free(ptr >>> 0, 1));\n function addToExternrefTable0(obj) {\n const idx = wasm.__externref_table_alloc();\n wasm.__wbindgen_externrefs.set(idx, obj);\n return idx;\n }\n function debugString(val) {\n const type = typeof val;\n if (type == "number" || type == "boolean" || val == null) {\n return `${val}`;\n }\n if (type == "string") {\n return `"${val}"`;\n }\n if (type == "symbol") {\n const description = val.description;\n if (description == null) {\n return "Symbol";\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == "function") {\n const name = val.name;\n if (typeof name == "string" && name.length > 0) {\n return `Function(${name})`;\n } else {\n return "Function";\n }\n }\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = "[";\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for (let i = 1; i < length; i++) {\n debug += ", " + debugString(val[i]);\n }\n debug += "]";\n return debug;\n }\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n return toString.call(val);\n }\n if (className == "Object") {\n try {\n return "Object(" + JSON.stringify(val) + ")";\n } catch (_) {\n return "Object";\n }\n }\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\n${val.stack}`;\n }\n return className;\n }\n function getArrayF32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n }\n function getArrayF64FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getFloat64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);\n }\n function getArrayU32FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);\n }\n function getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n }\n let cachedDataViewMemory0 = null;\n function getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === void 0 && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n }\n let cachedFloat32ArrayMemory0 = null;\n function getFloat32ArrayMemory0() {\n if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {\n cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);\n }\n return cachedFloat32ArrayMemory0;\n }\n let cachedFloat64ArrayMemory0 = null;\n function getFloat64ArrayMemory0() {\n if (cachedFloat64ArrayMemory0 === null || cachedFloat64ArrayMemory0.byteLength === 0) {\n cachedFloat64ArrayMemory0 = new Float64Array(wasm.memory.buffer);\n }\n return cachedFloat64ArrayMemory0;\n }\n function getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return decodeText(ptr, len);\n }\n let cachedUint32ArrayMemory0 = null;\n function getUint32ArrayMemory0() {\n if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {\n cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);\n }\n return cachedUint32ArrayMemory0;\n }\n let cachedUint8ArrayMemory0 = null;\n function getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n }\n function handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n const idx = addToExternrefTable0(e);\n wasm.__wbindgen_exn_store(idx);\n }\n }\n function isLikeNone(x) {\n return x === void 0 || x === null;\n }\n function passStringToWasm0(arg, malloc, realloc) {\n if (realloc === void 0) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr2 = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr2, ptr2 + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr2;\n }\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n const mem = getUint8ArrayMemory0();\n let offset = 0;\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 127) break;\n mem[ptr + offset] = code;\n }\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n WASM_VECTOR_LEN = offset;\n return ptr;\n }\n function takeFromExternrefTable0(idx) {\n const value = wasm.__wbindgen_externrefs.get(idx);\n wasm.__externref_table_dealloc(idx);\n return value;\n }\n let cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n const MAX_SAFARI_DECODE_BYTES = 2146435072;\n let numBytesDecoded = 0;\n function decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n }\n const cachedTextEncoder = new TextEncoder();\n if (!("encodeInto" in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function(arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n };\n }\n let WASM_VECTOR_LEN = 0;\n let wasm;\n function __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n cachedDataViewMemory0 = null;\n cachedFloat32ArrayMemory0 = null;\n cachedFloat64ArrayMemory0 = null;\n cachedUint32ArrayMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n wasm.__wbindgen_start();\n return wasm;\n }\n async function __wbg_load(module, imports) {\n if (typeof Response === "function" && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === "function") {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n const validResponse = module.ok && expectedResponseType(module.type);\n if (validResponse && module.headers.get("Content-Type") !== "application/wasm") {\n console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);\n } else {\n throw e;\n }\n }\n }\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n function expectedResponseType(type) {\n switch (type) {\n case "basic":\n case "cors":\n case "default":\n return true;\n }\n return false;\n }\n }\n async function __wbg_init(module_or_path) {\n if (wasm !== void 0) return wasm;\n if (module_or_path !== void 0) {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({ module_or_path } = module_or_path);\n } else {\n console.warn("using deprecated parameters for the initialization function; pass a single object instead");\n }\n }\n const imports = __wbg_get_imports();\n if (typeof module_or_path === "string" || typeof Request === "function" && module_or_path instanceof Request || typeof URL === "function" && module_or_path instanceof URL) {\n module_or_path = fetch(module_or_path);\n }\n const { instance } = await __wbg_load(await module_or_path, imports);\n return __wbg_finalize_init(instance);\n }\n const f32 = new Float32Array(1);\n const u32 = new Uint32Array(f32.buffer);\n const supportsFloat16Array = "Float16Array" in globalThis;\n const f16 = supportsFloat16Array ? new globalThis["Float16Array"](1) : null;\n const u16 = new Uint16Array(f16 == null ? void 0 : f16.buffer);\n function toHalfNative(value) {\n f16[0] = value;\n return u16[0];\n }\n function toHalfJs(value) {\n f32[0] = value;\n const bits = u32[0];\n const sign = bits >>> 16 & 32768;\n const exponent = bits >>> 23 & 255;\n const fraction = bits & 8388607;\n if (exponent === 255) {\n return sign | (fraction === 0 ? 31744 : 32767);\n }\n const halfExponent = exponent - 127 + 15;\n if (halfExponent >= 31) return sign | 31744;\n if (halfExponent <= 0) {\n if (halfExponent < -10) return sign;\n return sign | (fraction | 8388608) >>> 1 - halfExponent + 13;\n }\n return sign | halfExponent << 10 | fraction >>> 13;\n }\n function fromHalfNative(value) {\n u16[0] = value;\n return f16[0];\n }\n function fromHalfJs(value) {\n const sign = value >>> 15 & 1;\n const exponent = value >>> 10 & 31;\n const fraction = value & 1023;\n let bits;\n if (exponent === 0) {\n if (fraction === 0) {\n bits = sign << 31;\n } else {\n let mantissa = fraction;\n let adjustedExponent = -14;\n while ((mantissa & 1024) === 0) {\n mantissa <<= 1;\n adjustedExponent -= 1;\n }\n bits = sign << 31 | adjustedExponent + 127 << 23 | (mantissa & 1023) << 13;\n }\n } else if (exponent === 31) {\n bits = sign << 31 | (fraction === 0 ? 2139095040 : 2143289344);\n } else {\n bits = sign << 31 | exponent - 15 + 127 << 23 | fraction << 13;\n }\n u32[0] = bits;\n return f32[0];\n }\n const toHalf = supportsFloat16Array ? toHalfNative : toHalfJs;\n const fromHalf = supportsFloat16Array ? fromHalfNative : fromHalfJs;\n var Opcode = /* @__PURE__ */ ((Opcode2) => {\n Opcode2[Opcode2["Constant"] = 1] = "Constant";\n Opcode2[Opcode2["InputField"] = 2] = "InputField";\n Opcode2[Opcode2["InputAttribute"] = 3] = "InputAttribute";\n Opcode2[Opcode2["Negate"] = 10] = "Negate";\n Opcode2[Opcode2["Abs"] = 11] = "Abs";\n Opcode2[Opcode2["Sqrt"] = 12] = "Sqrt";\n Opcode2[Opcode2["Log"] = 13] = "Log";\n Opcode2[Opcode2["Exp"] = 14] = "Exp";\n Opcode2[Opcode2["Floor"] = 15] = "Floor";\n Opcode2[Opcode2["Ceil"] = 16] = "Ceil";\n Opcode2[Opcode2["Round"] = 17] = "Round";\n Opcode2[Opcode2["Normalize"] = 18] = "Normalize";\n Opcode2[Opcode2["Length"] = 19] = "Length";\n Opcode2[Opcode2["IsFinite"] = 20] = "IsFinite";\n Opcode2[Opcode2["Not"] = 22] = "Not";\n Opcode2[Opcode2["Sin"] = 23] = "Sin";\n Opcode2[Opcode2["Cos"] = 24] = "Cos";\n Opcode2[Opcode2["Acos"] = 25] = "Acos";\n Opcode2[Opcode2["Tan"] = 26] = "Tan";\n Opcode2[Opcode2["Asin"] = 27] = "Asin";\n Opcode2[Opcode2["Atan"] = 28] = "Atan";\n Opcode2[Opcode2["Add"] = 30] = "Add";\n Opcode2[Opcode2["Subtract"] = 31] = "Subtract";\n Opcode2[Opcode2["Multiply"] = 32] = "Multiply";\n Opcode2[Opcode2["Divide"] = 33] = "Divide";\n Opcode2[Opcode2["Min"] = 34] = "Min";\n Opcode2[Opcode2["Max"] = 35] = "Max";\n Opcode2[Opcode2["Pow"] = 36] = "Pow";\n Opcode2[Opcode2["Dot"] = 37] = "Dot";\n Opcode2[Opcode2["Cross"] = 38] = "Cross";\n Opcode2[Opcode2["Equal"] = 39] = "Equal";\n Opcode2[Opcode2["NotEqual"] = 40] = "NotEqual";\n Opcode2[Opcode2["Less"] = 41] = "Less";\n Opcode2[Opcode2["LessEqual"] = 42] = "LessEqual";\n Opcode2[Opcode2["Greater"] = 43] = "Greater";\n Opcode2[Opcode2["GreaterEqual"] = 44] = "GreaterEqual";\n Opcode2[Opcode2["And"] = 45] = "And";\n Opcode2[Opcode2["Or"] = 46] = "Or";\n Opcode2[Opcode2["QuaternionMultiply"] = 47] = "QuaternionMultiply";\n Opcode2[Opcode2["RotateVector"] = 48] = "RotateVector";\n Opcode2[Opcode2["Atan2"] = 49] = "Atan2";\n Opcode2[Opcode2["Select"] = 60] = "Select";\n Opcode2[Opcode2["Clamp"] = 61] = "Clamp";\n Opcode2[Opcode2["Mix"] = 62] = "Mix";\n Opcode2[Opcode2["Vec2"] = 70] = "Vec2";\n Opcode2[Opcode2["Vec3"] = 71] = "Vec3";\n Opcode2[Opcode2["Vec4"] = 72] = "Vec4";\n Opcode2[Opcode2["Component"] = 74] = "Component";\n Opcode2[Opcode2["MaxComponentIndex"] = 75] = "MaxComponentIndex";\n return Opcode2;\n })(Opcode || {});\n var InputField = /* @__PURE__ */ ((InputField2) => {\n InputField2[InputField2["Position"] = 1] = "Position";\n InputField2[InputField2["Scale"] = 2] = "Scale";\n InputField2[InputField2["Quaternion"] = 3] = "Quaternion";\n InputField2[InputField2["Opacity"] = 4] = "Opacity";\n InputField2[InputField2["Alpha"] = 5] = "Alpha";\n InputField2[InputField2["Color"] = 6] = "Color";\n InputField2[InputField2["Sh0"] = 7] = "Sh0";\n return InputField2;\n })(InputField || {});\n const SH_COEFFICIENT_COUNT = 15;\n const SPLAT_POST_DECODE_INSTRUCTION_OPCODE = 0;\n const SPLAT_POST_DECODE_INSTRUCTION_WIDTH = 1;\n const SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE = 2;\n const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 = 3;\n const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT = 4;\n const SPLAT_POST_DECODE_INSTRUCTION_STRIDE = 7;\n const SPLAT_POST_DECODE_MISSING_ARGUMENT = 65535;\n const ATTRIBUTE_FORMAT_BYTES = {\n f32: 4,\n f16: 2,\n u8: 1,\n unorm8: 1,\n i8: 1,\n snorm8: 1,\n u16: 2,\n unorm16: 2,\n i16: 2,\n snorm16: 2,\n u32: 4,\n i32: 4\n };\n const SPLAT_POST_DECODE_FLOW_STAGE_START = 0;\n const SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION = 1;\n const SPLAT_POST_DECODE_FLOW_STAGE_REGISTER = 2;\n const SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE = 3;\n const SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE = 4;\n const SPLAT_POST_DECODE_FLOW_STAGE_STRIDE = 5;\n const MAX_SPLAT_OPACITY = 1e3;\n const F32_EPSILON = 11920928955078125e-23;\n const ENCODED_IDENTITY_QUATERNION = 512 << 10 | 1023;\n function clamp$1(value, min, max) {\n return Math.min(max, Math.max(min, value));\n }\n function decodeSplatOpacity(word) {\n const shapeAmount = fromHalf(word >>> 16);\n if (shapeAmount > 0) {\n const kernelShape = shapeAmount * 4 + 1;\n return Math.min(\n MAX_SPLAT_OPACITY,\n Math.exp((kernelShape * kernelShape - 1) / Math.E)\n );\n }\n return fromHalf(word & 65535);\n }\n function encodeSplatOpacity(opacity) {\n if (opacity > 0 && opacity <= 1) return toHalf(opacity);\n const value = clamp$1(opacity, 0, MAX_SPLAT_OPACITY);\n if (value > 1) {\n const shapeAmount = 0.25 * (Math.sqrt(Math.log(value) * Math.E + 1) - 1);\n return (toHalf(1) | toHalf(shapeAmount) << 16) >>> 0;\n }\n return toHalf(value);\n }\n function decodeQuatOctXy1010R12ToArray(word, output, base = 0, stride = 1) {\n const u = word & 1023;\n const v = word >>> 10 & 1023;\n const angle = word >>> 20;\n let x = u / 1023 * 2 - 1;\n let y = v / 1023 * 2 - 1;\n const z = 1 - Math.abs(x) - Math.abs(y);\n const fold = Math.max(-z, 0);\n x += x >= 0 ? -fold : fold;\n y += y >= 0 ? -fold : fold;\n const inverseLength = 1 / Math.sqrt(x * x + y * y + z * z);\n const halfTheta = angle / 4095 * 0.5 * Math.PI;\n const sine = Math.sin(halfTheta);\n output[base] = x * inverseLength * sine;\n output[base + stride] = y * inverseLength * sine;\n output[base + stride * 2] = z * inverseLength * sine;\n output[base + stride * 3] = Math.cos(halfTheta);\n }\n function encodeQuaternion$1(qx, qy, qz, qw, minimumLengthSquared) {\n const lengthSquared = qx * qx + qy * qy + qz * qz + qw * qw;\n if (!Number.isFinite(lengthSquared) || lengthSquared <= minimumLengthSquared) {\n return void 0;\n }\n if (qx === 0 && qy === 0 && qz === 0) {\n return ENCODED_IDENTITY_QUATERNION;\n }\n const inverseLength = 1 / Math.sqrt(lengthSquared);\n let x = qx * inverseLength;\n let y = qy * inverseLength;\n let z = qz * inverseLength;\n let w = qw * inverseLength;\n if (w < 0) {\n x = -x;\n y = -y;\n z = -z;\n w = -w;\n }\n const theta = 2 * Math.acos(clamp$1(w, 0, 1));\n const sine = Math.sin(theta * 0.5);\n const axisX = Math.abs(sine) < 1e-6 ? 1 : x / sine;\n const axisY = Math.abs(sine) < 1e-6 ? 0 : y / sine;\n const axisZ = Math.abs(sine) < 1e-6 ? 0 : z / sine;\n const sum = Math.abs(axisX) + Math.abs(axisY) + Math.abs(axisZ);\n let octX = axisX / sum;\n let octY = axisY / sum;\n if (axisZ < 0) {\n const previousX = octX;\n octX = (1 - Math.abs(octY)) * (octX >= 0 ? 1 : -1);\n octY = (1 - Math.abs(previousX)) * (octY >= 0 ? 1 : -1);\n }\n const u = Math.round(clamp$1((octX * 0.5 + 0.5) * 1023, 0, 1023));\n const v = Math.round(clamp$1((octY * 0.5 + 0.5) * 1023, 0, 1023));\n const angle = Math.round(clamp$1(theta / Math.PI * 4095, 0, 4095));\n return (angle << 20 | v << 10 | u) >>> 0;\n }\n function tryEncodeQuatOctXy1010R12(qx, qy, qz, qw) {\n return encodeQuaternion$1(qx, qy, qz, qw, F32_EPSILON);\n }\n const MAX_BLOCK_SIZE = 512;\n const MAX_REGISTER_BYTES = 4 * 1024 ** 2;\n const CONDITION_CARRY_EVENT_OFFSET_MASK = 2147483647;\n const CONDITION_CARRY_EVENT_REMOVAL = 2147483648;\n function getInstructionCount(instructions) {\n const count = instructions.length / SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n if (!Number.isInteger(count)) {\n throw new Error("Invalid packed postDecode instructions");\n }\n return count;\n }\n function instructionWidth(instructions, index) {\n return instructions[index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE + SPLAT_POST_DECODE_INSTRUCTION_WIDTH];\n }\n function getBlockSize(registerValueCount, processCount) {\n const bytesPerSplat = registerValueCount * Float32Array.BYTES_PER_ELEMENT;\n return Math.min(\n processCount,\n MAX_BLOCK_SIZE,\n Math.max(1, Math.floor(MAX_REGISTER_BYTES / bytesPerSplat))\n );\n }\n function allocateSplatPostDecodeRegisters(program) {\n const { instructions, outputs, condition } = program;\n const instructionCount = getInstructionCount(instructions);\n const lastUses = new Uint32Array(instructionCount);\n for (let index = 0; index < instructionCount; index += 1) {\n lastUses[index] = index;\n const instructionOffset = index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n for (let argumentIndex = 0; argumentIndex < SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT; argumentIndex += 1) {\n const argument = instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 + argumentIndex];\n if (argument === SPLAT_POST_DECODE_MISSING_ARGUMENT) break;\n lastUses[argument] = index;\n }\n }\n const packedConditionStages = condition == null ? void 0 : condition.stages;\n if (packedConditionStages) {\n for (let stageOffset = 0; stageOffset < packedConditionStages.length; stageOffset += SPLAT_POST_DECODE_FLOW_STAGE_STRIDE) {\n const register = packedConditionStages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_REGISTER];\n const instruction = packedConditionStages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION];\n lastUses[register] = Math.max(lastUses[register], instruction);\n }\n }\n const programEnd = instructionCount;\n for (const output of [\n outputs.position,\n outputs.scale,\n outputs.quaternion,\n outputs.opacity,\n outputs.alpha,\n outputs.color,\n ...outputs.sh ?? []\n ]) {\n if (output !== void 0) lastUses[output] = programEnd;\n }\n const registerOffsets = new Uint32Array(instructionCount);\n const constantRegisters = new Uint8Array(instructionCount);\n let registerValueCount = 0;\n for (let index = 0; index < instructionCount; index += 1) {\n const instructionOffset = index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n if (instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE] === Opcode.Constant) {\n constantRegisters[index] = 1;\n lastUses[index] = programEnd;\n registerOffsets[index] = registerValueCount;\n registerValueCount += instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH];\n }\n }\n const releaseHeads = new Int32Array(instructionCount + 1).fill(-1);\n const releaseNext = new Int32Array(instructionCount).fill(-1);\n const freeRanges = [];\n const release = (releasedOffset, releasedWidth) => {\n let offset = releasedOffset;\n let width = releasedWidth;\n let insertIndex = 0;\n while (insertIndex < freeRanges.length && freeRanges[insertIndex].offset < offset) {\n insertIndex += 1;\n }\n const previous = freeRanges[insertIndex - 1];\n if (previous && previous.offset + previous.width === offset) {\n offset = previous.offset;\n width += previous.width;\n freeRanges.splice(insertIndex - 1, 1);\n insertIndex -= 1;\n }\n const next = freeRanges[insertIndex];\n if (next && offset + width === next.offset) {\n width += next.width;\n freeRanges.splice(insertIndex, 1);\n }\n freeRanges.splice(insertIndex, 0, { offset, width });\n };\n const allocate = (width) => {\n let bestIndex = -1;\n for (let index = 0; index < freeRanges.length; index += 1) {\n const range2 = freeRanges[index];\n if (range2.width >= width && (bestIndex === -1 || range2.width < freeRanges[bestIndex].width)) {\n bestIndex = index;\n }\n }\n if (bestIndex === -1) {\n const offset2 = registerValueCount;\n registerValueCount += width;\n return offset2;\n }\n const range = freeRanges[bestIndex];\n const offset = range.offset;\n if (range.width === width) freeRanges.splice(bestIndex, 1);\n else {\n range.offset += width;\n range.width -= width;\n }\n return offset;\n };\n for (let index = 0; index < instructionCount; index += 1) {\n for (let released = releaseHeads[index]; released !== -1; released = releaseNext[released]) {\n release(\n registerOffsets[released],\n instructionWidth(instructions, released)\n );\n }\n if (constantRegisters[index]) continue;\n const width = instructionWidth(instructions, index);\n const offset = allocate(width);\n registerOffsets[index] = offset;\n const releaseIndex = lastUses[index] + 1;\n if (releaseIndex <= instructionCount) {\n releaseNext[index] = releaseHeads[releaseIndex];\n releaseHeads[releaseIndex] = index;\n }\n }\n const conditionStageCount = packedConditionStages ? packedConditionStages.length / SPLAT_POST_DECODE_FLOW_STAGE_STRIDE : 0;\n if (!Number.isInteger(conditionStageCount)) {\n throw new Error("Invalid packed postDecode condition flow");\n }\n let conditionCarryStageStarts = new Uint32Array();\n let conditionCarryEvents = new Uint32Array();\n if (packedConditionStages && conditionStageCount !== 0) {\n if (registerValueCount > 65536) {\n throw new Error("postDecode register offsets exceed Uint16 capacity");\n }\n const stageBoundaries = new Uint16Array(conditionStageCount);\n for (let stage = 0; stage < conditionStageCount; stage += 1) {\n const boundary = packedConditionStages[stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION] + 1;\n if (boundary > instructionCount || stage !== 0 && boundary <= stageBoundaries[stage - 1]) {\n throw new Error("Invalid postDecode condition stage boundary");\n }\n stageBoundaries[stage] = boundary;\n }\n const stageAfterInstruction = (instruction) => {\n let start = 0;\n let end = conditionStageCount;\n while (start < end) {\n const middle = start + end >>> 1;\n if (stageBoundaries[middle] <= instruction) start = middle + 1;\n else end = middle;\n }\n return start;\n };\n const firstStages = new Uint16Array(instructionCount);\n const endStages = new Uint16Array(instructionCount);\n const eventCounts = new Uint32Array(conditionStageCount);\n const removalCounts = new Uint32Array(conditionStageCount);\n for (let index = 0; index < instructionCount; index += 1) {\n if (constantRegisters[index]) continue;\n const firstStage = stageAfterInstruction(index);\n const endStage = stageAfterInstruction(lastUses[index]);\n if (firstStage >= endStage) continue;\n firstStages[index] = firstStage;\n endStages[index] = endStage;\n const width = instructions[index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE + SPLAT_POST_DECODE_INSTRUCTION_WIDTH];\n eventCounts[firstStage] += width;\n if (endStage < conditionStageCount) {\n eventCounts[endStage] += width;\n removalCounts[endStage] += width;\n }\n }\n const eventStarts = new Uint32Array(conditionStageCount + 1);\n for (let stage = 0; stage < conditionStageCount; stage += 1) {\n eventStarts[stage + 1] = eventStarts[stage] + eventCounts[stage];\n }\n conditionCarryStageStarts = eventStarts;\n conditionCarryEvents = new Uint32Array(eventStarts[conditionStageCount]);\n const removalCursors = new Uint32Array(\n eventStarts.subarray(0, conditionStageCount)\n );\n const additionCursors = new Uint32Array(conditionStageCount);\n for (let stage = 0; stage < conditionStageCount; stage += 1) {\n additionCursors[stage] = eventStarts[stage] + removalCounts[stage];\n }\n for (let index = 0; index < instructionCount; index += 1) {\n const firstStage = firstStages[index];\n const endStage = endStages[index];\n if (firstStage >= endStage) continue;\n const width = instructions[index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE + SPLAT_POST_DECODE_INSTRUCTION_WIDTH];\n const offset = registerOffsets[index];\n for (let lane = 0; lane < width; lane += 1) {\n const carryOffset = offset + lane;\n if (endStage < conditionStageCount) {\n conditionCarryEvents[removalCursors[endStage]] = CONDITION_CARRY_EVENT_REMOVAL | carryOffset;\n removalCursors[endStage] += 1;\n }\n conditionCarryEvents[additionCursors[firstStage]] = carryOffset;\n additionCursors[firstStage] += 1;\n }\n }\n }\n return {\n registerOffsets,\n registerValueCount,\n conditionCarryStageStarts,\n conditionCarryEvents\n };\n }\n function rustMin(left, right) {\n if (Number.isNaN(left)) return right;\n if (Number.isNaN(right)) return left;\n return Math.min(left, right);\n }\n function rustMax(left, right) {\n if (Number.isNaN(left)) return right;\n if (Number.isNaN(right)) return left;\n return Math.max(left, right);\n }\n function roundAwayFromZero(value) {\n return value < 0 ? -Math.round(-value) : Math.round(value);\n }\n function clamp(value, min, max) {\n return Math.min(max, Math.max(min, value));\n }\n const ATTRIBUTE_READERS = {\n f32: (data, offset) => data.getFloat32(offset, true),\n f16: (data, offset) => fromHalf(data.getUint16(offset, true)),\n u8: (data, offset) => data.getUint8(offset),\n unorm8: (data, offset) => data.getUint8(offset) / 255,\n i8: (data, offset) => data.getInt8(offset),\n snorm8: (data, offset) => Math.max(-1, data.getInt8(offset) / 127),\n u16: (data, offset) => data.getUint16(offset, true),\n unorm16: (data, offset) => data.getUint16(offset, true) / 65535,\n i16: (data, offset) => data.getInt16(offset, true),\n snorm16: (data, offset) => Math.max(-1, data.getInt16(offset, true) / 32767),\n u32: (data, offset) => data.getUint32(offset, true),\n i32: (data, offset) => data.getInt32(offset, true)\n };\n function readAttributeBlock(data, attribute, blockStart, blockCount, blockSize, registers, outputBase, sourceIndices) {\n const componentBytes = ATTRIBUTE_FORMAT_BYTES[attribute.format];\n const read = ATTRIBUTE_READERS[attribute.format];\n for (let component = 0; component < attribute.components; component += 1) {\n const componentOutput = outputBase + component * blockSize;\n if (sourceIndices) {\n for (let index = 0; index < blockCount; index += 1) {\n const inputOffset = attribute.byteOffset + (blockStart + sourceIndices[index]) * attribute.byteStride + component * componentBytes;\n registers[componentOutput + index] = read(data, inputOffset);\n }\n } else {\n let inputOffset = attribute.byteOffset + blockStart * attribute.byteStride + component * componentBytes;\n for (let index = 0; index < blockCount; index += 1) {\n registers[componentOutput + index] = read(data, inputOffset);\n inputOffset += attribute.byteStride;\n }\n }\n }\n }\n function encodeQuaternion(registers, base, stride) {\n return tryEncodeQuatOctXy1010R12(\n registers[base],\n registers[base + stride],\n registers[base + stride * 2],\n registers[base + stride * 3]\n );\n }\n function decodeSh(word, output, base, stride) {\n const exponentAndSigns = word >>> 24;\n const multiplier = 2 ** ((exponentAndSigns >>> 3) - 15) / 255;\n for (let component = 0; component < 3; component += 1) {\n const magnitude = (word >>> component * 8 & 255) * multiplier;\n output[base + component * stride] = exponentAndSigns & 1 << component ? -magnitude : magnitude;\n }\n }\n function encodeSh(registers, base, stride) {\n const red = registers[base];\n const green = registers[base + stride];\n const blue = registers[base + stride * 2];\n const maxAbsolute = rustMax(\n Math.abs(red),\n rustMax(Math.abs(green), Math.abs(blue))\n );\n const exponent = roundAwayFromZero(\n clamp(Math.floor(Math.log2(maxAbsolute)) + 15, 0, 31)\n );\n const divisor = 2 ** (exponent - 15) / 255;\n const encodeComponent = (value) => roundAwayFromZero(clamp(Math.abs(value) / divisor, 0, 255));\n const signs = (red < 0 ? 1 : 0) | (green < 0 ? 2 : 0) | (blue < 0 ? 4 : 0);\n return (encodeComponent(red) | encodeComponent(green) << 8 | encodeComponent(blue) << 16 | (exponent << 3 | signs) << 24) >>> 0;\n }\n function shWord(data, coefficient) {\n if (coefficient <= 2 && data.sh1) return [data.sh1, coefficient];\n if (coefficient === 3 && data.sh1 && data.sh2) return [data.sh1, 3];\n if (coefficient <= 7 && data.sh2) return [data.sh2, coefficient - 4];\n if (coefficient <= 11 && data.sh3a) return [data.sh3a, coefficient - 8];\n if (coefficient <= 14 && data.sh3b) return [data.sh3b, coefficient - 12];\n return void 0;\n }\n const OUTPUT_POSITION = 0;\n const OUTPUT_SCALE = 1;\n const OUTPUT_QUATERNION = 2;\n const OUTPUT_OPACITY = 3;\n const OUTPUT_ALPHA = 4;\n const OUTPUT_COLOR = 5;\n const OUTPUT_COUNT = 6;\n const MISSING_OUTPUT_BASE = 4294967295;\n function createOutputWritePlan(data, program, registerBases) {\n const { outputs } = program;\n const outputBases = new Uint32Array(OUTPUT_COUNT);\n outputBases.fill(MISSING_OUTPUT_BASE);\n let outputFieldCount = 0;\n const setOutputBase = (slot, register) => {\n if (register !== void 0) {\n outputBases[slot] = registerBases[register];\n outputFieldCount += 1;\n }\n };\n setOutputBase(OUTPUT_POSITION, outputs.position);\n setOutputBase(OUTPUT_SCALE, outputs.scale);\n setOutputBase(OUTPUT_QUATERNION, outputs.quaternion);\n setOutputBase(OUTPUT_OPACITY, outputs.opacity);\n setOutputBase(OUTPUT_ALPHA, outputs.alpha);\n setOutputBase(OUTPUT_COLOR, outputs.color);\n const shTargetArrays = [];\n const shWordOffsets = [];\n const shRegisterBases = [];\n if (outputs.sh) {\n for (let coefficient = 0; coefficient < SH_COEFFICIENT_COUNT; coefficient += 1) {\n const location = shWord(data, coefficient);\n if (!location) continue;\n shTargetArrays.push(location[0]);\n shWordOffsets.push(location[1]);\n shRegisterBases.push(registerBases[outputs.sh[coefficient]]);\n }\n }\n return {\n outputBases,\n shTargetArrays,\n shWordOffsets: new Uint8Array(shWordOffsets),\n shRegisterBases: new Uint32Array(shRegisterBases),\n updatesSortCenter: outputs.position !== void 0 || outputs.scale !== void 0,\n writesOutputs: outputFieldCount !== 0 || shTargetArrays.length !== 0\n };\n }\n function evaluateInputFieldBlock(field, blockStart, blockCount, blockSize, data, splat0Float, registers, outputBase, sourceIndices) {\n switch (field) {\n case InputField.Position:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n registers[outputBase + index] = splat0Float[wordBase];\n registers[outputBase + blockSize + index] = splat0Float[wordBase + 1];\n registers[outputBase + blockSize * 2 + index] = splat0Float[wordBase + 2];\n }\n break;\n case InputField.Scale:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n const word1 = data.splat1[wordBase + 1];\n const word2 = data.splat1[wordBase + 2];\n registers[outputBase + index] = Math.exp(fromHalf(word1 >>> 16));\n registers[outputBase + blockSize + index] = Math.exp(\n fromHalf(word2 & 65535)\n );\n registers[outputBase + blockSize * 2 + index] = Math.exp(\n fromHalf(word2 >>> 16)\n );\n }\n break;\n case InputField.Quaternion:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n decodeQuatOctXy1010R12ToArray(\n data.splat1[wordBase + 3],\n registers,\n outputBase + index,\n blockSize\n );\n }\n break;\n case InputField.Opacity:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n registers[outputBase + index] = decodeSplatOpacity(\n data.splat0[(blockStart + sourceIndex) * 4 + 3]\n );\n }\n break;\n case InputField.Alpha:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n registers[outputBase + index] = fromHalf(\n data.splat0[(blockStart + sourceIndex) * 4 + 3] & 65535\n );\n }\n break;\n case InputField.Color:\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n const wordBase = (blockStart + sourceIndex) * 4;\n const word0 = data.splat1[wordBase];\n const word1 = data.splat1[wordBase + 1];\n registers[outputBase + index] = fromHalf(word0 & 65535);\n registers[outputBase + blockSize + index] = fromHalf(word0 >>> 16);\n registers[outputBase + blockSize * 2 + index] = fromHalf(\n word1 & 65535\n );\n }\n break;\n default: {\n const coefficient = field - InputField.Sh0;\n const location = shWord(data, coefficient);\n if (location) {\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (sourceIndices == null ? void 0 : sourceIndices[index]) ?? index;\n decodeSh(\n location[0][(blockStart + sourceIndex) * 4 + location[1]],\n registers,\n outputBase + index,\n blockSize\n );\n }\n } else {\n registers.fill(0, outputBase, outputBase + blockCount);\n registers.fill(\n 0,\n outputBase + blockSize,\n outputBase + blockSize + blockCount\n );\n registers.fill(\n 0,\n outputBase + blockSize * 2,\n outputBase + blockSize * 2 + blockCount\n );\n }\n }\n }\n }\n function prepareProgram(data, program, processCount) {\n var _a;\n const {\n registerOffsets: registerBases,\n registerValueCount,\n conditionCarryStageStarts,\n conditionCarryEvents\n } = allocateSplatPostDecodeRegisters(program);\n const blockSize = getBlockSize(registerValueCount, processCount);\n for (let index = 0; index < registerBases.length; index += 1) {\n registerBases[index] *= blockSize;\n }\n const conditionStages = (_a = program.condition) == null ? void 0 : _a.stages;\n const conditionStageCount = ((conditionStages == null ? void 0 : conditionStages.length) ?? 0) / SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;\n const outputInstructionStart = ((conditionStages == null ? void 0 : conditionStages[conditionStages.length - SPLAT_POST_DECODE_FLOW_STAGE_STRIDE + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION]) ?? -1) + 1;\n return {\n outputPlan: createOutputWritePlan(data, program, registerBases),\n registerBases,\n conditionStages,\n conditionStageCount,\n outputInstructionStart,\n conditionCarryStageStarts,\n conditionCarryEvents,\n blockSize,\n registerValueCount\n };\n }\n function compactRegisterBlock(registers, activeOffsets, activeCount, laneIndices, nextCount, blockSize) {\n for (let carryIndex = 0; carryIndex < activeCount; carryIndex += 1) {\n const offset = activeOffsets[carryIndex];\n const base = offset * blockSize;\n for (let index = 0; index < nextCount; index += 1) {\n registers[base + index] = registers[base + laneIndices[index]];\n }\n }\n }\n function applyConditionCarryEvents(carry, stage) {\n while (carry.nextStage <= stage) {\n const eventStart = carry.stageStarts[carry.nextStage];\n const eventEnd = carry.stageStarts[carry.nextStage + 1];\n for (let eventIndex = eventStart; eventIndex < eventEnd; eventIndex += 1) {\n const event = carry.events[eventIndex];\n const offset = event & CONDITION_CARRY_EVENT_OFFSET_MASK;\n if (event & CONDITION_CARRY_EVENT_REMOVAL) {\n const position = carry.activePositions[offset];\n if (position === -1) {\n throw new Error("Invalid postDecode condition carry removal");\n }\n const lastPosition = carry.activeCount - 1;\n const lastOffset = carry.activeOffsets[lastPosition];\n if (position !== lastPosition) {\n carry.activeOffsets[position] = lastOffset;\n carry.activePositions[lastOffset] = position;\n }\n carry.activePositions[offset] = -1;\n carry.activeCount = lastPosition;\n } else {\n if (carry.activePositions[offset] !== -1) {\n throw new Error("Invalid postDecode condition carry addition");\n }\n carry.activePositions[offset] = carry.activeCount;\n carry.activeOffsets[carry.activeCount] = offset;\n carry.activeCount += 1;\n }\n }\n carry.nextStage += 1;\n }\n }\n function collectConditionFlowBlock(heads, nextIndices, sourceIndices, stage, initialCount = 0) {\n let count = initialCount;\n let sourceIndex = heads[stage];\n while (sourceIndex !== -1) {\n sourceIndices[count] = sourceIndex;\n count += 1;\n sourceIndex = nextIndices[sourceIndex];\n }\n heads[stage] = -1;\n return count;\n }\n function enqueueConditionFlowBlock(heads, nextIndices, stage, sourceIndex) {\n if (stage < 0 || stage >= heads.length) return;\n nextIndices[sourceIndex] = heads[stage];\n heads[stage] = sourceIndex;\n }\n function evaluateUnaryBlock(opcode, registers, outputBase, inputBase, width, blockSize, blockCount) {\n for (let component = 0; component < width; component += 1) {\n const output = outputBase + component * blockSize;\n const input = inputBase + component * blockSize;\n switch (opcode) {\n case Opcode.Negate:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = -registers[input + lane];\n }\n break;\n case Opcode.Abs:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.abs(registers[input + lane]);\n }\n break;\n case Opcode.Log:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.log(registers[input + lane]);\n }\n break;\n case Opcode.Exp:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.exp(registers[input + lane]);\n }\n break;\n case Opcode.Floor:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.floor(registers[input + lane]);\n }\n break;\n case Opcode.Ceil:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.ceil(registers[input + lane]);\n }\n break;\n case Opcode.Round:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = roundAwayFromZero(registers[input + lane]);\n }\n break;\n case Opcode.Sin:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.sin(registers[input + lane]);\n }\n break;\n case Opcode.Cos:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.cos(registers[input + lane]);\n }\n break;\n case Opcode.Acos:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.acos(registers[input + lane]);\n }\n break;\n case Opcode.Tan:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.tan(registers[input + lane]);\n }\n break;\n case Opcode.Asin:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.asin(registers[input + lane]);\n }\n break;\n case Opcode.Atan:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.atan(registers[input + lane]);\n }\n break;\n }\n }\n }\n function evaluateBinaryBlock(opcode, registers, outputBase, arg0, arg1, width, arg1Width, blockSize, blockCount) {\n for (let component = 0; component < width; component += 1) {\n const output = outputBase + component * blockSize;\n const left = arg0 + component * blockSize;\n const right = arg1 + (arg1Width === 1 ? 0 : component * blockSize);\n switch (opcode) {\n case Opcode.Add:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = registers[left + lane] + registers[right + lane];\n }\n break;\n case Opcode.Subtract:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = registers[left + lane] - registers[right + lane];\n }\n break;\n case Opcode.Multiply:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = registers[left + lane] * registers[right + lane];\n }\n break;\n case Opcode.Divide:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = registers[left + lane] / registers[right + lane];\n }\n break;\n case Opcode.Pow:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = registers[left + lane] ** registers[right + lane];\n }\n break;\n case Opcode.Min:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = rustMin(\n registers[left + lane],\n registers[right + lane]\n );\n }\n break;\n case Opcode.Max:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = rustMax(\n registers[left + lane],\n registers[right + lane]\n );\n }\n break;\n case Opcode.Atan2:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.atan2(\n registers[left + lane],\n registers[right + lane]\n );\n }\n break;\n }\n }\n }\n function executeRange(data, program, attributeData, splat0Float, registers, registerBases, instructionStart, instructionEnd, blockStart, blockCount, blockSize, sourceIndices) {\n const { attributes, instructions } = program;\n for (let instructionIndex = instructionStart; instructionIndex < instructionEnd; instructionIndex += 1) {\n const instructionOffset = instructionIndex * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n const opcode = instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE];\n if (opcode === Opcode.Constant) continue;\n const width = instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH];\n const immediate = instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE];\n const outputBase = registerBases[instructionIndex];\n const argumentOffset = instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0;\n const arg0Register = instructions[argumentOffset];\n const arg1Register = instructions[argumentOffset + 1];\n const arg2Register = instructions[argumentOffset + 2];\n const arg3Register = instructions[argumentOffset + 3];\n const arg0 = arg0Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : registerBases[arg0Register];\n const arg1 = arg1Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : registerBases[arg1Register];\n const arg2 = arg2Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : registerBases[arg2Register];\n const arg3 = arg3Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : registerBases[arg3Register];\n const arg0Width = arg0Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : instructionWidth(instructions, arg0Register);\n const arg1Width = arg1Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : instructionWidth(instructions, arg1Register);\n const arg2Width = arg2Register === SPLAT_POST_DECODE_MISSING_ARGUMENT ? 0 : instructionWidth(instructions, arg2Register);\n switch (opcode) {\n case Opcode.InputField:\n evaluateInputFieldBlock(\n immediate,\n blockStart,\n blockCount,\n blockSize,\n data,\n splat0Float,\n registers,\n outputBase,\n sourceIndices\n );\n break;\n case Opcode.InputAttribute:\n readAttributeBlock(\n attributeData,\n attributes[immediate],\n blockStart,\n blockCount,\n blockSize,\n registers,\n outputBase,\n sourceIndices\n );\n break;\n case Opcode.Negate:\n case Opcode.Abs:\n case Opcode.Log:\n case Opcode.Exp:\n case Opcode.Floor:\n case Opcode.Ceil:\n case Opcode.Round:\n case Opcode.Sin:\n case Opcode.Cos:\n case Opcode.Acos:\n case Opcode.Tan:\n case Opcode.Asin:\n case Opcode.Atan:\n evaluateUnaryBlock(\n opcode,\n registers,\n outputBase,\n arg0,\n width,\n blockSize,\n blockCount\n );\n break;\n case Opcode.Sqrt:\n for (let component = 0; component < width; component += 1) {\n const output = outputBase + component * blockSize;\n const input = arg0 + component * blockSize;\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = Math.sqrt(registers[input + lane]);\n }\n }\n break;\n case Opcode.Normalize:\n for (let lane = 0; lane < blockCount; lane += 1) {\n let lengthSquared = 0;\n for (let component = 0; component < width; component += 1) {\n const value = registers[arg0 + component * blockSize + lane];\n lengthSquared += value * value;\n }\n const length = Math.sqrt(lengthSquared);\n for (let component = 0; component < width; component += 1) {\n const input = registers[arg0 + component * blockSize + lane];\n registers[outputBase + component * blockSize + lane] = length === 0 || !Number.isFinite(length) ? input : input / length;\n }\n }\n break;\n case Opcode.Length:\n for (let lane = 0; lane < blockCount; lane += 1) {\n let lengthSquared = 0;\n for (let component = 0; component < arg0Width; component += 1) {\n const value = registers[arg0 + component * blockSize + lane];\n lengthSquared += value * value;\n }\n registers[outputBase + lane] = Math.sqrt(lengthSquared);\n }\n break;\n case Opcode.IsFinite:\n for (let lane = 0; lane < blockCount; lane += 1) {\n let finite = true;\n for (let component = 0; component < arg0Width; component += 1) {\n finite && (finite = Number.isFinite(\n registers[arg0 + component * blockSize + lane]\n ));\n }\n registers[outputBase + lane] = finite ? 1 : 0;\n }\n break;\n case Opcode.Not:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane] === 0 ? 1 : 0;\n }\n break;\n case Opcode.Add:\n case Opcode.Subtract:\n case Opcode.Multiply:\n case Opcode.Divide:\n case Opcode.Pow:\n case Opcode.Min:\n case Opcode.Max:\n case Opcode.Atan2:\n evaluateBinaryBlock(\n opcode,\n registers,\n outputBase,\n arg0,\n arg1,\n width,\n arg1Width,\n blockSize,\n blockCount\n );\n break;\n case Opcode.Dot:\n for (let lane = 0; lane < blockCount; lane += 1) {\n let dot = 0;\n for (let component = 0; component < arg0Width; component += 1) {\n dot += registers[arg0 + component * blockSize + lane] * registers[arg1 + component * blockSize + lane];\n }\n registers[outputBase + lane] = dot;\n }\n break;\n case Opcode.Cross:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + blockSize + lane] * registers[arg1 + blockSize * 2 + lane] - registers[arg0 + blockSize * 2 + lane] * registers[arg1 + blockSize + lane];\n registers[outputBase + blockSize + lane] = registers[arg0 + blockSize * 2 + lane] * registers[arg1 + lane] - registers[arg0 + lane] * registers[arg1 + blockSize * 2 + lane];\n registers[outputBase + blockSize * 2 + lane] = registers[arg0 + lane] * registers[arg1 + blockSize + lane] - registers[arg0 + blockSize + lane] * registers[arg1 + lane];\n }\n break;\n case Opcode.Equal:\n case Opcode.NotEqual:\n for (let lane = 0; lane < blockCount; lane += 1) {\n let equal = true;\n for (let component = 0; component < arg0Width; component += 1) {\n equal && (equal = registers[arg0 + component * blockSize + lane] === registers[arg1 + component * blockSize + lane]);\n }\n registers[outputBase + lane] = (opcode === Opcode.Equal ? equal : !equal) ? 1 : 0;\n }\n break;\n case Opcode.Less:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane] < registers[arg1 + lane] ? 1 : 0;\n }\n break;\n case Opcode.LessEqual:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane] <= registers[arg1 + lane] ? 1 : 0;\n }\n break;\n case Opcode.Greater:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane] > registers[arg1 + lane] ? 1 : 0;\n }\n break;\n case Opcode.GreaterEqual:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane] >= registers[arg1 + lane] ? 1 : 0;\n }\n break;\n case Opcode.And:\n case Opcode.Or:\n for (let lane = 0; lane < blockCount; lane += 1) {\n const result = opcode === Opcode.And ? registers[arg0 + lane] !== 0 && registers[arg1 + lane] !== 0 : registers[arg0 + lane] !== 0 || registers[arg1 + lane] !== 0;\n registers[outputBase + lane] = result ? 1 : 0;\n }\n break;\n case Opcode.QuaternionMultiply:\n for (let lane = 0; lane < blockCount; lane += 1) {\n const leftX = registers[arg0 + lane];\n const leftY = registers[arg0 + blockSize + lane];\n const leftZ = registers[arg0 + blockSize * 2 + lane];\n const leftW = registers[arg0 + blockSize * 3 + lane];\n const rightX = registers[arg1 + lane];\n const rightY = registers[arg1 + blockSize + lane];\n const rightZ = registers[arg1 + blockSize * 2 + lane];\n const rightW = registers[arg1 + blockSize * 3 + lane];\n registers[outputBase + lane] = leftW * rightX + leftX * rightW + leftY * rightZ - leftZ * rightY;\n registers[outputBase + blockSize + lane] = leftW * rightY - leftX * rightZ + leftY * rightW + leftZ * rightX;\n registers[outputBase + blockSize * 2 + lane] = leftW * rightZ + leftX * rightY - leftY * rightX + leftZ * rightW;\n registers[outputBase + blockSize * 3 + lane] = leftW * rightW - leftX * rightX - leftY * rightY - leftZ * rightZ;\n }\n break;\n case Opcode.RotateVector:\n for (let lane = 0; lane < blockCount; lane += 1) {\n const quaternionX = registers[arg0 + lane];\n const quaternionY = registers[arg0 + blockSize + lane];\n const quaternionZ = registers[arg0 + blockSize * 2 + lane];\n const quaternionW = registers[arg0 + blockSize * 3 + lane];\n const vectorX = registers[arg1 + lane];\n const vectorY = registers[arg1 + blockSize + lane];\n const vectorZ = registers[arg1 + blockSize * 2 + lane];\n const crossX = 2 * (quaternionY * vectorZ - quaternionZ * vectorY);\n const crossY = 2 * (quaternionZ * vectorX - quaternionX * vectorZ);\n const crossZ = 2 * (quaternionX * vectorY - quaternionY * vectorX);\n registers[outputBase + lane] = vectorX + quaternionW * crossX + quaternionY * crossZ - quaternionZ * crossY;\n registers[outputBase + blockSize + lane] = vectorY + quaternionW * crossY + quaternionZ * crossX - quaternionX * crossZ;\n registers[outputBase + blockSize * 2 + lane] = vectorZ + quaternionW * crossZ + quaternionX * crossY - quaternionY * crossX;\n }\n break;\n case Opcode.Select:\n for (let component = 0; component < width; component += 1) {\n const output = outputBase + component * blockSize;\n const whenTrue = arg1 + component * blockSize;\n const whenFalse = arg2 + component * blockSize;\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = registers[arg0 + lane] !== 0 ? registers[whenTrue + lane] : registers[whenFalse + lane];\n }\n }\n break;\n case Opcode.Clamp:\n for (let component = 0; component < width; component += 1) {\n const output = outputBase + component * blockSize;\n const value = arg0 + component * blockSize;\n const min = arg1 + (arg1Width === 1 ? 0 : component * blockSize);\n const max = arg2 + (arg2Width === 1 ? 0 : component * blockSize);\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[output + lane] = rustMin(\n rustMax(registers[value + lane], registers[min + lane]),\n registers[max + lane]\n );\n }\n }\n break;\n case Opcode.Mix:\n for (let component = 0; component < width; component += 1) {\n const output = outputBase + component * blockSize;\n const left = arg0 + component * blockSize;\n const right = arg1 + (arg1Width === 1 ? 0 : component * blockSize);\n const amount = arg2 + (arg2Width === 1 ? 0 : component * blockSize);\n for (let lane = 0; lane < blockCount; lane += 1) {\n const leftValue = registers[left + lane];\n registers[output + lane] = leftValue + (registers[right + lane] - leftValue) * registers[amount + lane];\n }\n }\n break;\n case Opcode.Vec2:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane];\n registers[outputBase + blockSize + lane] = registers[arg1 + lane];\n }\n break;\n case Opcode.Vec3:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane];\n registers[outputBase + blockSize + lane] = registers[arg1 + lane];\n registers[outputBase + blockSize * 2 + lane] = registers[arg2 + lane];\n }\n break;\n case Opcode.Vec4:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + lane];\n registers[outputBase + blockSize + lane] = registers[arg1 + lane];\n registers[outputBase + blockSize * 2 + lane] = registers[arg2 + lane];\n registers[outputBase + blockSize * 3 + lane] = registers[arg3 + lane];\n }\n break;\n case Opcode.Component:\n for (let lane = 0; lane < blockCount; lane += 1) {\n registers[outputBase + lane] = registers[arg0 + immediate * blockSize + lane];\n }\n break;\n case Opcode.MaxComponentIndex:\n for (let lane = 0; lane < blockCount; lane += 1) {\n let largest = 0;\n let largestValue = registers[arg0 + lane];\n for (let component = 1; component < arg0Width; component += 1) {\n const value = registers[arg0 + component * blockSize + lane];\n if (value > largestValue) {\n largest = component;\n largestValue = value;\n }\n }\n registers[outputBase + lane] = largest;\n }\n break;\n default:\n throw new Error(`Unknown postDecode opcode: ${opcode}`);\n }\n }\n }\n function runProgram(data, program, plan, attributeData, splat0Float, registers, processCount) {\n const { constants, instructions } = program;\n const {\n registerBases,\n conditionStages: packedStages,\n conditionStageCount,\n outputInstructionStart,\n conditionCarryStageStarts,\n conditionCarryEvents,\n blockSize,\n outputPlan\n } = plan;\n const instructionCount = getInstructionCount(instructions);\n const flow = packedStages ? {\n stages: packedStages,\n sourceIndices: new Uint16Array(blockSize),\n laneIndices: new Uint16Array(blockSize),\n nextIndices: new Int32Array(blockSize).fill(-1),\n heads: new Int32Array(conditionStageCount + 1).fill(-1)\n } : void 0;\n const carry = conditionCarryEvents.length === 0 ? void 0 : {\n stageStarts: conditionCarryStageStarts,\n events: conditionCarryEvents,\n nextStage: 0,\n activeOffsets: new Uint16Array(registers.length / blockSize),\n activePositions: new Int32Array(registers.length / blockSize).fill(\n -1\n ),\n activeCount: 0\n };\n const outputWordBases = outputPlan.writesOutputs ? new Uint32Array(blockSize) : void 0;\n for (let instruction = 0; instruction < instructionCount; instruction += 1) {\n const instructionOffset = instruction * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;\n if (instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE] !== Opcode.Constant) {\n continue;\n }\n const outputBase = registerBases[instruction];\n const width = instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH];\n const immediate = instructions[instructionOffset + SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE];\n for (let lane = 0; lane < width; lane += 1) {\n registers.fill(\n constants[immediate + lane],\n outputBase + lane * blockSize,\n outputBase + (lane + 1) * blockSize\n );\n }\n }\n for (let blockStart = 0; blockStart < processCount; blockStart += blockSize) {\n let blockCount = Math.min(blockSize, processCount - blockStart);\n let sourceIndices;\n if (carry) {\n carry.nextStage = 0;\n carry.activeCount = 0;\n }\n for (let rangeIndex = 0; rangeIndex <= conditionStageCount; rangeIndex += 1) {\n const isConditionStage = rangeIndex < conditionStageCount;\n if (flow && flow.heads[rangeIndex] !== -1) {\n if (sourceIndices !== flow.sourceIndices) {\n if (sourceIndices) {\n flow.sourceIndices.set(sourceIndices.subarray(0, blockCount), 0);\n } else {\n for (let index = 0; index < blockCount; index += 1) {\n flow.sourceIndices[index] = index;\n }\n }\n }\n blockCount = collectConditionFlowBlock(\n flow.heads,\n flow.nextIndices,\n flow.sourceIndices,\n rangeIndex,\n blockCount\n );\n sourceIndices = flow.sourceIndices;\n }\n const stageOffset = rangeIndex * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;\n const instructionStart = flow && isConditionStage ? flow.stages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_START] : outputInstructionStart;\n const instructionEnd = flow && isConditionStage ? flow.stages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION] + 1 : instructionCount;\n if (blockCount !== 0) {\n executeRange(\n data,\n program,\n attributeData,\n splat0Float,\n registers,\n registerBases,\n instructionStart,\n instructionEnd,\n blockStart,\n blockCount,\n blockSize,\n sourceIndices\n );\n }\n if (flow && isConditionStage && blockCount !== 0) {\n const conditionRegister = flow.stages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_REGISTER];\n const conditionBase = registerBases[conditionRegister];\n const nextStage = rangeIndex + 1;\n const currentSourceIndices = sourceIndices;\n const previousCount = blockCount;\n let nextStageCount = 0;\n const onTrue = flow.stages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE];\n const onFalse = flow.stages[stageOffset + SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE];\n const directOnTrue = onTrue === nextStage;\n const directOnFalse = onFalse === nextStage;\n const rejectTarget = flow.heads.length;\n if (directOnTrue && onFalse === rejectTarget || directOnFalse && onTrue === rejectTarget) {\n for (let index = 0; index < blockCount; index += 1) {\n const truthy = registers[conditionBase + index] !== 0;\n if (truthy !== directOnTrue) continue;\n const sourceIndex = currentSourceIndices == null ? void 0 : currentSourceIndices[index];\n flow.laneIndices[nextStageCount] = index;\n if (sourceIndex !== void 0) {\n flow.sourceIndices[nextStageCount] = sourceIndex;\n }\n nextStageCount += 1;\n }\n } else {\n for (let index = 0; index < blockCount; index += 1) {\n const sourceIndex = (currentSourceIndices == null ? void 0 : currentSourceIndices[index]) ?? index;\n const target = registers[conditionBase + index] !== 0 ? onTrue : onFalse;\n if (target === nextStage) {\n flow.laneIndices[nextStageCount] = index;\n if (currentSourceIndices) {\n flow.sourceIndices[nextStageCount] = sourceIndex;\n }\n nextStageCount += 1;\n } else {\n enqueueConditionFlowBlock(\n flow.heads,\n flow.nextIndices,\n target,\n sourceIndex\n );\n }\n }\n }\n if (nextStageCount !== 0 && nextStageCount !== previousCount) {\n if (carry) {\n applyConditionCarryEvents(carry, rangeIndex);\n compactRegisterBlock(\n registers,\n carry.activeOffsets,\n carry.activeCount,\n flow.laneIndices,\n nextStageCount,\n blockSize\n );\n }\n }\n if (nextStageCount !== previousCount || currentSourceIndices === flow.laneIndices) {\n sourceIndices = nextStageCount === 0 ? void 0 : currentSourceIndices ? flow.sourceIndices : flow.laneIndices;\n }\n blockCount = nextStageCount;\n }\n }\n if (outputWordBases && blockCount !== 0) {\n if (sourceIndices) {\n for (let index = 0; index < blockCount; index += 1) {\n outputWordBases[index] = (blockStart + sourceIndices[index]) * 4;\n }\n } else {\n let wordBase = blockStart * 4;\n for (let index = 0; index < blockCount; index += 1) {\n outputWordBases[index] = wordBase;\n wordBase += 4;\n }\n }\n writeOutputBlock(\n data,\n splat0Float,\n registers,\n outputPlan,\n outputWordBases,\n blockSize,\n blockCount\n );\n }\n if (carry) {\n for (let index = 0; index < carry.activeCount; index += 1) {\n carry.activePositions[carry.activeOffsets[index]] = -1;\n }\n }\n }\n }\n function writeOutputBlock(data, splat0Float, registers, plan, outputWordBases, blockSize, blockCount) {\n const { outputBases } = plan;\n const positionBase = outputBases[OUTPUT_POSITION];\n if (positionBase !== MISSING_OUTPUT_BASE) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n const registerBase = positionBase + blockIndex;\n splat0Float[wordBase] = registers[registerBase];\n splat0Float[wordBase + 1] = registers[registerBase + blockSize];\n splat0Float[wordBase + 2] = registers[registerBase + blockSize * 2];\n }\n }\n const scaleBase = outputBases[OUTPUT_SCALE];\n if (scaleBase !== MISSING_OUTPUT_BASE) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n const registerBase = scaleBase + blockIndex;\n const first = data.splat1[wordBase + 1] & 65535;\n data.splat1[wordBase + 1] = (first | toHalf(Math.log(registers[registerBase])) << 16) >>> 0;\n data.splat1[wordBase + 2] = (toHalf(Math.log(registers[registerBase + blockSize])) | toHalf(Math.log(registers[registerBase + blockSize * 2])) << 16) >>> 0;\n }\n }\n const quaternionBase = outputBases[OUTPUT_QUATERNION];\n if (quaternionBase !== MISSING_OUTPUT_BASE) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n const encoded = encodeQuaternion(\n registers,\n quaternionBase + blockIndex,\n blockSize\n );\n if (encoded !== void 0) data.splat1[wordBase + 3] = encoded;\n }\n }\n const opacityBase = outputBases[OUTPUT_OPACITY];\n if (opacityBase !== MISSING_OUTPUT_BASE) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n data.splat0[wordBase + 3] = encodeSplatOpacity(\n registers[opacityBase + blockIndex]\n );\n }\n }\n const alphaBase = outputBases[OUTPUT_ALPHA];\n if (alphaBase !== MISSING_OUTPUT_BASE) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordIndex = outputWordBases[blockIndex] + 3;\n data.splat0[wordIndex] = (data.splat0[wordIndex] & 4294901760 | toHalf(clamp(registers[alphaBase + blockIndex], 0, 1))) >>> 0;\n }\n }\n const colorBase = outputBases[OUTPUT_COLOR];\n if (colorBase !== MISSING_OUTPUT_BASE) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n const registerBase = colorBase + blockIndex;\n data.splat1[wordBase] = (toHalf(registers[registerBase]) | toHalf(registers[registerBase + blockSize]) << 16) >>> 0;\n data.splat1[wordBase + 1] = (data.splat1[wordBase + 1] & 4294901760 | toHalf(registers[registerBase + blockSize * 2])) >>> 0;\n }\n }\n for (let shIndex = 0; shIndex < plan.shTargetArrays.length; shIndex += 1) {\n const target = plan.shTargetArrays[shIndex];\n const wordOffset = plan.shWordOffsets[shIndex];\n const shRegisterBase = plan.shRegisterBases[shIndex];\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n target[wordBase + wordOffset] = encodeSh(\n registers,\n shRegisterBase + blockIndex,\n blockSize\n );\n }\n }\n if (plan.updatesSortCenter) {\n for (let blockIndex = 0; blockIndex < blockCount; blockIndex += 1) {\n const wordBase = outputWordBases[blockIndex];\n const disabled = data.splat1[wordBase + 1] >>> 16 === 64512 && (data.splat1[wordBase + 2] & 65535) === 64512 && data.splat1[wordBase + 2] >>> 16 === 64512;\n const centerBase = (wordBase >>> 2) * 3;\n if (disabled) {\n data.sortCenters[centerBase] = Number.NaN;\n data.sortCenters[centerBase + 1] = Number.NaN;\n data.sortCenters[centerBase + 2] = Number.NaN;\n } else {\n data.sortCenters[centerBase] = splat0Float[wordBase];\n data.sortCenters[centerBase + 1] = splat0Float[wordBase + 1];\n data.sortCenters[centerBase + 2] = splat0Float[wordBase + 2];\n }\n }\n }\n }\n function applySplatPostDecode(data, program) {\n let processCount = data.numSplats;\n for (const attribute of program.attributes) {\n processCount = Math.min(processCount, attribute.count);\n }\n if (processCount === 0 || program.instructions.length === 0) return;\n const plan = prepareProgram(data, program, processCount);\n const registers = new Float32Array(plan.registerValueCount * plan.blockSize);\n const attributeData = new DataView(\n program.attributeData.buffer,\n program.attributeData.byteOffset,\n program.attributeData.byteLength\n );\n const splat0Float = new Float32Array(\n data.splat0.buffer,\n data.splat0.byteOffset,\n data.splat0.length\n );\n runProgram(\n data,\n program,\n plan,\n attributeData,\n splat0Float,\n registers,\n processCount\n );\n }\n function getTransferable(ctx) {\n const buffers = /* @__PURE__ */ new Set();\n const seen = /* @__PURE__ */ new Set();\n function traverse(obj) {\n if (!obj || typeof obj !== "object" || seen.has(obj)) return;\n seen.add(obj);\n if (obj instanceof ArrayBuffer) {\n buffers.add(obj);\n } else if (ArrayBuffer.isView(obj)) {\n buffers.add(obj.buffer);\n } else {\n Object.values(obj).forEach(traverse);\n }\n }\n traverse(ctx);\n return [...buffers];\n }\n const rpcHandlers = {\n setSortCenterState,\n sortCenters32,\n loadSplats,\n nextChunk\n };\n let wasmMemory;\n function getWasmMemoryBytes() {\n return (wasmMemory == null ? void 0 : wasmMemory.buffer.byteLength) ?? 0;\n }\n function setSortCenterState({\n centerUpdateRangeIndices,\n updateCenters,\n matrixUpdateRangeIndices,\n updateMatrices,\n rangeMeshIds,\n rangeBases,\n rangeCounts\n }) {\n set_sort_center_state(\n centerUpdateRangeIndices,\n updateCenters,\n matrixUpdateRangeIndices,\n updateMatrices,\n rangeMeshIds,\n rangeBases,\n rangeCounts\n );\n }\n function sortCenters32({\n numSplats,\n cameraPosition,\n direction,\n radial,\n ordering\n }) {\n const activeSplats = sort32_centers(\n numSplats,\n cameraPosition[0],\n cameraPosition[1],\n cameraPosition[2],\n direction[0],\n direction[1],\n direction[2],\n radial,\n ordering\n );\n return { activeSplats, ordering };\n }\n async function onMessage(event) {\n const {\n id,\n name,\n args\n } = event.data;\n try {\n const handler = rpcHandlers[name];\n if (!handler) {\n throw new Error(`Unknown worker RPC: ${name}`);\n }\n const sendStatus = (data) => {\n self.postMessage(\n { id, status: data },\n { transfer: getTransferable(data) }\n );\n };\n const result = await handler(args, { sendStatus });\n self.postMessage(\n { id, result, wasmMemoryBytes: getWasmMemoryBytes() },\n { transfer: getTransferable(result) }\n );\n } catch (error) {\n console.warn(`Worker error: ${error}`);\n self.postMessage(\n { id, error, wasmMemoryBytes: getWasmMemoryBytes() },\n { transfer: getTransferable(error) }\n );\n }\n }\n async function decodeBytesUrl({\n decoder,\n fileBytes,\n url,\n requestHeader,\n withCredentials,\n chunked,\n chunkedLength,\n sendStatus\n }) {\n if (fileBytes) {\n const byteLength = fileBytes.length;\n if (byteLength > 0) {\n decoder.set_expected_input_size(byteLength);\n }\n sendStatus({ loaded: byteLength, total: byteLength });\n decoder.push(fileBytes);\n return decoder.finish();\n }\n const suppliedInputLength = chunkedLength ?? 0;\n if (!Number.isSafeInteger(suppliedInputLength) || suppliedInputLength < 0) {\n throw new Error("streamLength must be a non-negative integer");\n }\n let streamLength = suppliedInputLength;\n let expectedInputLength = 0;\n let responseBody;\n if (url) {\n const request = new Request(url, {\n headers: requestHeader ? new Headers(requestHeader) : void 0,\n credentials: withCredentials ? "include" : "same-origin"\n });\n const response = await fetch(request);\n if (!response.ok || !response.body) {\n throw new Error(\n `Failed to fetch "${url}": ${response.status} ${response.statusText}`\n );\n }\n responseBody = response.body;\n const contentLength = Number(response.headers.get("Content-Length") || "0");\n const responseLength = Number.isSafeInteger(contentLength) && contentLength > 0 ? contentLength : 0;\n streamLength || (streamLength = responseLength);\n const contentEncoding = response.headers.get("Content-Encoding");\n const hasIdentityEncoding = !contentEncoding || contentEncoding.toLowerCase() === "identity";\n if (response.type === "basic" && hasIdentityEncoding) {\n expectedInputLength = responseLength;\n }\n } else if (!chunked) {\n throw new Error("No url or fileBytes provided");\n }\n const streamReader = responseBody == null ? void 0 : responseBody.getReader();\n const readInputChunk = async () => {\n if (streamReader) {\n const { done, value } = await streamReader.read();\n return done ? void 0 : value;\n }\n const chunk = await new Promise((resolve) => {\n nextChunkWaiter = resolve;\n sendStatus({ nextChunk: true });\n });\n return chunk.length === 0 ? void 0 : chunk;\n };\n let loaded = 0;\n try {\n if (expectedInputLength > 0) {\n decoder.set_expected_input_size(expectedInputLength);\n }\n while (true) {\n const value = await readInputChunk();\n if (!value) break;\n loaded += value.length;\n if (expectedInputLength > 0 && loaded > expectedInputLength) {\n throw new Error(\n `Input length exceeds the expected ${expectedInputLength} bytes`\n );\n }\n sendStatus({ loaded, total: streamLength });\n decoder.push(value);\n }\n if (expectedInputLength > 0 && loaded !== expectedInputLength) {\n throw new Error(\n `Input length mismatch: expected ${expectedInputLength} bytes, received ${loaded}`\n );\n }\n if (chunked && streamLength === 0) {\n sendStatus({ loaded, total: loaded });\n }\n return decoder.finish();\n } catch (error) {\n try {\n await (streamReader == null ? void 0 : streamReader.cancel(error));\n } catch {\n }\n throw error;\n } finally {\n streamReader == null ? void 0 : streamReader.releaseLock();\n }\n }\n function toSplatResult(decoded) {\n return {\n numSplats: decoded.numSplats,\n splatArrays: [decoded.splat0, decoded.splat1],\n sortCenters: decoded.sortCenters,\n extra: {\n sh1: decoded.sh1,\n sh2: decoded.sh2,\n sh3a: decoded.sh3a,\n sh3b: decoded.sh3b\n }\n };\n }\n async function loadSplats({\n url,\n requestHeader,\n withCredentials,\n fileBytes,\n fileType,\n pathName,\n chunked,\n chunkedLength,\n postDecode\n }, { sendStatus }) {\n const decoder = decode_to_splats(fileType, pathName ?? url);\n const decoded = await decodeBytesUrl({\n decoder,\n fileBytes,\n url,\n requestHeader,\n withCredentials,\n chunked,\n chunkedLength,\n sendStatus\n });\n if (postDecode) applySplatPostDecode(decoded, postDecode);\n return toSplatResult(decoded);\n }\n let nextChunkWaiter = (_chunk) => {\n };\n async function nextChunk({ chunk }) {\n nextChunkWaiter(chunk);\n }\n async function initialize() {\n let resolveWaitForModule;\n const waitForModule = new Promise((resolve) => {\n resolveWaitForModule = resolve;\n });\n const pending = [];\n const bufferMessage = (event) => {\n if (event.data.name === "init-wasm") {\n resolveWaitForModule(event.data.module);\n return;\n }\n pending.push(event);\n };\n self.addEventListener("message", bufferMessage);\n const wasm2 = await __wbg_init({ module_or_path: await waitForModule });\n wasmMemory = wasm2.memory;\n self.removeEventListener("message", bufferMessage);\n self.addEventListener("message", onMessage);\n for (const event of pending) {\n onMessage(event);\n }\n pending.length = 0;\n }\n initialize().catch(console.error);\n})();\n//# sourceMappingURL=worker-Cx-xVLFg.js.map\n';
|
|
2450
2450
|
const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
|
|
2451
2451
|
function WorkerWrapper(options) {
|
|
2452
2452
|
let objURL;
|
|
@@ -3490,6 +3490,13 @@ class SplatPostDecodeValue {
|
|
|
3490
3490
|
this.owner = owner;
|
|
3491
3491
|
}
|
|
3492
3492
|
}
|
|
3493
|
+
const SPLAT_POST_DECODE_INSTRUCTION_OPCODE = 0;
|
|
3494
|
+
const SPLAT_POST_DECODE_INSTRUCTION_WIDTH = 1;
|
|
3495
|
+
const SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE = 2;
|
|
3496
|
+
const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 = 3;
|
|
3497
|
+
const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT = 4;
|
|
3498
|
+
const SPLAT_POST_DECODE_INSTRUCTION_STRIDE = 7;
|
|
3499
|
+
const SPLAT_POST_DECODE_MISSING_ARGUMENT = 65535;
|
|
3493
3500
|
const ATTRIBUTE_FORMAT_BYTES = {
|
|
3494
3501
|
f32: 4,
|
|
3495
3502
|
f16: 2,
|
|
@@ -3504,7 +3511,6 @@ const ATTRIBUTE_FORMAT_BYTES = {
|
|
|
3504
3511
|
u32: 4,
|
|
3505
3512
|
i32: 4
|
|
3506
3513
|
};
|
|
3507
|
-
const COMPONENT_TYPES = ["float", "vec2", "vec3", "vec4"];
|
|
3508
3514
|
class SplatPostDecodeShPatch {
|
|
3509
3515
|
/** @internal */
|
|
3510
3516
|
constructor(owner, coefficients) {
|
|
@@ -3528,19 +3534,34 @@ class SplatPostDecodeShValue {
|
|
|
3528
3534
|
let index = 0;
|
|
3529
3535
|
for (let degree = 1; degree <= 3; degree += 1) {
|
|
3530
3536
|
for (let order = -degree; order <= degree; order += 1) {
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
+
coefficients.push(
|
|
3538
|
+
this.owner.coerce(
|
|
3539
|
+
transform(this.coefficient(index), { index, degree, order }),
|
|
3540
|
+
"vec3"
|
|
3541
|
+
)
|
|
3542
|
+
);
|
|
3537
3543
|
index += 1;
|
|
3538
3544
|
}
|
|
3539
3545
|
}
|
|
3540
3546
|
return new SplatPostDecodeShPatch(this.owner, coefficients);
|
|
3541
3547
|
}
|
|
3542
3548
|
}
|
|
3549
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_START = 0;
|
|
3550
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION = 1;
|
|
3551
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_REGISTER = 2;
|
|
3552
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE = 3;
|
|
3553
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE = 4;
|
|
3554
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_STRIDE = 5;
|
|
3543
3555
|
const SPLAT_POST_DECODE_PROGRAM = Symbol("SplatPostDecodeProgram");
|
|
3556
|
+
const COMPONENT_TYPES = ["float", "vec2", "vec3", "vec4"];
|
|
3557
|
+
function inferLiteralType(value) {
|
|
3558
|
+
if (typeof value === "boolean") return "bool";
|
|
3559
|
+
if (typeof value === "number") return "float";
|
|
3560
|
+
if (Array.isArray(value) && value.length >= 2 && value.length <= 4) {
|
|
3561
|
+
return COMPONENT_TYPES[value.length - 1];
|
|
3562
|
+
}
|
|
3563
|
+
throw new Error("Unsupported postDecode literal");
|
|
3564
|
+
}
|
|
3544
3565
|
function constantKey(type, values) {
|
|
3545
3566
|
return `${type}:${values.map((value) => Object.is(value, -0) ? "-0" : value).join(":")}`;
|
|
3546
3567
|
}
|
|
@@ -3552,46 +3573,46 @@ class ProgramBuilder {
|
|
|
3552
3573
|
this.constantRegisters = /* @__PURE__ */ new Map();
|
|
3553
3574
|
this.inputRegisters = /* @__PURE__ */ new Map();
|
|
3554
3575
|
this.op = this.createOperations();
|
|
3555
|
-
const
|
|
3576
|
+
const builder = this;
|
|
3556
3577
|
const sh = new SplatPostDecodeShValue(this);
|
|
3557
3578
|
this.splat = {
|
|
3558
3579
|
get position() {
|
|
3559
|
-
return
|
|
3580
|
+
return builder.inputField(
|
|
3560
3581
|
"vec3",
|
|
3561
3582
|
1
|
|
3562
3583
|
/* Position */
|
|
3563
3584
|
);
|
|
3564
3585
|
},
|
|
3565
3586
|
get scale() {
|
|
3566
|
-
return
|
|
3587
|
+
return builder.inputField(
|
|
3567
3588
|
"vec3",
|
|
3568
3589
|
2
|
|
3569
3590
|
/* Scale */
|
|
3570
3591
|
);
|
|
3571
3592
|
},
|
|
3572
3593
|
get quaternion() {
|
|
3573
|
-
return
|
|
3594
|
+
return builder.inputField(
|
|
3574
3595
|
"quaternion",
|
|
3575
3596
|
3
|
|
3576
3597
|
/* Quaternion */
|
|
3577
3598
|
);
|
|
3578
3599
|
},
|
|
3579
3600
|
get opacity() {
|
|
3580
|
-
return
|
|
3601
|
+
return builder.inputField(
|
|
3581
3602
|
"float",
|
|
3582
3603
|
4
|
|
3583
3604
|
/* Opacity */
|
|
3584
3605
|
);
|
|
3585
3606
|
},
|
|
3586
3607
|
get alpha() {
|
|
3587
|
-
return
|
|
3608
|
+
return builder.inputField(
|
|
3588
3609
|
"float",
|
|
3589
3610
|
5
|
|
3590
3611
|
/* Alpha */
|
|
3591
3612
|
);
|
|
3592
3613
|
},
|
|
3593
3614
|
get color() {
|
|
3594
|
-
return
|
|
3615
|
+
return builder.inputField(
|
|
3595
3616
|
"vec3",
|
|
3596
3617
|
6
|
|
3597
3618
|
/* Color */
|
|
@@ -3600,9 +3621,17 @@ class ProgramBuilder {
|
|
|
3600
3621
|
sh
|
|
3601
3622
|
};
|
|
3602
3623
|
}
|
|
3624
|
+
instruction(type, opcode, args = [], immediate = 0) {
|
|
3625
|
+
if (this.instructions.length >= 4096) {
|
|
3626
|
+
throw new Error("postDecode program exceeds 4096 instructions");
|
|
3627
|
+
}
|
|
3628
|
+
const register = this.instructions.length;
|
|
3629
|
+
this.instructions.push({ opcode, type, args, immediate });
|
|
3630
|
+
return new SplatPostDecodeValue(type, register, this);
|
|
3631
|
+
}
|
|
3603
3632
|
inputField(type, field) {
|
|
3604
|
-
const
|
|
3605
|
-
if (
|
|
3633
|
+
const existing = this.inputRegisters.get(field);
|
|
3634
|
+
if (existing) return existing;
|
|
3606
3635
|
const value = this.instruction(type, 2, [], field);
|
|
3607
3636
|
this.inputRegisters.set(field, value);
|
|
3608
3637
|
return value;
|
|
@@ -3612,8 +3641,9 @@ class ProgramBuilder {
|
|
|
3612
3641
|
throw new Error("postDecode attribute data must be an ArrayBuffer view");
|
|
3613
3642
|
}
|
|
3614
3643
|
const componentBytes = ATTRIBUTE_FORMAT_BYTES[options.format];
|
|
3615
|
-
if (!componentBytes)
|
|
3644
|
+
if (!componentBytes) {
|
|
3616
3645
|
throw new Error(`Unknown postDecode format: ${options.format}`);
|
|
3646
|
+
}
|
|
3617
3647
|
const count = options.count;
|
|
3618
3648
|
const components = options.components ?? 1;
|
|
3619
3649
|
const byteOffset = options.byteOffset ?? 0;
|
|
@@ -3634,7 +3664,6 @@ class ProgramBuilder {
|
|
|
3634
3664
|
if (!Number.isSafeInteger(requiredBytes) || requiredBytes > options.data.byteLength) {
|
|
3635
3665
|
throw new Error("postDecode attribute data is too small");
|
|
3636
3666
|
}
|
|
3637
|
-
const type = COMPONENT_TYPES[components - 1];
|
|
3638
3667
|
const index = this.attributes.length;
|
|
3639
3668
|
this.attributes.push({
|
|
3640
3669
|
data: options.data,
|
|
@@ -3645,7 +3674,7 @@ class ProgramBuilder {
|
|
|
3645
3674
|
byteStride
|
|
3646
3675
|
});
|
|
3647
3676
|
return this.instruction(
|
|
3648
|
-
|
|
3677
|
+
COMPONENT_TYPES[components - 1],
|
|
3649
3678
|
3,
|
|
3650
3679
|
[],
|
|
3651
3680
|
index
|
|
@@ -3659,8 +3688,8 @@ class ProgramBuilder {
|
|
|
3659
3688
|
);
|
|
3660
3689
|
}
|
|
3661
3690
|
if (expectedType && value.type !== expectedType) {
|
|
3662
|
-
const
|
|
3663
|
-
if (!
|
|
3691
|
+
const vec4Quaternion = expectedType === "quaternion" && value.type === "vec4" || expectedType === "vec4" && value.type === "quaternion";
|
|
3692
|
+
if (!vec4Quaternion) {
|
|
3664
3693
|
throw new Error(`Expected ${expectedType}, received ${value.type}`);
|
|
3665
3694
|
}
|
|
3666
3695
|
}
|
|
@@ -3672,31 +3701,18 @@ class ProgramBuilder {
|
|
|
3672
3701
|
if (numeric.length !== width) {
|
|
3673
3702
|
throw new Error(`Expected ${width} values for ${type}`);
|
|
3674
3703
|
}
|
|
3675
|
-
const
|
|
3676
|
-
if (!
|
|
3704
|
+
const values = numeric.map(Math.fround);
|
|
3705
|
+
if (!values.every(Number.isFinite)) {
|
|
3677
3706
|
throw new Error("postDecode constants must be finite");
|
|
3678
3707
|
}
|
|
3679
|
-
const key = constantKey(type,
|
|
3680
|
-
const
|
|
3681
|
-
if (
|
|
3682
|
-
const
|
|
3683
|
-
this.constants.push(...
|
|
3684
|
-
const
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
[],
|
|
3688
|
-
constantBase
|
|
3689
|
-
);
|
|
3690
|
-
this.constantRegisters.set(key, constant);
|
|
3691
|
-
return constant;
|
|
3692
|
-
}
|
|
3693
|
-
instruction(type, opcode, args = [], immediate = 0) {
|
|
3694
|
-
if (this.instructions.length >= 4096) {
|
|
3695
|
-
throw new Error("postDecode program exceeds 4096 instructions");
|
|
3696
|
-
}
|
|
3697
|
-
const register = this.instructions.length;
|
|
3698
|
-
this.instructions.push({ opcode, type, args, immediate });
|
|
3699
|
-
return new SplatPostDecodeValue(type, register, this);
|
|
3708
|
+
const key = constantKey(type, values);
|
|
3709
|
+
const existing = this.constantRegisters.get(key);
|
|
3710
|
+
if (existing) return existing;
|
|
3711
|
+
const immediate = this.constants.length;
|
|
3712
|
+
this.constants.push(...values);
|
|
3713
|
+
const result = this.instruction(type, 1, [], immediate);
|
|
3714
|
+
this.constantRegisters.set(key, result);
|
|
3715
|
+
return result;
|
|
3700
3716
|
}
|
|
3701
3717
|
unary(opcode, value, outputType) {
|
|
3702
3718
|
const input = this.coerce(value);
|
|
@@ -3722,10 +3738,7 @@ class ProgramBuilder {
|
|
|
3722
3738
|
}
|
|
3723
3739
|
coerceForBinary(value, targetType) {
|
|
3724
3740
|
if (value instanceof SplatPostDecodeValue) {
|
|
3725
|
-
|
|
3726
|
-
return this.coerce(value);
|
|
3727
|
-
}
|
|
3728
|
-
return this.coerce(value, targetType);
|
|
3741
|
+
return value.type === "float" && TYPE_WIDTHS[targetType] > 1 ? this.coerce(value) : this.coerce(value, targetType);
|
|
3729
3742
|
}
|
|
3730
3743
|
return this.coerce(
|
|
3731
3744
|
value,
|
|
@@ -3734,26 +3747,31 @@ class ProgramBuilder {
|
|
|
3734
3747
|
}
|
|
3735
3748
|
createOperations() {
|
|
3736
3749
|
const reduceNumeric = (opcode) => (first, ...rest) => {
|
|
3737
|
-
let
|
|
3750
|
+
let result = this.coerce(first);
|
|
3738
3751
|
for (const right of rest) {
|
|
3739
|
-
|
|
3752
|
+
result = this.binary(
|
|
3753
|
+
opcode,
|
|
3754
|
+
result,
|
|
3755
|
+
right
|
|
3756
|
+
);
|
|
3740
3757
|
}
|
|
3741
|
-
return
|
|
3758
|
+
return result;
|
|
3742
3759
|
};
|
|
3743
3760
|
const binaryNumeric = (opcode) => (left, right) => this.binary(opcode, left, right);
|
|
3744
3761
|
const unaryNumeric = (opcode) => (value) => this.unary(opcode, value);
|
|
3745
3762
|
const compare = (opcode) => (left, right) => this.binary(opcode, left, right, "bool");
|
|
3746
3763
|
const reduceBoolean = (opcode) => (first, ...rest) => {
|
|
3747
|
-
let
|
|
3764
|
+
let result = this.coerce(first, "bool");
|
|
3748
3765
|
for (const right of rest) {
|
|
3749
|
-
|
|
3766
|
+
result = this.binary(opcode, result, right, "bool");
|
|
3750
3767
|
}
|
|
3751
|
-
return
|
|
3752
|
-
};
|
|
3753
|
-
const construct = (opcode, type, values) => {
|
|
3754
|
-
const args = values.map((value) => this.coerce(value, "float").register);
|
|
3755
|
-
return this.instruction(type, opcode, args);
|
|
3768
|
+
return result;
|
|
3756
3769
|
};
|
|
3770
|
+
const construct = (opcode, type, values) => this.instruction(
|
|
3771
|
+
type,
|
|
3772
|
+
opcode,
|
|
3773
|
+
values.map((value) => this.coerce(value, "float").register)
|
|
3774
|
+
);
|
|
3757
3775
|
return {
|
|
3758
3776
|
add: reduceNumeric(
|
|
3759
3777
|
30
|
|
@@ -3784,12 +3802,7 @@ class ProgramBuilder {
|
|
|
3784
3802
|
/* Pow */
|
|
3785
3803
|
),
|
|
3786
3804
|
clamp: (value, min, max) => this.ternary(61, value, min, max),
|
|
3787
|
-
mix: (left, right, amount) => this.ternary(
|
|
3788
|
-
62,
|
|
3789
|
-
left,
|
|
3790
|
-
right,
|
|
3791
|
-
amount
|
|
3792
|
-
),
|
|
3805
|
+
mix: (left, right, amount) => this.ternary(62, left, right, amount),
|
|
3793
3806
|
neg: unaryNumeric(
|
|
3794
3807
|
10
|
|
3795
3808
|
/* Negate */
|
|
@@ -3834,6 +3847,22 @@ class ProgramBuilder {
|
|
|
3834
3847
|
25
|
|
3835
3848
|
/* Acos */
|
|
3836
3849
|
),
|
|
3850
|
+
tan: unaryNumeric(
|
|
3851
|
+
26
|
|
3852
|
+
/* Tan */
|
|
3853
|
+
),
|
|
3854
|
+
asin: unaryNumeric(
|
|
3855
|
+
27
|
|
3856
|
+
/* Asin */
|
|
3857
|
+
),
|
|
3858
|
+
atan: unaryNumeric(
|
|
3859
|
+
28
|
|
3860
|
+
/* Atan */
|
|
3861
|
+
),
|
|
3862
|
+
atan2: binaryNumeric(
|
|
3863
|
+
49
|
|
3864
|
+
/* Atan2 */
|
|
3865
|
+
),
|
|
3837
3866
|
normalize: (value) => this.unary(18, value),
|
|
3838
3867
|
length: (value) => this.unary(19, value, "float"),
|
|
3839
3868
|
isFinite: (value) => this.unary(20, value, "bool"),
|
|
@@ -3879,12 +3908,7 @@ class ProgramBuilder {
|
|
|
3879
3908
|
falseValue.register
|
|
3880
3909
|
]);
|
|
3881
3910
|
},
|
|
3882
|
-
dot: (left, right) => this.binary(
|
|
3883
|
-
37,
|
|
3884
|
-
left,
|
|
3885
|
-
right,
|
|
3886
|
-
"float"
|
|
3887
|
-
),
|
|
3911
|
+
dot: (left, right) => this.binary(37, left, right, "float"),
|
|
3888
3912
|
cross: (left, right) => this.binary(38, left, right),
|
|
3889
3913
|
vec2: (x, y) => construct(70, "vec2", [x, y]),
|
|
3890
3914
|
vec3: (x, y, z) => construct(71, "vec3", [x, y, z]),
|
|
@@ -3902,210 +3926,451 @@ class ProgramBuilder {
|
|
|
3902
3926
|
index
|
|
3903
3927
|
);
|
|
3904
3928
|
},
|
|
3905
|
-
maxComponentIndex: (value) => this.unary(
|
|
3906
|
-
75,
|
|
3907
|
-
value,
|
|
3908
|
-
"float"
|
|
3909
|
-
),
|
|
3929
|
+
maxComponentIndex: (value) => this.unary(75, value, "float"),
|
|
3910
3930
|
quatMul: (left, right) => {
|
|
3911
|
-
const
|
|
3912
|
-
const
|
|
3931
|
+
const a = this.coerce(left, "quaternion");
|
|
3932
|
+
const b = this.coerce(right, "quaternion");
|
|
3913
3933
|
return this.instruction("quaternion", 47, [
|
|
3914
|
-
|
|
3915
|
-
|
|
3934
|
+
a.register,
|
|
3935
|
+
b.register
|
|
3916
3936
|
]);
|
|
3917
3937
|
},
|
|
3918
3938
|
rotateVector: (quaternion, vector) => {
|
|
3919
|
-
const
|
|
3920
|
-
const
|
|
3939
|
+
const q = this.coerce(quaternion, "quaternion");
|
|
3940
|
+
const v = this.coerce(vector, "vec3");
|
|
3921
3941
|
return this.instruction("vec3", 48, [
|
|
3922
|
-
|
|
3923
|
-
|
|
3942
|
+
q.register,
|
|
3943
|
+
v.register
|
|
3924
3944
|
]);
|
|
3925
3945
|
}
|
|
3926
3946
|
};
|
|
3927
3947
|
}
|
|
3928
3948
|
}
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3949
|
+
class GenerationRegisterMap {
|
|
3950
|
+
constructor(size) {
|
|
3951
|
+
this.generation = 1;
|
|
3952
|
+
this.values = new Int32Array(size);
|
|
3953
|
+
this.generations = new Uint32Array(size);
|
|
3954
|
+
}
|
|
3955
|
+
clear() {
|
|
3956
|
+
if (this.generation === 4294967295) {
|
|
3957
|
+
this.generations.fill(0);
|
|
3958
|
+
this.generation = 1;
|
|
3959
|
+
} else {
|
|
3960
|
+
this.generation += 1;
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
has(source) {
|
|
3964
|
+
return this.generations[source] === this.generation;
|
|
3965
|
+
}
|
|
3966
|
+
get(source) {
|
|
3967
|
+
return this.has(source) ? this.values[source] : void 0;
|
|
3968
|
+
}
|
|
3969
|
+
set(source, target) {
|
|
3970
|
+
this.generations[source] = this.generation;
|
|
3971
|
+
this.values[source] = target;
|
|
3972
|
+
}
|
|
3973
|
+
delete(source) {
|
|
3974
|
+
this.generations[source] = 0;
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3977
|
+
function markDependencies(builder, roots, marked) {
|
|
3978
|
+
const pending = [];
|
|
3979
|
+
for (const root of roots) {
|
|
3980
|
+
if (root === void 0 || marked[root]) continue;
|
|
3981
|
+
marked[root] = 1;
|
|
3982
|
+
pending.push(root);
|
|
3983
|
+
}
|
|
3984
|
+
while (pending.length !== 0) {
|
|
3985
|
+
const register = pending.pop();
|
|
3986
|
+
if (register === void 0) break;
|
|
3987
|
+
for (const argument of builder.instructions[register].args) {
|
|
3988
|
+
if (marked[argument]) continue;
|
|
3989
|
+
marked[argument] = 1;
|
|
3990
|
+
pending.push(argument);
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
class InstructionSerializer {
|
|
3995
|
+
constructor(builder) {
|
|
3996
|
+
this.builder = builder;
|
|
3997
|
+
this.instructions = [];
|
|
3998
|
+
this.constants = [];
|
|
3999
|
+
this.attributes = [];
|
|
4000
|
+
this.constantMap = /* @__PURE__ */ new Map();
|
|
4001
|
+
this.attributeMap = /* @__PURE__ */ new Map();
|
|
4002
|
+
this.dependencyGeneration = 0;
|
|
4003
|
+
this.dependencyMarks = new Uint32Array(builder.instructions.length);
|
|
4004
|
+
}
|
|
4005
|
+
appendDependencies(roots, registers, forceRoots = false) {
|
|
4006
|
+
if (forceRoots) {
|
|
4007
|
+
for (const root of roots) {
|
|
4008
|
+
if (root !== void 0 && this.builder.instructions[root].opcode !== 1) {
|
|
4009
|
+
registers.delete(root);
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
this.dependencyGeneration += 1;
|
|
4014
|
+
const generation = this.dependencyGeneration;
|
|
4015
|
+
const pending = [];
|
|
4016
|
+
const sourceOrder = [];
|
|
4017
|
+
for (const root of roots) {
|
|
4018
|
+
if (root !== void 0 && !registers.has(root)) pending.push(root);
|
|
4019
|
+
}
|
|
4020
|
+
while (pending.length !== 0) {
|
|
4021
|
+
const source = pending.pop();
|
|
4022
|
+
if (source === void 0 || registers.has(source) || this.dependencyMarks[source] === generation) {
|
|
4023
|
+
continue;
|
|
4024
|
+
}
|
|
4025
|
+
this.dependencyMarks[source] = generation;
|
|
4026
|
+
sourceOrder.push(source);
|
|
4027
|
+
for (const argument of this.builder.instructions[source].args) {
|
|
4028
|
+
if (!registers.has(argument)) pending.push(argument);
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
sourceOrder.sort((left, right) => left - right);
|
|
4032
|
+
this.append(sourceOrder, registers);
|
|
4033
|
+
return registers;
|
|
4034
|
+
}
|
|
4035
|
+
append(sourceOrder, registers) {
|
|
4036
|
+
for (const sourceIndex of sourceOrder) {
|
|
4037
|
+
const source = this.builder.instructions[sourceIndex];
|
|
4038
|
+
if (source.opcode === 1) {
|
|
4039
|
+
let target = this.constantMap.get(sourceIndex);
|
|
4040
|
+
if (target === void 0) {
|
|
4041
|
+
this.reserveInstruction();
|
|
4042
|
+
target = this.instructions.length;
|
|
4043
|
+
this.constantMap.set(sourceIndex, target);
|
|
4044
|
+
const immediate2 = this.constants.length;
|
|
4045
|
+
this.constants.push(
|
|
4046
|
+
...this.builder.constants.slice(
|
|
4047
|
+
source.immediate,
|
|
4048
|
+
source.immediate + TYPE_WIDTHS[source.type]
|
|
4049
|
+
)
|
|
4050
|
+
);
|
|
4051
|
+
this.instructions.push({ ...source, immediate: immediate2 });
|
|
4052
|
+
}
|
|
4053
|
+
registers.set(sourceIndex, target);
|
|
4054
|
+
continue;
|
|
4055
|
+
}
|
|
4056
|
+
this.reserveInstruction();
|
|
4057
|
+
let immediate = source.immediate;
|
|
4058
|
+
if (source.opcode === 3) {
|
|
4059
|
+
let target = this.attributeMap.get(immediate);
|
|
4060
|
+
if (target === void 0) {
|
|
4061
|
+
target = this.attributes.length;
|
|
4062
|
+
this.attributeMap.set(immediate, target);
|
|
4063
|
+
this.attributes.push(this.builder.attributes[immediate]);
|
|
4064
|
+
}
|
|
4065
|
+
immediate = target;
|
|
4066
|
+
}
|
|
4067
|
+
const args = source.args.map((argument) => {
|
|
4068
|
+
const target = registers.get(argument);
|
|
4069
|
+
if (target === void 0) {
|
|
4070
|
+
throw new Error("Invalid postDecode instruction dependency");
|
|
4071
|
+
}
|
|
4072
|
+
return target;
|
|
4073
|
+
});
|
|
4074
|
+
registers.set(sourceIndex, this.instructions.length);
|
|
4075
|
+
this.instructions.push({ ...source, args, immediate });
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
reserveInstruction() {
|
|
4079
|
+
if (this.instructions.length >= 4096) {
|
|
4080
|
+
throw new Error("postDecode compiled program exceeds 4096 instructions");
|
|
4081
|
+
}
|
|
3936
4082
|
}
|
|
3937
|
-
throw new Error("Unsupported postDecode literal");
|
|
3938
4083
|
}
|
|
3939
|
-
function
|
|
4084
|
+
function emptyCompiledProgram() {
|
|
4085
|
+
return {
|
|
4086
|
+
instructions: [],
|
|
4087
|
+
constants: [],
|
|
4088
|
+
outputs: {},
|
|
4089
|
+
condition: void 0,
|
|
4090
|
+
attributes: []
|
|
4091
|
+
};
|
|
4092
|
+
}
|
|
4093
|
+
function remapOutputs(outputs, registers) {
|
|
3940
4094
|
var _a2;
|
|
4095
|
+
const remap = (register) => register === void 0 ? void 0 : registers.get(register);
|
|
4096
|
+
return {
|
|
4097
|
+
position: remap(outputs.position),
|
|
4098
|
+
scale: remap(outputs.scale),
|
|
4099
|
+
quaternion: remap(outputs.quaternion),
|
|
4100
|
+
opacity: remap(outputs.opacity),
|
|
4101
|
+
alpha: remap(outputs.alpha),
|
|
4102
|
+
color: remap(outputs.color),
|
|
4103
|
+
sh: (_a2 = outputs.sh) == null ? void 0 : _a2.map((register) => {
|
|
4104
|
+
const target = registers.get(register);
|
|
4105
|
+
if (target === void 0) {
|
|
4106
|
+
throw new Error("Invalid postDecode output dependency");
|
|
4107
|
+
}
|
|
4108
|
+
return target;
|
|
4109
|
+
})
|
|
4110
|
+
};
|
|
4111
|
+
}
|
|
4112
|
+
function compileConditionFlow(builder, outputs, outputRoots, whenRegister) {
|
|
4113
|
+
const FLOW_ACCEPT = -1;
|
|
4114
|
+
const FLOW_REJECT = -2;
|
|
4115
|
+
const FLOW_DYNAMIC = 0;
|
|
4116
|
+
const FLOW_CONSTANT_FALSE = 1;
|
|
4117
|
+
const FLOW_CONSTANT_TRUE = 2;
|
|
4118
|
+
const constantValues = new Uint8Array(whenRegister + 1);
|
|
4119
|
+
for (let register2 = 0; register2 <= whenRegister; register2 += 1) {
|
|
4120
|
+
const instruction = builder.instructions[register2];
|
|
4121
|
+
if (instruction.opcode === 1 && instruction.type === "bool") {
|
|
4122
|
+
constantValues[register2] = builder.constants[instruction.immediate] ? FLOW_CONSTANT_TRUE : FLOW_CONSTANT_FALSE;
|
|
4123
|
+
continue;
|
|
4124
|
+
}
|
|
4125
|
+
const left = constantValues[instruction.args[0]];
|
|
4126
|
+
if (instruction.opcode === 22) {
|
|
4127
|
+
constantValues[register2] = left === FLOW_CONSTANT_TRUE ? FLOW_CONSTANT_FALSE : left === FLOW_CONSTANT_FALSE ? FLOW_CONSTANT_TRUE : FLOW_DYNAMIC;
|
|
4128
|
+
} else if (instruction.opcode === 45) {
|
|
4129
|
+
const right = constantValues[instruction.args[1]];
|
|
4130
|
+
constantValues[register2] = left === FLOW_CONSTANT_FALSE || right === FLOW_CONSTANT_FALSE ? FLOW_CONSTANT_FALSE : left === FLOW_CONSTANT_TRUE && right === FLOW_CONSTANT_TRUE ? FLOW_CONSTANT_TRUE : FLOW_DYNAMIC;
|
|
4131
|
+
} else if (instruction.opcode === 46) {
|
|
4132
|
+
const right = constantValues[instruction.args[1]];
|
|
4133
|
+
constantValues[register2] = left === FLOW_CONSTANT_TRUE || right === FLOW_CONSTANT_TRUE ? FLOW_CONSTANT_TRUE : left === FLOW_CONSTANT_FALSE && right === FLOW_CONSTANT_FALSE ? FLOW_CONSTANT_FALSE : FLOW_DYNAMIC;
|
|
4134
|
+
}
|
|
4135
|
+
}
|
|
4136
|
+
const reverseNodes = [];
|
|
4137
|
+
const FLOW_AND_LEFT = 0;
|
|
4138
|
+
const FLOW_OR_LEFT = 1;
|
|
4139
|
+
const FLOW_CONTINUATION_SIZE = 3;
|
|
4140
|
+
let continuations;
|
|
4141
|
+
let continuationEnd = 0;
|
|
4142
|
+
let register = whenRegister;
|
|
4143
|
+
let onTrue = FLOW_ACCEPT;
|
|
4144
|
+
let onFalse = FLOW_REJECT;
|
|
4145
|
+
let compiledTarget = FLOW_REJECT;
|
|
4146
|
+
while (true) {
|
|
4147
|
+
const constant = constantValues[register];
|
|
4148
|
+
if (constant !== FLOW_DYNAMIC) {
|
|
4149
|
+
compiledTarget = constant === FLOW_CONSTANT_TRUE ? onTrue : onFalse;
|
|
4150
|
+
} else {
|
|
4151
|
+
const instruction = builder.instructions[register];
|
|
4152
|
+
if (instruction.opcode === 22) {
|
|
4153
|
+
register = instruction.args[0];
|
|
4154
|
+
const target2 = onTrue;
|
|
4155
|
+
onTrue = onFalse;
|
|
4156
|
+
onFalse = target2;
|
|
4157
|
+
continue;
|
|
4158
|
+
}
|
|
4159
|
+
if (instruction.opcode === 45 || instruction.opcode === 46) {
|
|
4160
|
+
continuations ?? (continuations = new Int32Array(
|
|
4161
|
+
(whenRegister + 1) * FLOW_CONTINUATION_SIZE
|
|
4162
|
+
));
|
|
4163
|
+
if (continuationEnd === continuations.length) {
|
|
4164
|
+
throw new Error("Invalid postDecode condition depth");
|
|
4165
|
+
}
|
|
4166
|
+
const isAnd = instruction.opcode === 45;
|
|
4167
|
+
continuations[continuationEnd] = isAnd ? FLOW_AND_LEFT : FLOW_OR_LEFT;
|
|
4168
|
+
continuations[continuationEnd + 1] = instruction.args[0];
|
|
4169
|
+
continuations[continuationEnd + 2] = isAnd ? onFalse : onTrue;
|
|
4170
|
+
continuationEnd += FLOW_CONTINUATION_SIZE;
|
|
4171
|
+
register = instruction.args[1];
|
|
4172
|
+
continue;
|
|
4173
|
+
}
|
|
4174
|
+
if (reverseNodes.length >= 4096) {
|
|
4175
|
+
throw new Error("postDecode condition exceeds 4096 flow nodes");
|
|
4176
|
+
}
|
|
4177
|
+
compiledTarget = reverseNodes.length;
|
|
4178
|
+
reverseNodes.push({ register, onTrue, onFalse });
|
|
4179
|
+
}
|
|
4180
|
+
if (continuationEnd === 0) break;
|
|
4181
|
+
continuationEnd -= FLOW_CONTINUATION_SIZE;
|
|
4182
|
+
if (!continuations) {
|
|
4183
|
+
throw new Error("Invalid postDecode condition continuation");
|
|
4184
|
+
}
|
|
4185
|
+
const type = continuations[continuationEnd];
|
|
4186
|
+
register = continuations[continuationEnd + 1];
|
|
4187
|
+
const target = continuations[continuationEnd + 2];
|
|
4188
|
+
if (type === FLOW_AND_LEFT) {
|
|
4189
|
+
onTrue = compiledTarget;
|
|
4190
|
+
onFalse = target;
|
|
4191
|
+
} else {
|
|
4192
|
+
onTrue = target;
|
|
4193
|
+
onFalse = compiledTarget;
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
const entry = compiledTarget;
|
|
4197
|
+
if (entry === FLOW_REJECT) return emptyCompiledProgram();
|
|
4198
|
+
if (entry === FLOW_ACCEPT) {
|
|
4199
|
+
outputs.when = void 0;
|
|
4200
|
+
return void 0;
|
|
4201
|
+
}
|
|
4202
|
+
const stageCount = reverseNodes.length;
|
|
4203
|
+
if (entry !== stageCount - 1) {
|
|
4204
|
+
throw new Error("Invalid postDecode condition flow");
|
|
4205
|
+
}
|
|
4206
|
+
const acceptTarget = stageCount;
|
|
4207
|
+
const rejectTarget = acceptTarget + 1;
|
|
4208
|
+
const stages = new Uint16Array(
|
|
4209
|
+
stageCount * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE
|
|
4210
|
+
);
|
|
4211
|
+
const predecessors = new Int32Array(stageCount).fill(-1);
|
|
4212
|
+
let acceptPredecessor = -1;
|
|
4213
|
+
const recordPredecessor = (target, predecessor) => {
|
|
4214
|
+
if (target === rejectTarget) return;
|
|
4215
|
+
if (target === acceptTarget) {
|
|
4216
|
+
acceptPredecessor = acceptPredecessor === -1 ? predecessor : acceptPredecessor === predecessor ? predecessor : -2;
|
|
4217
|
+
return;
|
|
4218
|
+
}
|
|
4219
|
+
predecessors[target] = predecessors[target] === -1 ? predecessor : predecessors[target] === predecessor ? predecessor : -2;
|
|
4220
|
+
};
|
|
4221
|
+
const remapTarget = (target) => target === FLOW_ACCEPT ? acceptTarget : target === FLOW_REJECT ? rejectTarget : stageCount - 1 - target;
|
|
4222
|
+
for (let stage = 0; stage < stageCount; stage += 1) {
|
|
4223
|
+
const node = reverseNodes[stageCount - 1 - stage];
|
|
4224
|
+
const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;
|
|
4225
|
+
const onTrue2 = remapTarget(node.onTrue);
|
|
4226
|
+
const onFalse2 = remapTarget(node.onFalse);
|
|
4227
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE] = onTrue2;
|
|
4228
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE] = onFalse2;
|
|
4229
|
+
recordPredecessor(onTrue2, stage);
|
|
4230
|
+
recordPredecessor(onFalse2, stage);
|
|
4231
|
+
}
|
|
4232
|
+
const serializer = new InstructionSerializer(builder);
|
|
4233
|
+
const pathRegisters = new GenerationRegisterMap(builder.instructions.length);
|
|
4234
|
+
for (let stage = 0; stage < stageCount; stage += 1) {
|
|
4235
|
+
if (stage === 0 || predecessors[stage] !== stage - 1) {
|
|
4236
|
+
pathRegisters.clear();
|
|
4237
|
+
}
|
|
4238
|
+
const node = reverseNodes[stageCount - 1 - stage];
|
|
4239
|
+
const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;
|
|
4240
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_START] = serializer.instructions.length;
|
|
4241
|
+
serializer.appendDependencies([node.register], pathRegisters, true);
|
|
4242
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION] = serializer.instructions.length - 1;
|
|
4243
|
+
const predicateRegister = pathRegisters.get(node.register);
|
|
4244
|
+
if (predicateRegister === void 0) {
|
|
4245
|
+
throw new Error("Invalid postDecode condition register");
|
|
4246
|
+
}
|
|
4247
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_REGISTER] = predicateRegister;
|
|
4248
|
+
}
|
|
4249
|
+
if (acceptPredecessor !== stageCount - 1) pathRegisters.clear();
|
|
4250
|
+
serializer.appendDependencies(outputRoots, pathRegisters);
|
|
4251
|
+
return {
|
|
4252
|
+
instructions: serializer.instructions,
|
|
4253
|
+
constants: serializer.constants,
|
|
4254
|
+
outputs: remapOutputs(outputs, pathRegisters),
|
|
4255
|
+
condition: { mode: "flow", stages },
|
|
4256
|
+
attributes: serializer.attributes
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4259
|
+
function compileProgram(builder, sourceOutputs) {
|
|
3941
4260
|
const outputs = { ...sourceOutputs };
|
|
3942
4261
|
if (outputs.when !== void 0) {
|
|
3943
4262
|
const condition = builder.instructions[outputs.when];
|
|
3944
4263
|
if (condition.opcode === 1) {
|
|
3945
4264
|
if (builder.constants[condition.immediate] === 0) {
|
|
3946
|
-
return
|
|
3947
|
-
instructions: [],
|
|
3948
|
-
constants: [],
|
|
3949
|
-
outputs: {},
|
|
3950
|
-
attributes: []
|
|
3951
|
-
};
|
|
4265
|
+
return emptyCompiledProgram();
|
|
3952
4266
|
}
|
|
3953
4267
|
outputs.when = void 0;
|
|
3954
4268
|
}
|
|
3955
4269
|
}
|
|
3956
|
-
const
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
if (register === void 0) break;
|
|
3966
|
-
for (const argument of builder.instructions[register].args) {
|
|
3967
|
-
if (marked[argument]) continue;
|
|
3968
|
-
marked[argument] = 1;
|
|
3969
|
-
pending.push(argument);
|
|
3970
|
-
}
|
|
3971
|
-
}
|
|
3972
|
-
};
|
|
3973
|
-
const live = new Uint8Array(builder.instructions.length);
|
|
3974
|
-
markDependencies(
|
|
3975
|
-
[
|
|
3976
|
-
outputs.when,
|
|
3977
|
-
outputs.position,
|
|
3978
|
-
outputs.scale,
|
|
3979
|
-
outputs.quaternion,
|
|
3980
|
-
outputs.opacity,
|
|
3981
|
-
outputs.alpha,
|
|
3982
|
-
outputs.color,
|
|
3983
|
-
...outputs.sh ?? []
|
|
3984
|
-
],
|
|
3985
|
-
live
|
|
3986
|
-
);
|
|
3987
|
-
const conditionLive = new Uint8Array(builder.instructions.length);
|
|
4270
|
+
const outputRoots = [
|
|
4271
|
+
outputs.position,
|
|
4272
|
+
outputs.scale,
|
|
4273
|
+
outputs.quaternion,
|
|
4274
|
+
outputs.opacity,
|
|
4275
|
+
outputs.alpha,
|
|
4276
|
+
outputs.color,
|
|
4277
|
+
...outputs.sh ?? []
|
|
4278
|
+
];
|
|
3988
4279
|
if (outputs.when !== void 0) {
|
|
3989
|
-
|
|
4280
|
+
const flow = compileConditionFlow(
|
|
4281
|
+
builder,
|
|
4282
|
+
outputs,
|
|
4283
|
+
outputRoots,
|
|
4284
|
+
outputs.when
|
|
4285
|
+
);
|
|
4286
|
+
if (flow) return flow;
|
|
3990
4287
|
}
|
|
4288
|
+
const live = new Uint8Array(builder.instructions.length);
|
|
4289
|
+
markDependencies(builder, outputRoots, live);
|
|
3991
4290
|
const instructionOrder = [];
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
if (live[index] && !conditionLive[index]) instructionOrder.push(index);
|
|
3999
|
-
}
|
|
4000
|
-
const registerMap = new Int32Array(builder.instructions.length).fill(-1);
|
|
4001
|
-
for (let index = 0; index < instructionOrder.length; index += 1) {
|
|
4002
|
-
registerMap[instructionOrder[index]] = index;
|
|
4003
|
-
}
|
|
4004
|
-
const constants = [];
|
|
4005
|
-
const attributes = [];
|
|
4006
|
-
const attributeMap = /* @__PURE__ */ new Map();
|
|
4007
|
-
const instructions = instructionOrder.map((sourceIndex) => {
|
|
4008
|
-
const instruction = builder.instructions[sourceIndex];
|
|
4009
|
-
let immediate = instruction.immediate;
|
|
4010
|
-
if (instruction.opcode === 1) {
|
|
4011
|
-
immediate = constants.length;
|
|
4012
|
-
constants.push(
|
|
4013
|
-
...builder.constants.slice(
|
|
4014
|
-
instruction.immediate,
|
|
4015
|
-
instruction.immediate + TYPE_WIDTHS[instruction.type]
|
|
4016
|
-
)
|
|
4017
|
-
);
|
|
4018
|
-
} else if (instruction.opcode === 3) {
|
|
4019
|
-
let mapped = attributeMap.get(instruction.immediate);
|
|
4020
|
-
if (mapped === void 0) {
|
|
4021
|
-
mapped = attributes.length;
|
|
4022
|
-
attributeMap.set(instruction.immediate, mapped);
|
|
4023
|
-
attributes.push(builder.attributes[instruction.immediate]);
|
|
4024
|
-
}
|
|
4025
|
-
immediate = mapped;
|
|
4026
|
-
}
|
|
4027
|
-
return {
|
|
4028
|
-
...instruction,
|
|
4029
|
-
args: instruction.args.map((argument) => registerMap[argument]),
|
|
4030
|
-
immediate
|
|
4031
|
-
};
|
|
4032
|
-
});
|
|
4033
|
-
const remap = (register) => register === void 0 ? void 0 : registerMap[register];
|
|
4291
|
+
for (let register = 0; register < live.length; register += 1) {
|
|
4292
|
+
if (live[register]) instructionOrder.push(register);
|
|
4293
|
+
}
|
|
4294
|
+
const serializer = new InstructionSerializer(builder);
|
|
4295
|
+
const registers = new GenerationRegisterMap(builder.instructions.length);
|
|
4296
|
+
serializer.append(instructionOrder, registers);
|
|
4034
4297
|
return {
|
|
4035
|
-
instructions,
|
|
4036
|
-
constants,
|
|
4037
|
-
outputs:
|
|
4038
|
-
|
|
4039
|
-
position: remap(outputs.position),
|
|
4040
|
-
scale: remap(outputs.scale),
|
|
4041
|
-
quaternion: remap(outputs.quaternion),
|
|
4042
|
-
opacity: remap(outputs.opacity),
|
|
4043
|
-
alpha: remap(outputs.alpha),
|
|
4044
|
-
color: remap(outputs.color),
|
|
4045
|
-
sh: (_a2 = outputs.sh) == null ? void 0 : _a2.map((register) => registerMap[register])
|
|
4046
|
-
},
|
|
4047
|
-
attributes
|
|
4298
|
+
instructions: serializer.instructions,
|
|
4299
|
+
constants: serializer.constants,
|
|
4300
|
+
outputs: remapOutputs(outputs, registers),
|
|
4301
|
+
attributes: serializer.attributes
|
|
4048
4302
|
};
|
|
4049
4303
|
}
|
|
4050
|
-
|
|
4051
|
-
const
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
const
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
const
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4304
|
+
function packInstructions(instructions) {
|
|
4305
|
+
const packed = new Uint16Array(
|
|
4306
|
+
instructions.length * SPLAT_POST_DECODE_INSTRUCTION_STRIDE
|
|
4307
|
+
);
|
|
4308
|
+
packed.fill(SPLAT_POST_DECODE_MISSING_ARGUMENT);
|
|
4309
|
+
for (let index = 0; index < instructions.length; index += 1) {
|
|
4310
|
+
const instruction = instructions[index];
|
|
4311
|
+
if (instruction.args.length > SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT || !Number.isInteger(instruction.immediate) || instruction.immediate < 0 || instruction.immediate > 65535 || instruction.args.some(
|
|
4312
|
+
(argument) => !Number.isInteger(argument) || argument < 0 || argument >= SPLAT_POST_DECODE_MISSING_ARGUMENT
|
|
4313
|
+
)) {
|
|
4314
|
+
throw new Error("postDecode instruction exceeds Uint16 bytecode limits");
|
|
4315
|
+
}
|
|
4316
|
+
const offset = index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;
|
|
4317
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE] = instruction.opcode;
|
|
4318
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH] = TYPE_WIDTHS[instruction.type];
|
|
4319
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE] = instruction.immediate;
|
|
4320
|
+
for (let argument = 0; argument < instruction.args.length; argument += 1) {
|
|
4321
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 + argument] = instruction.args[argument];
|
|
4322
|
+
}
|
|
4323
|
+
}
|
|
4324
|
+
return packed;
|
|
4325
|
+
}
|
|
4326
|
+
function snapshotAttributes(bindings) {
|
|
4327
|
+
const rangesByBuffer = /* @__PURE__ */ new Map();
|
|
4328
|
+
for (const binding of bindings) {
|
|
4329
|
+
if (binding.count === 0) continue;
|
|
4330
|
+
const packedBytes = ATTRIBUTE_FORMAT_BYTES[binding.format] * binding.components;
|
|
4331
|
+
const start = binding.data.byteOffset + binding.byteOffset;
|
|
4332
|
+
const end = start + (binding.count - 1) * binding.byteStride + packedBytes;
|
|
4333
|
+
const ranges = rangesByBuffer.get(binding.data.buffer) ?? [];
|
|
4334
|
+
ranges.push({ start, end });
|
|
4335
|
+
rangesByBuffer.set(binding.data.buffer, ranges);
|
|
4336
|
+
}
|
|
4337
|
+
const regions = [];
|
|
4338
|
+
const regionsByBuffer = /* @__PURE__ */ new Map();
|
|
4339
|
+
for (const [buffer, ranges] of rangesByBuffer) {
|
|
4340
|
+
ranges.sort((left, right) => left.start - right.start);
|
|
4341
|
+
const bufferRegions = [];
|
|
4342
|
+
for (const range of ranges) {
|
|
4343
|
+
const previous = bufferRegions[bufferRegions.length - 1];
|
|
4344
|
+
if (previous && range.start <= previous.end) {
|
|
4345
|
+
previous.end = Math.max(previous.end, range.end);
|
|
4346
|
+
} else {
|
|
4347
|
+
const region = { buffer, ...range, outputOffset: 0 };
|
|
4348
|
+
bufferRegions.push(region);
|
|
4349
|
+
regions.push(region);
|
|
4089
4350
|
}
|
|
4090
4351
|
}
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
)
|
|
4102
|
-
|
|
4103
|
-
|
|
4352
|
+
regionsByBuffer.set(buffer, bufferRegions);
|
|
4353
|
+
}
|
|
4354
|
+
let byteLength = 0;
|
|
4355
|
+
for (const region of regions) {
|
|
4356
|
+
region.outputOffset = byteLength;
|
|
4357
|
+
byteLength += region.end - region.start;
|
|
4358
|
+
}
|
|
4359
|
+
const data = new Uint8Array(byteLength);
|
|
4360
|
+
for (const region of regions) {
|
|
4361
|
+
data.set(
|
|
4362
|
+
new Uint8Array(region.buffer, region.start, region.end - region.start),
|
|
4363
|
+
region.outputOffset
|
|
4364
|
+
);
|
|
4365
|
+
}
|
|
4366
|
+
const attributes = bindings.map(
|
|
4367
|
+
(binding) => {
|
|
4368
|
+
var _a2;
|
|
4104
4369
|
let byteOffset = 0;
|
|
4105
|
-
if (
|
|
4106
|
-
const sourceOffset =
|
|
4107
|
-
const region =
|
|
4108
|
-
(candidate) =>
|
|
4370
|
+
if (binding.count !== 0) {
|
|
4371
|
+
const sourceOffset = binding.data.byteOffset + binding.byteOffset;
|
|
4372
|
+
const region = (_a2 = regionsByBuffer.get(binding.data.buffer)) == null ? void 0 : _a2.find(
|
|
4373
|
+
(candidate) => sourceOffset >= candidate.start && sourceOffset < candidate.end
|
|
4109
4374
|
);
|
|
4110
4375
|
if (!region) {
|
|
4111
4376
|
throw new Error("postDecode attribute view was not serialized");
|
|
@@ -4113,19 +4378,36 @@ const _SplatPostDecodeProgramImpl = class _SplatPostDecodeProgramImpl2 {
|
|
|
4113
4378
|
byteOffset = region.outputOffset + sourceOffset - region.start;
|
|
4114
4379
|
}
|
|
4115
4380
|
return {
|
|
4116
|
-
format:
|
|
4117
|
-
components:
|
|
4381
|
+
format: binding.format,
|
|
4382
|
+
components: binding.components,
|
|
4118
4383
|
byteOffset,
|
|
4119
|
-
byteStride:
|
|
4120
|
-
count:
|
|
4384
|
+
byteStride: binding.byteStride,
|
|
4385
|
+
count: binding.count
|
|
4121
4386
|
};
|
|
4122
|
-
}
|
|
4387
|
+
}
|
|
4388
|
+
);
|
|
4389
|
+
return { data, attributes };
|
|
4390
|
+
}
|
|
4391
|
+
_a = SPLAT_POST_DECODE_PROGRAM;
|
|
4392
|
+
const _SplatPostDecodeProgramImpl = class _SplatPostDecodeProgramImpl2 {
|
|
4393
|
+
constructor(builder, outputs) {
|
|
4394
|
+
this.builder = builder;
|
|
4395
|
+
this.outputs = outputs;
|
|
4396
|
+
this[_a] = true;
|
|
4397
|
+
}
|
|
4398
|
+
static serialize(program) {
|
|
4399
|
+
if (!(program instanceof _SplatPostDecodeProgramImpl2)) {
|
|
4400
|
+
throw new Error("Invalid postDecode program");
|
|
4401
|
+
}
|
|
4402
|
+
const compiled = compileProgram(program.builder, program.outputs);
|
|
4403
|
+
const snapshot = snapshotAttributes(compiled.attributes);
|
|
4123
4404
|
return {
|
|
4124
|
-
instructions,
|
|
4125
|
-
constants: new Float32Array(constants),
|
|
4126
|
-
outputs,
|
|
4127
|
-
|
|
4128
|
-
|
|
4405
|
+
instructions: packInstructions(compiled.instructions),
|
|
4406
|
+
constants: new Float32Array(compiled.constants),
|
|
4407
|
+
outputs: compiled.outputs,
|
|
4408
|
+
condition: compiled.condition,
|
|
4409
|
+
attributeData: snapshot.data,
|
|
4410
|
+
attributes: snapshot.attributes
|
|
4129
4411
|
};
|
|
4130
4412
|
}
|
|
4131
4413
|
};
|
|
@@ -4167,8 +4449,7 @@ function defineSplatPostDecode(build) {
|
|
|
4167
4449
|
if (!patch || typeof patch !== "object") {
|
|
4168
4450
|
throw new Error("postDecode builder must return a splat patch object");
|
|
4169
4451
|
}
|
|
4170
|
-
|
|
4171
|
-
return new SplatPostDecodeProgramImpl(builder, outputs);
|
|
4452
|
+
return new SplatPostDecodeProgramImpl(builder, buildOutputs(builder, patch));
|
|
4172
4453
|
}
|
|
4173
4454
|
const postDecode = {
|
|
4174
4455
|
define: defineSplatPostDecode
|