/* COPYRIGHT Esri - https://js.arcgis.com/5.0.18/LICENSE.txt */
import{clamp as t}from"../../../../core/mathUtils.js";import{estimateNumberArrayMemory as i}from"../../../../core/memoryEstimations.js";import{create as e}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{nan as n,fromValues as s}from"../../../../geometry/support/aaBoundingBox.js";import{newContinuousIndexArray as r}from"../../../../geometry/support/Indices.js";import{MeshIntersectionOptions as o,intersectRayTriangles as a}from"./RayIntersections.js";const c=40,h=.8,m=10,l=1e-6;class d{constructor(i,n,s){this.globalTriangleVertexIndices=i,this.numTriangles=n,this.positions=s,this._rayDirection=e(),this._callback=I,this._intersectionOptions=M,this.bspNodeTree=new Array,this.triangleIndexMap=r(n);const o=p(i,n,s.data,s.stride),a=t(Math.log2(n/c),2,m),l=(t,i,e)=>{const n=g(this.triangleIndexMap,o,t,i),s=i-t;if(s<=c){const e=new f(n,void 0,0,t,i);return this.bspNodeTree.push(e),e}const{axis:r,midValue:m}=x(n),d=u(this.triangleIndexMap,o,t,i,r,m),p=(t,i)=>{if(e>a)return;const n=i-t;return n<c||n>=h*s?void 0:l(t,i,e+1)},y=new f(n,r,m,d.next,d.mid);return this.bspNodeTree.push(y),y.leftNode=p(t,d.next),y.rightNode=p(d.mid,i),y};l(0,n,0)}intersectRayTriangleRange(t,i){if(t>=i)return;const{data:e,stride:n}=this.positions;a(this._rayFrom,this._rayDirection,t,i,this.globalTriangleVertexIndices,e,n,this._intersectionOptions.normalRequired,this._callback,this.triangleIndexMap),d.numFacesTested+=i-t}intersectRay(t,i,e,n){d.numFacesTested=0;const s=t,r=i,o=r[0]-s[0],a=r[1]-s[1],c=r[2]-s[2];if(o*o+a*a+c*c<l)return;this._rayFrom=s;const h=this._rayDirection;h[0]=o,h[1]=a,h[2]=c;const m=this.triangleIndexMap.length;this._callback=n,this._intersectionOptions=e,this.intersectRayBSP(this.bspNodeTree[0],0,m),this._callback=I,this._intersectionOptions=M}intersectRayBSP(t,i,e){const n=this._rayFrom,s=this._rayDirection;if(!y(t.aabb,n,s))return;const r=t.axis,o=t.d;if(n[r]<o||s[r]<0){const e=i,n=t.midStartIndex;if(e<n){const i=t.leftNode;void 0!==i?this.intersectRayBSP(i,e,n):this.intersectRayTriangleRange(e,n)}}if(this.intersectRayTriangleRange(t.midStartIndex,t.rightStartIndex),n[r]>o||s[r]>0){const i=t.rightStartIndex,n=e;if(i<n){const e=t.rightNode;void 0!==e?this.intersectRayBSP(e,i,n):this.intersectRayTriangleRange(i,n)}}}static{this.numFacesTested=0}get estimatedMemoryUsage(){return i(this.triangleIndexMap)}}class f{constructor(t,i,e,n,s){this.aabb=t,this.axis=i,this.d=e,this.midStartIndex=n,this.rightStartIndex=s}}function u(t,i,e,n,s,r){let o=e,a=n;for(;o<a;){const e=t[o];i[6*e+s+3]<=r?++o:(--a,t[o]=t[a],t[a]=e)}let c=o;for(a=n;c<a;){const e=t[a-1];i[6*e+s]>=r?--a:(t[a-1]=t[c],t[c]=e,++c)}return{next:o,mid:c}}function g(t,i,e,r){if(r<=e)return n;let o=6*t[e];const a=s(i[o++],i[o++],i[o++],i[o++],i[o++],i[o]);for(let n=e+1;n<r;++n){let e=6*t[n];a[0]=Math.min(a[0],i[e++]),a[1]=Math.min(a[1],i[e++]),a[2]=Math.min(a[2],i[e++]),a[3]=Math.max(a[3],i[e++]),a[4]=Math.max(a[4],i[e++]),a[5]=Math.max(a[5],i[e])}return a}function x(t){const i=t[3]-t[0],e=t[4]-t[1],n=t[5]-t[2],s=i>e?i>n?0:e>n?1:2:e>n?1:n>i?2:0;return{axis:s,midValue:(t[s]+t[s+3])/2}}function p(t,i,e,n){const s=new Array;for(let r=0;r<i;++r){const i=3*r,o=t[i]*n,a=t[i+1]*n,c=t[i+2]*n;for(let t=0;t<3;++t){const i=e[o+t],n=e[a+t],h=e[c+t];s[6*r+t]=Math.min(i,n,h),s[6*r+3+t]=Math.max(i,n,h)}}return s}function y(t,i,e){const n=i,s=e;let r=0,o=1/0;for(let a=0;a<3;++a){{const i=t[a];if(n[a]<i){if(s[a]<=l)return!1;const t=(i-n[a])/s[a];r=Math.max(r,t)}else if(s[a]<=-l){const t=(i-n[a])/s[a];o=Math.min(o,t)}if(r>o)return!1}{const i=t[a+3];if(n[a]>i){if(s[a]>=-l)return!1;const t=(i-n[a])/s[a];r=Math.max(r,t)}else if(s[a]>=l){const t=(i-n[a])/s[a];o=Math.min(o,t)}if(r>o)return!1}}return!0}const M=new o,I=()=>{};export{d as TriangleIntersectionData};
