@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 14.7 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{EventEmitter as e}from"../../../core/Evented.js";import{makeHandle as t}from"../../../core/handleUtils.js";import"../../../core/has.js";import{deg2rad as i}from"../../../core/mathUtils.js";import{destroyMaybe as s}from"../../../core/maybe.js";import{createRenderScreenPointArray3 as o,createScreenPointArray as r,screenPointObjectToArray as n,castRenderScreenPointArray as a}from"../../../core/screenUtils.js";import{fromMat4 as c}from"../../../core/libs/gl-matrix-2/math/mat3.js";import{create as l}from"../../../core/libs/gl-matrix-2/factories/mat3f64.js";import{copy as h,set as d,multiply as _,identity as u}from"../../../core/libs/gl-matrix-2/math/mat4.js";import{create as g}from"../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{squaredDistance as m}from"../../../core/libs/gl-matrix-2/math/vec2.js";import{add as f,transformMat3 as p,transformMat4 as b,scale as v,copy as y,squaredDistance as j,set as L,subtract as S}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{create as O,ZEROS as R}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{getReferenceEllipsoid as w}from"../../../geometry/ellipsoidUtils.js";import T from"../../../geometry/Point.js";import{canProjectWithoutEngine as A,projectPoint as E}from"../../../geometry/projectionUtils.js";import{computeENUToPCPFLocalRotation as D}from"../../../geometry/projection/localRotationUtils.js";import{sphericalPCPFtoLonLatElevation as F}from"../../../geometry/projection/projectors.js";import{containsPointObject as z}from"../../../geometry/support/aaBoundingRect.js";import{distance2 as P,fromPoints as x,closestRayDistance2 as C,create as M}from"../../../geometry/support/lineSegment.js";import{fromPositionAndNormal as k,intersectRay as I,create as U}from"../../../geometry/support/plane.js";import{create as W}from"../../../geometry/support/ray.js";import{sv3d as B}from"../../../geometry/support/vectorStacks.js";import{clonePoint as H,hydratedSpatialReference as q}from"../../../layers/graphics/hydratedFeatures.js";import{getElevationOffset as G}from"../../../support/elevationInfoUtils.js";import{getElevationAtPoint as V}from"../support/ElevationProvider.js";import{fromScreen as J}from"../support/geometryUtils/ray.js";import K from"../webgl/RenderCamera.js";import{Object3D as N}from"../webgl-engine/lib/Object3D.js";import{WebGLLayer as Q}from"../webgl-engine/lib/WebGLLayer.js";class X{constructor(t){this.metadata=void 0,this._camera=new K,this._elevation={offset:0,override:null},this.collisionType={type:"point"},this.collisionPriority=0,this._renderObjects=new Array,this.autoScaleRenderObjects=!0,this._available=!0,this._noDisplayCount=0,this._radius=10,this._worldSized=!1,this.focusMultiplier=2,this.touchMultiplier=2.5,this.worldOriented=!1,this._modelTransform=g(),this._worldFrame=null,this._renderLocation=O(),this._renderLocationDirty=!0,this._location=new T({x:0,y:0,z:0}),this._elevationAlignedLocation=new T,this._elevationAlignedLocationDirty=!0,this.interactive=!0,this.selectable=!1,this.grabbable=!0,this.consumesClicks=!0,this.cursor=null,this.grabCursor=null,this._grabbing=!1,this.dragging=!1,this._hovering=!1,this._selected=!1,this._state=0,this._focused=!1,this.events=new e,this._screenLocation={screenPointArray:r(),renderScreenPointArray:o(),pixelSize:0},this._screenLocationDirty=!0,this._engineResourcesAddedToStage=!1,this._attached=!1,this._location.spatialReference=t.view.spatialReference,Object.assign(this,t);const i=this.view.state?.camera;i&&this._camera.copyFrom(i)}destroy(){this._applyObjectTransform=ue,this._removeResourcesFromStage(),this._engineResources=null,this.view=null,this._camera=null}get _stage(){return this.view?.stage}get elevationInfo(){return this._elevationInfo}set elevationInfo(e){this._elevationInfo=e,this._elevationAlignedLocationDirty=!0,this._renderLocationDirty=!0,this._updateEngineObject()}get renderObjects(){return this._renderObjects}set renderObjects(e){this._removeResourcesFromStage(),this._engineResources=null,this._renderObjects=e.slice(),this._updateEngineObject()}set available(e){e!==this._available&&(this._available=e,this._updateEngineObject())}get available(){return this._available}disableDisplay(){return this._noDisplayCount++,1===this._noDisplayCount&&this._updateEngineObject(),t(()=>{this._noDisplayCount--,0===this._noDisplayCount&&this._updateEngineObject()})}set radius(e){e!==this._radius&&(this._radius=e,this._updateEngineObject())}get radius(){return this._radius}set worldSized(e){e!==this._worldSized&&(this._worldSized=e,this._updateEngineObject())}get worldSized(){return this._worldSized}get modelTransform(){return this._modelTransform}set modelTransform(e){Y(e)&&(this._screenLocationDirty=!0),h(this._modelTransform,e),this._updateEngineObject()}get renderLocation(){return this._renderLocationDirty&&(this._renderLocationDirty=!1,this.view.renderCoordsHelper.toRenderCoords(this.elevationAlignedLocation,this._renderLocation),this.worldOriented?(this._worldFrame||(this._worldFrame=g()),Z(this.view,this._renderLocation,this._worldFrame)):this._worldFrame&&(this._worldFrame=null)),this._renderLocation}set renderLocation(e){this.view.renderCoordsHelper.fromRenderCoords(e,this._location),this.elevationAlignedLocation=this._location}get location(){return this._location}set location(e){H(e,this._location),this._notifyLocationChanged()}_notifyLocationChanged(){this._renderLocationDirty=!0,this._screenLocationDirty=!0,this._elevationAlignedLocationDirty=!0,this._updateEngineObject(),this.events.emit("location-update",{location:this._location})}get elevationAlignedLocation(){return this._elevationAlignedLocationDirty?(this._evaluateElevationAlignment(),this._updateElevationAlignedLocation(),this._elevationAlignedLocation):this._elevationAlignedLocation}set elevationAlignedLocation(e){H(e,this._location),this._evaluateElevationAlignment(),this._location.z-=this._elevation.offset,this._updateElevationAlignedLocation(),this._updateEngineObject(),this.events.emit("location-update",{location:this._location})}_updateElevationAlignedLocation(){const e=null!=this._elevation.override?this._elevation.override:this.location.z||0;this._elevationAlignedLocation.x=this.location.x,this._elevationAlignedLocation.y=this.location.y,this._elevationAlignedLocation.z=e+this._elevation.offset,this._elevationAlignedLocation.spatialReference=q(this.location.spatialReference),this._renderLocationDirty=!0,this._screenLocationDirty=!0,this._elevationAlignedLocationDirty=!1}grabbableForEvent(){return!0}get grabbing(){return this._grabbing}set grabbing(e){e!==this._grabbing&&(this._grabbing=e,this._setFocused(this._hovering||this._grabbing),this._updateEngineObject())}get hovering(){return this._hovering}set hovering(e){e!==this._hovering&&(this._hovering=e,this._setFocused(this._hovering||this._grabbing),this._updateEngineObject())}get selected(){return this._selected}set selected(e){e!==this._selected&&(this._selected=e,this._updateEngineObject(),this.events.emit("select-changed",{action:e?"select":"deselect"}))}get state(){return this._state}set state(e){e!==this._state&&(this._state=e,this._updateEngineObject())}updateStateEnabled(e,t){t?this.state|=e:this.state&=~e}_setFocused(e){e!==this._focused&&(this._focused=e,this.events.emit("focus-changed",{action:!0===e?"focus":"unfocus"}))}get focused(){return this._focused}get screenLocation(){return this._ensureScreenLocation(),this._screenLocation}_ensureScreenLocation(){if(!this._screenLocationDirty)return;this._screenLocation.pixelSize=this._camera.computeScreenPixelSizeAt(this.renderLocation),this._screenLocationDirty=!1;let e;if(Y(this._modelTransform)){const t=this._calculateModelTransformOffset(de);e=f(t,t,this.renderLocation)}else e=this.renderLocation;this._camera.projectToRenderScreen(e,this._screenLocation.renderScreenPointArray),this._camera.renderToScreen(this._screenLocation.renderScreenPointArray,this._screenLocation.screenPointArray)}get applyObjectTransform(){return this._applyObjectTransform}set applyObjectTransform(e){this._applyObjectTransform=e,this._screenLocationDirty=!0,this._updateEngineObject()}get attached(){return this._attached}intersectionDistance(e,t){if(!this.available)return null;const i=n(e,$),s=this._getCollisionRadius(t),o=-1*this.collisionPriority;switch(this.collisionType.type){case"point":if(m(this.screenLocation.screenPointArray,i)<s*s)return this.screenLocation.renderScreenPointArray[2]+o;break;case"line":{const e=this.collisionType.paths,t=this._getWorldToScreenObjectScale(),r=this._calculateObjectTransform(t,oe),n=s*this.screenLocation.pixelSize,c=J(this._camera,i,te);if(null==c)return null;for(const i of e){if(0===i.length)continue;const e=b(ne,i[0],r);for(let t=1;t<i.length;t++){const s=b(ae,i[t],r),l=C(x(e,s,ee),c);if(null!=l&&l<n*n){const t=f(B.get(),e,s);v(t,t,.5);const i=a(B.get());if(this._camera.projectToRenderScreen(t,i))return i[2]+o}y(e,s)}}break}case"disc":{const e=this.collisionType.direction,t=this.collisionType.offset??R,r=this._getWorldToScreenObjectScale(),n=this._calculateObjectTransform(r,oe),a=s*this.screenLocation.pixelSize,l=J(this._camera,i,te);if(null==l)return null;const h=c(ie,n),d=p(le,e,h),_=b(he,t,n);k(_,d,re);const u=ce;if(I(re,l,u)&&j(u,_)<a*a)return this.screenLocation.renderScreenPointArray[2]+o;break}case"ribbon":{const{paths:e,direction:t}=this.collisionType,r=this._getWorldToScreenObjectScale(),n=this._calculateObjectTransform(r,oe),l=s*this._camera.computeScreenPixelSizeAt(this.renderLocation),h=J(this._camera,i,te);if(null==h)return null;const d=c(ie,n),_=p(le,t,d),u=this._calculateModelTransformPosition(he);k(u,_,re);const g=ce;if(!I(re,h,g))break;for(const i of e){if(0===i.length)continue;const e=b(ne,i[0],n);for(let t=1;t<i.length;t++){const s=b(ae,i[t],n),r=P(x(e,s,ee),g);if(null!=r&&r<l*l){const t=f(B.get(),e,s);v(t,t,.5);const i=a(B.get());if(this._camera.projectToRenderScreen(t,i))return i[2]+o}y(e,s)}}break}default:this.collisionType}return null}attach(e={manipulator3D:{}}){const t=this._stage;if(!t)return;const i=e.manipulator3D;null==i.engineLayerId?(this._engineLayer=new Q(t,{pickable:!1,updatePolicy:1}),i.engineLayerId=this._engineLayer.id):t?.getLayer&&(this._engineLayer=t.getLayer(i.engineLayerId)),i.engineLayerReferences=(i.engineLayerReferences||0)+1,this._camera.copyFrom(this.view.state.camera),this._attached=!0,this._updateEngineObject(),A(this._location.spatialReference,this.view.spatialReference)||(this.location=new T({x:0,y:0,z:0,spatialReference:this.view.spatialReference}))}detach(e={manipulator3D:{}}){const t=e.manipulator3D;t.engineLayerReferences--;const i=0===t.engineLayerReferences;this._removeResourcesFromStage(),i&&(t.engineLayerId=null,s(this._engineLayer)),this._engineResources=null,this._engineLayer=null,this._attached=!1}onViewChange(){this._camera.copyFrom(this.view.state.camera),this._screenLocationDirty=!0,this._updateEngineObject()}onElevationChange(e){E(this.location,_e,e.spatialReference)&&z(e.extent,_e)&&this._notifyLocationChanged()}_evaluateElevationAlignment(){if(null==this.elevationInfo)return;let e=null,t=0;const i=G(this.elevationInfo,this.location.spatialReference??this.view.elevationProvider.spatialReference);switch(this.elevationInfo.mode){case"on-the-ground":e=V(this.view.elevationProvider,this.location,"ground")??0;break;case"relative-to-ground":t=(V(this.view.elevationProvider,this.location,"ground")??0)+i;break;case"relative-to-scene":t=(V(this.view.elevationProvider,this.location,"scene")??0)+i;break;case"absolute-height":t=i}return t!==this._elevation.offset||e!==this._elevation.override?(this._elevation.offset=t,void(this._elevation.override=e)):void 0}_updateEngineObject(){if(!this._attached)return;if(!this.available)return void this._removeResourcesFromStage();const e=this._getWorldToScreenObjectScale(),t=oe;if(!0===this.autoScaleRenderObjects){const i=this._getFocusedSize(this._radius,this.focused)*e;this._calculateObjectTransform(i,t)}else this._calculateObjectTransform(e,t);const{objectsByState:i}=this._ensureEngineResources(),s=(this.focused?2:1)|(this.selected?8:4),o=this._noDisplayCount>0;for(const{stateMask:r,objects:n}of i){if(o){for(const e of n)e.visible=!1;continue}const e=!!!(15&r)||(s&r)===(15&r),i=!!!(65520&r)||(this.state&r)===(65520&r);if(e&&i)for(const s of n)s.visible=!0,s.transformation=t;else for(const t of n)t.visible=!1}}_ensureEngineResources(){if(null==this._engineResources){const e=this._engineLayer,t=[],i=new Set;this.renderObjects.forEach(({geometry:{material:e}})=>{i.has(e)||(t.push(e),i.add(e))});const s=new Map;this._renderObjects.forEach(e=>{const t=new N({castShadow:!1,geometries:[e.geometry]}),i=s.get(e.stateMask)||[];i.push(t),s.set(e.stateMask,i)});const o=[];s.forEach((e,t)=>o.push({stateMask:t,objects:e})),this._engineResources={objectsByState:o,layer:e,materials:t}}return this._addResourcesToStage(),this._engineResources}_addResourcesToStage(){const e=this._stage;if(this._engineResourcesAddedToStage||null==this._engineResources||!e)return;const{objectsByState:t,layer:i}=this._engineResources;t.forEach(({objects:e})=>i.addMany(e)),this._engineResourcesAddedToStage=!0}_removeResourcesFromStage(){const e=this._stage;if(!this._engineResourcesAddedToStage||null==this._engineResources||!e)return;const{objectsByState:t,layer:i}=this._engineResources;t.forEach(({objects:e})=>i.removeMany(e)),this._engineResourcesAddedToStage=!1}_getCollisionRadius(e){return this._getFocusedSize(this.radius,!0)*("touch"===e?this.touchMultiplier:1)}_getFocusedSize(e,t){return e*(t?this.focusMultiplier:1)}_getWorldToScreenObjectScale(){return this._worldSized?1:this.screenLocation.pixelSize}_calculateModelTransformPosition(e){const t=this._getWorldToScreenObjectScale(),i=this._calculateObjectTransform(t,se);return L(e,i[12],i[13],i[14])}_calculateModelTransformOffset(e){const t=this._calculateModelTransformPosition(e);return S(e,t,this.renderLocation)}_calculateObjectTransform(e,t){return d(t,e,0,0,0,0,e,0,0,0,0,e,0,0,0,0,1),this._worldFrame&&_(t,t,this._worldFrame),_(t,t,this._modelTransform),t[12]+=this.renderLocation[0],t[13]+=this.renderLocation[1],t[14]+=this.renderLocation[2],t[15]=1,null!=this._applyObjectTransform&&this._applyObjectTransform(t),t}get test(){}}function Y(e){return 0!==e[12]||0!==e[13]||0!==e[14]}function Z(e,t,s){switch(e.viewingMode){case"local":return u(s),!0;case"global":{const o=w(e.renderCoordsHelper.spatialReference);return F(t,0,ne,0,o.radius),D(i(ne[0]),i(ne[1]),s),!0}}}const $=r(),ee=M(),te=W(),ie=l(),se=g(),oe=g(),re=U(),ne=O(),ae=O(),ce=O(),le=O(),he=O(),de=O(),_e=new T({x:0,y:0,z:0,spatialReference:null}),ue=()=>{};export{X as Manipulator3D};