UNPKG

@arcgis/core

Version:

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

3 lines (2 loc) • 11.9 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{clamp as e,deg2rad as t}from"../../../../core/mathUtils.js";import{fromMat4 as i}from"../../../../core/libs/gl-matrix-2/math/mat3.js";import{create as s}from"../../../../core/libs/gl-matrix-2/factories/mat3f64.js";import{invert as r}from"../../../../core/libs/gl-matrix-2/math/mat4.js";import{create as a}from"../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{set as n,rotate as o}from"../../../../core/libs/gl-matrix-2/math/vec2.js";import{fromValues as l,create as c}from"../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{set as u,transformMat4 as f,normalize as p,subtract as h,scale as d,transformMat3 as m,scaleAndAdd as g,copy as b,length as v,distance as S,sub as x,dot as O}from"../../../../core/libs/gl-matrix-2/math/vec3.js";import{create as y,fromValues as z}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{fromArray as _,freeze as P,create as j}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{create as D}from"../../../../geometry/support/aaBoundingRect.js";import{BufferViewVec4u8 as A}from"../../../../geometry/support/buffer/BufferView.js";import{evaluateModelTransformScale as C}from"../../layers/support/FastSymbolUpdates.js";import{debugFlags as M}from"../../support/debugFlags.js";import{isColorHighlightOrOLID as V,isColor as R}from"../core/shaderLibrary/ShaderOutput.js";import{HUDVerticalPixelOffset as w}from"../core/shaderLibrary/hud/HUD.glsl.js";import{GLTextureMaterialBindParameters as F,GLTextureMaterial as T}from"../lib/GLTextureMaterial.js";import{Material as L}from"../lib/Material.js";import{SeparateScreenSizePerspectiveEvaluators as U}from"../lib/screenSizePerspectiveUtils.js";import{assert as B}from"../lib/Util.js";import{writePosition as E,writeNormal as I,writeColor as W,writeBufferVec2 as H,writeBufferFloat as G,writeBufferVec4 as N,writeBufferVec4Zeros as q,writeOlidColor as X}from"./internal/bufferWriterUtils.js";import{verticalOffsetAtDistance as Y}from"./internal/MaterialUtil.js";import{c as k,f as J}from"../../../../chunks/HUDMaterial.glsl.js";import{getInstanceLayout as K,baseLayout as Q,HUDMaterialTechnique as Z}from"../shaders/HUDMaterialTechnique.js";import{HUDMaterialTechniqueConfiguration as $}from"../shaders/HUDMaterialTechniqueConfiguration.js";import{alphaCutoff as ee}from"../../../../webscene/support/AlphaCutoff.js";class te extends L{constructor(e,t,i=!1){super(e,_e),this.produces=new Map([[14,e=>V(e)&&!this.parameters.drawAsLabel&&!this._configuration.transparentOccluded],[15,e=>V(e)&&!this.parameters.drawAsLabel&&this._configuration.transparentOccluded],[16,e=>V(e)&&this.parameters.drawAsLabel],[13,()=>this.parameters.useVisibilityPixel],[20,e=>this.parameters.draped&&V(e)]]),this._visible=!0,this._configuration=new $(t,i)}getConfiguration(e,t){const i=this.parameters.draped;return super.getConfiguration(e,t,this._configuration),this._configuration.hasSlicePlane=this.parameters.hasSlicePlane,this._configuration.hasVerticalOffset=!!this.parameters.verticalOffset,this._configuration.hasScreenSizePerspective=!!this.parameters.screenSizePerspective,this._configuration.screenCenterOffsetUnitsEnabled="screen"===this.parameters.centerOffsetUnits,this._configuration.hasPolygonOffset=this.parameters.polygonOffset,this._configuration.draped=i,this._configuration.useVisibilityPixel=this.parameters.useVisibilityPixel,this._configuration.pixelSnappingEnabled=this.parameters.pixelSnappingEnabled,this._configuration.signedDistanceFieldEnabled=this.parameters.textureIsSignedDistanceField,this._configuration.sampleSignedDistanceFieldTexelCenter=this.parameters.sampleSignedDistanceFieldTexelCenter,this._configuration.hasRotation=this.parameters.hasRotation,this._configuration.hasVVSize=!!this.parameters.vvSize,this._configuration.hasVVColor=!!this.parameters.vvColor,this._configuration.occlusionPass=13===t.slot,this._configuration.occludedFragmentFade=!i&&!!this.parameters.occludedFragmentOpacity,this._configuration.isFocused=this.parameters.isFocused,this._configuration.depthTestEnabled=this.parameters.depthEnabled||13===t.slot,R(e)&&(this._configuration.debugDrawLabelBorder=!!M.LABELS_SHOW_BORDER),this._configuration.terrainDepthTest=t.terrainDepthTest,this._configuration.cullAboveTerrain=t.cullAboveTerrain,this._configuration.hasOcclusionTexture=this._configuration.transparentOccluded&&0!==t.oitPass,this._configuration}intersect(e,t,s,a,n,o){const{options:{selectionMode:l,hud:c,excludeLabels:x},point:O,camera:z}=s,{parameters:P}=this;if(!l||!c||x&&P.isLabel||!e.visible||!O||!z)return;const j=e.attributes.get("featureAttribute"),D=null==j?null:_(j.data,ve),{scaleX:A,scaleY:C}=je(D,P,z.pixelRatio),M=e.attributes.get("position"),V=e.attributes.get("size"),R=e.attributes.get("normal"),w=e.attributes.get("rotation"),F=e.attributes.get("centerOffsetAndDistance");B(M.size>=3);const T=k(P),L="screen"===this.parameters.centerOffsetUnits;for(let _=0;_<M.data.length/M.size;_++){const e=_*M.size;u(oe,M.data[e],M.data[e+1],M.data[e+2]),f(oe,oe,t),f(oe,oe,z.viewMatrix);const a=_*F.size;if(u(ge,F.data[a],F.data[a+1],F.data[a+2]),!L&&(oe[0]+=ge[0],oe[1]+=ge[1],0!==ge[2])){const e=ge[2];p(ge,oe),h(oe,oe,d(ge,ge,e))}const n=_*R.size;u(le,R.data[n],R.data[n+1],R.data[n+2]),m(le,le,i(de,t));const{normal:l,cosAngle:c}=re(le,z,Se),x=Ae(this.parameters,oe,c,z,ne);if(g(oe,oe,l,x),z.applyProjection(oe,ce),ce[0]>-1){L&&(ge[0]||ge[1])&&(ce[0]+=ge[0]*z.pixelRatio,0!==ge[1]&&(ce[1]+=ne.alignmentEvaluator.apply(ge[1])*z.pixelRatio),z.unapplyProjection(ce,oe)),ce[0]+=this.parameters.screenOffset[0]*z.pixelRatio,ce[1]+=this.parameters.screenOffset[1]*z.pixelRatio,ce[0]=Math.floor(ce[0]),ce[1]=Math.floor(ce[1]);const e=_*V.size;ye[0]=V.data[e],ye[1]=V.data[e+1],ne.evaluator.applyVec2(ye,ye);const t=xe*z.pixelRatio;let i=0;if(P.textureIsSignedDistanceField){i=Math.min(P.outlineSize,.5*ye[0])*z.pixelRatio/2}ye[0]*=A,ye[1]*=C;const a=_*w.size,n=P.rotation+w.data[a];if(ae(O,ce[0],ce[1],ye,t,i,n,P,T)){const e=s.ray;if(f(fe,oe,r(me,z.viewMatrix)),ce[0]=O[0],ce[1]=O[1],z.unprojectFromRenderScreen(ce,oe)){const t=y();b(t,e.direction);const i=1/v(t);d(t,t,i);o(S(e.origin,oe)*i,t,-1,fe)}}}}}intersectDraped(e,t,i,s,r){const a=e.attributes.get("position"),n=e.attributes.get("size"),o=e.attributes.get("rotation"),l=this.parameters,c=k(l),u=e.attributes.get("featureAttribute"),f=null==u?null:_(u.data,ve),{scaleX:p,scaleY:h}=je(f,l,e.screenToWorldRatio),d=Oe*e.screenToWorldRatio;for(let m=0;m<a.data.length/a.size;m++){const t=m*a.size,u=a.data[t],f=a.data[t+1],g=m*n.size;ye[0]=n.data[g],ye[1]=n.data[g+1];let b=0;if(l.textureIsSignedDistanceField){b=Math.min(l.outlineSize,.5*ye[0])*e.screenToWorldRatio/2}ye[0]*=p,ye[1]*=h;const v=m*o.size,S=l.rotation+o.data[v];ae(i,u,f,ye,d,b,S,l,c)&&s(r.distance,r.normal,-1)}}createBufferWriter(){return new Pe}applyShaderOffsets(e,t,s,r,a,n,o){m(ue,s,i(de,r));const l=re(ue,n,Se),c=De(v(t),n),u=Ae(this.parameters,t,l.cosAngle,n,o);g(t,t,l.normal,u+c),g(e,e,ue,u+c);const f=a[3]+u;this._applyPolygonOffsetView(t,l,f,n,t),this._applyCenterOffsetView(t,a,t)}applyShaderOffsetsNDC(e,t,i,s,r){return this._applyCenterOffsetNDC(e,t,i,s),null!=r&&b(r,s),this._applyPolygonOffsetNDC(s,t,i,s),s}_applyPolygonOffsetView(t,i,s,r,a){const n=r.aboveGround?1:-1;let o=Math.sign(s);0===o&&(o=n);const l=n*o;if(this.parameters.shaderPolygonOffset<=0)return b(a,t);const c=e(Math.abs(i.cosAngle),.01,1),u=1-Math.sqrt(1-c*c)/c/r.viewport[2];return d(a,t,l>0?u:1/u),a}_applyCenterOffsetView(e,t,i){const s="screen"!==this.parameters.centerOffsetUnits;return i!==e&&b(i,e),s&&(i[0]+=t[0],i[1]+=t[1],t[2]&&(p(le,i),x(i,i,d(le,le,t[2])))),i}_applyCenterOffsetNDC(e,t,i,s){const r="screen"!==this.parameters.centerOffsetUnits;return s!==e&&b(s,e),r||(s[0]+=t[0]/i.fullWidth*2,s[1]+=t[1]/i.fullHeight*2),s}_applyPolygonOffsetNDC(e,t,i,s){const r=this.parameters.shaderPolygonOffset;if(e!==s&&b(s,e),r){const e=i.aboveGround?1:-1,a=e*Math.sign(t[3]);s[2]-=(a||e)*r}return s}set visible(e){this._visible=e}get visible(){const{color:e,outlineSize:t,outlineColor:i}=this.parameters,s=e[3]>=ee||t>=ee&&i[3]>=ee;return this._visible&&s}createGLMaterial(e){return new ie(e)}calculateRelativeScreenBounds(e,t,i=D()){return se(this.parameters,e,t,i),i[2]=i[0]+e[0],i[3]=i[1]+e[1],i}}class ie extends T{constructor(e){super({...e,...e.material.parameters})}beginSlot(e){return this.updateTexture(this._material.parameters.textureId),this._material.setParameters(this.textureBindParameters),this.getTechnique(Z,e)}}function se(e,t,i,s){s[0]=e.anchorPosition[0]*-t[0]+e.screenOffset[0]*i,s[1]=e.anchorPosition[1]*-t[1]+e.screenOffset[1]*i}function re(e,t,i){return f(i.normal,e,t.viewInverseTransposeMatrix),i.cosAngle=O(i.normal,ze),i}function ae(e,i,s,r,a,l,c,u,f){let p=i-a-r[0]*f[0],h=p+r[0]+2*a,d=s-a-r[1]*f[1],m=d+r[1]+2*a;const g=u.distanceFieldBoundingBox;return u.textureIsSignedDistanceField&&null!=g&&(p+=r[0]*g[0],d+=r[1]*g[1],h-=r[0]*(1-g[2]),m-=r[1]*(1-g[3]),p-=l,h+=l,d-=l,m+=l),n(he,i,s),o(pe,e,he,t(c)),pe[0]>p&&pe[0]<h&&pe[1]>d&&pe[1]<m}const ne=new U,oe=y(),le=y(),ce=j(),ue=y(),fe=y(),pe=c(),he=c(),de=s(),me=a(),ge=y(),be=y(),ve=j(),Se={normal:y(),cosAngle:0},xe=1,Oe=2,ye=l(0,0),ze=z(0,0,1);class _e extends F{constructor(){super(...arguments),this.renderOccluded=1,this.testsTransparentRenderOrder=0,this.isDecoration=!1,this.color=P(1,1,1,1),this.polygonOffset=!1,this.anchorPosition=l(.5,.5),this.screenOffset=[0,0],this.shaderPolygonOffset=1e-5,this.textureIsSignedDistanceField=!1,this.sampleSignedDistanceFieldTexelCenter=!1,this.outlineColor=P(1,1,1,1),this.outlineSize=0,this.distanceFieldBoundingBox=j(),this.rotation=0,this.hasRotation=!1,this.vvSizeEnabled=!1,this.vvSize=null,this.vvColor=null,this.vvOpacity=null,this.vvSymbolAnchor=null,this.vvSymbolRotationMatrix=null,this.hasSlicePlane=!1,this.pixelSnappingEnabled=!0,this.useVisibilityPixel=!0,this.occludedVisibilityMode="hidden",this.centerOffsetUnits="world",this.drawAsLabel=!1,this.depthEnabled=!0,this.isFocused=!0,this.draped=!1,this.isLabel=!1}get hasVVSize(){return!!this.vvSize}get hasVVColor(){return!!this.vvColor}get hasVVOpacity(){return!!this.vvOpacity}}class Pe{constructor(){this.layout=K(),this.baseInstanceLayout=Q}elementCount(e){return e.get("position").indices.length}elementCountBaseInstance(e){return e.get("uv0").indices.length}write(e,t,i,s,r,a){const{position:n,normal:o,color:l,size:c,rotation:u,centerOffsetAndDistance:f,featureAttribute:p,uvi:h}=r;E(i.get("position"),e,n,a),I(i.get("normal"),t,o,a);const d=i.get("position").indices.length;let m=0,g=0,b=J,v=J;const S=i.get("uvi")?.data;S&&S.length>=4&&(m=S[0],g=S[1],b=S[2],v=S[3]);for(let x=0;x<d;++x){const e=a+x;h.setValues(e,m,g,b,v)}if(W(i.get("color"),4,l,a),H(i.get("size"),c,a),G(i.get("rotation"),u,a),i.get("centerOffsetAndDistance")?N(i.get("centerOffsetAndDistance"),f,a):q(f,a,d),i.get("featureAttribute")?N(i.get("featureAttribute"),p,a):q(p,a,d),null!=s){const e=i.get("position")?.indices;if(e){const t=e.length,i=r.getField("olidColor",A);X(s,i,t,a)}}return{numVerticesPerItem:1,numItems:d}}writeBaseInstance(e,t){const{uv0:i}=t;H(e.get("uv0"),i,0)}}function je(e,t,i){return null==e||null==t.vvSize?{scaleX:i,scaleY:i}:(C(be,t,e),{scaleX:be[0]*i,scaleY:be[1]*i})}function De(e,t){const i=t.computeRenderPixelSizeAtDist(e)*w;return(t.aboveGround?1:-1)*i}function Ae(e,t,i,s,r){if(!e.verticalOffset?.screenLength){const s=v(t);return r.update(i,s,e.screenSizePerspective,e.screenSizePerspectiveMinPixelReferenceSize,e.screenSizePerspectiveAlignment,null),0}const a=v(t),n=e.screenSizePerspectiveAlignment??e.screenSizePerspective,o=Y(s,a,e.verticalOffset,i,n,e.screenSizePerspectiveMinPixelReferenceSize);return r.update(i,a,e.screenSizePerspective,e.screenSizePerspectiveMinPixelReferenceSize,e.screenSizePerspectiveAlignment,null),o}export{te as HUDMaterial,_e as Parameters};