UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 9.92 kB
import has from"../../../../core/has.js";import{clamp as t,lerp as e,acosClamped as s}from"../../../../core/mathUtils.js";import{isSome as a,disposeMaybe as i}from"../../../../core/maybe.js";import{c as r}from"../../../../chunks/mat3f64.js";import{w as h,m as c,a as n,u as o}from"../../../../chunks/mat4.js";import{c as _}from"../../../../chunks/mat4f64.js";import{s as d,j as u,b as m,l,k as p,a as f,h as x,n as g,f as T,c as b}from"../../../../chunks/vec2.js";import{a as w}from"../../../../chunks/vec2f64.js";import{k as S,c as M,o as C,m as D,s as E}from"../../../../chunks/vec3.js";import{c as j}from"../../../../chunks/vec3f64.js";import{s as v,t as R}from"../../../../chunks/vec4.js";import{c as z}from"../../../../chunks/vec4f64.js";import{ViewingMode as U}from"../../../ViewingMode.js";import{CascadeCamera as F}from"./CascadeCamera.js";import{assert as y,logWithBase as N,verify as O,rayRay2D as A}from"./Util.js";import{TextureType as L,ClearBufferBit as k,PixelFormat as B,PixelType as I,TextureWrapMode as V,TextureSamplingMode as G,TargetType as P,DepthStencilTargetType as X}from"../../../webgl/enums.js";import{FramebufferObject as H}from"../../../webgl/FramebufferObject.js";import{Texture as Y}from"../../../webgl/Texture.js";import{getGpuMemoryUsage as q}from"../../../webgl/Util.js";var W;!function(t){t[t.Highlight=0]="Highlight",t[t.Default=1]="Default"}(W||(W={}));class J{constructor(){this.camera=new F,this.lightMat=_()}}class K{get depthTexture(){return this._depthTexture}get textureSize(){return this._textureSize}get numCascades(){return this._numCascades}get cascadeDistances(){return v(this._usedCascadeDistances,this._cascadeDistances[0],this._numCascades>1?this._cascadeDistances[1]:1/0,this._numCascades>2?this._cascadeDistances[2]:1/0,this._numCascades>3?this._cascadeDistances[3]:1/0)}constructor(t,e){this._rctx=t,this._viewingMode=e,this._enabled=!1,this._snapshots=new Array,this._textureSize=0,this._numCascades=1,this._maxNumCascades=4,this._projectionView=_(),this._projectionViewInverse=_(),this._modelViewLight=_(),this._splitSchemeLambda=0,this._cascadeDistances=[0,0,0,0,0],this._usedCascadeDistances=z(),this._cascades=[new J,new J,new J,new J],this._lastOrigin=null,this._maxTextureSize=Math.min(has("esri-mobile")?2048:8192,this._rctx.parameters.maxTextureSize)}dispose(){this.enabled=!1,this.disposeOffscreenBuffers()}disposeOffscreenBuffers(){this._discardDepthTexture(),this._discardAllSnapshots()}set maxCascades(e){this._maxNumCascades=t(Math.floor(e),1,4)}get maxCascades(){return this._maxNumCascades}set enabled(t){this._enabled=t,t||(this._discardDepthTexture(),this._discardAllSnapshots())}get enabled(){return this._enabled}get ready(){return this._enabled&&a(this._depthTexture)}getSnapshot(t){return this.enabled?this._snapshots[t]:null}get cascades(){for(let t=0;t<this._numCascades;++t)ht[t]=this._cascades[t];return ht.length=this._numCascades,ht}start(t,e,s){y(this.enabled),this._textureSize=this._computeTextureSize(t.fullWidth,t.fullHeight),this._ensureDepthTexture();const{near:a,far:i}=this._clampNearFar(s);this._computeCascadeDistances(i,a),this._setupMatrices(t,e);const{viewMatrix:r,projectionMatrix:h}=t;for(let c=0;c<this._numCascades;++c)this._constructCascade(c,h,r,e);this._lastOrigin=null,this.clear()}finish(t){y(this.enabled),this._rctx.bindFramebuffer(t)}getShadowMapMatrices(t){if(!this._lastOrigin||!S(t,this._lastOrigin)){this._lastOrigin=this._lastOrigin||j(),M(this._lastOrigin,t);for(let e=0;e<this._numCascades;++e){h(ct,this._cascades[e].lightMat,t);for(let t=0;t<16;++t)nt[16*e+t]=ct[t]}}return nt}takeCascadeSnapshotTo(t,e){y(this.enabled);const s=this._ensureSnapshot(e);this._bindFbo();const a=this._rctx,i=a.bindTexture(s,Y.TEXTURE_UNIT_FOR_UPDATES);a.gl.copyTexSubImage2D(L.TEXTURE_2D,0,t.camera.viewport[0],t.camera.viewport[1],t.camera.viewport[0],t.camera.viewport[1],t.camera.viewport[2],t.camera.viewport[3]),a.bindTexture(i,Y.TEXTURE_UNIT_FOR_UPDATES)}clear(){const t=this._rctx;this._bindFbo(),t.setClearColor(1,1,1,1),t.clearSafe(k.COLOR_BUFFER_BIT|k.DEPTH_BUFFER_BIT)}_computeTextureSize(t,e){const s=.5*Math.log(t*t+e*e)*Math.LOG2E,a=.35,i=2**Math.round(s+a);return Math.min(this._maxTextureSize,2*i)}_ensureDepthTexture(){if(a(this._depthTexture)&&this._depthTexture.descriptor.width===this._textureSize)return;this._discardDepthTexture();const t={target:L.TEXTURE_2D,pixelFormat:B.RGBA,dataType:I.UNSIGNED_BYTE,wrapMode:V.CLAMP_TO_EDGE,samplingMode:G.NEAREST,flipped:!0,width:this._textureSize,height:this._textureSize};this._depthTexture=new Y(this._rctx,t),this._fbo=new H(this._rctx,{colorTarget:P.TEXTURE,depthStencilTarget:X.DEPTH_RENDER_BUFFER,width:this._textureSize,height:this._textureSize},this._depthTexture)}_ensureSnapshot(t){let e=this._snapshots[t];if(a(e)&&e.descriptor.width===this._textureSize)return e;this._discardSnapshot(t);const s={target:L.TEXTURE_2D,pixelFormat:B.RGBA,dataType:I.UNSIGNED_BYTE,wrapMode:V.CLAMP_TO_EDGE,samplingMode:G.NEAREST,flipped:!0,width:this._textureSize,height:this._textureSize};return e=new Y(this._rctx,s),this._snapshots[t]=e,e}_discardDepthTexture(){this._fbo=i(this._fbo),this._depthTexture=i(this._depthTexture)}_discardSnapshot(t){this._snapshots[t]=i(this._snapshots[t])}_discardAllSnapshots(){for(let t=0;t<this._snapshots.length;++t)this._discardSnapshot(t);this._snapshots.length=0}_bindFbo(){const t=this._rctx;t.unbindTexture(this._depthTexture),t.bindFramebuffer(this._fbo)}_constructCascade(t,e,s,a){const i=this._cascades[t],r=-this._cascadeDistances[t],n=-this._cascadeDistances[t+1],o=(e[10]*r+e[14])/Math.abs(e[11]*r+e[15]),_=(e[10]*n+e[14])/Math.abs(e[11]*n+e[15]);y(o<_);for(let h=0;h<8;++h){v(Z,h%4==0||h%4==3?-1:1,h%4==0||h%4==1?-1:1,h<4?o:_,1);const t=$[h];R(t,Z,this._projectionViewInverse),t[0]/=t[3],t[1]/=t[3],t[2]/=t[3]}C(rt,$[0]),i.camera.viewMatrix=h(Q,this._modelViewLight,rt);for(let h=0;h<8;++h)D($[h],$[h],i.camera.viewMatrix);let d=$[0][2],u=$[0][2];for(let h=1;h<8;++h)d=Math.min(d,$[h][2]),u=Math.max(u,$[h][2]);d-=200,u+=200,i.camera.near=-u,i.camera.far=-d,Et(s,a,d,u,i.camera),c(i.lightMat,i.camera.projectionMatrix,i.camera.viewMatrix);const m=this._textureSize/2;i.camera.viewport=[t%2==0?0:m,0===Math.floor(t/2)?0:m,m,m]}_setupMatrices(t,e){c(this._projectionView,t.projectionMatrix,t.viewMatrix),n(this._projectionViewInverse,this._projectionView);const s=this._viewingMode===U.Global?t.eye:E(rt,0,0,1);o(this._modelViewLight,[0,0,0],[-e[0],-e[1],-e[2]],s)}_clampNearFar(t){let{near:e,far:s}=t;return e<2&&(e=2),s<2&&(s=2),e>=s&&(e=2,s=4),{near:e,far:s}}_computeCascadeDistances(t,s){this._numCascades=Math.min(1+Math.floor(N(t/s,4)),this._maxNumCascades);const a=(t-s)/this._numCascades,i=(t/s)**(1/this._numCascades);let r=s,h=s;for(let c=0;c<this._numCascades+1;++c)this._cascadeDistances[c]=e(r,h,this._splitSchemeLambda),r*=i,h+=a}get gpuMemoryUsage(){return this._snapshots.reduce(((t,e)=>t+q(e)),this._fbo?.gpuMemoryUsage??0)}get test(){const t=this;return{maxNumCascades:this._maxNumCascades,cascades:this._cascades,textureSize:this._textureSize,set splitSchemeLambda(e){t._splitSchemeLambda=e},get splitSchemeLambda(){return t._splitSchemeLambda}}}}const Q=_(),Z=z(),$=[];for(let jt=0;jt<8;++jt)$.push(z());const tt=w(),et=w(),st=w(),at=w(),it=w(),rt=j(),ht=[],ct=_(),nt=new Float32Array(64),ot=w(),_t=w(),dt=[w(),w(),w(),w()],ut=w(),mt=w(),lt=w(),pt=w(),ft=w(),xt=w(),gt=w();function Tt(t,e,s,a,i,r,h,c){d(ot,0,0);for(let d=0;d<4;++d)u(ot,ot,t[d]);m(ot,ot,.25),d(_t,0,0);for(let d=4;d<8;++d)u(_t,_t,t[d]);m(_t,_t,.25),l(dt[0],t[4],t[5],.5),l(dt[1],t[5],t[6],.5),l(dt[2],t[6],t[7],.5),l(dt[3],t[7],t[4],.5);let n=0,o=p(dt[0],ot);for(let d=1;d<4;++d){const t=p(dt[d],ot);t<o&&(o=t,n=d)}f(ut,dt[n],t[n+4]);const _=ut[0];let w,S;ut[0]=-ut[1],ut[1]=_,f(mt,_t,ot),x(mt,ut)<0&&g(ut,ut),l(ut,ut,mt,s),T(ut,ut),w=S=x(f(lt,t[0],ot),ut);for(let d=1;d<8;++d){const e=x(f(lt,t[d],ot),ut);e<w?w=e:e>S&&(S=e)}b(a,ot),m(lt,ut,w-e),u(a,a,lt);let M=-1,C=1,D=0,E=0;for(let d=0;d<8;++d){f(pt,t[d],a),T(pt,pt);const e=ut[0]*pt[1]-ut[1]*pt[0];e>0?e>M&&(M=e,D=d):e<C&&(C=e,E=d)}O(M>0,"leftArea"),O(C<0,"rightArea"),m(ft,ut,w),u(ft,ft,ot),m(xt,ut,S),u(xt,xt,ot),gt[0]=-ut[1],gt[1]=ut[0];const j=A(a,t[E],xt,u(lt,xt,gt),1,i),v=A(a,t[D],xt,lt,1,r),R=A(a,t[D],ft,u(lt,ft,gt),1,h),z=A(a,t[E],ft,lt,1,c);O(j,"rayRay"),O(v,"rayRay"),O(R,"rayRay"),O(z,"rayRay")}function bt(t,e){return 3*e+t}const wt=w();function St(t,e){return d(wt,t[e],t[e+3]),wt}const Mt=w(),Ct=r();function Dt(t,e,s,a,i){f(Mt,s,a),m(Mt,Mt,.5),Ct[0]=Mt[0],Ct[1]=Mt[1],Ct[2]=0,Ct[3]=Mt[1],Ct[4]=-Mt[0],Ct[5]=0,Ct[6]=Mt[0]*Mt[0]+Mt[1]*Mt[1],Ct[7]=Mt[0]*Mt[1]-Mt[1]*Mt[0],Ct[8]=1,Ct[bt(0,2)]=-x(St(Ct,0),t),Ct[bt(1,2)]=-x(St(Ct,1),t);let r=x(St(Ct,0),s)+Ct[bt(0,2)],h=x(St(Ct,1),s)+Ct[bt(1,2)],c=x(St(Ct,0),a)+Ct[bt(0,2)],n=x(St(Ct,1),a)+Ct[bt(1,2)];r=-(r+c)/(h+n),Ct[bt(0,0)]+=Ct[bt(1,0)]*r,Ct[bt(0,1)]+=Ct[bt(1,1)]*r,Ct[bt(0,2)]+=Ct[bt(1,2)]*r,r=1/(x(St(Ct,0),s)+Ct[bt(0,2)]),h=1/(x(St(Ct,1),s)+Ct[bt(1,2)]),Ct[bt(0,0)]*=r,Ct[bt(0,1)]*=r,Ct[bt(0,2)]*=r,Ct[bt(1,0)]*=h,Ct[bt(1,1)]*=h,Ct[bt(1,2)]*=h,Ct[bt(2,0)]=Ct[bt(1,0)],Ct[bt(2,1)]=Ct[bt(1,1)],Ct[bt(2,2)]=Ct[bt(1,2)],Ct[bt(1,2)]+=1,r=x(St(Ct,1),e)+Ct[bt(1,2)],h=x(St(Ct,2),e)+Ct[bt(2,2)],c=x(St(Ct,1),s)+Ct[bt(1,2)],n=x(St(Ct,2),s)+Ct[bt(2,2)],r=-.5*(r/h+c/n),Ct[bt(1,0)]+=Ct[bt(2,0)]*r,Ct[bt(1,1)]+=Ct[bt(2,1)]*r,Ct[bt(1,2)]+=Ct[bt(2,2)]*r,r=x(St(Ct,1),e)+Ct[bt(1,2)],h=x(St(Ct,2),e)+Ct[bt(2,2)],c=-h/r,Ct[bt(1,0)]*=c,Ct[bt(1,1)]*=c,Ct[bt(1,2)]*=c,i[0]=Ct[0],i[1]=Ct[1],i[2]=0,i[3]=Ct[2],i[4]=Ct[3],i[5]=Ct[4],i[6]=0,i[7]=Ct[5],i[8]=0,i[9]=0,i[10]=1,i[11]=0,i[12]=Ct[6],i[13]=Ct[7],i[14]=0,i[15]=Ct[8]}function Et(t,e,a,i,r){const h=1/$[0][3],c=1/$[4][3];y(h<c);let n=h+Math.sqrt(h*c);const o=Math.sin(s(t[2]*e[0]+t[6]*e[1]+t[10]*e[2]));n/=o,Tt($,n,o,tt,et,st,at,it),Dt(tt,et,at,it,r.projectionMatrix),r.projectionMatrix[10]=2/(a-i),r.projectionMatrix[14]=-(a+i)/(a-i)}export{K as ShadowMap,W as SnapshotSlot};