/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{acosClamped as e,clamp as t,asinClamped as r,deg2rad as n}from"../../../../core/mathUtils.js";import{fromRotation as i}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as a}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{subtract as s,transformMat4 as o,scale as c,add as u,squaredLength as l,distance as m,dot as d,normalize as f,length as h}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{create as p}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{getReferenceEllipsoid as M}from"../../../../geometry/ellipsoidUtils.js";import{Sphere as y}from"../../../../geometry/support/sphere.js";import{defaultConstraintOptions as C,hasConstraintType as I,adjustRangeForInteraction as x}from"./common.js";import{viewAngle as S}from"../../state/utils/viewUtils.js";function v(e,t,r,n=!0){K.eyeCenterDistance=0,K.requiresTwoSteps=!1;const a=w(e,t,r,C,K);if(0===a)return!1;switch(i(k,-a,t.viewRight),r.tiltMode){case 1:o(U,t.viewForward,k),c(U,U,K.eyeCenterDistance),t.center=u(L,t.eye,U);break;case 0:s(U,t.center,t.eye),o(U,U,k),t.eye=s(L,t.center,U);break;default:r.tiltMode}return t.up=o(L,t.up,k),!K.requiresTwoSteps||!n||v(e,t,r,!1)}function w(e,t,r,n=C,i){if(!e.state.constraints.tilt)return 0;const a=Math.min(t.relativeElevation*B,t.distance),s=e.state.constraints.tilt(a,G);return F(e,r,s),2===n.interactionType&&I(n.selection,2)&&E(e,n.interactionStartCamera,s),1===r.tiltMode||1===n.tiltMode?P(e,t,s,i):A(e,t,s)}function A(e,r,n){const i=S(e.renderCoordsHelper,r.center,r.eye),a=i-t(i,n.min,n.max);return O(a)?a:0}function P(e,t,r,n){switch(n&&(n.requiresTwoSteps=!1),e.viewingMode){case"global":return T(e,t,r,n);case"local":return R(e,t,r,n)}}function R(e,r,n,i){const a=S(e.renderCoordsHelper,r.center,r.eye),s=t(a,n.min,n.max),o=a-s;if(!O(o))return 0;if(i){const t=Math.abs(e.pointsOfInterest.centerOnSurfaceFrequent.estimatedSurfaceAltitude),n=e.renderCoordsHelper.getAltitude(r.eye)-t,a=Math.max(Math.cos(s),1e-4);Math.abs(a)>1e-4?i.eyeCenterDistance=n/a:i.eyeCenterDistance=r.distance}return o}function T(e,r,n,i){const a=b(e,r,J),s=t(a.tiltAtCenter,n.min,n.max);if(!O(a.tiltAtCenter-s))return 0;let o,c;return a.centerIsOnSurface?(o=j(a),c=H(a,o)):(o=a.constraints.clampTilt(a.distance,a.tiltAtCenter),i&&o<Math.PI/2&&(i.requiresTwoSteps=!0,o=Math.PI/2-1e-5),c=D(a,o)),i&&(i.eyeCenterDistance=q(a,o)),c}function b(t,r,n){const i=t.pointsOfInterest.centerOnSurfaceFrequent.estimatedSurfaceAltitude,a=i+M(t.spatialReference).radius,s=t.renderCoordsHelper.intersectManifold(r.ray,i,L);return n.distance=Math.min(r.relativeElevation*B,r.distance),n.centerIsOnSurface=!1,null!=s?(n.distance=Math.min(r.relativeElevation*B,m(r.eye,s)),n.tiltAtCenter=S(t.renderCoordsHelper,s,r.eye),n.centerIsOnSurface=!0):t.state.isLocal?n.tiltAtCenter=S(t.renderCoordsHelper,r.center,r.eye):(g.radius=a,g.closestPointOnSilhouette(r.ray,L),n.distance=Math.min(r.relativeElevation*B,m(r.eye,L)),n.tiltAtCenter=e(-d(r.viewForward,f(L,L)))),n.radius=a,n.eyeRadius=h(r.eye),n.constraints=t.state.constraints,n}const g=new y;function O(e){return Math.abs(e)>1e-9}function j(e){const{constraints:t,distance:r,tiltAtCenter:n}=e;let i=n,a=t.clampTilt(r,n);const s=q(e,a);if(t.clampTilt(s,n)===a)return a;let o=0;for(;o<10&&O(a-i);){const r=(i+a)/2,n=q(e,r);O(t.clampTilt(n,r)-r)?i=r:a=r,o++}return a}function q(e,n){if(!e.centerIsOnSurface)return e.distance;const i=Math.PI-t(n,0,Math.PI),a=r(e.radius/e.eyeRadius*Math.sin(i)),s=Math.PI-i-a,o=Math.sin(s)/Math.sin(i);if(e.eyeRadius<e.radius&&o>1){const t=Math.PI-a,r=Math.PI-i-t;return Math.sin(r)/Math.sin(i)*e.eyeRadius}return o*e.eyeRadius}function H(e,t){const n=r(e.radius/e.eyeRadius*Math.sin(e.tiltAtCenter)),i=r(e.radius/e.eyeRadius*Math.sin(t));return e.eyeRadius>e.radius?n-i:i-n}function D(e,t){return e.tiltAtCenter-Math.PI/2-(t-Math.PI/2)}function F(e,t,r){if(0===t.interactionType)return;const{interactionStartCamera:n,interactionFactor:i}=t;if(!n)return;const{min:a,max:s}=r,o=w(e,n,C,t),c=0===o?0:S(e.renderCoordsHelper,n.center,n.eye);r.min=a,r.max=s,2===t.interactionType?(I(t.selection,2)&&E(e,n,r),x(o,c,!0,i,z,r)):x(o,c,!1,i,z,r)}function E(t,r,n){const i=t.state.constraints;if(t.state.isLocal||!i.altitude||!r)return;const a=l(r.center),s=Math.sqrt(a),o=r.distance,c=M(t.spatialReference).radius,u=i.altitude.min+c,m=i.altitude.max+c,d=(u*u-o*o-a)/(-2*s*o),f=(m*m-o*o-a)/(-2*s*o);n.min=Math.max(n.min,Math.min(Math.PI-e(f),n.max)),n.max=Math.min(n.max,Math.PI-e(d))}const U=p(),k=a(),L=p(),z=n(5),B=30,G={min:0,max:0},J={constraints:null,radius:0,eyeRadius:0,centerIsOnSurface:!0,distance:0,tiltAtCenter:0},K={eyeCenterDistance:0,requiresTwoSteps:!1};export{v as applyTiltConstraint,w as getTiltConstraintError};
