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
|
@@ -2464,7 +2464,7 @@ const QUAD_VERTICES = new Float32Array([
|
|
|
2464
2464
|
0
|
|
2465
2465
|
]);
|
|
2466
2466
|
const QUAD_INDICES = new Uint16Array([0, 1, 2, 0, 2, 3]);
|
|
2467
|
-
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';
|
|
2467
|
+
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';
|
|
2468
2468
|
const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
|
|
2469
2469
|
function WorkerWrapper(options) {
|
|
2470
2470
|
let objURL;
|
|
@@ -3508,6 +3508,13 @@ class SplatPostDecodeValue {
|
|
|
3508
3508
|
this.owner = owner;
|
|
3509
3509
|
}
|
|
3510
3510
|
}
|
|
3511
|
+
const SPLAT_POST_DECODE_INSTRUCTION_OPCODE = 0;
|
|
3512
|
+
const SPLAT_POST_DECODE_INSTRUCTION_WIDTH = 1;
|
|
3513
|
+
const SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE = 2;
|
|
3514
|
+
const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 = 3;
|
|
3515
|
+
const SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT = 4;
|
|
3516
|
+
const SPLAT_POST_DECODE_INSTRUCTION_STRIDE = 7;
|
|
3517
|
+
const SPLAT_POST_DECODE_MISSING_ARGUMENT = 65535;
|
|
3511
3518
|
const ATTRIBUTE_FORMAT_BYTES = {
|
|
3512
3519
|
f32: 4,
|
|
3513
3520
|
f16: 2,
|
|
@@ -3522,7 +3529,6 @@ const ATTRIBUTE_FORMAT_BYTES = {
|
|
|
3522
3529
|
u32: 4,
|
|
3523
3530
|
i32: 4
|
|
3524
3531
|
};
|
|
3525
|
-
const COMPONENT_TYPES = ["float", "vec2", "vec3", "vec4"];
|
|
3526
3532
|
class SplatPostDecodeShPatch {
|
|
3527
3533
|
/** @internal */
|
|
3528
3534
|
constructor(owner, coefficients) {
|
|
@@ -3546,19 +3552,34 @@ class SplatPostDecodeShValue {
|
|
|
3546
3552
|
let index = 0;
|
|
3547
3553
|
for (let degree = 1; degree <= 3; degree += 1) {
|
|
3548
3554
|
for (let order = -degree; order <= degree; order += 1) {
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
+
coefficients.push(
|
|
3556
|
+
this.owner.coerce(
|
|
3557
|
+
transform(this.coefficient(index), { index, degree, order }),
|
|
3558
|
+
"vec3"
|
|
3559
|
+
)
|
|
3560
|
+
);
|
|
3555
3561
|
index += 1;
|
|
3556
3562
|
}
|
|
3557
3563
|
}
|
|
3558
3564
|
return new SplatPostDecodeShPatch(this.owner, coefficients);
|
|
3559
3565
|
}
|
|
3560
3566
|
}
|
|
3567
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_START = 0;
|
|
3568
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION = 1;
|
|
3569
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_REGISTER = 2;
|
|
3570
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE = 3;
|
|
3571
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE = 4;
|
|
3572
|
+
const SPLAT_POST_DECODE_FLOW_STAGE_STRIDE = 5;
|
|
3561
3573
|
const SPLAT_POST_DECODE_PROGRAM = Symbol("SplatPostDecodeProgram");
|
|
3574
|
+
const COMPONENT_TYPES = ["float", "vec2", "vec3", "vec4"];
|
|
3575
|
+
function inferLiteralType(value) {
|
|
3576
|
+
if (typeof value === "boolean") return "bool";
|
|
3577
|
+
if (typeof value === "number") return "float";
|
|
3578
|
+
if (Array.isArray(value) && value.length >= 2 && value.length <= 4) {
|
|
3579
|
+
return COMPONENT_TYPES[value.length - 1];
|
|
3580
|
+
}
|
|
3581
|
+
throw new Error("Unsupported postDecode literal");
|
|
3582
|
+
}
|
|
3562
3583
|
function constantKey(type, values) {
|
|
3563
3584
|
return `${type}:${values.map((value) => Object.is(value, -0) ? "-0" : value).join(":")}`;
|
|
3564
3585
|
}
|
|
@@ -3570,46 +3591,46 @@ class ProgramBuilder {
|
|
|
3570
3591
|
this.constantRegisters = /* @__PURE__ */ new Map();
|
|
3571
3592
|
this.inputRegisters = /* @__PURE__ */ new Map();
|
|
3572
3593
|
this.op = this.createOperations();
|
|
3573
|
-
const
|
|
3594
|
+
const builder = this;
|
|
3574
3595
|
const sh = new SplatPostDecodeShValue(this);
|
|
3575
3596
|
this.splat = {
|
|
3576
3597
|
get position() {
|
|
3577
|
-
return
|
|
3598
|
+
return builder.inputField(
|
|
3578
3599
|
"vec3",
|
|
3579
3600
|
1
|
|
3580
3601
|
/* Position */
|
|
3581
3602
|
);
|
|
3582
3603
|
},
|
|
3583
3604
|
get scale() {
|
|
3584
|
-
return
|
|
3605
|
+
return builder.inputField(
|
|
3585
3606
|
"vec3",
|
|
3586
3607
|
2
|
|
3587
3608
|
/* Scale */
|
|
3588
3609
|
);
|
|
3589
3610
|
},
|
|
3590
3611
|
get quaternion() {
|
|
3591
|
-
return
|
|
3612
|
+
return builder.inputField(
|
|
3592
3613
|
"quaternion",
|
|
3593
3614
|
3
|
|
3594
3615
|
/* Quaternion */
|
|
3595
3616
|
);
|
|
3596
3617
|
},
|
|
3597
3618
|
get opacity() {
|
|
3598
|
-
return
|
|
3619
|
+
return builder.inputField(
|
|
3599
3620
|
"float",
|
|
3600
3621
|
4
|
|
3601
3622
|
/* Opacity */
|
|
3602
3623
|
);
|
|
3603
3624
|
},
|
|
3604
3625
|
get alpha() {
|
|
3605
|
-
return
|
|
3626
|
+
return builder.inputField(
|
|
3606
3627
|
"float",
|
|
3607
3628
|
5
|
|
3608
3629
|
/* Alpha */
|
|
3609
3630
|
);
|
|
3610
3631
|
},
|
|
3611
3632
|
get color() {
|
|
3612
|
-
return
|
|
3633
|
+
return builder.inputField(
|
|
3613
3634
|
"vec3",
|
|
3614
3635
|
6
|
|
3615
3636
|
/* Color */
|
|
@@ -3618,9 +3639,17 @@ class ProgramBuilder {
|
|
|
3618
3639
|
sh
|
|
3619
3640
|
};
|
|
3620
3641
|
}
|
|
3642
|
+
instruction(type, opcode, args = [], immediate = 0) {
|
|
3643
|
+
if (this.instructions.length >= 4096) {
|
|
3644
|
+
throw new Error("postDecode program exceeds 4096 instructions");
|
|
3645
|
+
}
|
|
3646
|
+
const register = this.instructions.length;
|
|
3647
|
+
this.instructions.push({ opcode, type, args, immediate });
|
|
3648
|
+
return new SplatPostDecodeValue(type, register, this);
|
|
3649
|
+
}
|
|
3621
3650
|
inputField(type, field) {
|
|
3622
|
-
const
|
|
3623
|
-
if (
|
|
3651
|
+
const existing = this.inputRegisters.get(field);
|
|
3652
|
+
if (existing) return existing;
|
|
3624
3653
|
const value = this.instruction(type, 2, [], field);
|
|
3625
3654
|
this.inputRegisters.set(field, value);
|
|
3626
3655
|
return value;
|
|
@@ -3630,8 +3659,9 @@ class ProgramBuilder {
|
|
|
3630
3659
|
throw new Error("postDecode attribute data must be an ArrayBuffer view");
|
|
3631
3660
|
}
|
|
3632
3661
|
const componentBytes = ATTRIBUTE_FORMAT_BYTES[options.format];
|
|
3633
|
-
if (!componentBytes)
|
|
3662
|
+
if (!componentBytes) {
|
|
3634
3663
|
throw new Error(`Unknown postDecode format: ${options.format}`);
|
|
3664
|
+
}
|
|
3635
3665
|
const count = options.count;
|
|
3636
3666
|
const components = options.components ?? 1;
|
|
3637
3667
|
const byteOffset = options.byteOffset ?? 0;
|
|
@@ -3652,7 +3682,6 @@ class ProgramBuilder {
|
|
|
3652
3682
|
if (!Number.isSafeInteger(requiredBytes) || requiredBytes > options.data.byteLength) {
|
|
3653
3683
|
throw new Error("postDecode attribute data is too small");
|
|
3654
3684
|
}
|
|
3655
|
-
const type = COMPONENT_TYPES[components - 1];
|
|
3656
3685
|
const index = this.attributes.length;
|
|
3657
3686
|
this.attributes.push({
|
|
3658
3687
|
data: options.data,
|
|
@@ -3663,7 +3692,7 @@ class ProgramBuilder {
|
|
|
3663
3692
|
byteStride
|
|
3664
3693
|
});
|
|
3665
3694
|
return this.instruction(
|
|
3666
|
-
|
|
3695
|
+
COMPONENT_TYPES[components - 1],
|
|
3667
3696
|
3,
|
|
3668
3697
|
[],
|
|
3669
3698
|
index
|
|
@@ -3677,8 +3706,8 @@ class ProgramBuilder {
|
|
|
3677
3706
|
);
|
|
3678
3707
|
}
|
|
3679
3708
|
if (expectedType && value.type !== expectedType) {
|
|
3680
|
-
const
|
|
3681
|
-
if (!
|
|
3709
|
+
const vec4Quaternion = expectedType === "quaternion" && value.type === "vec4" || expectedType === "vec4" && value.type === "quaternion";
|
|
3710
|
+
if (!vec4Quaternion) {
|
|
3682
3711
|
throw new Error(`Expected ${expectedType}, received ${value.type}`);
|
|
3683
3712
|
}
|
|
3684
3713
|
}
|
|
@@ -3690,31 +3719,18 @@ class ProgramBuilder {
|
|
|
3690
3719
|
if (numeric.length !== width) {
|
|
3691
3720
|
throw new Error(`Expected ${width} values for ${type}`);
|
|
3692
3721
|
}
|
|
3693
|
-
const
|
|
3694
|
-
if (!
|
|
3722
|
+
const values = numeric.map(Math.fround);
|
|
3723
|
+
if (!values.every(Number.isFinite)) {
|
|
3695
3724
|
throw new Error("postDecode constants must be finite");
|
|
3696
3725
|
}
|
|
3697
|
-
const key = constantKey(type,
|
|
3698
|
-
const
|
|
3699
|
-
if (
|
|
3700
|
-
const
|
|
3701
|
-
this.constants.push(...
|
|
3702
|
-
const
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
[],
|
|
3706
|
-
constantBase
|
|
3707
|
-
);
|
|
3708
|
-
this.constantRegisters.set(key, constant);
|
|
3709
|
-
return constant;
|
|
3710
|
-
}
|
|
3711
|
-
instruction(type, opcode, args = [], immediate = 0) {
|
|
3712
|
-
if (this.instructions.length >= 4096) {
|
|
3713
|
-
throw new Error("postDecode program exceeds 4096 instructions");
|
|
3714
|
-
}
|
|
3715
|
-
const register = this.instructions.length;
|
|
3716
|
-
this.instructions.push({ opcode, type, args, immediate });
|
|
3717
|
-
return new SplatPostDecodeValue(type, register, this);
|
|
3726
|
+
const key = constantKey(type, values);
|
|
3727
|
+
const existing = this.constantRegisters.get(key);
|
|
3728
|
+
if (existing) return existing;
|
|
3729
|
+
const immediate = this.constants.length;
|
|
3730
|
+
this.constants.push(...values);
|
|
3731
|
+
const result = this.instruction(type, 1, [], immediate);
|
|
3732
|
+
this.constantRegisters.set(key, result);
|
|
3733
|
+
return result;
|
|
3718
3734
|
}
|
|
3719
3735
|
unary(opcode, value, outputType) {
|
|
3720
3736
|
const input = this.coerce(value);
|
|
@@ -3740,10 +3756,7 @@ class ProgramBuilder {
|
|
|
3740
3756
|
}
|
|
3741
3757
|
coerceForBinary(value, targetType) {
|
|
3742
3758
|
if (value instanceof SplatPostDecodeValue) {
|
|
3743
|
-
|
|
3744
|
-
return this.coerce(value);
|
|
3745
|
-
}
|
|
3746
|
-
return this.coerce(value, targetType);
|
|
3759
|
+
return value.type === "float" && TYPE_WIDTHS[targetType] > 1 ? this.coerce(value) : this.coerce(value, targetType);
|
|
3747
3760
|
}
|
|
3748
3761
|
return this.coerce(
|
|
3749
3762
|
value,
|
|
@@ -3752,26 +3765,31 @@ class ProgramBuilder {
|
|
|
3752
3765
|
}
|
|
3753
3766
|
createOperations() {
|
|
3754
3767
|
const reduceNumeric = (opcode) => (first, ...rest) => {
|
|
3755
|
-
let
|
|
3768
|
+
let result = this.coerce(first);
|
|
3756
3769
|
for (const right of rest) {
|
|
3757
|
-
|
|
3770
|
+
result = this.binary(
|
|
3771
|
+
opcode,
|
|
3772
|
+
result,
|
|
3773
|
+
right
|
|
3774
|
+
);
|
|
3758
3775
|
}
|
|
3759
|
-
return
|
|
3776
|
+
return result;
|
|
3760
3777
|
};
|
|
3761
3778
|
const binaryNumeric = (opcode) => (left, right) => this.binary(opcode, left, right);
|
|
3762
3779
|
const unaryNumeric = (opcode) => (value) => this.unary(opcode, value);
|
|
3763
3780
|
const compare = (opcode) => (left, right) => this.binary(opcode, left, right, "bool");
|
|
3764
3781
|
const reduceBoolean = (opcode) => (first, ...rest) => {
|
|
3765
|
-
let
|
|
3782
|
+
let result = this.coerce(first, "bool");
|
|
3766
3783
|
for (const right of rest) {
|
|
3767
|
-
|
|
3784
|
+
result = this.binary(opcode, result, right, "bool");
|
|
3768
3785
|
}
|
|
3769
|
-
return
|
|
3770
|
-
};
|
|
3771
|
-
const construct = (opcode, type, values) => {
|
|
3772
|
-
const args = values.map((value) => this.coerce(value, "float").register);
|
|
3773
|
-
return this.instruction(type, opcode, args);
|
|
3786
|
+
return result;
|
|
3774
3787
|
};
|
|
3788
|
+
const construct = (opcode, type, values) => this.instruction(
|
|
3789
|
+
type,
|
|
3790
|
+
opcode,
|
|
3791
|
+
values.map((value) => this.coerce(value, "float").register)
|
|
3792
|
+
);
|
|
3775
3793
|
return {
|
|
3776
3794
|
add: reduceNumeric(
|
|
3777
3795
|
30
|
|
@@ -3802,12 +3820,7 @@ class ProgramBuilder {
|
|
|
3802
3820
|
/* Pow */
|
|
3803
3821
|
),
|
|
3804
3822
|
clamp: (value, min, max) => this.ternary(61, value, min, max),
|
|
3805
|
-
mix: (left, right, amount) => this.ternary(
|
|
3806
|
-
62,
|
|
3807
|
-
left,
|
|
3808
|
-
right,
|
|
3809
|
-
amount
|
|
3810
|
-
),
|
|
3823
|
+
mix: (left, right, amount) => this.ternary(62, left, right, amount),
|
|
3811
3824
|
neg: unaryNumeric(
|
|
3812
3825
|
10
|
|
3813
3826
|
/* Negate */
|
|
@@ -3852,6 +3865,22 @@ class ProgramBuilder {
|
|
|
3852
3865
|
25
|
|
3853
3866
|
/* Acos */
|
|
3854
3867
|
),
|
|
3868
|
+
tan: unaryNumeric(
|
|
3869
|
+
26
|
|
3870
|
+
/* Tan */
|
|
3871
|
+
),
|
|
3872
|
+
asin: unaryNumeric(
|
|
3873
|
+
27
|
|
3874
|
+
/* Asin */
|
|
3875
|
+
),
|
|
3876
|
+
atan: unaryNumeric(
|
|
3877
|
+
28
|
|
3878
|
+
/* Atan */
|
|
3879
|
+
),
|
|
3880
|
+
atan2: binaryNumeric(
|
|
3881
|
+
49
|
|
3882
|
+
/* Atan2 */
|
|
3883
|
+
),
|
|
3855
3884
|
normalize: (value) => this.unary(18, value),
|
|
3856
3885
|
length: (value) => this.unary(19, value, "float"),
|
|
3857
3886
|
isFinite: (value) => this.unary(20, value, "bool"),
|
|
@@ -3897,12 +3926,7 @@ class ProgramBuilder {
|
|
|
3897
3926
|
falseValue.register
|
|
3898
3927
|
]);
|
|
3899
3928
|
},
|
|
3900
|
-
dot: (left, right) => this.binary(
|
|
3901
|
-
37,
|
|
3902
|
-
left,
|
|
3903
|
-
right,
|
|
3904
|
-
"float"
|
|
3905
|
-
),
|
|
3929
|
+
dot: (left, right) => this.binary(37, left, right, "float"),
|
|
3906
3930
|
cross: (left, right) => this.binary(38, left, right),
|
|
3907
3931
|
vec2: (x, y) => construct(70, "vec2", [x, y]),
|
|
3908
3932
|
vec3: (x, y, z) => construct(71, "vec3", [x, y, z]),
|
|
@@ -3920,210 +3944,451 @@ class ProgramBuilder {
|
|
|
3920
3944
|
index
|
|
3921
3945
|
);
|
|
3922
3946
|
},
|
|
3923
|
-
maxComponentIndex: (value) => this.unary(
|
|
3924
|
-
75,
|
|
3925
|
-
value,
|
|
3926
|
-
"float"
|
|
3927
|
-
),
|
|
3947
|
+
maxComponentIndex: (value) => this.unary(75, value, "float"),
|
|
3928
3948
|
quatMul: (left, right) => {
|
|
3929
|
-
const
|
|
3930
|
-
const
|
|
3949
|
+
const a = this.coerce(left, "quaternion");
|
|
3950
|
+
const b = this.coerce(right, "quaternion");
|
|
3931
3951
|
return this.instruction("quaternion", 47, [
|
|
3932
|
-
|
|
3933
|
-
|
|
3952
|
+
a.register,
|
|
3953
|
+
b.register
|
|
3934
3954
|
]);
|
|
3935
3955
|
},
|
|
3936
3956
|
rotateVector: (quaternion, vector) => {
|
|
3937
|
-
const
|
|
3938
|
-
const
|
|
3957
|
+
const q = this.coerce(quaternion, "quaternion");
|
|
3958
|
+
const v = this.coerce(vector, "vec3");
|
|
3939
3959
|
return this.instruction("vec3", 48, [
|
|
3940
|
-
|
|
3941
|
-
|
|
3960
|
+
q.register,
|
|
3961
|
+
v.register
|
|
3942
3962
|
]);
|
|
3943
3963
|
}
|
|
3944
3964
|
};
|
|
3945
3965
|
}
|
|
3946
3966
|
}
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3967
|
+
class GenerationRegisterMap {
|
|
3968
|
+
constructor(size) {
|
|
3969
|
+
this.generation = 1;
|
|
3970
|
+
this.values = new Int32Array(size);
|
|
3971
|
+
this.generations = new Uint32Array(size);
|
|
3972
|
+
}
|
|
3973
|
+
clear() {
|
|
3974
|
+
if (this.generation === 4294967295) {
|
|
3975
|
+
this.generations.fill(0);
|
|
3976
|
+
this.generation = 1;
|
|
3977
|
+
} else {
|
|
3978
|
+
this.generation += 1;
|
|
3979
|
+
}
|
|
3980
|
+
}
|
|
3981
|
+
has(source) {
|
|
3982
|
+
return this.generations[source] === this.generation;
|
|
3983
|
+
}
|
|
3984
|
+
get(source) {
|
|
3985
|
+
return this.has(source) ? this.values[source] : void 0;
|
|
3986
|
+
}
|
|
3987
|
+
set(source, target) {
|
|
3988
|
+
this.generations[source] = this.generation;
|
|
3989
|
+
this.values[source] = target;
|
|
3990
|
+
}
|
|
3991
|
+
delete(source) {
|
|
3992
|
+
this.generations[source] = 0;
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
function markDependencies(builder, roots, marked) {
|
|
3996
|
+
const pending = [];
|
|
3997
|
+
for (const root of roots) {
|
|
3998
|
+
if (root === void 0 || marked[root]) continue;
|
|
3999
|
+
marked[root] = 1;
|
|
4000
|
+
pending.push(root);
|
|
4001
|
+
}
|
|
4002
|
+
while (pending.length !== 0) {
|
|
4003
|
+
const register = pending.pop();
|
|
4004
|
+
if (register === void 0) break;
|
|
4005
|
+
for (const argument of builder.instructions[register].args) {
|
|
4006
|
+
if (marked[argument]) continue;
|
|
4007
|
+
marked[argument] = 1;
|
|
4008
|
+
pending.push(argument);
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
class InstructionSerializer {
|
|
4013
|
+
constructor(builder) {
|
|
4014
|
+
this.builder = builder;
|
|
4015
|
+
this.instructions = [];
|
|
4016
|
+
this.constants = [];
|
|
4017
|
+
this.attributes = [];
|
|
4018
|
+
this.constantMap = /* @__PURE__ */ new Map();
|
|
4019
|
+
this.attributeMap = /* @__PURE__ */ new Map();
|
|
4020
|
+
this.dependencyGeneration = 0;
|
|
4021
|
+
this.dependencyMarks = new Uint32Array(builder.instructions.length);
|
|
4022
|
+
}
|
|
4023
|
+
appendDependencies(roots, registers, forceRoots = false) {
|
|
4024
|
+
if (forceRoots) {
|
|
4025
|
+
for (const root of roots) {
|
|
4026
|
+
if (root !== void 0 && this.builder.instructions[root].opcode !== 1) {
|
|
4027
|
+
registers.delete(root);
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
this.dependencyGeneration += 1;
|
|
4032
|
+
const generation = this.dependencyGeneration;
|
|
4033
|
+
const pending = [];
|
|
4034
|
+
const sourceOrder = [];
|
|
4035
|
+
for (const root of roots) {
|
|
4036
|
+
if (root !== void 0 && !registers.has(root)) pending.push(root);
|
|
4037
|
+
}
|
|
4038
|
+
while (pending.length !== 0) {
|
|
4039
|
+
const source = pending.pop();
|
|
4040
|
+
if (source === void 0 || registers.has(source) || this.dependencyMarks[source] === generation) {
|
|
4041
|
+
continue;
|
|
4042
|
+
}
|
|
4043
|
+
this.dependencyMarks[source] = generation;
|
|
4044
|
+
sourceOrder.push(source);
|
|
4045
|
+
for (const argument of this.builder.instructions[source].args) {
|
|
4046
|
+
if (!registers.has(argument)) pending.push(argument);
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4049
|
+
sourceOrder.sort((left, right) => left - right);
|
|
4050
|
+
this.append(sourceOrder, registers);
|
|
4051
|
+
return registers;
|
|
4052
|
+
}
|
|
4053
|
+
append(sourceOrder, registers) {
|
|
4054
|
+
for (const sourceIndex of sourceOrder) {
|
|
4055
|
+
const source = this.builder.instructions[sourceIndex];
|
|
4056
|
+
if (source.opcode === 1) {
|
|
4057
|
+
let target = this.constantMap.get(sourceIndex);
|
|
4058
|
+
if (target === void 0) {
|
|
4059
|
+
this.reserveInstruction();
|
|
4060
|
+
target = this.instructions.length;
|
|
4061
|
+
this.constantMap.set(sourceIndex, target);
|
|
4062
|
+
const immediate2 = this.constants.length;
|
|
4063
|
+
this.constants.push(
|
|
4064
|
+
...this.builder.constants.slice(
|
|
4065
|
+
source.immediate,
|
|
4066
|
+
source.immediate + TYPE_WIDTHS[source.type]
|
|
4067
|
+
)
|
|
4068
|
+
);
|
|
4069
|
+
this.instructions.push({ ...source, immediate: immediate2 });
|
|
4070
|
+
}
|
|
4071
|
+
registers.set(sourceIndex, target);
|
|
4072
|
+
continue;
|
|
4073
|
+
}
|
|
4074
|
+
this.reserveInstruction();
|
|
4075
|
+
let immediate = source.immediate;
|
|
4076
|
+
if (source.opcode === 3) {
|
|
4077
|
+
let target = this.attributeMap.get(immediate);
|
|
4078
|
+
if (target === void 0) {
|
|
4079
|
+
target = this.attributes.length;
|
|
4080
|
+
this.attributeMap.set(immediate, target);
|
|
4081
|
+
this.attributes.push(this.builder.attributes[immediate]);
|
|
4082
|
+
}
|
|
4083
|
+
immediate = target;
|
|
4084
|
+
}
|
|
4085
|
+
const args = source.args.map((argument) => {
|
|
4086
|
+
const target = registers.get(argument);
|
|
4087
|
+
if (target === void 0) {
|
|
4088
|
+
throw new Error("Invalid postDecode instruction dependency");
|
|
4089
|
+
}
|
|
4090
|
+
return target;
|
|
4091
|
+
});
|
|
4092
|
+
registers.set(sourceIndex, this.instructions.length);
|
|
4093
|
+
this.instructions.push({ ...source, args, immediate });
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
reserveInstruction() {
|
|
4097
|
+
if (this.instructions.length >= 4096) {
|
|
4098
|
+
throw new Error("postDecode compiled program exceeds 4096 instructions");
|
|
4099
|
+
}
|
|
3954
4100
|
}
|
|
3955
|
-
throw new Error("Unsupported postDecode literal");
|
|
3956
4101
|
}
|
|
3957
|
-
function
|
|
4102
|
+
function emptyCompiledProgram() {
|
|
4103
|
+
return {
|
|
4104
|
+
instructions: [],
|
|
4105
|
+
constants: [],
|
|
4106
|
+
outputs: {},
|
|
4107
|
+
condition: void 0,
|
|
4108
|
+
attributes: []
|
|
4109
|
+
};
|
|
4110
|
+
}
|
|
4111
|
+
function remapOutputs(outputs, registers) {
|
|
3958
4112
|
var _a2;
|
|
4113
|
+
const remap = (register) => register === void 0 ? void 0 : registers.get(register);
|
|
4114
|
+
return {
|
|
4115
|
+
position: remap(outputs.position),
|
|
4116
|
+
scale: remap(outputs.scale),
|
|
4117
|
+
quaternion: remap(outputs.quaternion),
|
|
4118
|
+
opacity: remap(outputs.opacity),
|
|
4119
|
+
alpha: remap(outputs.alpha),
|
|
4120
|
+
color: remap(outputs.color),
|
|
4121
|
+
sh: (_a2 = outputs.sh) == null ? void 0 : _a2.map((register) => {
|
|
4122
|
+
const target = registers.get(register);
|
|
4123
|
+
if (target === void 0) {
|
|
4124
|
+
throw new Error("Invalid postDecode output dependency");
|
|
4125
|
+
}
|
|
4126
|
+
return target;
|
|
4127
|
+
})
|
|
4128
|
+
};
|
|
4129
|
+
}
|
|
4130
|
+
function compileConditionFlow(builder, outputs, outputRoots, whenRegister) {
|
|
4131
|
+
const FLOW_ACCEPT = -1;
|
|
4132
|
+
const FLOW_REJECT = -2;
|
|
4133
|
+
const FLOW_DYNAMIC = 0;
|
|
4134
|
+
const FLOW_CONSTANT_FALSE = 1;
|
|
4135
|
+
const FLOW_CONSTANT_TRUE = 2;
|
|
4136
|
+
const constantValues = new Uint8Array(whenRegister + 1);
|
|
4137
|
+
for (let register2 = 0; register2 <= whenRegister; register2 += 1) {
|
|
4138
|
+
const instruction = builder.instructions[register2];
|
|
4139
|
+
if (instruction.opcode === 1 && instruction.type === "bool") {
|
|
4140
|
+
constantValues[register2] = builder.constants[instruction.immediate] ? FLOW_CONSTANT_TRUE : FLOW_CONSTANT_FALSE;
|
|
4141
|
+
continue;
|
|
4142
|
+
}
|
|
4143
|
+
const left = constantValues[instruction.args[0]];
|
|
4144
|
+
if (instruction.opcode === 22) {
|
|
4145
|
+
constantValues[register2] = left === FLOW_CONSTANT_TRUE ? FLOW_CONSTANT_FALSE : left === FLOW_CONSTANT_FALSE ? FLOW_CONSTANT_TRUE : FLOW_DYNAMIC;
|
|
4146
|
+
} else if (instruction.opcode === 45) {
|
|
4147
|
+
const right = constantValues[instruction.args[1]];
|
|
4148
|
+
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;
|
|
4149
|
+
} else if (instruction.opcode === 46) {
|
|
4150
|
+
const right = constantValues[instruction.args[1]];
|
|
4151
|
+
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;
|
|
4152
|
+
}
|
|
4153
|
+
}
|
|
4154
|
+
const reverseNodes = [];
|
|
4155
|
+
const FLOW_AND_LEFT = 0;
|
|
4156
|
+
const FLOW_OR_LEFT = 1;
|
|
4157
|
+
const FLOW_CONTINUATION_SIZE = 3;
|
|
4158
|
+
let continuations;
|
|
4159
|
+
let continuationEnd = 0;
|
|
4160
|
+
let register = whenRegister;
|
|
4161
|
+
let onTrue = FLOW_ACCEPT;
|
|
4162
|
+
let onFalse = FLOW_REJECT;
|
|
4163
|
+
let compiledTarget = FLOW_REJECT;
|
|
4164
|
+
while (true) {
|
|
4165
|
+
const constant = constantValues[register];
|
|
4166
|
+
if (constant !== FLOW_DYNAMIC) {
|
|
4167
|
+
compiledTarget = constant === FLOW_CONSTANT_TRUE ? onTrue : onFalse;
|
|
4168
|
+
} else {
|
|
4169
|
+
const instruction = builder.instructions[register];
|
|
4170
|
+
if (instruction.opcode === 22) {
|
|
4171
|
+
register = instruction.args[0];
|
|
4172
|
+
const target2 = onTrue;
|
|
4173
|
+
onTrue = onFalse;
|
|
4174
|
+
onFalse = target2;
|
|
4175
|
+
continue;
|
|
4176
|
+
}
|
|
4177
|
+
if (instruction.opcode === 45 || instruction.opcode === 46) {
|
|
4178
|
+
continuations ?? (continuations = new Int32Array(
|
|
4179
|
+
(whenRegister + 1) * FLOW_CONTINUATION_SIZE
|
|
4180
|
+
));
|
|
4181
|
+
if (continuationEnd === continuations.length) {
|
|
4182
|
+
throw new Error("Invalid postDecode condition depth");
|
|
4183
|
+
}
|
|
4184
|
+
const isAnd = instruction.opcode === 45;
|
|
4185
|
+
continuations[continuationEnd] = isAnd ? FLOW_AND_LEFT : FLOW_OR_LEFT;
|
|
4186
|
+
continuations[continuationEnd + 1] = instruction.args[0];
|
|
4187
|
+
continuations[continuationEnd + 2] = isAnd ? onFalse : onTrue;
|
|
4188
|
+
continuationEnd += FLOW_CONTINUATION_SIZE;
|
|
4189
|
+
register = instruction.args[1];
|
|
4190
|
+
continue;
|
|
4191
|
+
}
|
|
4192
|
+
if (reverseNodes.length >= 4096) {
|
|
4193
|
+
throw new Error("postDecode condition exceeds 4096 flow nodes");
|
|
4194
|
+
}
|
|
4195
|
+
compiledTarget = reverseNodes.length;
|
|
4196
|
+
reverseNodes.push({ register, onTrue, onFalse });
|
|
4197
|
+
}
|
|
4198
|
+
if (continuationEnd === 0) break;
|
|
4199
|
+
continuationEnd -= FLOW_CONTINUATION_SIZE;
|
|
4200
|
+
if (!continuations) {
|
|
4201
|
+
throw new Error("Invalid postDecode condition continuation");
|
|
4202
|
+
}
|
|
4203
|
+
const type = continuations[continuationEnd];
|
|
4204
|
+
register = continuations[continuationEnd + 1];
|
|
4205
|
+
const target = continuations[continuationEnd + 2];
|
|
4206
|
+
if (type === FLOW_AND_LEFT) {
|
|
4207
|
+
onTrue = compiledTarget;
|
|
4208
|
+
onFalse = target;
|
|
4209
|
+
} else {
|
|
4210
|
+
onTrue = target;
|
|
4211
|
+
onFalse = compiledTarget;
|
|
4212
|
+
}
|
|
4213
|
+
}
|
|
4214
|
+
const entry = compiledTarget;
|
|
4215
|
+
if (entry === FLOW_REJECT) return emptyCompiledProgram();
|
|
4216
|
+
if (entry === FLOW_ACCEPT) {
|
|
4217
|
+
outputs.when = void 0;
|
|
4218
|
+
return void 0;
|
|
4219
|
+
}
|
|
4220
|
+
const stageCount = reverseNodes.length;
|
|
4221
|
+
if (entry !== stageCount - 1) {
|
|
4222
|
+
throw new Error("Invalid postDecode condition flow");
|
|
4223
|
+
}
|
|
4224
|
+
const acceptTarget = stageCount;
|
|
4225
|
+
const rejectTarget = acceptTarget + 1;
|
|
4226
|
+
const stages = new Uint16Array(
|
|
4227
|
+
stageCount * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE
|
|
4228
|
+
);
|
|
4229
|
+
const predecessors = new Int32Array(stageCount).fill(-1);
|
|
4230
|
+
let acceptPredecessor = -1;
|
|
4231
|
+
const recordPredecessor = (target, predecessor) => {
|
|
4232
|
+
if (target === rejectTarget) return;
|
|
4233
|
+
if (target === acceptTarget) {
|
|
4234
|
+
acceptPredecessor = acceptPredecessor === -1 ? predecessor : acceptPredecessor === predecessor ? predecessor : -2;
|
|
4235
|
+
return;
|
|
4236
|
+
}
|
|
4237
|
+
predecessors[target] = predecessors[target] === -1 ? predecessor : predecessors[target] === predecessor ? predecessor : -2;
|
|
4238
|
+
};
|
|
4239
|
+
const remapTarget = (target) => target === FLOW_ACCEPT ? acceptTarget : target === FLOW_REJECT ? rejectTarget : stageCount - 1 - target;
|
|
4240
|
+
for (let stage = 0; stage < stageCount; stage += 1) {
|
|
4241
|
+
const node = reverseNodes[stageCount - 1 - stage];
|
|
4242
|
+
const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;
|
|
4243
|
+
const onTrue2 = remapTarget(node.onTrue);
|
|
4244
|
+
const onFalse2 = remapTarget(node.onFalse);
|
|
4245
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_TRUE] = onTrue2;
|
|
4246
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_ON_FALSE] = onFalse2;
|
|
4247
|
+
recordPredecessor(onTrue2, stage);
|
|
4248
|
+
recordPredecessor(onFalse2, stage);
|
|
4249
|
+
}
|
|
4250
|
+
const serializer = new InstructionSerializer(builder);
|
|
4251
|
+
const pathRegisters = new GenerationRegisterMap(builder.instructions.length);
|
|
4252
|
+
for (let stage = 0; stage < stageCount; stage += 1) {
|
|
4253
|
+
if (stage === 0 || predecessors[stage] !== stage - 1) {
|
|
4254
|
+
pathRegisters.clear();
|
|
4255
|
+
}
|
|
4256
|
+
const node = reverseNodes[stageCount - 1 - stage];
|
|
4257
|
+
const offset = stage * SPLAT_POST_DECODE_FLOW_STAGE_STRIDE;
|
|
4258
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_START] = serializer.instructions.length;
|
|
4259
|
+
serializer.appendDependencies([node.register], pathRegisters, true);
|
|
4260
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_INSTRUCTION] = serializer.instructions.length - 1;
|
|
4261
|
+
const predicateRegister = pathRegisters.get(node.register);
|
|
4262
|
+
if (predicateRegister === void 0) {
|
|
4263
|
+
throw new Error("Invalid postDecode condition register");
|
|
4264
|
+
}
|
|
4265
|
+
stages[offset + SPLAT_POST_DECODE_FLOW_STAGE_REGISTER] = predicateRegister;
|
|
4266
|
+
}
|
|
4267
|
+
if (acceptPredecessor !== stageCount - 1) pathRegisters.clear();
|
|
4268
|
+
serializer.appendDependencies(outputRoots, pathRegisters);
|
|
4269
|
+
return {
|
|
4270
|
+
instructions: serializer.instructions,
|
|
4271
|
+
constants: serializer.constants,
|
|
4272
|
+
outputs: remapOutputs(outputs, pathRegisters),
|
|
4273
|
+
condition: { mode: "flow", stages },
|
|
4274
|
+
attributes: serializer.attributes
|
|
4275
|
+
};
|
|
4276
|
+
}
|
|
4277
|
+
function compileProgram(builder, sourceOutputs) {
|
|
3959
4278
|
const outputs = { ...sourceOutputs };
|
|
3960
4279
|
if (outputs.when !== void 0) {
|
|
3961
4280
|
const condition = builder.instructions[outputs.when];
|
|
3962
4281
|
if (condition.opcode === 1) {
|
|
3963
4282
|
if (builder.constants[condition.immediate] === 0) {
|
|
3964
|
-
return
|
|
3965
|
-
instructions: [],
|
|
3966
|
-
constants: [],
|
|
3967
|
-
outputs: {},
|
|
3968
|
-
attributes: []
|
|
3969
|
-
};
|
|
4283
|
+
return emptyCompiledProgram();
|
|
3970
4284
|
}
|
|
3971
4285
|
outputs.when = void 0;
|
|
3972
4286
|
}
|
|
3973
4287
|
}
|
|
3974
|
-
const
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
if (register === void 0) break;
|
|
3984
|
-
for (const argument of builder.instructions[register].args) {
|
|
3985
|
-
if (marked[argument]) continue;
|
|
3986
|
-
marked[argument] = 1;
|
|
3987
|
-
pending.push(argument);
|
|
3988
|
-
}
|
|
3989
|
-
}
|
|
3990
|
-
};
|
|
3991
|
-
const live = new Uint8Array(builder.instructions.length);
|
|
3992
|
-
markDependencies(
|
|
3993
|
-
[
|
|
3994
|
-
outputs.when,
|
|
3995
|
-
outputs.position,
|
|
3996
|
-
outputs.scale,
|
|
3997
|
-
outputs.quaternion,
|
|
3998
|
-
outputs.opacity,
|
|
3999
|
-
outputs.alpha,
|
|
4000
|
-
outputs.color,
|
|
4001
|
-
...outputs.sh ?? []
|
|
4002
|
-
],
|
|
4003
|
-
live
|
|
4004
|
-
);
|
|
4005
|
-
const conditionLive = new Uint8Array(builder.instructions.length);
|
|
4288
|
+
const outputRoots = [
|
|
4289
|
+
outputs.position,
|
|
4290
|
+
outputs.scale,
|
|
4291
|
+
outputs.quaternion,
|
|
4292
|
+
outputs.opacity,
|
|
4293
|
+
outputs.alpha,
|
|
4294
|
+
outputs.color,
|
|
4295
|
+
...outputs.sh ?? []
|
|
4296
|
+
];
|
|
4006
4297
|
if (outputs.when !== void 0) {
|
|
4007
|
-
|
|
4298
|
+
const flow = compileConditionFlow(
|
|
4299
|
+
builder,
|
|
4300
|
+
outputs,
|
|
4301
|
+
outputRoots,
|
|
4302
|
+
outputs.when
|
|
4303
|
+
);
|
|
4304
|
+
if (flow) return flow;
|
|
4008
4305
|
}
|
|
4306
|
+
const live = new Uint8Array(builder.instructions.length);
|
|
4307
|
+
markDependencies(builder, outputRoots, live);
|
|
4009
4308
|
const instructionOrder = [];
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
if (live[index] && !conditionLive[index]) instructionOrder.push(index);
|
|
4017
|
-
}
|
|
4018
|
-
const registerMap = new Int32Array(builder.instructions.length).fill(-1);
|
|
4019
|
-
for (let index = 0; index < instructionOrder.length; index += 1) {
|
|
4020
|
-
registerMap[instructionOrder[index]] = index;
|
|
4021
|
-
}
|
|
4022
|
-
const constants = [];
|
|
4023
|
-
const attributes = [];
|
|
4024
|
-
const attributeMap = /* @__PURE__ */ new Map();
|
|
4025
|
-
const instructions = instructionOrder.map((sourceIndex) => {
|
|
4026
|
-
const instruction = builder.instructions[sourceIndex];
|
|
4027
|
-
let immediate = instruction.immediate;
|
|
4028
|
-
if (instruction.opcode === 1) {
|
|
4029
|
-
immediate = constants.length;
|
|
4030
|
-
constants.push(
|
|
4031
|
-
...builder.constants.slice(
|
|
4032
|
-
instruction.immediate,
|
|
4033
|
-
instruction.immediate + TYPE_WIDTHS[instruction.type]
|
|
4034
|
-
)
|
|
4035
|
-
);
|
|
4036
|
-
} else if (instruction.opcode === 3) {
|
|
4037
|
-
let mapped = attributeMap.get(instruction.immediate);
|
|
4038
|
-
if (mapped === void 0) {
|
|
4039
|
-
mapped = attributes.length;
|
|
4040
|
-
attributeMap.set(instruction.immediate, mapped);
|
|
4041
|
-
attributes.push(builder.attributes[instruction.immediate]);
|
|
4042
|
-
}
|
|
4043
|
-
immediate = mapped;
|
|
4044
|
-
}
|
|
4045
|
-
return {
|
|
4046
|
-
...instruction,
|
|
4047
|
-
args: instruction.args.map((argument) => registerMap[argument]),
|
|
4048
|
-
immediate
|
|
4049
|
-
};
|
|
4050
|
-
});
|
|
4051
|
-
const remap = (register) => register === void 0 ? void 0 : registerMap[register];
|
|
4309
|
+
for (let register = 0; register < live.length; register += 1) {
|
|
4310
|
+
if (live[register]) instructionOrder.push(register);
|
|
4311
|
+
}
|
|
4312
|
+
const serializer = new InstructionSerializer(builder);
|
|
4313
|
+
const registers = new GenerationRegisterMap(builder.instructions.length);
|
|
4314
|
+
serializer.append(instructionOrder, registers);
|
|
4052
4315
|
return {
|
|
4053
|
-
instructions,
|
|
4054
|
-
constants,
|
|
4055
|
-
outputs:
|
|
4056
|
-
|
|
4057
|
-
position: remap(outputs.position),
|
|
4058
|
-
scale: remap(outputs.scale),
|
|
4059
|
-
quaternion: remap(outputs.quaternion),
|
|
4060
|
-
opacity: remap(outputs.opacity),
|
|
4061
|
-
alpha: remap(outputs.alpha),
|
|
4062
|
-
color: remap(outputs.color),
|
|
4063
|
-
sh: (_a2 = outputs.sh) == null ? void 0 : _a2.map((register) => registerMap[register])
|
|
4064
|
-
},
|
|
4065
|
-
attributes
|
|
4316
|
+
instructions: serializer.instructions,
|
|
4317
|
+
constants: serializer.constants,
|
|
4318
|
+
outputs: remapOutputs(outputs, registers),
|
|
4319
|
+
attributes: serializer.attributes
|
|
4066
4320
|
};
|
|
4067
4321
|
}
|
|
4068
|
-
|
|
4069
|
-
const
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
const
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
const
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4322
|
+
function packInstructions(instructions) {
|
|
4323
|
+
const packed = new Uint16Array(
|
|
4324
|
+
instructions.length * SPLAT_POST_DECODE_INSTRUCTION_STRIDE
|
|
4325
|
+
);
|
|
4326
|
+
packed.fill(SPLAT_POST_DECODE_MISSING_ARGUMENT);
|
|
4327
|
+
for (let index = 0; index < instructions.length; index += 1) {
|
|
4328
|
+
const instruction = instructions[index];
|
|
4329
|
+
if (instruction.args.length > SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_COUNT || !Number.isInteger(instruction.immediate) || instruction.immediate < 0 || instruction.immediate > 65535 || instruction.args.some(
|
|
4330
|
+
(argument) => !Number.isInteger(argument) || argument < 0 || argument >= SPLAT_POST_DECODE_MISSING_ARGUMENT
|
|
4331
|
+
)) {
|
|
4332
|
+
throw new Error("postDecode instruction exceeds Uint16 bytecode limits");
|
|
4333
|
+
}
|
|
4334
|
+
const offset = index * SPLAT_POST_DECODE_INSTRUCTION_STRIDE;
|
|
4335
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_OPCODE] = instruction.opcode;
|
|
4336
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_WIDTH] = TYPE_WIDTHS[instruction.type];
|
|
4337
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_IMMEDIATE] = instruction.immediate;
|
|
4338
|
+
for (let argument = 0; argument < instruction.args.length; argument += 1) {
|
|
4339
|
+
packed[offset + SPLAT_POST_DECODE_INSTRUCTION_ARGUMENT_0 + argument] = instruction.args[argument];
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4342
|
+
return packed;
|
|
4343
|
+
}
|
|
4344
|
+
function snapshotAttributes(bindings) {
|
|
4345
|
+
const rangesByBuffer = /* @__PURE__ */ new Map();
|
|
4346
|
+
for (const binding of bindings) {
|
|
4347
|
+
if (binding.count === 0) continue;
|
|
4348
|
+
const packedBytes = ATTRIBUTE_FORMAT_BYTES[binding.format] * binding.components;
|
|
4349
|
+
const start = binding.data.byteOffset + binding.byteOffset;
|
|
4350
|
+
const end = start + (binding.count - 1) * binding.byteStride + packedBytes;
|
|
4351
|
+
const ranges = rangesByBuffer.get(binding.data.buffer) ?? [];
|
|
4352
|
+
ranges.push({ start, end });
|
|
4353
|
+
rangesByBuffer.set(binding.data.buffer, ranges);
|
|
4354
|
+
}
|
|
4355
|
+
const regions = [];
|
|
4356
|
+
const regionsByBuffer = /* @__PURE__ */ new Map();
|
|
4357
|
+
for (const [buffer, ranges] of rangesByBuffer) {
|
|
4358
|
+
ranges.sort((left, right) => left.start - right.start);
|
|
4359
|
+
const bufferRegions = [];
|
|
4360
|
+
for (const range of ranges) {
|
|
4361
|
+
const previous = bufferRegions[bufferRegions.length - 1];
|
|
4362
|
+
if (previous && range.start <= previous.end) {
|
|
4363
|
+
previous.end = Math.max(previous.end, range.end);
|
|
4364
|
+
} else {
|
|
4365
|
+
const region = { buffer, ...range, outputOffset: 0 };
|
|
4366
|
+
bufferRegions.push(region);
|
|
4367
|
+
regions.push(region);
|
|
4107
4368
|
}
|
|
4108
4369
|
}
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
)
|
|
4120
|
-
|
|
4121
|
-
|
|
4370
|
+
regionsByBuffer.set(buffer, bufferRegions);
|
|
4371
|
+
}
|
|
4372
|
+
let byteLength = 0;
|
|
4373
|
+
for (const region of regions) {
|
|
4374
|
+
region.outputOffset = byteLength;
|
|
4375
|
+
byteLength += region.end - region.start;
|
|
4376
|
+
}
|
|
4377
|
+
const data = new Uint8Array(byteLength);
|
|
4378
|
+
for (const region of regions) {
|
|
4379
|
+
data.set(
|
|
4380
|
+
new Uint8Array(region.buffer, region.start, region.end - region.start),
|
|
4381
|
+
region.outputOffset
|
|
4382
|
+
);
|
|
4383
|
+
}
|
|
4384
|
+
const attributes = bindings.map(
|
|
4385
|
+
(binding) => {
|
|
4386
|
+
var _a2;
|
|
4122
4387
|
let byteOffset = 0;
|
|
4123
|
-
if (
|
|
4124
|
-
const sourceOffset =
|
|
4125
|
-
const region =
|
|
4126
|
-
(candidate) =>
|
|
4388
|
+
if (binding.count !== 0) {
|
|
4389
|
+
const sourceOffset = binding.data.byteOffset + binding.byteOffset;
|
|
4390
|
+
const region = (_a2 = regionsByBuffer.get(binding.data.buffer)) == null ? void 0 : _a2.find(
|
|
4391
|
+
(candidate) => sourceOffset >= candidate.start && sourceOffset < candidate.end
|
|
4127
4392
|
);
|
|
4128
4393
|
if (!region) {
|
|
4129
4394
|
throw new Error("postDecode attribute view was not serialized");
|
|
@@ -4131,19 +4396,36 @@ const _SplatPostDecodeProgramImpl = class _SplatPostDecodeProgramImpl2 {
|
|
|
4131
4396
|
byteOffset = region.outputOffset + sourceOffset - region.start;
|
|
4132
4397
|
}
|
|
4133
4398
|
return {
|
|
4134
|
-
format:
|
|
4135
|
-
components:
|
|
4399
|
+
format: binding.format,
|
|
4400
|
+
components: binding.components,
|
|
4136
4401
|
byteOffset,
|
|
4137
|
-
byteStride:
|
|
4138
|
-
count:
|
|
4402
|
+
byteStride: binding.byteStride,
|
|
4403
|
+
count: binding.count
|
|
4139
4404
|
};
|
|
4140
|
-
}
|
|
4405
|
+
}
|
|
4406
|
+
);
|
|
4407
|
+
return { data, attributes };
|
|
4408
|
+
}
|
|
4409
|
+
_a = SPLAT_POST_DECODE_PROGRAM;
|
|
4410
|
+
const _SplatPostDecodeProgramImpl = class _SplatPostDecodeProgramImpl2 {
|
|
4411
|
+
constructor(builder, outputs) {
|
|
4412
|
+
this.builder = builder;
|
|
4413
|
+
this.outputs = outputs;
|
|
4414
|
+
this[_a] = true;
|
|
4415
|
+
}
|
|
4416
|
+
static serialize(program) {
|
|
4417
|
+
if (!(program instanceof _SplatPostDecodeProgramImpl2)) {
|
|
4418
|
+
throw new Error("Invalid postDecode program");
|
|
4419
|
+
}
|
|
4420
|
+
const compiled = compileProgram(program.builder, program.outputs);
|
|
4421
|
+
const snapshot = snapshotAttributes(compiled.attributes);
|
|
4141
4422
|
return {
|
|
4142
|
-
instructions,
|
|
4143
|
-
constants: new Float32Array(constants),
|
|
4144
|
-
outputs,
|
|
4145
|
-
|
|
4146
|
-
|
|
4423
|
+
instructions: packInstructions(compiled.instructions),
|
|
4424
|
+
constants: new Float32Array(compiled.constants),
|
|
4425
|
+
outputs: compiled.outputs,
|
|
4426
|
+
condition: compiled.condition,
|
|
4427
|
+
attributeData: snapshot.data,
|
|
4428
|
+
attributes: snapshot.attributes
|
|
4147
4429
|
};
|
|
4148
4430
|
}
|
|
4149
4431
|
};
|
|
@@ -4185,8 +4467,7 @@ function defineSplatPostDecode(build) {
|
|
|
4185
4467
|
if (!patch || typeof patch !== "object") {
|
|
4186
4468
|
throw new Error("postDecode builder must return a splat patch object");
|
|
4187
4469
|
}
|
|
4188
|
-
|
|
4189
|
-
return new SplatPostDecodeProgramImpl(builder, outputs);
|
|
4470
|
+
return new SplatPostDecodeProgramImpl(builder, buildOutputs(builder, patch));
|
|
4190
4471
|
}
|
|
4191
4472
|
const postDecode = {
|
|
4192
4473
|
define: defineSplatPostDecode
|