rgbd 1.0.7 → 1.0.9

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/index.js +3 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -74,12 +74,12 @@ void main()
74
74
  {
75
75
  fragColor = texture(u_colorImage, v_uv);
76
76
  }
77
- `,R=typeof window<"u"&&typeof HTMLElement<"u"&&typeof document<"u";R?p=class extends HTMLElement{constructor(){super(),this.t={GRID_SIZE:250,FOCAL_LENGTH:1200,DEPTH_MIN:.1,DEPTH_MAX:10,CAM_RADIUS:1.5,CAM_MAX_THETA_UNFOCUSED:Math.PI/32,CAM_MAX_PHI_UNFOCUSED:Math.PI/32,CAM_MAX_THETA_FOCUSED:Math.PI/32,CAM_MAX_PHI_FOCUSED:Math.PI/32,CAM_SMOOTHNESS:.9,CAM_ZOOM_AMOUNT:.2,BOOMERANG_SPEED:.001,BOOMERANG_SHAPE:"z",BACKGROUND_COLOR:[0,0,0],IMG_ZOOM_AMOUNT:0,XR_RECENTER_RADIUS:.5,XR_RECENTER_YAW:45},this.V=null,this.i=null,this.e=null,this.f=null,this.h=null,this.k=null,this.N={},this.g=null,this.m={x:0,y:0,hovered:!1},this.F=!1,this.yt=null,this.a={theta:Math.PI,phi:0,radius:this.t.CAM_RADIUS},this.j=0,this.D=null,this.Y=!1,this.rt=null,this.at=null,this.Tt=this.L.bind(this),this.P=this.Z.bind(this),this.Ct=this.Rt.bind(this),this.wt=this.St.bind(this),this.ut=this.Ot.bind(this),this.Dt=this.Pt.bind(this),this.ct=!1,this.r=null,this.T=null,this.U=null,this.o=null,this.Ut=!1,this.A=null,this.V=this.attachShadow({mode:"open"});let t=document.createElement("div");t.style.position="relative",t.style.width="100%",t.style.height="100%",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.background="black",this.V.appendChild(t);let e=document.createElement("style");e.textContent=`
77
+ `,C=typeof window<"u"&&typeof HTMLElement<"u"&&typeof document<"u";C?p=class extends HTMLElement{constructor(){super(),this.t={GRID_SIZE:250,FOCAL_LENGTH:1200,DEPTH_MIN:.1,DEPTH_MAX:10,CAM_RADIUS:1.5,CAM_MAX_THETA_UNFOCUSED:Math.PI/32,CAM_MAX_PHI_UNFOCUSED:Math.PI/32,CAM_MAX_THETA_FOCUSED:Math.PI/32,CAM_MAX_PHI_FOCUSED:Math.PI/32,CAM_SMOOTHNESS:.9,CAM_ZOOM_AMOUNT:.2,BOOMERANG_SPEED:.001,BOOMERANG_SHAPE:"z",BACKGROUND_COLOR:[0,0,0],IMG_ZOOM_AMOUNT:0,XR_RECENTER_RADIUS:.5,XR_RECENTER_YAW:45},this.W=null,this.s=null,this.e=null,this.f=null,this.h=null,this.k=null,this.N={},this.g=null,this.p={x:0,y:0,hovered:!1},this.a={theta:Math.PI,phi:0,radius:this.t.CAM_RADIUS},this.Ft=null,this.D=null,this.V=!1,this.ot=null,this.nt=null,this.rt=this.L.bind(this),this.P=this.j.bind(this),this.at=this.Tt.bind(this),this.ut=this.Rt.bind(this),this.ct=!1,this.r=null,this.T=null,this.U=null,this.o=null,this.Ct=!1,this.A=null,this.W=this.attachShadow({mode:"open"});let t=document.createElement("div");t.style.position="relative",t.style.width="100%",t.style.height="100%",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.background="black",this.W.appendChild(t);let e=document.createElement("style");e.textContent=`
78
78
  :host { display: inline-block; width: 300px; height: 200px; }
79
79
  :host([fullbleed]) { display:block; width:100%; height:100%; }
80
80
  canvas { touch-action: none; }
81
81
  .fallback { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; }
82
- `,this.V.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.A=document.createElement("button"),this.A.textContent="Enter VR",Object.assign(this.A.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.A),this.A.addEventListener("click",()=>{this.r?this.exitXR():this.enterXR()})}connectedCallback(){this.K();let t;try{this.It(),t=!1}catch{t=!0}this.i.addEventListener("pointerdown",this.Ct),this.i.addEventListener("pointermove",this.wt),this.i.addEventListener("pointerup",this.ut),this.i.addEventListener("pointercancel",this.ut),this.i.addEventListener("pointerleave",this.Dt),t?this.q():(this.L(),this.Y=!0,this.j=performance.now(),this.D=requestAnimationFrame(this.P)),this.lt()}disconnectedCallback(){this.Y=!1,cancelAnimationFrame(this.D),this.i.removeEventListener("resize",this.Tt),this.i.removeEventListener("mousemove",this.Vt),this.i.removeEventListener("mouseleave",this.jt);try{this.r&&(this.r.end(),this.r=null,this.Ut=!1)}catch{}try{if(this.h){let t=this.h;this.k&&t.deleteProgram(this.k);for(let e in this.N)t.deleteTexture(this.N[e].tex)}}catch{}}setViewMatrix(t){this.rt=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this.at=t&&t.length===16?new Float32Array(t):null}async enterXR(){if(!this.r)try{let t=await navigator.xr.requestSession("immersive-vr",{optionalFeatures:["local-floor","bounded-floor"]});this.h.makeXRCompatible&&await this.h.makeXRCompatible(),this.L();let e=new XRWebGLLayer(t,this.h);await t.updateRenderState({baseLayer:e});let i=await t.requestReferenceSpace("local");this.r=t,this.T=i,this.U=null,this.o={x:0,y:0,z:0,yaw:0},cancelAnimationFrame(this.D),t.addEventListener("end",()=>{this.exitXR()}),t.requestAnimationFrame(this.P)}catch(t){console.warn("Unable to start XR session",t)}}async exitXR(){if(this.r){try{await this.r.end()}catch{}this.r=null,this.T=null,this.U=null,this.L(),this.D=requestAnimationFrame(this.P)}}get width(){return this.C(this.e)}get height(){return this.R(this.e)}It(){let t=this.i.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this.h=t;let e=this.dt(t,I,N);if(!e)return;this.k=e,t.useProgram(e);let i=this.ft(t),s=this.ft(t);this.N.color=i,this.N.depth=s,this.M("color",this.e),this.M("depth",this.f);let h=t.getUniformLocation(e,"u_colorImage"),o=t.getUniformLocation(e,"u_depthImage");t.uniform1i(h,0),t.uniform1i(o,1),this.g={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")}}mt(t=null){if(!this.h)return;let e=this.h;e.bindFramebuffer(e.FRAMEBUFFER,t),e.clearColor(...this.t.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST)}X(t,e){if(!this.h)return;let i=this.h;i.useProgram(this.k);let s=this.C(this.e),h=this.R(this.e),o=s/h,n=Math.max(1,Math.floor(this.t.GRID_SIZE)),r=Math.max(1,Math.round(n/o));i.uniform2f(this.g.uImageSize,s,h),i.uniform1f(this.g.uFocal,this.t.FOCAL_LENGTH),i.uniform1f(this.g.uDepthMin,this.t.DEPTH_MIN),i.uniform1f(this.g.uDepthMax,this.t.DEPTH_MAX),i.uniform2i(this.g.uGridSegs,n,r),i.uniform1ui(this.g.uXr,this.r?1:0),i.uniformMatrix4fv(this.g.uView,!1,t),i.uniformMatrix4fv(this.g.uProjection,!1,e),i.drawArrays(i.TRIANGLES,0,n*r*6)}Z(t,e){if(!this.Y)return;let i=t-this.j;this.j=t,this.pt();let s,h;this.m.hovered?(s=this.m.x*this.t.CAM_MAX_THETA_FOCUSED+Math.PI,h=-this.m.y*this.t.CAM_MAX_PHI_FOCUSED):this.t.BOOMERANG_SHAPE==="z"?(s=Math.sin(t*this.t.BOOMERANG_SPEED)*this.t.CAM_MAX_THETA_UNFOCUSED+Math.PI,h=Math.sin(t*this.t.BOOMERANG_SPEED*.5+Math.PI)*this.t.CAM_MAX_PHI_UNFOCUSED):(s=Math.sin(t*this.t.BOOMERANG_SPEED)*this.t.CAM_MAX_THETA_UNFOCUSED+Math.PI,h=Math.cos(t*this.t.BOOMERANG_SPEED)*this.t.CAM_MAX_PHI_UNFOCUSED);let o=this.t.CAM_RADIUS*(1-this.t.CAM_ZOOM_AMOUNT),n=this.m.hovered?o:this.t.CAM_RADIUS;if(this.a.theta=this.S(s,this.a.theta,i),this.a.phi=this.S(h,this.a.phi,i),this.a.radius=this.S(n,this.a.radius,i),this.r){let r=this.T.getOffsetReferenceSpace(new XRRigidTransform({x:this.o.x,y:this.o.y,z:this.o.z},{x:0,y:Math.sin(this.o.yaw*.5),z:0,w:Math.cos(this.o.yaw*.5)}));this.o.x=this.S(0,this.o.x,i),this.o.y=this.S(0,this.o.y,i),this.o.z=this.S(0,this.o.z,i),this.o.yaw=this.S(0,this.o.yaw,i);let a=e.getViewerPose(this.T).transform;this.U||(this.U=a);let u=this.U,c=a.position.x-u.position.x,l=a.position.y-u.position.y,d=a.position.z-u.position.z,f=this._t(a.orientation);(Math.abs(f-this._t(u.orientation))>this.t.XR_RECENTER_YAW*Math.PI/180||Math.hypot(c,l,d)>this.t.XR_RECENTER_RADIUS)&&(this.o.x=-a.position.x,this.o.y=-a.position.y,this.o.z=-a.position.z,this.o.yaw=-f,this.T=this.T.getOffsetReferenceSpace(new XRRigidTransform(a.position,{x:0,y:Math.sin(f*.5),z:0,w:Math.cos(f*.5)})),this.U=null);let v=e.session,S=e.getViewerPose(r);if(!S){v.requestAnimationFrame(this.P);return}let O=v.renderState.baseLayer;this.mt(O.framebuffer);for(let C of S.views){let y=O.getViewport(C);this.h.viewport(y.x,y.y,y.width,y.height);let P=new Float32Array(C.transform.inverse.matrix),U=new Float32Array(C.projectionMatrix);this.X(P,U)}}else{let r=this.i.width/this.i.height,a=[this.a.radius*Math.cos(this.a.phi)*Math.sin(this.a.theta),this.a.radius*Math.sin(this.a.phi),this.t.CAM_RADIUS+this.a.radius*Math.cos(this.a.phi)*Math.cos(this.a.theta)],u=[0,0,this.t.CAM_RADIUS],c=[0,-1,0],l=this.height*(1-this.t.IMG_ZOOM_AMOUNT),d=2*Math.atan(l/(2*this.t.FOCAL_LENGTH)),f=this.rt||new Float32Array(this.Nt(a,u,c)),g=this.at||new Float32Array(this.Lt(d,r,.1,100));this.mt(),this.X(f,g)}this.r?this.D=e.session.requestAnimationFrame(this.P):this.D=requestAnimationFrame(this.P)}lt(){this.ct&&navigator.xr&&navigator.xr.isSessionSupported?navigator.xr.isSessionSupported("immersive-vr").then(t=>{this.A.style.display=t?"block":"none"}).catch(()=>{this.A.style.display="none"}):this.A.style.display="none"}Rt(t){this.F=!0,this.yt=t.pointerType,this.i.setPointerCapture(t.pointerId),this.m.hovered=!0,this.J(t)}St(t){if(t.pointerType==="mouse"){this.m.hovered=!0,this.J(t);return}this.F&&(this.m.hovered=!0,this.J(t))}Ot(t){this.F=!1,t.pointerType!=="mouse"&&(this.m.hovered=!1);try{this.i.releasePointerCapture(t.pointerId)}catch{}}Pt(){this.F=!1,this.m.hovered=!1}J(t){let e=this.i.getBoundingClientRect();this.m.x=(t.clientX-e.left)/e.width*2-1,this.m.y=(t.clientY-e.top)/e.height*2-1}L(){let t=window.devicePixelRatio||1,e=this.i.parentElement;if(!e)return;let i=e.clientWidth,s=e.clientHeight,h=this.C(this.e)||1,o=this.R(this.e)||1,n=h/o,r=i,a=r/n;a>s&&(a=s,r=a*n);let u=Math.max(1,Math.floor((this.r?i:r)*t)),c=Math.max(1,Math.floor((this.r?s:a)*t));this.i.width=u,this.i.height=c,this.h&&this.h.viewport(0,0,u,c)}K(){let t=this.t;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-unfocused")&&(t.CAM_MAX_THETA_UNFOCUSED=parseFloat(this.getAttribute("cam-max-theta-unfocused"))??t.CAM_MAX_THETA_UNFOCUSED),this.hasAttribute("cam-max-phi-unfocused")&&(t.CAM_MAX_PHI_UNFOCUSED=parseFloat(this.getAttribute("cam-max-phi-unfocused"))??t.CAM_MAX_PHI_UNFOCUSED),this.hasAttribute("cam-max-theta-focused")&&(t.CAM_MAX_THETA_FOCUSED=parseFloat(this.getAttribute("cam-max-theta-focused"))??t.CAM_MAX_THETA_FOCUSED),this.hasAttribute("cam-max-phi-focused")&&(t.CAM_MAX_PHI_FOCUSED=parseFloat(this.getAttribute("cam-max-phi-focused"))??t.CAM_MAX_PHI_FOCUSED),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("boomerang-shape")&&(t.BOOMERANG_SHAPE=this.getAttribute("boomerang-shape")==="circle"?"circle":"z"),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.ct=this.hasAttribute("xr-button"),this.hasAttribute("xr-recenter-yaw")&&(t.XR_RECENTER_YAW=parseFloat(this.getAttribute("xr-recenter-yaw"))??t.XR_RECENTER_YAW),this.hasAttribute("xr-recenter-radius")&&(t.XR_RECENTER_RADIUS=parseFloat(this.getAttribute("xr-recenter-radius"))??t.XR_RECENTER_RADIUS),this.lt()}gt(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)}dt(t,e,i){let s=this.gt(t,t.VERTEX_SHADER,e),h=this.gt(t,t.FRAGMENT_SHADER,i);if(!s||!h)return null;let o=t.createProgram();return t.attachShader(o,s),t.attachShader(o,h),t.linkProgram(o),t.getProgramParameter(o,t.LINK_STATUS)?(t.deleteShader(s),t.deleteShader(h),o):(console.error(t.getProgramInfoLog(o)),t.deleteProgram(o),null)}ft(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}}M(t,e){if(!this.h)return;let i=this.h,s=this.N[t];if(i.activeTexture(t==="color"?i.TEXTURE0:i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,s.tex),!this.Q(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.C(e)!=s.width||this.R(e)!=s.height)&&(this.L(),s.width=this.C(e),s.height=this.R(e))}catch{}}Lt(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]}Nt(t,e,i){function s(u){let c=Math.hypot(...u)||1;return u.map(l=>l/c)}function h(u,c){return[u[1]*c[2]-u[2]*c[1],u[2]*c[0]-u[0]*c[2],u[0]*c[1]-u[1]*c[0]]}function o(u,c){return u.map((l,d)=>l-c[d])}let n=s(o(t,e)),r=s(h(i,n)),a=h(n,r);return[r[0],a[0],n[0],0,r[1],a[1],n[1],0,r[2],a[2],n[2],0,-(r[0]*t[0]+r[1]*t[1]+r[2]*t[2]),-(a[0]*t[0]+a[1]*t[1]+a[2]*t[2]),-(n[0]*t[0]+n[1]*t[1]+n[2]*t[2]),1]}_t(t){return Math.atan2(2*(t.w*t.y+t.x*t.z),1-2*(t.y*t.y+t.x*t.x))}Ht(t){let e=-2*(t.x*t.z+t.w*t.y),i=-2*(t.y*t.z-t.w*t.x),s=2*(t.x*t.x+t.y*t.y)-1,h=Math.hypot(e,i,s)||1;return{x:e/h,y:i/h,z:s/h}}S(t,e,i){let s=(1-this.t.CAM_SMOOTHNESS)*i/16.67,h=Math.sign(t-e);return e+=(t-e)*s,Math.sign(t-e)!==h&&(e=t),e}q(){throw new Error("Must implement _createFallback")}pt(){}Q(t){throw new Error("Must implement _isSourceReady")}C(t){throw new Error("Must implement _getSourceWidth")}R(t){throw new Error("Must implement _getSourceHeight")}}:p=class{};var x=class extends p{static get observedAttributes(){return T}constructor(){super(),this.e=new Image,this.f=new Image,this.e.crossOrigin="anonymous",this.f.crossOrigin="anonymous",this.e.onload=()=>this.M("color",this.e),this.f.onload=()=>this.M("depth",this.f)}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.e.src=i||"":t==="depth-src"?this.f.src=i||"":this.K())}q(){this.e.style.display="block",this.e.classList.add("fallback"),this.i.parentElement.appendChild(this.e)}Q(t){return t&&t.complete&&t.naturalWidth>0}C(t){return t?t.width:1}R(t){return t?t.height:1}};var E=class{constructor(){this.context=null,this.sourceNodes=null,this.gainNode=null,this.volume=1,this.sampleRate=0,this.numChannels=0,this.timeSuspended=0,this.timeOffset=0,this.lastTime=0,this.context=null,this.isPaused=!1,this.loopHandle=null}start(t={}){if(this.context)throw new Error("Audio manager already started!");this.audioEnabled=t.audioEnabled??!0,this.sampleRate=t.sampleRate??44100,this.numChannels=t.numChannels??2,this.context=new AudioContext({sampleRate:this.sampleRate}),this.isPaused&&this.context.suspend(),this.sourceNodes=new Set,this.gainNode=this.context.createGain(),this.gainNode.gain.value=this.volume,this.gainNode.connect(this.context.destination),this.timeSuspended=0,this.timeOffset=0,this.lastTime=performance.now(),this.loopHandle=setInterval(()=>{let e=performance.now();!this.isPaused&&this.context.state==="suspended"&&(this.timeSuspended+=(e-this.lastTime)/1e3),this.lastTime=e},t.updateInterval??10),this.context.onstatechange=()=>{let e=performance.now();this.context?.state==="running"&&(this.timeSuspended+=(e-this.lastTime)/1e3),this.lastTime=e}}async stop(){if(!this.context)throw new Error("Audio manager not started!");clearInterval(this.loopHandle),this.loopHandle=null,await this.context.suspend(),this.context=null}started(){return this.context!=null}getTime(){return(this.context?.currentTime??0)+this.timeSuspended+this.timeOffset}getLatency(){return this.context?(this.context.outputLatency??0)+this.context.baseLatency:0}getVideoTime(){return this.getTime()-this.getLatency()}setVideoTime(t){if(t+=this.getLatency(),this.sourceNodes!=null){for(let e of this.sourceNodes)try{e.stop()}catch{}this.sourceNodes.clear()}this.timeOffset=t-((this.context?.currentTime??0)+this.timeSuspended)}setVolume(t){this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}async resumeContext(){if(!this.context)throw new Error("Audio manager not started!");this.context.state==="suspended"&&!this.isPaused&&await this.context.resume()}async pause(){this.isPaused||(this.context&&await this.context.suspend(),this.isPaused=!0)}async play(){this.isPaused&&(this.context&&await this.context.resume(),this.isPaused=!1)}scheduleChunk(t,e){let i=t[0].length;if(i<=0)return;let s=this.context.createBuffer(this.numChannels,i,this.sampleRate);for(let h=0;h<this.numChannels;h++)s.copyToChannel(t[h],h);if(e-=this.timeSuspended+this.timeOffset,e>this.context.currentTime&&this.context.state!=="suspended"){let h=this.context.createBufferSource();h.buffer=s,h.connect(this.gainNode),this.sourceNodes.add(h),h.onended=()=>this.sourceNodes.delete(h),h.start(e)}this.playHead+=s.duration}};import*as A from"mp4box";var w=class{constructor(t,e){this.d=t,this.vt=0,this.kt=e}write(t){let e=new ArrayBuffer(t.byteLength);new Uint8Array(e).set(t),e.fileStart=this.vt,this.vt+=e.byteLength,this.d.appendBuffer(e)}close(){this.d.flush(),this.kt()}},M=class{constructor(t,e,{onConfig:i,onChunk:s,onEndOfStream:h}){if(this.$=e,this.xt=i,this.Ft=s,this.d=A.createFile(),this.d.onReady=this.Xt.bind(this),this.d.onSamples=this.Gt.bind(this),this.done=!1,t instanceof ArrayBuffer)t.fileStart=0,this.d.appendBuffer(t),this.d.flush(),this.done=!0;else{let o=new w(this.d,()=>{this.done=!0});fetch(t).then(n=>{n.body.pipeTo(new WritableStream(o,{highWaterMark:2}))})}}Et(t){let i=this.d.getTrackById(t.id).mdia.minf.stbl.stsd.entries[0];if(this.$)return i.esds.esd.descs[0].descs[0].data;{let s=i.avcC||i.hvcC||i.vpcC||i.av1C;if(!s)return null;let h=new A.DataStream(void 0,0,A.DataStream.BIG_ENDIAN);return s.write(h),new Uint8Array(h.buffer,8)}}Xt(t){if(this.$){let e=t.audioTracks[0];this.xt(e?{codec:e.codec,sampleRate:e.audio.sample_rate,numberOfChannels:e.audio.channel_count,description:this.Et(e)}:null),e&&this.d.setExtractionOptions(e.id)}else{let e=t.videoTracks[0];this.xt({codec:e.codec.startsWith("vp08")?"vp8":e.codec,codedHeight:e.video.height,codedWidth:e.video.width,description:this.Et(e)}),this.d.setExtractionOptions(e.id)}this.d.start()}Gt(t,e,i){for(let s of i){let h;this.$?h=EncodedAudioChunk:h=EncodedVideoChunk,this.Ft(new h({type:s.is_sync?"key":"delta",timestamp:1e6*s.cts/s.timescale,duration:1e6*s.duration/s.timescale,data:s.data}))}}};var L=1,m=.1,D=.9,H=`#version 300 es
82
+ `,this.W.appendChild(e),this.s=document.createElement("canvas"),this.s.style.width="100%",this.s.style.height="100%",this.s.style.objectFit="contain",this.s.setAttribute("role","img"),this.s.setAttribute("aria-label","3D image"),t.appendChild(this.s),this.A=document.createElement("button"),this.A.textContent="Enter VR",Object.assign(this.A.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.A),this.A.addEventListener("click",()=>{this.r?this.exitXR():this.enterXR()})}connectedCallback(){this.Y();let t;try{this.wt(),t=!1}catch{t=!0}this.s.addEventListener("resize",this.rt),this.s.addEventListener("pointermove",this.at),this.s.addEventListener("pointerleave",this.ut),t?this.Z():(this.L(),this.V=!0,this.lt=performance.now(),this.D=requestAnimationFrame(this.P)),this.dt()}disconnectedCallback(){this.V=!1,cancelAnimationFrame(this.D),this.s.removeEventListener("resize",this.rt),this.s.removeEventListener("pointermove",this.at),this.s.removeEventListener("pointerleave",this.ut);try{this.r&&(this.r.end(),this.r=null,this.Ct=!1)}catch{}try{if(this.h){let t=this.h;this.k&&t.deleteProgram(this.k);for(let e in this.N)t.deleteTexture(this.N[e].tex)}}catch{}}setCamera(t){this.K=t}setViewMatrix(t){this.ot=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this.nt=t&&t.length===16?new Float32Array(t):null}async enterXR(){if(!this.r)try{let t=await navigator.xr.requestSession("immersive-vr",{optionalFeatures:["local-floor","bounded-floor"]});this.h.makeXRCompatible&&await this.h.makeXRCompatible(),this.L();let e=new XRWebGLLayer(t,this.h);await t.updateRenderState({baseLayer:e});let i=await t.requestReferenceSpace("local");this.r=t,this.T=i,this.U=null,this.o={x:0,y:0,z:0,yaw:0},cancelAnimationFrame(this.D),t.addEventListener("end",()=>{this.exitXR()}),t.requestAnimationFrame(this.P)}catch(t){console.warn("Unable to start XR session",t)}}async exitXR(){if(this.r){try{await this.r.end()}catch{}this.r=null,this.T=null,this.U=null,this.L(),this.D=requestAnimationFrame(this.P)}}get width(){return this.R(this.e)}get height(){return this.C(this.e)}wt(){let t=this.s.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this.h=t;let e=this.ft(t,I,N);if(!e)return;this.k=e,t.useProgram(e);let i=this.mt(t),s=this.mt(t);this.N.color=i,this.N.depth=s,this.M("color",this.e),this.M("depth",this.f);let h=t.getUniformLocation(e,"u_colorImage"),o=t.getUniformLocation(e,"u_depthImage");t.uniform1i(h,0),t.uniform1i(o,1),this.g={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")}}pt(t=null){if(!this.h)return;let e=this.h;e.bindFramebuffer(e.FRAMEBUFFER,t),e.clearColor(...this.t.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST)}F(t,e){if(!this.h)return;let i=this.h;i.useProgram(this.k);let s=this.R(this.e),h=this.C(this.e),o=s/h,n=Math.max(1,Math.floor(this.t.GRID_SIZE)),r=Math.max(1,Math.round(n/o));i.uniform2f(this.g.uImageSize,s,h),i.uniform1f(this.g.uFocal,this.t.FOCAL_LENGTH),i.uniform1f(this.g.uDepthMin,this.t.DEPTH_MIN),i.uniform1f(this.g.uDepthMax,this.t.DEPTH_MAX),i.uniform2i(this.g.uGridSegs,n,r),i.uniform1ui(this.g.uXr,this.r?1:0),i.uniformMatrix4fv(this.g.uView,!1,t),i.uniformMatrix4fv(this.g.uProjection,!1,e),i.drawArrays(i.TRIANGLES,0,n*r*6)}j(t,e){if(!this.V)return;let i=t-this.lt;this.lt=t,this._t();let s,h;this.p.hovered?(s=this.p.x*this.t.CAM_MAX_THETA_FOCUSED,h=-this.p.y*this.t.CAM_MAX_PHI_FOCUSED):this.t.BOOMERANG_SHAPE==="z"?(s=Math.sin(t*this.t.BOOMERANG_SPEED)*this.t.CAM_MAX_THETA_UNFOCUSED,h=Math.sin(t*this.t.BOOMERANG_SPEED*.5+Math.PI)*this.t.CAM_MAX_PHI_UNFOCUSED):(s=Math.sin(t*this.t.BOOMERANG_SPEED)*this.t.CAM_MAX_THETA_UNFOCUSED,h=Math.cos(t*this.t.BOOMERANG_SPEED)*this.t.CAM_MAX_PHI_UNFOCUSED);let o=this.t.CAM_RADIUS*(1-this.t.CAM_ZOOM_AMOUNT),n=this.p.hovered?o:this.t.CAM_RADIUS;if(s=(this.K?.theta??s)+Math.PI,h=this.K?.phi??h,n=this.K?.radius??n,this.a.theta=this.S(s,this.a.theta,i),this.a.phi=this.S(h,this.a.phi,i),this.a.radius=this.S(n,this.a.radius,i),this.r){let r=this.T.getOffsetReferenceSpace(new XRRigidTransform({x:this.o.x,y:this.o.y,z:this.o.z},{x:0,y:Math.sin(this.o.yaw*.5),z:0,w:Math.cos(this.o.yaw*.5)}));this.o.x=this.S(0,this.o.x,i),this.o.y=this.S(0,this.o.y,i),this.o.z=this.S(0,this.o.z,i),this.o.yaw=this.S(0,this.o.yaw,i);let a=e.getViewerPose(this.T).transform;this.U||(this.U=a);let u=this.U,c=a.position.x-u.position.x,l=a.position.y-u.position.y,d=a.position.z-u.position.z,f=this.gt(a.orientation);(Math.abs(f-this.gt(u.orientation))>this.t.XR_RECENTER_YAW*Math.PI/180||Math.hypot(c,l,d)>this.t.XR_RECENTER_RADIUS)&&(this.o.x=-a.position.x,this.o.y=-a.position.y,this.o.z=-a.position.z,this.o.yaw=-f,this.T=this.T.getOffsetReferenceSpace(new XRRigidTransform(a.position,{x:0,y:Math.sin(f*.5),z:0,w:Math.cos(f*.5)})),this.U=null);let x=e.session,S=e.getViewerPose(r);if(!S){x.requestAnimationFrame(this.P);return}let O=x.renderState.baseLayer;this.pt(O.framebuffer);for(let R of S.views){let y=O.getViewport(R);this.h.viewport(y.x,y.y,y.width,y.height);let P=new Float32Array(R.transform.inverse.matrix),U=new Float32Array(R.projectionMatrix);this.F(P,U)}}else{let r=this.s.width/this.s.height,a=[this.a.radius*Math.cos(this.a.phi)*Math.sin(this.a.theta),this.a.radius*Math.sin(this.a.phi),this.t.CAM_RADIUS+this.a.radius*Math.cos(this.a.phi)*Math.cos(this.a.theta)],u=[0,0,this.t.CAM_RADIUS],c=[0,-1,0],l=this.height*(1-this.t.IMG_ZOOM_AMOUNT),d=2*Math.atan(l/(2*this.t.FOCAL_LENGTH)),f=this.ot||new Float32Array(this.St(a,u,c)),g=this.nt||new Float32Array(this.Ot(d,r,.1,100));this.pt(),this.F(f,g)}this.r?this.D=e.session.requestAnimationFrame(this.P):this.D=requestAnimationFrame(this.P)}dt(){this.ct&&navigator.xr&&navigator.xr.isSessionSupported?navigator.xr.isSessionSupported("immersive-vr").then(t=>{this.A.style.display=t?"block":"none"}).catch(()=>{this.A.style.display="none"}):this.A.style.display="none"}Tt(t){if(t.pointerType!=="mouse")return;let e=this.s.getBoundingClientRect();this.p.hovered=!0,this.p.x=(t.clientX-e.left)/e.width*2-1,this.p.y=(t.clientY-e.top)/e.height*2-1}Rt(){this.p.hovered=!1}Xt(t){let e=this.s.getBoundingClientRect();this.p.x=(t.clientX-e.left)/e.width*2-1,this.p.y=(t.clientY-e.top)/e.height*2-1}L(){let t=window.devicePixelRatio||1,e=this.s.parentElement;if(!e)return;let i=e.clientWidth,s=e.clientHeight,h=this.R(this.e)||1,o=this.C(this.e)||1,n=h/o,r=i,a=r/n;a>s&&(a=s,r=a*n);let u=Math.max(1,Math.floor((this.r?i:r)*t)),c=Math.max(1,Math.floor((this.r?s:a)*t));this.s.width=u,this.s.height=c,this.h&&this.h.viewport(0,0,u,c)}Y(){let t=this.t;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-unfocused")&&(t.CAM_MAX_THETA_UNFOCUSED=parseFloat(this.getAttribute("cam-max-theta-unfocused"))??t.CAM_MAX_THETA_UNFOCUSED),this.hasAttribute("cam-max-phi-unfocused")&&(t.CAM_MAX_PHI_UNFOCUSED=parseFloat(this.getAttribute("cam-max-phi-unfocused"))??t.CAM_MAX_PHI_UNFOCUSED),this.hasAttribute("cam-max-theta-focused")&&(t.CAM_MAX_THETA_FOCUSED=parseFloat(this.getAttribute("cam-max-theta-focused"))??t.CAM_MAX_THETA_FOCUSED),this.hasAttribute("cam-max-phi-focused")&&(t.CAM_MAX_PHI_FOCUSED=parseFloat(this.getAttribute("cam-max-phi-focused"))??t.CAM_MAX_PHI_FOCUSED),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("boomerang-shape")&&(t.BOOMERANG_SHAPE=this.getAttribute("boomerang-shape")==="circle"?"circle":"z"),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.ct=this.hasAttribute("xr-button"),this.hasAttribute("xr-recenter-yaw")&&(t.XR_RECENTER_YAW=parseFloat(this.getAttribute("xr-recenter-yaw"))??t.XR_RECENTER_YAW),this.hasAttribute("xr-recenter-radius")&&(t.XR_RECENTER_RADIUS=parseFloat(this.getAttribute("xr-recenter-radius"))??t.XR_RECENTER_RADIUS),this.dt()}xt(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)}ft(t,e,i){let s=this.xt(t,t.VERTEX_SHADER,e),h=this.xt(t,t.FRAGMENT_SHADER,i);if(!s||!h)return null;let o=t.createProgram();return t.attachShader(o,s),t.attachShader(o,h),t.linkProgram(o),t.getProgramParameter(o,t.LINK_STATUS)?(t.deleteShader(s),t.deleteShader(h),o):(console.error(t.getProgramInfoLog(o)),t.deleteProgram(o),null)}mt(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}}M(t,e){if(!this.h)return;let i=this.h,s=this.N[t];if(i.activeTexture(t==="color"?i.TEXTURE0:i.TEXTURE1),i.bindTexture(i.TEXTURE_2D,s.tex),!this.q(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.R(e)!=s.width||this.C(e)!=s.height)&&(this.L(),s.width=this.R(e),s.height=this.C(e))}catch{}}Ot(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]}St(t,e,i){function s(u){let c=Math.hypot(...u)||1;return u.map(l=>l/c)}function h(u,c){return[u[1]*c[2]-u[2]*c[1],u[2]*c[0]-u[0]*c[2],u[0]*c[1]-u[1]*c[0]]}function o(u,c){return u.map((l,d)=>l-c[d])}let n=s(o(t,e)),r=s(h(i,n)),a=h(n,r);return[r[0],a[0],n[0],0,r[1],a[1],n[1],0,r[2],a[2],n[2],0,-(r[0]*t[0]+r[1]*t[1]+r[2]*t[2]),-(a[0]*t[0]+a[1]*t[1]+a[2]*t[2]),-(n[0]*t[0]+n[1]*t[1]+n[2]*t[2]),1]}gt(t){return Math.atan2(2*(t.w*t.y+t.x*t.z),1-2*(t.y*t.y+t.x*t.x))}Dt(t){let e=-2*(t.x*t.z+t.w*t.y),i=-2*(t.y*t.z-t.w*t.x),s=2*(t.x*t.x+t.y*t.y)-1,h=Math.hypot(e,i,s)||1;return{x:e/h,y:i/h,z:s/h}}S(t,e,i){let s=(1-this.t.CAM_SMOOTHNESS)*i/16.67,h=Math.sign(t-e);return e+=(t-e)*s,Math.sign(t-e)!==h&&(e=t),e}Z(){throw new Error("Must implement _createFallback")}_t(){}q(t){throw new Error("Must implement _isSourceReady")}R(t){throw new Error("Must implement _getSourceWidth")}C(t){throw new Error("Must implement _getSourceHeight")}}:p=class{};var v=class extends p{static get observedAttributes(){return T}constructor(){super(),this.e=new Image,this.f=new Image,this.e.crossOrigin="anonymous",this.f.crossOrigin="anonymous",this.e.onload=()=>this.M("color",this.e),this.f.onload=()=>this.M("depth",this.f)}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.e.src=i||"":t==="depth-src"?this.f.src=i||"":this.Y())}Z(){this.e.style.display="block",this.e.classList.add("fallback"),this.s.parentElement.appendChild(this.e)}q(t){return t&&t.complete&&t.naturalWidth>0}R(t){return t?t.width:1}C(t){return t?t.height:1}};var E=class{constructor(){this.context=null,this.sourceNodes=null,this.gainNode=null,this.volume=1,this.sampleRate=0,this.numChannels=0,this.timeSuspended=0,this.timeOffset=0,this.lastTime=0,this.context=null,this.isPaused=!1,this.loopHandle=null}start(t={}){if(this.context)throw new Error("Audio manager already started!");this.audioEnabled=t.audioEnabled??!0,this.sampleRate=t.sampleRate??44100,this.numChannels=t.numChannels??2,this.context=new AudioContext({sampleRate:this.sampleRate}),this.isPaused&&this.context.suspend(),this.sourceNodes=new Set,this.gainNode=this.context.createGain(),this.gainNode.gain.value=this.volume,this.gainNode.connect(this.context.destination),this.timeSuspended=0,this.timeOffset=0,this.lastTime=performance.now(),this.loopHandle=setInterval(()=>{let e=performance.now();!this.isPaused&&this.context.state==="suspended"&&(this.timeSuspended+=(e-this.lastTime)/1e3),this.lastTime=e},t.updateInterval??10),this.context.onstatechange=()=>{let e=performance.now();this.context?.state==="running"&&(this.timeSuspended+=(e-this.lastTime)/1e3),this.lastTime=e}}async stop(){if(!this.context)throw new Error("Audio manager not started!");clearInterval(this.loopHandle),this.loopHandle=null,await this.context.suspend(),this.context=null}started(){return this.context!=null}getTime(){return(this.context?.currentTime??0)+this.timeSuspended+this.timeOffset}getLatency(){return this.context?(this.context.outputLatency??0)+this.context.baseLatency:0}getVideoTime(){return this.getTime()-this.getLatency()}setVideoTime(t){if(t+=this.getLatency(),this.sourceNodes!=null){for(let e of this.sourceNodes)try{e.stop()}catch{}this.sourceNodes.clear()}this.timeOffset=t-((this.context?.currentTime??0)+this.timeSuspended)}setVolume(t){this.volume=t,this.gainNode&&(this.gainNode.gain.value=t)}async resumeContext(){if(!this.context)throw new Error("Audio manager not started!");this.context.state==="suspended"&&!this.isPaused&&await this.context.resume()}async pause(){this.isPaused||(this.context&&await this.context.suspend(),this.isPaused=!0)}async play(){this.isPaused&&(this.context&&await this.context.resume(),this.isPaused=!1)}scheduleChunk(t,e){let i=t[0].length;if(i<=0)return;let s=this.context.createBuffer(this.numChannels,i,this.sampleRate);for(let h=0;h<this.numChannels;h++)s.copyToChannel(t[h],h);if(e-=this.timeSuspended+this.timeOffset,e>this.context.currentTime&&this.context.state!=="suspended"){let h=this.context.createBufferSource();h.buffer=s,h.connect(this.gainNode),this.sourceNodes.add(h),h.onended=()=>this.sourceNodes.delete(h),h.start(e)}this.playHead+=s.duration}};import*as A from"mp4box";var w=class{constructor(t,e){this.d=t,this.vt=0,this.Pt=e}write(t){let e=new ArrayBuffer(t.byteLength);new Uint8Array(e).set(t),e.fileStart=this.vt,this.vt+=e.byteLength,this.d.appendBuffer(e)}close(){this.d.flush(),this.Pt()}},M=class{constructor(t,e,{onConfig:i,onChunk:s,onEndOfStream:h}){if(this.J=e,this.Et=i,this.Ut=s,this.d=A.createFile(),this.d.onReady=this.It.bind(this),this.d.onSamples=this.Nt.bind(this),this.done=!1,t instanceof ArrayBuffer)t.fileStart=0,this.d.appendBuffer(t),this.d.flush(),this.done=!0;else{let o=new w(this.d,()=>{this.done=!0});fetch(t).then(n=>{n.body.pipeTo(new WritableStream(o,{highWaterMark:2}))})}}At(t){let i=this.d.getTrackById(t.id).mdia.minf.stbl.stsd.entries[0];if(this.J)return i.esds.esd.descs[0].descs[0].data;{let s=i.avcC||i.hvcC||i.vpcC||i.av1C;if(!s)return null;let h=new A.DataStream(void 0,0,A.DataStream.BIG_ENDIAN);return s.write(h),new Uint8Array(h.buffer,8)}}It(t){if(this.J){let e=t.audioTracks[0];this.Et(e?{codec:e.codec,sampleRate:e.audio.sample_rate,numberOfChannels:e.audio.channel_count,description:this.At(e)}:null),e&&this.d.setExtractionOptions(e.id)}else{let e=t.videoTracks[0];this.Et({codec:e.codec.startsWith("vp08")?"vp8":e.codec,codedHeight:e.video.height,codedWidth:e.video.width,description:this.At(e)}),this.d.setExtractionOptions(e.id)}this.d.start()}Nt(t,e,i){for(let s of i){let h;this.J?h=EncodedAudioChunk:h=EncodedVideoChunk,this.Ut(new h({type:s.is_sync?"key":"delta",timestamp:1e6*s.cts/s.timescale,duration:1e6*s.duration/s.timescale,data:s.data}))}}};var L=1,m=.1,D=.9,H=`#version 300 es
83
83
 
84
84
  precision mediump float;
85
85
  precision mediump int;
@@ -213,4 +213,4 @@ void main()
213
213
 
214
214
  fragColor = vec4(col, 1.0);
215
215
  }
216
- `,b=class extends p{static get observedAttributes(){return T.concat(["autoplay","loop","muted","controls"])}constructor(){super(),this.n=[],this.c=[],this.l=[],this.tt=!1,this.et=!1,this.H=!0,this._=null,this.E=null,this.O=null,this.At=!1,this.s=new E,this.s.pause(),this.it=!1,this.b=document.createElement("div"),this.b.classList.add("rgbd-controls"),Object.assign(this.b.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.b),this.G=document.createElement("button"),Object.assign(this.G.style,{border:"none",background:"transparent",color:"white",fontSize:"24px",cursor:"pointer",padding:"4px",flexShrink:"0"}),this.b.appendChild(this.G),this.G.addEventListener("click",()=>{this.paused?this.play():this.pause()}),this.p=document.createElement("input"),this.p.type="range",this.p.min="0",this.p.max="1",this.p.value="0",this.p.step="any",Object.assign(this.p.style,{flex:"1 1 auto",minWidth:"120px",maxWidth:"100%",cursor:"pointer",accentColor:"#fff"}),this.b.appendChild(this.p),this.p.addEventListener("input",()=>{let t=this.n[0];if(!t||!t.duration)return;let e=t.startTime+this.p.value*t.duration;this.currentTime=e})}connectedCallback(){if(super.connectedCallback(),!this.h)return;let t=this.h;this._=this.dt(t,H,k),this.E={uProjection:t.getUniformLocation(this._,"u_projMat"),uView:t.getUniformLocation(this._,"u_viewMat"),uDepth:t.getUniformLocation(this._,"u_depth"),uHeight:t.getUniformLocation(this._,"u_height"),uScrubberWidth:t.getUniformLocation(this._,"u_scrubberWidth"),uProgress:t.getUniformLocation(this._,"u_progress"),uPaused:t.getUniformLocation(this._,"u_paused"),uHitPos:t.getUniformLocation(this._,"u_hitPos")}}disconnectedCallback(){this.s.started()&&this.s.stop(),super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.clear().then(()=>{this.n=[this.I(i,0,!1)],this.l=[this.I(i,0,!0)],this.st=this.n[0],this.ht=this.l[0]}):t==="depth-src"?(this.c=[this.I(i,0,!1)],this.ot=this.c[0]):t==="autoplay"?(this.tt=this.hasAttribute("autoplay"),this.tt&&this.s.play()):t==="loop"?this.et=this.hasAttribute("loop"):t==="muted"?(this.H=this.hasAttribute("muted"),this.s.setVolume(this.H?0:1),!this.H&&this.s.started()&&this.s.resumeContext()):t==="controls"?(this.it=this.hasAttribute("controls"),this.b.style.display=this.it?"flex":"none"):this.K())}async play(){await this.s.play()}async pause(){await this.s.pause()}async clear(){for(this.e=null,this.f=null,this.M("color",null),this.M("depth",null),this.st=null,this.ot=null,this.ht=null;this.n.length>0;)this.B(this.n.shift());for(;this.c.length>0;)this.B(this.c.shift());for(;this.l.length>0;)this.B(this.l.shift());this.currentTime=0,this.s.started()&&await this.s.stop()}enqueue(t,e,i){this.n.push(this.I(t,i,!1)),this.c.push(this.I(e,i,!1)),this.l.push(this.I(t,i,!0))}get paused(){return this.s.isPaused}get currentTime(){return this.s.getVideoTime()}set currentTime(t){let e=i=>{if(i.length==0)return;this.B(i[0]),i[0]=this.W(i[0],i[0].startTime);let s=i[0];s.demuxer.done||console.error("Demuxing not yet finished!");let h=Number.MAX_VALUE,o=-1;for(let n=0;n<s.chunks.length;n++){if(s.chunks[n].type!=="key")continue;let r=Math.abs(t-(s.startTime+s.chunks[n].timestamp/1e6));r<h&&(h=r,o=n)}o<0||(s.curChunk=o)};this.s.setVideoTime(t),this.nt=null,e(this.n),e(this.c),e(this.l)}get volume(){return this.s.volume}set volume(t){this.s.setVolume(t)}zt(t){if(this.s.started()){if(t==null)return;if(t.sampleRate!=this.s.sampleRate)throw new Error("Audio configs have mismatched sample rates!");if(t.numberOfChannels!=this.s.numChannels)throw new Error("Audio configs have mismatched channel counts!")}else this.s.start(t?{sampleRate:t.sampleRate,numChannels:t.numberOfChannels,volume:1}:{audioEnabled:!1}),this.H||this.s.resumeContext()}Mt(t,e){let i=e+t.timestamp/1e6,s=[];for(let h=0;h<t.numberOfChannels;h++){let o=new Float32Array(t.numberOfFrames);t.copyTo(o,{planeIndex:h,format:"f32-planar"}),s.push(o)}this.s.scheduleChunk(s,i)}I(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:o=>{i?this.Mt(o,s.startTime):s.frames.push(o)},error:o=>{console.error("Decoder encountered an error while decoding: ",o)}}),s.demuxer=new M(t,i,{onConfig:o=>{s.config=o,o?s.decoder?.configure(o):s.done=!0,i&&this.zt(o)},onChunk:o=>{s.chunks?.push(o),s.duration=Math.max(s.duration,(o.timestamp+o.duration)/1e6)}}),s}W(t,e){let i={startTime:e,isAudio:t.isAudio,duration:t.duration,demuxer:{done:!0},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.Mt(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}Bt(){let t=!this.paused;this.G.textContent=t?"\u23F8\uFE0F":"\u25B6\uFE0F";let e=this.n[0];if(!e||!e.duration){this.p.value=0;return}let i=this.currentTime-e.startTime,s=Math.max(0,Math.min(1,i/e.duration));this.p.value=s}Wt(t){let e=this.n[0];if(!e)return;this.O=null;let i=!1;for(let s of t.session.inputSources){if(!s.targetRaySpace)continue;let h=t.getPose(s.targetRaySpace,this.T);if(!h)continue;let o=h.transform.position,n=this.Ht(h.transform.orientation),r=(-this.t.DEPTH_MIN-o.z)/n.z;if(r<0)continue;let a=o.x+n.x*r,u=o.y+n.y*r,c=-.5*this.t.DEPTH_MIN,l=.5*this.t.DEPTH_MIN,d=(.5*m+.5+m/2)*-this.t.DEPTH_MIN,f=(-.5*m+.5+m/2)*-this.t.DEPTH_MIN;if(!(a<c||a>l||u<d||u>f)){if(this.O=this.O??{u:(a-c)/(l-c),v:(u-d)/(f-d)},s.gamepad?.buttons[0]?.pressed)i=!0;else continue;if(!this.At)if(this.O.u<m)this.paused?this.play():this.pause();else{let g=1-D,v=(this.O.u-m-g/2)/(1-m-g);this.currentTime=v*(e.duration??0),console.log(v)}}}this.At=i}X(t,e){if(super.X(t,e),!this.h)return;let i=this.h;if(this.r==null)return;let s=this.n[0];if(!s)return;let h;if(!s.duration)h=0;else{let o=this.currentTime-s.startTime;h=Math.max(0,Math.min(1,o/s.duration))}i.useProgram(this._),i.uniformMatrix4fv(this.E.uView,!1,t),i.uniformMatrix4fv(this.E.uProjection,!1,e),i.uniform1f(this.E.uDepth,this.t.DEPTH_MIN),i.uniform1f(this.E.uHeight,m),i.uniform1f(this.E.uScrubberWidth,D),i.uniform1f(this.E.uProgress,h),i.uniform1ui(this.E.uPaused,this.s.isPaused?1:0),i.uniform2f(this.E.uHitPos,this.O?.u??-1,this.O?.v??-1),i.drawArrays(i.TRIANGLES,0,6)}Z(t,e){let i=(h,o)=>{let n=h[o];for(;n.curChunk<n.chunks.length;){let r=n.chunks[n.curChunk];if(n.startTime+r.timestamp/1e6>this.s.getVideoTime()+L)break;n.decoder.decode(r),n.curChunk++}if(n.curChunk>=n.chunks.length&&n.demuxer.done&&n.decoder){let r=n.decoder;r.flush().then(()=>{r.close(),n.done=!0}),n.decoder=null}};for(let h=0;h<this.n.length;h++)i(this.n,h);for(let h=0;h<this.c.length;h++)i(this.c,h);for(let h=0;h<this.l.length;h++)this.l[h].config!=null&&i(this.l,h);let s=h=>h?h.done&&h.frames.length==1:!1;s(this.n[0])&&s(this.c[0])&&(this.n.shift(),this.c.shift(),this.bt=!0,this.onSegmentEnd?.(this.n.length==0)),this.l[0]?.done&&this.l.shift(),this.et&&this.n.length==0&&this.c.length==0&&this.l.length==0&&this.st!=null&&this.ot!=null&&(this.s.setVideoTime(0),this.n=[this.W(this.st,0)],this.c=[this.W(this.ot,0)],this.ht!=null&&(this.l=[this.W(this.ht,0)])),this.it&&this.Bt(),e!=null&&this.Wt(e),super.Z(t,e)}q(){this.e=document.createElement("video"),this.e.style.display="block",this.e.classList.add("fallback"),this.e.controls=this.b,this.e.muted=this.H,this.e.loop=this.et,this.e.autoplay=this.tt,this.e.src=this.getAttribute("color-src"),this.i.parentElement.appendChild(this.e),this.b.style.display="none"}pt(){let t=this.n[0],e=this.c[0];if(!t||!e)return;let i=this.s.getVideoTime(),s=this.nt!=null?Math.abs(i-this.nt):Number.MAX_VALUE,h=-1;for(let o=0;o<Math.min(t.frames.length,e.frames.length);o++){let n=Math.abs(i-(t.startTime+t.frames[o].timestamp/1e6));if(n<=s)s=n,h=o;else break}if(!(h<0)){this.bt&&(this.e?.close(),this.f?.close(),this.bt=!1),this.e=t.frames[h],this.f=e.frames[h],this.nt=t.startTime+this.e.timestamp/1e6,this.e?.timestamp!==this.f?.timestamp&&console.error("Color and depth frames have mismatched PTS"),this.M("color",this.e),this.M("depth",this.f);for(let o=0;o<h;o++)t.frames.shift().close(),e.frames.shift().close(),this.onFrameRendered?.()}}Q(t){return t instanceof VideoFrame}C(t){return t?t.codedWidth:1}R(t){return t?t.codedHeight:1}B(t){t.decoder?.close(),t.decoder=null;for(let e=0;e<t.frames.length;e++)t.frames[e].close()}};R&&(customElements.define("rgbd-img",x),customElements.define("rgbd-video",b));
216
+ `,b=class extends p{static get observedAttributes(){return T.concat(["autoplay","loop","muted","controls"])}constructor(){super(),this.n=[],this.c=[],this.l=[],this.Q=!1,this.$=!1,this.H=!0,this._=null,this.E=null,this.O=null,this.Mt=!1,this.i=new E,this.i.pause(),this.tt=!1,this.b=document.createElement("div"),this.b.classList.add("rgbd-controls"),Object.assign(this.b.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.b),this.X=document.createElement("button"),Object.assign(this.X.style,{border:"none",background:"transparent",color:"white",fontSize:"24px",cursor:"pointer",padding:"4px",flexShrink:"0"}),this.b.appendChild(this.X),this.X.addEventListener("click",()=>{this.paused?this.play():this.pause()}),this.m=document.createElement("input"),this.m.type="range",this.m.min="0",this.m.max="1",this.m.value="0",this.m.step="any",Object.assign(this.m.style,{flex:"1 1 auto",minWidth:"120px",maxWidth:"100%",cursor:"pointer",accentColor:"#fff"}),this.b.appendChild(this.m),this.m.addEventListener("input",()=>{let t=this.n[0];if(!t||!t.duration)return;let e=t.startTime+this.m.value*t.duration;this.currentTime=e})}connectedCallback(){if(super.connectedCallback(),!this.h)return;let t=this.h;this._=this.ft(t,H,k),this.E={uProjection:t.getUniformLocation(this._,"u_projMat"),uView:t.getUniformLocation(this._,"u_viewMat"),uDepth:t.getUniformLocation(this._,"u_depth"),uHeight:t.getUniformLocation(this._,"u_height"),uScrubberWidth:t.getUniformLocation(this._,"u_scrubberWidth"),uProgress:t.getUniformLocation(this._,"u_progress"),uPaused:t.getUniformLocation(this._,"u_paused"),uHitPos:t.getUniformLocation(this._,"u_hitPos")}}disconnectedCallback(){this.i.started()&&this.i.stop(),super.disconnectedCallback()}attributeChangedCallback(t,e,i){e!==i&&(t==="color-src"?this.clear().then(()=>{this.n=[this.I(i,0,!1)],this.l=[this.I(i,0,!0)],this.et=this.n[0],this.it=this.l[0]}):t==="depth-src"?(this.c=[this.I(i,0,!1)],this.st=this.c[0]):t==="autoplay"?(this.Q=this.hasAttribute("autoplay"),this.Q&&this.i.play()):t==="loop"?this.$=this.hasAttribute("loop"):t==="muted"?(this.H=this.hasAttribute("muted"),this.i.setVolume(this.H?0:1),!this.H&&this.i.started()&&this.i.resumeContext()):t==="controls"?(this.tt=this.hasAttribute("controls"),this.b.style.display=this.tt?"flex":"none"):this.Y())}async play(){await this.i.play()}async pause(){await this.i.pause()}async clear(){for(this.e=null,this.f=null,this.M("color",null),this.M("depth",null),this.et=null,this.st=null,this.it=null;this.n.length>0;)this.G(this.n.shift());for(;this.c.length>0;)this.G(this.c.shift());for(;this.l.length>0;)this.G(this.l.shift());this.currentTime=0,this.i.started()&&await this.i.stop()}enqueue(t,e,i){this.n.push(this.I(t,i,!1)),this.c.push(this.I(e,i,!1)),this.l.push(this.I(t,i,!0))}get paused(){return this.i.isPaused}get currentTime(){return this.i.getVideoTime()}set currentTime(t){let e=i=>{if(i.length==0)return;this.G(i[0]),i[0]=this.B(i[0],i[0].startTime);let s=i[0];s.demuxer.done||console.error("Demuxing not yet finished!");let h=Number.MAX_VALUE,o=-1;for(let n=0;n<s.chunks.length;n++){if(s.chunks[n].type!=="key")continue;let r=Math.abs(t-(s.startTime+s.chunks[n].timestamp/1e6));r<h&&(h=r,o=n)}o<0||(s.curChunk=o)};this.i.setVideoTime(t),this.ht=null,e(this.n),e(this.c),e(this.l)}get volume(){return this.i.volume}set volume(t){this.i.setVolume(t)}Lt(t){if(this.i.started()){if(t==null)return;if(t.sampleRate!=this.i.sampleRate)throw new Error("Audio configs have mismatched sample rates!");if(t.numberOfChannels!=this.i.numChannels)throw new Error("Audio configs have mismatched channel counts!")}else this.i.start(t?{sampleRate:t.sampleRate,numChannels:t.numberOfChannels,volume:1}:{audioEnabled:!1}),this.H||this.i.resumeContext()}bt(t,e){let i=e+t.timestamp/1e6,s=[];for(let h=0;h<t.numberOfChannels;h++){let o=new Float32Array(t.numberOfFrames);t.copyTo(o,{planeIndex:h,format:"f32-planar"}),s.push(o)}this.i.scheduleChunk(s,i)}I(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:o=>{i?this.bt(o,s.startTime):s.frames.push(o)},error:o=>{console.error("Decoder encountered an error while decoding: ",o)}}),s.demuxer=new M(t,i,{onConfig:o=>{s.config=o,o?s.decoder?.configure(o):s.done=!0,i&&this.Lt(o)},onChunk:o=>{s.chunks?.push(o),s.duration=Math.max(s.duration,(o.timestamp+o.duration)/1e6)}}),s}B(t,e){let i={startTime:e,isAudio:t.isAudio,duration:t.duration,demuxer:{done:!0},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.bt(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}Ht(){let t=!this.paused;this.X.textContent=t?"\u23F8\uFE0F":"\u25B6\uFE0F";let e=this.n[0];if(!e||!e.duration){this.m.value=0;return}let i=this.currentTime-e.startTime,s=Math.max(0,Math.min(1,i/e.duration));this.m.value=s}kt(t){let e=this.n[0];if(!e)return;this.O=null;let i=!1;for(let s of t.session.inputSources){if(!s.targetRaySpace)continue;let h=t.getPose(s.targetRaySpace,this.T);if(!h)continue;let o=h.transform.position,n=this.Dt(h.transform.orientation),r=(-this.t.DEPTH_MIN-o.z)/n.z;if(r<0)continue;let a=o.x+n.x*r,u=o.y+n.y*r,c=-.5*this.t.DEPTH_MIN,l=.5*this.t.DEPTH_MIN,d=(.5*m+.5+m/2)*-this.t.DEPTH_MIN,f=(-.5*m+.5+m/2)*-this.t.DEPTH_MIN;if(!(a<c||a>l||u<d||u>f)){if(this.O=this.O??{u:(a-c)/(l-c),v:(u-d)/(f-d)},s.gamepad?.buttons[0]?.pressed)i=!0;else continue;if(!this.Mt)if(this.O.u<m)this.paused?this.play():this.pause();else{let g=1-D,x=(this.O.u-m-g/2)/(1-m-g);this.currentTime=x*(e.duration??0),console.log(x)}}}this.Mt=i}F(t,e){if(super.F(t,e),!this.h)return;let i=this.h;if(this.r==null)return;let s=this.n[0];if(!s)return;let h;if(!s.duration)h=0;else{let o=this.currentTime-s.startTime;h=Math.max(0,Math.min(1,o/s.duration))}i.useProgram(this._),i.uniformMatrix4fv(this.E.uView,!1,t),i.uniformMatrix4fv(this.E.uProjection,!1,e),i.uniform1f(this.E.uDepth,this.t.DEPTH_MIN),i.uniform1f(this.E.uHeight,m),i.uniform1f(this.E.uScrubberWidth,D),i.uniform1f(this.E.uProgress,h),i.uniform1ui(this.E.uPaused,this.i.isPaused?1:0),i.uniform2f(this.E.uHitPos,this.O?.u??-1,this.O?.v??-1),i.drawArrays(i.TRIANGLES,0,6)}j(t,e){let i=(h,o)=>{let n=h[o];for(;n.curChunk<n.chunks.length;){let r=n.chunks[n.curChunk];if(n.startTime+r.timestamp/1e6>this.i.getVideoTime()+L)break;n.decoder.decode(r),n.curChunk++}if(n.curChunk>=n.chunks.length&&n.demuxer.done&&n.decoder){let r=n.decoder;r.flush().then(()=>{r.close(),n.done=!0}),n.decoder=null}};for(let h=0;h<this.n.length;h++)i(this.n,h);for(let h=0;h<this.c.length;h++)i(this.c,h);for(let h=0;h<this.l.length;h++)this.l[h].config!=null&&i(this.l,h);let s=h=>h?h.done&&h.frames.length==1:!1;s(this.n[0])&&s(this.c[0])&&(this.n.shift(),this.c.shift(),this.yt=!0,this.onSegmentEnd?.(this.n.length==0)),this.l[0]?.done&&this.l.shift(),this.$&&this.n.length==0&&this.c.length==0&&this.l.length==0&&this.et!=null&&this.st!=null&&(this.i.setVideoTime(0),this.n=[this.B(this.et,0)],this.c=[this.B(this.st,0)],this.it!=null&&(this.l=[this.B(this.it,0)])),this.tt&&this.Ht(),e!=null&&this.kt(e),super.j(t,e)}Z(){this.e=document.createElement("video"),this.e.style.display="block",this.e.classList.add("fallback"),this.e.controls=this.b,this.e.muted=this.H,this.e.loop=this.$,this.e.autoplay=this.Q,this.e.src=this.getAttribute("color-src"),this.s.parentElement.appendChild(this.e),this.b.style.display="none"}_t(){let t=this.n[0],e=this.c[0];if(!t||!e)return;let i=this.i.getVideoTime(),s=this.ht!=null?Math.abs(i-this.ht):Number.MAX_VALUE,h=-1;for(let o=0;o<Math.min(t.frames.length,e.frames.length);o++){let n=Math.abs(i-(t.startTime+t.frames[o].timestamp/1e6));if(n<=s)s=n,h=o;else break}if(!(h<0)){this.yt&&(this.e?.close(),this.f?.close(),this.yt=!1),this.e=t.frames[h],this.f=e.frames[h],this.ht=t.startTime+this.e.timestamp/1e6,this.e?.timestamp!==this.f?.timestamp&&console.error("Color and depth frames have mismatched PTS"),this.M("color",this.e),this.M("depth",this.f);for(let o=0;o<h;o++)t.frames.shift().close(),e.frames.shift().close(),this.onFrameRendered?.()}}q(t){return t instanceof VideoFrame}R(t){return t?t.codedWidth:1}C(t){return t?t.codedHeight:1}G(t){t.decoder?.close(),t.decoder=null;for(let e=0;e<t.frames.length;e++)t.frames[e].close()}};C&&(customElements.define("rgbd-img",v),customElements.define("rgbd-video",b));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rgbd",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",