UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 13.8 kB
import{cyclicalPI as t}from"../../../../../core/Cyclical.js";import e from"../../../../../core/Evented.js";import a from"../../../../../core/Handles.js";import{clamp as i,rad2deg as o}from"../../../../../core/mathUtils.js";import{isSome as s,destroyMaybe as n,unwrapOr as r,isNone as l}from"../../../../../core/maybe.js";import{createAngle as c,createLength as h}from"../../../../../core/quantityUtils.js";import{when as p,initial as d,watch as u}from"../../../../../core/reactiveUtils.js";import{addFrameTask as g}from"../../../../../core/scheduling.js";import{createScreenPointArray as m}from"../../../../../core/screenUtils.js";import{d as _,E as f,m as D,k as S,e as M}from"../../../../../chunks/mat4.js";import{c as v}from"../../../../../chunks/mat4f64.js";import{s as y,b,l as w,d as T,f as R,a as j}from"../../../../../chunks/vec3.js";import{a as O,f as I}from"../../../../../chunks/vec3f64.js";import{b as A}from"../../../../../chunks/vec4f64.js";import{fromPositionAndNormal as k,create as E,normal as F}from"../../../../../geometry/support/plane.js";import{wrap as P,distance2 as C}from"../../../../../geometry/support/ray.js";import{sv3d as U,sm4d as z}from"../../../../../geometry/support/vectorStacks.js";import{getGraphicEffectiveElevationInfo as L}from"../../../../../support/elevationInfoUtils.js";import{Manipulator3D as x}from"../../Manipulator3D.js";import{calculateInputRotationTransform as N}from"../../manipulatorUtils.js";import{RenderObject as H}from"../../RenderObject.js";import{screenToRenderPlane as V}from"../dragEventPipeline3D.js";import{ManipulatorType as q}from"../ManipulatorType.js";import{RING_INDICATOR_DELAY_MS as B,ROTATE_INDICATOR_DIRECTION_BUFFER as G,SCALE_INDICATOR_DIRECTION_BUFFER as J,ROTATE_INDICATOR_ARROW_PLACEMENT_PERCENTAGE as K,RING_THICKNESS as Q,HANDLE_COLOR as W,DRAG_THRESHOLD_PX as X,RING_RADIUS as Y,INNER_INDICATOR_RADIUS as Z,OUTER_INDICATOR_RADIUS as $,RING_HEIGHT as tt,ROTATE_INDICATOR_ARROW_TIP_RADIUS as et,ROTATE_INDICATOR_ARROW_TIP_LENGTH as at,SCALE_INDICATOR_OFFSET1 as it,SCALE_INDICATOR_OFFSET2 as ot,INDICATOR_THICKNESS as st,GEOMETRY_SEGMENTS as nt,ROTATE_INDICATOR_ARC_LENGTH as rt,RING_RESET_ANIMATION_SPEED_FACTOR as lt,SCALE_INDICATOR_ARC_LENGTH as ct}from"../manipulations/config.js";import{CullFaceOptions as ht}from"../../../webgl-engine/lib/basicInterfaces.js";import{createExtrudedTriangle as pt,transformInPlace as dt,createPathExtrusionGeometry as ut}from"../../../webgl-engine/lib/GeometryUtil.js";import{RenderOccludedFlag as gt}from"../../../webgl-engine/lib/Material.js";import{ColorMaterial as mt}from"../../../webgl-engine/materials/ColorMaterial.js";import{createManipulatorDragEventPipeline as _t}from"../../../../interactive/dragEventPipeline.js";import{ManipulatorStateCustomFlags as ft,ManipulatorStateFlags as Dt}from"../../../../interactive/interfaces.js";import{Tooltip as St}from"../../../../interactive/tooltip/Tooltip.js";import{TransformRotateTooltipInfo as Mt,TransformScaleTooltipInfo as vt,TransformAbsoluteTooltipInfo as yt}from"../../../../interactive/tooltip/TransformTooltipInfos.js";var bt,wt;!function(t){t.ScaleIn=ft.Custom2,t.ScaleOut=ft.Custom3,t.RotateLeft=ft.Custom4,t.RotateRight=ft.Custom5,t.Unlocked=ft.Custom7,t.DelayedFocused=ft.Custom8,t.TouchInput=ft.Custom12}(bt||(bt={}));class Tt{get angle(){return this._adapter.angle}get scale(){return this._adapter.scale}set location(t){this._ringManipulator.location=t}set elevationAlignedLocation(t){this._ringManipulator.elevationAlignedLocation=t}get grabbing(){return this._ringManipulator.grabbing}set interactive(t){this._ringManipulator.interactive=t}constructor({adapter:t,tooltipOptions:i,mode:o,tool:n}){this._mode=null,this._handles=new a,this._scaleRotateDragData=null,this._activeAnimation=null,this._ringIndicatorDelayMs=B,this.events=new e,this.getFocused=()=>this._ringManipulator.focused,this.getScale=()=>s(this._scaleRotateDragData)&&"scale"===this._scaleRotateDragData.mode?this._adapter.scale:1,this.tool=n,this._mode=o,this._adapter=t,this._tooltipOptions=i,this._tooltip=new St({view:n.view}),this._createManipulator(),this._updateDragState(),this._updateManipulatorTransform(),this._handles.add(p((()=>!this._tooltipOptions.enabled),(()=>this._tooltip.clear()),d))}destroy(){s(this._activeAnimation)&&(this._activeAnimation.frameTask.remove(),this._activeAnimation=null),this._handles=n(this._handles),this.tool.manipulators.remove(this._ringManipulator),this._ringManipulator=null,this._tooltip=n(this._tooltip)}startAnimation(t){this.cancelActiveAnimation(),t.start();const e=g({update:({deltaTime:e})=>{t.update(e)&&this.cancelActiveAnimation()}});this._activeAnimation={...t,frameTask:e}}cancelActiveAnimation(){s(this._activeAnimation)&&(this._activeAnimation.frameTask.remove(),this._activeAnimation=n(this._activeAnimation))}forEachManipulator(t){t(this._ringManipulator,q.SCALE_ROTATE)}_createManipulator(){const e=this._createRingManipulator();this._ringManipulator=e,this.tool.manipulators.add(e);const a=this.tool.graphicState.graphic,n=_t(e,((e,n,r)=>{this._scaleRotateDragData=null;const l=this._adapter.startInteraction(),c={mode:"none",origin:O(e.renderLocation),initialAngle:this._adapter.angle,angle:0,angleDir:0,scaleDir:0};this._scaleRotateDragData=c,this._updateDragState();const h=U.get();this.tool.view.renderCoordsHelper.worldUpAtPosition(e.renderLocation,h),n.next(V(this.tool.view,k(e.renderLocation,h,E()))).next((e=>{const n=F(e.plane),r=N(e.renderStart,e.renderEnd,c.origin,n),h=t.shortestSignedDiff(c.angle,r);c.angleDir=i(c.angleDir+h,-G,G),c.angle=r;const p=Rt(c,e),d=p-this._adapter.scale;if(c.scaleDir=i(c.scaleDir+d,-J,J),this._onScaleChanged(),"none"===c.mode){const t=this._mode||jt(e,e.plane,c.origin,this.tool.view.state.camera);if(s(t)){switch(t){case"rotate":this.tool.emit("graphic-rotate-start",{graphic:a,angle:0}),this.tool.emit("record-undo",{record:this._adapter.createUndoRecord()});break;case"scale":this.tool.emit("graphic-scale-start",{graphic:a,xScale:1,yScale:1}),this.tool.emit("record-undo",{record:this._adapter.createUndoRecord()})}c.mode=t}}switch(c.mode){case"rotate":l.state.angle=c.initialAngle+r;break;case"scale":l.state.scale=p,this._onScaleChanged()}switch(this._updateDragState(),this._updateManipulatorTransform(),e.action){case"start":case"update":switch(c.mode){case"rotate":this.tool.emit("graphic-rotate",{graphic:a,angle:o(c.angle)});break;case"scale":this.tool.emit("graphic-scale",{graphic:a,xScale:p,yScale:p})}break;case"end":switch(c.mode){case"rotate":this.tool.emit("graphic-rotate-stop",{graphic:a,angle:o(c.angle)});break;case"scale":this.tool.emit("graphic-scale-stop",{graphic:a,xScale:p,yScale:p})}}return"end"===e.action&&(this.startAnimation(It(this,(()=>this._onScaleChanged()))),this._scaleRotateDragData=null,this._updateDragState(),l.done()),e})).next(this._updateTooltipPipelineStep(c)),r.next((()=>{if(l.cancel(),s(this._scaleRotateDragData)){switch(this._scaleRotateDragData.mode){case"none":break;case"rotate":this.tool.emit("graphic-rotate-stop",{graphic:a,angle:0});break;case"scale":this.tool.emit("graphic-scale-stop",{graphic:a,xScale:1,yScale:1})}this.startAnimation(It(this,(()=>this._onScaleChanged()))),this._scaleRotateDragData=null,this._updateDragState()}this._updateFocusTooltip()}))}));this._handles.add([n,e.events.on("focus-changed",(t=>{"focus"===t.action?this.startAnimation(At(this,(()=>this._updateDelayedFocusedState()),{delayMs:this._ringIndicatorDelayMs})):this._updateDelayedFocusedState()})),e.events.on("immediate-click",(t=>{t.stopPropagation()})),u((()=>this.tool.graphicState?.displaying),(t=>this._ringManipulator.available=t),d)])}_updateTooltipPipelineStep(t){return e=>{const a=this._tooltipOptions;if(!a.enabled)return e;if("end"===e.action)return this._updateFocusTooltip(),e;const i=this._tooltip,o=this._tooltipOptions.visualVariables,n=s(o)?o.size:null,l=s(o)?o.rotation:null;switch(t.mode){case"scale":i.info=new vt({tooltipOptions:a,scale:{value:this._adapter.scale},size:h(r(this._adapter.size,-1),"meters"),sizeUnit:s(n)?n.unit:null,sizePrecision:s(n)?kt(n.valueType):null});break;case"rotate":{const t=s(l)?kt(l.valueType):null,e=s(l)?l.rotationType:"geographic";i.info=new Mt({tooltipOptions:a,rotation:c(r(-this._adapter.relativeAngle,0),"radians","geographic"),rotationPrecision:t,orientation:c(-this._adapter.angle,"radians","geographic"),orientationPrecision:t,rotationType:e})}}return e}}_updateFocusTooltip(){if(!this._tooltipOptions.enabled)return;if(this.getFocused()){const t=this._tooltipOptions.visualVariables,e=s(t)?t.rotation:null,a=s(t)?t.size:null;this._tooltip.info=new yt({tooltipOptions:this._tooltipOptions,orientation:c(-this._adapter.angle,"radians","geographic"),orientationEnabled:null==this._mode||"rotate"===this._mode,orientationPrecision:s(e)?kt(e.valueType):null,rotationType:s(e)?e.rotationType:"geographic",size:h(r(this._adapter.size,-1),"meters"),sizeUnit:s(a)?a.unit:null,sizeEnabled:null==this._mode||"scale"===this._mode,sizePrecision:s(a)?kt(a.valueType):null})}else this._tooltip.clear()}_onScaleChanged(){this.events.emit("scale-changed"),this._updateManipulatorTransform()}_updateDelayedFocusedState(){this._ringManipulator.updateStateEnabled(bt.DelayedFocused,this.getFocused()),this._updateFocusTooltip()}_updateDragState(){if(this._ringManipulator.updateStateEnabled(bt.Unlocked,!(s(this._scaleRotateDragData)&&"none"!==this._scaleRotateDragData.mode)),s(this._scaleRotateDragData))switch(this._scaleRotateDragData.mode){case"rotate":this._ringManipulator.updateStateEnabled(bt.ScaleIn|bt.ScaleOut,!1),this._ringManipulator.updateStateEnabled(bt.RotateLeft,this._scaleRotateDragData.angleDir<0),this._ringManipulator.updateStateEnabled(bt.RotateRight,this._scaleRotateDragData.angleDir>=0);break;case"scale":this._ringManipulator.updateStateEnabled(bt.RotateLeft|bt.RotateRight,!1),this._ringManipulator.updateStateEnabled(bt.ScaleIn,this._scaleRotateDragData.scaleDir<0),this._ringManipulator.updateStateEnabled(bt.ScaleOut,this._scaleRotateDragData.scaleDir>=0)}else this._ringManipulator.updateStateEnabled(bt.ScaleIn|bt.ScaleOut|bt.RotateLeft|bt.RotateRight,!1)}_updateManipulatorTransform(){const t=_(z.get(),this._adapter.angle,I(0,0,1));if(l(t))return;const e=this.getScale(),a=f(z.get(),y(U.get(),e,e,e));this._ringManipulator.modelTransform=D(z.get(),a,t)}_createRingManipulator(){const t=(t,e,a)=>{const i=[],o=Math.ceil(nt*(e-t)/(2*Math.PI));for(let s=0;s<o+1;s++){const n=t+s*(e-t)/o;i.push(I(a*Math.cos(n),a*Math.sin(n),0))}return i},e=e=>t(0,2*Math.PI,e),a=t=>[[-t/2,0],[t/2,0],[t/2,tt/2],[-t/2,tt/2]],i=this._createMaterial(1),o=(t,e,o=i)=>ut(o,a(e),t,[],[],!1),s=e(Y),n=o(s,Q),r={left:new Array,right:new Array},l=[];for(let R=0;R<2;R++){const e=R*Math.PI-Math.PI/4,a=Math.PI/2-rt,s=e+a,n=e+Math.PI/2-a,c=t(s,n,Z),h=o(c,st);l.push(c),l.push(t(s,n,$-Q/2)),r.left.push(h),r.right.push(h.instantiate());for(let t=0;t<2;t++){const e=0===t,a=v();if(e){S(a,a,[1,-1,1]),M(a,a,-s,[0,0,1]);const t=Math.round(K*(c.length-1));a[12]=c[t][0],a[13]=c[t][1],a[14]=c[t][2]}else{M(a,a,n,[0,0,1]);const t=Math.round((1-K)*(c.length-1));a[12]=c[t][0],a[13]=c[t][1],a[14]=c[t][2]}const o=pt(i,at,0,et,tt);dt(o,a),(e?r.left:r.right).push(o)}}const c=[];for(let S=0;S<2;S++){const e=S*Math.PI-Math.PI/4,a=Math.PI/2-ct,i=e+a,s=e+Math.PI/2-a,n=t(i,s,$);c.push(o(n,st))}const h=this._createMaterial(.66),p=this._createMaterial(.5),d=this._createMaterial(.33),u=e(Y+it),g=e(Y+ot),m=o(u,st,h),_=o(g,st,d),f=e(Y-it),D=e(Y-ot),y=o(f,st,h),b=o(D,st,d);let w=[new H(n,bt.DelayedFocused),new H(n.instantiate({material:p}),Dt.None)];this._mode&&"scale"!==this._mode||(w=w.concat([...c.map((t=>new H(t,bt.DelayedFocused|bt.Unlocked))),new H(m,bt.DelayedFocused|bt.ScaleIn),new H(_,bt.DelayedFocused|bt.ScaleIn),new H(y,bt.DelayedFocused|bt.ScaleOut),new H(b,bt.DelayedFocused|bt.ScaleOut)])),this._mode&&"rotate"!==this._mode||(w=w.concat([...r.right.map((t=>new H(t.instantiate(),bt.DelayedFocused|bt.Unlocked))),...r.left.map((t=>new H(t,bt.DelayedFocused|bt.RotateLeft))),...r.right.map((t=>new H(t,bt.DelayedFocused|bt.RotateRight)))]));const T=[s,...l];return new x({view:this.tool.view,renderObjects:w,autoScaleRenderObjects:!1,worldOriented:!0,radius:Q,focusMultiplier:1,touchMultiplier:1.5,elevationInfo:L(this.tool.graphicState.graphic),collisionType:{type:"ribbon",paths:T,direction:I(0,0,1)}})}_createMaterial(t){const e=A([...W,t]);return new mt({color:e,transparent:1!==t,cullFace:ht.Back,renderOccluded:gt.Transparent})}get test(){return{ringManipulator:this._ringManipulator,setRingIndicatorDelayMs:t=>this._ringIndicatorDelayMs=t,tooltip:this._tooltip}}}function Rt(t,e){const a=b(U.get(),e.renderStart,t.origin),i=b(U.get(),e.renderEnd,t.origin),o=w(a),s=w(i);return 0===o?0:s/o}function jt(t,e,a,i){const{renderStart:o,renderEnd:s}=t,n=Ot(o,i,U.get()),r=Ot(s,i,U.get());if(T(n,r)<X*X)return null;const l=b(U.get(),o,a),c=R(U.get(),l,F(e)),h=o,p=j(U.get(),h,c),d=Ot(a,i,U.get()),u=n,g=Ot(p,i,U.get()),m=b(U.get(),g,u),_=b(U.get(),n,d),f=P(u,m),D=P(d,_);return C(f,r)<C(D,r)?"rotate":"scale"}function Ot(t,e,a){return e.projectToScreen(t,Et),y(a,Et[0],Et[1],0)}function It(t,e){let a=null,i=1;const o=()=>i;return{start:()=>{i=t.getScale(),a=t.getScale,t.getScale=o,e()},update:t=>(i+=((i+1)/2-i)*Math.min(t*lt,1),e(),Math.abs(i-1)<.01?wt.STOP:wt.CONTINUE),destroy:()=>{a&&(t.getScale=a),e()}}}function At(t,e,a){let i=0,o=null;const s=()=>!1;return{start:()=>{o=t.getFocused,t.getFocused=s,i=0,e()},update:t=>(i+=t,!o?.()||i>=a.delayMs?wt.STOP:wt.CONTINUE),destroy:()=>{o&&(t.getFocused=o),e()}}}function kt(t){switch(t){case"integer":case"long":return 0;default:return null}}!function(t){t[t.CONTINUE=0]="CONTINUE",t[t.STOP=1]="STOP"}(wt||(wt={}));const Et=m();export{Tt as GraphicScaleRotateTransform};