/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import{lerp as t}from"../../../core/mathUtils.js";import{invert as e}from"../../../core/libs/gl-matrix-2/math/mat4.js";import{create as i}from"../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{add as r,scale as n,direction as o,transformMat4 as s,set as a,dot as c}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{create as l}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{getReferenceEllipsoid as p}from"../../../geometry/ellipsoidUtils.js";import{computeTranslationToOriginAndRotation as h}from"../../../geometry/projection/computeTranslationToOriginAndRotation.js";import{projectBoundingRect as d}from"../../../geometry/projection/projectBoundingRect.js";import{projectVectorToVector as _}from"../../../geometry/projection/projectVectorToVector.js";import{empty as m,expandWithVec3 as g,create as x}from"../../../geometry/support/aaBoundingBox.js";import{center as f,create as u}from"../../../geometry/support/aaBoundingRect.js";import{fromPoints as y,create as j}from"../../../geometry/support/lineSegment.js";import{create as b,fromVectorsAndPoint as R,copy as S,negate as B,signedDistance as C}from"../../../geometry/support/plane.js";import{wrap as H}from"../../../geometry/support/ray.js";import{frustumLineSegment as w}from"./intersectionUtils.js";const M=.5*Math.PI,A=M/Math.PI*180;class G{constructor(t){this._extent=new Array(4),this._planes=new Array(6),this._maxSpan=0,this._center={origin:l(),direction:l()},this._renderCoordsHelper=t.renderCoordsHelper;for(let e=0;e<4;e++)this._extent[e]={origin:l(),direction:l(),cap:{next:null,direction:l()}},this._planes[e]=b();this._planes[4]=b(),this._planes[5]=b(),this._planesWithoutFar=this._planes.slice(0,5)}update(t,e,i,s=!0){const a=this._extent;this._toRenderBoundingExtent(t,e,i),r(this._center.origin,a[0].origin,a[2].origin),n(this._center.origin,this._center.origin,.5),this._renderCoordsHelper.worldUpAtPosition(this._center.origin,this._center.direction),s||n(this._center.direction,this._center.direction,-1);for(let r=0;r<4;r++){const t=a[r];this._renderCoordsHelper.worldUpAtPosition(t.origin,t.direction);const e=a[3===r?0:r+1];t.cap.next=e.origin,o(t.cap.direction,t.origin,e.origin),R(t.direction,t.cap.direction,t.origin,this._planes[r]),s||n(t.direction,t.direction,-1)}R(a[0].cap.direction,a[1].cap.direction,a[0].origin,this._planes[4]),s?B(this._planes[4],this._planes[5]):(S(this._planes[5],this._planes[4]),B(this._planes[4],this._planes[4])),this._maxSpan=Math.max(Math.abs(t[0]-t[2]),Math.abs(t[1]-t[3])),this._maxSpanSpatialReference=e,this._minGlobalAltitude=.9*p(this._maxSpanSpatialReference).radius}isVisibleInFrustum(t,e,i=!1){if(null==t)return!1;if(1===this._renderCoordsHelper.viewingMode){const i=this._maxSpanSpatialReference.isGeographic?A:M*e;if(this._maxSpan>i)return!0;if(null!=t.altitude&&t.altitude>=this._minGlobalAltitude)return this._isVisibleInFrustumGlobal(t)}if(0===this._maxSpan){const e=this._extent[0];return!(i||!t.intersectsRay(H(e.origin,e.direction)))}for(let n=0;n<this._extent.length;n++){const e=this._extent[n];if(!i&&t.intersectsRay(H(e.origin,e.direction)))return!0;if(t.intersectsLineSegment(y(e.origin,e.cap.next,P),e.cap.direction))return!0}const r=i?this._planes:this._planesWithoutFar;for(let n=0;n<t.lines.length;n++){const e=t.lines[n];if(w(r,e.origin,e.endpoint,e.direction))return!0}return!1}_toRenderBoundingExtentGlobal(i,r,n){const o=5;f(i,v),v[2]=n,h(r,v,F,this._renderCoordsHelper.spatialReference),e(I,F),m(U);for(const{x0:e,x1:a,y0:c,y1:l}of E)for(let p=0;p<o;p++){const h=p/(o-1);v[0]=t(i[e],i[a],h),v[1]=t(i[c],i[l],h),v[2]=n,_(v,r,v,this._renderCoordsHelper.spatialReference),s(v,v,I),g(U,v)}a(this._extent[0].origin,U[0],U[1],U[2]),a(this._extent[1].origin,U[3],U[1],U[2]),a(this._extent[2].origin,U[3],U[4],U[2]),a(this._extent[3].origin,U[0],U[4],U[2]);for(let t=0;t<4;++t)s(this._extent[t].origin,this._extent[t].origin,F)}_toRenderBoundingExtentLocal(t,e,i){d(t,e,V,this._renderCoordsHelper.spatialReference),a(this._extent[0].origin,V[0],V[1],i),a(this._extent[1].origin,V[2],V[1],i),a(this._extent[2].origin,V[2],V[3],i),a(this._extent[3].origin,V[0],V[3],i)}_toRenderBoundingExtent(t,e,i){switch(this._renderCoordsHelper.viewingMode){case 1:this._toRenderBoundingExtentGlobal(t,e,i);break;case 2:this._toRenderBoundingExtentLocal(t,e,i);break;default:this._renderCoordsHelper.viewingMode}}_isVisibleInFrustumGlobal(t){if(C(t.planes[4],this._center.origin)<0&&c(this._center.direction,t.direction)<0)return!0;for(let e=0;e<4;e++){const i=this._extent[e];if(C(t.planes[4],i.origin)<0&&c(i.direction,t.direction)<0)return!0}return!1}}const E=[{x0:0,y0:1,x1:2,y1:1},{x0:0,y0:3,x1:2,y1:3},{x0:0,y0:1,x1:0,y1:3},{x0:2,y0:1,x1:2,y1:3}],v=l(),F=i(),I=i(),U=x(),V=u(),P=j();export{G as FrustumExtentIntersection};
