UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 7.77 kB
import{isNone as e,isSome as t,unwrapOr as r}from"../../../../core/maybe.js";import i from"../../../../core/PooledArray.js";import{castRenderScreenPointArray3 as n,createRenderScreenPointArray3 as s}from"../../../../core/screenUtils.js";import{a as o,n as a}from"../../../../chunks/vec3.js";import{c}from"../../../../chunks/vec3f64.js";import{create as l,copy as h,NEGATIVE_INFINITY as u,width as d,height as p,expandPointInPlace as m}from"../../../../geometry/support/aaBoundingRect.js";import{create as y}from"../../../../geometry/support/ray.js";import{sv3d as g}from"../../../../geometry/support/vectorStacks.js";import{ViewingMode as f}from"../../../ViewingMode.js";import{fromRenderAtEye as _,fromScreen as R}from"../../support/geometryUtils/ray.js";import{DEFAULT_TOLERANCE as v,newIntersector as I}from"../../webgl-engine/lib/Intersector.js";import{StoreResults as b,IntersectorType as w}from"../../webgl-engine/lib/IntersectorInterfaces.js";import{isValidIntersectorResult as P,sliceFilterPredicate as M}from"../../webgl-engine/lib/intersectorUtils.js";class j{constructor(e,t,r){this.viewingMode=e,this._forEachLayer=t,this._view=r,this._externalIntersectionHandlers=new i,this._tolerance=v,this._tmpRay=y(),this._tmpRegion=l(),this._validateHUDIntersector=I(this.viewingMode),this._validateHUDIntersector.options.hud=!1}intersectScreen(e,t,r){return this.intersectRay(this._getPickRay(e,this._tmpRay),L(this.viewingMode),t,r)}intersectScreenFreePointFallback(e,t,r){return this.intersectRayFreePointFallback(this._getPickRay(e,this._tmpRay),t,r)}intersectRayFreePointFallback(e,t,r){return this.intersectRay(e,L(this.viewingMode),t,r)||this._intersectRayFreePointLocal(e,t)}intersectRay(e,t,r,i){return t.options.selectionMode=!1,t.options.store=b.MIN,this.computeIntersection(e,t,i),!!t.results.min&&t.results.min.getIntersectionPoint(r)}getCenterRayWithSubpixelOffset(e,t,r=.5,i=.5){return e.getRenderCenter(F,r,i),F[0]+=.0466,F[1]-=.0123,_(e,F,t)}intersectIntersectorScreen(e,t,r){this.computeIntersection(this._getPickRay(e,this._tmpRay),t,r)}intersectToolIntersectorScreen(e,t,r){const i=this._getPickRay(e,this._tmpRay);this.intersectToolIntersectorRay(i,t,r)}intersectToolIntersectorRay(e,t,r){t.options.selectionMode=!0,this.computeIntersection(e,t,r);const i=t.results.min;!!this._view.basemapTerrain&&this._view.basemapTerrain.opaque||P(i)&&i.intersector!==w.TERRAIN||(t.options.selectionMode=!1,this.computeIntersection(e,t,r))}setTolerance(e=v){this._tolerance=e}addIntersectionHandler(e){this._externalIntersectionHandlers.push(e),this._externalIntersectionHandlers.sort(((e,t)=>e.type===w.TERRAIN?1:t.type===w.TERRAIN?-1:0))}removeIntersectionHandler(e){null!=this._externalIntersectionHandlers.removeUnordered(e)&&this._externalIntersectionHandlers.sort(((e,t)=>e.type===w.TERRAIN?1:t.type===w.TERRAIN?-1:0))}_getPickRay(e,t){const r=this._view.state.camera;return R(r,e,t)}_intersectRayFreePointLocal(t,r){return this.viewingMode!==f.Local||e(t)||o(r,t.origin,a(g.get(),t.direction)),!1}intersectElevationFromScreen(e,t,r=0,i=null){return this._intersectElevation(this._getPickRay(e,this._tmpRay),t,r,i)}_intersectElevation(i,s,a=0,c=null){if(e(i))return null;const l=t(s)?s.mode:"absolute-height",h=t(s)?r(s.offset,0):0,u="on-the-ground"!==l?h+a:0,d=u/this._view.renderCoordsHelper.unitInMeters;if("absolute-height"===l){if(this._view.renderCoordsHelper.intersectInfiniteManifold(i,u,A)){const e=this._view.computeMapPointFromVec3d(A);return e.z??(e.z=0),e.z-=h,e}return null}const p=this._view.state.camera,m=n(g.get());p.projectToRenderScreen(i.origin,m);const y=new T(null,this._forEachLayer),f=this._view.slicePlane,_=t(f)?M(f):null,R=I(this.viewingMode);R.options.store=b.MIN,R.options.verticalOffset=d;const v=i.origin,P=o(g.get(),v,i.direction);R.reset(v,P,p),R.point=m;const j=t(c)?"type"in c&&"graphics"===c.type?e=>e.metadata?.layerUid!==c.uid:e=>e.metadata?.graphicUid!==c.uid:null;switch(l){case"relative-to-scene":{const t=t=>(e(j)||j(t))&&!!t.metadata?.isElevationSource;R.intersect(y.layers,m,this._tolerance,null,t),this._externalIntersectionHandlers.forAll((e=>{if(e.type===w.I3S||e.type===w.TERRAIN){const t=e.slicePlaneEnabled?_:null;e.intersect(R,t,R.rayBegin,R.rayEnd,m)}}));break}case"on-the-ground":case"relative-to-ground":this._externalIntersectionHandlers.forAll((e=>{if(e.isGround){const t=e.slicePlaneEnabled?_:null;e.intersect(R,t,R.rayBegin,R.rayEnd,m)}}))}if(R.results.min.getIntersectionPoint(A)){const e=this._view.computeMapPointFromVec3d(A);return e.z=a,e}return null}computeIntersection(i,s,a){if(e(i))return;const c=this._view.state.camera,l=n(g.get());c.projectToRenderScreen(i.origin,l);const h=new T(a,this._forEachLayer);s.options.selectOpaqueTerrainOnly=!a||!("include"in a||"exclude"in a);const u=i.origin,d=o(g.get(),i.origin,i.direction);s.reset(u,d,c),s.intersect(h.layers,l,this._tolerance);const p=this._view.slicePlane,m=t(p)?M(p):null;s.intersect(h.sliceableLayers,l,this._tolerance,m);const y=a&&(a.requiresGroundFeedback||a.enableDraped);this._externalIntersectionHandlers.forAll((e=>{const t=e.layerUid,r=Array.isArray(t),i=r?t:[t];r&&(s.options.filteredLayerUids=[]);let n=!1;for(const o of i){!h.filterLayerUid(o)?r&&s.options.filteredLayerUids.push(o):n=!0}if(s.options.isFiltered=!n,e.isGround&&y||!s.options.isFiltered){const t=e.slicePlaneEnabled?m:null;e.intersect(s,t,u,d,l)}}));const f=g.get(),_=this._view.basemapTerrain;if(a&&a.enableDraped&&t(_.spatialReference)&&s.results.ground.getIntersectionPoint(f)){const e=_.overlayManager.renderer,t=this._view.renderCoordsHelper.spatialReference,i=g.get();this._view.renderCoordsHelper.fromRenderCoords(f,i,_.spatialReference),i[2]=r(this._view.elevationProvider?.getElevation(f[0],f[1],f[2],t,"ground"),0),e.intersect(s,i,s.results.ground,(e=>h.filterRenderGeometry(e)))}s.sortResults(),this._processHUDResults(s)}_processHUDResults(r){const i=r.results.hud;h(this._tmpRegion,u);const n=this._view.state.camera,s=[],o=this._tmpRegion,a=e=>{const t=new H(e);n.projectToRenderScreen(e.target.center,t.screenPoint),t.screenPoint[0]=Math.floor(t.screenPoint[0]),t.screenPoint[1]=Math.floor(t.screenPoint[1]),s.push(t),m(o,t.screenPoint)};r.sortResults(i.all),t(i.min.dist)&&a(i.min);for(const e of i.all)i.min.target.object!==e.target.object&&i.max.target.object!==e.target.object&&a(e);if(t(i.max.dist)&&i.max.target.object!==i.min.target.object&&a(i.max),!s.length)return;o[0]===o[2]&&(o[2]+=1),o[1]===o[3]&&(o[3]+=1);const c=n.fullWidth,l=n.fullHeight,y=Math.max(0,o[0]-x),g=Math.max(0,o[1]-x),f=Math.min(d(o)+2*x,c-y),_=Math.min(p(o)+2*x,l-g),R=new Uint8Array(f*_*4);this._view._stage.renderer.readHUDVisibility(y,g,f,_,R);let v=!0;const I=e(r.results.max.dist);let w=0;for(const e of s)for(const t of U){if(R[4*(Math.min(e.screenPoint[0]+t[0],c)-o[0]+(Math.min(e.screenPoint[1]+t[1],l)-o[1])*f)]){v&&(r.results.min.copy(e.result),v=!1),I&&r.results.max.copy(e.result),r.options.store===b.ALL&&r.results.all.splice(w++,0,e.result);break}}}}const x=1,U=(()=>{const e=[],t=x;for(let r=-t;r<=t;r++)for(let i=-t;i<=t;i++)e.push([i+t,r+t]);return e})();class H{constructor(e){this.result=e,this.screenPoint=s()}}let E;function L(e){return E&&E.viewingMode===e||(E=I(e)),E}class T{constructor(e,t){this.layers=new Array,this.sliceableLayers=new Array,this.include=e?.include,this.exclude=e?.exclude,t((e=>{e.pickable&&this.filterLayerUid(e.apiLayerUid)&&(e.sliceable?this.sliceableLayers:this.layers).push(e)}))}filterLayerUid(t){const{include:r,exclude:i}=this;return e(t)?null==r&&null==i:(null==r||r.has(t))&&(null==i||!i.has(t))}filterRenderGeometry(e){return this.filterLayerUid(e.layerUid)}}function k(e){return"object"==typeof e&&"intersect"in e}const A=c(),F=s();export{j as SceneIntersectionHelper,k as isIntersectionHandler};