126 lines
3.4 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
};
|