"use client"; import { useState, useRef, useEffect } from "react"; export default function XgridsWizard() { const [files, setFiles] = useState([]); const [status, setStatus] = useState("Waiting for upload..."); const [isProcessing, setIsProcessing] = useState(false); const workerRef = useRef(null); useEffect(() => { const worker = new Worker( new URL("./workers/converter.worker.ts", import.meta.url), ); workerRef.current = worker; worker.onmessage = (e) => { const { type, message, data } = e.data; if (type === "LOG") setStatus(message); if (type === "DONE") { setIsProcessing(false); setStatus("Pipeline Complete!"); data.files.forEach((file: { name: string; blob: Blob }) => { downloadFile(file.blob, file.name); }); } }; return () => worker.terminate(); }, []); const downloadFile = (blob: Blob, name: string) => { const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = name; a.click(); URL.revokeObjectURL(url); }; const handleFolderUpload = (e: React.ChangeEvent) => { const uploadedFiles = Array.from(e.target.files || []); if (uploadedFiles.length > 0) { setFiles(uploadedFiles); setStatus(`Loaded ${uploadedFiles.length} files. Ready to convert.`); } }; const startPipeline = async () => { if (!files.length || !workerRef.current) return; // FIND SPECIFIC ENTRIES const lciFile = files.find((f) => f.name.toLowerCase() === "collision.lci"); const lccFile = files.find((f) => f.name.toLowerCase().endsWith(".lcc")); if (!lciFile) { setStatus("Error: 'collision.lci' not found in folder."); return; } if (!lccFile) { setStatus("Error: Main '.lcc' scene file not found."); return; } setIsProcessing(true); try { // --- PHASE 1: Python (Only collision.lci) --- setStatus("Step 1/2: Converting collision.lci to PLY..."); const formData = new FormData(); formData.append("file", lciFile); const pyResponse = await fetch("/api/convert", { method: "POST", body: formData, }); if (!pyResponse.ok) { const err = await pyResponse.json(); throw new Error(err.error || "Python script failed"); } const plyBlob = await pyResponse.blob(); downloadFile(plyBlob, "collision_mesh.ply"); // --- PHASE 2: Worker (The whole folder context) --- setStatus("Step 2/2: Generating Splats and LODs from .lcc..."); const filesData = await Promise.all( files.map(async (f) => ({ name: f.name, buffer: await f.arrayBuffer(), })), ); const buffersToTransfer = filesData.map((f) => f.buffer); workerRef.current.postMessage( { type: "START_CONVERSION", filesData, mainLccName: lccFile.name, fileName: lccFile.name.replace(".lcc", ""), }, buffersToTransfer, ); } catch (error: any) { console.error(error); setStatus(`Error: ${error.message}`); setIsProcessing(false); } }; return (

Xgrids Scene Wizard

Targeting collision.lci + scene.lcc

{"> "} {status}

); }