rgbd 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/rgbd.js +1 -1
  2. package/package.json +1 -1
package/dist/rgbd.js CHANGED
@@ -79,4 +79,4 @@ var M=class{constructor(){this.context=null,this.sourceNodes=null,this.gainNode=
79
79
  :host([fullbleed]) { display:block; width:100%; height:100%; }
80
80
  canvas { touch-action: none; }
81
81
  .cover-img, .cover-video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
82
- `,this.L.appendChild(e),this.i=document.createElement("canvas"),this.i.style.width="100%",this.i.style.height="100%",this.i.style.objectFit="contain",this.i.setAttribute("role","img"),this.i.setAttribute("aria-label","3D image"),t.appendChild(this.i),this.p=document.createElement("button"),this.p.textContent="Enter VR",Object.assign(this.p.style,{position:"absolute",display:"none",top:"1%",right:"1%",color:"white",background:"rgba(0,0,0,0.4)",padding:"8px 8px",fontFamily:"monospace",fontSize:"20px",borderRadius:"8px",border:"1px solid white",backdropFilter:"blur(6px)",whiteSpace:"pre"}),t.appendChild(this.p),this.p.addEventListener("click",()=>{this.o?this.et():this.vt()})}connectedCallback(){this.G();let t;try{this.Et(),t=!1}catch{t=!0}this.i.addEventListener("resize",this.J),this.i.addEventListener("mousemove",this.Q),this.i.addEventListener("mouseleave",this.$),t?this.H():(this.w(),this.k=!0,this.P=performance.now(),this.A=requestAnimationFrame(this.v)),this.it()}disconnectedCallback(){this.k=!1,cancelAnimationFrame(this.A),this.i.removeEventListener("resize",this.J),this.i.removeEventListener("mousemove",this.Q),this.i.removeEventListener("mouseleave",this.$);try{this.o&&(this.o.end(),this.o=null,this.xt=!1)}catch{}try{if(this.h){let t=this.h;this.S&&t.deleteProgram(this.S);for(let e in this.T)t.deleteTexture(this.T[e].tex)}}catch{}}setViewMatrix(t){this.K=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this.Y=t&&t.length===16?new Float32Array(t):null}get width(){return this.g(this.t)}get height(){return this._(this.t)}Et(){let t=this.i.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this.h=t;let e=this.Mt(t,v,a);if(!e)return;this.S=e,t.useProgram(e);let i=this.st(t),s=this.st(t);this.T.color=i,this.T.depth=s,this.E("color",this.t),this.E("depth",this.d);let h=t.getUniformLocation(e,"u_colorImage"),n=t.getUniformLocation(e,"u_depthImage");t.uniform1i(h,0),t.uniform1i(n,1),this.f={uProjection:t.getUniformLocation(e,"u_projMat"),uView:t.getUniformLocation(e,"u_viewMat"),uImageSize:t.getUniformLocation(e,"u_imageSize"),uFocal:t.getUniformLocation(e,"u_focal"),uDepthMin:t.getUniformLocation(e,"u_depthMin"),uDepthMax:t.getUniformLocation(e,"u_depthMax"),uGridSegs:t.getUniformLocation(e,"u_grid"),uXr:t.getUniformLocation(e,"u_xr")}}ht(t=null){if(!this.h)return;let e=this.h;e.bindFramebuffer(e.FRAMEBUFFER,t),e.useProgram(this.S),e.clearColor(...this.s.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST)}nt(t,e){if(!this.h)return;let i=this.h,s=this.g(this.t),h=this._(this.t),n=s/h,r=Math.max(1,Math.floor(this.s.GRID_SIZE)),u=Math.max(1,Math.round(r/n));i.uniform2f(this.f.uImageSize,s,h),i.uniform1f(this.f.uFocal,this.s.FOCAL_LENGTH),i.uniform1f(this.f.uDepthMin,this.s.DEPTH_MIN),i.uniform1f(this.f.uDepthMax,this.s.DEPTH_MAX),i.uniform2i(this.f.uGridSegs,r,u),i.uniform1ui(this.f.uXr,this.o?1:0),i.uniformMatrix4fv(this.f.uView,!1,t),i.uniformMatrix4fv(this.f.uProjection,!1,e),i.drawArrays(i.TRIANGLES,0,r*u*6)}N(t,e){if(!this.k)return;let i=t-this.P;this.P=t,this.rt(),this.m.hovered||(this.m.x=Math.sin(t*this.s.BOOMERANG_SPEED),this.m.y=Math.sin(t*this.s.BOOMERANG_SPEED*.5+Math.PI));let s=this.m.x*this.s.CAM_MAX_THETA+Math.PI,h=-this.m.y*this.s.CAM_MAX_PHI,n=this.s.CAM_RADIUS*(1-this.s.CAM_ZOOM_AMOUNT),r=this.m.hovered?n:this.s.CAM_RADIUS;if(this.r.theta=this.F(s,this.r.theta,i),this.r.phi=this.F(h,this.r.phi,i),this.r.radius=this.F(r,this.r.radius,i),this.o){let u=e.session,f=e.getViewerPose(this.U);if(!f){u.requestAnimationFrame(this.v);return}let l=u.renderState.baseLayer;this.ht(l.framebuffer);for(let d of f.views){let g=l.getViewport(d);this.h.viewport(g.x,g.y,g.width,g.height);let _=new Float32Array(d.transform.inverse.matrix),T=new Float32Array(d.projectionMatrix);this.nt(_,T)}}else{let u=this.i.width/this.i.height,f=[this.r.radius*Math.cos(this.r.phi)*Math.sin(this.r.theta),this.r.radius*Math.sin(this.r.phi),this.s.CAM_RADIUS+this.r.radius*Math.cos(this.r.phi)*Math.cos(this.r.theta)],l=[0,0,this.s.CAM_RADIUS],d=[0,-1,0],g=this.height*(1-this.s.IMG_ZOOM_AMOUNT),_=2*Math.atan(g/(2*this.s.FOCAL_LENGTH)),T=this.K||new Float32Array(this.bt(f,l,d)),S=this.Y||new Float32Array(this.Tt(_,u,.1,100));this.ht(),this.nt(T,S)}this.o?this.A=e.session.requestAnimationFrame(this.v):this.A=requestAnimationFrame(this.v)}it(){this.tt&&navigator.xr&&navigator.xr.isSessionSupported?navigator.xr.isSessionSupported("immersive-vr").then(t=>{this.p.style.display=t?"block":"none"}).catch(()=>{this.p.style.display="none"}):this.p.style.display="none"}async vt(){if(!this.o)try{let t=await navigator.xr.requestSession("immersive-vr",{optionalFeatures:["local-floor","bounded-floor"]});this.h.makeXRCompatible&&await this.h.makeXRCompatible(),this.w();let e=new XRWebGLLayer(t,this.h);await t.updateRenderState({baseLayer:e});let i=await t.requestReferenceSpace("local");this.o=t,this.U=i,cancelAnimationFrame(this.A),t.addEventListener("end",()=>{this.et()}),t.requestAnimationFrame(this.v)}catch(t){console.warn("Unable to start XR session",t)}}async et(){if(this.o){try{await this.o.end()}catch{}this.o=null,this.U=null,this.w(),this.A=requestAnimationFrame(this.v)}}_t(t){let e=this.i.getBoundingClientRect();this.m.hovered=!0,this.m.x=(t.clientX-e.left)/e.width*2-1,this.m.y=(t.clientY-e.top)/e.height*2-1}At(){this.m.hovered=!1}w(){let t=window.devicePixelRatio||1,e=this.i.parentElement;if(!e)return;let i=e.clientWidth,s=e.clientHeight,h=this.g(this.t)||1,n=this._(this.t)||1,r=h/n,u=i,f=u/r;f>s&&(f=s,u=f*r);let l=Math.max(1,Math.floor((this.o?i:u)*t)),d=Math.max(1,Math.floor((this.o?s:f)*t));this.i.width=l,this.i.height=d,this.h&&this.h.viewport(0,0,l,d)}G(){let t=this.s;if(this.hasAttribute("grid-size")&&(t.GRID_SIZE=parseInt(this.getAttribute("grid-size"))??t.GRID_SIZE),this.hasAttribute("focal-length")&&(t.FOCAL_LENGTH=parseFloat(this.getAttribute("focal-length"))??t.FOCAL_LENGTH),this.hasAttribute("depth-min")&&(t.DEPTH_MIN=parseFloat(this.getAttribute("depth-min"))??t.DEPTH_MIN),this.hasAttribute("depth-max")&&(t.DEPTH_MAX=parseFloat(this.getAttribute("depth-max"))??t.DEPTH_MAX),this.hasAttribute("cam-radius")&&(t.CAM_RADIUS=parseFloat(this.getAttribute("cam-radius"))??t.CAM_RADIUS),this.hasAttribute("cam-max-theta")&&(t.CAM_MAX_THETA=parseFloat(this.getAttribute("cam-max-theta"))??t.CAM_MAX_THETA),this.hasAttribute("cam-max-phi")&&(t.CAM_MAX_PHI=parseFloat(this.getAttribute("cam-max-phi"))??t.CAM_MAX_PHI),this.hasAttribute("cam-smoothness")&&(t.CAM_SMOOTHNESS=parseFloat(this.getAttribute("cam-smoothness"))??t.CAM_SMOOTHNESS),this.hasAttribute("cam-zoom-amount")&&(t.CAM_ZOOM_AMOUNT=parseFloat(this.getAttribute("cam-zoom-amount"))??t.CAM_ZOOM_AMOUNT),this.hasAttribute("boomerang-speed")&&(t.BOOMERANG_SPEED=parseFloat(this.getAttribute("boomerang-speed"))??t.BOOMERANG_SPEED),this.hasAttribute("background-color"))try{let e=this.getAttribute("background-color").split(",").map(Number);e.length===3&&(t.BACKGROUND_COLOR=e)}catch{}this.hasAttribute("img-zoom-amount")&&(t.IMG_ZOOM_AMOUNT=parseFloat(this.getAttribute("img-zoom-amount"))??t.IMG_ZOOM_AMOUNT),this.tt=this.hasAttribute("allow-xr"),this.it()}ot(t,e,i){let s=t.createShader(e);return t.shaderSource(s,i),t.compileShader(s),t.getShaderParameter(s,t.COMPILE_STATUS)?s:(console.error(t.getShaderInfoLog(s)),t.deleteShader(s),null)}Mt(t,e,i){let s=this.ot(t,t.VERTEX_SHADER,e),h=this.ot(t,t.FRAGMENT_SHADER,i);if(!s||!h)return null;let n=t.createProgram();return t.attachShader(n,s),t.attachShader(n,h),t.linkProgram(n),t.getProgramParameter(n,t.LINK_STATUS)?(t.deleteShader(s),t.deleteShader(h),n):(console.error(t.getProgramInfoLog(n)),t.deleteProgram(n),null)}st(t){let e=t.createTexture();return t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),{tex:e,width:0,height:0}}E(t,e){if(!this.h)return;let i=this.h,s=this.T[t];if(i.activeTexture(t==="color"?i.TEXTURE0:i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,s.tex),!this.B(e)){i.texImage2D(i.TEXTURE_2D,0,i.RGBA,1,1,0,i.RGBA,i.UNSIGNED_BYTE,new Uint8Array([0,0,0,0]));return}try{i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!1),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,e),(this.g(e)!=s.width||this._(e)!=s.height)&&(this.w(),s.width=this.g(e),s.height=this._(e))}catch{}}Tt(t,e,i,s){let h=1/Math.tan(t/2);return[h/e,0,0,0,0,h,0,0,0,0,(s+i)/(i-s),-1,0,0,2*s*i/(i-s),0]}bt(t,e,i){function s(l){let d=Math.hypot(...l)||1;return l.map(g=>g/d)}function h(l,d){return[l[1]*d[2]-l[2]*d[1],l[2]*d[0]-l[0]*d[2],l[0]*d[1]-l[1]*d[0]]}function n(l,d){return l.map((g,_)=>g-d[_])}let r=s(n(t,e)),u=s(h(i,r)),f=h(r,u);return[u[0],f[0],r[0],0,u[1],f[1],r[1],0,u[2],f[2],r[2],0,-(u[0]*t[0]+u[1]*t[1]+u[2]*t[2]),-(f[0]*t[0]+f[1]*t[1]+f[2]*t[2]),-(r[0]*t[0]+r[1]*t[1]+r[2]*t[2]),1]}F(t,e,i){let s=(1-this.s.CAM_SMOOTHNESS)*i/16.67,h=Math.sign(t-e);return e+=(t-e)*s,Math.sign(t-e)!==h&&(e=t),e}H(){throw new Error("Must implement _createFallback")}rt(){}B(t){throw new Error("Must implement _isSourceReady")}g(t){throw new Error("Must implement _getSourceWidth")}_(t){throw new Error("Must implement _getSourceHeight")}}b=p;class m extends b{static get observedAttributes(){return["color-src","depth-src","grid-size","focal-length","depth-min","depth-max","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color","allow-xr"]}constructor(){super(),this.t=new Image,this.d=new Image,this.t.crossOrigin="anonymous",this.d.crossOrigin="anonymous",this.t.onload=()=>this.E("color",this.t),this.d.onload=()=>this.E("depth",this.d)}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.t.src=i||"":t==="depth-src"?this.d.src=i||"":this.G())}H(){this.t.style.display="block",this.t.classList.add("cover-img"),this.i.parentElement.appendChild(this.t)}B(t){return t&&t.complete&&t.naturalWidth>0}g(t){return t?t.width:1}_(t){return t?t.height:1}}w=m;class c extends b{static get observedAttributes(){return["color-src","depth-src","grid-size","focal-length","depth-min","depth-max","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color","allow-xr","autoplay","loop","muted","controls"]}constructor(){super(),this.n=[],this.a=[],this.u=[],this.X=!1,this.z=!1,this.C=!0,this.e=new M,this.e.pause(),this.W=!1,this.M=document.createElement("div"),this.M.classList.add("rgbd-controls"),Object.assign(this.M.style,{position:"absolute",bottom:"1%",left:"50%",transform:"translateX(-50%)",display:"none",alignItems:"center",justifyContent:"center",gap:"8px",background:"rgba(0, 0, 0, 0.4)",padding:"8px 8px",borderRadius:"8px",backdropFilter:"blur(6px)",boxSizing:"border-box",width:"50%",flexWrap:"wrap"}),this.shadowRoot.appendChild(this.M),this.R=document.createElement("button"),Object.assign(this.R.style,{border:"none",background:"transparent",color:"white",fontSize:"24px",cursor:"pointer",padding:"4px",flexShrink:"0"}),this.M.appendChild(this.R),this.R.addEventListener("click",()=>{this.paused?this.play():this.pause()}),this.l=document.createElement("input"),this.l.type="range",this.l.min="0",this.l.max="1",this.l.value="0",this.l.step="any",Object.assign(this.l.style,{flex:"1 1 auto",minWidth:"120px",maxWidth:"100%",cursor:"pointer",accentColor:"#fff"}),this.M.appendChild(this.l),this.l.addEventListener("input",()=>{let t=this.n[0];if(!t||!t.duration)return;let e=t.startTime+this.l.value*t.duration;this.currentTime=e})}disconnectedCallback(){this.e.started()&&this.e.stop(),super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.clear().then(()=>{this.n=[this.b(i,0,!1)],this.u=[this.b(i,0,!0)],this.at=this.n[0],this.ut=this.u[0]}):t==="depth-src"?(this.a=[this.b(i,0,!1)],this.ct=this.a[0]):t==="autoplay"?(this.X=this.hasAttribute("autoplay"),this.X&&this.e.play()):t==="loop"?this.z=this.hasAttribute("loop"):t==="muted"?(this.C=this.hasAttribute("muted"),this.e.setVolume(this.C?0:1),!this.C&&this.e.started()&&this.e.resumeContext()):t==="controls"?(this.W=this.hasAttribute("controls"),this.M.style.display=this.W?"flex":"none"):this.G())}async play(){await this.e.play()}async pause(){await this.e.pause()}async clear(){for(let t=0;t<this.n.length;t++)this.O(this.n[t]);for(let t=0;t<this.a.length;t++)this.O(this.a[t]);for(let t=0;t<this.u.length;t++)this.O(this.u[t]);this.e.setVideoTime(0),this.e.started()&&await this.e.stop()}enqueue(t,e,i){this.n.push(this.b(t,i,!1)),this.a.push(this.b(e,i,!1)),this.u.push(this.b(t,i,!0))}get paused(){return this.e.isPaused}get currentTime(){return this.e.getVideoTime()}set currentTime(t){let e=i=>{if(i.length==0)return;this.O(i[0]),i[0]=this.D(i[0],i[0].startTime);let s=i[0];s.demuxer!=null&&console.error("Demuxing not yet finished!");let h=Number.MAX_VALUE,n=-1;for(let r=0;r<s.chunks.length;r++){if(s.chunks[r].type!=="key")continue;let u=Math.abs(t-(s.startTime+s.chunks[r].timestamp/1e6));u<h&&(h=u,n=r)}n<0||(s.curChunk=n)};this.e.setVideoTime(t),this.V=null,e(this.n),e(this.a),e(this.u)}get volume(){return this.e.volume}set volume(t){this.e.setVolume(t)}yt(t){if(this.e.started()){if(t==null)return;if(t.sampleRate!=this.e.sampleRate)throw new Error("Audio configs have mismatched sample rates!");if(t.numberOfChannels!=this.e.numChannels)throw new Error("Audio configs have mismatched channel counts!")}else this.e.start(t?{sampleRate:t.sampleRate,numChannels:t.numberOfChannels,volume:1}:{audioEnabled:!1}),this.C||this.e.resumeContext()}lt(t,e){let i=e+t.timestamp/1e6,s=[];for(let h=0;h<t.numberOfChannels;h++){let n=new Float32Array(t.numberOfFrames);t.copyTo(n,{planeIndex:h,format:"f32-planar"}),s.push(n)}this.e.scheduleChunk(s,i)}b(t,e,i){let s={startTime:e,isAudio:i,duration:0,demuxer:null,decoder:null,chunks:[],frames:[],curChunk:0},h;return i?h=AudioDecoder:h=VideoDecoder,s.decoder=new h({output:n=>{i?this.lt(n,s.startTime):s.frames.push(n)},error:n=>{console.error("Decoder encountered an error while decoding: ",n)}}),s.demuxer=new x(t,i,{onConfig:n=>{s.config=n,n?s.decoder?.configure(n):s.done=!0,i&&this.yt(n)},onChunk:n=>{s.chunks?.push(n),s.duration=Math.max(s.duration,(n.timestamp+n.duration)/1e6)},onEndOfStream:()=>{s.demuxer=null}}),s}D(t,e){let i={startTime:e,isAudio:t.isAudio,duration:t.duration,demuxer:null,decoder:null,config:t.config,chunks:t.chunks,frames:[],curChunk:0},s;return t.isAudio?s=AudioDecoder:s=VideoDecoder,i.decoder=new s({output:h=>{i.isAudio?this.lt(h,i.startTime):i.frames.push(h)},error:h=>{console.error("Decoder encountered an error while decoding: ",h)}}),t.config?i.decoder.configure(t.config):i.done=!0,i}wt(){let t=!this.paused;this.R.textContent=t?"\u23F8\uFE0F":"\u25B6\uFE0F";let e=this.n[0];if(!e||!e.duration){this.l.value=0;return}let i=this.currentTime-e.startTime,s=Math.max(0,Math.min(1,i/e.duration));this.l.value=s}N(t,e){let i=(h,n)=>{let r=h[n];for(;r.curChunk<r.chunks.length;){let u=r.chunks[r.curChunk];if(r.startTime+u.timestamp/1e6>this.e.getVideoTime()+1)break;r.decoder.decode(u),r.curChunk++}if(r.curChunk>=r.chunks.length&&!r.demuxer&&r.decoder){let u=r.decoder;u.flush().then(()=>{u.close(),r.done=!0}),r.decoder=null}};for(let h=0;h<this.n.length;h++)i(this.n,h);for(let h=0;h<this.a.length;h++)i(this.a,h);for(let h=0;h<this.u.length;h++)this.u[h].config!=null&&i(this.u,h);let s=h=>h?h.done&&h.frames.length==1:!1;s(this.n[0])&&s(this.a[0])&&(this.n.shift(),this.a.shift(),this.dt=!0),this.u[0]?.done&&this.u.shift(),this.z&&this.n.length==0&&this.a.length==0&&this.u.length==0&&this.at!=null&&this.ct!=null&&this.ut!=null&&(this.e.setVideoTime(0),this.n=[this.D(this.at,0)],this.a=[this.D(this.ct,0)],this.u=[this.D(this.ut,0)]),this.W&&this.wt(),super.N(t,e)}H(){this.t=document.createElement("video"),this.t.style.display="block",this.t.classList.add("cover-video"),this.t.muted=this.C,this.t.autoplay=this.X,this.t.loop=this.z,this.t.src=this.getAttribute("color-src"),this.i.parentElement.appendChild(this.t)}rt(){let t=this.n[0],e=this.a[0];if(!t||!e)return;let i=this.e.getVideoTime(),s=this.V!=null?Math.abs(i-this.V):Number.MAX_VALUE,h=-1;for(let n=0;n<Math.min(t.frames.length,e.frames.length);n++){let r=Math.abs(i-(t.startTime+t.frames[n].timestamp/1e6));if(r<=s)s=r,h=n;else break}if(!(h<0)){this.dt&&(this.t.close(),this.d.close(),this.dt=!1),this.t=t.frames[h],this.d=e.frames[h],this.V=t.startTime+this.t.timestamp/1e6,this.t?.timestamp!==this.d?.timestamp&&console.error("Color and depth frames have mismatched PTS"),this.E("color",this.t),this.E("depth",this.d);for(let n=0;n<h;n++)t.frames.shift().close(),e.frames.shift().close()}}B(t){return t instanceof VideoFrame}g(t){return t?t.codedWidth:1}_(t){return t?t.codedHeight:1}O(t){t.decoder?.close(),t.decoder=null;for(let e=0;e<t.frames.length;e++)t.frames[e].close()}}C=c,customElements.define("rgbd-img",w),customElements.define("rgbd-video",C)}
82
+ `,this.L.appendChild(e),this.i=document.createElement("canvas"),this.i.style.width="100%",this.i.style.height="100%",this.i.style.objectFit="contain",this.i.setAttribute("role","img"),this.i.setAttribute("aria-label","3D image"),t.appendChild(this.i),this.p=document.createElement("button"),this.p.textContent="Enter VR",Object.assign(this.p.style,{position:"absolute",display:"none",top:"1%",right:"1%",color:"white",background:"rgba(0,0,0,0.4)",padding:"8px 8px",fontFamily:"monospace",fontSize:"20px",borderRadius:"8px",border:"1px solid white",backdropFilter:"blur(6px)",whiteSpace:"pre"}),t.appendChild(this.p),this.p.addEventListener("click",()=>{this.o?this.et():this.vt()})}connectedCallback(){this.G();let t;try{this.Et(),t=!1}catch{t=!0}this.i.addEventListener("resize",this.J),this.i.addEventListener("mousemove",this.Q),this.i.addEventListener("mouseleave",this.$),t?this.H():(this.w(),this.k=!0,this.P=performance.now(),this.A=requestAnimationFrame(this.v)),this.it()}disconnectedCallback(){this.k=!1,cancelAnimationFrame(this.A),this.i.removeEventListener("resize",this.J),this.i.removeEventListener("mousemove",this.Q),this.i.removeEventListener("mouseleave",this.$);try{this.o&&(this.o.end(),this.o=null,this.xt=!1)}catch{}try{if(this.h){let t=this.h;this.S&&t.deleteProgram(this.S);for(let e in this.T)t.deleteTexture(this.T[e].tex)}}catch{}}setViewMatrix(t){this.K=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this.Y=t&&t.length===16?new Float32Array(t):null}get width(){return this.g(this.t)}get height(){return this._(this.t)}Et(){let t=this.i.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this.h=t;let e=this.Mt(t,v,a);if(!e)return;this.S=e,t.useProgram(e);let i=this.st(t),s=this.st(t);this.T.color=i,this.T.depth=s,this.E("color",this.t),this.E("depth",this.d);let h=t.getUniformLocation(e,"u_colorImage"),n=t.getUniformLocation(e,"u_depthImage");t.uniform1i(h,0),t.uniform1i(n,1),this.f={uProjection:t.getUniformLocation(e,"u_projMat"),uView:t.getUniformLocation(e,"u_viewMat"),uImageSize:t.getUniformLocation(e,"u_imageSize"),uFocal:t.getUniformLocation(e,"u_focal"),uDepthMin:t.getUniformLocation(e,"u_depthMin"),uDepthMax:t.getUniformLocation(e,"u_depthMax"),uGridSegs:t.getUniformLocation(e,"u_grid"),uXr:t.getUniformLocation(e,"u_xr")}}ht(t=null){if(!this.h)return;let e=this.h;e.bindFramebuffer(e.FRAMEBUFFER,t),e.useProgram(this.S),e.clearColor(...this.s.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST)}nt(t,e){if(!this.h)return;let i=this.h,s=this.g(this.t),h=this._(this.t),n=s/h,r=Math.max(1,Math.floor(this.s.GRID_SIZE)),u=Math.max(1,Math.round(r/n));i.uniform2f(this.f.uImageSize,s,h),i.uniform1f(this.f.uFocal,this.s.FOCAL_LENGTH),i.uniform1f(this.f.uDepthMin,this.s.DEPTH_MIN),i.uniform1f(this.f.uDepthMax,this.s.DEPTH_MAX),i.uniform2i(this.f.uGridSegs,r,u),i.uniform1ui(this.f.uXr,this.o?1:0),i.uniformMatrix4fv(this.f.uView,!1,t),i.uniformMatrix4fv(this.f.uProjection,!1,e),i.drawArrays(i.TRIANGLES,0,r*u*6)}N(t,e){if(!this.k)return;let i=t-this.P;this.P=t,this.rt(),this.m.hovered||(this.m.x=Math.sin(t*this.s.BOOMERANG_SPEED),this.m.y=Math.sin(t*this.s.BOOMERANG_SPEED*.5+Math.PI));let s=this.m.x*this.s.CAM_MAX_THETA+Math.PI,h=-this.m.y*this.s.CAM_MAX_PHI,n=this.s.CAM_RADIUS*(1-this.s.CAM_ZOOM_AMOUNT),r=this.m.hovered?n:this.s.CAM_RADIUS;if(this.r.theta=this.F(s,this.r.theta,i),this.r.phi=this.F(h,this.r.phi,i),this.r.radius=this.F(r,this.r.radius,i),this.o){let u=e.session,f=e.getViewerPose(this.U);if(!f){u.requestAnimationFrame(this.v);return}let l=u.renderState.baseLayer;this.ht(l.framebuffer);for(let d of f.views){let g=l.getViewport(d);this.h.viewport(g.x,g.y,g.width,g.height);let _=new Float32Array(d.transform.inverse.matrix),T=new Float32Array(d.projectionMatrix);this.nt(_,T)}}else{let u=this.i.width/this.i.height,f=[this.r.radius*Math.cos(this.r.phi)*Math.sin(this.r.theta),this.r.radius*Math.sin(this.r.phi),this.s.CAM_RADIUS+this.r.radius*Math.cos(this.r.phi)*Math.cos(this.r.theta)],l=[0,0,this.s.CAM_RADIUS],d=[0,-1,0],g=this.height*(1-this.s.IMG_ZOOM_AMOUNT),_=2*Math.atan(g/(2*this.s.FOCAL_LENGTH)),T=this.K||new Float32Array(this.bt(f,l,d)),S=this.Y||new Float32Array(this.Tt(_,u,.1,100));this.ht(),this.nt(T,S)}this.o?this.A=e.session.requestAnimationFrame(this.v):this.A=requestAnimationFrame(this.v)}it(){this.tt&&navigator.xr&&navigator.xr.isSessionSupported?navigator.xr.isSessionSupported("immersive-vr").then(t=>{this.p.style.display=t?"block":"none"}).catch(()=>{this.p.style.display="none"}):this.p.style.display="none"}async vt(){if(!this.o)try{let t=await navigator.xr.requestSession("immersive-vr",{optionalFeatures:["local-floor","bounded-floor"]});this.h.makeXRCompatible&&await this.h.makeXRCompatible(),this.w();let e=new XRWebGLLayer(t,this.h);await t.updateRenderState({baseLayer:e});let i=await t.requestReferenceSpace("local");this.o=t,this.U=i,cancelAnimationFrame(this.A),t.addEventListener("end",()=>{this.et()}),t.requestAnimationFrame(this.v)}catch(t){console.warn("Unable to start XR session",t)}}async et(){if(this.o){try{await this.o.end()}catch{}this.o=null,this.U=null,this.w(),this.A=requestAnimationFrame(this.v)}}_t(t){let e=this.i.getBoundingClientRect();this.m.hovered=!0,this.m.x=(t.clientX-e.left)/e.width*2-1,this.m.y=(t.clientY-e.top)/e.height*2-1}At(){this.m.hovered=!1}w(){let t=window.devicePixelRatio||1,e=this.i.parentElement;if(!e)return;let i=e.clientWidth,s=e.clientHeight,h=this.g(this.t)||1,n=this._(this.t)||1,r=h/n,u=i,f=u/r;f>s&&(f=s,u=f*r);let l=Math.max(1,Math.floor((this.o?i:u)*t)),d=Math.max(1,Math.floor((this.o?s:f)*t));this.i.width=l,this.i.height=d,this.h&&this.h.viewport(0,0,l,d)}G(){let t=this.s;if(this.hasAttribute("grid-size")&&(t.GRID_SIZE=parseInt(this.getAttribute("grid-size"))??t.GRID_SIZE),this.hasAttribute("focal-length")&&(t.FOCAL_LENGTH=parseFloat(this.getAttribute("focal-length"))??t.FOCAL_LENGTH),this.hasAttribute("depth-min")&&(t.DEPTH_MIN=parseFloat(this.getAttribute("depth-min"))??t.DEPTH_MIN),this.hasAttribute("depth-max")&&(t.DEPTH_MAX=parseFloat(this.getAttribute("depth-max"))??t.DEPTH_MAX),this.hasAttribute("cam-radius")&&(t.CAM_RADIUS=parseFloat(this.getAttribute("cam-radius"))??t.CAM_RADIUS),this.hasAttribute("cam-max-theta")&&(t.CAM_MAX_THETA=parseFloat(this.getAttribute("cam-max-theta"))??t.CAM_MAX_THETA),this.hasAttribute("cam-max-phi")&&(t.CAM_MAX_PHI=parseFloat(this.getAttribute("cam-max-phi"))??t.CAM_MAX_PHI),this.hasAttribute("cam-smoothness")&&(t.CAM_SMOOTHNESS=parseFloat(this.getAttribute("cam-smoothness"))??t.CAM_SMOOTHNESS),this.hasAttribute("cam-zoom-amount")&&(t.CAM_ZOOM_AMOUNT=parseFloat(this.getAttribute("cam-zoom-amount"))??t.CAM_ZOOM_AMOUNT),this.hasAttribute("boomerang-speed")&&(t.BOOMERANG_SPEED=parseFloat(this.getAttribute("boomerang-speed"))??t.BOOMERANG_SPEED),this.hasAttribute("background-color"))try{let e=this.getAttribute("background-color").split(",").map(Number);e.length===3&&(t.BACKGROUND_COLOR=e)}catch{}this.hasAttribute("img-zoom-amount")&&(t.IMG_ZOOM_AMOUNT=parseFloat(this.getAttribute("img-zoom-amount"))??t.IMG_ZOOM_AMOUNT),this.tt=this.hasAttribute("allow-xr"),this.it()}ot(t,e,i){let s=t.createShader(e);return t.shaderSource(s,i),t.compileShader(s),t.getShaderParameter(s,t.COMPILE_STATUS)?s:(console.error(t.getShaderInfoLog(s)),t.deleteShader(s),null)}Mt(t,e,i){let s=this.ot(t,t.VERTEX_SHADER,e),h=this.ot(t,t.FRAGMENT_SHADER,i);if(!s||!h)return null;let n=t.createProgram();return t.attachShader(n,s),t.attachShader(n,h),t.linkProgram(n),t.getProgramParameter(n,t.LINK_STATUS)?(t.deleteShader(s),t.deleteShader(h),n):(console.error(t.getProgramInfoLog(n)),t.deleteProgram(n),null)}st(t){let e=t.createTexture();return t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),{tex:e,width:0,height:0}}E(t,e){if(!this.h)return;let i=this.h,s=this.T[t];if(i.activeTexture(t==="color"?i.TEXTURE0:i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,s.tex),!this.B(e)){i.texImage2D(i.TEXTURE_2D,0,i.RGBA,1,1,0,i.RGBA,i.UNSIGNED_BYTE,new Uint8Array([0,0,0,0]));return}try{i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!1),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,e),(this.g(e)!=s.width||this._(e)!=s.height)&&(this.w(),s.width=this.g(e),s.height=this._(e))}catch{}}Tt(t,e,i,s){let h=1/Math.tan(t/2);return[h/e,0,0,0,0,h,0,0,0,0,(s+i)/(i-s),-1,0,0,2*s*i/(i-s),0]}bt(t,e,i){function s(l){let d=Math.hypot(...l)||1;return l.map(g=>g/d)}function h(l,d){return[l[1]*d[2]-l[2]*d[1],l[2]*d[0]-l[0]*d[2],l[0]*d[1]-l[1]*d[0]]}function n(l,d){return l.map((g,_)=>g-d[_])}let r=s(n(t,e)),u=s(h(i,r)),f=h(r,u);return[u[0],f[0],r[0],0,u[1],f[1],r[1],0,u[2],f[2],r[2],0,-(u[0]*t[0]+u[1]*t[1]+u[2]*t[2]),-(f[0]*t[0]+f[1]*t[1]+f[2]*t[2]),-(r[0]*t[0]+r[1]*t[1]+r[2]*t[2]),1]}F(t,e,i){let s=(1-this.s.CAM_SMOOTHNESS)*i/16.67,h=Math.sign(t-e);return e+=(t-e)*s,Math.sign(t-e)!==h&&(e=t),e}H(){throw new Error("Must implement _createFallback")}rt(){}B(t){throw new Error("Must implement _isSourceReady")}g(t){throw new Error("Must implement _getSourceWidth")}_(t){throw new Error("Must implement _getSourceHeight")}}b=p;class m extends b{static get observedAttributes(){return["color-src","depth-src","grid-size","focal-length","depth-min","depth-max","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color","allow-xr"]}constructor(){super(),this.t=new Image,this.d=new Image,this.t.crossOrigin="anonymous",this.d.crossOrigin="anonymous",this.t.onload=()=>this.E("color",this.t),this.d.onload=()=>this.E("depth",this.d)}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.t.src=i||"":t==="depth-src"?this.d.src=i||"":this.G())}H(){this.t.style.display="block",this.t.classList.add("cover-img"),this.i.parentElement.appendChild(this.t)}B(t){return t&&t.complete&&t.naturalWidth>0}g(t){return t?t.width:1}_(t){return t?t.height:1}}w=m;class c extends b{static get observedAttributes(){return["color-src","depth-src","grid-size","focal-length","depth-min","depth-max","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color","allow-xr","autoplay","loop","muted","controls"]}constructor(){super(),this.n=[],this.a=[],this.u=[],this.X=!1,this.z=!1,this.C=!0,this.e=new M,this.e.pause(),this.W=!1,this.M=document.createElement("div"),this.M.classList.add("rgbd-controls"),Object.assign(this.M.style,{position:"absolute",bottom:"1%",left:"50%",transform:"translateX(-50%)",display:"none",alignItems:"center",justifyContent:"center",gap:"8px",background:"rgba(0, 0, 0, 0.4)",padding:"8px 8px",borderRadius:"8px",backdropFilter:"blur(6px)",boxSizing:"border-box",width:"50%",flexWrap:"wrap"}),this.shadowRoot.appendChild(this.M),this.R=document.createElement("button"),Object.assign(this.R.style,{border:"none",background:"transparent",color:"white",fontSize:"24px",cursor:"pointer",padding:"4px",flexShrink:"0"}),this.M.appendChild(this.R),this.R.addEventListener("click",()=>{this.paused?this.play():this.pause()}),this.l=document.createElement("input"),this.l.type="range",this.l.min="0",this.l.max="1",this.l.value="0",this.l.step="any",Object.assign(this.l.style,{flex:"1 1 auto",minWidth:"120px",maxWidth:"100%",cursor:"pointer",accentColor:"#fff"}),this.M.appendChild(this.l),this.l.addEventListener("input",()=>{let t=this.n[0];if(!t||!t.duration)return;let e=t.startTime+this.l.value*t.duration;this.currentTime=e})}disconnectedCallback(){this.e.started()&&this.e.stop(),super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.clear().then(()=>{this.n=[this.b(i,0,!1)],this.u=[this.b(i,0,!0)],this.at=this.n[0],this.ut=this.u[0]}):t==="depth-src"?(this.a=[this.b(i,0,!1)],this.ct=this.a[0]):t==="autoplay"?(this.X=this.hasAttribute("autoplay"),this.X&&this.e.play()):t==="loop"?this.z=this.hasAttribute("loop"):t==="muted"?(this.C=this.hasAttribute("muted"),this.e.setVolume(this.C?0:1),!this.C&&this.e.started()&&this.e.resumeContext()):t==="controls"?(this.W=this.hasAttribute("controls"),this.M.style.display=this.W?"flex":"none"):this.G())}async play(){await this.e.play()}async pause(){await this.e.pause()}async clear(){for(let t=0;t<this.n.length;t++)this.O(this.n[t]);for(let t=0;t<this.a.length;t++)this.O(this.a[t]);for(let t=0;t<this.u.length;t++)this.O(this.u[t]);this.currentTime=0,this.e.started()&&await this.e.stop()}enqueue(t,e,i){this.n.push(this.b(t,i,!1)),this.a.push(this.b(e,i,!1)),this.u.push(this.b(t,i,!0))}get paused(){return this.e.isPaused}get currentTime(){return this.e.getVideoTime()}set currentTime(t){let e=i=>{if(i.length==0)return;this.O(i[0]),i[0]=this.D(i[0],i[0].startTime);let s=i[0];s.demuxer!=null&&console.error("Demuxing not yet finished!");let h=Number.MAX_VALUE,n=-1;for(let r=0;r<s.chunks.length;r++){if(s.chunks[r].type!=="key")continue;let u=Math.abs(t-(s.startTime+s.chunks[r].timestamp/1e6));u<h&&(h=u,n=r)}n<0||(s.curChunk=n)};this.e.setVideoTime(t),this.V=null,e(this.n),e(this.a),e(this.u)}get volume(){return this.e.volume}set volume(t){this.e.setVolume(t)}yt(t){if(this.e.started()){if(t==null)return;if(t.sampleRate!=this.e.sampleRate)throw new Error("Audio configs have mismatched sample rates!");if(t.numberOfChannels!=this.e.numChannels)throw new Error("Audio configs have mismatched channel counts!")}else this.e.start(t?{sampleRate:t.sampleRate,numChannels:t.numberOfChannels,volume:1}:{audioEnabled:!1}),this.C||this.e.resumeContext()}lt(t,e){let i=e+t.timestamp/1e6,s=[];for(let h=0;h<t.numberOfChannels;h++){let n=new Float32Array(t.numberOfFrames);t.copyTo(n,{planeIndex:h,format:"f32-planar"}),s.push(n)}this.e.scheduleChunk(s,i)}b(t,e,i){let s={startTime:e,isAudio:i,duration:0,demuxer:null,decoder:null,chunks:[],frames:[],curChunk:0},h;return i?h=AudioDecoder:h=VideoDecoder,s.decoder=new h({output:n=>{i?this.lt(n,s.startTime):s.frames.push(n)},error:n=>{console.error("Decoder encountered an error while decoding: ",n)}}),s.demuxer=new x(t,i,{onConfig:n=>{s.config=n,n?s.decoder?.configure(n):s.done=!0,i&&this.yt(n)},onChunk:n=>{s.chunks?.push(n),s.duration=Math.max(s.duration,(n.timestamp+n.duration)/1e6)},onEndOfStream:()=>{s.demuxer=null}}),s}D(t,e){let i={startTime:e,isAudio:t.isAudio,duration:t.duration,demuxer:null,decoder:null,config:t.config,chunks:t.chunks,frames:[],curChunk:0},s;return t.isAudio?s=AudioDecoder:s=VideoDecoder,i.decoder=new s({output:h=>{i.isAudio?this.lt(h,i.startTime):i.frames.push(h)},error:h=>{console.error("Decoder encountered an error while decoding: ",h)}}),t.config?i.decoder.configure(t.config):i.done=!0,i}wt(){let t=!this.paused;this.R.textContent=t?"\u23F8\uFE0F":"\u25B6\uFE0F";let e=this.n[0];if(!e||!e.duration){this.l.value=0;return}let i=this.currentTime-e.startTime,s=Math.max(0,Math.min(1,i/e.duration));this.l.value=s}N(t,e){let i=(h,n)=>{let r=h[n];for(;r.curChunk<r.chunks.length;){let u=r.chunks[r.curChunk];if(r.startTime+u.timestamp/1e6>this.e.getVideoTime()+1)break;r.decoder.decode(u),r.curChunk++}if(r.curChunk>=r.chunks.length&&!r.demuxer&&r.decoder){let u=r.decoder;u.flush().then(()=>{u.close(),r.done=!0}),r.decoder=null}};for(let h=0;h<this.n.length;h++)i(this.n,h);for(let h=0;h<this.a.length;h++)i(this.a,h);for(let h=0;h<this.u.length;h++)this.u[h].config!=null&&i(this.u,h);let s=h=>h?h.done&&h.frames.length==1:!1;s(this.n[0])&&s(this.a[0])&&(this.n.shift(),this.a.shift(),this.dt=!0),this.u[0]?.done&&this.u.shift(),this.z&&this.n.length==0&&this.a.length==0&&this.u.length==0&&this.at!=null&&this.ct!=null&&this.ut!=null&&(this.e.setVideoTime(0),this.n=[this.D(this.at,0)],this.a=[this.D(this.ct,0)],this.u=[this.D(this.ut,0)]),this.W&&this.wt(),super.N(t,e)}H(){this.t=document.createElement("video"),this.t.style.display="block",this.t.classList.add("cover-video"),this.t.muted=this.C,this.t.autoplay=this.X,this.t.loop=this.z,this.t.src=this.getAttribute("color-src"),this.i.parentElement.appendChild(this.t)}rt(){let t=this.n[0],e=this.a[0];if(!t||!e)return;let i=this.e.getVideoTime(),s=this.V!=null?Math.abs(i-this.V):Number.MAX_VALUE,h=-1;for(let n=0;n<Math.min(t.frames.length,e.frames.length);n++){let r=Math.abs(i-(t.startTime+t.frames[n].timestamp/1e6));if(r<=s)s=r,h=n;else break}if(!(h<0)){this.dt&&(this.t.close(),this.d.close(),this.dt=!1),this.t=t.frames[h],this.d=e.frames[h],this.V=t.startTime+this.t.timestamp/1e6,this.t?.timestamp!==this.d?.timestamp&&console.error("Color and depth frames have mismatched PTS"),this.E("color",this.t),this.E("depth",this.d);for(let n=0;n<h;n++)t.frames.shift().close(),e.frames.shift().close()}}B(t){return t instanceof VideoFrame}g(t){return t?t.codedWidth:1}_(t){return t?t.codedHeight:1}O(t){t.decoder?.close(),t.decoder=null;for(let e=0;e<t.frames.length;e++)t.frames[e].close()}}C=c,customElements.define("rgbd-img",w),customElements.define("rgbd-video",C)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rgbd",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "type": "module",
5
5
  "main": "dist/rgbd.js",
6
6
  "module": "dist/rgbd.js",