UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) 8.8 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.33/esri/copyright.txt for details. */ import"../../../../core/has.js";import e from"../../../../core/PooledArray.js";import{createRenderScreenPointArray3 as t,castRenderScreenPointArray3 as r}from"../../../../core/screenUtils.js";import{getMetersPerVerticalUnitForSR as i}from"../../../../core/unitUtils.js";import{f as n,n as s,e as o}from"../../../../chunks/vec32.js";import{create as l}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{create as a,copy as c,negativeInfinity as u,width as h,height as p,expandPointInPlace as d}from"../../../../geometry/support/aaBoundingRect.js";import{create as m}from"../../../../geometry/support/ray.js";import{sv3d as f}from"../../../../geometry/support/vectorStacks.js";import{getElevationOffsetInMeters as g}from"../../../../support/elevationInfoUtils.js";import{ViewingMode as y}from"../../../ViewingMode.js";import{computeMapPointFromVec3d as R}from"../../support/hitTest.js";import{fromRenderAtEye as _,fromScreen as w}from"../../support/geometryUtils/ray.js";import{defaultTolerance as b,Intersector as I}from"../../webgl-engine/lib/Intersector.js";import{StoreResults as v}from"../../webgl-engine/lib/IntersectorInterfaces.js";import{isValidIntersectorResult as j}from"../../webgl-engine/lib/IntersectorResult.js";import{IntersectorType as P}from"../../webgl-engine/lib/IntersectorType.js";import{sliceFilterPredicate as M}from"../../webgl-engine/lib/intersectorUtils.js";import{HUDMaterial as U}from"../../webgl-engine/materials/HUDMaterial.js";class x{constructor(t,r,i){this.viewingMode=t,this._forEachLayer=r,this._view=i,this._externalIntersectionHandlers=new e,this._tolerance=b,this._tmpRay=m(),this._tmpRegion=a(),this._validateHUDIntersector=new I(this.viewingMode),this._validateHUDIntersector.options.hud=!1}intersectScreen(e,t,r){return this.intersectRay(this._getPickRay(e,this._tmpRay),A(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,A(this.viewingMode),t,r)||this._intersectRayFreePointLocal(e,t)}intersectRay(e,t,r,i){return t.options.selectionMode=!1,t.options.store=v.MIN,this.computeIntersection(e,t,!1,i),!!t.results.min&&t.results.min.getIntersectionPoint(r)}getCenterRayWithSubpixelOffset(e,t,r=.5,i=.5){return e.getRenderCenter(D,r,i),D[0]+=.0466,D[1]-=.0123,_(e,D,t)}intersectIntersectorScreen(e,t,r){this.computeIntersection(this._getPickRay(e,this._tmpRay),t,!1,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,!1,r);const i=t.results.min;!!this._view.basemapTerrain&&this._view.basemapTerrain.opaque||j(i)&&i.intersector!==P.TERRAIN||(t.options.selectionMode=!1,this.computeIntersection(e,t,!1,r))}setTolerance(e=b){this._tolerance=e}addIntersectionHandler(e){this._externalIntersectionHandlers.push(e),this._externalIntersectionHandlers.sort(((e,t)=>e.type===P.TERRAIN?1:t.type===P.TERRAIN?-1:0))}removeIntersectionHandler(e){null!=this._externalIntersectionHandlers.removeUnordered(e)&&this._externalIntersectionHandlers.sort(((e,t)=>e.type===P.TERRAIN?1:t.type===P.TERRAIN?-1:0))}_getPickRay(e,t){const r=this._view.state.camera;return w(r,e,t)}_intersectRayFreePointLocal(e,t){return this.viewingMode!==y.Local||null==e||n(t,e.origin,s(f.get(),e.direction)),!1}intersectElevationFromScreen(e,t,r=0,i=null){return this._intersectElevation(this._getPickRay(e,this._tmpRay),t,r,i)}_intersectElevation(e,t,l=0,a=null){if(null==e)return null;const c=this._view,{renderCoordsHelper:u}=c,h=i(c.spatialReference),p=null!=t?t.mode:"absolute-height",d=g(t)/h,m=("on-the-ground"!==p?d+l:0)*h/u.unitInMeters,{camera:y}=c.state;if("absolute-height"===p){const t=u?.getAltitude(y.eye),r=o(s(F,e.direction),u.worldUpAtPosition(y.eye,S));if(t<m&&r<0||t>=m&&r>0)return null;if(u.intersectInfiniteManifold(e,m,F)){const e=R(c,F);return e.z??=0,e.z-=d,e}return null}const _=r(f.get());y.projectToRenderScreen(e.origin,_);const w=new k(null,this._forEachLayer),{slice:{plane:b}}=c,j=null!=b?M(b):null,U=new I(this.viewingMode);U.options.store=v.MIN,U.options.verticalOffset=m,U.options.normalRequired=!1;const x=e.origin,T=n(f.get(),x,e.direction);U.reset(x,T,y),U.point=_;let E=null;if(a&&"type"in a&&"graphics"===a.type){const e=c.allLayerViews.find((e=>e.layer===a))?.uid;E=e?t=>t.layerViewUid===e:null}else a&&(E=e=>e.graphicUid!==a.uid);switch(p){case"relative-to-scene":{const e=e=>(!E||E(e))&&!!e.lastValidElevationBB;U.intersect(w.layers,_,this._tolerance,null,e),this._externalIntersectionHandlers.forAll((e=>{if(e.type===P.I3S||e.type===P.TERRAIN||e.type===P.TILES3D){const t=e.slicePlaneEnabled?j:null;e.intersect(U,t,U.rayBegin,U.rayEnd,_,!1)}}));break}case"on-the-ground":case"relative-to-ground":this._externalIntersectionHandlers.forAll((e=>{if(e.isGround){const t=e.slicePlaneEnabled?j:null;e.intersect(U,t,U.rayBegin,U.rayEnd,_,!1)}}))}if(U.results.min.getIntersectionPoint(F)){const e=R(c,F);return e.z=l,e}return null}computeIntersection(e,t,i,s){if(null==e)return;const o=this._view.state.camera,l=r(f.get());o.projectToRenderScreen(e.origin,l);const a=new k(s,this._forEachLayer);t.options.selectOpaqueTerrainOnly=!s||!("include"in s||"exclude"in s);const c=e.origin,u=n(f.get(),e.origin,e.direction);t.reset(c,u,o),t.intersect(a.layers,l,this._tolerance);const h=this._view.slice.plane,p=null!=h?M(h):null;t.intersect(a.sliceableLayers,l,this._tolerance,p);const d=s&&(s.requiresGroundFeedback||s.enableDraped);this._externalIntersectionHandlers.forAll((e=>{const r=e.layerViewUid,n=Array.isArray(r),s=n?r:[r];n&&(t.options.filteredLayerViewUids=[]);let o=!1;for(const i of s){!a.filterLayerViewUid(i)?n&&t.options.filteredLayerViewUids.push(i):o=!0}if(t.options.isFiltered=!o,e.isGround&&d||!t.options.isFiltered){const r=e.slicePlaneEnabled?p:null;e.intersect(t,r,c,u,l,i)}}));const m=f.get(),g=this._view.basemapTerrain;if(s&&s.enableDraped&&null!=g.spatialReference&&t.results.ground.getIntersectionPoint(m)){const e=g.overlayManager.renderer,r=this._view.renderCoordsHelper.spatialReference,i=f.get();this._view.renderCoordsHelper.fromRenderCoords(m,i,g.spatialReference),i[2]=this._view.elevationProvider?.getElevation(m[0],m[1],m[2],r,"ground")??0,e.intersect(t,i,t.results.ground,(e=>a.filterRenderGeometry(e)))}t.sortResults(),this._processHUDResults(t)}_processHUDResults(e){const t=e.results.hud;c(this._tmpRegion,u);const r=this._view.state.camera,i=[],n=this._tmpRegion,s=e=>{const t=new H(e),s=t.result.target.object.geometries.every((e=>e.material instanceof U&&e.material.parameters.occlusionTest));i.push({item:t,occlusionTest:s}),s&&(r.projectToRenderScreen(e.target.center,t.screenPoint),t.screenPoint[0]=Math.floor(t.screenPoint[0]),t.screenPoint[1]=Math.floor(t.screenPoint[1]),d(n,t.screenPoint))};e.sortResults(t.all),null!=t.min.distance&&s(t.min);for(const c of t.all)t.min.target.object!==c.target.object&&t.max.target.object!==c.target.object&&s(c);if(null!=t.max.distance&&t.max.target.object!==t.min.target.object&&s(t.max),!i.length)return;n[0]===n[2]&&(n[2]+=1),n[1]===n[3]&&(n[3]+=1);const o=r.fullWidth,l=r.fullHeight,a=Math.max(0,n[0]-T),m=Math.max(0,n[1]-T),f=Math.min(h(n)+2*T,o-a),g=Math.min(p(n)+2*T,l-m),y=f>0&&g>0?new Uint8Array(f*g*4):null;y&&this._view.stage.renderer.readHUDVisibility(a,m,f,g,y);let R=!0;const _=null==e.results.max.distance;let w=0;for(const{item:c,occlusionTest:u}of i){let t=!u;if(u&&y)for(const e of E){const r=4*(Math.min(c.screenPoint[0]+e[0],o)-n[0]+(Math.min(c.screenPoint[1]+e[1],l)-n[1])*f);if(r>=0&&r<y.length&&y[r]){t=!0;break}}t&&(R&&(e.results.min.copy(c.result),R=!1),_&&e.results.max.copy(c.result),e.options.store===v.ALL&&e.results.all.splice(w++,0,c.result))}}}const T=1,E=(()=>{const e=[],t=T;for(let r=-1;r<=t;r++)for(let i=-1;i<=t;i++)e.push([i+t,r+t]);return e})();class H{constructor(e){this.result=e,this.screenPoint=t()}}let L;function A(e){return L&&L.viewingMode===e||(L=new I(e)),L}class k{constructor(e,t){this.layers=new Array,this.sliceableLayers=new Array,this.include=e?.include,this.exclude=e?.exclude,t((e=>{e.pickable&&this.filterLayerViewUid(e.apiLayerViewUid)&&(e.sliceable?this.sliceableLayers:this.layers).push(e)}))}filterLayerViewUid(e){const{include:t,exclude:r}=this;return null==e?null==t&&null==r:(null==t||t.has(e))&&(null==r||!r.has(e))}filterRenderGeometry(e){return this.filterLayerViewUid(e.layerViewUid)}}function V(e){return"object"==typeof e&&"intersect"in e}const F=l(),S=l(),D=t();export{x as SceneIntersectionHelper,V as isIntersectionHandler};