UNPKG

@arcgis/core

Version:

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

6 lines (5 loc) • 13.3 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import{clamp as e,deg2rad as t}from"../../../../core/mathUtils.js";import{fromMat4 as s}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 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 o,rotate as n}from"../../../../core/libs/gl-matrix-2/math/vec2.js";import{create as c,fromValues as l}from"../../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{i as f,t as h,n as p,d as u,h as m,c as d,l as g,j as O,g as S,q as T,f as b}from"../../../../chunks/vec32.js";import{create as v,fromValues as A}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{fromArray as E,create as _,freeze as I}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{isMat4 as R}from"../../../../core/libs/gl-matrix-2/types/mat4.js";import{create as x}from"../../../../geometry/support/aaBoundingRect.js";import{BufferViewVec4u8 as C}from"../../../../geometry/support/buffer/BufferView.js";import{evaluateModelTransformScale as P}from"../../layers/support/FastSymbolUpdates.js";import{debugFlags as D}from"../../support/debugFlags.js";import{newLayout as y}from"../../support/buffer/InterleavedLayout.js";import{isColorEmissionHighlightOrOID as F,isColorOrColorEmission as j}from"../core/shaderLibrary/ShaderOutput.js";import{HUDVerticalPixelOffset as L}from"../core/shaderLibrary/hud/HUD.glsl.js";import{olidEnabled as N}from"../effects/geometry/olidUtils.js";import{GLTextureMaterial as z,GLTextureMaterialBindParameters as U}from"../lib/GLTextureMaterial.js";import{Material as M,RenderOccludedFlag as w}from"../lib/Material.js";import{RenderSlot as B}from"../lib/RenderSlot.js";import{applyScaleFactor as V,applyPrecomputedScaleFactor as q,precomputeScaleFactor as G}from"../lib/screenSizePerspectiveUtils.js";import{assert as H}from"../lib/Util.js";import{VertexAttribute as W}from"../lib/VertexAttribute.js";import{ScaleInfo as X}from"./ScaleInfo.js";import{writePosition as Y,writeNormal as Z,writeColor as k,writeBufferFloat as J,writeBufferVec4 as K,writeBufferVec4Zeros as Q,writeObjectAndLayerIdColor as $}from"./internal/bufferWriterUtils.js";import{verticalOffsetAtDistance as ee}from"./internal/MaterialUtil.js";import{c as te}from"../../../../chunks/HUDMaterial.glsl.js";import{HUDMaterialTechnique as se}from"../shaders/HUDMaterialTechnique.js";import{HUDMaterialTechniqueConfiguration as ie}from"../shaders/HUDMaterialTechniqueConfiguration.js";import{alphaCutoff as re}from"../../../../webscene/support/AlphaCutoff.js";class ae extends M{constructor(e,t){super(e,De),this.produces=new Map([[B.HUD_MATERIAL,e=>F(e)&&!this.parameters.drawAsLabel],[B.LABEL_MATERIAL,e=>F(e)&&this.parameters.drawAsLabel],[B.OCCLUSION_PIXELS,()=>this.parameters.occlusionTest],[B.DRAPED_MATERIAL,e=>this.parameters.draped&&F(e)]]),this._visible=!0,this._configuration=new ie(t)}getConfiguration(e,t){return this._configuration.output=e,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=this.parameters.draped,this._configuration.occlusionTestEnabled=this.parameters.occlusionTest,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.vvSize=!!this.parameters.vvSize,this._configuration.vvColor=!!this.parameters.vvColor,this._configuration.occlusionPass=t.slot===B.OCCLUSION_PIXELS,this._configuration.occludedFragmentFade=this.parameters.occludedFragmentFade,this._configuration.horizonCullingEnabled=this.parameters.horizonCullingEnabled,this._configuration.isFocused=this.parameters.isFocused,this._configuration.depthTestEnabled=this.parameters.depthEnabled||t.slot===B.OCCLUSION_PIXELS,j(e)&&(this._configuration.debugDrawLabelBorder=!!D.LABELS_SHOW_BORDER),this._configuration.oitPass=t.oitPass,this._configuration.terrainDepthTest=t.terrainDepthTest,this._configuration.cullAboveTerrain=t.cullAboveTerrain,this._configuration}intersect(e,t,i,a,o,n){const{options:{selectionMode:c,hud:l,excludeLabels:S},point:T,camera:b}=i,{parameters:A}=this;if(!c||!l||S&&A.isLabel||!e.visible||!T)return;const{scaleX:E,scaleY:_}=this._getScreenScale(e,b.pixelRatio);s(Te,t),e.attributes.has(W.FEATUREATTRIBUTE)&&le(Te);const I=e.attributes.get(W.POSITION),R=e.attributes.get(W.SIZE),x=e.attributes.get(W.NORMAL),C=e.attributes.get(W.ROTATION),P=e.attributes.get(W.CENTEROFFSETANDDISTANCE);H(I.size>=3);const D=te(A),y="screen"===this.parameters.centerOffsetUnits;for(let s=0;s<I.data.length/I.size;s++){const e=s*I.size;f(pe,I.data[e],I.data[e+1],I.data[e+2]),h(pe,pe,t),h(pe,pe,b.viewMatrix);const a=s*P.size;if(f(Ae,P.data[a],P.data[a+1],P.data[a+2]),!y&&(pe[0]+=Ae[0],pe[1]+=Ae[1],0!==Ae[2])){const e=Ae[2];p(Ae,pe),u(pe,pe,m(Ae,Ae,e))}const o=s*x.size;if(f(ue,x.data[o],x.data[o+1],x.data[o+2]),ce(ue,Te,b,Ie),this._applyVerticalOffsetTransformationView(pe,Ie,b,he),b.applyProjection(pe,me),me[0]>-1){y&&(Ae[0]||Ae[1])&&(me[0]+=Ae[0]*b.pixelRatio,0!==Ae[1]&&(me[1]+=V(Ae[1],he.factorAlignment)*b.pixelRatio),b.unapplyProjection(me,pe)),me[0]+=this.parameters.screenOffset[0]*b.pixelRatio,me[1]+=this.parameters.screenOffset[1]*b.pixelRatio,me[0]=Math.floor(me[0]),me[1]=Math.floor(me[1]);const e=s*R.size;Ce[0]=R.data[e],Ce[1]=R.data[e+1],q(Ce,he.factor,Ce);const t=Re*b.pixelRatio;let a=0;if(A.textureIsSignedDistanceField){a=Math.min(A.outlineSize,.5*Ce[0])*b.pixelRatio/2}Ce[0]*=E,Ce[1]*=_;const o=s*C.size,c=A.rotation+C.data[o];if(fe(T,me[0],me[1],Ce,t,a,c,A,D)){const e=i.ray;if(h(ge,pe,r(ve,b.viewMatrix)),me[0]=T[0],me[1]=T[1],b.unprojectFromRenderScreen(me,pe)){const t=v();d(t,e.direction);const s=1/g(t);m(t,t,s);n(O(e.origin,pe)*s,t,-1,!0,1,ge)}}}}}intersectDraped(e,t,s,i,r,a){const o=e.attributes.get(W.POSITION),n=e.attributes.get(W.SIZE),c=e.attributes.get(W.ROTATION),l=this.parameters,f=te(l),{scaleX:h,scaleY:p}=this._getScreenScale(e,e.screenToWorldRatio),u=xe*e.screenToWorldRatio;for(let m=0;m<o.data.length/o.size;m++){const t=m*o.size,s=o.data[t],d=o.data[t+1],g=m*n.size;Ce[0]=n.data[g],Ce[1]=n.data[g+1];let O=0;if(l.textureIsSignedDistanceField){O=Math.min(l.outlineSize,.5*Ce[0])*e.screenToWorldRatio/2}Ce[0]*=h,Ce[1]*=p;const S=m*c.size,T=l.rotation+c.data[S];fe(i,s,d,Ce,u,O,T,l,f)&&r(a.dist,a.normal,-1,!1)}}createBufferWriter(){return new je}_updateScaleInfo(e,t,s){const i=this.parameters;null!=i.screenSizePerspective?G(s,t,i.screenSizePerspective,e.factor):(e.factor.scale=1,e.factor.factor=0,e.factor.minScaleFactor=0),null!=i.screenSizePerspectiveAlignment?G(s,t,i.screenSizePerspectiveAlignment,e.factorAlignment):(e.factorAlignment.factor=e.factor.factor,e.factorAlignment.scale=e.factor.scale,e.factorAlignment.minScaleFactor=e.factor.minScaleFactor)}applyShaderOffsetsView(e,t,s,i,r,a,o){const n=ce(t,s,r,Ie);return this._applyVerticalGroundOffsetView(e,n,r,o),this._applyVerticalOffsetTransformationView(o,n,r,a),this._applyPolygonOffsetView(o,n,i[3],r,o),this._applyCenterOffsetView(o,i,o),o}applyShaderOffsetsNDC(e,t,s,i,r){return this._applyCenterOffsetNDC(e,t,s,i),null!=r&&d(r,i),this._applyPolygonOffsetNDC(i,t,s,i),i}_applyPolygonOffsetView(t,s,i,r,a){const o=r.aboveGround?1:-1;let n=Math.sign(i);0===n&&(n=o);const c=o*n;if(this.parameters.shaderPolygonOffset<=0)return d(a,t);const l=e(Math.abs(s.cosAngle),.01,1),f=1-Math.sqrt(1-l*l)/l/r.viewport[2];return m(a,t,c>0?f:1/f),a}_applyVerticalGroundOffsetView(e,t,s,i){const r=g(e),a=s.aboveGround?1:-1,o=s.computeRenderPixelSizeAtDist(r)*L,n=m(pe,t.normal,a*o);return S(i,e,n),i}_applyVerticalOffsetTransformationView(e,t,s,i){const r=this.parameters;if(!r.verticalOffset?.screenLength){if(r.screenSizePerspective||r.screenSizePerspectiveAlignment){const s=g(e);this._updateScaleInfo(i,s,t.cosAngle)}else i.factor.scale=1,i.factorAlignment.scale=1;return e}const a=g(e),o=r.screenSizePerspectiveAlignment??r.screenSizePerspective,n=ee(s,a,r.verticalOffset,t.cosAngle,o);return this._updateScaleInfo(i,a,t.cosAngle),m(t.normal,t.normal,n),S(e,e,t.normal)}_applyCenterOffsetView(e,t,s){const i="screen"!==this.parameters.centerOffsetUnits;return s!==e&&d(s,e),i&&(s[0]+=t[0],s[1]+=t[1],t[2]&&(p(ue,s),S(s,s,m(ue,ue,t[2])))),s}_applyCenterOffsetNDC(e,t,s,i){const r="screen"!==this.parameters.centerOffsetUnits;return i!==e&&d(i,e),r||(i[0]+=t[0]/s.fullWidth*2,i[1]+=t[1]/s.fullHeight*2),i}_applyPolygonOffsetNDC(e,t,s,i){const r=this.parameters.shaderPolygonOffset;if(e!==i&&d(i,e),r){const e=s.aboveGround?1:-1,a=e*Math.sign(t[3]);i[2]-=(a||e)*r}return i}set visible(e){this._visible=e}get visible(){const{color:e,outlineSize:t,outlineColor:s}=this.parameters,i=e[3]>=re||t>=re&&s[3]>=re;return this._visible&&i}createGLMaterial(e){return new oe(e)}calculateRelativeScreenBounds(e,t,s=x()){return ne(this.parameters,e,t,s),s[2]=s[0]+e[0],s[3]=s[1]+e[1],s}_getScreenScale(e,t){const s=e.attributes.get(W.FEATUREATTRIBUTE);if(null==s)return{scaleX:t,scaleY:t};const i=E(s.data,_e);return P(Ee,this.parameters,i),{scaleX:Ee[0]*t,scaleY:Ee[1]*t}}}class oe extends z{constructor(e){super({...e,...e.material.parameters})}beginSlot(e){return this.updateTexture(this._material.parameters.textureId),this._material.setParameters(this.textureBindParameters),this.getTechnique(se,e)}}function ne(e,t,s,i){i[0]=e.anchorPosition[0]*-t[0]+e.screenOffset[0]*s,i[1]=e.anchorPosition[1]*-t[1]+e.screenOffset[1]*s}function ce(e,t,i,r){return R(t)&&(t=s(be,t)),T(r.normal,e,t),h(r.normal,r.normal,i.viewInverseTransposeMatrix),r.cosAngle=b(de,Pe),r}function le(e){const t=e[0],s=e[1],i=e[2],r=e[3],a=e[4],o=e[5],n=e[6],c=e[7],l=e[8],f=1/Math.sqrt(t*t+s*s+i*i),h=1/Math.sqrt(r*r+a*a+o*o),p=1/Math.sqrt(n*n+c*c+l*l);return e[0]=t*f,e[1]=s*f,e[2]=i*f,e[3]=r*h,e[4]=a*h,e[5]=o*h,e[6]=n*p,e[7]=c*p,e[8]=l*p,e}function fe(e,s,i,r,a,c,l,f,h){let p=s-a-r[0]*h[0],u=p+r[0]+2*a,m=i-a-r[1]*h[1],d=m+r[1]+2*a;const g=f.distanceFieldBoundingBox;return f.textureIsSignedDistanceField&&null!=g&&(p+=r[0]*g[0],m+=r[1]*g[1],u-=r[0]*(1-g[2]),d-=r[1]*(1-g[3]),p-=c,u+=c,m-=c,d+=c),o(Se,s,i),n(Oe,e,Se,t(l)),Oe[0]>p&&Oe[0]<u&&Oe[1]>m&&Oe[1]<d}const he=new X,pe=v(),ue=v(),me=_(),de=v(),ge=v(),Oe=c(),Se=c(),Te=i(),be=i(),ve=a(),Ae=v(),Ee=v(),_e=_(),Ie={normal:de,cosAngle:0},Re=1,xe=2,Ce=[0,0],Pe=A(0,0,1);class De extends U{constructor(){super(...arguments),this.renderOccluded=w.Occlude,this.isDecoration=!1,this.color=I(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=I(1,1,1,1),this.outlineSize=0,this.distanceFieldBoundingBox=_(),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.occlusionTest=!0,this.occludedFragmentFade=!1,this.horizonCullingEnabled=!1,this.centerOffsetUnits="world",this.drawAsLabel=!1,this.depthEnabled=!0,this.isFocused=!0,this.focusEffect="none",this.draped=!1,this.isLabel=!1}}const ye=y().vec3f(W.POSITION).vec3f(W.NORMAL).vec2f(W.UV0).vec4u8(W.COLOR).vec2f(W.SIZE).f32(W.ROTATION).vec4f(W.CENTEROFFSETANDDISTANCE).vec4f(W.FEATUREATTRIBUTE),Fe=ye.clone().vec4u8(W.OBJECTANDLAYERIDCOLOR);class je{constructor(){this.vertexBufferLayout=N()?Fe:ye}elementCount(e){return 6*e.get(W.POSITION).indices.length}write(e,t,s,i,r,a){Y(s.get(W.POSITION),e,r.position,a,6),Z(s.get(W.NORMAL),t,r.normal,a,6);const o=s.get(W.UV0)?.data;let n=0,c=0,l=1,f=1;o&&o.length>=4&&(n=o[0],c=o[1],l=o[2],f=o[3]),l=Math.min(1.99999,l+1),f=Math.min(1.99999,f+1);let h=s.get(W.POSITION).indices.length,p=a;const u=r.uv0;for(let O=0;O<h;++O)u.set(p,0,n),u.set(p,1,c),p++,u.set(p,0,l),u.set(p,1,c),p++,u.set(p,0,l),u.set(p,1,f),p++,u.set(p,0,l),u.set(p,1,f),p++,u.set(p,0,n),u.set(p,1,f),p++,u.set(p,0,n),u.set(p,1,c),p++;k(s.get(W.COLOR),4,r.color,a,6);const{data:m,indices:d}=s.get(W.SIZE);h=d.length;const g=r.size;p=a;for(let O=0;O<h;++O){const e=m[2*d[O]],t=m[2*d[O]+1];for(let s=0;s<6;++s)g.set(p,0,e),g.set(p,1,t),p++}if(J(s.get(W.ROTATION),r.rotation,a,6),s.get(W.CENTEROFFSETANDDISTANCE)?K(s.get(W.CENTEROFFSETANDDISTANCE),r.centerOffsetAndDistance,a,6):Q(r.centerOffsetAndDistance,a,6*h),s.get(W.FEATUREATTRIBUTE)?K(s.get(W.FEATUREATTRIBUTE),r.featureAttribute,a,6):Q(r.featureAttribute,a,6*h),null!=i){const e=s.get(W.POSITION)?.indices;if(e){const t=e.length,s=r.getField(W.OBJECTANDLAYERIDCOLOR,C);$(i,s,t,a,6)}}}}export{ae as HUDMaterial,De as Parameters};