@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 8.01 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 t from"../MemoryBuffer.js";import{EncodingType as e,AttributeStatus as n}from"./enums.js";import{DataType as o}from"../../../../webgl/enums.js";import{VertexElementDescriptor as s}from"../../../../webgl/VertexElementDescriptor.js";class r{constructor(t){this._locations=new Map,this._key=t}get key(){return this._key}get type(){return 7&this._key}defines(){return[]}getStride(){return this._layout||this._buildAttributesInfo(),this._stride}getAttributeLocations(){return 0===this._locations.size&&this._buildAttributesInfo(),this._locations}getLayoutInfo(){return this._layout||this._buildAttributesInfo(),this._layout}getEncodingInfos(){return this._propertyEncodingInfo||this._buildAttributesInfo(),this._propertyEncodingInfo}getUniforms(){return this._uniforms||this._buildAttributesInfo(),this._uniforms}getShaderHeader(){return this._shaderHeader||this._buildAttributesInfo(),this._shaderHeader}getShaderMain(){return this._shaderMain||this._buildAttributesInfo(),this._shaderMain}setDataUniforms(t,e,n,o,s){const r=this.getUniforms();for(const i of r){const{name:r,type:a,getValue:c}=i,u=c(n,e,o,s);if(null!==u)switch(a){case"float":t.setUniform1f(r,u);break;case"vec2":t.setUniform2fv(r,u);break;case"vec4":t.setUniform4fv(r,u)}}}encodeAttributes(t,n,o,s){const r=this.attributesInfo(),i=this.getEncodingInfos(),a=[];let c=0,u=0;for(const _ of Object.keys(i)){const l=i[_],{type:f,precisionFactor:h,isLayout:d}=r[_],y=d?o.getLayoutProperty(_):o.getPaintProperty(_),m=y.interpolator?.getInterpolationRange(n);let E=0;for(const o of l){const{offset:r,bufferElementsToAdd:i}=o;if(i>0){for(let t=0;t<i;t++)a.push(0);c+=u,u=o.bufferElementsToAdd}const _=s??y.getValue(m?m[E]:n,t);switch(f){case e.R8_SIGNED:case e.R8_UNSIGNED:a[c]|=this._encodeByte(_*(h||1),8*r);break;case e.R16_SIGNED:case e.R16_UNSIGNED:a[c]|=this._encodeShort(_*(h||1),8*r);break;case e.R8G8_SIGNED:case e.R8G8_UNSIGNED:a[c]|=this._encodeByte(_*(h||1),8*r),a[c]|=this._encodeByte(_*(h||1),8*r+8);break;case e.R16G16_SIGNED:case e.R16G16_UNSIGNED:a[c]|=this._encodeShort(_*(h||1),8*r),a[c]|=this._encodeShort(_*(h||1),8*r+16);break;case e.R8G8B8A8_SIGNED:case e.R8G8B8A8_UNSIGNED:a[c]|=this._encodeByte(_*(h||1),8*r),a[c]|=this._encodeByte(_*(h||1),8*r+8),a[c]|=this._encodeByte(_*(h||1),8*r+16),a[c]|=this._encodeByte(_*(h||1),8*r+24);break;case e.R8G8B8A8_COLOR:a[c]=this._encodeColor(_);break;case e.R16G16B16A16_DASHARRAY:case e.R16G16B16A16_PATTERN:this._encodePattern(c,a,_);break;default:throw new Error("Unsupported encoding type")}E++}}return a}getAtributeState(t){let e=0;const n=3+2*t;return e|=this._bit(n),e|=this._bit(n+1)<<1,e}_buildAttributesInfo(){const t=[],e={},s={};let i=-1;const a=this.attributesInfo(),c=this.attributes();let u=-1;for(const o of c){u++;const c=this.getAtributeState(u);if(c===n.UNIFORM||c===n.UNUSED)continue;const _=a[o],l=[];e[o]=l;const f=_.type;for(let e=0;e<c;e++){const{dataType:e,bytesPerElement:n,count:o,normalized:a}=r._encodingInfo[f],c=n*o,u=`${e}-${!0===a}`;let _=s[u],h=0;if(!_||_.count+o>4)i++,_={dataIndex:i,count:0,offset:0},4!==o&&(s[u]=_),t.push({location:-1,name:"a_data_"+i,count:o,type:e,normalized:a}),h=Math.ceil(Math.max(c/4,1));else{const e=t[_.dataIndex];e.count+=o;h=Math.ceil(Math.max(e.count*n/4,1))-Math.ceil(Math.max(_.offset/4,1))}l.push({dataIndex:_.dataIndex,offset:_.offset,bufferElementsToAdd:h}),_.offset+=c,_.count+=o}}for(const n of t)switch(n.type){case o.BYTE:case o.UNSIGNED_BYTE:n.count=4;break;case o.SHORT:case o.UNSIGNED_SHORT:n.count+=n.count%2}this._buildVertexBufferLayout(t);let _=0;const l=this._layout.get("geometry");for(const n of l)this._locations.set(n.name,_++);const f=this._layout.get("opacity");if(f)for(const n of f)this._locations.set(n.name,_++);this._buildShaderInfo(t,e),this._propertyEncodingInfo=e}_buildVertexBufferLayout(t){const e=new Map,n=this.geometryInfo();let o=n[0].stride;if(0===t.length)e.set("geometry",n);else{const r=[];let a=o;for(const e of t)o+=i(e.type)*e.count;for(const t of n)r.push(new s(t.name,t.count,t.type,t.offset,o,t.normalized));for(const e of t)r.push(new s(e.name,e.count,e.type,a,o,e.normalized)),a+=i(e.type)*e.count;e.set("geometry",r)}const r=this.opacityInfo();r&&e.set("opacity",r),this._layout=e,this._stride=o}_buildShaderInfo(t,o){let s="\n",i="\n";const c=[];for(const e of t)s+=`attribute ${this._getType(e.count)} ${e.name};\n`;const u=this.attributes(),_=this.attributesInfo();let l=-1;for(const f of u){l++;const{name:t,type:u,precisionFactor:h,isLayout:d}=_[f],y=h&&1!==h?" * "+1/h:"",{bytesPerElement:m,count:E}=r._encodingInfo[u],I=t=>`a_data_${t.dataIndex}${a(E,t.offset,m)}`;switch(this.getAtributeState(l)){case n.UNIFORM:{const n=this._getType(E),o=`u_${t}`;c.push({name:o,type:n,getValue:(t,n,o,s)=>{const r=d?t.getLayoutValue(f,n):t.getPaintValue(f,n);if(u===e.R16G16B16A16_DASHARRAY){const e=t.getDashKey(r,t.getLayoutValue("line-cap",n)),o=s.getMosaicItemPosition(e,!1);if(null==o)return null;const{tl:i,br:a}=o;return[i[0],a[1],a[0],i[1]]}if(u===e.R16G16B16A16_PATTERN){const t=s.getMosaicItemPosition(r,!f.includes("line-"));if(null==t)return null;const{tl:e,br:n}=t;return[e[0],n[1],n[0],e[1]]}if(u===e.R8G8B8A8_COLOR){const t=r[3];return[t*r[0],t*r[1],t*r[2],t]}return r}}),s+=`uniform ${n} ${o};\n`,i+=`${n} ${t} = ${o};\n`}break;case n.DATA_DRIVEN:{const e=I(o[f][0]);i+=`${this._getType(E)} ${t} = ${e}${y};\n`}break;case n.INTERPOLATED_DATA_DRIVEN:{const e=`u_t_${t}`;c.push({name:e,type:"float",getValue:(t,e,n,o)=>(d?t.getLayoutProperty(f):t.getPaintProperty(f)).interpolator.interpolationUniformValue(n,e)}),s+=`uniform float ${e};\n`;const n=I(o[f][0]),r=I(o[f][1]);i+=`${this._getType(E)} ${t} = mix(${n}${y}, ${r}${y}, ${e});\n`}}}this._shaderHeader=s,this._shaderMain=i,this._uniforms=c}_bit(t){return(this._key&1<<t)>>t}_getType(t){switch(t){case 1:return"float";case 2:return"vec2";case 3:return"vec3";case 4:return"vec4"}throw new Error("Invalid count")}_encodeColor(e){const n=255*e[3];return t.i8888to32(e[0]*n,e[1]*n,e[2]*n,n)}_encodePattern(t,e,n){if(!n?.rect)return;const o=2,s=n.rect,r=n.width,i=n.height;e[t]=this._encodeShort(s.x+o,0),e[t]|=this._encodeShort(s.y+o+i,16),e[t+1]=this._encodeShort(s.x+o+r,0),e[t+1]|=this._encodeShort(s.y+o,16)}_encodeByte(t,e){return(255&t)<<e}_encodeShort(t,e){return(65535&t)<<e}}r._encodingInfo={[e.R8_SIGNED]:{dataType:o.BYTE,bytesPerElement:1,count:1,normalized:!1},[e.R8_UNSIGNED]:{dataType:o.UNSIGNED_BYTE,bytesPerElement:1,count:1,normalized:!1},[e.R16_SIGNED]:{dataType:o.SHORT,bytesPerElement:2,count:1,normalized:!1},[e.R16_UNSIGNED]:{dataType:o.UNSIGNED_SHORT,bytesPerElement:2,count:1,normalized:!1},[e.R8G8_SIGNED]:{dataType:o.BYTE,bytesPerElement:1,count:2,normalized:!1},[e.R8G8_UNSIGNED]:{dataType:o.UNSIGNED_BYTE,bytesPerElement:1,count:2,normalized:!1},[e.R16G16_SIGNED]:{dataType:o.SHORT,bytesPerElement:2,count:2,normalized:!1},[e.R16G16_UNSIGNED]:{dataType:o.UNSIGNED_SHORT,bytesPerElement:2,count:2,normalized:!1},[e.R8G8B8A8_SIGNED]:{dataType:o.BYTE,bytesPerElement:1,count:4,normalized:!1},[e.R8G8B8A8_UNSIGNED]:{dataType:o.UNSIGNED_BYTE,bytesPerElement:1,count:4,normalized:!1},[e.R8G8B8A8_COLOR]:{dataType:o.UNSIGNED_BYTE,bytesPerElement:1,count:4,normalized:!0},[e.R16G16B16A16_DASHARRAY]:{dataType:o.UNSIGNED_SHORT,bytesPerElement:2,count:4,normalized:!1},[e.R16G16B16A16_PATTERN]:{dataType:o.UNSIGNED_SHORT,bytesPerElement:2,count:4,normalized:!1}};const i=t=>{switch(t){case o.FLOAT:case o.INT:case o.UNSIGNED_INT:return 4;case o.SHORT:case o.UNSIGNED_SHORT:case o.HALF_FLOAT:return 2;case o.BYTE:case o.UNSIGNED_BYTE:return 1}},a=(t,e,n)=>{const o=e/n;if(1===t)switch(o){case 0:return".x";case 1:return".y";case 2:return".z";case 3:return".w"}else if(2===t)switch(o){case 0:return".xy";case 1:return".yz";case 2:return".zw"}else if(3===t)switch(o){case 0:return".xyz";case 1:return".yzw"}return""};export{r as VTLMaterial};