@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 5.09 kB
JavaScript
import{acosClamped as e}from"../../../../core/mathUtils.js";import t from"../../../../core/ObjectPool.js";import{b as i,g as s,a as r,o as n,e as o}from"../../../../chunks/vec3.js";import{c as a}from"../../../../chunks/vec3f64.js";import{getReferenceEllipsoid as u}from"../../../../geometry/ellipsoidUtils.js";import{PointIndex as l,PlaneIndex as d}from"../../../../geometry/support/frustum.js";import{create as _,projectVector as c,fromPoints as h,normal as m}from"../../../../geometry/support/plane.js";import{wrap as T}from"../../../../geometry/support/ray.js";import{ViewingMode as p}from"../../../ViewingMode.js";import{FeatureTileDescriptor3D as E,Visibility as I}from"./FeatureTileDescriptor3D.js";import{Frustum as F}from"../../state/Frustum.js";import{FrustumExtentIntersection as f}from"../../support/FrustumExtentIntersection.js";class A{constructor(e){this._renderCoordsHelper=e,this._surfaceElevation=0,this._cache=new Map,this._frustum=new F(e),this._extendedFrustum=new F(e),this._intersector=new f({renderCoordsHelper:e}),this._renderCoordsHelper=e}begin(e,t){this._surfaceElevation=t,this._aboveGround=this._renderCoordsHelper.getAltitude(e.eye)>t,this._frustum.update(e),this._shortenFrustumFarPlane(this._frustum),this._updateExtendedFrustum(e)}end(){this._cache.clear()}calculate(e){if(this._allTilesInvisible)return I.INVISIBLE;const t=this._renderCoordsHelper.viewingMode===p.Global&&e.lij[0]>=R&&e.lij[0]<O,i=this._getOrCalculateSingleTileVisibility(e,!t);return i!==I.INVISIBLE&&t?this._calculateAggregatedChildrenVisibility(e):i}_shortenFrustumFarPlane(e){const t=F.nearFarLineIndices,n=e.mutablePoints;for(const o of t){const[e,t]=o,a=n[e],u=n[t];i(S,u,a),s(S,S,b),r(n[t],a,S)}e.updatePoints(n)}_calculateAggregatedChildrenVisibility(e){let t=I.INVISIBLE;const i=this._cache.get(e.id);if(null!=i)return i;const s=H.acquire();e.getChildren(s);for(const r of s){const e=this.calculate(r);if(e!==I.INVISIBLE&&(t=e,e===I.VISIBLE_ON_SURFACE))break}return H.release(s),this._cache.set(e.id,t),t}_getOrCalculateSingleTileVisibility(e,t){const i=this._cache.get(e.id);if(null!=i)return i;const s=this._calculateSingleTileVisibility(e);return t&&this._cache.set(e.id,s),s}_calculateSingleTileVisibility(e){if(!this._aboveGround&&this._renderCoordsHelper.viewingMode===p.Global&&e.lij[0]<g){return this._calculateSingleTileVisibilitySided(e,!1)===I.INVISIBLE?this._calculateSingleTileVisibilitySided(e,!0):void 0}return this._calculateSingleTileVisibilitySided(e,this._aboveGround)}_calculateSingleTileVisibilitySided(e,t){this._intersector.update(e.extent,e.tilingScheme.spatialReference,this._surfaceElevation,t);const i=u(e.tilingScheme.spatialReference).radius;return this._intersector.isVisibleInFrustum(this._extendedFrustum,i)?this._intersector.isVisibleInFrustum(this._frustum,i,!0)?I.VISIBLE_ON_SURFACE:I.VISIBLE_WHEN_EXTENDED:I.INVISIBLE}_updateExtendedFrustum(t){this._extendedFrustum.update(t),this._shortenFrustumFarPlane(this._extendedFrustum);const i=this._renderCoordsHelper.worldUpAtPosition(t.eye,S);this._aboveGround||n(i,i);const r=e(-o(i,t.viewForward));if(this._allTilesInvisible=r>(Math.PI+t.fovY)/2,this._allTilesInvisible)return;if(this._hasExtendedFrustum=r>t.fovY/2,!this._hasExtendedFrustum)return;const a=this._extendedFrustumParameters(),u=this._extendedFrustum.mutablePoints;for(let e=0;e<4;e++){const t=a.pointIndices[e],i=u[t],r=this._renderCoordsHelper.getAltitude(i);if(a.needsAltitudeAdjustment(r)){switch(this._renderCoordsHelper.worldUpAtPosition(i,S),t){case l.FAR_BOTTOM_LEFT:case l.FAR_TOP_LEFT:case l.NEAR_BOTTOM_LEFT:case l.NEAR_TOP_LEFT:c(this._extendedFrustum.planes[d.LEFT],S,S);break;case l.FAR_BOTTOM_RIGHT:case l.FAR_TOP_RIGHT:case l.NEAR_BOTTOM_RIGHT:case l.NEAR_TOP_RIGHT:c(this._extendedFrustum.planes[d.RIGHT],S,S)}s(S,S,a.direction),this._renderCoordsHelper.intersectInfiniteManifold(T(i,S),a.zWithMargin,i)}}if(this._extendedFrustum.updatePoints(u),h(u[l.NEAR_BOTTOM_LEFT],u[l.NEAR_BOTTOM_RIGHT],u[l.NEAR_TOP_RIGHT],N),h(u[l.NEAR_BOTTOM_RIGHT],u[l.NEAR_TOP_RIGHT],u[l.NEAR_TOP_LEFT],v),o(m(N),m(v))<0){const e=this._extendedFrustum.mutablePoints;this._aboveGround?[e[l.NEAR_BOTTOM_LEFT],e[l.NEAR_BOTTOM_RIGHT]]=[e[l.NEAR_BOTTOM_RIGHT],e[l.NEAR_BOTTOM_LEFT]]:[e[l.NEAR_TOP_LEFT],e[l.NEAR_TOP_RIGHT]]=[e[l.NEAR_TOP_RIGHT],e[l.NEAR_TOP_LEFT]],this._extendedFrustum.updatePoints(e)}}_extendedFrustumParameters(){return this._aboveGround?this._extendedFrustumParametersAboveSurface():this._extendedFrustumParametersBelowSurface()}_extendedFrustumParametersAboveSurface(){const e=this._surfaceElevation-P;return{zWithMargin:e,pointIndices:F.planePointIndices.bottom,direction:-1,needsAltitudeAdjustment:t=>t>e}}_extendedFrustumParametersBelowSurface(){const e=this._surfaceElevation+P;return{zWithMargin:e,pointIndices:F.planePointIndices.top,direction:1,needsAltitudeAdjustment:t=>t<e}}}const R=2,O=6,g=12,b=.95,P=1,S=a(),N=_(),v=_(),H=new t(Array,(e=>{4!==e.length&&(e[0]=new E,e[1]=new E,e[2]=new E,e[3]=new E)}),(e=>{e[0].release(),e[1].release(),e[2].release(),e[3].release()}));export{A as FeatureTileVisibility3D};