UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 7.88 kB
import{isNone as t}from"../../../../../core/maybe.js";import e from"../MemoryBuffer.js";import{EncodingType as n,AttributeStatus as o}from"./enums.js";import{DataType as s}from"../../../../webgl/enums.js";import{VertexElementDescriptor as r}from"../../../../webgl/VertexElementDescriptor.js";class i{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._layoutInfo||this._buildAttributesInfo(),this._stride}getAttributeLocations(){return 0===this._locations.size&&this._buildAttributesInfo(),this._locations}getLayoutInfo(){return this._layoutInfo||this._buildAttributesInfo(),this._layoutInfo}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,e,o,s){const r=this.attributesInfo(),i=this.getEncodingInfos(),a=[];let c=0,u=0;for(const f of Object.keys(i)){const _=i[f],{type:h,precisionFactor:d,isLayout:l}=r[f],y=l?o.getLayoutProperty(f):o.getPaintProperty(f),m=y.interpolator?.getInterpolationRange(e);let I=0;for(const o of _){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 f=s??y.getValue(m?m[I]:e,t);switch(h){case n.R8_SIGNED:case n.R8_UNSIGNED:a[c]|=this._encodeByte(f*(d||1),8*r);break;case n.R16_SIGNED:case n.R16_UNSIGNED:a[c]|=this._encodeShort(f*(d||1),8*r);break;case n.R8G8_SIGNED:case n.R8G8_UNSIGNED:a[c]|=this._encodeByte(f*(d||1),8*r),a[c]|=this._encodeByte(f*(d||1),8*r+8);break;case n.R16G16_SIGNED:case n.R16G16_UNSIGNED:a[c]|=this._encodeShort(f*(d||1),8*r),a[c]|=this._encodeShort(f*(d||1),8*r+16);break;case n.R8G8B8A8_SIGNED:case n.R8G8B8A8_UNSIGNED:a[c]|=this._encodeByte(f*(d||1),8*r),a[c]|=this._encodeByte(f*(d||1),8*r+8),a[c]|=this._encodeByte(f*(d||1),8*r+16),a[c]|=this._encodeByte(f*(d||1),8*r+24);break;case n.R8G8B8A8_COLOR:a[c]=this._encodeColor(f);break;case n.R16G16B16A16_DASHARRAY:case n.R16G16B16A16_PATTERN:this._encodePattern(c,a,f);break;default:throw new Error("Unsupported encoding type")}I++}}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={},n={};let r=-1;const a=this.attributesInfo(),c=this.attributes();let u=-1;for(const s of c){u++;const c=this.getAtributeState(u);if(c===o.UNIFORM||c===o.UNUSED)continue;const f=a[s],_=[];e[s]=_;const h=f.type;for(let e=0;e<c;e++){const{dataType:e,bytesPerElement:o,count:s,normalized:a}=i._encodingInfo[h],c=o*s,u=`${e}-${!0===a}`;let f=n[u],d=0;if(!f||f.count+s>4)r++,f={dataIndex:r,count:0,offset:0},4!==s&&(n[u]=f),t.push({location:-1,name:"a_data_"+r,count:s,type:e,normalized:a}),d=Math.ceil(Math.max(c/4,1));else{const e=t[f.dataIndex];e.count+=s;d=Math.ceil(Math.max(e.count*o/4,1))-Math.ceil(Math.max(f.offset/4,1))}_.push({dataIndex:f.dataIndex,offset:f.offset,bufferElementsToAdd:d}),f.offset+=c,f.count+=s}}for(const o of t)switch(o.type){case s.BYTE:case s.UNSIGNED_BYTE:o.count=4;break;case s.SHORT:case s.UNSIGNED_SHORT:o.count+=o.count%2}this._buildVertexBufferLayout(t);let f=0;const _=this._layoutInfo.geometry;for(const o of _)this._locations.set(o.name,f++);const h=this._layoutInfo.opacity;if(h)for(const o of h)this._locations.set(o.name,f++);this._buildShaderInfo(t,e),this._propertyEncodingInfo=e}_buildVertexBufferLayout(t){const e={},n=this.geometryInfo();let o=n[0].stride;if(0===t.length)e.geometry=n;else{const s=[];let i=o;for(const e of t)o+=a(e.type)*e.count;for(const t of n)s.push(new r(t.name,t.count,t.type,t.offset,o,t.normalized));for(const e of t)s.push(new r(e.name,e.count,e.type,i,o,e.normalized)),i+=a(e.type)*e.count;e.geometry=s}this.opacityInfo()&&(e.opacity=this.opacityInfo()),this._layoutInfo=e,this._stride=o}_buildShaderInfo(e,s){let r="\n",a="\n";const u=[];for(const t of e)r+=`attribute ${this._getType(t.count)} ${t.name};\n`;const f=this.attributes(),_=this.attributesInfo();let h=-1;for(const d of f){h++;const{name:e,type:f,precisionFactor:l,isLayout:y}=_[d],m=l&&1!==l?" * "+1/l:"",{bytesPerElement:I,count:E}=i._encodingInfo[f],p=t=>`a_data_${t.dataIndex}${c(E,t.offset,I)}`;switch(this.getAtributeState(h)){case o.UNIFORM:{const o=this._getType(E),s=`u_${e}`;u.push({name:s,type:o,getValue:(e,o,s,r)=>{const i=y?e.getLayoutValue(d,o):e.getPaintValue(d,o);if(f===n.R16G16B16A16_DASHARRAY){const n=e.getDashKey(i,e.getLayoutValue("line-cap",o)),s=r.getMosaicItemPosition(n,!1);if(t(s))return null;const{tl:a,br:c}=s;return[a[0],c[1],c[0],a[1]]}if(f===n.R16G16B16A16_PATTERN){const e=r.getMosaicItemPosition(i,!d.includes("line-"));if(t(e))return null;const{tl:n,br:o}=e;return[n[0],o[1],o[0],n[1]]}if(f===n.R8G8B8A8_COLOR){const t=i[3];return[t*i[0],t*i[1],t*i[2],t]}return i}}),r+=`uniform ${o} ${s};\n`,a+=`${o} ${e} = ${s};\n`}break;case o.DATA_DRIVEN:{const t=p(s[d][0]);a+=`${this._getType(E)} ${e} = ${t}${m};\n`}break;case o.INTERPOLATED_DATA_DRIVEN:{const t=`u_t_${e}`;u.push({name:t,type:"float",getValue:(t,e,n,o)=>(y?t.getLayoutProperty(d):t.getPaintProperty(d)).interpolator.interpolationUniformValue(n,e)}),r+=`uniform float ${t};\n`;const n=p(s[d][0]),o=p(s[d][1]);a+=`${this._getType(E)} ${e} = mix(${n}${m}, ${o}${m}, ${t});\n`}}}this._shaderHeader=r,this._shaderMain=a,this._uniforms=u}_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(t){const n=255*t[3];return e.i8888to32(t[0]*n,t[1]*n,t[2]*n,n)}_encodePattern(t,e,n){if(!n||!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}}i._encodingInfo={[n.R8_SIGNED]:{dataType:s.BYTE,bytesPerElement:1,count:1,normalized:!1},[n.R8_UNSIGNED]:{dataType:s.UNSIGNED_BYTE,bytesPerElement:1,count:1,normalized:!1},[n.R16_SIGNED]:{dataType:s.SHORT,bytesPerElement:2,count:1,normalized:!1},[n.R16_UNSIGNED]:{dataType:s.UNSIGNED_SHORT,bytesPerElement:2,count:1,normalized:!1},[n.R8G8_SIGNED]:{dataType:s.BYTE,bytesPerElement:1,count:2,normalized:!1},[n.R8G8_UNSIGNED]:{dataType:s.UNSIGNED_BYTE,bytesPerElement:1,count:2,normalized:!1},[n.R16G16_SIGNED]:{dataType:s.SHORT,bytesPerElement:2,count:2,normalized:!1},[n.R16G16_UNSIGNED]:{dataType:s.UNSIGNED_SHORT,bytesPerElement:2,count:2,normalized:!1},[n.R8G8B8A8_SIGNED]:{dataType:s.BYTE,bytesPerElement:1,count:4,normalized:!1},[n.R8G8B8A8_UNSIGNED]:{dataType:s.UNSIGNED_BYTE,bytesPerElement:1,count:4,normalized:!1},[n.R8G8B8A8_COLOR]:{dataType:s.UNSIGNED_BYTE,bytesPerElement:1,count:4,normalized:!0},[n.R16G16B16A16_DASHARRAY]:{dataType:s.UNSIGNED_SHORT,bytesPerElement:2,count:4,normalized:!1},[n.R16G16B16A16_PATTERN]:{dataType:s.UNSIGNED_SHORT,bytesPerElement:2,count:4,normalized:!1}};const a=t=>{switch(t){case s.FLOAT:case s.INT:case s.UNSIGNED_INT:return 4;case s.SHORT:case s.UNSIGNED_SHORT:return 2;case s.BYTE:case s.UNSIGNED_BYTE:return 1}},c=(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{i as VTLMaterial};