/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{add as t,transformMat4 as i}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{create as r}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{create as s,fromPoints as e,copy as n}from"../../../../geometry/support/ray.js";import a from"../../webgl/RenderCamera.js";import{HUDTarget as o,HUDIntersectorResult as h}from"./HUDIntersectorResult.js";import{IntersectorOptions as c}from"./IntersectorInterfaces.js";import{IntersectorResult as l}from"./IntersectorResult.js";import{IntersectorTransform as f,getVerticalOffsetObject3D as d}from"./verticalOffsetUtils.js";const m=1e-5;class u{constructor(t){this.options=new c,this._results=new _,this.transform=new f,this.camera=new a,this.tolerance=m,this.verticalOffset=null,this._ray=s(),this._rayEnd=r(),this._rayBeginTransformed=r(),this._rayEndTransformed=r(),this.viewingMode=t??1}get results(){return this._results}get ray(){return this._ray}get rayBegin(){return this._ray.origin}get rayEnd(){return this._rayEnd}reset(t,i,r){this.resetWithRay(e(t,i,this._ray),r)}resetWithRay(i,r){this.camera=r,i!==this._ray&&n(i,this._ray),0!==this.options.verticalOffset?2===this.viewingMode?this._ray.origin[2]-=this.options.verticalOffset:this.verticalOffset=this.options.verticalOffset:this.verticalOffset=null,t(this._rayEnd,this._ray.origin,this._ray.direction),this._results.init(this._ray)}intersect(t=null,i,r,s,e){this.point=i,this.filterPredicate=s,this.tolerance=r??m;const n=d(this.verticalOffset);if(t&&t.length>0){const i=e?t=>{e(t)&&this.intersectObject(t)}:t=>{this.intersectObject(t)};for(const r of t){const t=r.getSpatialQueryAccelerator?.();null!=t?(null!=n?t.forEachAlongRayWithVerticalOffset(this._ray.origin,this._ray.direction,i,n):t.forEachAlongRay(this._ray.origin,this._ray.direction,i),this.options.selectionMode&&this.options.hud&&t.forEachDegenerateObject(i)):r.objects.forEach(t=>i(t))}}this.sortResults()}intersectObject(t){const r=t.geometries;if(!r)return;const s=t.effectiveTransformation,e=d(this.verticalOffset);for(const n of r){if(!n.visible)continue;const{material:r,id:a}=n;if(!r.visible)continue;this.transform.setAndInvalidateLazyTransforms(s,n.transformation),i(this._rayBeginTransformed,this.rayBegin,this.transform.inverse),i(this._rayEndTransformed,this.rayEnd,this.transform.inverse);const o=this.transform.transform;null!=e&&(e.objectTransform=this.transform),r.intersect(n,this.transform.transform,this,this._rayBeginTransformed,this._rayEndTransformed,(i,r,s,e)=>this.handleObjectIntersection({object:t,geometryId:a,primitiveIndex:s},i,r,o,e))}}handleObjectIntersection(t,i,r,s,e){if(i<0||null!=this.filterPredicate&&!this.filterPredicate(this._ray.origin,this._rayEnd,i))return;const n=e?this._results.hud:this._results;t=e?new o(t,e):t;const a=e?s=>s.set(1,t,i,r):e=>e.set(4,t,i,r,s);if((null==n.min.distance||i<n.min.distance)&&a(n.min),0!==this.options.store&&(null==n.max.distance||i>n.max.distance)&&a(n.max),2===this.options.store)if(e){const t=new h(this._ray);a(t),this._results.hud.all.push(t)}else{const t=new l(this._ray);a(t),this._results.all.push(t)}}sortResults(t=this._results.all){t.sort((t,i)=>t.distance!==i.distance?(t.distance??0)-(i.distance??0):t.drapedLayerOrder!==i.drapedLayerOrder?y(t.drapedLayerOrder,i.drapedLayerOrder):y(t.renderPriority,i.renderPriority))}}function y(t,i){return(i??-Number.MAX_VALUE)-(t??-Number.MAX_VALUE)}class _{constructor(){this.min=new l(s()),this.max=new l(s()),this.hud={min:new h(s()),max:new h(s()),all:new Array},this.ground=new l(s()),this.all=[]}init(t){this.min.init(t),this.max.init(t),this.ground.init(t),this.all.length=0,this.hud.min.init(t),this.hud.max.init(t),this.hud.all.length=0}}export{u as Intersector,m as defaultTolerance};
