UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 8.79 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{lerp as t}from"../../../core/mathUtils.js";import{normalize as e,set as i,add as s,scale as n,len as o,cross as r,dot as l,dist as a,sub as h}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{ZEROS as u,create as c}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{lonLatToSphericalPCPF as d}from"../../../geometry/projection/lonLatToSphericalPCPF.js";import{newDoubleArray as p}from"../../../geometry/support/DoubleArray.js";import{intersectsSphere as f,numPlanes as m}from"../../../geometry/support/frustum.js";import{Sphere as g}from"../../../geometry/support/sphere.js";import{createSphericalGlobePatch as x,updateCornerSpherical as $,updateEdgesAndCornersSpherical as v,updateEdgeElevationsAndResolutionsSpherical as M}from"./PatchGeometryFactory.js";import{enableTerrainInternalChecks as _,internalAssert as b,almostEquals as j}from"./terrainUtils.js";import{Tile as y}from"./Tile.js";import{compareTilesByLij as B}from"./tileUtils.js";class S extends y{constructor(t,e,i,s,n){super(),this._convexHull=new Array(24),this._boundingSphere=new g,this._baseUsedMemory=1816,this.init(t,e,i,s,n)}init(i,s,n,o,r){super.init(i,s,n,o,r);const l=this.ellipsoid.radius,a=this.extentInRadians[0],h=this.extentInRadians[1],u=this.extentInRadians[2],c=this.extentInRadians[3],p=t(h,c,.5),f=t(a,u,.5),m=0===i?0:Math.min(Math.abs(h),Math.abs(c));this._edgeLen=(u-a)*Math.cos(m)*l,this._edgeLen2=this._edgeLen*this._edgeLen,this._curvatureHeight=l-Math.sqrt(l*l-this._edgeLen2/4),d(this.centerAtSeaLevel,f,p,this.ellipsoid.radius),e(this.up,this.centerAtSeaLevel),this.updateRadiusAndCenter()}updateRadiusAndCenter(){this._updateBoundingVolumes();const t=this._center;if(0===this.lij[0])t[1].center=u,i(t[0],0,0,0),i(t[2],0,0,0),t[1].radius=this.ellipsoid.radius+this.elevationBoundsMax;else{this._updateCenter();const e=t[1],i=this.convexHull;let s=0;const n=e.center;for(let t=0;t<8;++t)s=Math.max(s,R(n,i,3*t));t[1].radius=Math.sqrt(s)}}_calculateFrustumVisibility(t){if(!f(t,this._boundingSphere))return 2;if(this.lij[0]<10)return 1;const e=this.convexHull,i=this.surface.view.state.camera.near;let s=!0;for(let n=0;n<m;n++){const o=4===n,r=t[n],l=r[0],a=r[1],h=r[2],u=r[3]-(o?i:0);let c=!1;for(let t=0;t<8;++t){const i=3*t;if(l*e[i]+a*e[i+1]+h*e[i+2]+u<0){if(c=!0,!s)break}else s=!1}if(!c)return 2}return s?0:1}computeElevationBounds(){super.computeElevationBounds(),this._updateBoundingVolumes()}createGeometry(){x(this.renderData,this._getPatchType()),this._updateBoundingVolumes(),this.setMemoryDirty()}_updateBoundingVolumes(){this._updateConvexHull(),this._updateBoundingSphere(),_&&this._checkBVs()}_updateBoundingSphere(){const t=this._boundingSphere,e=this.elevationBoundsMin,i=this.elevationBoundsMax,r=this.ellipsoid.radius,l=i;if(0===this.level)t.center=u,t.radius=r+l;else{const l=this.extentInRadians,a=.5*(l[0]+l[2]),h=l[1],u=l[3];H(I,a,h,r),H(L,a,u,r),s(t.center,I,L);const c=r+.5*(e+i);n(t.center,t.center,c/o(t.center));const d=this.convexHull;let p=0;const f=(t,e)=>{const i=t[0]-d[3*e],s=t[1]-d[3*e+1],n=t[2]-d[3*e+2];return Math.sqrt(i*i+s*s+n*n)};for(let e=0;e<8;++e){const i=f(t.center,e);p=Math.max(p,i)}const m=p;t.radius=m+2}}_updateConvexHull(){const t=this.extentInRadians,i=this.ellipsoid.radius;if(0===this.level)return;const a=this.elevationBoundsMin,u=this.elevationBoundsMax,d=this._getPatchType(),p=this.surface.isWebMercator,f=p&&1===d,m=p&&2===d,g=m||f,x=Math.PI/2,$=t[0],v=t[2],M=m?-x:t[1],_=f?x:t[3],y=.5*($+v),B=a,S=i+(g?Math.min(0,B-1):B),V=(t,e,i)=>H(t,e,i,S),R=c(),T=c(),I=c(),L=c();V(R,$,M),V(T,$,_),V(I,v,_),V(L,v,M);const P=(t,e)=>{for(let i=0;i<3;++i)this._convexHull[3*e+i]=t[i]};P(R,0),P(T,1),P(I,2),P(L,3);const F=u,A=i+(g?Math.max(0,F+1):F),D=c(),E=c(),k=c();H(E,y,_,S),H(k,y,M,S),s(D,E,k),e(D,D);const w=c(),U=c(),q=(t,i)=>{h(U,t,i),e(U,U);const o=-l(t,w)/l(U,w);b(o>=0),n(U,U,o),s(t,t,U)};if(2**this.lij[0]>2*this.lij[1]){const t=k,i=c();r(i,C,t),e(i,i),r(w,t,i),e(w,w),b(j(l(w,t)/o(t),0)),q(R,T),q(L,I),P(R,0),P(L,3)}else if(2**this.lij[0]!==2*this.lij[1]){const t=E,i=c();r(i,C,t),e(i,i),r(w,i,t),e(w,w),q(T,R),q(I,L),P(T,1),P(I,2)}const N=(t,e)=>{const i=A/l(e,D);for(let s=0;s<3;++s)this._convexHull[3*t+s]=e[s]*i};N(4,R),N(5,T),N(6,I),N(7,L)}_getPatchType(){const t=this.lij[1],e=0===t,i=t===(1<<this.level)-1;return e?i?3:1:i?2:0}intersectsRay(t,e,i,s){const n=this._boundingSphere,o=n.radius+i,r=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],l=n.center[0]-t[0],a=n.center[1]-t[1],h=n.center[2]-t[2],u=(l*e[0]+a*e[1]+h*e[2])/r,c=e[0]*u-l,d=e[1]*u-a,p=e[2]*u-h;return c*c+d*d+p*p<o*o}get minimumVerticesPerSide(){return this.level<V.length?V[this.level]+1:2}updateCornerElevations(){$(this.renderData),this._updateBoundingVolumes()}updateEdgeElevations(){v(this.renderData),this._updateBoundingVolumes()}updateEdgeElevationsAndResolutions(){M(this.renderData),this._updateBoundingVolumes()}_checkBVs(){if(!_)return;if(this.level<=2)return;const t=this._boundingSphere,i=t.radius,n=t.center,u=c(),d=this.ellipsoid.radius,f=this.elevationBoundsMin,m=this.elevationBoundsMax,g=d+f,x=1,$=0,v=this._center[1];v.center;const M=v.radius,y=this.convexHull,S=(t,e)=>{for(let i=0;i<3;++i)t[i]=y[3*e+i]};{const t=c(),i=c(),s=c(),n=c(),o=c(),a=(a,u,c,d)=>{S(i,a),S(s,u),S(n,c),h(i,i,s),h(n,n,s),r(t,i,n),e(t,t);const p=l(t,s);S(o,d);const f=l(t,o),m=Math.abs(f-p);b(j(m,0),`Non coplanar ${a},${u},${c},${d} diff = ${m}`)};a(0,1,2,3),a(4,5,6,7),a(0,1,4,5),a(1,2,5,6),a(2,3,6,7),a(3,0,7,4)}const V=p(24),R=(t,e,i)=>{const s=4*t;for(let n=0;n<3;++n)V[s+n]=e[n];V[s+3]=i},C=c(),I=c(),L=c(),P=c(),F=(t,i,s,n)=>{S(C,i),S(I,s),S(L,n),h(C,C,I),e(C,C),h(L,L,I),e(L,L),r(P,C,L),e(P,P);const o=l(P,I);R(t,P,o)};F(0,0,1,2),F(1,1,0,4),F(2,1,5,2),F(3,3,2,6),F(4,4,0,3),F(5,4,6,5);const A=(t,e,i,s)=>{const n=4*t;return V[n]*e+V[n+1]*i+V[n+2]*s-V[n+3]},D=(t,e,i,s)=>A(t,e,i,s)>=-1,E=(t,e)=>D(t,e[0],e[1],e[2]),k=2**this.lij[0]>2*this.lij[1],w=(t,e,s)=>Math.sqrt(T(t,e,s,n[0],n[1],n[2]))<i,U=t=>w(t[0],t[1],t[2]),q=(t,e)=>w(t[e],t[e+1],t[e+2]),N=this.extentInRadians,G=.5*(N[0]+N[2]),z=N[1],O=N[3],W=c(),J=c();H(W,G,O,g),H(J,G,z,g);const K=k?"Upper":"Lower";let Q=!0;for(let e=0;e<6;++e){for(let t=0;t<8;++t){const i=3*t,s=D(e,y[i],y[i+1],y[i+2]);Q&&=s,b(s,`Tile[${this.lij}] Convex hull point ${t} outside of plane ${e}`)}b(E(e,J),`Tile[${this.lij}] (${K}) bottom mid outside of plane ${e}`),b(E(e,W),`Tile[${this.lij}] (${K}) top mid outside of plane ${e}`)}b(Q,"Not all convex hull points are inside convex hull polyhedron"),b(U(J),`Tile[${this.lij}] (${K}) bottom mid outside of bounding sphere`),b(U(W),`Tile[${this.lij}] (${K}) top mid outside of bounding sphere`);for(let e=0;e<8;++e){const t=q(y,3*e);b(t,`Tile[${this.lij}] Convex hull point ${e} outside of bounding sphere`)}for(let e=0;e<6;++e)for(let t=0;t<8;++t){const i=3*t;D(e,y[i],y[i+1],y[i+2])||console.error(`Tile[${this.lij}] Convex hull point ${t} outside of plane ${e}`)}const{extentInRadians:X}=this,Y=Math.max(X[2]-X[0],X[3]-X[1]),Z=Math.round(Y*d),{renderData:tt}=this;if(!tt)return;const{geometry:et,geometryState:it,localOrigin:st}=tt,nt=et.vertexAttributes?.position;if(!nt)return;const ot=c(),rt=et.numVerticesPerSide-2,{indices:lt,indexCount:at,edgeVerticesStartIndex:ht,poleVerticesStartIndex:ut}=et;if(!lt)return;const ct=new Set;for(let e=0;e<at;++e){const t=lt[e];if(ct.has(t))continue;ct.add(t);const r=t<ut,l=t>=ht;let h=!1,c=-1;if(l){let e=ht;for(let i=0;i<4;++i){const s=it.edgeResolutions[i];if(t===e||t===e+s-1){h=!0;break}if(e+=s,t<e){c=i;break}}}const p=l?it.edgePeerNeighbors[c]:null,g=l&&p&&B(this,p)>0;nt.getVec(t,u),s(ot,u,st);const v=o(ot)-d;let _=0,b=!1;const j=f-v,y=v-m,S=j>x,V=y>x,R=S||V,T=()=>{const e=r?"internal":l&&!h?"edge":h?"corner":"pole";return`Tile[${this.lij}].vertex[${t}]:${e}`+(S?"(below)":V?"(above)":"")+(g?"(Neighbor)":"")},H=a(ot,n);if(H>=i+$){const t=H-i;R||(console.error(`${T()} is out of the bounding sphere by ${t.toFixed(0)} / ${i.toFixed(0)}[tol=${$}] h=${v.toFixed(0)} / [${f.toFixed(0)}..${m.toFixed(0)}] (${(t/i).toFixed(0)})`),b=!0)}for(let e=0;e<6;++e)if(!D(e,ot[0],ot[1],ot[2])){const s=A(e,ot[0],ot[1],ot[2]),n=t%rt,o=(t-n)/rt;0===e&&j||5===e&&y||(console.error(`${T()} (${n},${o})|${rt}] is out of the bounding trapezoid plane ${e} h=${Math.round(v)} / [${Math.round(f)}..${Math.round(m)}] dist=${Math.round(s)} radii = ${Math.round(i)}/${Math.round(M)}} : maxL = ${Z}`),++_)}if(b||_>0)break}}get convexHull(){return this._convexHull}}const V=[128,64,64,32,16,8,8,4];function R(t,e,i){return T(t[0],t[1],t[2],e[i],e[i+1],e[i+2])}function T(t,e,i,s,n,o){const r=s-t,l=n-e,a=o-i;return r*r+l*l+a*a}const H=(t,e,i,s)=>{const n=Math.cos(e),o=Math.sin(e),r=Math.cos(i),l=Math.sin(i);t[0]=s*r*n,t[1]=s*r*o,t[2]=s*l},C=[0,0,1],I=c(),L=c();export{S as SphericalPatch};