UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 27.2 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.19/LICENSE.txt */ import e from"../../../../Color.js";import{linearize as t}from"../../../../colorUtils.js";import{deg2rad as r}from"../../../../core/mathUtils.js";import{releaseMaybe as o}from"../../../../core/maybe.js";import{isPromiseLike as n}from"../../../../core/promiseUtils.js";import{normalFromMat4 as s,fromMat4 as a}from"../../../../core/libs/gl-matrix-2/math/mat3.js";import{create as i}from"../../../../core/libs/gl-matrix-2/factories/mat3f64.js";import{fromTranslation as l,multiply as c,invert as u,getTranslation as m}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as f,IDENTITY as p,clone as h}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{ONES as d}from"../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{set as g,add as x,scale as _,transformMat4 as y,transformMat3 as T,normalize as b,scaleAndAdd as v,subtract as w,cross as C,dot as M}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{fromValues as j,ONES as R,ZEROS as A,create as P}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{ONES as S}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{canProjectWithoutEngine as I}from"../../../../geometry/projectionUtils.js";import{computeTranslationToOriginAndRotation as B}from"../../../../geometry/projection/computeTranslationToOriginAndRotation.js";import{projectBuffer as U}from"../../../../geometry/projection/projectBuffer.js";import{projectVectorToVector as E}from"../../../../geometry/projection/projectVectorToVector.js";import{fromBuffer as F,intersectsClippingArea as O,create as V}from"../../../../geometry/support/aaBoundingBox.js";import{newFloatArray as $}from"../../../../geometry/support/FloatArray.js";import{getZeroIndexArray as G,getContinuousIndexArray as D}from"../../../../geometry/support/Indices.js";import L from"../../../../geometry/support/MeshComponent.js";import N from"../../../../geometry/support/MeshMaterialMetallicRoughness.js";import H from"../../../../geometry/support/MeshTextureTransform.js";import{isRelativeVertexSpace as k,isAbsoluteVertexSpace as z}from"../../../../geometry/support/meshVertexSpaceUtils.js";import{equals as q,isPlateCarree as W}from"../../../../geometry/support/spatialReferenceUtils.js";import{t as Y}from"../../../../chunks/vec3.js";import{transformNormal as K,transformVectorENUPlateCarree as J,transformVectorWMPlateCarree as Q,projectNormalToPCPF as X,transformTangent as Z,projectTangentToPCPF as ee}from"../../../../geometry/support/meshUtils/projection.js";import{projectMeshVertexPositions as te}from"../../../../geometry/support/meshUtils/projectMeshVertexPositions.js";import{getEmissiveMode as re}from"../../../../symbols/support/materialUtils.js";import{isEncodedMeshTexture as oe}from"../../glTF/internal/resourceUtils.js";import{getTransformMatrix as ne}from"../../glTF/internal/TextureTransformUtils.js";import{defaultSymbolLayerMemoryComplexity as se}from"./defaultSymbolComplexity.js";import{perObjectElevationAligner as ae}from"./ElevationAligners.js";import{needsElevationUpdates3D as ie,evaluateElevationInfoAtPoint as le}from"./elevationAlignmentUtils.js";import{preparePatchEmissiveStrength as ce}from"./emissiveUtils.js";import{Graphics3DMeshObject3DGraphicLayer as ue}from"./Graphics3DMeshObject3DGraphicLayer.js";import{Object3DEdgeState as me}from"./Graphics3DObject3DGraphicLayer.js";import{Graphics3DSymbolLayer as fe,nanFallbackColor as pe}from"./Graphics3DSymbolLayer.js";import{MaterialInfoCache as he,MeshFastUpdateProcessor as de}from"./MeshFastUpdateProcessor.js";import{SymbolComplexity as ge}from"./SymbolComplexity.js";import{hasEdges as xe,createMaterial as _e}from"../support/edgeUtils.js";import{debugFlags as ye}from"../../support/debugFlags.js";import{Attribute as Te}from"../../webgl-engine/lib/Attribute.js";import{Geometry as be}from"../../webgl-engine/lib/Geometry.js";import{ManagedTexture as ve}from"../../webgl-engine/lib/ManagedTexture.js";import{Object3D as we}from"../../webgl-engine/lib/Object3D.js";import{DefaultMaterial as Ce}from"../../webgl-engine/materials/DefaultMaterial.js";import{NativeLineMaterial as Me}from"../../webgl-engine/materials/NativeLineMaterial.js";import{useSchematicPBR as je,advancedMRRFactors as Re,schematicMRRFactors as Ae}from"../../webgl-engine/materials/pbrUtils.js";const Pe=["mesh"];class Se extends fe{constructor(e,t,r,o){super(e,t,r,o,Ye(t)),this._materialInfoCache=new he,this._fastUpdateProcessor=new de,this._textures=new Map,this.ensureDrapedStatus(!1)}async doLoad(){ye.DRAW_MESH_GEOMETRY_NORMALS&&(this._debugVertexNormalMaterial=new Me({color:[1,0,1,1]}),this._debugTangentNormalMaterial=new Me({color:[1,.5,0,1]}),this._debugFaceNormalMaterial=new Me({color:[0,1,1,1]})),this.updateComplexity()}destroy(){super.destroy(),this._textures.forEach(e=>e.unload()),this._context.stage.removeTextures(Array.from(this._textures.values())),this._materialInfoCache.clear(),this._textures.clear(),this._fastUpdateProcessor.destroy()}get materials(){return this._materialInfoCache.materials}createGraphics3DGraphic(e){const t=e.graphic;if(!this._validateGeometry(t.geometry,Pe,"fill on mesh-3d"))return null;const r=this.createElevationContextForGraphic(t),o=e.renderingInfo;return this._createAs3DShape(t,o,r,t.uid)}onRemoveGraphic(e){this._fastUpdateProcessor.onRemoveGraphic(e,this._materialInfoCache)}layerOpacityChanged(e,t){const r=this._getLayerOpacity();this._updateMaterialParameters(e=>{e.material.setParameters({layerOpacity:r});const t=e.material.parameters;this._setMaterialTextureAlphaMode(t,e)}),e?.forEach(e=>t(e)?.layerOpacityChanged(r,this._context.isAsync))}layerScreenSizePerspectiveChanged(){}layerElevationInfoChanged(e,t){return this.updateGraphics3DGraphicElevationInfo(e,t,ie)}slicePlaneEnabledChanged(e,t){return this._updateMaterialParameters(({material:e})=>{e.setParameters({hasSlicePlane:this._context.slicePlaneEnabled})}),e?.forEach(e=>t(e)?.slicePlaneEnabledChanged(this._context.slicePlaneEnabled,this._context.isAsync)),!0}physicalBasedRenderingChanged(){const e=this._usePBR();return this._updateMaterialParameters(({material:t})=>t.setParameters({usePBR:e})),!0}updateTransform(e,t,r,o){if(!e.fastTransformUpdatesAllowed)return!1;const n=e.fastTransformUpdatesEnabled;switch(o){case 0:if(n)return!0;break;case 1:if(!n)return!0;break;default:if(!n)return!!this.updateTransform(e,t,r,0)&&(e.autoDisableFastTransformUpdates(()=>this.updateTransform(e,t,r,1)),!0)}const s=this._context.renderCoordsHelper.spatialReference,a=rt,{origin:i,transform:l}=r;if(!B(t,g(Qe,i.x,i.y,i.z??0),a,s))return!1;switch(o){case 0:this._fastUpdateProcessor.enable(e,this._materialInfoCache,this._context);break;case 1:this._fastUpdateProcessor.disable(e,this._materialInfoCache)}e.updateFastLocalOrigin(a,l,this._context.localOriginFactory,!1);const{elevationContext:c}=e;c.centerInElevationSR=this._getCenterInElevationSR(a);const{elevationProvider:u,renderCoordsHelper:m}=this._context,f=(e,t)=>le(e,u,c,m,t);return e.alignedSampledElevation=ae(e,c,u.spatialReference,f,m,a),e.updateTransform(a,l,this._context.isAsync),e.updateAutoDisableFastTransformUpdates(()=>this.updateTransform(e,t,r,1)),!0}computeComplexity(){if(!this._textures||0===this._textures.size)return super.computeComplexity();let e=0;for(const o of this._textures.values())e+=o.usedMemory;const t={...se(this.symbol,this.symbolLayer),resourceBytes:e},r=xe(this.symbolLayer)?2:0;return new ge({drawCallsPerFeature:r,memory:t})}_requiresSymbolVertexColors(){return this._hasDrivenColorOrOpacity}_materialPropertiesDefault(e,t){const r=this._requiresSymbolVertexColors(),o=!!e.vertexAttributes.color,n=!!e.vertexAttributes.tangent;return{hasSymbolVertexColors:r,hasVertexColors:o,hasVertexTangents:n,uid:`vc:${o},vt:${n},vct${t},svc:${r}`}}_materialProperties(e,t,r){const o=this._materialPropertiesDefault(e,r);if(!t.material)return o;const{color:n,colorTexture:s,colorTextureTransform:a,normalTexture:i,normalTextureTransform:l,doubleSided:c,alphaCutoff:u,alphaMode:m}=t.material,f=ze(n),p=ze(s),h=qe(a),d=ze(i),g=qe(l);if(o.color=n,o.colorTexture=s,o.normalTexture=i,o.uid=`${o.uid},cmuid:${f},ctmuid:${p},cttuid:${h},ntmuid:${d},nttuid:${g},ds:${c},ac:${u},am:${m}`,t.material instanceof N){const{metallic:e,roughness:r,metallicRoughnessTexture:n,metallicRoughnessTextureTransform:s,emissiveColor:i,emissiveStrength:c,emissiveTexture:u,emissiveTextureTransform:m,occlusionTexture:f,occlusionTextureTransform:p}=t.material,h=ze(n),d=qe(s),g=ze(i),x=ze(u),_=qe(m),y=ze(f),T=qe(p);o.uid=[o.uid,`mrm:${e}`,`mrr:${r}`,`mrt:${h}`,`mrtt:${d}`,`emuid:${g}`,`ems:${c}`,`etmuid:${x}`,`ett:${_}`,`otmuid:${y}`,`ott:${T}`].join(","),o.metallic=e,o.roughness=r,o.metallicRoughnessTexture=n,o.emissiveColor=i,o.emissiveStrength=c,o.emissiveTexture=u,o.occlusionTexture=f,o.colorTextureTransform=Ge(a),o.normalTextureTransform=Ge(l),o.emissiveTextureTransform=Ge(m),o.occlusionTextureTransform=Ge(p),o.metallicRoughnessTextureTransform=Ge(s)}return o}_getInternalTexture(e,t=!1,r=1){const s=ke(e);if(!s)return null;const a=`${e.contentHash}/${r}`;let i=this._textures.get(a);if(i){const e=this._context.stage.renderView.textures;let t=null;const r=e.acquire(i.id);return null==r||n(r)||(i.events.on("unloaded",()=>t=o(t)),t=r),i}let l=null;const c=this._context.stage.renderView.renderingContext.parameters.maxMaxAnisotropy,u={wrap:De(e.wrap),noUnpackFlip:!0,maxAnisotropy:c,mipmap:c>1};return oe(s)?(l=s.data,u.preMultiplyAlpha=!1,u.encoding=s.encoding):(l=s,u.preMultiplyAlpha=1!==r,u.compressionOptions=t?{compressionTracker:this._context.compressionTracker,compressionCallback:()=>this.updateComplexity()}:void 0),i=new ve(l,u),this._textures.set(a,i),i.events.on("loaded",()=>this.updateComplexity()),i.load(this._context.stage.renderView.renderingContext),this._context.stage.addTexture(i),i.events.on("unloaded",()=>{this._textures.delete(a)}),i}_setInternalMaterialTextureParameters(e,r){if(null!=e.colorTexture){const t=1!==r.textureAlphaMode,o=this._getInternalTexture(e.colorTexture,t,r.textureAlphaMode);o?(r.textureId=o.id,r.textureAlphaPremultiplied=!!o.parameters.preMultiplyAlpha):r.textureId=void 0}if(e.normalTexture&&(r.normalTextureId=this._getInternalTexture(e.normalTexture)?.id),e.emissiveColor){const o=e.emissiveColor?.toUnitRGB();r.emissiveBaseColor=j(t(o[0]),t(o[1]),t(o[2]))}e.emissiveStrength&&(r.emissiveStrengthKHR=e.emissiveStrength),e.emissiveTexture&&(r.emissiveTextureId=this._getInternalTexture(e.emissiveTexture)?.id),e.occlusionTexture&&(r.occlusionTextureId=this._getInternalTexture(e.occlusionTexture,!0)?.id),e.metallicRoughnessTexture&&(r.metallicRoughnessTextureId=this._getInternalTexture(e.metallicRoughnessTexture,!0)?.id)}_setInternalMaterialParameters(e,t,r){null!=e.color&&He(e.color,t,r),this._setInternalMaterialTextureParameters(e,t),t.colorTextureTransformMatrix=ne(e.colorTextureTransform),t.normalTextureTransformMatrix=ne(e.normalTextureTransform);const o=null!=e.normalTextureTransform?.scale?e.normalTextureTransform?.scale:d;t.scale=[o[0],o[1]],t.occlusionTextureTransformMatrix=ne(e.occlusionTextureTransform),t.emissiveTextureTransformMatrix=ne(e.emissiveTextureTransform),t.metallicRoughnessTextureTransformMatrix=ne(e.metallicRoughnessTextureTransform)}_setExternalMaterialParameters(e,t=this._materialColor){const r=this._drivenProperties.color,o=this._drivenProperties.opacity;if(r)e.externalColor=S;else{const r=t??null;if(r){const t=r.toUnitRGBA();o&&(t[3]=1),e.externalColor=t}else e.externalColor=pe}e.colorMixMode=this.symbolLayer.material?.colorMixMode??"multiply",e.castShadows=!!this.symbolLayer.castShadows,e.emissiveStrengthFromSymbol=this.symbolLayer?.material?.emissive?.strength??1,e.emissiveSource=re(this.symbolLayer?.material?.emissive?.source??"emissive")}_getOrCreateMaterial(e,t){const r=t.material?.color,o=t.material?.colorTexture,n=t.material?.alphaMode,s="blend"===n,a=!("opaque"===n)&&(Ne(e)||null!=r&&r.a<1||o?.transparent||s),i=this._materialProperties(e,t,a),l=this._materialInfoCache.byUid(i.uid);if(l)return this._setInternalMaterialTextureParameters(i,l.material.parameters),l.material;const c={uid:i.uid,material:null,isComponentTransparent:a,alphaMode:t.material?t.material.alphaMode:"opaque"},u=je({normalTexture:i.normalTexture,metallicRoughnessTexture:i.metallicRoughnessTexture,metallicFactor:i.metallic,roughnessFactor:i.roughness,emissiveTexture:i.emissiveTexture,emissiveFactor:i.emissiveColor?.toUnitRGB(),occlusionTexture:i.occlusionTexture}),m={usePBR:this._usePBR(),isSchematic:u,hasVertexColors:i.hasVertexColors,hasSymbolColors:i.hasSymbolVertexColors,hasVertexTangents:i.hasVertexTangents,ambient:A,diffuse:R,opacity:1,doubleSided:!0,doubleSidedType:"winding-order",cullFace:0,layerOpacity:this._getLayerOpacity(),hasSlicePlane:this._context.slicePlaneEnabled,drivenOpacity:this.needsDrivenTransparentPass||c.isComponentTransparent};m.mrrFactors=u?Ae:[i.metallic,i.roughness,Re[2]],t.material&&(m.doubleSided=t.material.doubleSided,m.cullFace=t.material.doubleSided?0:2,m.textureAlphaCutoff=t.material.alphaCutoff),this._setExternalMaterialParameters(m),this._setMaterialTextureAlphaMode(m,c),this._setInternalMaterialParameters(i,m,c);const f=new Ce(m,this._context);return c.material=f,this._materialInfoCache.set(i.uid,c),f}prepareSymbolLayerPatch(e){if("partial"!==e.diff.type)return;const t=e.diff.diff;this._preparePatchColor(e,t),this._preparePatchEmissive(e,t)}_preparePatchColor(e,t){if(!t.material||"partial"!==t.material.type)return;const r=t.material.diff;if(!r.color||"complete"!==r.color.type||null==r.color.newValue||null==r.color.oldValue)return;const o=r.color.newValue;delete r.color,e.symbolLayerStatePatches.push(()=>{this._updateMaterialParameters(e=>{const t=e.material.parameters;this._setExternalMaterialParameters(t,o),this._setMaterialTextureAlphaMode(t,e),e.material.setParameters({externalColor:t.externalColor})})})}_preparePatchEmissive(e,t){return ce(e,t,e=>{this._updateMaterialParameters(t=>{t.material.setParameters({emissiveStrengthFromSymbol:e??1})})},this.view.stage.renderView.renderingContext.driverTest.floatBufferBlend.result)}_usePBR(){return this._context.physicalBasedRenderingEnabled}_setMaterialTextureAlphaMode(e,t){if("auto"===t.alphaMode){const r=this.needsDrivenTransparentPass||t.isComponentTransparent||(e.layerOpacity??1)<1||(e.opacity??1)<1||(e.externalColor?.[3]??1)<1;e.textureAlphaMode=r?3:1}else e.textureAlphaMode="opaque"===t.alphaMode?1:"mask"===t.alphaMode?2:0}_createFaceDebugNormals(e,t){const r=t.length,o=e.spatialReference.isGeographic?20015077/180:1,n=.1*Math.max(e.extent.width*o,e.extent.height*o,e.extent.zmax-e.extent.zmin),a=[],l=[],c=t[0].transformation,u=s(i(),c);for(let s=0;s<r;s++){const e=t[s].attributes.get("position");if(!e)continue;const r=e.data,o=e.indices;for(let t=0;t<o.length;t+=3)$e(r,o,t,et),Ve(r,o,t,Qe,Xe,Ze),x(Qe,Qe,Xe),x(Qe,Qe,Ze),_(Qe,Qe,1/3),y(Qe,Qe,c),a.push(...Qe),T(et,et,u),b(et,et),v(Qe,Qe,et,n),a.push(...Qe),l.push(l.length),l.push(l.length)}return a.length?new be(this._debugFaceNormalMaterial,[["position",new Te(a,l,3,!0)]],null,2):null}_createPerVertexDebugVectors(e,t,r,o,n){const l=t.length,c=e.spatialReference.isGeographic?20015077/180:1,u=.1*n*Math.max(e.extent.width*c,e.extent.height*c,e.extent.zmax-e.extent.zmin),m=[],f=[],p=t[0].transformation,h=s(i(),p);"tangent"===r&&a(h,p);for(let s=0;s<l;s++){const e=t[s],o=e.attributes.get("position"),n=e.attributes.get(r);if(!o||!n)continue;const a=o.data,i=o.indices,l=n.data,c=n.indices;for(let t=0;t<i.length;t++){const e=3*i[t],r=c[t]*n.stride;g(Qe,a[e+0],a[e+1],a[e+2]),y(Qe,Qe,p),m.push(...Qe),g(Xe,l[r+0],l[r+1],l[r+2]),T(Xe,Xe,h),b(Xe,Xe),v(Qe,Qe,Xe,u),m.push(...Qe),f.push(f.length),f.push(f.length)}}return m.length?new be(o,[["position",new Te(m,f,3,!0)]],null,2):null}_createAs3DShape(e,t,r,o){const n=e.geometry;if("mesh"!==n.type)return null;const s=this._createGeometryInfo(n,t,o);if(null==s)return null;const{geometries:a,objectTransformation:i}=s;if(ye.DRAW_MESH_GEOMETRY_NORMALS){const e=this._createPerVertexDebugVectors(n,a,"normal",this._debugVertexNormalMaterial,1),t=this._createPerVertexDebugVectors(n,a,"tangent",this._debugTangentNormalMaterial,.5),r=this._createFaceDebugNormals(n,a);e&&a.push(e),t&&a.push(t),r&&a.push(r)}const l=this._context.layerViewUid,c=new we({geometries:a,layerViewUid:l,graphicUid:o,isElevationSource:!0});c.transformation=i;const u=_e(this.symbolLayer,{opacity:this._getLayerOpacity()}),m=u?new me(a[0].material,u,this._context.slicePlaneEnabled):null,f=new ue(this,c,null,ae,r,m);this._fastUpdateProcessor.onAddGraphic(),f.needsElevationUpdates=ie(r.mode),f.useObjectOriginAsAttachmentOrigin=!0,f.fastTransformUpdatesAllowed=this._fastTransformUpdatesAllowed(n),r.centerInElevationSR=this._getCenterInElevationSR(c.transformation);const{elevationProvider:p,renderCoordsHelper:h}=this._context,d=(e,t)=>le(e,p,r,h,t);return f.alignedSampledElevation=ae(f,r,p.spatialReference,d,h),f}_fastTransformUpdatesAllowed(e){const{vertexSpace:t,spatialReference:r}=e;if(!k(t))return!1;const{type:o}=t,{view:n}=this._context.graphicsCoreOwner,{viewingMode:s}=n.state,a=n.spatialReference;return 1===s&&"local"===o||2===s&&q(a,r)&&"georeferenced"===o&&!r.isGeographic}_getElevationSR(){return this._context.elevationProvider.spatialReference??null}_getCenterInElevationSR(e){const t=P(),r=g(st,e[12],e[13],e[14]);return E(r,this._context.renderCoordsHelper.spatialReference,t,this._getElevationSR()),t}_passthroughReprojectionInfo(e){return 0===e.reprojection&&!!e.objectTransformation}_createPositionBuffer(e,t){const r=e.vertexAttributes.position;let o,n=r;if(0===t.reprojection)return{position:n,georeferencedPositionBuffer:o};const s=1===t.reprojection?t.transformBeforeProject:null;s&&(n=Y(new Float64Array(n.length),n,s));const{normal:a,tangent:i}=e.vertexAttributes;this._passthroughReprojectionInfo(t)||!a&&!i||(o=n);const l=n===r||n===o?new Float64Array(n.length):n;return U(n,e.spatialReference,0,l,this._context.renderCoordsHelper.spatialReference,0),{position:l,georeferencedPositionBuffer:o}}_createNormalBuffer(e,t,r,o){const n=e.vertexAttributes.normal;if(null==n)return null;let s=n;const a=1===o.reprojection?o.transformBeforeProject:null;a&&(s=K(s,new Float32Array(s.length),a));const i=this._context.graphicsCoreOwner.view.viewingMode;if(0===o.reprojection)return s;if("local"===i){if(!W(this._context.renderCoordsHelper.spatialReference))return s;if(null==r)return null;if(e.spatialReference.isGeographic){const e=s===n?new Float32Array(s.length):s;return J(s,0,r,e)}if(e.spatialReference.isWebMercator){const e=s===n?new Float32Array(s.length):s;return Q(s,0,r,e)}return s}if(null==r)return null;const l=s===n?new Float32Array(s.length):s,c=this._context.renderCoordsHelper.spatialReference;return X(s,r,e.spatialReference,t,c,l)}_createTangentBuffer(e,t,r,o){const n=e.vertexAttributes.tangent;if(null==n)return null;let s=n;const a=1===o.reprojection?o.transformBeforeProject:null;a&&(s=Z(s,new Float32Array(s.length),a));const i=this._context.graphicsCoreOwner.view.viewingMode;if(0===o.reprojection)return s;if("local"===i){if(!W(this._context.renderCoordsHelper.spatialReference))return s;if(null==r)return null;if(e.spatialReference.isGeographic){const e=s===n?new Float32Array(s.length):s;return J(s,1,r,e)}if(e.spatialReference.isWebMercator){const e=s===n?new Float32Array(s.length):s;return Q(s,1,r,e)}return s}if(null==r)return null;const l=s===n?new Float32Array(s.length):s,c=this._context.renderCoordsHelper.spatialReference;return ee(s,r,e.spatialReference,t,c,l)}_createSymbolColorBuffer(e){return this._requiresSymbolVertexColors()?new Uint8Array(this._getDrivenUInt8ColorWithNaNSupport(e,this._materialColor,!0)):null}_createBuffers(e,t){const r=e.vertexAttributes&&e.vertexAttributes.position;if(!r)return this.logger.warn("Mesh geometry must contain position vertex attributes"),null;const o=e.vertexAttributes.normal,n=e.vertexAttributes.uv,s=e.vertexAttributes.tangent;if(o&&o.length!==r.length)return this.logger.warn("Mesh normal vertex buffer must contain the same number of elements as the position buffer"),null;if(s&&s.length/4!=r.length/3)return this.logger.warn("Mesh tangent vertex buffer must contain the same number of elements as the position buffer"),null;if(n&&n.length/2!=r.length/3)return this.logger.warn("Mesh uv vertex buffer must contain the same number of elements as the position buffer"),null;const a=this._computeReprojectionInfo(e),{position:i,georeferencedPositionBuffer:l}=this._createPositionBuffer(e,a),c=We(e),u=this._createSymbolColorBuffer(t),m=this._createNormalBuffer(e,i,l,a),p=this._createTangentBuffer(e,i,l,a),h=n,{transformation:d,position:g,normal:x,tangent:_}=this._passthroughReprojectionInfo(a)?{transformation:a.objectTransformation,position:i,normal:m,tangent:p}:this._transformOriginLocal(e,i,m,p);return{positionBuffer:g,normalBuffer:x,tangentBuffer:_,uvBuffer:h,colorBuffer:c,symbolColorBuffer:u,objectTransformation:d,geometryTransformation:0===a.reprojection&&a.geometryTransformation?a.geometryTransformation:f()}}_computeReprojectionInfo(e){const{vertexSpace:t}=e,r="georeferenced"===t.type?q(this._context.renderCoordsHelper.spatialReference,e.spatialReference)?0:1:0;if(z(t))return{reprojection:r};const o=t.origin,n=f(),s=e.transform?.localMatrix??p;if(0===r){B(e.spatialReference,o,n,this._context.renderCoordsHelper.spatialReference);return{reprojection:r,objectTransformation:n,geometryTransformation:h(s)}}const a=l(f(),o);return c(a,a,s),{reprojection:r,transformBeforeProject:a}}_transformOriginLocal(e,t,r,o){const n=this._context.renderCoordsHelper.spatialReference,s=e.origin;Je[0]=s.x,Je[1]=s.y,Je[2]=s.z??0;const a=f();B(e.spatialReference,Je,a,n),u(tt,a);const{position:i,normal:l,tangent:c}=e.vertexAttributes,m=t===i?new Float64Array(t.length):t;Y(m,t,tt);const p=r?r===l?new Float32Array(r.length):r:null,h=o?o===c?new Float32Array(o.length):o:null;return r&&p&&K(r,p,tt),o&&h&&Z(o,h,tt),{transformation:a,position:m,normal:p,tangent:h}}_validateFaces(e,t){const r=e.vertexAttributes.position.length/3,o=t.faces;if(o){let e=-1;for(let t=0;t<o.length;t++){const r=o[t];r>e&&(e=r)}if(r<=e)return this.logger.warn(`Vertex index ${e} is out of bounds of the mesh position buffer`),!1}else if(r%3!=0)return this.logger.warn("Mesh position buffer length must be a multiple of 9 if no component faces are defined (3 values per vertex * 3 vertices per triangle)"),!1;return!0}_isOutsideClippingArea(e){if(!this._context.clippingExtent)return!1;const t=e.vertexAttributes?.position;if(!t)return!1;const r=this._context.elevationProvider.spatialReference,o=te(e,r??e.spatialReference);return!!o&&(F(o,ot),!O(ot,this._context.clippingExtent))}_createGeometryInfo(e,t,r){if(!I(e.spatialReference,this._context.renderCoordsHelper.spatialReference))return this.logger.warn("Geometry spatial reference is not compatible with the view"),null;if(!this._validateVertexSpace(e))return null;if(this._isOutsideClippingArea(e))return null;const o=this._createBuffers(e,t);if(null==o)return null;const{positionBuffer:n,uvBuffer:s,colorBuffer:a,symbolColorBuffer:i,normalBuffer:l,tangentBuffer:c,objectTransformation:u,geometryTransformation:f}=o,p=e.components??nt,h=new Array;let d=!1;const g=m(Qe,u),x=this._context.localOriginFactory.getOrigin(g);for(const m of p){if(!this._validateFaces(e,m))return null;const t=Be(e,m);if(0===t.length)continue;const o=Ue(n,l,m,t);o.didFlipNormals&&(d=!0);const u=[["position",new Te(n,t,3,!0)],["normal",new Te(o.normals,o.indices,3,!0)]];a&&u.push(["color",new Te(a,t,4,!0)]),i&&u.push(["symbolColor",new Te(i,G(t.length),4,!0)]),s&&u.push(["uv0",new Te(s,t,2,!0)]),c&&u.push(["tangent",new Te(c,t,4,!0)]);const p=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:r,layerViewUid:this._context.layerViewUid}),g=this._getOrCreateMaterial(e,m),_=new be(g,u,null,0,p);_.transformation=f,_.localOrigin=x,h.push(_)}return d&&this.logger.warn("Normals have been automatically flipped to be consistent with the counter clock wise face winding order. It is better to generate mesh geometries that have consistent normals."),{geometries:h,objectTransformation:u}}_updateMaterialParameters(e){this._materialInfoCache.forEachMaterialInfo(e),this._fastUpdateProcessor.forEachMaterialInfo(e),this._fastUpdateProcessor.forEachClonedMaterial((e,t)=>{t.setParameters(e.parameters)})}_validateVertexSpace(e){const{_context:{graphicsCoreOwner:{view:{state:{viewingMode:t}}}}}=this,{vertexSpace:r}=e;return 2!==t||"local"!==r.type||(this.logger.warn("Displaying a mesh with a local vertex space in a view in local viewing mode is not supported."),!1)}test(){return{...super.test(),materials:this._materialInfoCache.materials}}get _materialColor(){return this.symbolLayer.material?.color}}class Ie{constructor(e,t,r){this.normals=e,this.indices=t,this.didFlipNormals=r}}function Be(e,t){return t.faces??D(e.vertexAttributes.position.length/3)}function Ue(e,t,r,o){switch(r.shading||"flat"){default:case"source":return Fe(e,t,r,o);case"flat":return Ee(e,o);case"smooth":return Oe(e,o)}}function Ee(e,t){const r=$(t.length),o=new Array(3*t.length);for(let n=0;n<t.length;n+=3){const s=$e(e,t,n,et);for(let e=0;e<3;e++)r[n+e]=s[e],o[n+e]=n/3}return new Ie(r,o,!1)}function Fe(e,t,r,o){if(null==t)return Ee(e,o);let n=!1;if(!r.trustSourceNormals)for(let s=0;s<o.length;s+=3){$e(e,o,s,et);for(let e=0;e<3;e++){const r=3*o[s+e];Qe[0]=t[r],Qe[1]=t[r+1],Qe[2]=t[r+2],M(et,Qe)<0&&(t[r]=-t[r],t[r+1]=-t[r+1],t[r+2]=-t[r+2],n=!0)}}return new Ie(t,o,n)}function Oe(e,t){const r={};for(let s=0;s<t.length;s+=3){const o=$e(e,t,s,et);for(let e=0;e<3;e++){const n=t[s+e];let a=r[n];a||(a={normal:P(),count:0},r[n]=a),x(a.normal,a.normal,o),a.count++}}const o=$(3*t.length),n=new Array(3*t.length);for(let s=0;s<t.length;s++){const e=r[t[s]];1!==e.count&&(b(e.normal,e.normal),e.count=1);for(let t=0;t<3;t++)o[3*s+t]=e.normal[t];n[s]=s}return new Ie(o,n,!1)}function Ve(e,t,r,o,n,s){const a=3*t[r],i=3*t[r+1],l=3*t[r+2];o[0]=e[a],o[1]=e[a+1],o[2]=e[a+2],n[0]=e[i],n[1]=e[i+1],n[2]=e[i+2],s[0]=e[l],s[1]=e[l+1],s[2]=e[l+2]}function $e(e,t,r,o){return Ve(e,t,r,Qe,Xe,Ze),w(Xe,Xe,Qe),w(Ze,Ze,Qe),C(Qe,Xe,Ze),b(o,Qe),o}function Ge(e){if(!e)return null;const{scale:t,offset:o,rotation:n}=e;return{scale:t,offset:o,rotation:r(n)}}function De(e="repeat"){if("string"==typeof e){const t=Le(e);return{s:t,t}}return{s:Le(e.horizontal),t:Le(e.vertical)}}function Le(e){switch(e){case"clamp":return 33071;case"mirror":return 33648;default:return 10497}}function Ne(e){const t=e.vertexAttributes.color;if(null==t)return!1;for(let r=3;r<t.length;r+=4)if(255!==t[r])return!0;return!1}function He(e,t,r){t.diffuse=e.toUnitRGB(),t.opacity="opaque"===r.alphaMode?1:e.a}function ke(e){return e.data??e.url}function ze(t){return null==t?"-":t instanceof e?t.toHex():t.contentHash}function qe(e){const{offset:t,scale:r,rotation:o}=e??Ke;return`${t[0]},${t[1]},${o},${r[0]},${r[1]}`}function We(e){return e.vertexAttributes.color}function Ye(e){return 1===(e.material?.color?.a??0)}const Ke=new H,Je=P(),Qe=P(),Xe=P(),Ze=P(),et=P(),tt=f(),rt=f(),ot=V(),nt=[new L],st=P();export{Se as Graphics3DMeshFillSymbolLayer};