@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 18.7 kB
JavaScript
import e from"../../../../Color.js";import has from"../../../../core/has.js";import{isSome as t,get as s,none as r,isNone as i,unwrapOr as a}from"../../../../core/maybe.js";import{throwIfAborted as o}from"../../../../core/promiseUtils.js";import{pt2px as n}from"../../../../core/screenUtils.js";import{c,i as l,k as h,w as d}from"../../../../chunks/mat4.js";import{c as p}from"../../../../chunks/mat4f64.js";import{l as m,o as u,c as y,B as f,a as _,s as b}from"../../../../chunks/vec3.js";import{d as g,O as P,Z as x,f as R,c as v}from"../../../../chunks/vec3f64.js";import{O as L,c as S}from"../../../../chunks/vec4f64.js";import{projectPointToVector as C,computeTranslationToOriginAndRotation as j}from"../../../../geometry/projection.js";import{create as w,size as U,containsPoint as E,center as T}from"../../../../geometry/support/aaBoundingBox.js";import{defaultPrimitive as A}from"../../../../symbols/support/ObjectSymbol3DLayerResource.js";import{objectSymbolLayerPrimitiveBoundingBox as B,objectSymbolLayerSizeWithResourceSize as I}from"../../../../symbols/support/symbolLayerUtils3D.js";import{perLodInstanceElevationAligner as O}from"./ElevationAligners.js";import{needsElevationUpdates3D as G,evaluateElevationInfoAtPoint as D,SampleElevationInfo as M}from"./elevationAlignmentUtils.js";import{ElevationContext as z}from"./ElevationContext.js";import F from"./Graphics3DLodInstanceGraphicLayer.js";import{Graphics3DSymbolLayer as V}from"./Graphics3DSymbolLayer.js";import{validateSymbolLayerSize as k,mixinColorAndOpacity as H,computeObjectScale as W,computeObjectRotation as q}from"./graphicUtils.js";import{ApplyRendererDiffResult as N}from"./interfaces.js";import{LoadStatus as $}from"./Loadable.js";import{makeLodResources as Z}from"./lodResourceUtils.js";import{fetch as J}from"./objectResourceUtils.js";import{placePointOnGeometry as K,extendPointGraphicElevationContext as Q}from"./pointUtils.js";import{isValidPrimitive as X,primitiveLodResources as Y}from"./primitiveObjectSymbolUtils.js";import{defaultSymbolLayerMemoryComplexity as ee}from"./symbolComplexity.js";import{initFastSymbolUpdatesState as te,updateFastSymbolUpdatesState as se,evaluateModelTransform as re,evaluateModelTransformScale as ie}from"../support/FastSymbolUpdates.js";import{CullFaceOptions as ae}from"../../webgl-engine/lib/basicInterfaces.js";import{VertexAttribute as oe}from"../../webgl-engine/lib/VertexAttribute.js";import{LodRenderer as ne}from"../../webgl-engine/lib/lodRendering/LodRenderer.js";import{materialsFromLodResources as ce,texturesFromLodResources as le,geometriesFromLodResources as he,geometriesFromLodLevelResources as de}from"../../webgl-engine/lib/lodRendering/LodResources.js";import{DefaultMaterial as pe}from"../../webgl-engine/materials/DefaultMaterial.js";class me{constructor(e,t,s,r,i,a,o,n,c,l,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=c,this.extentPadding=l,this.physicalBasedRenderingEnabled=h,this.pivotOffset=d}}class ue extends V{getCachedSize(){const[e,s,r]=t(this._resources)?this._resources.symbolSize:[1,1,1];return{width:e,depth:s,height:r}}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.ensureDrapedStatus(!1),this._hasLoadedPBRTextures=s.physicalBasedRenderingEnabled}async doLoad(e){if(!this._drivenProperties.size){if(k(this.symbolLayer))throw new Error}const t=this.symbolLayer;if(this._isPrimitive){const s=t.resource?t.resource.primitive:A;this._resources=await this._createResourcesForPrimitive(s,e)}else this._resources=await this._createResourcesForUrl(t.resource.href,e);this.layerOpacityChanged(),this.slicePlaneEnabledChanged(),this.physicalBasedRenderingChanged(),this.complexity=this.computeComplexity()}get extentPadding(){return t(this._resources)?this._resources.extentPadding:0}get _isPrimitive(){return!(this.symbolLayer.resource&&this.symbolLayer.resource.href)}get lodRenderer(){return t(this._resources)?this._resources.lodRenderer:null}_setMaterialTransparencyParams(e,t=s(this.symbolLayer,"material","color")){const r=this._getCombinedOpacity(t),i=r<1||this.needsDrivenTransparentPass;return e.transparent=i,e.opacity=r,e.cullFace=i?ae.None:ae.Back,e}async _createResourcesForPrimitive(s,i){if(!X(s))throw new Error(`Unknown object symbol primitive: ${s}`);const a=this.symbolLayer,o=w(B(s)),c=g(U(o)),l=g(I(c,a)),h=m(l),d=!1,p=!1,u={usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0,ambient:P,diffuse:P,hasSlicePlane:this._context.slicePlaneEnabled,hasSliceHighlight:!1,castShadows:this.symbolLayer.castShadows,offsetTransparentBackfaces:!this.symbolLayer.isPrimitive},y=!!u.usePBR;this._setMaterialTransparencyParams(u);const f=this.symbol;if("point-3d"===f.type&&f.verticalOffset){const{screenLength:e,minWorldLength:s,maxWorldLength:r}=f.verticalOffset;u.verticalOffset={screenLength:n(e),minWorldLength:s||0,maxWorldLength:t(r)?r:1/0},u.castShadows=!1}if(this._context.screenSizePerspectiveEnabled&&(u.screenSizePerspective=this._context.sharedResources.screenSizePerspectiveSettings),this._drivenProperties.color)u.externalColor=L;else{const s=t(a.material)?a.material.color:null,r=t(s)?e.toUnitRGBA(s):L;u.externalColor=r}this._fastUpdates=te(this._context.renderer,this._fastVisualVariableConvertOptions(o,l,c,r)),u.instanced=["transformation"],this._fastUpdates.enabled?(Object.assign(u,this._fastUpdates.materialParameters),u.instanced.push("featureAttribute"),this._optionalFields.push("featureAttribute")):this._hasPerInstanceColor()&&(u.instanced.push("color"),this._optionalFields.push("color")),has("enable-feature:objectAndLayerId-rendering")&&(u.instanced.push("objectAndLayerIdColor"),this._optionalFields.push("objectAndLayerIdColor"));const _=new pe(u),b=Y(s,_);if(!b)throw new Error(`Unknown object symbol primitive: ${s}`);const x=ce(b).map((e=>({opacity:1,transparent:e.parameters.transparent}))),R=await this._createStageResources(b,y,i),v=await this._createLodRenderer(b,i);return new me(b,v,R,x,c,d,p,o,l,h,y,r)}async _createResourcesForUrl(e,i){const a=["transformation"],o={materialParamsMixin:{instanced:a,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows},streamDataRequester:this._context.streamDataRequester,cache:this._context.sharedResources.objectResourceCache};this._fastUpdates=te(this._context.renderer,this._fastVisualVariableConvertOptions(r,r,r,r)),this._fastUpdates.enabled?(Object.assign(o.materialParamsMixin,this._fastUpdates.materialParameters),a.push("featureAttribute"),this._optionalFields.push("featureAttribute")):this._hasPerInstanceColor()&&(a.push("color"),this._optionalFields.push("color")),has("enable-feature:objectAndLayerId-rendering")&&(a.push("objectAndLayerIdColor"),this._optionalFields.push("objectAndLayerIdColor"));const c=this.symbol;if("point-3d"===c.type&&c.verticalOffset){const{screenLength:e,minWorldLength:s,maxWorldLength:r}=c.verticalOffset;o.materialParamsMixin.verticalOffset={screenLength:n(e),minWorldLength:s||0,maxWorldLength:t(r)?r:1/0},o.materialParamsMixin.castShadows=!1}o.signal=i,o.usePBR=this._context.physicalBasedRenderingEnabled,o.skipHighLods=this._context.skipHighSymbolLods;const l=o.usePBR,h=await J(e,o),d=h.isEsriSymbolResource,p=h.isWosr,u=Z(h.lods);u.levels.sort(((e,t)=>e.minScreenSpaceRadius-t.minScreenSpaceRadius));const y=this._context,f=this.symbolLayer.material,_=this._getExternalColorParameters(f),b=s(this.symbolLayer,"material","color"),P=this._getCombinedOpacity(b,{hasIntrinsicColor:!0}),x=this.needsDrivenTransparentPass,R=ce(u),v=ce(u).map((e=>({opacity:e.parameters.opacity||1,transparent:e.parameters.transparent})));R.forEach((e=>{const t=e.parameters;e.setParameters(_);const s=t.opacity*P,r=s<1||x||t.transparent;e.setParameters({opacity:s,transparent:r}),y.screenSizePerspectiveEnabled&&e.setParameters({screenSizePerspective:y.sharedResources.screenSizePerspectiveSettings})}));const L=h.referenceBoundingBox,S=g(U(L)),C=g(u.levels[0].pivotOffset),j=g(I(S,this.symbolLayer)),w=m(j);se(this._fastUpdates,this._context.renderer,this._fastVisualVariableConvertOptions(L,j,S,C))&&R.forEach((e=>e.setParameters(this._fastUpdates.materialParameters)));const E=await this._createStageResources(u,l,i),T=await this._createLodRenderer(u,i);return new me(u,T,E,v,S,d,p,L,j,w,l,C)}_addDisposeResource(e){this._disposeResourceHandles.push(e)}async _createStageResources(e,t,s){const r=this._context.stage,i=ce(e);t!==this._context.physicalBasedRenderingEnabled&&this.physicalBasedRenderingChanged(),r.addMany(i),this._addDisposeResource((()=>r.removeMany(i)));const a=le(e);r.addMany(a),this._addDisposeResource((()=>r.removeMany(a))),await r.load(a,s),o(s);const n=he(e);return r.addMany(n),this._addDisposeResource((()=>r.removeMany(n))),{materials:i,textures:a,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.enabled?{applyTransform:(e,t,s)=>{e.getFeatureAttribute(t,be),c(s,re(this._fastUpdates.materialParameters,be,s))},scaleFactor:(e,t,s)=>(t.getFeatureAttribute(s,be),ie(e,this._fastUpdates.materialParameters,be))}:null,a=new ne({symbol:e,optionalFields:this._optionalFields,metadata:r,shaderTransformation:i},this._context.scheduler);return a.slicePlaneEnabled=this._context.slicePlaneEnabled,this._addDisposeResource((()=>{s.removeRenderPlugin(a),a.destroy()})),await s.addRenderPlugin(a.slots,a,t),a}_getExternalColorParameters(s){const r={};return this._drivenProperties.color?r.externalColor=L:t(s)&&t(s.color)?r.externalColor=e.toUnitRGBA(s.color):(r.externalColor=L,r.colorMixMode="ignore"),r}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=K(t.geometry);if(i(s))return this.logger.warn(`unsupported geometry type for icon symbol: ${t.geometry.type}`),null;const r=this.setGraphicElevationContext(t,new z),a=e.renderingInfo;return this._createAs3DShape(t,s,a,r,t.uid,e.layer.uid)}notifyDestroyGraphicLayer(e){this._instanceIndexToGraphicUid.delete(e.instanceIndex)}graphicLayerToGraphicId(){return 0}layerOpacityChanged(){if(i(this._resources))return;const e=this._drivenProperties.opacity,t=!this._isPrimitive,r=this._resources.stageResources.materials,a=this._resources.originalMaterialParameters;for(let i=0;i<r.length;i++){const o=r[i],n=s(this.symbolLayer,"material","color"),c=a[i],l=this._getCombinedOpacity(n,{hasIntrinsicColor:t})*c.opacity,h=l<1||e||c.transparent;o.setParameters({opacity:l,transparent:h}),this._isPrimitive&&o.setParameters({cullFace:h?ae.None:ae.Back})}}layerElevationInfoChanged(e,t){return this.updateGraphics3DGraphicElevationInfo(e,t,G)}slicePlaneEnabledChanged(){if(i(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(i(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)}pixelRatioChanged(){return!0}skipHighSymbolLodsChanged(){return!1}applyRendererDiff(e,t){if(i(this._resources))return N.Recreate_Symbol;const{stageResources:{materials:s},lodRenderer:r,resourceBoundingBox:a,symbolSize:o,resourceSize:n,pivotOffset:c}=this._resources;for(const i in e.diff){if("visualVariables"!==i)return N.Recreate_Symbol;if(!se(this._fastUpdates,t,this._fastVisualVariableConvertOptions(a,o,n,c)))return N.Recreate_Symbol;for(const e of s)e.setParameters(this._fastUpdates.materialParameters);r.notifyShaderTransformationChanged()}return N.Fast_Update}computeComplexity(){if(i(this._resources))return super.computeComplexity();const e=this._resources.lodResources,t=de(e.levels[0]).reduce(((e,t)=>e+t.indices.get(oe.POSITION).length),0)/3,s=e=>Array.from(e.vertexAttributes.values()).reduce(((e,t)=>e+(t.data.buffer?.byteLength??0)),0)+Array.from(e.indices.values()).reduce(((e,t)=>e+(Array.isArray(t)?12*t.length:t.buffer.byteLength)),0),r=le(e).reduce(((e,t)=>e+(t.params.encoding&&"image/ktx2"===t.params.encoding?t.estimatedTexMemRequired:t.estimatedTexMemRequired/4)),0)+he(e).reduce(((e,t)=>e+s(t)),0);return{primitivesPerFeature:t,primitivesPerCoordinate:0,drawCallsPerFeature:0,estimated:!1,memory:{...ee(this.symbol,this.symbolLayer),resourceBytes:r}}}_hasLodRenderer(){return t(this._resources)}_createAs3DShape(e,s,r,a,o,n){if(!this._hasLodRenderer()||i(this._resources))return null;const c=this.getFastUpdateAttrValues(e),l=!this._fastUpdates.enabled&&this._hasPerInstanceColor()?H(r.color,r.opacity):null,h=this._context.clippingExtent;if(C(s,ye,this._context.elevationProvider.spatialReference),t(h)&&!E(h,ye))return null;const d=this._requiresTerrainElevation(a),p=this._computeGlobalTransform(s,a,_e,ge),m=this._computeLocalTransform(this._resources,this.symbolLayer,r,fe),u=this._resources.lodRenderer.instanceData,y=u.addInstance();this._instanceIndexToGraphicUid.set(y,o),u.setLocalTransform(y,m,!1),u.setGlobalTransform(y,p),c&&u.setFeatureAttribute(y,c),l&&u.setColor(y,l),t(this._context.stage.renderView.objectAndLayerIdRenderHelper)&&u.setObjectAndLayerIdColor(y,this._context.stage.renderView.objectAndLayerIdRenderHelper.getObjectAndLayerIdColor({graphicUid:o,layerUid:n}));const f=new F(this,y,O,a);return d&&(f.alignedSampledElevation=ge.sampledElevation),f.needsElevationUpdates=G(a.mode),Q(f,s,this._context.elevationProvider),f}_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,j(e.spatialReference,ye,s,this._context.renderCoordsHelper.spatialReference),s}_computeLocalTransform(e,t,s,r){return l(r),this._applyObjectRotation(s,!1,r),this._applyObjectRotation(t,!0,r),this._applyObjectScale(e,s,r),this._applyAnchor(e,t,r),r}_applyObjectScale(e,t,s){if(this._fastUpdates.enabled&&this._fastUpdates.requiresShaderTransformation)return;const r=this._drivenProperties.size&&t.size?t.size:e.symbolSize,i=W(r,e.symbolSize,e.resourceSize,this._context.renderCoordsHelper.unitInMeters);1===i[0]&&1===i[1]&&1===i[2]||h(s,s,i)}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(i(this._resources))return!0;const s=t&&K(t);if(i(s))return!1;const r=this.getGeometryElevationMode(t);return e.elevationContext.mode===r&&(this._computeGlobalTransform(s,e.elevationContext,_e,ge),this._requiresTerrainElevation(e.elevationContext)&&(e.alignedSampledElevation=ge.sampledElevation),this._resources.lodRenderer.instanceData.setGlobalTransform(e.instanceIndex,_e,!0),Q(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(i(this._resources))return;const s=(e,t,s)=>a(null!=e&&"complete"===e.type?e.newValue:t,s),r=s(t.heading,this.symbolLayer.heading,0),o=s(t.tilt,this.symbolLayer.tilt,0),n=s(t.roll,this.symbolLayer.roll,0),c=s(t.width,this.symbolLayer.width,void 0),l=s(t.height,this.symbolLayer.height,void 0),h=s(t.depth,this.symbolLayer.depth,void 0),d=s(t.anchor,this.symbolLayer.anchor,void 0),p=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 m={heading:r,tilt:o,roll:n,anchor:d,anchorPosition:p},u=this._resources;this.loadStatus===$.LOADED&&e.symbolLayerStatePatches.push((()=>{u.symbolSize=g(I(u.resourceSize,{width:c,height:l,depth:h,isPrimitive:this.symbolLayer.isPrimitive}))})),e.graphics3DGraphicPatches.push(((e,t)=>{const s=this._computeLocalTransform(u,m,t,fe),r=e.instanceIndex;u.lodRenderer.instanceData.setLocalTransform(r,s,!0)}))}_preparePatchColor(s,r){if(!r.material||"partial"!==r.material.type)return;const a=r.material.diff;if(!a.color||"complete"!==a.color.type||null==a.color.newValue||null==a.color.oldValue)return;const o=a.color.newValue,n=t(o)?e.toUnitRGBA(o):L;delete a.color;const c=this._resources;i(c)||s.graphics3DGraphicPatches.push((e=>{let t;this._hasPerInstanceColor()?(c.lodRenderer.instanceData.setColor(e.instanceIndex,n),t=this._setMaterialTransparencyParams({},o)):t=this._setMaterialTransparencyParams({externalColor:n},o);for(const s of c.stageResources.materials)s.setParameters(t)}))}_requiresTerrainElevation(e){return"absolute-height"!==e.mode}_applyObjectRotation(e,t,s){if(!(this._fastUpdates.enabled&&this._fastUpdates.requiresShaderTransformation&&t))return q(e.heading,e.tilt,e.roll,s)}_computeAnchor(e,s,r){const i=v();switch(r.anchor){case"center":y(i,T(e)),u(i,i);break;case"top":{const t=T(e);b(i,-t[0],-t[1],-e[5]);break}case"bottom":{const t=T(e);b(i,-t[0],-t[1],-e[2]);break}case"relative":{const t=T(e),s=U(e),a=r.anchorPosition,o=a?R(a.x,a.y,a.z):x;f(i,s,o),_(i,i,t),u(i,i);break}default:t(s)?u(i,s):y(i,x)}return i}_applyAnchor(e,t,s){if(this._fastUpdates.enabled&&this._fastUpdates.requiresShaderTransformation)return;const r=this._computeAnchor(e.resourceBoundingBox,e.pivotOffset,t);r&&d(s,s,r)}_hasPerInstanceColor(){return this._drivenProperties.color||this._drivenProperties.opacity}_fastVisualVariableConvertOptions(e,s,r,i){const a=t(e)?g(U(e)):P,o=t(e)?this._computeAnchor(e,i,this.symbolLayer):x,n=this._context.renderCoordsHelper.unitInMeters,c=W(t(s)?s:void 0,s,r,n),l=R(this.symbolLayer.tilt||0,this.symbolLayer.roll||0,this.symbolLayer.heading||0);return{modelSize:a,symbolSize:t(s)?s:P,unitInMeters:n,transformation:{anchor:o,scale:c,rotation:l}}}}const ye=v(),fe=p(),_e=p(),be=S(),ge=new M;export{ue as Graphics3DObjectSymbolLayer};