@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 12.2 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"../../../../core/has.js";import t from"../../../../core/Error.js";import{clone as e}from"../../../../core/lang.js";import{getMetersPerVerticalUnitForSR as r}from"../../../../core/unitUtils.js";import{e as s}from"../../../../chunks/earcut.js";import{normalFromMat4 as o}from"../../../../core/libs/gl-matrix-2/math/mat3.js";import{create as i}from"../../../../core/libs/gl-matrix-2/factories/mat3f64.js";import{invert as n,invertOrIdentity as a}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as l}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{F as c,c as m,n as p,i as h,d as g,e as d,t as u,a as f}from"../../../../chunks/vec32.js";import{fromArray as y,clone as b,ZEROS as _,create as x}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{computeTranslationToOriginAndRotation as S}from"../../../../geometry/projection/computeTranslationToOriginAndRotation.js";import{create as j,fromBuffer as P,intersectsClippingArea as E}from"../../../../geometry/support/aaBoundingBox.js";import{newDoubleArray as w}from"../../../../geometry/support/DoubleArray.js";import{newIndexArray as O,getZeroIndexArray as v}from"../../../../geometry/support/Indices.js";import{t as C}from"../../../../chunks/vec3.js";import{makeVertexCandidate as M,makeEdgeCandidate as I}from"../../../../layers/graphics/data/SnappingCandidate.js";import{getDriverAxisSizeValue as A}from"../../../../renderers/support/renderingInfoUtils.js";import{ViewingMode as L}from"../../../ViewingMode.js";import{needsElevationUpdates3D as z,SampleElevationInfo as B}from"./elevationAlignmentUtils.js";import{Object3DEdgeState as D,Graphics3DObject3DGraphicLayer as R}from"./Graphics3DObject3DGraphicLayer.js";import{Graphics3DSymbolLayer as T}from"./Graphics3DSymbolLayer.js";import{validateSymbolLayerSize as U,computeCentroid as G}from"./graphicUtils.js";import{ApplyRendererDiffResult as N}from"./interfaces.js";import{geometryAsPolygon as V}from"./polygonUtils.js";import{createMaterial as F}from"../support/edgeUtils.js";import{debugFlags as k}from"../../support/debugFlags.js";import{SamplePosition as H}from"../../support/ElevationProvider.js";import{geometryToRenderInfo as W}from"../../support/renderInfoUtils/polygon.js";import{NormalType as q}from"../../webgl-engine/core/shaderLibrary/attributes/NormalAttribute.glsl.js";import{Attribute as Z}from"../../webgl-engine/lib/Attribute.js";import{CullFaceOptions as J}from"../../webgl-engine/lib/basicInterfaces.js";import{ContentObjectType as K}from"../../webgl-engine/lib/ContentObjectType.js";import{Geometry as Q}from"../../webgl-engine/lib/Geometry.js";import{isGeometryWithMapPositions as X}from"../../webgl-engine/lib/GeometryWithMapPositions.js";import{compressNormals as Y,compressNormal as $}from"../../webgl-engine/lib/Normals.js";import{Object3D as tt}from"../../webgl-engine/lib/Object3D.js";import{VertexAttribute as et}from"../../webgl-engine/lib/VertexAttribute.js";import{DefaultMaterial as rt}from"../../webgl-engine/materials/DefaultMaterial.js";const st=["polygon","extent"];class ot extends T{constructor(t,e,r,s){super(t,e,r,s),this.ensureDrapedStatus(!1)}async doLoad(){if(!this._drivenProperties.size){const e=U(this._getSymbolSize());if(e)throw new t("graphics3dextrudesymbollayer:invalid-size",e)}const e=this.symbolLayer?.material?.color,r=this._getCombinedOpacityAndColor(e),s=y(r),o=r[3],i=o<1||this.needsDrivenTransparentPass,n=this.symbolLayer?.material?.emissiveFactor,a=n?c(b(n)):_,l={usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0,diffuse:s,ambient:s,opacity:o,transparent:i,cullFace:i?J.None:J.Back,hasVertexColors:!0,hasSlicePlane:this._context.slicePlaneEnabled,castShadows:this.symbolLayer.castShadows,emissiveFactor:a,offsetTransparentBackfaces:!0,normalType:q.Compressed};this._materials[It.Main]=new rt(l,this._context),this._materials[It.Bottom]=new rt({...l,cullFace:J.Back},this._context),this._context.stage.addMany(this._materials)}destroy(){super.destroy(),this._context.stage.removeMany(this._materials),this._materials.length=0}createGraphics3DGraphic(t){const e=t.graphic;if(!this._validateGeometry(e.geometry,st,this.symbolLayer.type))return null;const r=this._getVertexOpacityAndColor(t.renderingInfo,255),s=this.setGraphicElevationContext(e);return this._createAs3DShape(e,t.renderingInfo,r,s,e.uid)}layerOpacityChanged(t,e){const r=this.symbolLayer?.material?.color,s=this._getCombinedOpacity(r),o=s<1||this.needsDrivenTransparentPass;this._materials[It.Main]?.setParameters({opacity:s,transparent:o}),this._materials[It.Bottom]?.setParameters({opacity:s,transparent:o});const i=this._getLayerOpacity();t.forEach((t=>e(t)?.layerOpacityChanged(i,this._context.isAsync)))}layerElevationInfoChanged(t,e){return this.updateGraphics3DGraphicElevationInfo(t,e,z)}slicePlaneEnabledChanged(t,e){return this._materials[It.Main]?.setParameters({hasSlicePlane:this._context.slicePlaneEnabled}),this._materials[It.Bottom]?.setParameters({hasSlicePlane:this._context.slicePlaneEnabled}),t.forEach((t=>{const r=e(t);null!=r&&r.slicePlaneEnabledChanged(this._context.slicePlaneEnabled,this._context.isAsync)})),!0}physicalBasedRenderingChanged(){const t={usePBR:this._context.physicalBasedRenderingEnabled,isSchematic:!0};return this._materials[It.Main]?.setParameters(t),this._materials[It.Bottom]?.setParameters(t),!0}_getExtrusionSize(t){let e;return e=t.size&&this._drivenProperties.size?A(t.size,2)??0:this._getSymbolSize(),e/=this._context.renderCoordsHelper.unitInMeters,e}applyRendererDiff(t,e){return this._drivenPropertiesChanged(e)?N.RecreateSymbol:N.RecreateGraphics}async queryForSnapping(t,s,o,i){const n=this._getExtrusionSize(o)*this._context.renderCoordsHelper.unitInMeters/r(s),{objectId:a,target:l}=t,c=e(l);switch(c.z=(c.z??0)+n,t.type){case"edge":{const{start:r,end:s}=t,o=e(r),i=e(s);return o.z=(o.z??0)+n,i.z=(i.z??0)+n,[I(a,c,1/0,o,i)]}case"vertex":return[M(a,c,1/0),I(a,l,1/0,l,c)];default:return[]}}_getSymbolSize(){return this.symbolLayer.size??1}_createAs3DShape(t,e,r,a,c){const m=V(t.geometry);if(null==m)return null;if(0===m.rings.length||!m.rings.some((t=>t.length>0)))return this._logGeometryValidationWarnings(m.rings,"rings","ExtrudeSymbol3DLayer"),null;const p=W(m,this._context.elevationProvider,this._context.renderCoordsHelper,a);this._logGeometryCreationWarnings(p,m.rings,"rings","ExtrudeSymbol3DLayer");const h=G(m);if(null==h)return null;const g=new Array,d=new Array,u=j(),f=l(),y=x(),b=this._context.renderCoordsHelper.viewingMode===L.Global;b||this._context.renderCoordsHelper.worldUpAtPosition(null,y),S(m.spatialReference,[h.x,h.y,0],f,this._context.renderCoordsHelper.spatialReference);const _=l();n(_,f);const v=i();o(v,_);const{polygons:M,mapPositions:I,position:A}=p,B=new Map,T=this._materials[It.Main];for(const o of M){const t=o.count;if(this._context.clippingExtent&&(P(o.mapPositions,u),!E(u,this._context.clippingExtent)))continue;const i=s(o.mapPositions,o.holeIndices,3);if(0===i.length)continue;const n=i.length,a=6*t,l=O(a+n),m=O(n),p=w(3*a),h=w(3*a),x=w(3*a),S=w(a);nt(A,I,i,o,p,x,h,S,l,m,this._getExtrusionSize(e),y,b),C(p,p,_);const j=this._context.stage.renderView.getObjectAndLayerIdColor({graphicUid:c,layerUid:this._context.layer.uid}),v=new At(p,x,Y(h),S),M=it(T,l,l.length-m.length,v,r,j),L=t,z=t,D=2*o.count,R=new Lt(L,z,D,n/3);_t(M,R,f),B.set(M,R),g.push(M,it(this._materials[It.Bottom],m,0,v,r,j)),d.push(v.heights)}if(0===g.length)return null;const U=new tt({geometries:g,layerUid:this._context.layer.uid,graphicUid:c,isElevationSource:!0});U.transformation=f;const N=F(this.symbolLayer,{opacity:this._getLayerOpacity()}),k=N?new D(this._materials[It.Main],N,this._context.slicePlaneEnabled):null,H=new R(this,U,g,null,null,((t,e,r,s,o)=>bt(t,e,r,s,o,d,B)),a,k);return H.alignedSampledElevation=p.sampledElevation,H.needsElevationUpdates=z(a.mode),H}}function it(t,e,r,s,o,i){const n=v(e.length),a=[[et.POSITION,new Z(s.positions,e,3,!0)],[et.NORMALCOMPRESSED,new Z(s.normals,e,2,!0)],[et.COLOR,new Z(o,n,4,!0)]];return new Q(t,a,s.elevation,K.Mesh,i,r)}function nt(t,e,r,s,o,i,n,a,l,c,m,p,h){{const g=r.length/3,d=2*s.count;at(t,e,s.index,s.count,r,0,g,o,i,n,a,l,c,d,m,p,h)}{let t=0,e=2*s.count,r=0;const c=s.pathLengths[0];mt(o,i,a,n,t,c,s.count,e,l,r,m),e+=4*c,r+=2*c,t+=c;for(let p=1;p<s.pathLengths.length;++p){const c=s.pathLengths[p];mt(o,i,a,n,t,c,s.count,e,l,r,m),e+=4*c,r+=2*c,t+=c}}}function at(t,e,r,s,o,i,n,a,l,c,h,g,d,u,f,y,b){m(St,y);{const o=f>0?1:-1;let i=3*r,n=0,m=3*n,g=s,d=3*g;for(let r=0;r<s;++r){const r=t[i],s=t[i+1],u=t[i+2];b&&(St[0]=r,St[1]=s,St[2]=u,p(St,St)),a[m+0]=r,a[m+1]=s,a[m+2]=u;const y=e[i+0],_=e[i+1],x=e[i+2];l[m+0]=y,l[m+1]=_,l[m+2]=x,c[m+0]=-o*St[0],c[m+1]=-o*St[1],c[m+2]=-o*St[2],h[n]=0,a[d+0]=r+f*St[0],a[d+1]=s+f*St[1],a[d+2]=u+f*St[2],l[d+0]=y,l[d+1]=_,l[d+2]=x,h[g]=f,m+=3,d+=3,i+=3,n+=1,g+=1}}{let t=3*i,e=0,r=3*u;const a=f<0?Et:Pt,l=f<0?Pt:Et;for(let i=0;i<n;++i)d[e]=o[t+a[0]],d[e+1]=o[t+a[1]],d[e+2]=o[t+a[2]],g[r]=o[t+l[0]]+s,g[r+1]=o[t+l[1]]+s,g[r+2]=o[t+l[2]]+s,e+=3,r+=3,t+=3}}function lt(t,e,r,s,o,i,n){s[i]=s[n],n*=3,t[i*=3]=t[n],t[i+1]=t[n+1],t[i+2]=t[n+2],e[i]=e[n],e[i+1]=e[n+1],e[i+2]=e[n+2],r[i]=o[0],r[i+1]=o[1],r[i+2]=o[2]}const ct=x();function mt(t,e,r,s,o,i,n,a,l,c,m){let p=o,h=o+1,g=o+n,d=o+n+1,u=a,f=a+1,y=a+2*i,b=a+2*i+1;m<0&&(p=o+n+1,d=o);let _=3*c;for(let x=0;x<i;++x)x===i-1&&(h=o,m>0?d=o+n:p=o+n),ft(t,p,h,g,ct),lt(t,e,s,r,ct,u,p),lt(t,e,s,r,ct,f,h),lt(t,e,s,r,ct,y,g),lt(t,e,s,r,ct,b,d),l[_]=u,l[_+1]=y,l[_+2]=b,l[_+3]=u,l[_+4]=b,l[_+5]=f,_+=6,p++,h++,g++,d++,u+=2,f+=2,y+=2,b+=2}const pt=x(),ht=x(),gt=x(),dt=x(),ut=x();function ft(t,e,r,s,o){e*=3,r*=3,s*=3,h(pt,t[e++],t[e++],t[e++]),h(ht,t[r++],t[r++],t[r++]),h(gt,t[s++],t[s++],t[s++]),g(dt,ht,pt),g(ut,gt,pt),d(o,ut,dt),p(o,o)}const yt=x();function bt(t,e,r,s,o,i,n){const c=t.stageObject,m=c.geometries,p=m.length,g="absolute-height"!==e.mode;let d=0;const f=c.transformation,y=a(l(),f);for(let a=0;a<p;a+=2){const t=m[a];if(!X(t))continue;const e=t.getMutableAttribute(et.POSITION).data,l=i[a/2],p=new H(t.mapPositions),b=e.length/3;let _=!1,x=0;{let t=0;for(let i=0;i<b;i++){yt[0]=e[t],yt[1]=e[t+1],yt[2]=e[t+2],s(p,jt),g&&(x+=jt.sampledElevation),k.TESTS_DISABLE_OPTIMIZATIONS?(h(xt,p.array[p.offset],p.array[p.offset+1],jt.z+l[t/3]),null!=r&&o.toRenderCoords(xt,r,xt),u(xt,xt,y)):(h(xt,e[t],e[t+1],e[t+2]),u(xt,xt,f),o.setAltitude(xt,jt.z+l[t/3]),u(xt,xt,y)),e[t]=xt[0],e[t+1]=xt[1],e[t+2]=xt[2];const i=wt/o.unitInMeters;(Math.abs(yt[0]-e[t])>=i||Math.abs(yt[1]-e[t+1])>=i||Math.abs(yt[2]-e[t+2])>=i)&&(_=!0),p.offset+=3,t+=3}}if(_){const e=n.get(t);e&&_t(t,e,f),c.geometryVertexAttributeUpdated(m[a],et.NORMALCOMPRESSED),t.invalidateBoundingInfo(),c.geometryVertexAttributeUpdated(m[a],et.POSITION),m[a+1].invalidateBoundingInfo(),c.geometryVertexAttributeUpdated(m[a+1],et.POSITION)}d+=x/b}return d/p}function _t(t,e,r){const s=t.getMutableAttribute(et.POSITION),o=t.getMutableAttribute(et.NORMALCOMPRESSED).data,{topVertexStart:i,topVertexCount:n,topFaceStart:a,topFaceCount:l}=e,c=s.data,m=n,g=t.attributes.get(et.POSITION).indices,y=a+l,b=i+n,_=w(3*m);for(let p=0;p<m;++p){const t=3*p;_[t+0]=0,_[t+1]=0,_[t+2]=0}const x=Ot,S=vt,j=Ct,P=Mt,E=St;for(let w=a;w<y;++w){const t=3*w;for(let e=0;e<3;++e){const s=g[t+e];P[e]=s;const o=3*s;h(xt,c[o+0],c[o+1],c[o+2]),u(x[e],xt,r)}f(S,x[1],x[0]),f(j,x[2],x[0]),d(E,S,j),p(E,E);for(let e=0;e<3;++e){const t=3*(P[e]-i);_[t+0]+=E[0],_[t+1]+=E[1],_[t+2]+=E[2]}}for(let p=i;p<b;++p){const t=3*(p-i),e=_[t+0],r=_[t+1],s=_[t+2],n=Math.sqrt(e*e+r*r+s*s);$(o,p,e/n,r/n,s/n)}}const xt=x(),St=x(),jt=new B,Pt=[0,2,1],Et=[0,1,2],wt=.01,Ot=[x(),x(),x()],vt=x(),Ct=x(),Mt=[0,0,0];var It;!function(t){t[t.Main=0]="Main",t[t.Bottom=1]="Bottom"}(It||(It={}));class At{constructor(t,e,r,s){this.positions=t,this.elevation=e,this.normals=r,this.heights=s}}class Lt{constructor(t,e,r,s){this.topVertexStart=t,this.topVertexCount=e,this.topFaceStart=r,this.topFaceCount=s}}export{ot as Graphics3DExtrudeSymbolLayer,nt as extrudePolygon};