dylanebert's picture
dylanebert HF staff
fix download bug
18a4acc
raw
history blame
5.34 kB
import * as SPLAT from "gsplat";
import { Engine } from "./Engine";
import { SelectionManager } from "./SelectionManager";
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
const progressDialog = document.getElementById("progress-dialog") as HTMLDialogElement;
const progressIndicator = document.getElementById("progress-indicator") as HTMLProgressElement;
const uploadButton = document.getElementById("upload-button") as HTMLButtonElement;
const downloadButton = document.getElementById("download-button") as HTMLButtonElement;
const controlsDisplayButton = document.getElementById("controls-display-button") as HTMLButtonElement;
const controlsDisplay = document.getElementById("controls-display") as HTMLDivElement;
const uploadModal = document.getElementById("upload-modal") as HTMLDialogElement;
const uploadModalClose = document.getElementById("upload-modal-close") as HTMLButtonElement;
const fileInput = document.getElementById("file-input") as HTMLInputElement;
const urlInput = document.getElementById("url-input") as HTMLInputElement;
const uploadSubmit = document.getElementById("upload-submit") as HTMLButtonElement;
const uploadError = document.getElementById("upload-error") as HTMLDivElement;
const learnMoreButton = document.getElementById("about") as HTMLButtonElement;
const engine = new Engine(canvas);
let loading = false;
async function selectFile(file: File) {
if (loading) return;
SelectionManager.selectedSplat = null;
loading = true;
if (file.name.endsWith(".splat")) {
uploadModal.style.display = "none";
progressDialog.showModal();
await SPLAT.Loader.LoadFromFileAsync(file, engine.scene, (progress: number) => {
progressIndicator.value = progress * 100;
});
progressDialog.close();
} else if (file.name.endsWith(".ply")) {
const format = "";
// const format = "polycam"; // Uncomment to load a Polycam PLY file
uploadModal.style.display = "none";
progressDialog.showModal();
await SPLAT.PLYLoader.LoadFromFileAsync(
file,
engine.scene,
(progress: number) => {
progressIndicator.value = progress * 100;
},
format,
);
progressDialog.close();
} else {
uploadError.style.display = "block";
uploadError.innerText = `Invalid file type: ${file.name}`;
}
loading = false;
}
async function main() {
const url = "https://huggingface.co/datasets/dylanebert/3dgs/resolve/main/bonsai/bonsai-7k-mini.splat";
await SPLAT.Loader.LoadAsync(url, engine.scene, (progress) => (progressIndicator.value = progress * 100));
progressDialog.close();
engine.renderer.backgroundColor = new SPLAT.Color32(64, 64, 64, 255);
const handleResize = () => {
engine.renderer.setSize(canvas.clientWidth, canvas.clientHeight);
};
const frame = () => {
engine.update();
requestAnimationFrame(frame);
};
handleResize();
window.addEventListener("resize", handleResize);
requestAnimationFrame(frame);
document.addEventListener("drop", (e) => {
e.preventDefault();
e.stopPropagation();
if (e.dataTransfer != null) {
selectFile(e.dataTransfer.files[0]);
}
});
uploadButton.addEventListener("click", () => {
uploadModal.style.display = "block";
});
uploadModalClose.addEventListener("click", () => {
uploadModal.style.display = "none";
});
downloadButton.addEventListener("click", () => {
if (SelectionManager.selectedSplat !== null) {
SelectionManager.selectedSplat.saveToFile();
} else {
engine.scene.saveToFile();
}
});
controlsDisplayButton.addEventListener("click", () => {
controlsDisplayButton.classList.toggle("active");
controlsDisplay.classList.toggle("active");
});
fileInput.addEventListener("change", () => {
if (fileInput.files != null) {
selectFile(fileInput.files[0]);
}
});
uploadSubmit.addEventListener("click", async () => {
let url = urlInput.value;
if (url === "") {
url = urlInput.placeholder;
}
if (url.endsWith(".splat")) {
uploadModal.style.display = "none";
progressDialog.showModal();
await SPLAT.Loader.LoadAsync(url, engine.scene, (progress) => (progressIndicator.value = progress * 100));
progressDialog.close();
} else if (url.endsWith(".ply")) {
uploadModal.style.display = "none";
progressDialog.showModal();
await SPLAT.PLYLoader.LoadAsync(
url,
engine.scene,
(progress) => (progressIndicator.value = progress * 100),
);
progressDialog.close();
} else {
uploadError.style.display = "block";
uploadError.innerText = `Invalid file type: ${url}`;
return;
}
});
learnMoreButton.addEventListener("click", () => {
window.open("https://huggingface.co/spaces/dylanebert/gsplat-editor/discussions/1", "_blank");
});
window.addEventListener("click", () => {
window.focus();
});
}
main();