@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 11.3 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import e from"../../../../core/Error.js";import{px2pt as t,pt2px as r}from"../../../../core/screenUtils.js";import{fromValues as i,clone as a}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import s from"../../../../geometry/Extent.js";import n from"../../../../geometry/Polygon.js";import{create as o,fromBuffer as l,intersectsClippingArea as h,empty as m,expandWithAABB as p,expandWithBuffer as c}from"../../../../geometry/support/aaBoundingBox.js";import{getDriverAxisSizeValueAny as d}from"../../../../renderers/support/renderingInfoUtils.js";import{sharedGeometryElevationAligner as y}from"./ElevationAligners.js";import{SymbolUpdateType as u,elevationModeChangeUpdateType as _,needsElevationUpdates2D as g}from"./elevationAlignmentUtils.js";import{Graphics3DDrapedGraphicLayer as f}from"./Graphics3DDrapedGraphicLayer.js";import{Graphics3DObject3DGraphicLayer as b}from"./Graphics3DObject3DGraphicLayer.js";import{Graphics3DSymbolLayer as M}from"./Graphics3DSymbolLayer.js";import{ApplyRendererDiffResult as L}from"./interfaces.js";import{parseCapType as E,parseLineMarkerStyle as P}from"./lineUtils.js";import{initFastSymbolUpdatesState as v,updateFastSymbolUpdatesState as C,getAttributeValue as R,ConvertOptions as w}from"../support/FastSymbolUpdates.js";import{debugFlags as x}from"../../support/debugFlags.js";import{createGeometry as D}from"../../support/engineContent/line.js";import{geometryToRenderInfo as k,geometryToRenderInfoDraped as j}from"../../support/renderInfoUtils/line.js";import{Object3D as S}from"../../webgl-engine/lib/Object3D.js";import{RenderGeometry as A}from"../../webgl-engine/lib/RenderGeometry.js";import{LineMarkerMaterial as U}from"../../webgl-engine/materials/LineMarkerMaterial.js";import{getStipplePatternForLinePattern as z}from"../../webgl-engine/materials/lineStippleUtils.js";import{RibbonLineMaterial as W}from"../../webgl-engine/materials/RibbonLineMaterial.js";const G=["polyline","polygon","extent"],O=new w({size:!0,color:!0,rotation:!1,opacity:!0});class V extends M{constructor(e,t,r,i){super(e,t,r,i)}async doLoad(){if(this._fastUpdates=v(this._context.renderer,O),!this._drivenProperties.size){if((null!=this.symbolLayer.size?this.symbolLayer.size:t(1))<0)throw new e("graphics3dlinesymbollayer:invalid-size","Symbol sizes may not be negative values")}}_getMaterialParameters(e,t=!1){const r=this._getCombinedOpacityAndColor(t&&this._markerColor||this._materialColor);this._patternHidesLine&&!t&&(r[3]=0);const i={width:this._computeMaterialWidth(this.symbolLayer?.size),color:r,hasPolygonOffset:!0,join:this.symbolLayer.join||"miter",cap:E(this.symbolLayer.cap||"butt"),hasSlicePlane:this._context.slicePlaneEnabled,isClosed:e,stipplePattern:z(this.symbolLayer.pattern)};return this._fastUpdates?.visualVariables?{...i,...this._fastUpdates.materialParameters}:i}get _materialColor(){return this.symbolLayer.material?.color}get _markerColor(){return this.symbolLayer.marker?.color}get _lineMaterial(){return null==this._materials[H.Line]&&(this._materials[H.Line]=new W(this._getMaterialParameters(!1)),this._context.stage.add(this._materials[H.Line])),this._materials[H.Line]}get _ringMaterial(){return null==this._materials[H.Ring]&&(this._materials[H.Ring]=new W(this._getMaterialParameters(!0)),this._context.stage.add(this._materials[H.Ring])),this._materials[H.Ring]}get _wireframeLineMaterial(){return null==this._materials[H.LineWireframe]&&(this._materials[H.LineWireframe]=new W({...this._getMaterialParameters(!1),wireframe:!0}),this._context.stage.add(this._materials[H.LineWireframe])),this._materials[H.LineWireframe]}get _wireframeRingMaterial(){return null==this._materials[H.RingWireframe]&&(this._materials[H.RingWireframe]=new W({...this._getMaterialParameters(!0),wireframe:!0}),this._context.stage.add(this._materials[H.RingWireframe])),this._materials[H.RingWireframe]}get _markerMaterial(){return null==this._materials[H.Marker]&&null!=this.symbolLayer.marker&&(this._materials[H.Marker]=new U({...this._getMaterialParameters(!1,!0),placement:this.symbolLayer.marker.placement,markerPrimitive:P(this.symbolLayer.marker.style)}),this._context.stage.add(this._materials[H.Marker])),this._materials[H.Marker]}destroy(){super.destroy(),this._forEachMaterial((e=>this._context.stage.remove(e))),this._materials.length=0}_getDrivenSize(e){return this._drivenProperties.size&&e.size?r(d(e.size)):1}_getDrivenColor(e){const t=i(1,1,1,1);return this._drivenProperties.color&&e.color&&(t[0]=e.color[0],t[1]=e.color[1],t[2]=e.color[2],e.color.length>0&&(t[3]=e.color[3])),this._drivenProperties.opacity&&e.opacity&&(t[3]=e.opacity),t}createGraphics3DGraphic(e){const t=e.graphic;if(!this._validateGeometry(t.geometry,G,this.symbolLayer.type))return null;const r=this.setGraphicElevationContext(t);return this.ensureDrapedStatus("on-the-ground"===r.mode),this.draped?this._createAsOverlay(e,this._context.layer.uid):this._createAs3DShape(e,r,t.uid)}applyRendererDiff(e,t){for(const r in e.diff){if("visualVariables"!==r)return L.RecreateSymbol;{const e=this._fastUpdates;if(!C(e,t,O))return L.RecreateSymbol;this._forEachMaterial((t=>t?.setParameters(e.materialParameters)))}}return L.FastUpdate}prepareSymbolLayerPatch(e){if("partial"!==e.diff.type)return;const t=e.diff.diff,r={};"complete"===t.size?.type&&(r.width=this._computeMaterialWidth(t.size.newValue),delete t.size),"complete"===t.cap?.type&&(r.cap=E(t.cap.newValue??"butt"),delete t.cap);const i=this._prepareMarkerPatch(e,t);this._prepareMaterialPatch(e,t,i),e.symbolLayerStatePatches.push((()=>this._forEachMaterial((e=>e?.setParameters(r)))))}layerOpacityChanged(){this._forEachMaterial(((e,t)=>this._updateMaterialLayerOpacity(e,t===H.Marker)))}_forEachMaterial(e){this._materials.forEach(e)}_updateMaterialLayerOpacity(e,t=!1){if(null==e)return;const r=e.parameters.color,a=this.symbolLayer?.material?.color,s=this._patternHidesLine&&!t?0:this._getCombinedOpacity(a),n=i(r[0],r[1],r[2],s);e.setParameters({color:n})}layerElevationInfoChanged(e,t,r){const i=this._elevationContext.mode,a=_(V.elevationModeChangeTypes,r,i);if(a!==u.UPDATE)return a;const s=g(i);return this.updateGraphics3DGraphicElevationInfo(e,t,(()=>s))}slicePlaneEnabledChanged(){const e={hasSlicePlane:this._context.slicePlaneEnabled};return this._forEachMaterial((t=>t?.setParameters(e))),!0}physicalBasedRenderingChanged(){return!0}_createAs3DShape(e,t,r){const i=I(e.graphic.geometry),a="polygon"===i.type?i.rings:i.paths,s=new Array,n=o(),m=k(i,this._context.elevationProvider,this._context.renderCoordsHelper,t),p="polygon"===i.type?"rings":"paths";this._logGeometryCreationWarnings(m,a,p,"LineSymbol3DLayer");for(let o=0;o<m.lines.length;o++){const t=m.lines[o],a=t.position,p=t.mapPositions;if(null!=this._context.clippingExtent&&(l(p,n),!h(n,this._context.clippingExtent)))continue;const c=this._createGeometry("polygon"===i.type?this._ringMaterial:this._lineMaterial,e,a,p,i.type,F.ELEVATED,r);s.push(c),x.LINE_WIREFRAMES&&s.push(c.instantiate({material:"polygon"===i.type?this._wireframeRingMaterial:this._wireframeLineMaterial})),null!=this._markerMaterial&&s.push(c.instantiate({material:this._markerMaterial}))}if(0===s.length)return null;const c=new S({geometries:s,castShadow:!1,layerUid:this._context.layer.uid,graphicUid:r}),d=new b(this,c,s,null,null,y,t);return d.alignedSampledElevation=m.sampledElevation,d.needsElevationUpdates=g(t.mode),d}_createGeometry(e,t,r,i,a,s,n){const o=s===F.DRAPED?{spatialReference:this._context.overlaySR,renderCoordsHelper:this._context.renderCoordsHelper}:null,l="polygon"===a,h=this._fastUpdates?.visualVariables.color,m=this._fastUpdates?.visualVariables.size,p=this._fastUpdates?.visualVariables.opacity,c=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:n,layerUid:this._context.layer.uid}),d={position:r,size:m?null:this._getDrivenSize(t.renderingInfo),color:h?null:this._getDrivenColor(t.renderingInfo),sizeFeature:m?R(m.field,t.graphic):null,colorFeature:h?R(h.field,t.graphic):null,opacityFeature:p?R(p.field,t.graphic):null};return D(e,{overlayInfo:o,removeDuplicateStartEnd:l,mapPositions:i,attributeData:d},c)}_createAsOverlay(e,t){const r=e.graphic,i=I(r.geometry),a="polygon"===i.type?i.rings:i.paths,s="polygon"===i.type?this._ringMaterial:this._lineMaterial;s.renderPriority=this._renderPriority;const n=x.LINE_WIREFRAMES?"polygon"===i.type?this._wireframeRingMaterial:this._wireframeLineMaterial:null,d=this._markerMaterial;null!=n&&(n.renderPriority=this._renderPriority-.001),null!=d&&(d.renderPriority=this._renderPriority-.002);const y=new Array,u=o(),_=m(),g=j(i,this._context.overlaySR),b="polygon"===i.type?"rings":"paths";this._logGeometryCreationWarnings(g,a,b,"LineSymbol3DLayer");for(const o of g.lines){if(l(o.position,u),!h(u,this._context.clippingExtent))continue;p(_,u);const a=a=>{const s=this._createGeometry(a,e,o.position,void 0,i.type,F.DRAPED,r.uid),n=new A(s,{layerUid:t,graphicUid:r.uid});y.push(n)};if(null!=d){a(d);const e=this.symbolLayer.marker.placement;"begin"!==e&&"begin-end"!==e||c(u,o.position,0,1),"end"!==e&&"begin-end"!==e||c(u,o.position,o.position.length-3,1)}a(s),x.LINE_WIREFRAMES&&a(n)}return new f(this,y,_,this._context.drapeSourceRenderer)}get _patternHidesLine(){const e=this.symbolLayer.pattern;return null!=e&&"style"===e.type&&"none"===e.style}_computeMaterialWidth(e){return e=e??t(1),this._drivenProperties.size?this._fastUpdates?.visualVariables.size?r(1):1:r(e)}_prepareMaterialPatch(e,t,r){const i=t.material;if(null==i)return void(r.changed&&r.useMaterialColor&&T(this._getCombinedOpacityAndColor(this._materialColor),this._materials[H.Marker],e));if("collection"===i.type)return;const s="complete"===i.type?i.newValue?.color:"complete"===i.diff.color?.type?i.diff.color.newValue:null,n=this._getCombinedOpacityAndColor(s);r.useMaterialColor&&T(a(n),this._materials[H.Marker],e),this._patternHidesLine&&(n[3]=0),T(n,this._materials[H.Line],e),delete t.material}_prepareMarkerPatch(e,t){const r=t.marker,i=this._markerMaterial;if(null==r||"partial"!==r.type||null==r.diff||null!=r.diff.placement||null!=r.diff.style&&"complete"!==r.diff.style.type||null!=r.diff.color&&"complete"!==r.diff.color.type||null==i)return{changed:!1,useMaterialColor:null==this._markerColor};const a=r.diff.color,s=null!=a,n=s?a.newValue:null,o=null==n&&null==this._markerColor;n&&T(this._getCombinedOpacityAndColor(n),i,e);const l=r.diff.style?.newValue;return l&&e.symbolLayerStatePatches.push((()=>i.setParameters({markerPrimitive:P(l)}))),delete t.marker,{changed:s,useMaterialColor:o}}}function I(e){switch(e.type){case"extent":if(e instanceof s)return n.fromExtent(e);break;case"polygon":case"polyline":return e}return null}function T(e,t,r){null!=t&&r.symbolLayerStatePatches.push((()=>t.setParameters({color:e})))}var F,H;V.elevationModeChangeTypes={definedChanged:u.RECREATE,staysOnTheGround:u.NONE,onTheGroundChanged:u.RECREATE},function(e){e[e.DRAPED=0]="DRAPED",e[e.ELEVATED=1]="ELEVATED"}(F||(F={})),function(e){e[e.Line=0]="Line",e[e.Ring=1]="Ring",e[e.LineWireframe=2]="LineWireframe",e[e.RingWireframe=3]="RingWireframe",e[e.Marker=4]="Marker"}(H||(H={}));export{V as Graphics3DLineSymbolLayer};