UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 10.9 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import e from"../../../../core/Error.js";import{translate as t}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{IDENTITY as r,create as i}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,clone as l}from"../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{set as h}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{fromArray as c,create as p}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{projectBuffer as m}from"../../../../geometry/projection/projectBuffer.js";import{create as f,fromSubBuffer as d,intersectsClippingArea as u}from"../../../../geometry/support/aaBoundingBox.js";import{newDoubleArray as g,doubleArrayFrom as _}from"../../../../geometry/support/DoubleArray.js";import{newFloatArray as b}from"../../../../geometry/support/FloatArray.js";import{needsElevationUpdates3D as y,evaluateElevationAlignmentAtPoint as v,SampleElevationInfo as w}from"./elevationAlignmentUtils.js";import{Graphics3DObject3DGraphicLayer as x}from"./Graphics3DObject3DGraphicLayer.js";import{pathNumRoundJoinSubdivisions as S,pathNumRoundCapExtrusionSubdivisions as C}from"./Graphics3DPathSymbolLayerConstants.js";import{Graphics3DSymbolLayer as P,nanFallbackColor as D}from"./Graphics3DSymbolLayer.js";import{isValidSize as j}from"./graphicUtils.js";import{ConvertOptions as V,initFastSymbolUpdatesState as U,updateFastSymbolUpdatesState as z,getSizeAttributeValue as A,getAttributeValue as E}from"../support/FastSymbolUpdates.js";import{SamplePosition as R}from"../../support/ElevationProvider.js";import{Object3D as k}from"../../webgl-engine/lib/Object3D.js";import{Path as L}from"../../webgl-engine/lib/Path.js";import{PathBuilder as G}from"../../webgl-engine/lib/PathBuilder.js";import{RoundCapBuilder as O,TriangulationCapBuilder as I,NoCapBuilder as B}from"../../webgl-engine/lib/PathCapBuilder.js";import{SimpleExtruder as F,MiterExtruder as M}from"../../webgl-engine/lib/PathExtruder.js";import{PathGeometry as T,isPathGeometry as q}from"../../webgl-engine/lib/PathGeometry.js";import{FastUpdatePathGeometry as H,StaticPathGeometry as N}from"../../webgl-engine/lib/PathGeometryData.js";import{computeMinimumRotationTangentFrame as W}from"../../webgl-engine/lib/pathGeometryUtils.js";import{quadProfiles as Z,circleProfiles as J}from"../../webgl-engine/lib/PathProfile.js";import{newPathVertex as K}from"../../webgl-engine/lib/PathVertex.js";import{DefaultMaterial as Q}from"../../webgl-engine/materials/DefaultMaterial.js";import{PathMaterial as X}from"../../webgl-engine/materials/PathMaterial.js";const Y=["polyline"];class $ extends P{constructor(e,t,r,i){super(e,t,r,i,se(t)),this._intrinsicSize=o(1,1),this._upVectorAlignment=1,this._stencilWidth=.1,this.ensureDrapedStatus(!1)}async doLoad(){const t=this.symbolLayer,r=null!=t.width?t.width:t.height,i=null!=t.height?t.height:r;this._vvConvertOptions=new V({supports:{size:!0,color:!0,rotation:!1,opacity:!0},modelSize:[1,1,1],symbolSize:[r,1,i],unitInMeters:this._context.renderCoordsHelper.unitInMeters,fallbackColor:this._getFallbackOpacityAndColor(D),fallbackSize:[r,1,i]});const o=this._context.renderer?.visualVariables;this._fastUpdates=o?.length?U(this._context.renderer,this._vvConvertOptions):null;const l=t.anchor||"center";this._upVectorAlignment="heading"===t.profileRotation?0:1;const h=t.profile||"circle";switch(h){default:case"circle":this._profile=J[l];break;case"quad":this._profile=Z[l]}switch(t.join){case"round":this._extruder=new M(0,S);break;case"bevel":this._extruder=new M(0,1);break;case"miter":this._extruder=new M(.8*Math.PI,1);break;default:this._extruder=new F}switch(this._cap){case"none":this._startCap=new B,this._endCap=new B;break;case"butt":default:this._startCap=new I(this._profile,0),this._endCap=new I(this._profile,0,!0);break;case"square":this._startCap=new I(this._profile,-.5),this._endCap=new I(this._profile,.5,!0);break;case"round":{const e="quad"===h;this._startCap=new O({profile:this._profile,flip:!1,breakNormals:e,subdivisions:C}),this._endCap=new O({profile:this._profile,flip:!0,breakNormals:e,subdivisions:C});break}}const p=this._materialColor,m=this._getCombinedOpacityAndColor(p),f=c(m),d=m[3],u=this.needsDrivenTransparentPass,g=t.material?.emissive,_={diffuse:f,ambient:f,emissiveStrengthFromSymbol:("color"===g?.source?g?.strength:void 0)??0,emissiveSource:1,opacity:d,drivenOpacity:u,hasVertexColors:!1,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows,offsetTransparentBackfaces:!0};if(!this._drivenProperties.size&&(s(this._intrinsicSize,r,i),!j(this._intrinsicSize[0])||!j(this._intrinsicSize[1])))throw new e("graphics3dpathsymbollayer:invalid-size","Symbol sizes may not be negative values");let b;this._fastUpdates?.visualVariables.size||a(this._intrinsicSize,this._intrinsicSize,1/this._context.renderCoordsHelper.unitInMeters),this._fastUpdates?b=new X({..._,...this._fastUpdates.materialParameters,size:n(this._intrinsicSize)},this._context):(_.hasVertexColors=this._drivenProperties.color||this._drivenProperties.opacity,_.normalType=1,b=new Q(_,this._context)),b.setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0}),this._materials[0]=b,this._updateTransparentDepedentMaterialParameters()}createGraphics3DGraphic(e){const t=e.graphic;if(!this._validateGeometry(t.geometry,Y,this.symbolLayer.type))return null;const r=this.createElevationContextForGraphic(t);return this._createAs3DShape(e,r)}layerOpacityChanged(){const e=this._materialColor,t=this._getCombinedOpacity(e),r=this._materials[0];r&&(r.setParameters({opacity:t}),this._updateTransparentDepedentMaterialParameters())}layerScreenSizePerspectiveChanged(){}layerElevationInfoChanged(e,t){return this.updateGraphics3DGraphicElevationInfo(e,t,y)}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 r in e.diff){if("visualVariables"!==r)return 0;if(!z(this._fastUpdates,t,this._vvConvertOptions))return 0;this._materials[0]?.setParameters(this._fastUpdates.materialParameters)}return 2}_getVertexData(e){let t=0;const r=e.paths,i=[],s=e.spatialReference,a=this._context.elevationProvider.spatialReference,o=this._context.renderCoordsHelper.spatialReference;for(const c of r)t+=c.length;const n=g(3*t);let l,h=0;for(const c of r){i.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)||m(n,s,0,n,a,0,t)?(null==a||a.equals(o)?l=_(n):(l=g(3*t),m(n,a,0,l,o,0,t)),{pathVertexDataInfos:i,vertexDataES:n,vertexDataRS:l}):null}_createAs3DShape(e,s){const{graphic:a,renderingInfo:o}=e,n=a.geometry,c=this._getVertexData(n);if(null==c)return this.logger.warn("PathSymbol3DLayer geometry failed to be created (failed to project geometry to view spatial reference)"),null;if(0===c.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 p=new Array,m=n.spatialReference,g=f(),_=this._context.renderCoordsHelper,w=new R(c.vertexDataES),S=a.uid,C=b(c.vertexDataRS.length);for(const f of c.pathVertexDataInfos){const e=f.numVertices;if(e<2)continue;const a=f.offset;if(null!=this._context.clippingExtent&&(d(c.vertexDataES,a,e,g),!u(g,this._context.clippingExtent)))continue;const n=new Array,b=a+3*e;for(let t=a;t<b;t+=3){w.offset=t;const e=v(w,this._context.elevationProvider,s,_);h(ae,c.vertexDataRS[t],c.vertexDataRS[t+1],c.vertexDataRS[t+2]),_.setAltitude(ae,e),c.vertexDataRS[t]=ae[0],c.vertexDataRS[t+1]=ae[1],c.vertexDataRS[t+2]=ae[2],n.push(K(this._upVectorAlignment))}const y=new L(n,c.vertexDataES,c.vertexDataRS,a,C);ee(y,this._upVectorAlignment,this._context.renderCoordsHelper);const x=new G(y,this._profile,this._extruder,this._startCap,this._endCap);let P=null;if(this._fastUpdates){const{size:e,color:t,opacity:r}=this._fastUpdates.visualVariables,i=A(e,o.size),s=E(t,o.color),a=E(r,o.opacity);P=new H(x,i,s,a)}else{const e=l(this._intrinsicSize);if(this._drivenProperties.size){const t=o.size?.output??["symbol-value","symbol-value","symbol-value"];e[0]*=te(t[0],"symbol-value"===t[2]?this.symbolLayer.height||0:t[2],this.symbolLayer.width||0),e[1]*=te(t[2],"symbol-value"===t[0]?this.symbolLayer.width||0:t[0],this.symbolLayer.height||0)}const t=new N(x);t.bake(e);const r=this._getDrivenColor(o);r&&t.bakeVertexColors(r),P=t}const D=P.createGeometryData(),j=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:S,layerViewUid:this._context.layerViewUid}),V=new T(this._materials[0],D,P,m,this._stencilWidth,j);V.transformation=t(i(),r,x.path.origin),p.push(V)}if(0===p.length)return null;const P=new k({geometries:p,layerViewUid:this._context.layerViewUid,graphicUid:S}),D=new x(this,P,null,(e,t,r,i,s)=>ie(e,t,i,s,this._upVectorAlignment),s,null);return D.alignedSampledElevation=0,D.needsElevationUpdates=y(s.mode),D}_getDrivenColor(e){return this._hasDrivenColorOrOpacity?this._getDrivenUInt8ColorWithNaNSupport(e,this._materialColor,!1):null}get _materialColor(){return this.symbolLayer.material?.color}_getFallbackOpacityAndColor(e){return this._materialColor?.toUnitRGBA()??e}get _cap(){return this.symbolLayer.cap||"butt"}_updateTransparentDepedentMaterialParameters(){const e=this._materials[0];e&&e.setParameters({cullFace:e.transparent||"none"===this._cap?0:2})}}function ee(e,t,r){const{origin:i,positions:s}=e;let a=e.offset;switch(t){default:case 0:for(const t of e.vertices)ae[0]=s[a++]+i[0],ae[1]=s[a++]+i[1],ae[2]=s[a++]+i[2],r.worldUpAtPosition(ae,ae),t.setFrameFromUpVector(ae);break;case 1:ae[0]=s[a]+i[0],ae[1]=s[a+1]+i[1],ae[2]=s[a+2]+i[2],r.worldUpAtPosition(ae,ae),W(e,ae)}}function te(e,t,r){switch(e){case"symbol-value":return r;case"proportional":return t;default:return e}}function re(e,t,r,i){let s=0;const{origin:a,vertices:o,positions:n,positionsES:l}=e,c=e.offset+3*o.length;for(let p=e.offset;p<c;p+=3)h(ae,l[p],l[p+1],l[p+2]),r(ae,oe),s+=oe.sampledElevation,ae[0]=n[p]+a[0],ae[1]=n[p+1]+a[1],ae[2]=n[p+2]+a[2],i.setAltitude(ae,oe.z),n[p]=ae[0]-a[0],n[p+1]=ae[1]-a[1],n[p+2]=ae[2]-a[2];return e.updatePathVertexInformation(),s/o.length}function ie(e,t,r,i,s){const a=e.stageObject,o=a.geometries;let n=0;for(const l of o){if(!q(l))continue;const e=l.path,o=e.builder.path;n+=re(o,t,r,i),0!==s&&ee(o,s,i),e.onPathChanged(l),l.invalidateBoundingInfo(),a.geometryVertexAttributeUpdated(l,"position")}return n/o.length}function se(e){return 1===(e.material?.color?.a??0)}const ae=p(),oe=new w;export{$ as Graphics3DPathSymbolLayer};