test
This commit is contained in:
109
public/workers/converter.worker.js
Normal file
109
public/workers/converter.worker.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import {
|
||||
WebPCodec,
|
||||
readFile,
|
||||
writeFile,
|
||||
MemoryReadFileSystem,
|
||||
MemoryFileSystem,
|
||||
} from "@playcanvas/splat-transform";
|
||||
|
||||
// 1. Configure WASM path for the browser environment
|
||||
WebPCodec.config({ wasmUrl: "/webp.wasm" });
|
||||
|
||||
/**
|
||||
* Converts Xgrids LCI binary data to a standard PLY
|
||||
* Parses 12-byte float chunks (X, Y, Z) from the binary buffer.
|
||||
*/
|
||||
function convertLciToPly(lciBuffer) {
|
||||
const view = new DataView(lciBuffer);
|
||||
|
||||
// Xgrids LCI files usually start with a 4-byte point count
|
||||
const numPoints = view.getUint32(0, true);
|
||||
const points = [];
|
||||
|
||||
let offset = 4;
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
if (offset + 12 > lciBuffer.byteLength) break;
|
||||
|
||||
const x = view.getFloat32(offset, true);
|
||||
const y = view.getFloat32(offset + 4, true);
|
||||
const z = view.getFloat32(offset + 8, true);
|
||||
|
||||
points.push(`${x} ${y} ${z}`);
|
||||
offset += 12;
|
||||
}
|
||||
|
||||
const header = [
|
||||
"ply",
|
||||
"format ascii 1.0",
|
||||
`element vertex ${points.length}`,
|
||||
"property float x",
|
||||
"property float y",
|
||||
"property float z",
|
||||
"end_header",
|
||||
].join("\n");
|
||||
|
||||
return header + "\n" + points.join("\n");
|
||||
}
|
||||
|
||||
self.onmessage = async (e) => {
|
||||
const { type, lccBuffer, lciBuffer, fileName } = e.data;
|
||||
|
||||
if (type === "START_CONVERSION") {
|
||||
try {
|
||||
// --- STEP 1: GENERATE COLLISION MESH (.PLY) ---
|
||||
self.postMessage({ type: "LOG", message: "Parsing LCI Geometry..." });
|
||||
const plyData = convertLciToPly(lciBuffer);
|
||||
const plyBlob = new Blob([plyData], { type: "text/plain" });
|
||||
|
||||
// --- STEP 2: GENERATE HIGHEST QUALITY .SOG ---
|
||||
self.postMessage({
|
||||
type: "LOG",
|
||||
message: "Loading LCC into Splat Engine...",
|
||||
});
|
||||
|
||||
const readFs = new MemoryReadFileSystem();
|
||||
readFs.add(`${fileName}.lcc`, new Uint8Array(lccBuffer));
|
||||
|
||||
// splat-transform handles LCC containers natively
|
||||
const dataTable = await readFile(`${fileName}.lcc`, { fs: readFs });
|
||||
|
||||
self.postMessage({
|
||||
type: "LOG",
|
||||
message: "Compiling High Quality SOG (WASM)...",
|
||||
});
|
||||
const writeFsSog = new MemoryFileSystem();
|
||||
await writeFile(dataTable, `${fileName}.sog`, { fs: writeFsSog });
|
||||
const sogBlob = new Blob([writeFsSog.get(`${fileName}.sog`)]);
|
||||
|
||||
// --- STEP 3: GENERATE LODs (UNBUNDLED TILES) ---
|
||||
self.postMessage({
|
||||
type: "LOG",
|
||||
message: "Generating LOD Tiled Structure...",
|
||||
});
|
||||
const writeFsLod = new MemoryFileSystem();
|
||||
|
||||
// 'unbundled' creates the tiled WebP/JSON structure for streaming
|
||||
await writeFile(dataTable, "lods/meta.json", {
|
||||
fs: writeFsLod,
|
||||
unbundled: true,
|
||||
});
|
||||
|
||||
// --- STEP 4: RETURN ALL ASSETS ---
|
||||
self.postMessage({
|
||||
type: "DONE",
|
||||
data: {
|
||||
sog: sogBlob,
|
||||
ply: plyBlob,
|
||||
lods: writeFsLod.files, // This contains the meta.json and .webp tiles
|
||||
fileName: fileName,
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
self.postMessage({
|
||||
type: "LOG",
|
||||
message: `CRITICAL ERROR: ${err.message}`,
|
||||
});
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
public/workers/webp.wasm
Executable file
BIN
public/workers/webp.wasm
Executable file
Binary file not shown.
Reference in New Issue
Block a user