UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 12 kB
import"../../../../core/has.js";import t from"../../../../core/Error.js";import{acosClamped as e,reciprocalClamped as i}from"../../../../core/mathUtils.js";import{isSome as r,get as s}from"../../../../core/maybe.js";import{s as a}from"../../../../chunks/mat2.js";import{s as o,b as n}from"../../../../chunks/vec2.js";import{f as l,b as h}from"../../../../chunks/vec2f64.js";import{s as c,c as p,a as m,e as f,f as d,g as u,n as g,o as y,b as _}from"../../../../chunks/vec3.js";import{d as b,c as v}from"../../../../chunks/vec3f64.js";import{projectBuffer as x}from"../../../../geometry/projection.js";import{create as w,empty as S,expandWithBuffer as P,intersectsClippingArea as R}from"../../../../geometry/support/aaBoundingBox.js";import{makeDehydratedPoint as j}from"../../../../layers/graphics/dehydratedFeatures.js";import{needsElevationUpdates3D as C,evaluateElevationAlignmentAtPoint as D,SampleElevationInfo as U}from"./elevationAlignmentUtils.js";import{ElevationContext as L}from"./ElevationContext.js";import{Graphics3DObject3DGraphicLayer as A}from"./Graphics3DObject3DGraphicLayer.js";import{PATH_NUM_CIRCLE_PROFILE_SUBDIVISIONS as V,PATH_NUM_ROUND_JOIN_SUBDIVISIONS as E,PATH_NUM_ROUND_CAP_EXTRUSION_SUBDIVISIONS as z}from"./Graphics3DPathSymbolLayerConstants.js";import{Graphics3DSymbolLayer as M,getAttributeValue as k}from"./Graphics3DSymbolLayer.js";import{isValidSize as I}from"./graphicUtils.js";import{ApplyRendererDiffResult as F}from"./interfaces.js";import{initFastSymbolUpdatesState as G,updateFastSymbolUpdatesState as B}from"../support/FastSymbolUpdates.js";import{CullFaceOptions as O}from"../../webgl-engine/lib/basicInterfaces.js";import{newDoubleArray as H}from"../../webgl-engine/lib/DoubleArray.js";import{Object3D as q}from"../../webgl-engine/lib/Object3D.js";import{UpVectorAlignment as W,PathGeometry as T,isPathGeometry as N}from"../../webgl-engine/lib/PathGeometry.js";import{creatQuadProfile as Z,createCircleProfile as J,SimpleExtruder as K,MiterExtruder as Q,RoundCapBuilder as X,TriangulationCapBuilder as Y,NoCapBuilder as $,PathVertex as tt,Path as et,Builder as it,FastUpdatePathGeometry as rt,StaticPathGeometry as st,computeMinimumRotationTangentFrame as at,vertexSpaceToProfileSpace as ot}from"../../webgl-engine/lib/pathGeometryUtils.js";import{DefaultMaterial as nt}from"../../webgl-engine/materials/DefaultMaterial.js";import{PathMaterial as lt}from"../../webgl-engine/materials/PathMaterial.js";const ht=["polyline"];class ct extends M{constructor(t,e,i,r){super(t,e,i,r),this._intrinsicSize=l(1,1),this._upVectorAlignment=W.Path,this._stencilWidth=.1,this.ensureDrapedStatus(!1)}async doLoad(){const e=r(this.symbolLayer.width)?this.symbolLayer.width:this.symbolLayer.height,i=r(this.symbolLayer.height)?this.symbolLayer.height:e;this._vvConvertOptions={modelSize:[1,1,1],symbolSize:[e,1,i],unitInMeters:this._context.renderCoordsHelper.unitInMeters,transformation:{anchor:[0,0,0],scale:[1,1,1],rotation:[0,0,0]},supportedTypes:{size:!0,color:!0,opacity:!0,rotation:!1}},this._context.renderer&&this._context.renderer.visualVariables&&this._context.renderer.visualVariables.length>0?this._fastUpdates=G(this._context.renderer,this._vvConvertOptions):this._fastUpdates={enabled:!1};const a=this.symbolLayer.anchor||"center";this._upVectorAlignment="heading"===this.symbolLayer.profileRotation?W.World:W.Path;const l=this.symbolLayer.profile||"circle";switch(l){default:case"circle":this._profile=J(V);break;case"quad":this._profile=Z()}let c=[0,0];switch("center"!==a&&(c={left:[.5,0],right:[-.5,0],top:[0,-.5],bottom:[0,.5]}[a],this._profile.translate(c[0],c[1])),this.symbolLayer.join){case"round":this._extruder=new Q(0,E);break;case"bevel":this._extruder=new Q(0,1);break;case"miter":this._extruder=new Q(.8*Math.PI,1);break;default:this._extruder=new K}const p=this.symbolLayer.cap||"butt";switch(p){case"none":this._startCap=new $,this._endCap=new $;break;case"butt":default:this._startCap=new Y(this._profile,0),this._endCap=new Y(this._profile,0,!0);break;case"square":this._startCap=new Y(this._profile,-.5),this._endCap=new Y(this._profile,.5,!0);break;case"round":{const t="quad"===l;this._startCap=new X({profile:this._profile,flip:!1,breakNormals:t,subdivisions:z}),this._endCap=new X({profile:this._profile,flip:!0,breakNormals:t,subdivisions:z});break}}const m=s(this.symbolLayer,"material","color"),f=this._getCombinedOpacityAndColor(m),d=b(f),u=f[3],g=u<1||this.needsDrivenTransparentPass,y={diffuse:d,ambient:d,opacity:u,transparent:g,hasVertexColors:!1,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows,cullFace:g||"none"===p?O.None:O.Back,offsetTransparentBackfaces:!0};if(!this._drivenProperties.size&&(o(this._intrinsicSize,e,i),!I(this._intrinsicSize[0])||!I(this._intrinsicSize[1])))throw new t("graphics3dpathsymbollayer:invalid-size","Symbol sizes may not be negative values");if(this._fastUpdates.enabled&&this._fastUpdates.visualVariables.size||n(this._intrinsicSize,this._intrinsicSize,1/this._context.renderCoordsHelper.unitInMeters),this._fastUpdates.enabled){const t={...y,...this._fastUpdates.materialParameters,size:h(this._intrinsicSize)};this._material=new lt(t)}else y.hasVertexColors=this._drivenProperties.color||this._drivenProperties.opacity,this._material=new nt(y);this._material.setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0}),this._context.stage.add(this._material)}destroy(){super.destroy(),this._context.stage.remove(this._material),this._material=null}createGraphics3DGraphic(t){const e=t.graphic;if(!this._validateGeometry(e.geometry,ht,this.symbolLayer.type))return null;const i=this.setGraphicElevationContext(e,new L),r=t.renderingInfo;return this._createAs3DShape(e,r,i,e.uid)}layerOpacityChanged(){const t=s(this.symbolLayer,"material","color"),e=this._getCombinedOpacity(t),i=e<1||this.needsDrivenTransparentPass;this._material.setParameters({opacity:e,transparent:i})}layerElevationInfoChanged(t,e){return this.updateGraphics3DGraphicElevationInfo(t,e,C)}slicePlaneEnabledChanged(){return this._material.setParameters({hasSlicePlane:this._context.slicePlaneEnabled}),!0}physicalBasedRenderingChanged(){return this._material.setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0}),!0}pixelRatioChanged(){return!0}skipHighSymbolLodsChanged(){return!0}applyRendererDiff(t,e){for(const i in t.diff){if("visualVariables"!==i)return F.Recreate_Symbol;if(!B(this._fastUpdates,e,this._vvConvertOptions))return F.Recreate_Symbol;this._material.setParameters(this._fastUpdates.materialParameters)}return F.Fast_Update}_getVertexData(t){let e=0;const i=t.paths,s=[],a=t.spatialReference,o=this._context.elevationProvider.spatialReference,n=this._context.renderCoordsHelper.spatialReference;for(const r of i)e+=r.length;const l=H(3*e),h=H(3*e);let c=0;for(const r of i){s.push({index:c,numVertices:r.length});for(const e of r)l[c++]=e[0],l[c++]=e[1],l[c++]=t.hasZ?e[2]:0}let p=!0;return r(o)&&!a.equals(o)&&(p=x(l,a,0,l,o,0,e)),r(o)&&!o.equals(n)?x(l,o,0,h,n,0,e):this._copyVertices(l,0,h,0,e),{pathVertexDataInfos:s,vertexDataES:l,vertexDataRS:h,projectionSuccess:p,terrainElevation:0}}_copyVertices(t,e,i,r,s){e*=3,r*=3;for(let a=0;a<s;++a)i[r++]=t[e++],i[r++]=t[e++],i[r++]=t[e++]}_createAs3DShape(t,e,i,s){const a=t.geometry,o=new Array,n=a.spatialReference,l=w(),h=this._context.renderCoordsHelper;gt.spatialReference=n;const m=this._getVertexData(a);if(!m.projectionSuccess)return this.logger.warn("PathSymbol3DLayer geometry failed to be created (failed to project geometry to view spatial reference)"),null;if(0===m.pathVertexDataInfos.length)return 0!==a.paths.length&&a.paths.some((t=>t.length>0))||this.logger.warn("PathSymbol3DLayer geometry failed to be created (no paths were defined)"),null;for(const g of m.pathVertexDataInfos){const a=g.index,f=g.numVertices;if(f<2)continue;if(r(this._context.clippingExtent)&&(S(l),P(l,m.vertexDataES,3*a,f),!R(l,this._context.clippingExtent)))continue;const d=[];for(let t=a;t<a+3*f;){const e=t++,r=t++,s=t++,a=new tt;c(a.posES,m.vertexDataES[e],m.vertexDataES[r],m.vertexDataES[s]);const o=D(a.posES,this._context.elevationProvider,i,h);c(yt,m.vertexDataRS[e],m.vertexDataRS[r],m.vertexDataRS[s]),h.setAltitude(yt,o),p(a.pos,yt),d.push(a)}const u=new et(d);pt(u,this._upVectorAlignment,this._context.renderCoordsHelper);const y=new it(u,this._profile,this._extruder,this._startCap,this._endCap);let _=null;if(this._fastUpdates.enabled){const e=this._fastUpdates.visualVariables,i=e.size?k(e.size.field,t):0,r=e.color?k(e.color.field,t):0,s=e.opacity?k(e.opacity.field,t):0;_=new rt(y,i,r,s)}else{const t=[this._intrinsicSize[0],this._intrinsicSize[1]];if(this._drivenProperties.size){const i=e.size;t[0]*=mt(i[0],"symbol-value"===i[2]?this.symbolLayer.height||0:i[2],this.symbolLayer.width||0),t[1]*=mt(i[2],"symbol-value"===i[0]?this.symbolLayer.width||0:i[0],this.symbolLayer.height||0)}let i;this._drivenProperties.color&&(i=e.color),this._drivenProperties.opacity&&null!=e.opacity&&(i=i?[i[0],i[1],i[2],e.opacity]:[1,1,1,e.opacity]);const r=new st(y);r.bake(t),i&&r.bakeVertexColors(i),_=r}const{vertexAttributes:b,indices:v}=_.createGeometryData(),x=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:s,layerUid:this._context.layer.uid}),w=new T(this._material,b,v,_,n,this._upVectorAlignment,this._stencilWidth,x);w.transformation=_.xform,o.push(w)}if(0===o.length)return null;const f={layerUid:this._context.layer.uid,graphicUid:s},d=new q({geometries:o,metadata:f}),u=new A(this,d,o,null,null,dt,i);return u.alignedSampledElevation=m.terrainElevation,u.needsElevationUpdates=C(i.mode),u}}function pt(t,r,s){switch(r){default:case W.World:for(const r of t.vertices){m(yt,r.pos,t.offset),s.worldUpAtPosition(yt,yt),r.setFrameFromUpVector(yt),r.rotationFrameUp=r.frame.up,o(r.rotationRight,1,0),u(yt,r.frame.up,f(r.frame.up,r.vLeft)),_(yt,r.vLeft,yt),y(yt,yt),g(yt,yt),u(_t,r.frame.up,f(r.frame.up,r.vRight)),_(_t,r.vRight,_t),g(_t,_t),d(bt,r.rotationFrameUp,r.vLeft);const n=Math.sign(f(bt,r.vRight));if(r.rotationAngle=n*(Math.PI-e(f(yt,_t))),Math.abs(r.rotationAngle)>0){const t=i(Math.cos(.5*r.rotationAngle));a(r.miterStretch,t-1+1,0,0,1)}const l=Math.PI-r.rotationAngle;r.maxStretchDistance=Math.abs(r.vMinSiblingLength/Math.cos(.5*l))}break;case W.Path:m(yt,t.vertices[0].pos,t.offset),s.worldUpAtPosition(yt,yt),at(t,yt);for(const r of t.vertices){const t=Math.sign(f(r.frame.right,r.vRight));d(r.rotationFrameUp,r.vRight,r.vLeft),u(r.rotationFrameUp,r.rotationFrameUp,t),g(r.rotationFrameUp,r.rotationFrameUp);const s=f(r.rotationFrameUp,r.frame.up),o=f(r.rotationFrameUp,r.frame.right);if(u(yt,r.frame.up,-o),u(_t,r.frame.right,s),m(yt,yt,_t),g(yt,yt),ot(r.rotationRight,r.frame,yt),y(yt,r.vLeft),r.rotationAngle=-t*(Math.PI-e(f(yt,r.vRight))),Math.abs(r.rotationAngle)>0){const t=i(Math.cos(.5*r.rotationAngle));a(r.miterStretch,1+(t-1)*r.rotationRight[0]*r.rotationRight[0],(t-1)*r.rotationRight[0]*r.rotationRight[1],(t-1)*r.rotationRight[0]*r.rotationRight[1],1+(t-1)*r.rotationRight[1]*r.rotationRight[1])}const n=Math.PI-r.rotationAngle;r.maxStretchDistance=Math.abs(r.vMinSiblingLength*i(Math.cos(.5*n)))}}}function mt(t,e,i){switch(t){case"symbol-value":return i;case"proportional":return e;default:return t}}function ft(t,e,i,r){let s=0;for(const a of t.vertices)i(a.posES,vt),s+=vt.sampledElevation,m(yt,a.pos,t.offset),r.setAltitude(yt,vt.z),_(a.pos,yt,t.offset);return t.updatePathVertexInformation(),s/t.vertices.length}function dt(t,e,i,r,s){const a=t.stageObject,o=a.geometries;let n=0;ut.spatialReference=s.spatialReference;for(const l of o){if(!N(l))continue;const t=l.path,i=t.builder.path,o=l.geometrySR;gt.spatialReference=o,n+=ft(i,e,r,s),l.upVectorAlignment!==W.World&&pt(i,l.upVectorAlignment,s),t.onPathChanged(),l.invalidateBoundingInfo(),a.geometryVertexAttrsUpdated(l)}return n/o.length}const ut=j(0,0,0,null),gt=j(0,0,0,null),yt=v(),_t=v(),bt=v(),vt=new U;export{ct as Graphics3DPathSymbolLayer};