Files
XgridConverter/app/workers/converter.worker.ts
Andreas Wilms 9b5f2d0814 test
2026-03-09 12:25:43 +01:00

126 lines
3.4 KiB
TypeScript

const originalFetch = globalThis.fetch;
globalThis.fetch = async (input, init) => {
const url = input instanceof Request ? input.url : input.toString();
self.postMessage({ type: "LOG", message: `FETCH: ${url}` });
if (url.includes("webp.wasm")) {
self.postMessage({
type: "LOG",
message: `INTERCEPTED → /workers/webp.wasm`,
});
const res = await originalFetch("/workers/webp.wasm", init);
self.postMessage({
type: "LOG",
message: `WASM response status: ${res.status}`,
});
return res;
}
return originalFetch(input, init);
};
// Intercept XMLHttpRequest (Emscripten uses this in Workers)
if (typeof XMLHttpRequest !== "undefined") {
const originalOpen = XMLHttpRequest.prototype.open;
// @ts-ignore
XMLHttpRequest.prototype.open = function (
method: string,
url: string | URL,
...rest: any[]
) {
if (typeof url === "string" && url.includes("webp.wasm")) {
url = "/workers/webp.wasm";
}
return originalOpen.apply(this, [method, url, ...rest] as any);
};
}
self.onmessage = async (e: MessageEvent) => {
const { type, filesData, mainLccName, fileName } = e.data;
if (type === "START_CONVERSION") {
try {
self.postMessage({ type: "LOG", message: "Initialisiere..." });
// Fetch the WASM binary ourselves and inject it
const wasmResponse = await fetch("/workers/webp.wasm");
const wasmBinary = await wasmResponse.arrayBuffer();
// Inject before the module loads
// @ts-ignore
globalThis.Module = { wasmBinary };
const {
readFile,
writeFile,
MemoryReadFileSystem,
MemoryFileSystem,
getInputFormat,
getOutputFormat,
} = await import("@playcanvas/splat-transform");
const readFs = new MemoryReadFileSystem();
self.postMessage({
type: "LOG",
message: "Lade Dateien in den virtuellen Speicher...",
});
for (const file of filesData) {
readFs.set(file.name, new Uint8Array(file.buffer));
}
const fullOptions = {
iterations: 0,
lodSelect: [0],
unbundled: false,
lodChunkCount: 0,
lodChunkExtent: 0,
};
self.postMessage({ type: "LOG", message: "Lese LCC und Binärdaten..." });
const tables = await readFile({
filename: mainLccName,
fileSystem: readFs,
inputFormat: getInputFormat(mainLccName),
params: [],
options: fullOptions,
});
const mainTable = tables[0];
if (!mainTable) throw new Error("Keine Splat-Daten gefunden.");
self.postMessage({ type: "LOG", message: "Kompiliere SOG..." });
const writeFs = new MemoryFileSystem();
const outputName = `${fileName}.sog`;
await writeFile(
{
filename: outputName,
outputFormat: getOutputFormat(outputName, fullOptions),
dataTable: mainTable,
options: { ...fullOptions, iterations: 8 },
},
writeFs,
);
const sogData = writeFs.results.get(outputName);
if (!sogData) throw new Error("SOG-Erstellung fehlgeschlagen.");
self.postMessage({
type: "DONE",
data: {
sog: new Blob([new Uint8Array(sogData).slice().buffer], {
type: "application/octet-stream",
}),
fileName,
},
});
} catch (err: any) {
self.postMessage({ type: "LOG", message: `Fehler: ${err.message}` });
console.error(err);
}
}
};