UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) • 9.88 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import has from"../../../../core/has.js";import{clamp as t,lerp as s,acosClamped as e}from"../../../../core/mathUtils.js";import{releaseMaybe as i}from"../../../../core/maybe.js";import{create as a}from"../../../../core/libs/gl-matrix-2/factories/mat3f64.js";import{translate as r,multiply as h,invert as o,lookAt as n}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{IDENTITY as c,create as l}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{set as d,add as m,scale as u,lerp as _,squaredDistance as f,subtract as g,dot as p,negate as x,normalize as b,copy as w}from"../../../../core/libs/gl-matrix-2/math/vec2.js";import{create as M}from"../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{p as C,c as j,v as T,t as y,i as D}from"../../../../chunks/vec32.js";import{create as H}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{s as v,t as S}from"../../../../chunks/vec42.js";import{create as R}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{ViewingMode as O}from"../../../ViewingMode.js";import{ColorFormat as E,DepthFormat as U}from"../../webgl/formats.js";import{CascadeCamera as F}from"./CascadeCamera.js";import{applyTextureResizeModulo as L,applyTextureResizeFloorModulo as Q}from"./textureUtils.js";import{assert as V,logWithBase as N,verify as A,rayRay2D as B}from"./Util.js";import{TextureType as I,FramebufferBit as W}from"../../../webgl/enums.js";import{Texture as z}from"../../../webgl/Texture.js";var P;!function(t){t[t.Highlight=0]="Highlight",t[t.ExcludeHighlight=1]="ExcludeHighlight"}(P||(P={}));class q{constructor(){this.camera=new F,this.lightMat=l()}}class G{constructor(){this.maxNumCascadesHighQuality=4,this.maxNumCascadesLowQuality=4,this.textureSizeModHighQuality=1.3,this.textureSizeModLowQuality=.9,this.splitSchemeLambda=0}}class X{constructor(t,s){this._fbos=t,this._viewingMode=s,this._enabled=!1,this._snapshots=new Array,this._textureHeight=0,this._numCascades=1,this.settings=new G,this._projectionView=l(),this._projectionViewInverse=l(),this._modelViewLight=l(),this._cascadeDistances=[0,0,0,0,0],this._usedCascadeDistances=R(),this._cascades=[new q,new q,new q,new q],this._lastOrigin=null,this._maxTextureWidth=Math.min(has("esri-mobile")?4096:16384,t.rctx.parameters.maxTextureSize)}dispose(){this.enabled=!1,this.disposeOffscreenBuffers()}get depthTexture(){return this._handle?.getTexture()}get _textureWidth(){return this._textureHeight*this._numCascades}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)}disposeOffscreenBuffers(){this._handle=i(this._handle),this._discardSnapshots()}set maxCascades(s){this.settings.maxNumCascadesHighQuality=t(Math.floor(s),1,4)}get maxCascades(){return this.settings.maxNumCascadesHighQuality}set enabled(t){this._enabled=t,t||this.disposeOffscreenBuffers()}get enabled(){return this._enabled}get ready(){return this._enabled&&null!=this.depthTexture}get cascades(){for(let t=0;t<this._numCascades;++t)it[t]=this._cascades[t];return it.length=this._numCascades,it}start(t,s,e,i,a){V(this.enabled);const{near:r,far:h}=Tt(e);this._computeCascadeDistances(r,h,i),this._textureHeight=this._computeTextureHeight(t,a,i),this._setupMatrices(t,s);const{viewMatrix:o,projectionMatrix:n}=t;for(let c=0;c<this._numCascades;++c)this._constructCascade(c,n,o,s);this._lastOrigin=null,this.clear()}finish(){V(this.enabled),this._handle?.detachDepth()}getShadowMapMatrices(t){if(!this._lastOrigin||!C(t,this._lastOrigin)){this._lastOrigin=this._lastOrigin||H(),j(this._lastOrigin,t);for(let s=0;s<this._numCascades;++s){r(at,this._cascades[s].lightMat,t);for(let t=0;t<16;++t)rt[16*s+t]=at[t]}}return rt}moveSnapshot(t){V(this.enabled),this._handle?.detachDepth(),this._snapshots[t]?.release(),this._snapshots[t]=this._handle,this._handle=null,this.clear()}copySnapshot(t){const s=this._handle?.getTexture()?.descriptor;if(!this.enabled||!s)return;this._snapshots[t]?.release();const{width:e,height:i}=s,a=t===P.Highlight?"shadow highlight snapshot":"shadow no highlight snapshot";this._snapshots[t]=this._fbos.acquire(e,i,a,E.RGBA4);const r=this._fbos.rctx;this._bindFbo();const h=r.bindTexture(this._snapshots[t]?.getTexture(),z.TEXTURE_UNIT_FOR_UPDATES);r.gl.copyTexSubImage2D(I.TEXTURE_2D,0,0,0,0,0,e,i),r.bindTexture(h,z.TEXTURE_UNIT_FOR_UPDATES)}getSnapshot(t){return this.enabled?this._snapshots[t]?.getTexture():null}clear(){const t=this._fbos.rctx;this._ensureFbo(),this._bindFbo(),t.setClearColor(1,1,1,1),t.clear(W.COLOR|W.DEPTH)}_computeTextureHeight(t,s,e){const i=Math.min(window.devicePixelRatio,s)/t.pixelRatio,a=e?this.settings.textureSizeModHighQuality:this.settings.textureSizeModLowQuality,r=L(Math.floor(Math.max(t.fullWidth,t.fullHeight)*i*a)),h=Math.min(this._maxTextureWidth,this._numCascades*r);return Q(h/this._numCascades)}_ensureFbo(){this._handle?.fbo?.width===this._textureWidth&&this._handle?.fbo.height===this._textureHeight||(this._handle?.release(),this._handle=this._fbos.acquire(this._textureWidth,this._textureHeight,"shadow map",E.RGBA4)),this._handle?.acquireDepth(U.DEPTH16_BUFFER)}_discardSnapshot(t){this._snapshots[t]=i(this._snapshots[t])}_discardSnapshots(){for(let t=0;t<this._snapshots.length;++t)this._discardSnapshot(t);this._snapshots.length=0}_bindFbo(){this._fbos.rctx.bindFramebuffer(this._handle?.fbo)}_constructCascade(t,s,e,i){const a=this._cascades[t],o=-this._cascadeDistances[t],n=-this._cascadeDistances[t+1],c=(s[10]*o+s[14])/Math.abs(s[11]*o+s[15]),l=(s[10]*n+s[14])/Math.abs(s[11]*n+s[15]);V(c<l);for(let r=0;r<8;++r){v(J,r%4==0||r%4==3?-1:1,r%4==0||r%4==1?-1:1,r<4?c:l,1);const t=K[r];S(t,J,this._projectionViewInverse),t[0]/=t[3],t[1]/=t[3],t[2]/=t[3]}T(et,K[0]),a.camera.viewMatrix=r(k,this._modelViewLight,et);for(let r=0;r<8;++r)y(K[r],K[r],a.camera.viewMatrix);let d=K[0][2],m=K[0][2];for(let r=1;r<8;++r)d=Math.min(d,K[r][2]),m=Math.max(m,K[r][2]);d-=200,m+=200,a.camera.near=-m,a.camera.far=-d,jt(e,i,d,m,a.camera),h(a.lightMat,a.camera.projectionMatrix,a.camera.viewMatrix);const u=this._textureHeight;a.camera.viewport=[t*u,0,u,u]}_setupMatrices(t,s){h(this._projectionView,t.projectionMatrix,t.viewMatrix),o(this._projectionViewInverse,this._projectionView);const e=this._viewingMode===O.Global?t.eye:D(et,0,0,1);n(this._modelViewLight,[0,0,0],[-s[0],-s[1],-s[2]],e)}_computeCascadeDistances(t,e,i){const a=i?this.settings.maxNumCascadesHighQuality:this.settings.maxNumCascadesLowQuality;this._numCascades=Math.min(1+Math.floor(N(e/t,4)),a);const r=(e-t)/this._numCascades,h=(e/t)**(1/this._numCascades);let o=t,n=t;for(let c=0;c<this._numCascades+1;++c)this._cascadeDistances[c]=s(o,n,this.settings.splitSchemeLambda),o*=h,n+=r}get test(){}}const k=l(),J=R(),K=[];for(let yt=0;yt<8;++yt)K.push(R());const Y=M(),Z=M(),$=M(),tt=M(),st=M(),et=H(),it=[],at=l(),rt=c.concat(c,c,c,c),ht=M(),ot=M(),nt=[M(),M(),M(),M()],ct=M(),lt=M(),dt=M(),mt=M(),ut=M(),_t=M(),ft=M();function gt(t,s,e,i,a,r,h,o){d(ht,0,0);for(let d=0;d<4;++d)m(ht,ht,t[d]);u(ht,ht,.25),d(ot,0,0);for(let d=4;d<8;++d)m(ot,ot,t[d]);u(ot,ot,.25),_(nt[0],t[4],t[5],.5),_(nt[1],t[5],t[6],.5),_(nt[2],t[6],t[7],.5),_(nt[3],t[7],t[4],.5);let n=0,c=f(nt[0],ht);for(let d=1;d<4;++d){const t=f(nt[d],ht);t<c&&(c=t,n=d)}g(ct,nt[n],t[n+4]);const l=ct[0];let M,C;ct[0]=-ct[1],ct[1]=l,g(lt,ot,ht),p(lt,ct)<0&&x(ct,ct),_(ct,ct,lt,e),b(ct,ct),M=C=p(g(dt,t[0],ht),ct);for(let d=1;d<8;++d){const s=p(g(dt,t[d],ht),ct);s<M?M=s:s>C&&(C=s)}w(i,ht),u(dt,ct,M-s),m(i,i,dt);let j=-1,T=1,y=0,D=0;for(let d=0;d<8;++d){g(mt,t[d],i),b(mt,mt);const s=ct[0]*mt[1]-ct[1]*mt[0];s>0?s>j&&(j=s,y=d):s<T&&(T=s,D=d)}A(j>0,"leftArea"),A(T<0,"rightArea"),u(ut,ct,M),m(ut,ut,ht),u(_t,ct,C),m(_t,_t,ht),ft[0]=-ct[1],ft[1]=ct[0];const H=B(i,t[D],_t,m(dt,_t,ft),1,a),v=B(i,t[y],_t,dt,1,r),S=B(i,t[y],ut,m(dt,ut,ft),1,h),R=B(i,t[D],ut,dt,1,o);A(H,"rayRay"),A(v,"rayRay"),A(S,"rayRay"),A(R,"rayRay")}function pt(t,s){return 3*s+t}const xt=M();function bt(t,s){return d(xt,t[s],t[s+3]),xt}const wt=M(),Mt=a();function Ct(t,s,e,i,a){g(wt,e,i),u(wt,wt,.5),Mt[0]=wt[0],Mt[1]=wt[1],Mt[2]=0,Mt[3]=wt[1],Mt[4]=-wt[0],Mt[5]=0,Mt[6]=wt[0]*wt[0]+wt[1]*wt[1],Mt[7]=wt[0]*wt[1]-wt[1]*wt[0],Mt[8]=1,Mt[pt(0,2)]=-p(bt(Mt,0),t),Mt[pt(1,2)]=-p(bt(Mt,1),t);let r=p(bt(Mt,0),e)+Mt[pt(0,2)],h=p(bt(Mt,1),e)+Mt[pt(1,2)],o=p(bt(Mt,0),i)+Mt[pt(0,2)],n=p(bt(Mt,1),i)+Mt[pt(1,2)];r=-(r+o)/(h+n),Mt[pt(0,0)]+=Mt[pt(1,0)]*r,Mt[pt(0,1)]+=Mt[pt(1,1)]*r,Mt[pt(0,2)]+=Mt[pt(1,2)]*r,r=1/(p(bt(Mt,0),e)+Mt[pt(0,2)]),h=1/(p(bt(Mt,1),e)+Mt[pt(1,2)]),Mt[pt(0,0)]*=r,Mt[pt(0,1)]*=r,Mt[pt(0,2)]*=r,Mt[pt(1,0)]*=h,Mt[pt(1,1)]*=h,Mt[pt(1,2)]*=h,Mt[pt(2,0)]=Mt[pt(1,0)],Mt[pt(2,1)]=Mt[pt(1,1)],Mt[pt(2,2)]=Mt[pt(1,2)],Mt[pt(1,2)]+=1,r=p(bt(Mt,1),s)+Mt[pt(1,2)],h=p(bt(Mt,2),s)+Mt[pt(2,2)],o=p(bt(Mt,1),e)+Mt[pt(1,2)],n=p(bt(Mt,2),e)+Mt[pt(2,2)],r=-.5*(r/h+o/n),Mt[pt(1,0)]+=Mt[pt(2,0)]*r,Mt[pt(1,1)]+=Mt[pt(2,1)]*r,Mt[pt(1,2)]+=Mt[pt(2,2)]*r,r=p(bt(Mt,1),s)+Mt[pt(1,2)],h=p(bt(Mt,2),s)+Mt[pt(2,2)],o=-h/r,Mt[pt(1,0)]*=o,Mt[pt(1,1)]*=o,Mt[pt(1,2)]*=o,a[0]=Mt[0],a[1]=Mt[1],a[2]=0,a[3]=Mt[2],a[4]=Mt[3],a[5]=Mt[4],a[6]=0,a[7]=Mt[5],a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=Mt[6],a[13]=Mt[7],a[14]=0,a[15]=Mt[8]}function jt(t,s,i,a,r){const h=1/K[0][3],o=1/K[4][3];V(h<o);let n=h+Math.sqrt(h*o);const c=Math.sin(e(t[2]*s[0]+t[6]*s[1]+t[10]*s[2]));n/=c,gt(K,n,c,Y,Z,$,tt,st),Ct(Y,Z,tt,st,r.projectionMatrix),r.projectionMatrix[10]=2/(i-a),r.projectionMatrix[14]=-(i+a)/(i-a)}function Tt(t){let{near:s,far:e}=t;return s<2&&(s=2),e<2&&(e=2),s>=e&&(s=2,e=4),{near:s,far:e}}export{X as ShadowMap,P as SnapshotSlot};