UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 11.2 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import"../../../../core/has.js";import e from"../../../../core/Error.js";import{translate as t}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{IDENTITY as i,create as r}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{set as s,scale as a}from"../../../../core/libs/gl-matrix-2/math/vec2.js";import{fromValues as o,fromArray as n}from"../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{F as l,i as h}from"../../../../chunks/vec32.js";import{clone as c,ZEROS as m,fromArray as p,create as d}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{projectBuffer as f}from"../../../../geometry/projection/projectBuffer.js";import{create as u,fromSubBuffer as y,intersectsClippingArea as b}from"../../../../geometry/support/aaBoundingBox.js";import{newDoubleArray as g,doubleArrayFrom as _}from"../../../../geometry/support/DoubleArray.js";import{needsElevationUpdates3D as v,evaluateElevationAlignmentAtPoint as x,SampleElevationInfo as w}from"./elevationAlignmentUtils.js";import{Graphics3DObject3DGraphicLayer as P}from"./Graphics3DObject3DGraphicLayer.js";import{pathNumRoundJoinSubdivisions as j,pathNumRoundCapExtrusionSubdivisions as S}from"./Graphics3DPathSymbolLayerConstants.js";import{Graphics3DSymbolLayer as D}from"./Graphics3DSymbolLayer.js";import{isValidSize as C}from"./graphicUtils.js";import{ApplyRendererDiffResult as L}from"./interfaces.js";import{ConvertOptions as V,initFastSymbolUpdatesState as U,updateFastSymbolUpdatesState as A,getAttributeValue as E}from"../support/FastSymbolUpdates.js";import{SamplePosition as R}from"../../support/ElevationProvider.js";import{NormalType as z}from"../../webgl-engine/core/shaderLibrary/attributes/NormalAttribute.glsl.js";import{CullFaceOptions as k}from"../../webgl-engine/lib/basicInterfaces.js";import{Object3D as I}from"../../webgl-engine/lib/Object3D.js";import{Path as G}from"../../webgl-engine/lib/Path.js";import{PathBuilder as B}from"../../webgl-engine/lib/PathBuilder.js";import{RoundCapBuilder as M,TriangulationCapBuilder as O,NoCapBuilder as F}from"../../webgl-engine/lib/PathCapBuilder.js";import{SimpleExtruder as q,MiterExtruder as H}from"../../webgl-engine/lib/PathExtruder.js";import{UpVectorAlignment as N,PathGeometry as T,isPathGeometry as W}from"../../webgl-engine/lib/PathGeometry.js";import{FastUpdatePathGeometry as Z,StaticPathGeometry as J}from"../../webgl-engine/lib/PathGeometryData.js";import{computeMinimumRotationTangentFrame as K}from"../../webgl-engine/lib/pathGeometryUtils.js";import{quadProfiles as Q,circleProfiles as X}from"../../webgl-engine/lib/PathProfile.js";import{newPathVertex as Y}from"../../webgl-engine/lib/PathVertex.js";import{VertexAttribute as $}from"../../webgl-engine/lib/VertexAttribute.js";import{DefaultMaterial as ee}from"../../webgl-engine/materials/DefaultMaterial.js";import{PathMaterial as te}from"../../webgl-engine/materials/PathMaterial.js";const ie=["polyline"];class re extends D{get usedMemory(){return this._usedMemory+super.usedMemory}constructor(e,t,i,r){super(e,t,i,r),this._intrinsicSize=o(1,1),this._upVectorAlignment=N.Path,this._stencilWidth=.1,this._usedMemory=0,this.ensureDrapedStatus(!1)}async doLoad(){const t=null!=this.symbolLayer.width?this.symbolLayer.width:this.symbolLayer.height,i=null!=this.symbolLayer.height?this.symbolLayer.height:t;this._vvConvertOptions=new V({size:!0,color:!0,rotation:!1,opacity:!0},[1,1,1],[t,1,i],this._context.renderCoordsHelper.unitInMeters);const r=this._context.renderer?.visualVariables;this._fastUpdates=r?.length?U(this._context.renderer,this._vvConvertOptions):null;const o=this.symbolLayer.anchor||"center";this._upVectorAlignment="heading"===this.symbolLayer.profileRotation?N.World:N.Path;const h=this.symbolLayer.profile||"circle";switch(h){default:case"circle":this._profile=X[o];break;case"quad":this._profile=Q[o]}switch(this.symbolLayer.join){case"round":this._extruder=new H(0,j);break;case"bevel":this._extruder=new H(0,1);break;case"miter":this._extruder=new H(.8*Math.PI,1);break;default:this._extruder=new q}const d=this.symbolLayer.cap||"butt";switch(d){case"none":this._startCap=new F,this._endCap=new F;break;case"butt":default:this._startCap=new O(this._profile,0),this._endCap=new O(this._profile,0,!0);break;case"square":this._startCap=new O(this._profile,-.5),this._endCap=new O(this._profile,.5,!0);break;case"round":{const e="quad"===h;this._startCap=new M({profile:this._profile,flip:!1,breakNormals:e,subdivisions:S}),this._endCap=new M({profile:this._profile,flip:!0,breakNormals:e,subdivisions:S});break}}const f=this.symbolLayer?.material?.emissiveFactor,u=f?l(c(f)):m,y=this.symbolLayer?.material?.color,b=this._getCombinedOpacityAndColor(y),g=p(b),_=b[3],v=_<1||this.needsDrivenTransparentPass,x={diffuse:g,ambient:g,emissiveFactor:u,opacity:_,transparent:v,hasVertexColors:!1,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows,cullFace:v||"none"===d?k.None:k.Back,offsetTransparentBackfaces:!0};if(!this._drivenProperties.size&&(s(this._intrinsicSize,t,i),!C(this._intrinsicSize[0])||!C(this._intrinsicSize[1])))throw new e("graphics3dpathsymbollayer:invalid-size","Symbol sizes may not be negative values");if(this._fastUpdates?.visualVariables.size||a(this._intrinsicSize,this._intrinsicSize,1/this._context.renderCoordsHelper.unitInMeters),this._fastUpdates){const e={...x,...this._fastUpdates.materialParameters,size:n(this._intrinsicSize)};this._materials[0]=new te(e,this._context)}else x.hasVertexColors=this._drivenProperties.color||this._drivenProperties.opacity,x.normalType=z.Compressed,this._materials[0]=new ee(x,this._context);this._materials[0].setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0}),this._context.stage.add(this._materials[0])}destroy(){super.destroy(),this._context.stage.remove(this._materials[0]),this._materials.length=0}createGraphics3DGraphic(e){const t=e.graphic;if(!this._validateGeometry(t.geometry,ie,this.symbolLayer.type))return null;const i=this.setGraphicElevationContext(t),r=e.renderingInfo;return this._createAs3DShape(t,r,i,t.uid)}layerOpacityChanged(){const e=this.symbolLayer?.material?.color,t=this._getCombinedOpacity(e),i=t<1||this.needsDrivenTransparentPass;this._materials[0]?.setParameters({opacity:t,transparent:i})}layerElevationInfoChanged(e,t){return this.updateGraphics3DGraphicElevationInfo(e,t,v)}slicePlaneEnabledChanged(){return this._materials[0]?.setParameters({hasSlicePlane:this._context.slicePlaneEnabled}),!0}physicalBasedRenderingChanged(){return this._materials[0]?.setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0}),!0}applyRendererDiff(e,t){for(const i in e.diff){if("visualVariables"!==i)return L.RecreateSymbol;if(!A(this._fastUpdates,t,this._vvConvertOptions))return L.RecreateSymbol;this._materials[0]?.setParameters(this._fastUpdates.materialParameters)}return L.FastUpdate}_getVertexData(e){let t=0;const i=e.paths,r=[],s=e.spatialReference,a=this._context.elevationProvider.spatialReference,o=this._context.renderCoordsHelper.spatialReference;for(const c of i)t+=c.length;const n=g(3*t);let l,h=0;for(const c of i){r.push({offset:h,numVertices:c.length});for(const t of c)n[h++]=t[0],n[h++]=t[1],n[h++]=e.hasZ?t[2]:0}return null==a||s.equals(a)||f(n,s,0,n,a,0,t)?(null==a||a.equals(o)?l=_(n):(l=g(3*t),f(n,a,0,l,o,0,t)),{pathVertexDataInfos:r,vertexDataES:n,vertexDataRS:l}):null}_createAs3DShape(e,s,a,o){this._usedMemory=0;const n=e.geometry,l=this._getVertexData(n);if(null==l)return this.logger.warn("PathSymbol3DLayer geometry failed to be created (failed to project geometry to view spatial reference)"),null;if(0===l.pathVertexDataInfos.length)return 0!==n.paths.length&&n.paths.some((e=>e.length>0))||this.logger.warn("PathSymbol3DLayer geometry failed to be created (no paths were defined)"),null;const c=new Array,m=n.spatialReference,p=u(),d=this._context.renderCoordsHelper,f=new R(l.vertexDataES);for(const u of l.pathVertexDataInfos){const n=u.numVertices;if(n<2)continue;const g=u.offset;if(null!=this._context.clippingExtent&&(y(l.vertexDataES,g,n,p),!b(p,this._context.clippingExtent)))continue;const _=new Array,v=g+3*n;for(let e=g;e<v;e+=3){f.offset=e;const t=x(f,this._context.elevationProvider,a,d);h(le,l.vertexDataRS[e],l.vertexDataRS[e+1],l.vertexDataRS[e+2]),d.setAltitude(le,t),l.vertexDataRS[e]=le[0],l.vertexDataRS[e+1]=le[1],l.vertexDataRS[e+2]=le[2],_.push(Y(this._upVectorAlignment))}const w=new G(_,l.vertexDataES,l.vertexDataRS,g);se(w,this._upVectorAlignment,this._context.renderCoordsHelper);const P=new B(w,this._profile,this._extruder,this._startCap,this._endCap);let j=null;if(this._fastUpdates){const t=this._fastUpdates.visualVariables,i=E(t.size?.field,e)??0,r=E(t.color?.field,e)??0,s=E(t.opacity?.field,e)??0;j=new Z(P,i,r,s)}else{const e=[this._intrinsicSize[0],this._intrinsicSize[1]];if(this._drivenProperties.size){const t=s.size;e[0]*=ae(t[0],"symbol-value"===t[2]?this.symbolLayer.height||0:t[2],this.symbolLayer.width||0),e[1]*=ae(t[2],"symbol-value"===t[0]?this.symbolLayer.width||0:t[0],this.symbolLayer.height||0)}let t;this._drivenProperties.color&&(t=s.color),this._drivenProperties.opacity&&null!=s.opacity&&(t=t?[t[0],t[1],t[2],s.opacity]:[1,1,1,s.opacity]);const i=new J(P);i.bake(e),t&&i.bakeVertexColors(t),j=i}const S=j.createGeometryData(),D=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:o,layerUid:this._context.layer.uid}),C=new T(this._materials[0],S,j,m,this._stencilWidth,D);C.transformation=t(r(),i,P.path.origin),c.push(C),this._usedMemory+=P.usedMemory}if(0===c.length)return null;const g=new I({geometries:c,layerUid:this._context.layer.uid,graphicUid:o}),_=new P(this,g,c,null,null,((e,t,i,r,s)=>ne(e,t,r,s,this._upVectorAlignment)),a);return _.alignedSampledElevation=0,_.needsElevationUpdates=v(a.mode),_}}function se(e,t,i){const{origin:r,positions:s}=e;let a=e.offset;switch(t){default:case N.World:for(const t of e.vertices)le[0]=s[a++]+r[0],le[1]=s[a++]+r[1],le[2]=s[a++]+r[2],i.worldUpAtPosition(le,le),t.setFrameFromUpVector(le);break;case N.Path:le[0]=s[a]+r[0],le[1]=s[a+1]+r[1],le[2]=s[a+2]+r[2],i.worldUpAtPosition(le,le),K(e,le)}}function ae(e,t,i){switch(e){case"symbol-value":return i;case"proportional":return t;default:return e}}function oe(e,t,i,r){let s=0;const{origin:a,vertices:o,positions:n,positionsES:l}=e,c=e.offset+3*o.length;for(let m=e.offset;m<c;m+=3)h(le,l[m],l[m+1],l[m+2]),i(le,he),s+=he.sampledElevation,le[0]=n[m]+a[0],le[1]=n[m+1]+a[1],le[2]=n[m+2]+a[2],r.setAltitude(le,he.z),n[m]=le[0]-a[0],n[m+1]=le[1]-a[1],n[m+2]=le[2]-a[2];return e.updatePathVertexInformation(),s/o.length}function ne(e,t,i,r,s){const a=e.stageObject,o=a.geometries;let n=0;for(const l of o){if(!W(l))continue;const e=l.path,o=e.builder.path;n+=oe(o,t,i,r),s!==N.World&&se(o,s,r),e.onPathChanged(l),l.invalidateBoundingInfo(),a.geometryVertexAttributeUpdated(l,$.POSITION)}return n/o.length}const le=d(),he=new w;export{re as Graphics3DPathSymbolLayer};