@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 8.5 kB
JavaScript
import{lerp as t}from"../../../core/mathUtils.js";import{n as e,s,a as i,g as o,u as n,f as r,e as l,j as a,w as h}from"../../../chunks/vec3.js";import{d as u,c}from"../../../chunks/vec3f64.js";import{lonLatToSphericalPCPF as d}from"../../../geometry/projection.js";import{intersectsSphere as p,NumPlanes as f,PlaneIndex as m}from"../../../geometry/support/frustum.js";import{c as g}from"../../../chunks/sphere.js";import{TileFrustumVisibility as $,PatchType as _}from"./interfaces.js";import{createSphericalGlobePatch as v,updateCornerSpherical as x,updateEdgesAndCornersSpherical as M}from"./PatchGeometryFactory.js";import{ENABLE_TERRAIN_INTERNAL_CHECKS as b,internalAssert as j,almostEquals as S}from"./terrainUtils.js";import{Tile as T,CenterPosition as E}from"./Tile.js";import{compareTilesByLij as H}from"./tileUtils.js";import{newDoubleArray as D}from"../webgl-engine/lib/DoubleArray.js";class I extends T{get convexHull(){return this._convexHull}constructor(t,e,s){super(),this._convexHull=new Array(24),this._boundingSphere=g(),void 0!==t&&this.init(t,e,s)}init(s,i,o){super.init(s,i,o);const n=this.ellipsoid.radius,r=this.extentInRadians[0],l=this.extentInRadians[1],a=this.extentInRadians[2],h=this.extentInRadians[3],c=s[0],p=t(l,h,.5),f=t(r,a,.5),m=0===c?0:Math.min(Math.abs(l),Math.abs(h));this._edgeLen=(a-r)*Math.cos(m)*n,this._edgeLen2=this._edgeLen*this._edgeLen,this._curvatureHeight=n-Math.sqrt(n*n-this._edgeLen2/4),d(this.centerAtSeaLevel,f,p,this.ellipsoid.radius);const g=u(this.centerAtSeaLevel);e(g,g),this.up=g,this.updateRadiusAndCenter()}updateRadiusAndCenter(){this._updateBoundingVolumes();const t=this._center;if(0===this.lij[0])s(t[E.MIDDLE],0,0,0),s(t[E.TOP],0,0,0),s(t[E.BOTTOM],0,0,0),t[E.MIDDLE][3]=this.ellipsoid.radius+this.elevationBounds[1];else{this._updateCenter();const e=t[E.MIDDLE],s=this.convexHull;let i=0;for(let t=0;t<8;++t)i=Math.max(i,R(e,s,3*t));t[E.MIDDLE][3]=Math.sqrt(i)}}_calculateFrustumVisibilityStatus(t){if(!p(t,this._boundingSphere))return $.OUTSIDE;if(this.lij[0]<10)return $.INTERSECTS;const e=this.convexHull,s=this.surface.view.state.camera.near;let i=!0;for(let o=0;o<f.NUM;o++){const n=o===m.NEAR,r=t[o],l=r[0],a=r[1],h=r[2],u=r[3]-(n?s:0);let c=!1;for(let t=0;t<8;++t){const s=3*t;if(l*e[s+0]+a*e[s+1]+h*e[s+2]+u<0){if(c=!0,!i)break}else i=!1}if(!c)return $.OUTSIDE}return i?$.INSIDE:$.INTERSECTS}computeElevationBounds(){super.computeElevationBounds(),this._updateBoundingVolumes()}createGeometry(){v(this.renderData,this._getPatchType()),this._updateBoundingVolumes(),this.setMemoryDirty()}_updateBoundingVolumes(){this._updateConvexHull(),this._updateBoundingSphere(),b&&this._checkBVs()}_updateBoundingSphere(){const t=this._boundingSphere,e=t,r=this.elevationBounds,l=this.ellipsoid.radius,a=r[1];if(0===this.level)s(e,0,0,0),t[3]=l+a;else{const s=this.extentInRadians,a=.5*(s[0]+s[2]),h=s[1],u=s[3];B(A,a,h,l),B(P,a,u,l),i(e,A,P);const c=.5*(r[0]+r[1]);o(e,e,(l+c)/n(e));const d=this.convexHull;let p=0;const f=(t,e)=>{const s=t[0]-d[3*e+0],i=t[1]-d[3*e+1],o=t[2]-d[3*e+2];return Math.sqrt(s*s+i*i+o*o)};for(let t=0;t<8;++t){const s=f(e,t);p=Math.max(p,s)}const m=p;t[3]=m+2}}_updateConvexHull(){const t=this.extentInRadians,s=this.ellipsoid.radius;if(0===this.level)return;const a=this.elevationBounds,u=this._getPatchType(),d=this.surface.isWebMercator,p=d&&u===_.HAS_NORTH_POLE,f=d&&u===_.HAS_SOUTH_POLE,m=f||p,g=Math.PI/2,$=t[0],v=t[2],x=f?-g:t[1],M=p?g:t[3],b=.5*($+v),T=a[0],E=s+(m?Math.min(0,T-1):T),H=(t,e,s)=>B(t,e,s,E),D=c(),I=c(),L=c(),R=c();H(D,$,x),H(I,$,M),H(L,v,M),H(R,v,x);const y=(t,e)=>{for(let s=0;s<3;++s)this._convexHull[3*e+s]=t[s]};y(D,0),y(I,1),y(L,2),y(R,3);const A=a[1],P=s+(m?Math.max(0,A+1):A),V=c(),C=c(),N=c();B(C,b,M,E),B(N,b,x,E),i(V,C,N),e(V,V);const U=c(),k=c(),F=(t,s)=>{h(k,t,s),e(k,k);const n=-l(t,U)/l(k,U);j(n>=0),o(k,k,n),i(t,t,k)};if(2**this.lij[0]>2*this.lij[1]){const t=N,s=c();r(s,O,t),e(s,s),r(U,t,s),e(U,U),j(S(l(U,t)/n(t),0)),F(D,I),F(R,L),y(D,0),y(R,3)}else if(2**this.lij[0]!==2*this.lij[1]){const t=C,s=c();r(s,O,t),e(s,s),r(U,s,t),e(U,U),F(I,D),F(L,R),y(I,1),y(L,2)}const w=(t,e)=>{const s=P/l(e,V);for(let i=0;i<3;++i)this._convexHull[3*t+i]=e[i]*s};w(4,D),w(5,I),w(6,L),w(7,R)}_getPatchType(){const t=this.lij[1],e=0===t,s=t===(1<<this.level)-1;return e?s?_.HAS_BOTH_POLES:_.HAS_NORTH_POLE:s?_.HAS_SOUTH_POLE:_.REGULAR}intersectsRay(t,e,s,i){const o=this._boundingSphere,n=o[3]+s,r=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],l=o[0]-t[0],a=o[1]-t[1],h=o[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<n*n}getDefaultVerticesPerSide(){return this.level<L.length?L[this.level]+1:2}updateCornerElevations(){x(this.renderData),this._updateBoundingVolumes()}updateEdgeElevations(){M(this.renderData),this._updateBoundingVolumes()}_checkBVs(){if(!b)return;if(this.level<=2)return;const t=this._boundingSphere,s=t[3],o=t,u=c(),d=this.ellipsoid.radius,p=this.elevationBounds;p[1],p[0];const f=d+p[0],m=1,g=0,$=this._center[E.MIDDLE][3],_=this.convexHull,v=(t,e)=>{for(let s=0;s<3;++s)t[s]=_[3*e+s]};{const t=c(),s=c(),i=c(),o=c(),n=c(),a=(a,u,c,d)=>{v(s,a),v(i,u),v(o,c),h(s,s,i),h(o,o,i),r(t,s,o),e(t,t);const p=l(t,i);v(n,d);const f=l(t,n),m=Math.abs(f-p);j(S(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 x=D(24),M=(t,e,s)=>{const i=4*t;for(let o=0;o<3;++o)x[i+o]=e[o];x[i+3]=s},T=c(),I=c(),L=c(),R=c(),O=(t,s,i,o)=>{v(T,s),v(I,i),v(L,o),h(T,T,I),e(T,T),h(L,L,I),e(L,L),r(R,T,L),e(R,R);const n=l(R,I);M(t,R,n)};O(0,0,1,2),O(1,1,0,4),O(2,1,5,2),O(3,3,2,6),O(4,4,0,3),O(5,4,6,5);const A=1,P=(t,e,s,i)=>{const o=4*t;return x[o+0]*e+x[o+1]*s+x[o+2]*i-x[o+3]},V=(t,e,s,i)=>P(t,e,s,i)>=-A,C=(t,e)=>V(t,e[0],e[1],e[2]),N=2**this.lij[0]>2*this.lij[1],U=(t,e,i)=>Math.sqrt(y(t,e,i,o[0],o[1],o[2]))<s,k=t=>U(t[0],t[1],t[2]),F=(t,e)=>U(t[e+0],t[e+1],t[e+2]),w=this.extentInRadians,q=.5*(w[0]+w[2]),G=w[1],z=w[3],W=c(),J=c();B(W,q,z,f),B(J,q,G,f);const K=N?"Upper":"Lower";let Q=!0;for(let e=0;e<6;++e){for(let t=0;t<8;++t){const s=3*t,i=V(e,_[s+0],_[s+1],_[s+2]);Q&&(Q=i),j(i,`Tile[${this.lij}] Convex hull point ${t} outside of plane ${e}`)}j(C(e,J),`Tile[${this.lij}] (${K}) bottom mid outside of plane ${e}`),j(C(e,W),`Tile[${this.lij}] (${K}) top mid outside of plane ${e}`)}j(Q,"Not all convex hull points are inside convex hull polyhedron"),j(k(J),`Tile[${this.lij}] (${K}) bottom mid outside of bounding sphere`),j(k(W),`Tile[${this.lij}] (${K}) top mid outside of bounding sphere`);for(let e=0;e<8;++e){const t=F(_,3*e);j(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 s=3*t;V(e,_[s+0],_[s+1],_[s+2])||console.error(`Tile[${this.lij}] Convex hull point ${t} outside of plane ${e}`)}const X=this.extentInRadians,Y=Math.max(X[2]-X[0],X[3]-X[1]),Z=Math.round(Y*d),tt=this.renderData;if(tt){const t=tt.geometryInfo,e=tt.localOrigin,r=t.vertexAttributes?.position;if(!r)return;const l=r.count,h=c(),f=t.numVerticesPerSide-2,_=f*f,v=tt.geometryState.neighborData,x=v.edgeResolutions.reduce(((t,e)=>t+e+1),0);for(let c=0;c<l;++c){const t=c<_,l=!t&&c<_+x;let M=!1,b=-1;if(l){let t=_;for(let e=0;e<4;++e){const s=v.edgeResolutions[e];if(c===t||c===t+s-1){M=!0;break}if(t+=s,c<t){b=e;break}}}const j=b,S=M,T=l&&!S,E=l?v.edgePeerNeighbors[j]:null,D=l&&E&&H(this,E)>0,I=t?"internal":T?"edge":S?"corner":"pole";r.getVec(c,u),i(h,u,e);const L=n(h)-d;let R=0,y=!1;const B=p[0]-L,O=L-p[1],A=B>m,C=O>m,N=A||C,U=`Tile[${this.lij}].vertex[${c}]:${I}`+(A?"(below)":C?"(above)":"")+(D?"(Neighbor)":"");{const t=a(h,o);if(t>=s+g){const e=t-s;N||(console.error(`${U} is out of the bounding sphere by ${e.toFixed(0)} / ${s.toFixed(0)}[tol=${g}] h=${L.toFixed(0)} / [${p[0].toFixed(0)}..${p[1].toFixed(0)}] (${(e/s).toFixed(0)})`),y=!0)}}for(let e=0;e<6;++e)if(!V(e,h[0],h[1],h[2])){const t=P(e,h[0],h[1],h[2]),i=c%f,o=(c-i)/f;0===e&&B||5===e&&O||(console.error(`${U} (${i},${o})|${f}] is out of the bounding trapezoid plane ${e} h=${Math.round(L)} / [${Math.round(p[0])}..${Math.round(p[1])}] dist=${Math.round(t)} radii = ${Math.round(s)}/${Math.round($)}} : maxL = ${Z}`),++R)}if(y||R>0)break}}}}const L=[128,64,64,32,16,8,8,4];function R(t,e,s){return y(t[0],t[1],t[2],e[s+0],e[s+1],e[s+2])}function y(t,e,s,i,o,n){const r=i-t,l=o-e,a=n-s;return r*r+l*l+a*a}const B=(t,e,s,i)=>{const o=Math.cos(e),n=Math.sin(e),r=Math.cos(s),l=Math.sin(s);t[0]=i*r*o,t[1]=i*r*n,t[2]=i*l},O=[0,0,1],A=c(),P=c();export{I as SphericalPatch};