UNPKG

@deck.gl/extensions

Version:

Plug-and-play functionalities for deck.gl layers

1,187 lines (1,036 loc) 84.9 kB
(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['deck'] = factory(); else root['deck'] = factory();})(globalThis, function () { "use strict";var __exports__=(()=>{var jt=Object.create;var Q=Object.defineProperty;var Vt=Object.getOwnPropertyDescriptor;var zt=Object.getOwnPropertyNames;var Ut=Object.getPrototypeOf,Gt=Object.prototype.hasOwnProperty;var Te=(o,e)=>()=>(e||o((e={exports:{}}).exports,e),e.exports),Ae=(o,e)=>{for(var t in e)Q(o,t,{get:e[t],enumerable:!0})},X=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of zt(e))!Gt.call(o,s)&&s!==t&&Q(o,s,{get:()=>e[s],enumerable:!(r=Vt(e,s))||r.enumerable});return o},y=(o,e,t)=>(X(o,e,"default"),t&&X(t,e,"default")),d=(o,e,t)=>(t=o!=null?jt(Ut(o)):{},X(e||!o||!o.__esModule?Q(t,"default",{value:o,enumerable:!0}):t,o)),qt=o=>X(Q({},"__esModule",{value:!0}),o);var _=Te((Dr,Oe)=>{Oe.exports=globalThis.deck});var qe=Te((qr,Ge)=>{Ge.exports=globalThis.luma});var Z={};Ae(Z,{BrushingExtension:()=>Re,ClipExtension:()=>xt,CollisionFilterExtension:()=>Ft,DataFilterExtension:()=>Ze,FillStyleExtension:()=>ht,Fp64Extension:()=>ct,MaskExtension:()=>Ct,PathStyleExtension:()=>pt,_TerrainExtension:()=>Dt,project64:()=>re});var g={},Le=d(_(),1);y(g,d(_(),1));if(!Le.Layer)throw new Error("@deck.gl/core is not found");y(Z,g);var ke=d(_(),1);var Ce=d(_(),1),Se=`uniform brushingUniforms { bool enabled; highp int target; vec2 mousePos; float radius; } brushing; `,Ht=` in vec2 brushingTargets; out float brushing_isVisible; bool brushing_isPointInRange(vec2 position) { if (!brushing.enabled) { return true; } vec2 source_commonspace = project_position(position); vec2 target_commonspace = project_position(brushing.mousePos); float distance = length((target_commonspace - source_commonspace) / project.commonUnitsPerMeter.xy); return distance <= brushing.radius; } bool brushing_arePointsInRange(vec2 sourcePos, vec2 targetPos) { return brushing_isPointInRange(sourcePos) || brushing_isPointInRange(targetPos); } void brushing_setVisible(bool visible) { brushing_isVisible = float(visible); } `,Yt=` ${Se} ${Ht} `,Wt=` in float brushing_isVisible; `,Kt=` ${Se} ${Wt} `,$t={source:0,target:1,custom:2,source_target:3},Zt={"vs:DECKGL_FILTER_GL_POSITION":` vec2 brushingTarget; vec2 brushingSource; if (brushing.target == 3) { brushingTarget = geometry.worldPositionAlt.xy; brushingSource = geometry.worldPosition.xy; } else if (brushing.target == 0) { brushingTarget = geometry.worldPosition.xy; } else if (brushing.target == 1) { brushingTarget = geometry.worldPositionAlt.xy; } else { brushingTarget = brushingTargets; } bool visible; if (brushing.target == 3) { visible = brushing_arePointsInRange(brushingSource, brushingTarget); } else { visible = brushing_isPointInRange(brushingTarget); } brushing_setVisible(visible); `,"fs:DECKGL_FILTER_COLOR":` if (brushing.enabled && brushing_isVisible < 0.5) { discard; } `},Ie={name:"brushing",dependencies:[Ce.project],vs:Yt,fs:Kt,inject:Zt,getUniforms:o=>{if(!o||!("viewport"in o))return{};let{brushingEnabled:e=!0,brushingRadius:t=1e4,brushingTarget:r="source",mousePosition:s,viewport:i}=o;return{enabled:Boolean(e&&s&&i.containsPixel(s)),radius:t,target:$t[r]||0,mousePos:s?i.unproject([s.x-i.x,s.y-i.y]):[0,0]}},uniformTypes:{enabled:"i32",target:"i32",mousePos:"vec2<f32>",radius:"f32"}};var Xt={getBrushingTarget:{type:"accessor",value:[0,0]},brushingTarget:"source",brushingEnabled:!0,brushingRadius:1e4},C=class extends ke.LayerExtension{getShaders(){return{modules:[Ie]}}initializeState(e,t){let r=this.getAttributeManager();r&&r.add({brushingTargets:{size:2,stepMode:"dynamic",accessor:"getBrushingTarget"}});let s=()=>{this.getCurrentLayer()?.setNeedsRedraw()};this.state.onMouseMove=s,e.deck&&e.deck.eventManager.on({pointermove:s,pointerleave:s})}finalizeState(e,t){if(e.deck){let r=this.state.onMouseMove;e.deck.eventManager.off({pointermove:r,pointerleave:r})}}draw(e,t){let{viewport:r,mousePosition:s}=e.context,{brushingEnabled:i,brushingRadius:n,brushingTarget:a}=this.props,l={viewport:r,mousePosition:s,brushingEnabled:i,brushingRadius:n,brushingTarget:a};this.setShaderModuleProps({brushing:l})}};C.defaultProps=Xt;C.extensionName="BrushingExtension";var Re=C;var E=d(_(),1);var we=`uniform dataFilterUniforms { bool useSoftMargin; bool enabled; bool transformSize; bool transformColor; #ifdef DATAFILTER_TYPE DATAFILTER_TYPE min; DATAFILTER_TYPE softMin; DATAFILTER_TYPE softMax; DATAFILTER_TYPE max; #ifdef DATAFILTER_DOUBLE DATAFILTER_TYPE min64High; DATAFILTER_TYPE max64High; #endif #endif #ifdef DATACATEGORY_TYPE highp uvec4 categoryBitMask; #endif } dataFilter; `,Qt=` #ifdef DATAFILTER_TYPE in DATAFILTER_TYPE filterValues; #ifdef DATAFILTER_DOUBLE in DATAFILTER_TYPE filterValues64Low; #endif #endif #ifdef DATACATEGORY_TYPE in DATACATEGORY_TYPE filterCategoryValues; #endif out float dataFilter_value; float dataFilter_reduceValue(float value) { return value; } float dataFilter_reduceValue(vec2 value) { return min(value.x, value.y); } float dataFilter_reduceValue(vec3 value) { return min(min(value.x, value.y), value.z); } float dataFilter_reduceValue(vec4 value) { return min(min(value.x, value.y), min(value.z, value.w)); } #ifdef DATAFILTER_TYPE void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax) { if (dataFilter.useSoftMargin) { // smoothstep results are undefined if edge0 \u2265 edge1 // Fallback to ignore filterSoftRange if it is truncated by filterRange DATAFILTER_TYPE leftInRange = mix( smoothstep(dataFilter.min, dataFilter.softMin, valueFromMin), step(dataFilter.min, valueFromMin), step(dataFilter.softMin, dataFilter.min) ); DATAFILTER_TYPE rightInRange = mix( 1.0 - smoothstep(dataFilter.softMax, dataFilter.max, valueFromMax), step(valueFromMax, dataFilter.max), step(dataFilter.max, dataFilter.softMax) ); dataFilter_value = dataFilter_reduceValue(leftInRange * rightInRange); } else { dataFilter_value = dataFilter_reduceValue( step(dataFilter.min, valueFromMin) * step(valueFromMax, dataFilter.max) ); } } #endif #ifdef DATACATEGORY_TYPE void dataFilter_setCategoryValue(DATACATEGORY_TYPE category) { #if DATACATEGORY_CHANNELS == 1 // One 128-bit mask uint dataFilter_masks = dataFilter.categoryBitMask[category / 32u]; #elif DATACATEGORY_CHANNELS == 2 // Two 64-bit masks uvec2 dataFilter_masks = uvec2( dataFilter.categoryBitMask[category.x / 32u], dataFilter.categoryBitMask[category.y / 32u + 2u] ); #elif DATACATEGORY_CHANNELS == 3 // Three 32-bit masks uvec3 dataFilter_masks = dataFilter.categoryBitMask.xyz; #else // Four 32-bit masks uvec4 dataFilter_masks = dataFilter.categoryBitMask; #endif // Shift mask and extract relevant bits DATACATEGORY_TYPE dataFilter_bits = DATACATEGORY_TYPE(dataFilter_masks) >> (category & 31u); dataFilter_bits &= 1u; #if DATACATEGORY_CHANNELS == 1 if(dataFilter_bits == 0u) dataFilter_value = 0.0; #else if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0u)))) dataFilter_value = 0.0; #endif } #endif `,Ne=` ${we} ${Qt} `,Jt=` in float dataFilter_value; `,Be=` ${we} ${Jt} `;function De(o){if(!o||!("extensions"in o))return{};let{filterRange:e=[-1,1],filterEnabled:t=!0,filterTransformSize:r=!0,filterTransformColor:s=!0,categoryBitMask:i}=o,n=o.filterSoftRange||e;return{...Number.isFinite(e[0])?{min:e[0],softMin:n[0],softMax:n[1],max:e[1]}:{min:e.map(a=>a[0]),softMin:n.map(a=>a[0]),softMax:n.map(a=>a[1]),max:e.map(a=>a[1])},enabled:t,useSoftMargin:Boolean(o.filterSoftRange),transformSize:t&&r,transformColor:t&&s,...i&&{categoryBitMask:i}}}function eo(o){if(!o||!("extensions"in o))return{};let e=De(o);if(Number.isFinite(e.min)){let t=Math.fround(e.min);e.min-=t,e.softMin-=t,e.min64High=t;let r=Math.fround(e.max);e.max-=r,e.softMax-=r,e.max64High=r}else{let t=e.min.map(Math.fround);e.min=e.min.map((s,i)=>s-t[i]),e.softMin=e.softMin.map((s,i)=>s-t[i]),e.min64High=t;let r=e.max.map(Math.fround);e.max=e.max.map((s,i)=>s-r[i]),e.softMax=e.softMax.map((s,i)=>s-r[i]),e.max64High=r}return e}var je={"vs:#main-start":` dataFilter_value = 1.0; if (dataFilter.enabled) { #ifdef DATAFILTER_TYPE #ifdef DATAFILTER_DOUBLE dataFilter_setValue( filterValues - dataFilter.min64High + filterValues64Low, filterValues - dataFilter.max64High + filterValues64Low ); #else dataFilter_setValue(filterValues, filterValues); #endif #endif #ifdef DATACATEGORY_TYPE dataFilter_setCategoryValue(filterCategoryValues); #endif } `,"vs:#main-end":` if (dataFilter_value == 0.0) { gl_Position = vec4(0.); } `,"vs:DECKGL_FILTER_SIZE":` if (dataFilter.transformSize) { size = size * dataFilter_value; } `,"fs:DECKGL_FILTER_COLOR":` if (dataFilter_value == 0.0) discard; if (dataFilter.transformColor) { color.a *= dataFilter_value; } `};function Ve(o){let{categorySize:e,filterSize:t,fp64:r}=o,s={useSoftMargin:"i32",enabled:"i32",transformSize:"i32",transformColor:"i32"};if(t){let i=t===1?"f32":`vec${t}<f32>`;s.min=i,s.softMin=i,s.softMax=i,s.max=i,r&&(s.min64High=i,s.max64High=i)}return e&&(s.categoryBitMask="vec4<i32>"),s}var ze={name:"dataFilter",vs:Ne,fs:Be,inject:je,getUniforms:De,uniformTypesFromOptions:Ve},Ue={name:"dataFilter",vs:Ne,fs:Be,inject:je,getUniforms:eo,uniformTypesFromOptions:Ve};var He=d(qe(),1),to=`#version 300 es #define SHADER_NAME data-filter-vertex-shader #ifdef FLOAT_TARGET in float filterIndices; in float filterPrevIndices; #else in vec2 filterIndices; in vec2 filterPrevIndices; #endif out vec4 vColor; const float component = 1.0 / 255.0; void main() { #ifdef FLOAT_TARGET dataFilter_value *= float(filterIndices != filterPrevIndices); gl_Position = vec4(0.0, 0.0, 0.0, 1.0); vColor = vec4(0.0, 0.0, 0.0, 1.0); #else // Float texture is not supported: pack result into 4 channels x 256 px x 64px dataFilter_value *= float(filterIndices.x != filterPrevIndices.x); float col = filterIndices.x; float row = filterIndices.y * 4.0; float channel = floor(row); row = fract(row); vColor = component * vec4(bvec4(channel == 0.0, channel == 1.0, channel == 2.0, channel == 3.0)); gl_Position = vec4(col * 2.0 - 1.0, row * 2.0 - 1.0, 0.0, 1.0); #endif gl_PointSize = 1.0; } `,oo=`#version 300 es #define SHADER_NAME data-filter-fragment-shader precision highp float; in vec4 vColor; out vec4 fragColor; void main() { if (dataFilter_value < 0.5) { discard; } fragColor = vColor; } `,ro=["float32-renderable-webgl","texture-blend-float-webgl"];function Ye(o){return ro.every(e=>o.features.has(e))}function We(o,e){return e?o.createFramebuffer({width:1,height:1,colorAttachments:[o.createTexture({format:"rgba32float",mipmaps:!1})]}):o.createFramebuffer({width:256,height:64,colorAttachments:[o.createTexture({format:"rgba8unorm",mipmaps:!1})]})}function Ke(o,e,t,r){return t.defines.NON_INSTANCED_MODEL=1,r&&(t.defines.FLOAT_TARGET=1),new He.Model(o,{id:"data-filter-aggregation-model",vertexCount:1,isInstanced:!1,topology:"point-list",disableWarnings:!0,vs:to,fs:oo,bufferLayout:e,...t})}var $e={blend:!0,blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",blendColorOperation:"add",blendAlphaOperation:"add",depthCompare:"never"};var io={getFilterValue:{type:"accessor",value:0},getFilterCategory:{type:"accessor",value:0},onFilteredItemsChange:{type:"function",value:null,optional:!0},filterEnabled:!0,filterRange:[-1,1],filterSoftRange:null,filterCategories:[0],filterTransformSize:!0,filterTransformColor:!0},no={categorySize:0,filterSize:1,fp64:!1,countItems:!1},ao={1:"uint",2:"uvec2",3:"uvec3",4:"uvec4"},lo={1:"float",2:"vec2",3:"vec3",4:"vec4"},S=class extends E.LayerExtension{constructor(e={}){super({...no,...e})}getShaders(e){let{categorySize:t,filterSize:r,fp64:s}=e.opts,i={};t&&(i.DATACATEGORY_TYPE=ao[t],i.DATACATEGORY_CHANNELS=t),r&&(i.DATAFILTER_TYPE=lo[r],i.DATAFILTER_DOUBLE=Boolean(s));let n=s?Ue:ze;return n.uniformTypes=n.uniformTypesFromOptions(e.opts),{modules:[n],defines:i}}initializeState(e,t){let r=this.getAttributeManager(),{categorySize:s,filterSize:i,fp64:n}=t.opts;r&&(i&&r.add({filterValues:{size:i,type:n?"float64":"float32",stepMode:"dynamic",accessor:"getFilterValue"}}),s&&r.add({filterCategoryValues:{size:s,stepMode:"dynamic",accessor:"getFilterCategory",type:"uint32",transform:s===1?l=>t._getCategoryKey.call(this,l,0):l=>l.map((c,f)=>t._getCategoryKey.call(this,c,f))}}));let{device:a}=this.context;if(r&&t.opts.countItems){let l=Ye(a);r.add({filterVertexIndices:{size:l?1:2,vertexOffset:1,type:"unorm8",accessor:(u,{index:p})=>{let m=u&&u.__source?u.__source.index:p;return l?(m+1)%255:[(m+1)%255,Math.floor(m/255)%255]},shaderAttributes:{filterPrevIndices:{vertexOffset:0},filterIndices:{vertexOffset:1}}}});let c=We(a,l),f=Ke(a,r.getBufferLayouts({isInstanced:!1}),t.getShaders.call(this,t),l);this.setState({filterFBO:c,filterModel:f})}}updateState({props:e,oldProps:t,changeFlags:r},s){let i=this.getAttributeManager(),{categorySize:n}=s.opts;if(this.state.filterModel){let a=i.attributes.filterValues?.needsUpdate()||i.attributes.filterCategoryValues?.needsUpdate()||e.filterEnabled!==t.filterEnabled||e.filterRange!==t.filterRange||e.filterSoftRange!==t.filterSoftRange||e.filterCategories!==t.filterCategories;a&&this.setState({filterNeedsUpdate:a})}i?.attributes.filterCategoryValues&&((i.attributes.filterCategoryValues.needsUpdate()||!(0,E._deepEqual)(e.filterCategories,t.filterCategories,2))&&this.setState({categoryBitMask:null}),r.dataChanged&&(this.setState({categoryMap:Array(n).fill(0).map(()=>({}))}),i.attributes.filterCategoryValues.setNeedsUpdate("categoryMap")))}draw(e,t){let r=this.state.filterFBO,s=this.state.filterModel,i=this.state.filterNeedsUpdate;this.state.categoryBitMask||t._updateCategoryBitMask.call(this,e,t);let{onFilteredItemsChange:n,extensions:a,filterEnabled:l,filterRange:c,filterSoftRange:f,filterTransformSize:u,filterTransformColor:p,filterCategories:m}=this.props,v={extensions:a,filterEnabled:l,filterRange:c,filterSoftRange:f,filterTransformSize:u,filterTransformColor:p,filterCategories:m};if(this.state.categoryBitMask&&(v.categoryBitMask=this.state.categoryBitMask),this.setShaderModuleProps({dataFilter:v}),i&&n&&s){let b=this.getAttributeManager(),{attributes:{filterValues:h,filterCategoryValues:L,filterVertexIndices:fe}}=b;s.setVertexCount(this.getNumInstances());let ue={...h?.getValue(),...L?.getValue(),...fe?.getValue()};s.setAttributes(ue),s.shaderInputs.setProps({dataFilter:v});let pe=[0,0,r.width,r.height],Ee=s.device.beginRenderPass({id:"data-filter-aggregation",framebuffer:r,parameters:{viewport:pe},clearColor:[0,0,0,0]});s.setParameters($e),s.draw(Ee),Ee.end();let Me=s.device.readPixelsToArrayWebGL(r),Fe=0;for(let de=0;de<Me.length;de++)Fe+=Me[de];n({id:this.id,count:Fe}),this.state.filterNeedsUpdate=!1}}finalizeState(){let e=this.state.filterFBO,t=this.state.filterModel;e?.destroy(),t?.destroy()}_updateCategoryBitMask(e,t){let{categorySize:r}=t.opts;if(!r)return;let{filterCategories:s}=this.props,i=new Uint32Array([0,0,0,0]),n=r===1?[s]:s,a=r===1?128:r===2?64:32;for(let l=0;l<n.length;l++){let c=n[l];for(let f of c){let u=t._getCategoryKey.call(this,f,l);if(u<a){let p=l*(a/32)+Math.floor(u/32);i[p]+=Math.pow(2,u%32)}else E.log.warn(`Exceeded maximum number of categories (${a})`)()}}this.state.categoryBitMask=i}_getCategoryKey(e,t){let r=this.state.categoryMap[t];return e in r||(r[e]=Object.keys(r).length),r[e]}};S.defaultProps=io;S.extensionName="DataFilterExtension";var Ze=S;var w=d(_(),1);var Wr=1/Math.PI*180,Kr=1/180*Math.PI,co={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...co}};var I=globalThis.mathgl.config;function _e(o){return Array.isArray(o)||ArrayBuffer.isView(o)&&!(o instanceof DataView)}function M(o,e,t){let r=I.EPSILON;t&&(I.EPSILON=t);try{if(o===e)return!0;if(_e(o)&&_e(e)){if(o.length!==e.length)return!1;for(let s=0;s<o.length;++s)if(!M(o[s],e[s]))return!1;return!0}return o&&o.equals?o.equals(e):e&&e.equals?e.equals(o):typeof o=="number"&&typeof e=="number"?Math.abs(o-e)<=I.EPSILON*Math.max(1,Math.abs(o),Math.abs(e)):!1}finally{I.EPSILON=r}}var k=typeof Float32Array<"u"?Float32Array:Array,me=Math.random;function J(o){return o>=0?Math.round(o):o%.5===0?Math.floor(o):Math.round(o)}var Zr=Math.PI/180;var R={};Ae(R,{add:()=>ho,angle:()=>jo,bezier:()=>So,ceil:()=>vo,clone:()=>uo,copy:()=>_o,create:()=>Xe,cross:()=>Ao,dist:()=>Wo,distance:()=>ot,div:()=>Yo,divide:()=>tt,dot:()=>ve,equals:()=>Go,exactEquals:()=>Uo,floor:()=>go,forEach:()=>Xo,fromValues:()=>po,hermite:()=>Co,inverse:()=>Fo,len:()=>$o,length:()=>Qe,lerp:()=>Oo,max:()=>yo,min:()=>xo,mul:()=>Ho,multiply:()=>et,negate:()=>Mo,normalize:()=>To,random:()=>Io,rotateX:()=>No,rotateY:()=>Bo,rotateZ:()=>Do,round:()=>Po,scale:()=>bo,scaleAndAdd:()=>Eo,set:()=>mo,slerp:()=>Lo,sqrDist:()=>Ko,sqrLen:()=>Zo,squaredDistance:()=>rt,squaredLength:()=>st,str:()=>zo,sub:()=>qo,subtract:()=>Je,transformMat3:()=>Ro,transformMat4:()=>ko,transformQuat:()=>wo,zero:()=>Vo});function Xe(){let o=new k(3);return k!=Float32Array&&(o[0]=0,o[1]=0,o[2]=0),o}function uo(o){let e=new k(3);return e[0]=o[0],e[1]=o[1],e[2]=o[2],e}function Qe(o){let e=o[0],t=o[1],r=o[2];return Math.sqrt(e*e+t*t+r*r)}function po(o,e,t){let r=new k(3);return r[0]=o,r[1]=e,r[2]=t,r}function _o(o,e){return o[0]=e[0],o[1]=e[1],o[2]=e[2],o}function mo(o,e,t,r){return o[0]=e,o[1]=t,o[2]=r,o}function ho(o,e,t){return o[0]=e[0]+t[0],o[1]=e[1]+t[1],o[2]=e[2]+t[2],o}function Je(o,e,t){return o[0]=e[0]-t[0],o[1]=e[1]-t[1],o[2]=e[2]-t[2],o}function et(o,e,t){return o[0]=e[0]*t[0],o[1]=e[1]*t[1],o[2]=e[2]*t[2],o}function tt(o,e,t){return o[0]=e[0]/t[0],o[1]=e[1]/t[1],o[2]=e[2]/t[2],o}function vo(o,e){return o[0]=Math.ceil(e[0]),o[1]=Math.ceil(e[1]),o[2]=Math.ceil(e[2]),o}function go(o,e){return o[0]=Math.floor(e[0]),o[1]=Math.floor(e[1]),o[2]=Math.floor(e[2]),o}function xo(o,e,t){return o[0]=Math.min(e[0],t[0]),o[1]=Math.min(e[1],t[1]),o[2]=Math.min(e[2],t[2]),o}function yo(o,e,t){return o[0]=Math.max(e[0],t[0]),o[1]=Math.max(e[1],t[1]),o[2]=Math.max(e[2],t[2]),o}function Po(o,e){return o[0]=J(e[0]),o[1]=J(e[1]),o[2]=J(e[2]),o}function bo(o,e,t){return o[0]=e[0]*t,o[1]=e[1]*t,o[2]=e[2]*t,o}function Eo(o,e,t,r){return o[0]=e[0]+t[0]*r,o[1]=e[1]+t[1]*r,o[2]=e[2]+t[2]*r,o}function ot(o,e){let t=e[0]-o[0],r=e[1]-o[1],s=e[2]-o[2];return Math.sqrt(t*t+r*r+s*s)}function rt(o,e){let t=e[0]-o[0],r=e[1]-o[1],s=e[2]-o[2];return t*t+r*r+s*s}function st(o){let e=o[0],t=o[1],r=o[2];return e*e+t*t+r*r}function Mo(o,e){return o[0]=-e[0],o[1]=-e[1],o[2]=-e[2],o}function Fo(o,e){return o[0]=1/e[0],o[1]=1/e[1],o[2]=1/e[2],o}function To(o,e){let t=e[0],r=e[1],s=e[2],i=t*t+r*r+s*s;return i>0&&(i=1/Math.sqrt(i)),o[0]=e[0]*i,o[1]=e[1]*i,o[2]=e[2]*i,o}function ve(o,e){return o[0]*e[0]+o[1]*e[1]+o[2]*e[2]}function Ao(o,e,t){let r=e[0],s=e[1],i=e[2],n=t[0],a=t[1],l=t[2];return o[0]=s*l-i*a,o[1]=i*n-r*l,o[2]=r*a-s*n,o}function Oo(o,e,t,r){let s=e[0],i=e[1],n=e[2];return o[0]=s+r*(t[0]-s),o[1]=i+r*(t[1]-i),o[2]=n+r*(t[2]-n),o}function Lo(o,e,t,r){let s=Math.acos(Math.min(Math.max(ve(e,t),-1),1)),i=Math.sin(s),n=Math.sin((1-r)*s)/i,a=Math.sin(r*s)/i;return o[0]=n*e[0]+a*t[0],o[1]=n*e[1]+a*t[1],o[2]=n*e[2]+a*t[2],o}function Co(o,e,t,r,s,i){let n=i*i,a=n*(2*i-3)+1,l=n*(i-2)+i,c=n*(i-1),f=n*(3-2*i);return o[0]=e[0]*a+t[0]*l+r[0]*c+s[0]*f,o[1]=e[1]*a+t[1]*l+r[1]*c+s[1]*f,o[2]=e[2]*a+t[2]*l+r[2]*c+s[2]*f,o}function So(o,e,t,r,s,i){let n=1-i,a=n*n,l=i*i,c=a*n,f=3*i*a,u=3*l*n,p=l*i;return o[0]=e[0]*c+t[0]*f+r[0]*u+s[0]*p,o[1]=e[1]*c+t[1]*f+r[1]*u+s[1]*p,o[2]=e[2]*c+t[2]*f+r[2]*u+s[2]*p,o}function Io(o,e){e=e===void 0?1:e;let t=me()*2*Math.PI,r=me()*2-1,s=Math.sqrt(1-r*r)*e;return o[0]=Math.cos(t)*s,o[1]=Math.sin(t)*s,o[2]=r*e,o}function ko(o,e,t){let r=e[0],s=e[1],i=e[2],n=t[3]*r+t[7]*s+t[11]*i+t[15];return n=n||1,o[0]=(t[0]*r+t[4]*s+t[8]*i+t[12])/n,o[1]=(t[1]*r+t[5]*s+t[9]*i+t[13])/n,o[2]=(t[2]*r+t[6]*s+t[10]*i+t[14])/n,o}function Ro(o,e,t){let r=e[0],s=e[1],i=e[2];return o[0]=r*t[0]+s*t[3]+i*t[6],o[1]=r*t[1]+s*t[4]+i*t[7],o[2]=r*t[2]+s*t[5]+i*t[8],o}function wo(o,e,t){let r=t[0],s=t[1],i=t[2],n=t[3],a=e[0],l=e[1],c=e[2],f=s*c-i*l,u=i*a-r*c,p=r*l-s*a,m=s*p-i*u,v=i*f-r*p,b=r*u-s*f,h=n*2;return f*=h,u*=h,p*=h,m*=2,v*=2,b*=2,o[0]=a+f+m,o[1]=l+u+v,o[2]=c+p+b,o}function No(o,e,t,r){let s=[],i=[];return s[0]=e[0]-t[0],s[1]=e[1]-t[1],s[2]=e[2]-t[2],i[0]=s[0],i[1]=s[1]*Math.cos(r)-s[2]*Math.sin(r),i[2]=s[1]*Math.sin(r)+s[2]*Math.cos(r),o[0]=i[0]+t[0],o[1]=i[1]+t[1],o[2]=i[2]+t[2],o}function Bo(o,e,t,r){let s=[],i=[];return s[0]=e[0]-t[0],s[1]=e[1]-t[1],s[2]=e[2]-t[2],i[0]=s[2]*Math.sin(r)+s[0]*Math.cos(r),i[1]=s[1],i[2]=s[2]*Math.cos(r)-s[0]*Math.sin(r),o[0]=i[0]+t[0],o[1]=i[1]+t[1],o[2]=i[2]+t[2],o}function Do(o,e,t,r){let s=[],i=[];return s[0]=e[0]-t[0],s[1]=e[1]-t[1],s[2]=e[2]-t[2],i[0]=s[0]*Math.cos(r)-s[1]*Math.sin(r),i[1]=s[0]*Math.sin(r)+s[1]*Math.cos(r),i[2]=s[2],o[0]=i[0]+t[0],o[1]=i[1]+t[1],o[2]=i[2]+t[2],o}function jo(o,e){let t=o[0],r=o[1],s=o[2],i=e[0],n=e[1],a=e[2],l=Math.sqrt((t*t+r*r+s*s)*(i*i+n*n+a*a)),c=l&&ve(o,e)/l;return Math.acos(Math.min(Math.max(c,-1),1))}function Vo(o){return o[0]=0,o[1]=0,o[2]=0,o}function zo(o){return`vec3(${o[0]}, ${o[1]}, ${o[2]})`}function Uo(o,e){return o[0]===e[0]&&o[1]===e[1]&&o[2]===e[2]}function Go(o,e){let t=o[0],r=o[1],s=o[2],i=e[0],n=e[1],a=e[2];return Math.abs(t-i)<=1e-6*Math.max(1,Math.abs(t),Math.abs(i))&&Math.abs(r-n)<=1e-6*Math.max(1,Math.abs(r),Math.abs(n))&&Math.abs(s-a)<=1e-6*Math.max(1,Math.abs(s),Math.abs(a))}var qo=Je,Ho=et,Yo=tt,Wo=ot,Ko=rt,$o=Qe,Zo=st,Xo=function(){let o=Xe();return function(e,t,r,s,i,n){let a,l;for(t||(t=3),r||(r=0),s?l=Math.min(s*t+r,e.length):l=e.length,a=r;a<l;a+=t)o[0]=e[a],o[1]=e[a+1],o[2]=e[a+2],i(o,o,n),e[a]=o[0],e[a+1]=o[1],e[a+2]=o[2];return e}}();function ee(o,e=[],t=0){let r=Math.fround(o),s=o-r;return e[t]=r,e[t+1]=s,e}function ge(o){return o-Math.fround(o)}function xe(o){let e=new Float32Array(32);for(let t=0;t<4;++t)for(let r=0;r<4;++r){let s=t*4+r;ee(o[r*4+t],e,s*2)}return e}var it=` uniform fp64arithmeticUniforms { uniform float ONE; } fp64; /* About LUMA_FP64_CODE_ELIMINATION_WORKAROUND The purpose of this workaround is to prevent shader compilers from optimizing away necessary arithmetic operations by swapping their sequences or transform the equation to some 'equivalent' form. The method is to multiply an artifical variable, ONE, which will be known to the compiler to be 1 only at runtime. The whole expression is then represented as a polynomial with respective to ONE. In the coefficients of all terms, only one a and one b should appear err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE */ // Divide float number to high and low floats to extend fraction bits vec2 split(float a) { const float SPLIT = 4097.0; float t = a * SPLIT; #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float a_hi = t * fp64.ONE - (t - a); float a_lo = a * fp64.ONE - a_hi; #else float a_hi = t - (t - a); float a_lo = a - a_hi; #endif return vec2(a_hi, a_lo); } // Divide float number again when high float uses too many fraction bits vec2 split2(vec2 a) { vec2 b = split(a.x); b.y += a.y; return b; } // Special sum operation when a > b vec2 quickTwoSum(float a, float b) { #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float sum = (a + b) * fp64.ONE; float err = b - (sum - a) * fp64.ONE; #else float sum = a + b; float err = b - (sum - a); #endif return vec2(sum, err); } // General sum operation vec2 twoSum(float a, float b) { float s = (a + b); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float v = (s * fp64.ONE - a) * fp64.ONE; float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE + (b - v); #else float v = s - a; float err = (a - (s - v)) + (b - v); #endif return vec2(s, err); } vec2 twoSub(float a, float b) { float s = (a - b); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float v = (s * fp64.ONE - a) * fp64.ONE; float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE - (b + v); #else float v = s - a; float err = (a - (s - v)) - (b + v); #endif return vec2(s, err); } vec2 twoSqr(float a) { float prod = a * a; vec2 a_fp64 = split(a); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float err = ((a_fp64.x * a_fp64.x - prod) * fp64.ONE + 2.0 * a_fp64.x * a_fp64.y * fp64.ONE * fp64.ONE) + a_fp64.y * a_fp64.y * fp64.ONE * fp64.ONE * fp64.ONE; #else float err = ((a_fp64.x * a_fp64.x - prod) + 2.0 * a_fp64.x * a_fp64.y) + a_fp64.y * a_fp64.y; #endif return vec2(prod, err); } vec2 twoProd(float a, float b) { float prod = a * b; vec2 a_fp64 = split(a); vec2 b_fp64 = split(b); float err = ((a_fp64.x * b_fp64.x - prod) + a_fp64.x * b_fp64.y + a_fp64.y * b_fp64.x) + a_fp64.y * b_fp64.y; return vec2(prod, err); } vec2 sum_fp64(vec2 a, vec2 b) { vec2 s, t; s = twoSum(a.x, b.x); t = twoSum(a.y, b.y); s.y += t.x; s = quickTwoSum(s.x, s.y); s.y += t.y; s = quickTwoSum(s.x, s.y); return s; } vec2 sub_fp64(vec2 a, vec2 b) { vec2 s, t; s = twoSub(a.x, b.x); t = twoSub(a.y, b.y); s.y += t.x; s = quickTwoSum(s.x, s.y); s.y += t.y; s = quickTwoSum(s.x, s.y); return s; } vec2 mul_fp64(vec2 a, vec2 b) { vec2 prod = twoProd(a.x, b.x); // y component is for the error prod.y += a.x * b.y; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) prod = split2(prod); #endif prod = quickTwoSum(prod.x, prod.y); prod.y += a.y * b.x; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) prod = split2(prod); #endif prod = quickTwoSum(prod.x, prod.y); return prod; } vec2 div_fp64(vec2 a, vec2 b) { float xn = 1.0 / b.x; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) vec2 yn = mul_fp64(a, vec2(xn, 0)); #else vec2 yn = a * xn; #endif float diff = (sub_fp64(a, mul_fp64(b, yn))).x; vec2 prod = twoProd(xn, diff); return sum_fp64(yn, prod); } vec2 sqrt_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) return vec2(0.0, 0.0); if (a.x < 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0); float x = 1.0 / sqrt(a.x); float yn = a.x * x; #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) vec2 yn_sqr = twoSqr(yn) * fp64.ONE; #else vec2 yn_sqr = twoSqr(yn); #endif float diff = sub_fp64(a, yn_sqr).x; vec2 prod = twoProd(x * 0.5, diff); #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) return sum_fp64(split(yn), prod); #else return sum_fp64(vec2(yn, 0.0), prod); #endif } `;var nt=`const vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08); const vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09); const vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8); const vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7); const vec2 PI_2_FP64 = vec2(1.5707963705062866, -4.371139006309477e-8); const vec2 PI_4_FP64 = vec2(0.7853981852531433, -2.1855695031547384e-8); const vec2 PI_16_FP64 = vec2(0.19634954631328583, -5.463923757886846e-9); const vec2 PI_16_2_FP64 = vec2(0.39269909262657166, -1.0927847515773692e-8); const vec2 PI_16_3_FP64 = vec2(0.5890486240386963, -1.4906100798128818e-9); const vec2 PI_180_FP64 = vec2(0.01745329238474369, 1.3519960498364902e-10); const vec2 SIN_TABLE_0_FP64 = vec2(0.19509032368659973, -1.6704714833615242e-9); const vec2 SIN_TABLE_1_FP64 = vec2(0.3826834261417389, 6.22335089017767e-9); const vec2 SIN_TABLE_2_FP64 = vec2(0.5555702447891235, -1.1769521357507529e-8); const vec2 SIN_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617041793133e-8); const vec2 COS_TABLE_0_FP64 = vec2(0.9807852506637573, 2.9739473106360492e-8); const vec2 COS_TABLE_1_FP64 = vec2(0.9238795042037964, 2.8307490351764386e-8); const vec2 COS_TABLE_2_FP64 = vec2(0.8314695954322815, 1.6870263741530778e-8); const vec2 COS_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617152815436e-8); const vec2 INVERSE_FACTORIAL_3_FP64 = vec2(1.666666716337204e-01, -4.967053879312289e-09); // 1/3! const vec2 INVERSE_FACTORIAL_4_FP64 = vec2(4.16666679084301e-02, -1.2417634698280722e-09); // 1/4! const vec2 INVERSE_FACTORIAL_5_FP64 = vec2(8.333333767950535e-03, -4.34617203337595e-10); // 1/5! const vec2 INVERSE_FACTORIAL_6_FP64 = vec2(1.3888889225199819e-03, -3.3631094437103215e-11); // 1/6! const vec2 INVERSE_FACTORIAL_7_FP64 = vec2(1.9841270113829523e-04, -2.725596874933456e-12); // 1/7! const vec2 INVERSE_FACTORIAL_8_FP64 = vec2(2.4801587642286904e-05, -3.406996025904184e-13); // 1/8! const vec2 INVERSE_FACTORIAL_9_FP64 = vec2(2.75573188446287533e-06, 3.7935713937038186e-14); // 1/9! const vec2 INVERSE_FACTORIAL_10_FP64 = vec2(2.755731998149713e-07, -7.575112367869873e-15); // 1/10! float nint(float d) { if (d == floor(d)) return d; return floor(d + 0.5); } vec2 nint_fp64(vec2 a) { float hi = nint(a.x); float lo; vec2 tmp; if (hi == a.x) { lo = nint(a.y); tmp = quickTwoSum(hi, lo); } else { lo = 0.0; if (abs(hi - a.x) == 0.5 && a.y < 0.0) { hi -= 1.0; } tmp = vec2(hi, lo); } return tmp; } /* k_power controls how much range reduction we would like to have Range reduction uses the following method: assume a = k_power * r + m * log(2), k and m being integers. Set k_power = 4 (we can choose other k to trade accuracy with performance. we only need to calculate exp(r) and using exp(a) = 2^m * exp(r)^k_power; */ vec2 exp_fp64(vec2 a) { // We need to make sure these two numbers match // as bit-wise shift is not available in GLSL 1.0 const int k_power = 4; const float k = 16.0; const float inv_k = 1.0 / k; if (a.x <= -88.0) return vec2(0.0, 0.0); if (a.x >= 88.0) return vec2(1.0 / 0.0, 1.0 / 0.0); if (a.x == 0.0 && a.y == 0.0) return vec2(1.0, 0.0); if (a.x == 1.0 && a.y == 0.0) return E_FP64; float m = floor(a.x / LOG2_FP64.x + 0.5); vec2 r = sub_fp64(a, mul_fp64(LOG2_FP64, vec2(m, 0.0))) * inv_k; vec2 s, t, p; p = mul_fp64(r, r); s = sum_fp64(r, p * 0.5); p = mul_fp64(p, r); t = mul_fp64(p, INVERSE_FACTORIAL_3_FP64); s = sum_fp64(s, t); p = mul_fp64(p, r); t = mul_fp64(p, INVERSE_FACTORIAL_4_FP64); s = sum_fp64(s, t); p = mul_fp64(p, r); t = mul_fp64(p, INVERSE_FACTORIAL_5_FP64); // s = sum_fp64(s, t); // p = mul_fp64(p, r); // t = mul_fp64(p, INVERSE_FACTORIAL_6_FP64); // s = sum_fp64(s, t); // p = mul_fp64(p, r); // t = mul_fp64(p, INVERSE_FACTORIAL_7_FP64); s = sum_fp64(s, t); // At this point, s = exp(r) - 1; but after following 4 recursions, we will get exp(r) ^ 512 - 1. for (int i = 0; i < k_power; i++) { s = sum_fp64(s * 2.0, mul_fp64(s, s)); } #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) s = sum_fp64(s, vec2(fp64.ONE, 0.0)); #else s = sum_fp64(s, vec2(1.0, 0.0)); #endif return s * pow(2.0, m); // return r; } vec2 log_fp64(vec2 a) { if (a.x == 1.0 && a.y == 0.0) return vec2(0.0, 0.0); if (a.x <= 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0); vec2 x = vec2(log(a.x), 0.0); vec2 s; #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) s = vec2(fp64.ONE, 0.0); #else s = vec2(1.0, 0.0); #endif x = sub_fp64(sum_fp64(x, mul_fp64(a, exp_fp64(-x))), s); return x; } vec2 sin_taylor_fp64(vec2 a) { vec2 r, s, t, x; if (a.x == 0.0 && a.y == 0.0) { return vec2(0.0, 0.0); } x = -mul_fp64(a, a); s = a; r = a; r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_3_FP64); s = sum_fp64(s, t); r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_5_FP64); s = sum_fp64(s, t); /* keep the following commented code in case we need them for extra accuracy from the Taylor expansion*/ // r = mul_fp64(r, x); // t = mul_fp64(r, INVERSE_FACTORIAL_7_FP64); // s = sum_fp64(s, t); // r = mul_fp64(r, x); // t = mul_fp64(r, INVERSE_FACTORIAL_9_FP64); // s = sum_fp64(s, t); return s; } vec2 cos_taylor_fp64(vec2 a) { vec2 r, s, t, x; if (a.x == 0.0 && a.y == 0.0) { return vec2(1.0, 0.0); } x = -mul_fp64(a, a); r = x; s = sum_fp64(vec2(1.0, 0.0), r * 0.5); r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_4_FP64); s = sum_fp64(s, t); r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_6_FP64); s = sum_fp64(s, t); /* keep the following commented code in case we need them for extra accuracy from the Taylor expansion*/ // r = mul_fp64(r, x); // t = mul_fp64(r, INVERSE_FACTORIAL_8_FP64); // s = sum_fp64(s, t); // r = mul_fp64(r, x); // t = mul_fp64(r, INVERSE_FACTORIAL_10_FP64); // s = sum_fp64(s, t); return s; } void sincos_taylor_fp64(vec2 a, out vec2 sin_t, out vec2 cos_t) { if (a.x == 0.0 && a.y == 0.0) { sin_t = vec2(0.0, 0.0); cos_t = vec2(1.0, 0.0); } sin_t = sin_taylor_fp64(a); cos_t = sqrt_fp64(sub_fp64(vec2(1.0, 0.0), mul_fp64(sin_t, sin_t))); } vec2 sin_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) { return vec2(0.0, 0.0); } // 2pi range reduction vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64)); vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z)); vec2 t; float q = floor(r.x / PI_2_FP64.x + 0.5); int j = int(q); if (j < -2 || j > 2) { return vec2(0.0 / 0.0, 0.0 / 0.0); } t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0))); q = floor(t.x / PI_16_FP64.x + 0.5); int k = int(q); if (k == 0) { if (j == 0) { return sin_taylor_fp64(t); } else if (j == 1) { return cos_taylor_fp64(t); } else if (j == -1) { return -cos_taylor_fp64(t); } else { return -sin_taylor_fp64(t); } } int abs_k = int(abs(float(k))); if (abs_k > 4) { return vec2(0.0 / 0.0, 0.0 / 0.0); } else { t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0))); } vec2 u = vec2(0.0, 0.0); vec2 v = vec2(0.0, 0.0); #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #else if (abs_k == 1) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs_k == 2) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs_k == 3) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs_k == 4) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #endif vec2 sin_t, cos_t; sincos_taylor_fp64(t, sin_t, cos_t); vec2 result = vec2(0.0, 0.0); if (j == 0) { if (k > 0) { result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } } else if (j == 1) { if (k > 0) { result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } else { result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } else if (j == -1) { if (k > 0) { result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t)); } else { result = -sum_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t)); } } else { if (k > 0) { result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t)); } } return result; } vec2 cos_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) { return vec2(1.0, 0.0); } // 2pi range reduction vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64)); vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z)); vec2 t; float q = floor(r.x / PI_2_FP64.x + 0.5); int j = int(q); if (j < -2 || j > 2) { return vec2(0.0 / 0.0, 0.0 / 0.0); } t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0))); q = floor(t.x / PI_16_FP64.x + 0.5); int k = int(q); if (k == 0) { if (j == 0) { return cos_taylor_fp64(t); } else if (j == 1) { return -sin_taylor_fp64(t); } else if (j == -1) { return sin_taylor_fp64(t); } else { return -cos_taylor_fp64(t); } } int abs_k = int(abs(float(k))); if (abs_k > 4) { return vec2(0.0 / 0.0, 0.0 / 0.0); } else { t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0))); } vec2 u = vec2(0.0, 0.0); vec2 v = vec2(0.0, 0.0); #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #else if (abs_k == 1) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs_k == 2) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs_k == 3) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs_k == 4) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #endif vec2 sin_t, cos_t; sincos_taylor_fp64(t, sin_t, cos_t); vec2 result = vec2(0.0, 0.0); if (j == 0) { if (k > 0) { result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } else { result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } else if (j == 1) { if (k > 0) { result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t)); } } else if (j == -1) { if (k > 0) { result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } } else { if (k > 0) { result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t)); } else { result = -sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } return result; } vec2 tan_fp64(vec2 a) { vec2 sin_a; vec2 cos_a; if (a.x == 0.0 && a.y == 0.0) { return vec2(0.0, 0.0); } // 2pi range reduction vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64)); vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z)); vec2 t; float q = floor(r.x / PI_2_FP64.x + 0.5); int j = int(q); if (j < -2 || j > 2) { return vec2(0.0 / 0.0, 0.0 / 0.0); } t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0))); q = floor(t.x / PI_16_FP64.x + 0.5); int k = int(q); int abs_k = int(abs(float(k))); // We just can't get PI/16 * 3.0 very accurately. // so let's just store it if (abs_k > 4) { return vec2(0.0 / 0.0, 0.0 / 0.0); } else { t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0))); } vec2 u = vec2(0.0, 0.0); vec2 v = vec2(0.0, 0.0); vec2 sin_t, cos_t; vec2 s, c; sincos_taylor_fp64(t, sin_t, cos_t); if (k == 0) { s = sin_t; c = cos_t; } else { #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #else if (abs_k == 1) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs_k == 2) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs_k == 3) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs_k == 4) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #endif if (k > 0) { s = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); c = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } else { s = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); c = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } if (j == 0) { sin_a = s; cos_a = c; } else if (j == 1) { sin_a = c; cos_a = -s; } else if (j == -1) { sin_a = -c; cos_a = s; } else { sin_a = -s; cos_a = -c; } return div_fp64(sin_a, cos_a); } vec2 radians_fp64(vec2 degree) { return mul_fp64(degree, PI_180_FP64); } vec2 mix_fp64(vec2 a, vec2 b, float x) { vec2 range = sub_fp64(b, a); return sum_fp64(a, mul_fp64(range, vec2(x, 0.0))); } // Vector functions // vec2 functions void vec2_sum_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = sum_fp64(a[0], b[0]); out_val[1] = sum_fp64(a[1], b[1]); } void vec2_sub_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = sub_fp64(a[0], b[0]); out_val[1] = sub_fp64(a[1], b[1]); } void vec2_mul_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = mul_fp64(a[0], b[0]); out_val[1] = mul_fp64(a[1], b[1]); } void vec2_div_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = div_fp64(a[0], b[0]); out_val[1] = div_fp64(a[1], b[1]); } void vec2_mix_fp64(vec2 x[2], vec2 y[2], float a, out vec2 out_val[2]) { vec2 range[2]; vec2_sub_fp64(y, x, range); vec2 portion[2]; portion[0] = range[0] * a; portion[1] = range[1] * a; vec2_sum_fp64(x, portion, out_val); } vec2 vec2_length_fp64(vec2 x[2]) { return sqrt_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1]))); } void vec2_normalize_fp64(vec2 x[2], out vec2 out_val[2]) { vec2 length = vec2_length_fp64(x); vec2 length_vec2[2]; length_vec2[0] = length; length_vec2[1] = length; vec2_div_fp64(x, length_vec2, out_val); } vec2 vec2_distance_fp64(vec2 x[2], vec2 y[2]) { vec2 diff[2]; vec2_sub_fp64(x, y, diff); return vec2_length_fp64(diff); } vec2 vec2_dot_fp64(vec2 a[2], vec2 b[2]) { vec2 v[2]; v[0] = mul_fp64(a[0], b[0]); v[1] = mul_fp64(a[1], b[1]); return sum_fp64(v[0], v[1]); } // vec3 functions void vec3_sub_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) { for (int i = 0; i < 3; i++) { out_val[i] = sum_fp64(a[i], b[i]); } } void vec3_sum_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) { for (int i = 0; i < 3; i++) { out_val[i] = sum_fp64(a[i], b[i]); } } vec2 vec3_length_fp64(vec2 x[3]) { return sqrt_fp64(sum_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1])), mul_fp64(x[2], x[2]))); } vec2 vec3_distance_fp64(vec2 x[3], vec2 y[3]) { vec2 diff[3]; vec3_sub_fp64(x, y, diff); return vec3_length_fp64(diff); } // vec4 functions void vec4_fp64(vec4 a, out vec2 out_val[4]) { out_val[0].x = a[0]; out_val[0].y = 0.0; out_val[1].x = a[1]; out_val[1].y = 0.0; out_val[2].x = a[2]; out_val[2].y = 0.0; out_val[3].x = a[3]; out_val[3].y = 0.0; } void vec4_scalar_mul_fp64(vec2 a[4], vec2 b, out vec2 out_val[4]) { out_val[0] = mul_fp64(a[0], b); out_val[1] = mul_fp64(a[1], b); out_val[2] = mul_fp64(a[2], b); out_val[3] = mul_fp64(a[3], b); } void vec4_sum_fp64(vec2 a[4], vec2 b[4], out vec2 out_val[4]) { for (int i = 0; i < 4; i++) { out_val[i] = sum_fp64(a[i], b[i]); } } void vec4_dot_fp64(vec2 a[4], vec2 b[4], out vec2 out_val) { vec2 v[4]; v[0] = mul_fp64(a[0], b[0]); v[1] = mul_fp64(a[1], b[1]); v[2] = mul_fp64(a[2], b[2]); v[3] = mul_fp64(a[3], b[3]); out_val = sum_fp64(sum_fp64(v[0], v[1]), sum_fp64(v[2], v[3])); } void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) { vec2 tmp[4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { tmp[j] = b[j + i * 4]; } vec4_dot_fp64(a, tmp, out_val[i]); } } `;var Qo={ONE:1},at={name:"fp64arithmetic",vs:it,defaultUniforms:Qo,uniformTypes:{ONE:"f32"},fp64ify:ee,fp64LowPart:ge,fp64ifyMatrix4:xe},te={name:"fp64",vs:nt,dependencies:[at],fp64ify:ee,fp64LowPart:ge,fp64ifyMatrix4:xe};var oe=d(_(),1);var lt=`const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097); uniform project64Uniforms { vec2 scale; mat4 viewProjectionMatrix; mat4 viewProjectionMatrix64Low; } project64; void mercatorProject_fp64(vec4 lnglat_fp64, out vec2 out_val[2]) { #if defined(NVIDIA_FP64_WORKAROUND) out_val[0] = sum_fp64(radians_fp64(lnglat_fp64.xy), PI_FP64 * ONE); #else out_val[0] = sum_fp64(radians_fp64(lnglat_fp64.xy), PI_FP64); #endif out_val[1] = sum_fp64(PI_FP64, log_fp64(tan_fp64(sum_fp64(PI_4_FP64, radians_fp64(lnglat_fp64.zw) / 2.0)))); return; } void project_position_fp64(vec4 position_fp64, out vec2 out_val[2]) { vec2 pos_fp64[2]; mercatorProject_fp64(position_fp64, pos_fp64); out_val[0] = mul_fp64(pos_fp64[0], WORLD_SCALE_FP64); out_val[1] = mul_fp64(pos_fp64[1], WORLD_SCALE_FP64); return; } void project_position_fp64(vec2 position, vec2 position64xyLow, out vec2 out_val[2]) { vec4 position64xy = vec4( position.x, position64xyLow.x, position.y, position64xyLow.y); project_position_fp64(position64xy, out_val); } vec4 project_common_position_to_clipspace_fp64(vec2 vertex_pos_modelspace[4]) { vec2 vertex_pos_clipspace[4]; vec2 viewProjectionMatrixFP64[16]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { viewProjectionMatrixFP64[4 * i + j] = vec2( project64.viewProjectionMatrix[j][i], project64.viewProjectionMatrix64Low[j][i] ); } } mat4_vec4_mul_fp64(viewProjectionMatrixFP64, vertex_pos_modelspace, vertex_pos_clipspace); return vec4( vertex_pos_clipspace[0].x, vertex_pos_clipspace[1].x, vertex_pos_clipspace[2].x, vertex_pos_clipspace[3].x ); } vec4 project_position_to_clipspace( vec3 position, vec3 position64xyLow, vec3 offset, out vec4 commonPosition ) { vec2 offset64[4]; vec4_fp64(vec4(offset, 0.0), offset64); float z = project_size(position.z); vec2 projectedPosition64xy[2]; project_position_fp64(position.xy, position64xyLow.xy, projectedPosition64xy); vec2 commonPosition64[4]; commonPosition64[0] = sum_fp64(offset64[0], projectedPosition64xy[0]); commonPosition64[1] = sum_fp64(offset64[1], projectedPosition64xy[1]); commonPosition64[2] = sum_fp64(offset64[2], vec2(z, 0.0)); commonPosition64[3] = vec2(1.0, 0.0); commonPosition = vec4(projectedPosition64xy[0].x, projectedPosition64xy[1].x, z, 1.0); return project_common_position_to_clipspace_fp64(commonPosition64); } vec4 project_position_to_clipspace( vec3 position, vec3 position64xyLow, vec3 offset ) { vec4 commonPosition; return project_position_to_clipspace( position, position64xyLow, offset, commonPosition ); } `;var{fp64ify:Jo,fp64ifyMatrix4:er}=te,re={name:"project64",dependencies:[oe.project,te],vs:lt,getUniforms:or,uniformTypes:{scale:"vec2<f32>",viewProjectionMatrix:"mat4x4<f32>",viewProjectionMatrix64Low:"mat4x4<f32>"}},tr=(0,oe._memoize)(rr);function or(o){if(o&&"viewport"in o){let{viewProjectionMatrix:e,scale:t}=o.viewport;return tr({viewProjectionMatrix:e,scale:t})}return{}}function rr({viewProjectionMatrix:o,scale:e}){let t=er(o),r=new Float32Array(16),s=new Float32Array(16);for(let i=0;i<4;i++)for(let n=0;n<4;n++){let a=4*i+n,l=4*n+i;r[l]=t[2*a],s[l]=t[2*a+1]}return{scale:Jo(e),viewProjectionMatrix:[...r],viewProjectionMatrix64Low:[...s]}}var se=class extends w.LayerExtension{getShaders(){let{coordinateSystem:e}=this.props;if(e!==w.COORDINATE_SYSTEM.LNGLAT&&e!==w.COORDINATE_SYSTEM.DEFAULT)throw new Error("fp64: coordinateSystem must be LNGLAT");return{modules:[re]}}draw(e,t){let{viewport:r}=e.context;this.setShaderModuleProps({project64:{viewport:r}})}};se.extensionName="Fp64Extension";var ct=se;var N=d(_(),1);var ft={inject:{"vs:#decl":` in vec2 instanceDashArrays; in float instanceDashOffsets; out vec2 vDashArray; out float vDashOffset; `,"vs:#main-end":` vDashArray = instanceDashArrays; vDashOffset = instanceDashOffsets / width.x; `,"fs:#decl":` uniform pathStyleUniforms { float dashAlignMode; bool dashGapPickable; } pathStyle; in vec2 vDashArray; in float vDashOffset; `,"fs:#main-start":` float solidLength = vDashArray.x; float gapLength = vDashArray.y; float unitLength = solidLength + gapLength; float offset; if (unitLength > 0.0) { if (pathStyle.dashAlignMode == 0.0) { offset = vDashOffset; } else { unitLength = vPathLength / round(vPathLength / unitLength); offset = solidLength / 2.0; } float unitOffset = mod(vPathPosition.y + offset, unitLength); if (gapLength > 0.0 && unitOffset > solidLength) { if (