/* COPYRIGHT Esri - https://js.arcgis.com/5.1.0/LICENSE.txt */
import"../../core/has.js";import"../../core/Logger.js";import{acosClamped as t}from"../../core/mathUtils.js";import{getEpsilon as e}from"../../core/libs/gl-matrix-2/math/common.js";import{fromRotation as r}from"../../core/libs/gl-matrix-2/math/mat4.js";import{copy as i,equals as s,squaredDistance as n,subtract as o,scale as c,length as a,add as h,cross as u,transformMat4 as m,distance as l,lerp as d,scaleAndAdd as g,squaredLength as f,normalize as p,set as M}from"../../core/libs/gl-matrix-2/math/vec3.js";import{fromValues as j,fromArray as y,clone as x,create as _}from"../../core/libs/gl-matrix-2/factories/vec3f64.js";import{fromValues as b}from"../../core/libs/gl-matrix-2/factories/vec4f64.js";import{isVec3 as v}from"../../core/libs/gl-matrix-2/types/vec3.js";import{isVec4 as P}from"../../core/libs/gl-matrix-2/types/vec4.js";import{fromPoints as S,closestPoint as A}from"./ray.js";import{cartesianToSpherical as R}from"./sphereUtils.js";import{angle as q}from"./vector.js";import{sv3d as F,sm4d as O}from"./vectorStacks.js";class w{constructor(t=0,e=0,r=0,i=0){this.radius=i,"number"==typeof t?this._center=j(t,e,r):v(t)||P(t)?(this._center=y(t),this.radius=4===t.length?t[3]:e):(this._center=x(t.center),this.radius=t.radius)}get isValid(){return this.radius>=0}invalidate(){this.radius=-1}get center(){return this._center}set center(t){i(this.center,t)}exactEquals(t){return s(this._center,t.center)&&this.radius===t.radius}copyFrom(t){return t!==this&&(i(this._center,t.center),this.radius=t.radius),this}clone(){return new w(this.center,this.radius)}toVec4(){return b(this.center[0],this.center[1],this.center[2],this.radius)}contains(t){return n(this.center,t)<=this.radius**2}intersectRay(t,e){if(null==t)return!1;if(!this._intersect(t,V))return!1;let{t0:r,t1:i}=V;if((r<0||i<r&&i>0)&&(r=i),r<0)return!1;if(e){const{origin:i,direction:s}=t;e[0]=i[0]+s[0]*r,e[1]=i[1]+s[1]*r,e[2]=i[2]+s[2]*r}return!0}intersectLine(t,r){const i=S(t,r);if(!this._intersect(i,V))return[];const{origin:s,direction:n}=i,{t0:o,t1:c}=V,a=t=>{const e=_();return g(e,s,n,t),this.projectPoint(e,e)};return Math.abs(o-c)<e()?[a(o)]:[a(o),a(c)]}_intersect(t,e){const{origin:r,direction:i}=t,s=C;s[0]=r[0]-this.center[0],s[1]=r[1]-this.center[1],s[2]=r[2]-this.center[2];const n=i[0]*i[0]+i[1]*i[1]+i[2]*i[2];if(0===n)return!1;const o=2*(i[0]*s[0]+i[1]*s[1]+i[2]*s[2]),c=o*o-4*n*(s[0]*s[0]+s[1]*s[1]+s[2]*s[2]-this.radius**2);if(c<0)return!1;const a=Math.sqrt(c);return e.t0=(-o-a)/(2*n),e.t1=(-o+a)/(2*n),!0}projectPoint(t,e){const r=o(F.get(),t,this.center),i=c(F.get(),r,this.radius/a(r));return h(e,i,this.center)}closestPointOnSilhouette(t,e){const i=F.get(),s=O.get();u(i,t.origin,t.direction),u(e,i,t.origin),c(e,e,1/a(e)*this.radius);const n=this._angleToSilhouette(t.origin),o=q(t.origin,e);return r(s,o+n,i),m(e,e,s),e}frustumCoverage(t,e,r){const i=this.radius,s=i*i,n=t+.5*Math.PI,o=e*e+s-2*Math.cos(n)*e*i,c=Math.sqrt(o),a=o-s;if(a<=0)return.5;const h=Math.sqrt(a),u=Math.acos(h/c)-Math.asin(i/(c/Math.sin(n)));return Math.min(1,(u+.5*r)/r)}_angleToSilhouette(e){const r=o(F.get(),e,this.center),i=a(r),s=this.radius,n=s+Math.abs(s-i);return t(s/n)}union(t){const e=l(this._center,t.center),r=this.radius,i=t.radius;return e+i<r?this:e+r<i?(this.copyFrom(t),this):(d(this._center,this._center,t.center,(e+i-r)/(2*e)),this.radius=(e+r+i)/2,this)}toJSON(){return{center:this.center,radius:this.radius}}signedDistanceToPlane(t){const{center:e,radius:r}=this,i=t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3];return i<0?Math.min(i+r,0):Math.max(i-r,0)}}const T={create:t=>new w(t),copy:(t,e)=>e.copyFrom(t),setExtent:(t,e,r)=>r.copyFrom(t),getExtent:(t,e)=>e,elevate:(t,e,r)=>(r.copyFrom(t),r.radius+=e,r),axisAt(t,e,r,i){const s=o(L,e,t.center);switch(r){case 0:{const t=R(s,L)[2];return M(i,-Math.sin(t),Math.cos(t),0)}case 1:{const t=R(s,L),e=t[1],r=t[2],n=Math.sin(e);return M(i,-n*Math.cos(r),-n*Math.sin(r),Math.cos(e))}case 2:return p(i,s);default:return}},altitudeAt(t,e){const r=o(U,e,t.center);return a(r)-t.radius},setAltitudeAt(t,e,r,i){const s=T.altitudeAt(t,e),n=T.axisAt(t,e,2,U),o=c(U,n,r-s);return h(i,e,o)},intersectRay:(t,e,r)=>t.intersectRay(e,r),closestPoint:(t,e,r)=>t.intersectRay(e,r)?r:(A(e,t.center,r),t.projectPoint(r,r)),intersectRayClosestSilhouette(t,e,r){if(t.intersectRay(e,r))return r;const i=t.closestPointOnSilhouette(e,F.get());return h(r,e.origin,c(F.get(),e.direction,l(e.origin,i)/a(e.direction))),r},closestPointOnSilhouette:(t,e,r)=>t.closestPointOnSilhouette(e,r),distanceToSilhouette(t,e){const r=o(F.get(),e,t.center),i=f(r),s=t.radius**2;return Math.sqrt(Math.abs(i-s))}},E=new w,V={t0:0,t1:0},C=_(),L=_(),U=_();export{E as NullSphere,w as Sphere,T as sphereCSO};
