|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createUI() { |
|
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"); |
|
|
|
var initInstructions = new BABYLON.GUI.TextBlock(); |
|
initInstructions.text = "Gaussian Splattings Object Compressor\n\nDrag and drop\n.ply or .splat or .hyp to start\n\nOR"; |
|
initInstructions.color = "black"; |
|
initInstructions.fontSize = 40; |
|
advancedTexture.addControl(initInstructions); |
|
|
|
|
|
var navInstructionBt = BABYLON.GUI.Button.CreateSimpleButton("nav", ""); |
|
navInstructionBt.color = "black"; |
|
navInstructionBt.background = "white"; |
|
navInstructionBt.textBlock.fontSize = 40; |
|
navInstructionBt.alpha = 0.5; |
|
navInstructionBt.isVisible = false; |
|
advancedTexture.addControl(navInstructionBt); |
|
|
|
var navInstructionsTxt = new BABYLON.GUI.TextBlock(); |
|
navInstructionsTxt.text = "Drag to rotate\nScroll to zoom\nRight click to pan"; |
|
navInstructionsTxt.color = "black"; |
|
navInstructionsTxt.background = "white"; |
|
navInstructionsTxt.fontSize = 40; |
|
navInstructionsTxt.isVisible = false; |
|
advancedTexture.addControl(navInstructionsTxt); |
|
|
|
|
|
var homeBt = BABYLON.GUI.Button.CreateSimpleButton("home", "hyperinteractivity.com"); |
|
homeBt.width = 0.25; |
|
homeBt.height = 0.05; |
|
homeBt.color = "white"; |
|
homeBt.background = "black"; |
|
homeBt.isVisible = true; |
|
homeBt.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_RIGHT; |
|
homeBt.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP; |
|
|
|
homeBt.onPointerDownObservable.add(function() { |
|
window.location.href = "https://hyperinteractivity.com"; |
|
}); |
|
advancedTexture.addControl(homeBt); |
|
|
|
var loadExampleBt = BABYLON.GUI.Button.CreateSimpleButton("loadExample", "load our example"); |
|
loadExampleBt.width = 0.2; |
|
loadExampleBt.height = 0.2; |
|
loadExampleBt.color = "white"; |
|
loadExampleBt.background = "black"; |
|
loadExampleBt.textBlock.fontSize = 40; |
|
|
|
loadExampleBt.cornerRadius = 30; |
|
loadExampleBt.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER; |
|
loadExampleBt.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM; |
|
advancedTexture.addControl(loadExampleBt); |
|
|
|
var convertBt = BABYLON.GUI.Button.CreateSimpleButton("convert", "Convert"); |
|
convertBt.width = 0.2; |
|
convertBt.height = 0.2; |
|
convertBt.textBlock.fontSize = 40; |
|
convertBt.color = "white"; |
|
convertBt.background = "black"; |
|
|
|
convertBt.cornerRadius = 30; |
|
convertBt.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER; |
|
convertBt.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM; |
|
convertBt.isVisible = false; |
|
advancedTexture.addControl(convertBt); |
|
|
|
var downloadBt = BABYLON.GUI.Button.CreateSimpleButton("download", "Download"); |
|
downloadBt.width = 0.2; |
|
downloadBt.height = 0.2; |
|
downloadBt.color = "white"; |
|
downloadBt.background = "green"; |
|
downloadBt.cornerRadius = 30; |
|
downloadBt.textBlock.fontSize = 40; |
|
downloadBt.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER; |
|
downloadBt.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM; |
|
downloadBt.isVisible = false; |
|
advancedTexture.addControl(downloadBt); |
|
|
|
var progressBar = new BABYLON.GUI.Rectangle(); |
|
progressBar.height = 0.1; |
|
progressBar.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER; |
|
progressBar.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM; |
|
progressBar.background = "black"; |
|
progressBar.isVisible = false; |
|
advancedTexture.addControl( progressBar ); |
|
|
|
var progressBarInner = new BABYLON.GUI.Rectangle(); |
|
progressBarInner.width = 0; |
|
progressBarInner.height = 0.1; |
|
progressBarInner.thickness = 0; |
|
progressBarInner.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT; |
|
progressBarInner.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM; |
|
progressBarInner.background = "green"; |
|
progressBarInner.isVisible = false; |
|
advancedTexture.addControl( progressBarInner ); |
|
|
|
return [initInstructions, [navInstructionBt, navInstructionsTxt], loadExampleBt, convertBt, downloadBt, progressBar, progressBarInner]; |
|
} |
|
|
|
function downloadHyp(hyp, filename) { |
|
const blob = new Blob([hyp.buffer], { type: 'application/octet-stream' }); |
|
const url = URL.createObjectURL(blob); |
|
const anchor = document.createElement('a'); |
|
|
|
anchor.href = url; |
|
anchor.download = filename; |
|
anchor.click(); |
|
|
|
setTimeout(() => { |
|
URL.revokeObjectURL(url); |
|
}, 100); |
|
} |
|
|
|
|
|
|
|
var createScene = function () { |
|
|
|
var hypData = null; |
|
var gaussianSplattingsMesh = null; |
|
var gaussianSplattingsFile = null; |
|
|
|
|
|
var scene = new BABYLON.Scene(engine); |
|
scene.clearColor = new BABYLON.Color3(1.0, 1.0, 1.0); |
|
|
|
|
|
let radius = 3; |
|
var camera = new BABYLON.ArcRotateCamera("camera1", -Math.PI / 2, Math.PI / 2, radius,new BABYLON.Vector3(0, 0, 0), scene); |
|
|
|
camera.attachControl(canvas, true); |
|
camera.fov = 0.6; |
|
|
|
let [initInstructions, navInstruciton, loadExampleBt, convertBt, downloadBt, progressBar, progressBarInner] = createUI(); |
|
|
|
|
|
let filesInput = new BABYLON.FilesInput(engine, null, scene, null, null, null, function () { BABYLON.Tools.ClearLogCache() }, null, null); |
|
filesInput.onProcessFileCallback = (file, name, extension) => {dragAndDropCB(file, name, extension); }; |
|
filesInput.monitorElementForDragNDrop(canvas); |
|
|
|
function loadExampleCB() { |
|
|
|
navInstruciton[0].isVisible = true; |
|
navInstruciton[1].isVisible = true; |
|
setTimeout(function() { |
|
navInstruciton[0].isVisible = false; |
|
navInstruciton[1].isVisible = false; |
|
}, 1500); |
|
|
|
initInstructions.isVisible = false; |
|
loadExampleBt.isVisible = false; |
|
let url = "https://hyperinteractive.ai/data/clown.splat" |
|
gaussianSplattingsMesh = new BABYLON.GaussianSplattingMesh("gs", url, scene, true); |
|
gaussianSplattingsFile = "clown"; |
|
gaussianSplattingsMesh.onMeshReadyObservable.add(() => { |
|
initInstructions.isVisible = false; |
|
convertBt.isVisible = true; |
|
downloadBt.isVisible = false; |
|
}); |
|
} |
|
|
|
|
|
function dragAndDropCB(file, name, extension) { |
|
if(extension !== "splat" && extension !== "ply" && extension !== "hyp") { |
|
alert("Only .splat, .ply, and .hyp files are supported"); |
|
return; |
|
} |
|
|
|
|
|
initInstructions.isVisible = false; |
|
navInstruciton[0].isVisible = true; |
|
navInstruciton[1].isVisible = true; |
|
setTimeout(function() { |
|
navInstruciton[0].isVisible = false; |
|
navInstruciton[1].isVisible = false; |
|
}, 1500); |
|
|
|
loadExampleBt.isVisible = false; |
|
|
|
|
|
gaussianSplattingsFile = name.replace(/\.[^/.]+$/, ""); |
|
|
|
if(gaussianSplattingsMesh) { |
|
gaussianSplattingsMesh.dispose(); |
|
} |
|
|
|
const blob = new Blob([file]); |
|
let url = URL.createObjectURL(blob); |
|
if(extension === "hyp") { |
|
const fileReader = new FileReader(); |
|
fileReader.onload = function() { |
|
const arrayBuffer = this.result; |
|
const hypData = new Uint8Array(arrayBuffer); |
|
|
|
let newGS = fromHyp(hypData, scene) |
|
if(gaussianSplattingsMesh) |
|
gaussianSplattingsMesh.dispose(); |
|
gaussianSplattingsMesh = newGS; |
|
}; |
|
fileReader.readAsArrayBuffer(blob); |
|
} |
|
else { |
|
gaussianSplattingsMesh = new BABYLON.GaussianSplattingMesh("gs", url, scene, true); |
|
|
|
gaussianSplattingsMesh.onMeshReadyObservable.add(() => { |
|
initInstructions.isVisible = false; |
|
convertBt.isVisible = true; |
|
downloadBt.isVisible = false; |
|
}); |
|
} |
|
} |
|
|
|
|
|
|
|
loadExampleBt.onPointerDownObservable.add(loadExampleCB); |
|
|
|
convertBt.onPointerDownObservable.add(function() { |
|
convertBt.isVisible = false; |
|
|
|
progressBarInner.isVisible = true; |
|
progressBar.isVisible = true; |
|
updateProgressBar(0.0); |
|
|
|
|
|
babylonGsToHyp(gaussianSplattingsMesh, { updateCB: updateProgressBar}).then( |
|
(hyp) => { |
|
|
|
|
|
progressBarInner.isVisible = false; |
|
progressBar.isVisible = false; |
|
|
|
hypData = hyp; |
|
if(hypData){ |
|
downloadBt.isVisible = true; |
|
|
|
let newGS = fromHyp(hypData, scene) |
|
gaussianSplattingsMesh.dispose(); |
|
gaussianSplattingsMesh = newGS; |
|
} |
|
else { |
|
alert("Failed to convert to hyp"); |
|
|
|
gaussianSplattingsMesh.dispose(); |
|
gaussianSplattingsMesh = null; |
|
|
|
initInstructions.isVisible = true; |
|
} |
|
} |
|
); |
|
}); |
|
|
|
downloadBt.onPointerDownObservable.add(function() { |
|
downloadHyp(hypData, gaussianSplattingsFile + ".hyp"); |
|
} ); |
|
|
|
function updateProgressBar(progress) { |
|
progressBarInner.width = progress; |
|
} |
|
|
|
return scene; |
|
}; |
|
|