UNPKG

cg-vue-splat

Version:

Vue 3 wrapper component for GaussianSplats3D rendering library

271 lines (270 loc) 7.12 kB
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 };