UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 9.71 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.33/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 u,scale as m,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{q as C,c as j,u as y,t as H,i as v}from"../../../../chunks/vec32.js";import{create as D}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{s as S,t as O}from"../../../../chunks/vec42.js";import{create as T}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{ViewingMode as F}from"../../../ViewingMode.js";import{DepthFormat as B}from"../core/FBOCacheFormats.js";import{CascadeCamera as Q}from"./CascadeCamera.js";import{applyTextureResizeModulo as V}from"./textureUtils.js";import{assert as L,logWithBase as N,verify as q,rayRay2D as R}from"./Util.js";import{DepthStencilAttachment as W,FramebufferBit as z}from"../../../webgl/enums.js";var E;!function(t){t[t.Highlight=0]="Highlight",t[t.ExcludeHighlight=1]="ExcludeHighlight"}(E||(E={}));class P{constructor(){this.camera=new Q,this.lightMat=l()}}class A{constructor(){this.maxNumCascadesHighQuality=4,this.maxNumCascadesLowQuality=4,this.textureSizeModHighQuality=1.3,this.textureSizeModLowQuality=.9,this.splitSchemeLambda=0}}class I{constructor(t,s){this._fbos=t,this._viewingMode=s,this._snapshots=new Array,this._textureHeight=0,this._numCascades=1,this.settings=new A,this._projectionView=l(),this._projectionViewInverse=l(),this._modelViewLight=l(),this._cascadeDistances=[0,0,0,0,0],this._usedCascadeDistances=T(),this._cascades=[new P,new P,new P,new P],this._lastOrigin=null,this._enabled=!1,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(W)}get _textureWidth(){return this._textureHeight*this._numCascades}get numCascades(){return this._numCascades}get cascadeDistances(){return S(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)}disposeMainBuffer(){this._handle=i(this._handle)}disposeOffscreenBuffers(){this.disposeMainBuffer(),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)tt[t]=this._cascades[t];return tt.length=this._numCascades,tt}start(t,s,e,i,a){L(this.enabled);const{near:r,far:h}=Mt(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(){L(this.enabled)}getShadowMapMatrices(t){if(!this._lastOrigin||!C(t,this._lastOrigin)){this._lastOrigin=this._lastOrigin||D(),j(this._lastOrigin,t);for(let s=0;s<this._numCascades;++s){r(st,this._cascades[s].lightMat,t);for(let t=0;t<16;++t)et[16*s+t]=st[t]}}return et}moveSnapshot(t){L(this.enabled),this._snapshots[t]?.release(),this._snapshots[t]=this._handle,this._handle?.setName(t===E.Highlight?"shadow map highlight":"shadow map excluding highlight"),this._handle=null}copySnapshot(t){if(!this.enabled)return;const s=this._handle?.getTexture(W)?.descriptor;if(!s)return;this._snapshots[t]?.release();const e=t===E.Highlight?"shadow map highlight":"shadow map excluding highlight",i=this._acquireFBO(e);this._snapshots[t]=i;const a=this._handle?.fbo;if(!a||!i?.fbo)return void console.error("No FBO");const{rctx:r}=this._fbos;r.blitFramebuffer(a,i.fbo,z.DEPTH)}getSnapshot(t){return this.enabled?this._snapshots[t]?.getTexture(W):null}clear(){this._ensureFbo(),this.bindFbo(),this._fbos.rctx.clear(z.DEPTH)}_computeTextureHeight({pixelRatio:t,fullWidth:s,fullHeight:e},i,a){const r=Math.min(window.devicePixelRatio,i)/t,h=a?this.settings.textureSizeModHighQuality:this.settings.textureSizeModLowQuality;return V(Math.max(s,e)*r*h,this._maxTextureWidth/this._numCascades)}_ensureFbo(){this._handle?.fbo?.width===this._textureWidth&&this._handle?.fbo.height===this._textureHeight||(this._handle?.release(),this._handle=this._acquireFBO("shadow map"))}_acquireFBO(t){const s=this._fbos.acquire(this._textureWidth,this._textureHeight,t,B.DEPTH16);return s.getTexture(W)?.setShadowFiltering(!0),s}_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]);L(c<l);for(let r=0;r<8;++r){S(k,r%4==0||r%4==3?-1:1,r%4==0||r%4==1?-1:1,r<4?c:l,1);const t=G[r];O(t,k,this._projectionViewInverse),t[0]/=t[3],t[1]/=t[3],t[2]/=t[3]}y($,G[0]),a.camera.viewMatrix=r(U,this._modelViewLight,$);for(let r=0;r<8;++r)H(G[r],G[r],a.camera.viewMatrix);let d=G[0][2],u=G[0][2];for(let r=1;r<8;++r)d=Math.min(d,G[r][2]),u=Math.max(u,G[r][2]);d-=200,u+=200,a.camera.near=-u,a.camera.far=-d,wt(e,i,d,u,a.camera),h(a.lightMat,a.camera.projectionMatrix,a.camera.viewMatrix);const m=this._textureHeight;a.camera.viewport=[t*m,0,m,m]}_setupMatrices(t,s){h(this._projectionView,t.projectionMatrix,t.viewMatrix),o(this._projectionViewInverse,this._projectionView);const e=this._viewingMode===F.Global?t.eye:v($,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 U=l(),k=T(),G=[];for(let Ct=0;Ct<8;++Ct)G.push(T());const J=M(),K=M(),X=M(),Y=M(),Z=M(),$=D(),tt=[],st=l(),et=c.concat(c,c,c,c),it=M(),at=M(),rt=[M(),M(),M(),M()],ht=M(),ot=M(),nt=M(),ct=M(),lt=M(),dt=M(),ut=M();function mt(t,s,e,i,a,r,h,o){d(it,0,0);for(let d=0;d<4;++d)u(it,it,t[d]);m(it,it,.25),d(at,0,0);for(let d=4;d<8;++d)u(at,at,t[d]);m(at,at,.25),_(rt[0],t[4],t[5],.5),_(rt[1],t[5],t[6],.5),_(rt[2],t[6],t[7],.5),_(rt[3],t[7],t[4],.5);let n=0,c=f(rt[0],it);for(let d=1;d<4;++d){const t=f(rt[d],it);t<c&&(c=t,n=d)}g(ht,rt[n],t[n+4]);const l=ht[0];let M,C;ht[0]=-ht[1],ht[1]=l,g(ot,at,it),p(ot,ht)<0&&x(ht,ht),_(ht,ht,ot,e),b(ht,ht),M=C=p(g(nt,t[0],it),ht);for(let d=1;d<8;++d){const s=p(g(nt,t[d],it),ht);s<M?M=s:s>C&&(C=s)}w(i,it),m(nt,ht,M-s),u(i,i,nt);let j=-1,y=1,H=0,v=0;for(let d=0;d<8;++d){g(ct,t[d],i),b(ct,ct);const s=ht[0]*ct[1]-ht[1]*ct[0];s>0?s>j&&(j=s,H=d):s<y&&(y=s,v=d)}q(j>0,"leftArea"),q(y<0,"rightArea"),m(lt,ht,M),u(lt,lt,it),m(dt,ht,C),u(dt,dt,it),ut[0]=-ht[1],ut[1]=ht[0];const D=R(i,t[v],dt,u(nt,dt,ut),1,a),S=R(i,t[H],dt,nt,1,r),O=R(i,t[H],lt,u(nt,lt,ut),1,h),T=R(i,t[v],lt,nt,1,o);q(D,"rayRay"),q(S,"rayRay"),q(O,"rayRay"),q(T,"rayRay")}function _t(t,s){return 3*s+t}const ft=M();function gt(t,s){return d(ft,t[s],t[s+3]),ft}const pt=M(),xt=a();function bt(t,s,e,i,a){g(pt,e,i),m(pt,pt,.5),xt[0]=pt[0],xt[1]=pt[1],xt[2]=0,xt[3]=pt[1],xt[4]=-pt[0],xt[5]=0,xt[6]=pt[0]*pt[0]+pt[1]*pt[1],xt[7]=pt[0]*pt[1]-pt[1]*pt[0],xt[8]=1,xt[_t(0,2)]=-p(gt(xt,0),t),xt[_t(1,2)]=-p(gt(xt,1),t);let r=p(gt(xt,0),e)+xt[_t(0,2)],h=p(gt(xt,1),e)+xt[_t(1,2)],o=p(gt(xt,0),i)+xt[_t(0,2)],n=p(gt(xt,1),i)+xt[_t(1,2)];r=-(r+o)/(h+n),xt[_t(0,0)]+=xt[_t(1,0)]*r,xt[_t(0,1)]+=xt[_t(1,1)]*r,xt[_t(0,2)]+=xt[_t(1,2)]*r,r=1/(p(gt(xt,0),e)+xt[_t(0,2)]),h=1/(p(gt(xt,1),e)+xt[_t(1,2)]),xt[_t(0,0)]*=r,xt[_t(0,1)]*=r,xt[_t(0,2)]*=r,xt[_t(1,0)]*=h,xt[_t(1,1)]*=h,xt[_t(1,2)]*=h,xt[_t(2,0)]=xt[_t(1,0)],xt[_t(2,1)]=xt[_t(1,1)],xt[_t(2,2)]=xt[_t(1,2)],xt[_t(1,2)]+=1,r=p(gt(xt,1),s)+xt[_t(1,2)],h=p(gt(xt,2),s)+xt[_t(2,2)],o=p(gt(xt,1),e)+xt[_t(1,2)],n=p(gt(xt,2),e)+xt[_t(2,2)],r=-.5*(r/h+o/n),xt[_t(1,0)]+=xt[_t(2,0)]*r,xt[_t(1,1)]+=xt[_t(2,1)]*r,xt[_t(1,2)]+=xt[_t(2,2)]*r,r=p(gt(xt,1),s)+xt[_t(1,2)],h=p(gt(xt,2),s)+xt[_t(2,2)],o=-h/r,xt[_t(1,0)]*=o,xt[_t(1,1)]*=o,xt[_t(1,2)]*=o,a[0]=xt[0],a[1]=xt[1],a[2]=0,a[3]=xt[2],a[4]=xt[3],a[5]=xt[4],a[6]=0,a[7]=xt[5],a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=xt[6],a[13]=xt[7],a[14]=0,a[15]=xt[8]}function wt(t,s,i,a,r){const h=1/G[0][3],o=1/G[4][3];L(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,mt(G,n,c,J,K,X,Y,Z),bt(J,K,Y,Z,r.projectionMatrix),r.projectionMatrix[10]=2/(i-a),r.projectionMatrix[14]=-(i+a)/(i-a)}function Mt(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{I as ShadowMap,E as SnapshotSlot};