@babylonjs/viewer
Version:
The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.
3 lines (2 loc) • 15.8 kB
JavaScript
import{p as e,F as t,B as n,U as r,ap as o,o as s,b0 as i,b1 as a,b2 as l,b3 as c,b4 as u,b5 as f,b6 as p,t as d,n as g,b7 as v,g as _,b8 as b,b9 as m,ba as h,an as x}from"./index-B8IgtevW.esm.min.js";function w(n){const r=new e(n),o=new t(n),s=r.byteLength/32|0;if(0===s)throw new Error("splat buffer is empty");const{width:i,height:a}=(l=s,{width:4096,height:Math.max(1,Math.ceil(l/4096))});var l;const c=i*a,u=new t(3*s),f=new t(4*c),p=new t(4*c),d=new t(4*c),g=new t(4*c);let v=1/0,_=1/0,b=1/0,m=-1/0,h=-1/0,x=-1/0;const w=new t(9);for(let e=0;e<s;e++){const t=8*e,n=32*e,s=o[t],i=-o[t+1],a=o[t+2];u[3*e]=s,u[3*e+1]=i,u[3*e+2]=a,s<v&&(v=s),i<_&&(_=i),a<b&&(b=a),s>m&&(m=s),i>h&&(h=i),a>x&&(x=a),f[4*e]=s,f[4*e+1]=i,f[4*e+2]=a,f[4*e+3]=1,g[4*e]=r[n+24]/255,g[4*e+1]=r[n+25]/255,g[4*e+2]=r[n+26]/255,g[4*e+3]=r[n+27]/255;let l=-(r[n+28]-127.5)/127.5,c=(r[n+29]-127.5)/127.5,y=-(r[n+30]-127.5)/127.5,R=(r[n+31]-127.5)/127.5;const M=1/(Math.hypot(l,c,y,R)||1);l*=M,c*=M,y*=M,R*=M;const T=2*o[t+3],B=2*o[t+4],A=2*o[t+5],S=c*c,E=y*y,G=R*R,O=c*y,I=c*R,L=y*R,k=l*c,C=l*y,F=l*R,V=1-2*(E+G),z=2*(O+F),P=2*(I-C),j=2*(O-F),N=1-2*(S+G),D=2*(L+k),U=2*(I+C),q=2*(L-k),H=1-2*(S+E);w[0]=V*T,w[1]=z*T,w[2]=P*T,w[3]=j*B,w[4]=N*B,w[5]=D*B,w[6]=U*A,w[7]=q*A,w[8]=H*A;const W=w[0]*w[0]+w[3]*w[3]+w[6]*w[6],X=w[0]*w[1]+w[3]*w[4]+w[6]*w[7],K=w[0]*w[2]+w[3]*w[5]+w[6]*w[8],Q=w[1]*w[1]+w[4]*w[4]+w[7]*w[7],Y=w[1]*w[2]+w[4]*w[5]+w[7]*w[8],$=w[2]*w[2]+w[5]*w[5]+w[8]*w[8];p[4*e]=W,p[4*e+1]=X,p[4*e+2]=K,p[4*e+3]=1,d[4*e]=Q,d[4*e+1]=Y,d[4*e+2]=$,d[4*e+3]=1}return{vertexCount:s,boundMin:[v,_,b],boundMax:[m,h,x],textureWidth:i,textureHeight:a,positions:u,centersRGBA:f,covARGBA:p,covBRGBA:d,colorsRGBA:g}}function y(e,d,g,v,_){const b=e._device,m=b.queue,{textureWidth:h,textureHeight:x,vertexCount:y}=g,R=e=>{const t=b.createTexture({size:[h,x],format:"rgba32float",usage:s.TEXTURE_BINDING|s.COPY_DST});return m.writeTexture({texture:t},e.buffer,{bytesPerRow:16*h},{width:h,height:x}),{tex:t,view:t.createView()}},M=R(g.centersRGBA),T=R(g.covARGBA),B=R(g.covBRGBA),A=R(g.colorsRGBA),S=b.createSampler({magFilter:"nearest",minFilter:"nearest",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),E=b.createBuffer({size:32,usage:n.VERTEX,mappedAtCreation:!0});new t(E.getMappedRange()).set([-2,-2,2,-2,2,2,-2,2]),E.unmap();const G=b.createBuffer({size:12,usage:n.INDEX,mappedAtCreation:!0});new r(G.getMappedRange()).set([0,1,2,0,2,3]),G.unmap();const O=new t(y);for(let e=0;e<y;e++)O[e]=e;const I=b.createBuffer({size:O.byteLength,usage:n.VERTEX|n.COPY_DST});m.writeBuffer(I,0,O.buffer,0,O.byteLength);let L=null;const k=new Promise(e=>{L=e});let C=_.data;const F={_kind:"gs-mesh",name:d,vertexCount:y,textureWidth:h,textureHeight:x,boundMin:g.boundMin.slice(),boundMax:g.boundMax.slice(),shDegree:_.shDegree??0,_worker:v,_orderPool:[new o(y),new o(y)],_pendingOrder:null,_sortDepthTransform:new t(4),_nextSortDepthTransform:new t(4),firstSortReady:k,_firstSortResolve:L,_gs:{_centersTex:M.tex,_centersView:M.view,_covATex:T.tex,_covAView:T.view,_covBTex:B.tex,_covBView:B.view,_colorsTex:A.tex,_colorsView:A.view,_sampler:S,_quadBuffer:E,_indexBuffer:G,_splatIndexBuffer:I,_splatIndexCpu:O,_shTextures:null,_shViews:null}};return Object.defineProperty(F,"splatsData",{get:()=>C}),F.updateData=e=>{const t=w(e);if(t.vertexCount!==F.vertexCount)throw Error("GS vertex count mismatch");const n=F._gs,r=(e,n)=>{m.writeTexture({texture:e},n.buffer,{bytesPerRow:16*t.textureWidth},{width:t.textureWidth,height:t.textureHeight})};r(n._centersTex,t.centersRGBA),r(n._covATex,t.covARGBA),r(n._covBTex,t.covBRGBA),r(n._colorsTex,t.colorsRGBA),F.boundMin=t.boundMin.slice(),F.boundMax=t.boundMax.slice(),F._worker.postMessage({p:t.positions},[t.positions.buffer]),F._sortDepthTransform.fill(0),C=e},function(e){const t=i(()=>a(e.position,e.rotationQuaternion,e.scaling)),n=()=>t.markLocalDirty(),[r,o,s,d]=p(0,0,0),g=new l(r,o,s,d,n);e.rotationQuaternion=g,e.rotation=c(g),e.position=new u(0,0,0,n),e.scaling=new u(1,1,1,n),e.children=[],Object.defineProperty(e,"parent",{get:()=>t.parent,set(e){t.parent=e},configurable:!0,enumerable:!0}),Object.defineProperty(e,"worldMatrix",{get:()=>t.getWorldMatrix(),configurable:!0,enumerable:!1}),Object.defineProperty(e,"worldMatrixVersion",{get:()=>t.getWorldMatrixVersion(),configurable:!0,enumerable:!1}),f(e,t)}(F),v.postMessage({p:g.positions},[g.positions.buffer]),v.onmessage=e=>{const t=e.data;F._pendingOrder&&F._orderPool.push(F._pendingOrder),F._pendingOrder=t.o,F._firstSortResolve&&(F._firstSortResolve(),F._firstSortResolve=null)},F}function R(e,t){const n=t._pendingOrder;if(!n)return;t._pendingOrder=null;const r=t._gs._splatIndexCpu;r.set(n),e.writeBuffer(t._gs._splatIndexBuffer,0,r.buffer,0,r.byteLength),t._orderPool.push(n)}function M(e,t,n){if(0===e._orderPool.length)return;const r=n[2],o=n[6],s=n[10],i=e._sortDepthTransform,a=e._nextSortDepthTransform;let l=!1;for(let e=0;e<4;e++)a[e]=r*t[4*e]+o*t[4*e+1]+s*t[4*e+2]+(3===e?n[14]:0),Math.abs(i[e]-a[e])>1e-4&&(l=!0);if(!l)return;i.set(a);const c=e._orderPool.pop();e._worker.postMessage({t:i,o:c},[c.buffer])}function T(e){const t=e._gs;[t._centersTex,t._covATex,t._covBTex,t._colorsTex,t._quadBuffer,t._indexBuffer,t._splatIndexBuffer,...t._shTextures??[]].forEach(e=>e.destroy()),e._worker.terminate()}function B(e,t,n){const r={entity:t,load:n};return e._pickSources.push(r),()=>{const t=e._pickSources.indexOf(r);t>=0&&e._pickSources.splice(t,1)}}let A=null;function S(e,t){const n={};for(const e of t){e.helperFunctions&&(n.GS_FRAGMENT_DEFINITIONS=(n.GS_FRAGMENT_DEFINITIONS??"")+e.helperFunctions+"\n");for(const[t,r]of Object.entries(e.fragmentSlots??{}))n[t]=(n[t]??"")+r+"\n"}const r=[["world","w"],["view","v"],["projection","p"],["viewport","vp"],["focal","f"],["dataSize","ds"],["alpha","a"],["_pad","_p"],["vColor","vc"],["vPos","vq"],["dataUv","du"],["splatIndex","si"],["corner","co"],["center","ce"],["color","cl"],["covA","ca"],["covB","cb"],["worldPos","wp"],["modelView","mv"],["camspace","cs"],["pos2d","p2"],["bounds","bd"],["Vrk","vr"],["invZ2","iz2"],["invZ","iz"],["cov2d","c2"],["kernelSize","ks"],["radius","ra"],["epsilon","ep"],["lambda1","l1"],["lambda2","l2"],["diag","dg"],["majorAxis","ma"],["minorAxis","mi"],["vCenter","vc2"]];let o=e.replace(/\/\*(GS_FRAGMENT_\w+)\*\//g,(e,t)=>n[t]??"");for(const[e,t]of r)o=o.replace(new RegExp(`\\b${e}\\b`,"g"),t);return o}function E(e,r,o){const s=e.surface.engine,i=s._device,a=i.createBuffer({size:224,usage:n.UNIFORM|n.COPY_DST}),l=new t(56);l[52]=r.textureWidth,l[53]=r.textureHeight,l[54]=1,l[55]=0;const c=new Map,u=()=>{const t=e.camera;if(!t)return;R(i.queue,r);const n=b(s),o=n.width/n.height,c=m(t),u=h(t,o),f=r.worldMatrix;l.set(f,0),l.set(c,16),l.set(u,32),l[48]=n.width,l[49]=n.height,l[50]=.5*n.width*u[0],l[51]=.5*n.height*u[5],i.queue.writeBuffer(a,0,l.buffer,0,224),M(r,f,c)},f={order:200,isTransparent:!0,bind(e,t){const n=function(e,t){const n=e._device;A&&A.device===n||(A={device:n,modules:new Map,entries:new Map});const r=d(t)+"";let o=A.entries.get(r);if(o)return o;let s=A.modules.get("");s||(s=n.createShaderModule({code:"struct S{w:mat4x4<f32>,v:mat4x4<f32>,p:mat4x4<f32>,vp:vec2<f32>,f:vec2<f32>,ds:vec2<f32>,a:f32,_p:f32}@group(1) @binding(0) var<uniform> u:S;@group(1) @binding(1) var e:sampler;@group(1) @binding(2) var F:texture_2d<f32>;@group(1) @binding(3) var G:texture_2d<f32>;@group(1) @binding(4) var J:texture_2d<f32>;@group(1) @binding(5) var K:texture_2d<f32>;struct A{@builtin(position) pos:vec4<f32>,@location(0) vc:vec4<f32>,@location(1) vq:vec2<f32>}fn B(r:f32)->vec2<f32>{let v=floor(r/u.ds.x);let N=r-v*u.ds.x;return vec2<f32>((N+0.5)/u.ds.x,(v+0.5)/u.ds.y);}@vertex fn vs(@location(0) k:vec2<f32>,@location(1) R:f32)->A{var a:A;let j=B(R);let M=textureSampleLevel(F,e,j,0.0).xyz;let q=textureSampleLevel(K,e,j,0.0);let d=textureSampleLevel(G,e,j,0.0).xyz;let i=textureSampleLevel(J,e,j,0.0).xyz;let C=u.w*vec4<f32>(M,1.0);let m=u.v*u.w;let h=u.v*C;let b=u.p*h;let g=1.2*b.w;if (b.z<0.0||b.x<-g||b.x>g||b.y<-g||b.y>g){a.pos=vec4<f32>(0.0,0.0,2.0,1.0);a.vc=vec4<f32>(0.0);a.vq=vec2<f32>(0.0);return a;}let H=mat3x3<f32>(vec3<f32>(d.x,d.y,d.z),vec3<f32>(d.y,i.x,i.y),vec3<f32>(d.z,i.y,i.z));let f=1.0/h.z;let s=f*f;let E=mat3x3<f32>(vec3<f32>(u.f.x*f,0.0,-u.f.x*h.x*s),vec3<f32>(0.0,u.f.y*f,-u.f.y*h.y*s),vec3<f32>(0.0,0.0,0.0));let P=mat3x3<f32>(m[0].xyz,m[1].xyz,m[2].xyz);let t=transpose(P)*E;var c=transpose(t)*H*t;let w:f32=0.3;c[0][0]+=w;c[1][1]+=w;let z=(c[0][0]+c[1][1])*0.5;let I=(c[0][0]-c[1][1])*0.5;let y=length(vec2<f32>(I,c[0][1]));let x:f32=0.0001;let n=z+y+x;let p=z-y+x;if (p<0.0){a.pos=vec4<f32>(0.0,0.0,2.0,1.0);a.vc=vec4<f32>(0.0);a.vq=vec2<f32>(0.0);return a;}let l=normalize(vec2<f32>(c[0][1],n-c[0][0]));let O=min(sqrt(2.0*n),1024.0)*l;let D=min(sqrt(2.0*p),1024.0)*vec2<f32>(l.y,-l.x);let Q=b.xy;a.pos=vec4<f32>(Q+(k.x*O+k.y*D)*b.w/u.vp,b.z,b.w);a.vc=vec4<f32>(q.rgb,q.a*u.a);a.vq=k;return a;}/*GS_FRAGMENT_DEFINITIONS*/@fragment fn fs(in:A)->@location(0) vec4<f32>{/*GS_FRAGMENT_MAIN_BEGIN*/let o=-dot(in.vq,in.vq);var finalColor:vec4<f32>;if (o>-4.0){let L=exp(o)*in.vc.a;finalColor=vec4<f32>(in.vc.rgb,L);} else{finalColor=vec4<f32>(0.0);}/*GS_FRAGMENT_BEFORE_FRAGCOLOR*//*GS_FRAGMENT_MAIN_END*/return finalColor;}"}),A.modules.set("",s));const i=n.createBindGroupLayout({entries:[{binding:0,visibility:g.VERTEX|g.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:g.VERTEX,sampler:{type:"non-filtering"}},{binding:2,visibility:g.VERTEX,texture:{sampleType:"unfilterable-float"}},{binding:3,visibility:g.VERTEX,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:g.VERTEX,texture:{sampleType:"unfilterable-float"}},{binding:5,visibility:g.VERTEX,texture:{sampleType:"unfilterable-float"}}]});return o={pipeline:n.createRenderPipeline({layout:n.createPipelineLayout({bindGroupLayouts:[_(e),i]}),vertex:{module:s,entryPoint:"vs",buffers:[{arrayStride:8,stepMode:"vertex",attributes:[{shaderLocation:0,offset:0,format:"float32x2"}]},{arrayStride:4,stepMode:"instance",attributes:[{shaderLocation:1,offset:0,format:"float32"}]}]},fragment:{module:s,entryPoint:"fs",targets:[{format:t._colorFormat,blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}},writeMask:v.ALL}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:t._depthStencilFormat??"depth24plus-stencil8",depthCompare:t._depthCompare??"greater-equal",depthWriteEnabled:!1},multisample:{count:t._sampleCount}}),meshBindGroupLayout:i},A.entries.set(r,o),o}(e,t),o=(e=>{let t=c.get(e.pipeline);return t||(t=i.createBindGroup({layout:e.meshBindGroupLayout,entries:[{binding:0,resource:{buffer:a}},{binding:1,resource:r._gs._sampler},{binding:2,resource:r._gs._centersView},{binding:3,resource:r._gs._covAView},{binding:4,resource:r._gs._covBView},{binding:5,resource:r._gs._colorsView}]}),c.set(e.pipeline,t),t)})(n);return{renderable:f,pipeline:n.pipeline,update:u,draw:e=>(e.setBindGroup(1,o),e.setVertexBuffer(0,r._gs._quadBuffer),e.setVertexBuffer(1,r._gs._splatIndexBuffer),e.setIndexBuffer(r._gs._indexBuffer,"uint16"),e.drawIndexed(6,r.vertexCount),1)}}};return f}const G="(()=>{function w(c,s,o,a,j){const m=o[0],u=o[1],b=o[2],d=o[3],f=j[0];let r=1/0,g=-1/0;for(let t=0;t<s;t++){f[t]=m*c[3*t]+u*c[3*t+1]+b*c[3*t+2]+d;const n=f[t];n-n===0&&(n<r&&(r=n),n>g&&(g=n))}const h=g-r;if(!(h>1e-12)){for(let t=0;t<s;t++)a[t]=t;return}const e=j[1];e.fill(0);const i=e.length-1,p=i/h;for(let t=0;t<s;t++){const n=f[t];let l;n-n===0?(l=(n-r)*p|0,l>i&&(l=i)):l=i,f[t]=l,e[l]++}let M=0;for(let t=i;t>=0;t--){const n=e[t];e[t]=M,M+=n}for(let t=0;t<s;t++){const n=f[t];a[e[n]++]=t}}let y,k;self.onmessage=c=>{const s=c.data;if(s.p){y=s.p;const a=y.length/3;k=[new Float32Array(a),new Uint32Array(1<<Math.max(10,Math.min(20,Math.round(Math.log2(a/4)))))];return}const o=s.o;w(y,o.length,s.t,o,k),self.postMessage({o},[o.buffer])};})();",O="undefined"!=typeof self&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",G],{type:"text/javascript;charset=utf-8"});function I(e){let t;try{if(t=O&&(self.URL||self.webkitURL).createObjectURL(O),!t)throw"";const n=new Worker(t,{type:"module",name:e?.name});return n.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch(t){return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(G),{type:"module",name:e?.name})}}async function L(e,t,n,r){const o=w(n.data),s=new I({name:"babylon-lite-splat-sort"}),i=y(e.surface.engine,t,o,s,n);if(n.sh&&n.shDegree&&n.shDegree>0){const{attachGaussianSplattingMeshSH:t}=await import("./gaussian-splatting-pipeline-sh-BQI2m8Y8.esm.min.js");t(e,i,n.sh,r)}else!function(e,t){const n=e;n._renderables.push(E(e,t));const r=B(e,t,()=>import("./gs-picking-pipeline-DUMOqxO3.esm.min.js"));n._disposables.push(()=>{r(),T(t)})}(e,i);return i}const k="KHR_gaussian_splatting",C="KHR_gaussian_splatting:ROTATION",F="KHR_gaussian_splatting:SCALE",V="KHR_gaussian_splatting:OPACITY",z="KHR_gaussian_splatting:SH_DEGREE_0_COEF_0",P=5120,j=5121,N=5122,D=5123,U=5125,q=5126,H={[P]:1,[j]:1,[N]:2,[D]:2,[U]:4,[q]:4},W=.28209479177387814;function X(e){return e<=0?0:e>=255?255:e+.5|0}function K(e){if(e?.extensions?.[k])return!0;const t=e?.attributes;if(!t)return!1;for(const e in t)if(e.startsWith(k+":"))return!0;return!1}function Q(e,t,n){const r=e.accessors[n],o=x[r.type]??1,s=r.count,i=new Float32Array(s*o);if(void 0===r.bufferView)return i;const a=e.bufferViews[r.bufferView],l=r.componentType,c=H[l]??4,u=o*c,f=a.byteStride??u,p=!!r.normalized,d=t.byteOffset+(a.byteOffset??0)+(r.byteOffset??0),g=new DataView(t.buffer);for(let e=0;e<s;e++){const t=d+e*f;for(let n=0;n<o;n++){const r=t+n*c;let s;switch(l){case 5126:default:s=g.getFloat32(r,!0);break;case 5121:s=p?g.getUint8(r)/255:g.getUint8(r);break;case 5120:s=p?Math.max(g.getInt8(r)/127,-1):g.getInt8(r);break;case 5123:s=p?g.getUint16(r,!0)/65535:g.getUint16(r,!0);break;case 5122:s=p?Math.max(g.getInt16(r,!0)/32767,-1):g.getInt16(r,!0);break;case 5125:s=g.getUint32(r,!0)}i[e*o+n]=s}}return i}function Y(e,t,n){const r=n.attributes,o=Q(e,t,r.POSITION),s=o.length/3|0,i=void 0!==r[F]?Q(e,t,r[F]):null,a=void 0!==r[C]?Q(e,t,r[C]):null,l=void 0!==r[V]?Q(e,t,r[V]):null,c=void 0!==r[z]?Q(e,t,r[z]):null,u=void 0!==r.COLOR_0?Q(e,t,r.COLOR_0):null,f=u?u.length/s|0:0,p=new ArrayBuffer(32*s),d=new Float32Array(p),g=new Uint8Array(p);for(let e=0;e<s;e++){const t=8*e,n=32*e,r=3*e;if(d[t+0]=o[r+0],d[t+1]=o[r+1],d[t+2]=o[r+2],d[t+3]=i?i[r+0]:1,d[t+4]=i?i[r+1]:1,d[t+5]=i?i[r+2]:1,c)g[n+24]=X(255*(.5+W*c[r+0])),g[n+25]=X(255*(.5+W*c[r+1])),g[n+26]=X(255*(.5+W*c[r+2]));else if(u){const t=e*f;g[n+24]=X(255*u[t+0]),g[n+25]=X(255*u[t+1]),g[n+26]=X(255*u[t+2])}else g[n+24]=255,g[n+25]=255,g[n+26]=255;g[n+27]=l?X(255*l[e]):u&&f>=4?X(255*u[e*f+3]):255;const s=4*e,p=a?a[s+0]:0,v=a?a[s+1]:0,_=a?a[s+2]:0,b=a?a[s+3]:1;g[n+28]=X(127.5*b+127.5),g[n+29]=X(127.5*p+127.5),g[n+30]=X(127.5*v+127.5),g[n+31]=X(127.5*_+127.5)}return p}const $={id:k,async preParse(e){const t=[],n=e.meshes??[];for(let e=0;e<n.length;e++){const r=n[e],o=r?.primitives;if(!o?.length)continue;const s=[];for(let n=0;n<o.length;n++){const i=o[n];K(i)?t.push({name:`${r.name??"splat"}_${e}_${n}`,attributes:i.attributes}):s.push(i)}r.primitives=s}t.length&&(e.__gsSplats=t)},async applyAsset(e,t,n){const r=n._json.__gsSplats;if(!r?.length)return{};const o=r.map(e=>({name:e.name,buffer:Y(n._json,n._binChunk,e)})),s=[];return{_sceneSetup:e=>{for(const t of o)s.push(L(e,t.name,{data:t.buffer}).then(e=>(e.rotation.z=Math.PI,e)))},_gaussianSplats:s}}};var J=Object.freeze({__proto__:null,default:$});export{S as a,T as d,J as g,M as p,B as r,R as u};
//# sourceMappingURL=gltf-feature-gaussian-splatting-Ce1heiDe.esm.min.js.map