cg-vue-splat
Version:
Vue 3 wrapper component for GaussianSplats3D rendering library
271 lines (270 loc) • 7.12 kB
JavaScript
import { createElementBlock as u, openBlock as f, createCommentVNode as h, toDisplayString as v, ref as m, onMounted as g, onBeforeUnmount as p, watch as c } from "vue";
import * as S from "@mkkellogg/gaussian-splats-3d";
const w = (e, l) => {
const r = e.__vccOpts || e;
for (const [o, i] of l)
r[o] = i;
return r;
}, B = {
name: "GaussianSplat",
props: {
// Required props
src: {
type: String,
required: !0
},
// Optional positioning props
position: {
type: Array,
default: () => [0, 0, 0]
},
rotation: {
type: Array,
default: () => [0, 0, 0, 1]
// Quaternion [x, y, z, w]
},
scale: {
type: Array,
default: () => [1, 1, 1]
},
// Camera props
cameraPosition: {
type: Array,
default: () => [0, 0, 3]
},
cameraLookAt: {
type: Array,
default: () => [0, 0, 0]
},
cameraUp: {
type: Array,
default: () => [0, -1, 0]
},
fov: {
type: Number,
default: 45
},
// Viewer options
showLoadingUI: {
type: Boolean,
default: !0
},
splatAlphaRemovalThreshold: {
type: Number,
default: 5
},
selfDrivenMode: {
type: Boolean,
default: !0
},
gpuAcceleratedSort: {
type: Boolean,
default: !1
},
// Additional optional props based on documentation
enableSIMDInSort: {
type: Boolean,
default: !0
},
sharedMemoryForWorkers: {
type: Boolean,
default: !1
},
integerBasedSort: {
type: Boolean,
default: !0
},
halfPrecisionCovariancesOnGPU: {
type: Boolean,
default: !1
},
antialiased: {
type: Boolean,
default: !0
},
dynamicScene: {
type: Boolean,
default: !1
},
progressiveLoad: {
type: Boolean,
default: !0
},
focusDistance: {
type: Number,
default: 1.2
},
sphericalHarmonicsDegree: {
type: Number,
default: 0,
validator: (e) => [0, 1, 2].includes(e)
},
maxScreenSpaceSplatSize: {
type: Number,
default: 2048
},
kernel2DSize: {
type: Number,
default: 0.5
},
autoRotate: {
type: Boolean,
default: !1
},
autoRotateSpeed: {
type: Number,
default: 0.5
},
showFps: {
type: Boolean,
default: !1
},
responsive: {
type: Boolean,
default: !0
},
enableControls: {
type: Boolean,
default: !0
}
},
emits: ["loaded", "error"],
setup(e, { emit: l }) {
const r = m(null), o = m(!1), i = m("");
let t = null;
const y = async () => {
if (!r.value) {
l("error", new Error("Container not found"));
return;
}
o.value = !0, i.value = "";
try {
d(), console.log("Initializing viewer with src:", e.src), console.log(
"Container dimensions:",
r.value.clientWidth,
"x",
r.value.clientHeight
), t = new S.Viewer({
rootElement: r.value,
cameraUp: e.cameraUp,
initialCameraPosition: e.cameraPosition,
initialCameraLookAt: e.cameraLookAt,
fov: e.fov,
selfDrivenMode: e.selfDrivenMode,
gpuAcceleratedSort: e.gpuAcceleratedSort,
sharedMemoryForWorkers: e.sharedMemoryForWorkers,
enableSIMDInSort: e.enableSIMDInSort,
integerBasedSort: e.integerBasedSort,
halfPrecisionCovariancesOnGPU: e.halfPrecisionCovariancesOnGPU,
antialiased: e.antialiased,
dynamicScene: e.dynamicScene,
focalAdjustment: e.focusDistance,
sphericalHarmonicsDegree: e.sphericalHarmonicsDegree,
kernel2DSize: e.kernel2DSize,
maxScreenSpaceSplatSize: e.maxScreenSpaceSplatSize,
autoRotate: e.autoRotate,
autoRotateSpeed: e.autoRotateSpeed,
showFps: e.showFps,
responsive: e.responsive,
controls: e.enableControls
}), t.threeRenderer && t.threeRenderer.domElement && (t.threeRenderer.domElement.style.width = "100%", t.threeRenderer.domElement.style.height = "100%", t.threeRenderer.domElement.style.display = "block"), console.log("Loading splat file:", e.src);
const a = e.src;
await t.addSplatScene(a, {
splatAlphaRemovalThreshold: e.splatAlphaRemovalThreshold,
showLoadingUI: e.showLoadingUI,
position: e.position,
rotation: e.rotation,
scale: e.scale,
progressiveLoad: e.progressiveLoad
}), console.log("Starting viewer"), t.start(), console.log("Viewer started successfully"), setTimeout(() => {
r.value && r.value.isConnected && (l("loaded"), o.value = !1);
}, 100);
} catch (a) {
console.error("Error initializing GaussianSplats3D viewer:", a), i.value = `Error: ${a.message}`, d(), l("error", a), o.value = !1;
}
}, d = () => {
if (t) {
try {
t.dispose ? t.dispose() : t.stop && t.stop();
} catch (a) {
console.warn("Error disposing viewer:", a);
}
t = null;
}
};
let s = null;
return g(() => {
console.log("Component mounted, initializing viewer"), setTimeout(y, 300), s = new ResizeObserver(() => {
if (t && t.threeRenderer) {
const a = r.value.clientWidth, n = r.value.clientHeight;
t.setSize(a, n);
}
}), r.value && s.observe(r.value);
}), p(() => {
s && (s.disconnect(), s = null), d();
}), c(
() => e.src,
(a) => {
console.log("src changed to:", a), setTimeout(y, 300);
}
), c(
() => e.position,
(a) => {
try {
t && t.splatMesh && t.splatMesh.position.fromArray(a);
} catch (n) {
console.error("Error updating position:", n);
}
},
{ deep: !0 }
), c(
() => e.rotation,
(a) => {
try {
t && t.splatMesh && t.splatMesh.quaternion.fromArray(a);
} catch (n) {
console.error("Error updating rotation:", n);
}
},
{ deep: !0 }
), c(
() => e.scale,
(a) => {
try {
t && t.splatMesh && t.splatMesh.scale.fromArray(a);
} catch (n) {
console.error("Error updating scale:", n);
}
},
{ deep: !0 }
), {
containerWrapper: r,
loading: o,
errorMsg: i
};
}
}, A = {
ref: "containerWrapper",
class: "gaussian-splat-container"
}, M = {
key: 0,
class: "loading-overlay"
}, _ = {
key: 1,
class: "error-overlay"
};
function D(e, l, r, o, i, t) {
return f(), u("div", A, [
o.loading ? (f(), u("div", M, "Loading splat...")) : h("", !0),
o.errorMsg ? (f(), u("div", _, v(o.errorMsg), 1)) : h("", !0)
], 512);
}
const b = /* @__PURE__ */ w(B, [["render", D], ["__scopeId", "data-v-78c67811"]]), k = {
install: (e) => {
e.component("GaussianSplat", b);
}
};
export {
b as GaussianSplat,
k as default
};