UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 18.5 kB
/* 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"../../../../Color.js";import{throwIfAborted as t}from"../../../../core/promiseUtils.js";import{pt2px as s}from"../../../../core/screenUtils.js";import{identity as r,scale as i,translate as a,copy as o}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as n}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{l,F as c,v as h,c as d,C as m,g as p,i as u}from"../../../../chunks/vec32.js";import{fromArray as y,clone as f,ZEROS as _,ONES as g,fromValues as b,create as P}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{ONES as R,create as x}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{computeTranslationToOriginAndRotation as v}from"../../../../geometry/projection/computeTranslationToOriginAndRotation.js";import{projectPointToVector as L}from"../../../../geometry/projection/projectPointToVector.js";import{create as C,size as S,containsPoint as w,center as E}from"../../../../geometry/support/aaBoundingBox.js";import{defaultPrimitive as j}from"../../../../symbols/support/ObjectSymbol3DLayerResource.js";import{objectSymbolLayerPrimitiveBoundingBox as U,objectSymbolLayerSizeWithResourceSize as T}from"../../../../symbols/support/symbolLayerUtils3D.js";import{estimateNumVerticesForLods as O,defaultSymbolLayerMemoryComplexity as B}from"./defaultSymbolComplexity.js";import{perLodInstanceElevationAligner as G}from"./ElevationAligners.js";import{needsElevationUpdates3D as I,evaluateElevationInfoAtPoint as D,SampleElevationInfo as F}from"./elevationAlignmentUtils.js";import{Graphics3DLodInstanceGraphicLayer as A}from"./Graphics3DLodInstanceGraphicLayer.js";import{Graphics3DSymbolLayer as M}from"./Graphics3DSymbolLayer.js";import{validateSymbolLayerSize as z,mixinColorAndOpacity as V,computeObjectScale as k,computeObjectRotation as H}from"./graphicUtils.js";import{ApplyRendererDiffResult as W}from"./interfaces.js";import{LoadStatus as q}from"./Loadable.js";import{makeLodResources as N}from"./lodResourceUtils.js";import{fetch as J}from"./objectResourceUtils.js";import{placePointOnGeometry as Y,extendPointGraphicElevationContext as $}from"./pointUtils.js";import{isValidPrimitive as K,primitiveLodResources as Q}from"./primitiveObjectSymbolUtils.js";import{SymbolComplexity as X}from"./SymbolComplexity.js";import{getResourceUrlFromSymbolStyle as Z}from"./webStyleUtils.js";import{initFastSymbolUpdatesState as ee,updateFastSymbolUpdatesState as te,ConvertOptions as se,evaluateModelTransform as re,evaluateModelTransformScale as ie}from"../support/FastSymbolUpdates.js";import{olidEnabled as ae}from"../../webgl-engine/effects/geometry/olidUtils.js";import{CullFaceOptions as oe}from"../../webgl-engine/lib/basicInterfaces.js";import{VertexAttribute as ne}from"../../webgl-engine/lib/VertexAttribute.js";import{LodRenderer as le}from"../../webgl-engine/lib/lodRendering/LodRenderer.js";import{DefaultMaterial as ce}from"../../webgl-engine/materials/DefaultMaterial.js";import{schematicMRRFactors as he}from"../../webgl-engine/materials/pbrUtils.js";class de{constructor(e,t,s,r,i,a,o,n,l,c,h,d){this.lodResources=e,this.lodRenderer=t,this.stageResources=s,this.originalMaterialParameters=r,this.resourceSize=i,this.isEsriSymbolResource=a,this.isWosr=o,this.resourceBoundingBox=n,this.symbolSize=l,this.extentPadding=c,this.physicalBasedRenderingEnabled=h,this.pivotOffset=d}}class me extends M{getCachedSize(){const[e,t,s]=null!=this._resources?this._resources.symbolSize:[1,1,1];return{width:e,depth:t,height:s}}constructor(e,t,s,r){super(e,t,s,r),this._resources=null,this._optionalFields=new Array,this._instanceIndexToGraphicUid=new Map,this._hasLoadedPBRTextures=!1,this._disposeResourceHandles=new Array,this.skipHighSymbolLodsChanged=!1,this.ensureDrapedStatus(!1),this._hasLoadedPBRTextures=s.physicalBasedRenderingEnabled}async doLoad(e){if(!this._drivenProperties.size){const e=z(this.symbolLayer);if(e)throw new Error(e)}if(this._isPrimitive){const t=this.symbolLayer.resource,s=t&&K(t?.primitive)?t.primitive:j;this._resources=await this._createResourcesForPrimitive(s,e)}else{const t=await Z(this.symbol.styleOrigin),s=t?.href??this.symbolLayer.resource?.href;this._resources=await this._createResourcesForUrl(s,e)}this.layerOpacityChanged(),this.slicePlaneEnabledChanged(),this.physicalBasedRenderingChanged(),this.complexity=this.computeComplexity()}get extentPadding(){return null!=this._resources?this._resources.extentPadding:0}get _isPrimitive(){return!this.symbolLayer.resource?.href}get lodRenderer(){return this._resources?.lodRenderer}get materials(){return this._resources?.stageResources.materials??[]}_setMaterialTransparencyParameters(e,t=this.symbolLayer?.material?.color){const s=this._getCombinedOpacity(t),r=s<1||this.needsDrivenTransparentPass;return e.transparent=r,e.opacity=s,e.cullFace=r?oe.None:oe.Back,e}async _createResourcesForPrimitive(t,r){const i=this.symbolLayer,a=C(U(t)),o=y(S(a)),n=y(T(o,i)),h=l(n),d=!1,m=!1,p=this.symbolLayer?.material?.emissiveFactor,u=p?c(f(p)):_,b={usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0,mrrFactors:he,ambient:g,diffuse:g,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows,emissiveFactor:u,offsetTransparentBackfaces:!this.symbolLayer.isPrimitive},P=!!b.usePBR;this._setMaterialTransparencyParameters(b);const x=this.symbol;if("point-3d"===x.type&&x.verticalOffset){const{screenLength:e,minWorldLength:t,maxWorldLength:r}=x.verticalOffset;b.verticalOffset={screenLength:s(e),minWorldLength:t||0,maxWorldLength:null!=r?r:1/0},b.castShadows=!1}if(this._context.screenSizePerspectiveEnabled&&(b.screenSizePerspective=this._context.sharedResources.screenSizePerspectiveSettings),this._drivenProperties.color)b.externalColor=R;else{const t=null!=i.material?i.material.color:null,s=null!=t?e.toUnitRGBA(t):R;b.externalColor=s}this._fastUpdates=ee(this._context.renderer,this._fastVisualVariableConvertOptions(a,n,o,null)),b.isInstanced=!0,this._fastUpdates?(Object.assign(b,this._fastUpdates.materialParameters),this._optionalFields.push(ne.FEATUREATTRIBUTE)):this._hasPerInstanceColor()&&(b.hasInstancedColor=!0,this._optionalFields.push(ne.COLOR)),ae()&&this._optionalFields.push(ne.OBJECTANDLAYERIDCOLOR);const v=new ce(b,this._context),L=Q(t,v);if(!L)throw new Error(`Unknown object symbol primitive: ${t}`);const w=L.getMaterials().map((e=>({opacity:1,transparent:e.parameters.transparent}))),E=await this._createStageResources(L,P,r),j=await this._createLodRenderer(L,r);return new de(L,j,E,w,o,d,m,a,n,h,P,null)}async _createResourcesForUrl(e,t){const r={isInstanced:!0,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows},i={spherical:this._context.spherical,doublePrecisionRequiresObfuscation:this._context.doublePrecisionRequiresObfuscation,materialParameters:r,streamDataRequester:this._context.streamDataRequester,cache:this._context.sharedResources.objectResourceCache};this._fastUpdates=ee(this._context.renderer,this._fastVisualVariableConvertOptions(null,null,null,null)),this._fastUpdates?(Object.assign(i.materialParameters,this._fastUpdates.materialParameters),this._optionalFields.push(ne.FEATUREATTRIBUTE)):this._hasPerInstanceColor()&&(i.materialParameters.hasInstancedColor=!0,this._optionalFields.push(ne.COLOR)),ae()&&this._optionalFields.push(ne.OBJECTANDLAYERIDCOLOR);const a=this.symbol;if("point-3d"===a.type&&a.verticalOffset){const{screenLength:e,minWorldLength:t,maxWorldLength:r}=a.verticalOffset;i.materialParameters.verticalOffset={screenLength:s(e),minWorldLength:t||0,maxWorldLength:null!=r?r:1/0},i.materialParameters.castShadows=!1}const o=this._context.physicalBasedRenderingEnabled;i.signal=t,i.usePBR=o,i.skipHighLods=this._context.skipHighSymbolLods;const n=await J(e,i),c=n.isEsriSymbolResource,h=n.isWosr,d=N(n.lods),m=this._context,p=this.symbolLayer.material,u=this._getExternalColorParameters(p),f=this.symbolLayer?.material?.color,_=this._getCombinedOpacity(f,{hasIntrinsicColor:!0}),g=this.needsDrivenTransparentPass,b=d.getMaterials(),P=d.getMaterials().map((e=>({opacity:e.parameters.opacity||1,transparent:e.parameters.transparent})));b.forEach((e=>{const t=e.parameters;e.setParameters(u);const s=t.opacity*_,r=s<1||g||t.transparent;e.setParameters({opacity:s,transparent:r}),m.screenSizePerspectiveEnabled&&e.setParameters({screenSizePerspective:m.sharedResources.screenSizePerspectiveSettings})}));const R=n.referenceBoundingBox,x=y(S(R)),v=y(d.levels[0].pivotOffset),L=y(T(x,this.symbolLayer)),C=l(L),w=this._fastUpdates;te(w,this._context.renderer,this._fastVisualVariableConvertOptions(R,L,x,v))&&b.forEach((e=>e.setParameters(w.materialParameters)));const E=await this._createStageResources(d,o,t),j=await this._createLodRenderer(d,t);return new de(d,j,E,P,x,c,h,R,L,C,o,v)}_addDisposeResource(e){this._disposeResourceHandles.push(e)}async _createStageResources(e,s,r){const i=this._context.stage,a=e.getMaterials();s!==this._context.physicalBasedRenderingEnabled&&this.physicalBasedRenderingChanged(),i.addMany(a),this._addDisposeResource((()=>i.removeMany(a)));const o=e.getTextures();i.addMany(o),this._addDisposeResource((()=>{o.forEach((e=>e.unload())),i.removeMany(o)})),await Promise.all(o.map((e=>this._context.stage.schedule((()=>e.load(i.renderView.renderingContext)),r)))),t(r);const n=e.getEngineGeometries();return i.addMany(n),this._addDisposeResource((()=>i.removeMany(n))),{materials:a,textures:o,geometries:n}}async _createLodRenderer(e,t){const s=this._context.stage,r={layerUid:this._context.layer.uid,graphicUid:e=>this._instanceIndexToGraphicUid.get(e),notifyGraphicGeometryChanged:e=>this._context.notifyGraphicGeometryChanged(this._instanceIndexToGraphicUid.get(e)),notifyGraphicVisibilityChanged:e=>this._context.notifyGraphicVisibilityChanged(this._instanceIndexToGraphicUid.get(e))},i=this._fastUpdates,a=i?{applyTransform:(e,t,s)=>{e.getFeatureAttribute(t,ge),o(s,re(i.materialParameters,ge,s))},scaleFactor:(e,t,s)=>{t.getFeatureAttribute(s,ge),ie(e,i.materialParameters,ge)}}:null,n=new le({symbol:e,optionalFields:this._optionalFields,metadata:r,shaderTransformation:a},this._context.scheduler);return n.slicePlaneEnabled=this._context.slicePlaneEnabled,this._addDisposeResource((()=>{s.removeRenderPlugin(n),n.destroy()})),await s.addRenderPlugin(n,t),n}_getExternalColorParameters(t){const s={};return this._drivenProperties.color?s.externalColor=R:null!=t?.color?s.externalColor=e.toUnitRGBA(t.color):(s.externalColor=R,s.colorMixMode="ignore"),s}destroy(){super.destroy(),this._cleanupResources()}_cleanupResources(){this._disposeResourceHandles.forEach((e=>e())),this._disposeResourceHandles.length=0,this._resources=null}createGraphics3DGraphic(e){const t=e.graphic;if(!this._validateGeometry(t.geometry))return null;const s=Y(t.geometry);if(null==s)return this.logger.warn(`unsupported geometry type for object symbol: ${t.geometry.type}`),null;const r=this.setGraphicElevationContext(t),i=e.renderingInfo;return this._createAs3DShape(t,s,i,r,t.uid,e.layer.uid)}notifyDestroyGraphicLayer(e){this._instanceIndexToGraphicUid.delete(e.instanceIndex)}graphicLayerToGraphicId(){return 0}layerOpacityChanged(){if(null==this._resources)return;const e=this._drivenProperties.opacity,t=!this._isPrimitive,s=this._resources.stageResources.materials,r=this._resources.originalMaterialParameters;for(let i=0;i<s.length;i++){const a=s[i],o=this.symbolLayer?.material?.color,n=r[i],l=this._getCombinedOpacity(o,{hasIntrinsicColor:t})*n.opacity,c=l<1||e||n.transparent;a.setParameters({opacity:l,transparent:c}),this._isPrimitive&&a.setParameters({cullFace:c?oe.None:oe.Back})}}layerElevationInfoChanged(e,t){return this.updateGraphics3DGraphicElevationInfo(e,t,I)}slicePlaneEnabledChanged(){if(null==this._resources)return!0;this._resources.lodRenderer.slicePlaneEnabled=this._context.slicePlaneEnabled;for(const e of this._resources.stageResources.materials)e.setParameters({hasSlicePlane:this._context.slicePlaneEnabled});return!0}physicalBasedRenderingChanged(){if(null==this._resources)return!0;const{stageResources:e,isWosr:t}=this._resources;for(const s of e.materials)this._isPrimitive?s.setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0}):t||s.setParameters({usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!1});return!1!==this._hasLoadedPBRTextures||!0!==this._context.physicalBasedRenderingEnabled||(this._hasLoadedPBRTextures=!0,!1)}applyRendererDiff(e,t){if(null==this._resources)return W.RecreateSymbol;const{stageResources:{materials:s},lodRenderer:r,resourceBoundingBox:i,symbolSize:a,resourceSize:o,pivotOffset:n}=this._resources;for(const l in e.diff){if("visualVariables"!==l)return W.RecreateSymbol;if(!te(this._fastUpdates,t,this._fastVisualVariableConvertOptions(i,a,o,n)))return W.RecreateSymbol;for(const e of s)e.setParameters(this._fastUpdates.materialParameters);r.notifyShaderTransformationChanged()}return W.FastUpdate}computeComplexity(){if(null==this._resources)return super.computeComplexity();const e=this._resources.lodResources,t=O(e.levels),s=e.computeUsedMemory(),r={...B(this.symbol,this.symbolLayer),resourceBytes:s};return new X({verticesPerFeature:t,memory:r})}_hasLodRenderer(){return null!=this._resources}_createAs3DShape(e,t,s,r,i,a){if(!this._hasLodRenderer()||null==this._resources)return null;const o=this.getFastUpdateAttrValues(e),n=this._context.clippingExtent;if(L(t,ye,this._context.elevationProvider.spatialReference),null!=n&&!w(n,ye))return null;const l=ue(r),c=this._computeGlobalTransform(t,r,_e,be),h=this._computeLocalTransform(this._resources,this.symbolLayer,s,fe),d=this._resources.lodRenderer.instanceData,m=d.addInstance();this._instanceIndexToGraphicUid.set(m,i),d.setLocalTransform(m,h,!1),d.setGlobalTransform(m,c),o&&d.setFeatureAttribute(m,o),null==this._fastUpdates&&this._hasPerInstanceColor()&&d.setColor(m,V(s.color,s.opacity,255));const p=this._context.stage.renderView.olidRenderHelper;p&&d.setObjectAndLayerIdColor(m,p.getObjectAndLayerIdColor({graphicUid:i,layerUid:a}));const u=new A(this,m,G,r,this._context.stage.view.state.highlightOrderMap);return l&&(u.alignedSampledElevation=be.sampledElevation),u.needsElevationUpdates=I(r.mode),$(u,t,this._context.elevationProvider),u}_computeGlobalTransform(e,t,s,r){return D(e,this._context.elevationProvider,t,this._context.renderCoordsHelper,r),ye[0]=e.x,ye[1]=e.y,ye[2]=r.z,v(e.spatialReference,ye,s,this._context.renderCoordsHelper.spatialReference),s}_computeLocalTransform(e,t,s,i){return r(i),this._applyObjectRotation(s,!1,i),this._applyObjectRotation(t,!0,i),this._applyObjectScale(e,s,i),this._applyAnchor(e,t,i),i}_applyObjectScale(e,t,s){if(this._fastUpdates?.requiresShaderTransformation)return;const r=this._drivenProperties.size&&t.size?t.size:e.symbolSize,a=k(r,e.symbolSize,e.resourceSize,this._context.renderCoordsHelper.unitInMeters);1===a[0]&&1===a[1]&&1===a[2]||i(s,s,a)}prepareSymbolLayerPatch(e){if("partial"!==e.diff.type)return;const t=e.diff.diff;this._preparePatchTransform(e,t),this._preparePatchColor(e,t)}updateGeometry(e,t){if(null==this._resources)return!0;const s=t&&Y(t);if(null==s)return!1;const r=this.getGeometryElevationMode(t);return e.elevationContext.mode===r&&(this._computeGlobalTransform(s,e.elevationContext,_e,be),ue(e.elevationContext)&&(e.alignedSampledElevation=be.sampledElevation),this._resources.lodRenderer.instanceData.setGlobalTransform(e.instanceIndex,_e,!0),$(e,s,this._context.elevationProvider),!0)}_preparePatchTransform(e,t){if(!(t.heading||t.tilt||t.roll||t.width||t.height||t.depth||t.anchor||t.anchorPosition))return;if(null==this._resources)return;const s=(e,t,s)=>(null!=e&&"complete"===e.type?e.newValue:t)??s,r=s(t.heading,this.symbolLayer.heading,0),i=s(t.tilt,this.symbolLayer.tilt,0),a=s(t.roll,this.symbolLayer.roll,0),o=s(t.width,this.symbolLayer.width,void 0),n=s(t.height,this.symbolLayer.height,void 0),l=s(t.depth,this.symbolLayer.depth,void 0),c=s(t.anchor,this.symbolLayer.anchor,void 0),h=s(t.anchorPosition,this.symbolLayer.anchorPosition,void 0);delete t.heading,delete t.tilt,delete t.roll,delete t.width,delete t.height,delete t.depth,delete t.anchor,delete t.anchorPosition;const d={heading:r,tilt:i,roll:a,anchor:c,anchorPosition:h},m=this._resources;this.loadStatus===q.LOADED&&e.symbolLayerStatePatches.push((()=>{m.symbolSize=y(T(m.resourceSize,{width:o,height:n,depth:l,isPrimitive:this.symbolLayer.isPrimitive}))})),e.graphics3DGraphicPatches.push((({instanceIndex:e},t)=>{const s=this._computeLocalTransform(m,d,t,fe);m.lodRenderer.instanceData.setLocalTransform(e,s,!0)}))}_preparePatchColor(t,s){if(!s.material||"partial"!==s.material.type)return;const r=s.material.diff;if(!r.color||"complete"!==r.color.type||null==r.color.newValue||null==r.color.oldValue)return;const i=r.color.newValue,a=null!=i?e.toUnitRGBA(i):R;delete r.color;const o=this._resources;null!=o&&t.graphics3DGraphicPatches.push((({instanceIndex:e})=>{let t;this._hasPerInstanceColor()?(o.lodRenderer.instanceData.setColor(e,a),t=this._setMaterialTransparencyParameters({},i)):t=this._setMaterialTransparencyParameters({externalColor:a},i);for(const s of o.stageResources.materials)s.setParameters(t)}))}_applyObjectRotation(e,t,s){if(!this._fastUpdates?.requiresShaderTransformation||!t)return H(e.heading,e.tilt,e.roll,s)}_applyAnchor(e,t,s){if(this._fastUpdates?.requiresShaderTransformation)return;const r=pe(e.resourceBoundingBox,e.pivotOffset,t);r&&a(s,s,r)}_hasPerInstanceColor(){return this._drivenProperties.color||this._drivenProperties.opacity}_fastVisualVariableConvertOptions(e,t,s,r){const i=null!=e?y(S(e)):g,a=null!=e?pe(e,r,this.symbolLayer):_,o=this._context.renderCoordsHelper.unitInMeters,n=k(null!=t?t:void 0,t,s,o),l=b(this.symbolLayer.tilt||0,this.symbolLayer.roll||0,this.symbolLayer.heading||0);return new se({size:!0,color:!0,rotation:!0,opacity:!1},i,t??g,o,a,n,l)}}function pe(e,t,s){const r=P();switch(s.anchor){case"center":d(r,E(e)),h(r,r);break;case"top":{const t=E(e);u(r,-t[0],-t[1],-e[5]);break}case"bottom":{const t=E(e);u(r,-t[0],-t[1],-e[2]);break}case"relative":{const t=E(e),i=S(e),a=s.anchorPosition,o=a?b(a.x,a.y,a.z):_;m(r,i,o),p(r,r,t),h(r,r);break}default:null!=t?h(r,t):d(r,_)}return r}function ue(e){return"absolute-height"!==e.mode}const ye=P(),fe=n(),_e=n(),ge=x(),be=new F;export{me as Graphics3DObjectSymbolLayer};