@deck.gl/extensions 9.4.0-alpha.1 → 9.4.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clip/clip-extension.d.ts +3 -0
- package/dist/clip/clip-extension.d.ts.map +1 -1
- package/dist/clip/clip-extension.js +7 -0
- package/dist/clip/clip-extension.js.map +1 -1
- package/dist/dist.dev.js +1164 -5
- package/dist/index.cjs +2623 -128
- package/dist/index.cjs.map +3 -4
- package/dist/terrain/shader-module.d.ts +16 -2
- package/dist/terrain/shader-module.d.ts.map +1 -1
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist.min.js +1197 -54
- package/package.json +10 -6
- package/src/clip/clip-extension.ts +15 -1
package/dist.min.js
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
5
5
|
else if (typeof exports === 'object') exports['deck'] = factory();
|
|
6
6
|
else root['deck'] = factory();})(globalThis, function () {
|
|
7
|
-
"use strict";var __exports__=(()=>{var Kt=Object.create;var
|
|
7
|
+
"use strict";var __exports__=(()=>{var Kt=Object.create;var J=Object.defineProperty;var Zt=Object.getOwnPropertyDescriptor;var $t=Object.getOwnPropertyNames;var Qt=Object.getPrototypeOf,Jt=Object.prototype.hasOwnProperty;var Be=(i,e)=>()=>{try{return e||i((e={exports:{}}).exports,e),e.exports}catch(t){throw e=0,t}},Le=(i,e)=>{for(var t in e)J(i,t,{get:e[t],enumerable:!0})},Q=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of $t(e))!Jt.call(i,n)&&n!==t&&J(i,n,{get:()=>e[n],enumerable:!(r=Zt(e,n))||r.enumerable});return i},b=(i,e,t)=>(Q(i,e,"default"),t&&Q(t,e,"default")),d=(i,e,t)=>(t=i!=null?Kt(Qt(i)):{},Q(e||!i||!i.__esModule?J(t,"default",{value:i,enumerable:!0}):t,i)),Xt=i=>Q(J({},"__esModule",{value:!0}),i);var _=Be((Wr,Oe)=>{Oe.exports=globalThis.deck});var Ye=Be((Jr,We)=>{We.exports=globalThis.luma});var $={};Le($,{BrushingExtension:()=>Ne,ClipExtension:()=>At,CollisionFilterExtension:()=>wt,DataFilterExtension:()=>Xe,FillStyleExtension:()=>Et,Fp64Extension:()=>_t,MaskExtension:()=>Nt,PathStyleExtension:()=>xt,_TerrainExtension:()=>Yt,project64:()=>ne});var x={},we=d(_(),1);b(x,d(_(),1));if(!we.Layer)throw new Error("@deck.gl/core is not found");b($,x);var ke=d(_(),1);var Ie=d(_(),1),Re=`layout(std140) uniform brushingUniforms {
|
|
8
8
|
bool enabled;
|
|
9
9
|
highp int target;
|
|
10
10
|
vec2 mousePos;
|
|
11
11
|
float radius;
|
|
12
12
|
} brushing;
|
|
13
|
-
`,
|
|
13
|
+
`,ei=`
|
|
14
14
|
in vec2 brushingTargets;
|
|
15
15
|
|
|
16
16
|
out float brushing_isVisible;
|
|
@@ -33,15 +33,15 @@
|
|
|
33
33
|
void brushing_setVisible(bool visible) {
|
|
34
34
|
brushing_isVisible = float(visible);
|
|
35
35
|
}
|
|
36
|
-
`,
|
|
37
|
-
${
|
|
38
|
-
${
|
|
39
|
-
`,
|
|
36
|
+
`,ti=`
|
|
37
|
+
${Re}
|
|
38
|
+
${ei}
|
|
39
|
+
`,ii=`
|
|
40
40
|
in float brushing_isVisible;
|
|
41
|
-
`,
|
|
42
|
-
${
|
|
43
|
-
${
|
|
44
|
-
`,
|
|
41
|
+
`,ri=`
|
|
42
|
+
${Re}
|
|
43
|
+
${ii}
|
|
44
|
+
`,ni={source:0,target:1,custom:2,source_target:3},oi={"vs:DECKGL_FILTER_GL_POSITION":`
|
|
45
45
|
vec2 brushingTarget;
|
|
46
46
|
vec2 brushingSource;
|
|
47
47
|
if (brushing.target == 3) {
|
|
@@ -65,7 +65,7 @@ ${tr}
|
|
|
65
65
|
if (brushing.enabled && brushing_isVisible < 0.5) {
|
|
66
66
|
discard;
|
|
67
67
|
}
|
|
68
|
-
`},
|
|
68
|
+
`},Ce={name:"brushing",dependencies:[Ie.project],vs:ti,fs:ri,inject:oi,getUniforms:i=>{if(!i||!("viewport"in i))return{};let{brushingEnabled:e=!0,brushingRadius:t=1e4,brushingTarget:r="source",mousePosition:n,viewport:o}=i;return{enabled:!!(e&&n&&o.containsPixel(n)),radius:t,target:ni[r]||0,mousePos:n?o.unproject([n.x-o.x,n.y-o.y]):[0,0]}},uniformTypes:{enabled:"i32",target:"i32",mousePos:"vec2<f32>",radius:"f32"}};var si={getBrushingTarget:{type:"accessor",value:[0,0]},brushingTarget:"source",brushingEnabled:!0,brushingRadius:1e4},L=class extends ke.LayerExtension{getShaders(){return{modules:[Ce]}}initializeState(e,t){let r=this.getAttributeManager();r&&r.add({brushingTargets:{size:2,stepMode:"dynamic",accessor:"getBrushingTarget"}});let n=()=>{this.getCurrentLayer()?.setNeedsRedraw()};this.state.onMouseMove=n,e.deck&&e.deck.eventManager.on({pointermove:n,pointerleave:n})}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:n}=e.context,{brushingEnabled:o,brushingRadius:s,brushingTarget:a}=this.props,f={viewport:r,mousePosition:n,brushingEnabled:o,brushingRadius:s,brushingTarget:a};this.setShaderModuleProps({brushing:f})}};L.defaultProps=si;L.extensionName="BrushingExtension";var Ne=L;var E=d(_(),1);var De=`layout(std140) uniform dataFilterUniforms {
|
|
69
69
|
bool useSoftMargin;
|
|
70
70
|
bool enabled;
|
|
71
71
|
bool transformSize;
|
|
@@ -78,7 +78,7 @@ ${tr}
|
|
|
78
78
|
vec4 max64High;
|
|
79
79
|
highp uvec4 categoryBitMask;
|
|
80
80
|
} dataFilter;
|
|
81
|
-
`,
|
|
81
|
+
`,ai=`
|
|
82
82
|
#ifdef DATAFILTER_TYPE
|
|
83
83
|
in DATAFILTER_TYPE filterValues;
|
|
84
84
|
#ifdef DATAFILTER_DOUBLE
|
|
@@ -241,13 +241,13 @@ float dataFilter_reduceValue(vec4 value) {
|
|
|
241
241
|
#endif
|
|
242
242
|
`,ze=`
|
|
243
243
|
${De}
|
|
244
|
-
${
|
|
245
|
-
`,
|
|
244
|
+
${ai}
|
|
245
|
+
`,fi=`
|
|
246
246
|
in float dataFilter_value;
|
|
247
247
|
`,Ve=`
|
|
248
248
|
${De}
|
|
249
|
-
${
|
|
250
|
-
`;function
|
|
249
|
+
${fi}
|
|
250
|
+
`;function Ue(i){if(!i||!("extensions"in i))return{};let{filterRange:e=[-1,1],filterEnabled:t=!0,filterTransformSize:r=!0,filterTransformColor:n=!0,categoryBitMask:o}=i,s=i.filterSoftRange||e,a=f=>Array.isArray(f)?[f[0]||0,f[1]||0,f[2]||0,f[3]||0]:[f,0,0,0];return{...Number.isFinite(e[0])?{min:a(e[0]),softMin:a(s[0]),softMax:a(s[1]),max:a(e[1])}:{min:a(e.map(f=>f[0])),softMin:a(s.map(f=>f[0])),softMax:a(s.map(f=>f[1])),max:a(e.map(f=>f[1]))},enabled:t,useSoftMargin:!!i.filterSoftRange,transformSize:t&&r,transformColor:t&&n,...o&&{categoryBitMask:o}}}function li(i){if(!i||!("extensions"in i))return{};let e=Ue(i),t=e.min.map(Math.fround);e.min=e.min.map((n,o)=>n-t[o]),e.softMin=e.softMin.map((n,o)=>n-t[o]),e.min64High=t;let r=e.max.map(Math.fround);return e.max=e.max.map((n,o)=>n-r[o]),e.softMax=e.softMax.map((n,o)=>n-r[o]),e.max64High=r,e}var je={"vs:#main-start":`
|
|
251
251
|
dataFilter_value = 1.0;
|
|
252
252
|
if (dataFilter.enabled) {
|
|
253
253
|
#ifdef DATAFILTER_TYPE
|
|
@@ -278,7 +278,7 @@ ${nr}
|
|
|
278
278
|
if (dataFilter.transformColor) {
|
|
279
279
|
color.a *= dataFilter_value;
|
|
280
280
|
}
|
|
281
|
-
`};function Ge(
|
|
281
|
+
`};function Ge(i){return{useSoftMargin:"i32",enabled:"i32",transformSize:"i32",transformColor:"i32",min:"vec4<f32>",softMin:"vec4<f32>",softMax:"vec4<f32>",max:"vec4<f32>",min64High:"vec4<f32>",max64High:"vec4<f32>",categoryBitMask:"vec4<u32>"}}var He={name:"dataFilter",vs:ze,fs:Ve,inject:je,getUniforms:Ue,uniformTypesFromOptions:Ge},qe={name:"dataFilter",vs:ze,fs:Ve,inject:je,getUniforms:li,uniformTypesFromOptions:Ge};var Ke=d(Ye(),1),ui=`#version 300 es
|
|
282
282
|
#define SHADER_NAME data-filter-vertex-shader
|
|
283
283
|
|
|
284
284
|
#ifdef FLOAT_TARGET
|
|
@@ -309,7 +309,7 @@ void main() {
|
|
|
309
309
|
#endif
|
|
310
310
|
gl_PointSize = 1.0;
|
|
311
311
|
}
|
|
312
|
-
`,
|
|
312
|
+
`,ci=`#version 300 es
|
|
313
313
|
#define SHADER_NAME data-filter-fragment-shader
|
|
314
314
|
precision highp float;
|
|
315
315
|
|
|
@@ -323,7 +323,7 @@ void main() {
|
|
|
323
323
|
}
|
|
324
324
|
fragColor = vColor;
|
|
325
325
|
}
|
|
326
|
-
`,pr=["float32-renderable-webgl","texture-blend-float-webgl"];function $e(r){return pr.every(e=>r.features.has(e))}function Ze(r,e){return e?r.createFramebuffer({width:1,height:1,colorAttachments:[r.createTexture({format:"rgba32float",dimension:"2d",width:1,height:1})]}):r.createFramebuffer({width:256,height:64,colorAttachments:[r.createTexture({format:"rgba8unorm",dimension:"2d",width:256,height:64})]})}function Je(r,e,t,o){return t.defines.NON_INSTANCED_MODEL=1,o&&(t.defines.FLOAT_TARGET=1),new Ye.Model(r,{id:"data-filter-aggregation-model",vertexCount:1,isInstanced:!1,topology:"point-list",disableWarnings:!0,vs:cr,fs:fr,bufferLayout:e,...t})}var Xe={blend:!0,blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",blendColorOperation:"add",blendAlphaOperation:"add",depthCompare:"never"};var dr={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},_r={categorySize:0,filterSize:1,fp64:!1,countItems:!1},mr={1:"uint",2:"uvec2",3:"uvec3",4:"uvec4"},hr={1:"float",2:"vec2",3:"vec3",4:"vec4"},I=class extends M.LayerExtension{constructor(e={}){super({..._r,...e})}getShaders(e){let{categorySize:t,filterSize:o,fp64:i}=e.opts,s={};t&&(s.DATACATEGORY_TYPE=mr[t],s.DATACATEGORY_CHANNELS=t),o&&(s.DATAFILTER_TYPE=hr[o],s.DATAFILTER_DOUBLE=Boolean(i));let a=i?qe:He;return a.uniformTypes=a.uniformTypesFromOptions(e.opts),{modules:[a],defines:s}}initializeState(e,t){let o=this.getAttributeManager(),{categorySize:i,filterSize:s,fp64:a}=t.opts;o&&(s&&o.add({filterValues:{size:s,type:a?"float64":"float32",stepMode:"dynamic",accessor:"getFilterValue"}}),i&&o.add({filterCategoryValues:{size:i,stepMode:"dynamic",accessor:"getFilterCategory",type:"uint32",transform:i===1?l=>t._getCategoryKey.call(this,l,0):l=>l.map((c,p)=>t._getCategoryKey.call(this,c,p))}}));let{device:n}=this.context;if(o&&t.opts.countItems){let l=$e(n);o.add({filterVertexIndices:{size:l?1:2,vertexOffset:1,type:"unorm8",accessor:(f,{index:u})=>{let m=f&&f.__source?f.__source.index:u;return l?(m+1)%255:[(m+1)%255,Math.floor(m/255)%255]},shaderAttributes:{filterPrevIndices:{vertexOffset:0},filterIndices:{vertexOffset:1}}}});let c=Ze(n,l),p=Je(n,o.getBufferLayouts({isInstanced:!1}),t.getShaders.call(this,t),l);this.setState({filterFBO:c,filterModel:p})}}updateState({props:e,oldProps:t,changeFlags:o},i){let s=this.getAttributeManager(),{categorySize:a}=i.opts;if(this.state.filterModel){let n=s.attributes.filterValues?.needsUpdate()||s.attributes.filterCategoryValues?.needsUpdate()||e.filterEnabled!==t.filterEnabled||e.filterRange!==t.filterRange||e.filterSoftRange!==t.filterSoftRange||e.filterCategories!==t.filterCategories;n&&this.setState({filterNeedsUpdate:n})}s?.attributes.filterCategoryValues&&((s.attributes.filterCategoryValues.needsUpdate()||!(0,M._deepEqual)(e.filterCategories,t.filterCategories,2))&&this.setState({categoryBitMask:null}),o.dataChanged&&(this.setState({categoryMap:Array(a).fill(0).map(()=>({}))}),s.attributes.filterCategoryValues.setNeedsUpdate("categoryMap")))}draw(e,t){let o=this.state.filterFBO,i=this.state.filterModel,s=this.state.filterNeedsUpdate;this.state.categoryBitMask||t._updateCategoryBitMask.call(this,e,t);let{onFilteredItemsChange:a,extensions:n,filterEnabled:l,filterRange:c,filterSoftRange:p,filterTransformSize:f,filterTransformColor:u,filterCategories:m}=this.props,h={extensions:n,filterEnabled:l,filterRange:c,filterSoftRange:p,filterTransformSize:f,filterTransformColor:u,filterCategories:m};if(this.state.categoryBitMask&&(h.categoryBitMask=this.state.categoryBitMask),this.setShaderModuleProps({dataFilter:h}),s&&a&&i){let b=this.getAttributeManager(),{attributes:{filterValues:v,filterCategoryValues:L,filterVertexIndices:pe}}=b;i.setVertexCount(this.getNumInstances());let ue={...v?.getValue(),...L?.getValue(),...pe?.getValue()};i.setAttributes(ue),i.shaderInputs.setProps({dataFilter:h});let de=[0,0,o.width,o.height],Te=i.device.beginRenderPass({id:"data-filter-aggregation",framebuffer:o,parameters:{viewport:de},clearColor:[0,0,0,0]});i.setParameters(Xe),i.draw(Te),Te.end();let Oe=i.device.readPixelsToArrayWebGL(o),Ae=0;for(let _e=0;_e<Oe.length;_e++)Ae+=Oe[_e];a({id:this.id,count:Ae}),this.state.filterNeedsUpdate=!1}}finalizeState(){let e=this.state.filterFBO,t=this.state.filterModel;e?.destroy(),t?.destroy()}_updateCategoryBitMask(e,t){let{categorySize:o}=t.opts;if(!o)return;let{filterCategories:i}=this.props,s=new Uint32Array([0,0,0,0]),a=o===1?[i]:i,n=o===1?128:o===2?64:32;for(let l=0;l<a.length;l++){let c=a[l];for(let p of c){let f=t._getCategoryKey.call(this,p,l);if(f<n){let u=l*(n/32)+Math.floor(f/32);s[u]+=Math.pow(2,f%32)}else M.log.warn(`Exceeded maximum number of categories (${n})`)()}}this.state.categoryBitMask=s}_getCategoryKey(e,t){let o=this.state.categoryMap[t];return e in o||(o[e]=Object.keys(o).length),o[e]}};I.defaultProps=dr;I.extensionName="DataFilterExtension";var Qe=I;var ut=d(_(),1);var ti=1/Math.PI*180,ri=1/180*Math.PI,vr={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...vr}};var R=globalThis.mathgl.config;function me(r){return Array.isArray(r)||ArrayBuffer.isView(r)&&!(r instanceof DataView)}function E(r,e,t){let o=R.EPSILON;t&&(R.EPSILON=t);try{if(r===e)return!0;if(me(r)&&me(e)){if(r.length!==e.length)return!1;for(let i=0;i<r.length;++i)if(!E(r[i],e[i]))return!1;return!0}return r&&r.equals?r.equals(e):e&&e.equals?e.equals(r):typeof r=="number"&&typeof e=="number"?Math.abs(r-e)<=R.EPSILON*Math.max(1,Math.abs(r),Math.abs(e)):!1}finally{R.EPSILON=o}}var C=typeof Float32Array<"u"?Float32Array:Array,he=Math.random;function ee(r){return r>=0?Math.round(r):r%.5===0?Math.floor(r):Math.round(r)}var ii=Math.PI/180;var k={};Se(k,{add:()=>Mr,angle:()=>Wr,bezier:()=>Dr,ceil:()=>Er,clone:()=>xr,copy:()=>Pr,create:()=>et,cross:()=>kr,dist:()=>eo,distance:()=>st,div:()=>Qr,divide:()=>it,dot:()=>ge,equals:()=>Zr,exactEquals:()=>$r,floor:()=>Fr,forEach:()=>io,fromValues:()=>yr,hermite:()=>Br,inverse:()=>Rr,len:()=>ro,length:()=>tt,lerp:()=>wr,max:()=>Or,min:()=>Tr,mul:()=>Xr,multiply:()=>ot,negate:()=>Ir,normalize:()=>Cr,random:()=>zr,rotateX:()=>Gr,rotateY:()=>Hr,rotateZ:()=>qr,round:()=>Ar,scale:()=>Lr,scaleAndAdd:()=>Sr,set:()=>br,slerp:()=>Nr,sqrDist:()=>to,sqrLen:()=>oo,squaredDistance:()=>at,squaredLength:()=>nt,str:()=>Yr,sub:()=>Jr,subtract:()=>rt,transformMat3:()=>jr,transformMat4:()=>Vr,transformQuat:()=>Ur,zero:()=>Kr});function et(){let r=new C(3);return C!=Float32Array&&(r[0]=0,r[1]=0,r[2]=0),r}function xr(r){let e=new C(3);return e[0]=r[0],e[1]=r[1],e[2]=r[2],e}function tt(r){let e=r[0],t=r[1],o=r[2];return Math.sqrt(e*e+t*t+o*o)}function yr(r,e,t){let o=new C(3);return o[0]=r,o[1]=e,o[2]=t,o}function Pr(r,e){return r[0]=e[0],r[1]=e[1],r[2]=e[2],r}function br(r,e,t,o){return r[0]=e,r[1]=t,r[2]=o,r}function Mr(r,e,t){return r[0]=e[0]+t[0],r[1]=e[1]+t[1],r[2]=e[2]+t[2],r}function rt(r,e,t){return r[0]=e[0]-t[0],r[1]=e[1]-t[1],r[2]=e[2]-t[2],r}function ot(r,e,t){return r[0]=e[0]*t[0],r[1]=e[1]*t[1],r[2]=e[2]*t[2],r}function it(r,e,t){return r[0]=e[0]/t[0],r[1]=e[1]/t[1],r[2]=e[2]/t[2],r}function Er(r,e){return r[0]=Math.ceil(e[0]),r[1]=Math.ceil(e[1]),r[2]=Math.ceil(e[2]),r}function Fr(r,e){return r[0]=Math.floor(e[0]),r[1]=Math.floor(e[1]),r[2]=Math.floor(e[2]),r}function Tr(r,e,t){return r[0]=Math.min(e[0],t[0]),r[1]=Math.min(e[1],t[1]),r[2]=Math.min(e[2],t[2]),r}function Or(r,e,t){return r[0]=Math.max(e[0],t[0]),r[1]=Math.max(e[1],t[1]),r[2]=Math.max(e[2],t[2]),r}function Ar(r,e){return r[0]=ee(e[0]),r[1]=ee(e[1]),r[2]=ee(e[2]),r}function Lr(r,e,t){return r[0]=e[0]*t,r[1]=e[1]*t,r[2]=e[2]*t,r}function Sr(r,e,t,o){return r[0]=e[0]+t[0]*o,r[1]=e[1]+t[1]*o,r[2]=e[2]+t[2]*o,r}function st(r,e){let t=e[0]-r[0],o=e[1]-r[1],i=e[2]-r[2];return Math.sqrt(t*t+o*o+i*i)}function at(r,e){let t=e[0]-r[0],o=e[1]-r[1],i=e[2]-r[2];return t*t+o*o+i*i}function nt(r){let e=r[0],t=r[1],o=r[2];return e*e+t*t+o*o}function Ir(r,e){return r[0]=-e[0],r[1]=-e[1],r[2]=-e[2],r}function Rr(r,e){return r[0]=1/e[0],r[1]=1/e[1],r[2]=1/e[2],r}function Cr(r,e){let t=e[0],o=e[1],i=e[2],s=t*t+o*o+i*i;return s>0&&(s=1/Math.sqrt(s)),r[0]=e[0]*s,r[1]=e[1]*s,r[2]=e[2]*s,r}function ge(r,e){return r[0]*e[0]+r[1]*e[1]+r[2]*e[2]}function kr(r,e,t){let o=e[0],i=e[1],s=e[2],a=t[0],n=t[1],l=t[2];return r[0]=i*l-s*n,r[1]=s*a-o*l,r[2]=o*n-i*a,r}function wr(r,e,t,o){let i=e[0],s=e[1],a=e[2];return r[0]=i+o*(t[0]-i),r[1]=s+o*(t[1]-s),r[2]=a+o*(t[2]-a),r}function Nr(r,e,t,o){let i=Math.acos(Math.min(Math.max(ge(e,t),-1),1)),s=Math.sin(i),a=Math.sin((1-o)*i)/s,n=Math.sin(o*i)/s;return r[0]=a*e[0]+n*t[0],r[1]=a*e[1]+n*t[1],r[2]=a*e[2]+n*t[2],r}function Br(r,e,t,o,i,s){let a=s*s,n=a*(2*s-3)+1,l=a*(s-2)+s,c=a*(s-1),p=a*(3-2*s);return r[0]=e[0]*n+t[0]*l+o[0]*c+i[0]*p,r[1]=e[1]*n+t[1]*l+o[1]*c+i[1]*p,r[2]=e[2]*n+t[2]*l+o[2]*c+i[2]*p,r}function Dr(r,e,t,o,i,s){let a=1-s,n=a*a,l=s*s,c=n*a,p=3*s*n,f=3*l*a,u=l*s;return r[0]=e[0]*c+t[0]*p+o[0]*f+i[0]*u,r[1]=e[1]*c+t[1]*p+o[1]*f+i[1]*u,r[2]=e[2]*c+t[2]*p+o[2]*f+i[2]*u,r}function zr(r,e){e=e===void 0?1:e;let t=he()*2*Math.PI,o=he()*2-1,i=Math.sqrt(1-o*o)*e;return r[0]=Math.cos(t)*i,r[1]=Math.sin(t)*i,r[2]=o*e,r}function Vr(r,e,t){let o=e[0],i=e[1],s=e[2],a=t[3]*o+t[7]*i+t[11]*s+t[15];return a=a||1,r[0]=(t[0]*o+t[4]*i+t[8]*s+t[12])/a,r[1]=(t[1]*o+t[5]*i+t[9]*s+t[13])/a,r[2]=(t[2]*o+t[6]*i+t[10]*s+t[14])/a,r}function jr(r,e,t){let o=e[0],i=e[1],s=e[2];return r[0]=o*t[0]+i*t[3]+s*t[6],r[1]=o*t[1]+i*t[4]+s*t[7],r[2]=o*t[2]+i*t[5]+s*t[8],r}function Ur(r,e,t){let o=t[0],i=t[1],s=t[2],a=t[3],n=e[0],l=e[1],c=e[2],p=i*c-s*l,f=s*n-o*c,u=o*l-i*n,m=i*u-s*f,h=s*p-o*u,b=o*f-i*p,v=a*2;return p*=v,f*=v,u*=v,m*=2,h*=2,b*=2,r[0]=n+p+m,r[1]=l+f+h,r[2]=c+u+b,r}function Gr(r,e,t,o){let i=[],s=[];return i[0]=e[0]-t[0],i[1]=e[1]-t[1],i[2]=e[2]-t[2],s[0]=i[0],s[1]=i[1]*Math.cos(o)-i[2]*Math.sin(o),s[2]=i[1]*Math.sin(o)+i[2]*Math.cos(o),r[0]=s[0]+t[0],r[1]=s[1]+t[1],r[2]=s[2]+t[2],r}function Hr(r,e,t,o){let i=[],s=[];return i[0]=e[0]-t[0],i[1]=e[1]-t[1],i[2]=e[2]-t[2],s[0]=i[2]*Math.sin(o)+i[0]*Math.cos(o),s[1]=i[1],s[2]=i[2]*Math.cos(o)-i[0]*Math.sin(o),r[0]=s[0]+t[0],r[1]=s[1]+t[1],r[2]=s[2]+t[2],r}function qr(r,e,t,o){let i=[],s=[];return i[0]=e[0]-t[0],i[1]=e[1]-t[1],i[2]=e[2]-t[2],s[0]=i[0]*Math.cos(o)-i[1]*Math.sin(o),s[1]=i[0]*Math.sin(o)+i[1]*Math.cos(o),s[2]=i[2],r[0]=s[0]+t[0],r[1]=s[1]+t[1],r[2]=s[2]+t[2],r}function Wr(r,e){let t=r[0],o=r[1],i=r[2],s=e[0],a=e[1],n=e[2],l=Math.sqrt((t*t+o*o+i*i)*(s*s+a*a+n*n)),c=l&&ge(r,e)/l;return Math.acos(Math.min(Math.max(c,-1),1))}function Kr(r){return r[0]=0,r[1]=0,r[2]=0,r}function Yr(r){return`vec3(${r[0]}, ${r[1]}, ${r[2]})`}function $r(r,e){return r[0]===e[0]&&r[1]===e[1]&&r[2]===e[2]}function Zr(r,e){let t=r[0],o=r[1],i=r[2],s=e[0],a=e[1],n=e[2];return Math.abs(t-s)<=1e-6*Math.max(1,Math.abs(t),Math.abs(s))&&Math.abs(o-a)<=1e-6*Math.max(1,Math.abs(o),Math.abs(a))&&Math.abs(i-n)<=1e-6*Math.max(1,Math.abs(i),Math.abs(n))}var Jr=rt,Xr=ot,Qr=it,eo=st,to=at,ro=tt,oo=nt,io=function(){let r=et();return function(e,t,o,i,s,a){let n,l;for(t||(t=3),o||(o=0),i?l=Math.min(i*t+o,e.length):l=e.length,n=o;n<l;n+=t)r[0]=e[n],r[1]=e[n+1],r[2]=e[n+2],s(r,r,a),e[n]=r[0],e[n+1]=r[1],e[n+2]=r[2];return e}}();function te(r,e=[],t=0){let o=Math.fround(r),i=r-o;return e[t]=o,e[t+1]=i,e}function xe(r){return r-Math.fround(r)}function ye(r){let e=new Float32Array(32);for(let t=0;t<4;++t)for(let o=0;o<4;++o){let i=t*4+o;te(r[o*4+t],e,i*2)}return e}var Pe=`
|
|
326
|
+
`,pi=["float32-renderable-webgl","texture-blend-float-webgl"];function Ze(i){return pi.every(e=>i.features.has(e))}function $e(i,e){return e?i.createFramebuffer({width:1,height:1,colorAttachments:[i.createTexture({format:"rgba32float",dimension:"2d",width:1,height:1})]}):i.createFramebuffer({width:256,height:64,colorAttachments:[i.createTexture({format:"rgba8unorm",dimension:"2d",width:256,height:64})]})}function Qe(i,e,t,r){return t.defines.NON_INSTANCED_MODEL=1,r&&(t.defines.FLOAT_TARGET=1),new Ke.Model(i,{id:"data-filter-aggregation-model",vertexCount:1,isInstanced:!1,topology:"point-list",disableWarnings:!0,vs:ui,fs:ci,bufferLayout:e,...t})}var Je={blend:!0,blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one",blendColorOperation:"add",blendAlphaOperation:"add",depthCompare:"never"};var _i={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},mi={categorySize:0,filterSize:1,fp64:!1,countItems:!1},hi={1:"uint",2:"uvec2",3:"uvec3",4:"uvec4"},gi={1:"float",2:"vec2",3:"vec3",4:"vec4"},O=class extends E.LayerExtension{constructor(e={}){super({...mi,...e})}getShaders(e){let{categorySize:t,filterSize:r,fp64:n}=e.opts,o={};t&&(o.DATACATEGORY_TYPE=hi[t],o.DATACATEGORY_CHANNELS=t),r&&(o.DATAFILTER_TYPE=gi[r],o.DATAFILTER_DOUBLE=!!n);let s=n?qe:He;return s.uniformTypes=s.uniformTypesFromOptions(e.opts),{modules:[s],defines:o}}initializeState(e,t){let r=this.getAttributeManager(),{categorySize:n,filterSize:o,fp64:s}=t.opts;r&&(o&&r.add({filterValues:{size:o,type:s?"float64":"float32",stepMode:"dynamic",accessor:"getFilterValue"}}),n&&r.add({filterCategoryValues:{size:n,stepMode:"dynamic",accessor:"getFilterCategory",type:"uint32",transform:n===1?f=>t._getCategoryKey.call(this,f,0):f=>f.map((l,c)=>t._getCategoryKey.call(this,l,c))}}));let{device:a}=this.context;if(r&&t.opts.countItems){let f=Ze(a);r.add({filterVertexIndices:{size:f?1:2,vertexOffset:1,type:"unorm8",accessor:(u,{index:p})=>{let m=u&&u.__source?u.__source.index:p;return f?(m+1)%255:[(m+1)%255,Math.floor(m/255)%255]},shaderAttributes:{filterPrevIndices:{vertexOffset:0},filterIndices:{vertexOffset:1}}}});let l=$e(a,f),c=Qe(a,r.getBufferLayouts({isInstanced:!1}),t.getShaders.call(this,t),f);this.setState({filterFBO:l,filterModel:c})}}updateState({props:e,oldProps:t,changeFlags:r},n){let o=this.getAttributeManager(),{categorySize:s}=n.opts;if(this.state.filterModel){let a=o.attributes.filterValues?.needsUpdate()||o.attributes.filterCategoryValues?.needsUpdate()||e.filterEnabled!==t.filterEnabled||e.filterRange!==t.filterRange||e.filterSoftRange!==t.filterSoftRange||e.filterCategories!==t.filterCategories;a&&this.setState({filterNeedsUpdate:a})}o?.attributes.filterCategoryValues&&((o.attributes.filterCategoryValues.needsUpdate()||!(0,E._deepEqual)(e.filterCategories,t.filterCategories,2))&&this.setState({categoryBitMask:null}),r.dataChanged&&(this.setState({categoryMap:Array(s).fill(0).map(()=>({}))}),o.attributes.filterCategoryValues.setNeedsUpdate("categoryMap")))}draw(e,t){let r=this.state.filterFBO,n=this.state.filterModel,o=this.state.filterNeedsUpdate;this.state.categoryBitMask||t._updateCategoryBitMask.call(this,e,t);let{onFilteredItemsChange:s,extensions:a,filterEnabled:f,filterRange:l,filterSoftRange:c,filterTransformSize:u,filterTransformColor:p,filterCategories:m}=this.props,h={extensions:a,filterEnabled:f,filterRange:l,filterSoftRange:c,filterTransformSize:u,filterTransformColor:p,filterCategories:m};if(this.state.categoryBitMask&&(h.categoryBitMask=this.state.categoryBitMask),this.setShaderModuleProps({dataFilter:h}),o&&s&&n){let P=this.getAttributeManager(),{attributes:{filterValues:g,filterCategoryValues:B,filterVertexIndices:ce}}=P;n.setVertexCount(this.getNumInstances());let pe={...g?.getValue(),...B?.getValue(),...ce?.getValue()};n.setAttributes(pe),n.shaderInputs.setProps({dataFilter:h});let de=[0,0,r.width,r.height],Ae=n.device.beginRenderPass({id:"data-filter-aggregation",framebuffer:r,parameters:{viewport:de},clearColor:[0,0,0,0]});n.setParameters(Je),n.draw(Ae),Ae.end();let Se=n.device.readPixelsToArrayWebGL(r),Te=0;for(let _e=0;_e<Se.length;_e++)Te+=Se[_e];s({id:this.id,count:Te}),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:n}=this.props,o=new Uint32Array([0,0,0,0]),s=r===1?[n]:n,a=r===1?128:r===2?64:32;for(let f=0;f<s.length;f++){let l=s[f];for(let c of l){let u=t._getCategoryKey.call(this,c,f);if(u<a){let p=f*(a/32)+Math.floor(u/32);o[p]+=Math.pow(2,u%32)}else E.log.warn(`Exceeded maximum number of categories (${a})`)()}}this.state.categoryBitMask=o}_getCategoryKey(e,t){let r=this.state.categoryMap[t];return e in r||(r[e]=Object.keys(r).length),r[e]}};O.defaultProps=_i;O.extensionName="DataFilterExtension";var Xe=O;var dt=d(_(),1);var tn=1/Math.PI*180,rn=1/180*Math.PI,vi={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...vi}};var w=globalThis.mathgl.config;function me(i){return Array.isArray(i)||ArrayBuffer.isView(i)&&!(i instanceof DataView)}function M(i,e,t){let r=w.EPSILON;t&&(w.EPSILON=t);try{if(i===e)return!0;if(me(i)&&me(e)){if(i.length!==e.length)return!1;for(let n=0;n<i.length;++n)if(!M(i[n],e[n]))return!1;return!0}return i&&i.equals?i.equals(e):e&&e.equals?e.equals(i):typeof i=="number"&&typeof e=="number"?Math.abs(i-e)<=w.EPSILON*Math.max(1,Math.abs(i),Math.abs(e)):!1}finally{w.EPSILON=r}}var I=typeof Float32Array<"u"?Float32Array:Array,he=Math.random;function X(i){return i>=0?Math.round(i):i%.5===0?Math.floor(i):Math.round(i)}var on=Math.PI/180;var ee={};Le(ee,{add:()=>Mi,angle:()=>Yi,bezier:()=>zi,ceil:()=>Fi,clone:()=>bi,copy:()=>Pi,create:()=>et,cross:()=>Ci,dist:()=>tr,distance:()=>ot,div:()=>er,divide:()=>nt,dot:()=>ve,equals:()=>Qi,exactEquals:()=>$i,floor:()=>Ai,forEach:()=>or,fromValues:()=>yi,hermite:()=>Di,inverse:()=>Ii,len:()=>rr,length:()=>tt,lerp:()=>ki,max:()=>Ti,min:()=>Si,mul:()=>Xi,multiply:()=>rt,negate:()=>wi,normalize:()=>Ri,random:()=>Vi,rotateX:()=>Hi,rotateY:()=>qi,rotateZ:()=>Wi,round:()=>Bi,scale:()=>Li,scaleAndAdd:()=>Oi,set:()=>Ei,slerp:()=>Ni,sqrDist:()=>ir,sqrLen:()=>nr,squaredDistance:()=>st,squaredLength:()=>at,str:()=>Zi,sub:()=>Ji,subtract:()=>it,transformMat3:()=>ji,transformMat4:()=>Ui,transformQuat:()=>Gi,zero:()=>Ki});function et(){let i=new I(3);return I!=Float32Array&&(i[0]=0,i[1]=0,i[2]=0),i}function bi(i){let e=new I(3);return e[0]=i[0],e[1]=i[1],e[2]=i[2],e}function tt(i){let e=i[0],t=i[1],r=i[2];return Math.sqrt(e*e+t*t+r*r)}function yi(i,e,t){let r=new I(3);return r[0]=i,r[1]=e,r[2]=t,r}function Pi(i,e){return i[0]=e[0],i[1]=e[1],i[2]=e[2],i}function Ei(i,e,t,r){return i[0]=e,i[1]=t,i[2]=r,i}function Mi(i,e,t){return i[0]=e[0]+t[0],i[1]=e[1]+t[1],i[2]=e[2]+t[2],i}function it(i,e,t){return i[0]=e[0]-t[0],i[1]=e[1]-t[1],i[2]=e[2]-t[2],i}function rt(i,e,t){return i[0]=e[0]*t[0],i[1]=e[1]*t[1],i[2]=e[2]*t[2],i}function nt(i,e,t){return i[0]=e[0]/t[0],i[1]=e[1]/t[1],i[2]=e[2]/t[2],i}function Fi(i,e){return i[0]=Math.ceil(e[0]),i[1]=Math.ceil(e[1]),i[2]=Math.ceil(e[2]),i}function Ai(i,e){return i[0]=Math.floor(e[0]),i[1]=Math.floor(e[1]),i[2]=Math.floor(e[2]),i}function Si(i,e,t){return i[0]=Math.min(e[0],t[0]),i[1]=Math.min(e[1],t[1]),i[2]=Math.min(e[2],t[2]),i}function Ti(i,e,t){return i[0]=Math.max(e[0],t[0]),i[1]=Math.max(e[1],t[1]),i[2]=Math.max(e[2],t[2]),i}function Bi(i,e){return i[0]=X(e[0]),i[1]=X(e[1]),i[2]=X(e[2]),i}function Li(i,e,t){return i[0]=e[0]*t,i[1]=e[1]*t,i[2]=e[2]*t,i}function Oi(i,e,t,r){return i[0]=e[0]+t[0]*r,i[1]=e[1]+t[1]*r,i[2]=e[2]+t[2]*r,i}function ot(i,e){let t=e[0]-i[0],r=e[1]-i[1],n=e[2]-i[2];return Math.sqrt(t*t+r*r+n*n)}function st(i,e){let t=e[0]-i[0],r=e[1]-i[1],n=e[2]-i[2];return t*t+r*r+n*n}function at(i){let e=i[0],t=i[1],r=i[2];return e*e+t*t+r*r}function wi(i,e){return i[0]=-e[0],i[1]=-e[1],i[2]=-e[2],i}function Ii(i,e){return i[0]=1/e[0],i[1]=1/e[1],i[2]=1/e[2],i}function Ri(i,e){let t=e[0],r=e[1],n=e[2],o=t*t+r*r+n*n;return o>0&&(o=1/Math.sqrt(o)),i[0]=e[0]*o,i[1]=e[1]*o,i[2]=e[2]*o,i}function ve(i,e){return i[0]*e[0]+i[1]*e[1]+i[2]*e[2]}function Ci(i,e,t){let r=e[0],n=e[1],o=e[2],s=t[0],a=t[1],f=t[2];return i[0]=n*f-o*a,i[1]=o*s-r*f,i[2]=r*a-n*s,i}function ki(i,e,t,r){let n=e[0],o=e[1],s=e[2];return i[0]=n+r*(t[0]-n),i[1]=o+r*(t[1]-o),i[2]=s+r*(t[2]-s),i}function Ni(i,e,t,r){let n=Math.acos(Math.min(Math.max(ve(e,t),-1),1)),o=Math.sin(n),s=Math.sin((1-r)*n)/o,a=Math.sin(r*n)/o;return i[0]=s*e[0]+a*t[0],i[1]=s*e[1]+a*t[1],i[2]=s*e[2]+a*t[2],i}function Di(i,e,t,r,n,o){let s=o*o,a=s*(2*o-3)+1,f=s*(o-2)+o,l=s*(o-1),c=s*(3-2*o);return i[0]=e[0]*a+t[0]*f+r[0]*l+n[0]*c,i[1]=e[1]*a+t[1]*f+r[1]*l+n[1]*c,i[2]=e[2]*a+t[2]*f+r[2]*l+n[2]*c,i}function zi(i,e,t,r,n,o){let s=1-o,a=s*s,f=o*o,l=a*s,c=3*o*a,u=3*f*s,p=f*o;return i[0]=e[0]*l+t[0]*c+r[0]*u+n[0]*p,i[1]=e[1]*l+t[1]*c+r[1]*u+n[1]*p,i[2]=e[2]*l+t[2]*c+r[2]*u+n[2]*p,i}function Vi(i,e){e=e===void 0?1:e;let t=he()*2*Math.PI,r=he()*2-1,n=Math.sqrt(1-r*r)*e;return i[0]=Math.cos(t)*n,i[1]=Math.sin(t)*n,i[2]=r*e,i}function Ui(i,e,t){let r=e[0],n=e[1],o=e[2],s=t[3]*r+t[7]*n+t[11]*o+t[15];return s=s||1,i[0]=(t[0]*r+t[4]*n+t[8]*o+t[12])/s,i[1]=(t[1]*r+t[5]*n+t[9]*o+t[13])/s,i[2]=(t[2]*r+t[6]*n+t[10]*o+t[14])/s,i}function ji(i,e,t){let r=e[0],n=e[1],o=e[2];return i[0]=r*t[0]+n*t[3]+o*t[6],i[1]=r*t[1]+n*t[4]+o*t[7],i[2]=r*t[2]+n*t[5]+o*t[8],i}function Gi(i,e,t){let r=t[0],n=t[1],o=t[2],s=t[3],a=e[0],f=e[1],l=e[2],c=n*l-o*f,u=o*a-r*l,p=r*f-n*a,m=n*p-o*u,h=o*c-r*p,P=r*u-n*c,g=s*2;return c*=g,u*=g,p*=g,m*=2,h*=2,P*=2,i[0]=a+c+m,i[1]=f+u+h,i[2]=l+p+P,i}function Hi(i,e,t,r){let n=[],o=[];return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],o[0]=n[0],o[1]=n[1]*Math.cos(r)-n[2]*Math.sin(r),o[2]=n[1]*Math.sin(r)+n[2]*Math.cos(r),i[0]=o[0]+t[0],i[1]=o[1]+t[1],i[2]=o[2]+t[2],i}function qi(i,e,t,r){let n=[],o=[];return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],o[0]=n[2]*Math.sin(r)+n[0]*Math.cos(r),o[1]=n[1],o[2]=n[2]*Math.cos(r)-n[0]*Math.sin(r),i[0]=o[0]+t[0],i[1]=o[1]+t[1],i[2]=o[2]+t[2],i}function Wi(i,e,t,r){let n=[],o=[];return n[0]=e[0]-t[0],n[1]=e[1]-t[1],n[2]=e[2]-t[2],o[0]=n[0]*Math.cos(r)-n[1]*Math.sin(r),o[1]=n[0]*Math.sin(r)+n[1]*Math.cos(r),o[2]=n[2],i[0]=o[0]+t[0],i[1]=o[1]+t[1],i[2]=o[2]+t[2],i}function Yi(i,e){let t=i[0],r=i[1],n=i[2],o=e[0],s=e[1],a=e[2],f=Math.sqrt((t*t+r*r+n*n)*(o*o+s*s+a*a)),l=f&&ve(i,e)/f;return Math.acos(Math.min(Math.max(l,-1),1))}function Ki(i){return i[0]=0,i[1]=0,i[2]=0,i}function Zi(i){return`vec3(${i[0]}, ${i[1]}, ${i[2]})`}function $i(i,e){return i[0]===e[0]&&i[1]===e[1]&&i[2]===e[2]}function Qi(i,e){let t=i[0],r=i[1],n=i[2],o=e[0],s=e[1],a=e[2];return Math.abs(t-o)<=1e-6*Math.max(1,Math.abs(t),Math.abs(o))&&Math.abs(r-s)<=1e-6*Math.max(1,Math.abs(r),Math.abs(s))&&Math.abs(n-a)<=1e-6*Math.max(1,Math.abs(n),Math.abs(a))}var Ji=it,Xi=rt,er=nt,tr=ot,ir=st,rr=tt,nr=at,or=(function(){let i=et();return function(e,t,r,n,o,s){let a,f;for(t||(t=3),r||(r=0),n?f=Math.min(n*t+r,e.length):f=e.length,a=r;a<f;a+=t)i[0]=e[a],i[1]=e[a+1],i[2]=e[a+2],o(i,i,s),e[a]=i[0],e[a+1]=i[1],e[a+2]=i[2];return e}})();function te(i,e=[],t=0){let r=Math.fround(i),n=i-r;return e[t]=r,e[t+1]=n,e}function xe(i){return i-Math.fround(i)}function be(i){let e=new Float32Array(32);for(let t=0;t<4;++t)for(let r=0;r<4;++r){let n=t*4+r;te(i[r*4+t],e,n*2)}return e}var ye=`
|
|
327
327
|
layout(std140) uniform fp64arithmeticUniforms {
|
|
328
328
|
uniform float ONE;
|
|
329
329
|
uniform float SPLIT;
|
|
@@ -522,6 +522,456 @@ vec2 sqrt_fp64(vec2 a) {
|
|
|
522
522
|
return sum_fp64(vec2(yn, 0.0), prod);
|
|
523
523
|
#endif
|
|
524
524
|
}
|
|
525
|
+
`;var ft=`struct Fp64F32Bits {
|
|
526
|
+
sign: u32,
|
|
527
|
+
baseExponent: i32,
|
|
528
|
+
significand: u32,
|
|
529
|
+
isZero: bool,
|
|
530
|
+
isInf: bool,
|
|
531
|
+
isNan: bool,
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
// Decode an f32 as (-1)^sign * significand * 2^baseExponent.
|
|
535
|
+
fn fp64_decode_f32_bits(bits: u32) -> Fp64F32Bits {
|
|
536
|
+
let sign = bits >> 31u;
|
|
537
|
+
let exponentBits = (bits >> 23u) & 0xffu;
|
|
538
|
+
let fraction = bits & 0x7fffffu;
|
|
539
|
+
|
|
540
|
+
if (exponentBits == 0xffu) {
|
|
541
|
+
return Fp64F32Bits(sign, 0, 0u, false, fraction == 0u, fraction != 0u);
|
|
542
|
+
}
|
|
543
|
+
if (exponentBits == 0u) {
|
|
544
|
+
return Fp64F32Bits(sign, -149, fraction, fraction == 0u, false, false);
|
|
545
|
+
}
|
|
546
|
+
return Fp64F32Bits(sign, i32(exponentBits) - 150, 0x800000u | fraction, false, false, false);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
fn fp64_f32_magnitude_compare(aBits: u32, bBits: u32) -> i32 {
|
|
550
|
+
let aMagnitude = aBits & 0x7fffffffu;
|
|
551
|
+
let bMagnitude = bBits & 0x7fffffffu;
|
|
552
|
+
if (aMagnitude == bMagnitude) {
|
|
553
|
+
return 0;
|
|
554
|
+
}
|
|
555
|
+
return select(-1, 1, aMagnitude > bMagnitude);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
fn fp64_make_residual_f32_bits(
|
|
559
|
+
exactSign: u32,
|
|
560
|
+
exactMagnitude: vec2u,
|
|
561
|
+
exactBaseExponent: i32,
|
|
562
|
+
highBits: u32
|
|
563
|
+
) -> u32 {
|
|
564
|
+
if (fp64_u64_is_zero(exactMagnitude)) {
|
|
565
|
+
return 0u;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
let high = fp64_decode_f32_bits(highBits);
|
|
569
|
+
if (high.isInf || high.isNan) {
|
|
570
|
+
return exactSign << 31u;
|
|
571
|
+
}
|
|
572
|
+
if (high.isZero) {
|
|
573
|
+
return fp64_make_f32_bits_from_u64(exactSign, exactMagnitude, exactBaseExponent);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
let commonBaseExponent = min(exactBaseExponent, high.baseExponent);
|
|
577
|
+
let exactShift = exactBaseExponent - commonBaseExponent;
|
|
578
|
+
let highShift = high.baseExponent - commonBaseExponent;
|
|
579
|
+
|
|
580
|
+
// A normal two-sum/two-product residual never needs a shift this large.
|
|
581
|
+
// This guard gives deterministic underflow behavior outside that contract.
|
|
582
|
+
if (exactShift >= 64 || highShift >= 64) {
|
|
583
|
+
return exactSign << 31u;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
let exactAligned = fp64_u64_shift_left(exactMagnitude, u32(exactShift));
|
|
587
|
+
let highAligned = fp64_u64_shift_left(vec2u(0u, high.significand), u32(highShift));
|
|
588
|
+
let comparison = fp64_u64_compare(exactAligned, highAligned);
|
|
589
|
+
if (comparison == 0) {
|
|
590
|
+
return 0u;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
var residualSign = exactSign;
|
|
594
|
+
var residualMagnitude: vec2u;
|
|
595
|
+
if (comparison > 0) {
|
|
596
|
+
residualMagnitude = fp64_u64_sub(exactAligned, highAligned);
|
|
597
|
+
} else {
|
|
598
|
+
residualSign = exactSign ^ 1u;
|
|
599
|
+
residualMagnitude = fp64_u64_sub(highAligned, exactAligned);
|
|
600
|
+
}
|
|
601
|
+
return fp64_make_f32_bits_from_u64(
|
|
602
|
+
residualSign,
|
|
603
|
+
residualMagnitude,
|
|
604
|
+
commonBaseExponent
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
fn fp64_split_accumulator_bits(
|
|
609
|
+
sign: u32,
|
|
610
|
+
magnitude: vec2u,
|
|
611
|
+
baseExponent: i32
|
|
612
|
+
) -> vec2u {
|
|
613
|
+
let highBits = fp64_make_f32_bits_from_u64(sign, magnitude, baseExponent);
|
|
614
|
+
let lowBits = fp64_make_residual_f32_bits(sign, magnitude, baseExponent, highBits);
|
|
615
|
+
return vec2u(highBits, lowBits);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
fn fp64_two_sum_integer_bits(aBits: u32, bBits: u32) -> vec2u {
|
|
619
|
+
let a = fp64_decode_f32_bits(aBits);
|
|
620
|
+
let b = fp64_decode_f32_bits(bBits);
|
|
621
|
+
|
|
622
|
+
if (a.isNan || b.isNan) {
|
|
623
|
+
return vec2u(0x7fc00000u, 0u);
|
|
624
|
+
}
|
|
625
|
+
if (a.isInf || b.isInf) {
|
|
626
|
+
if (a.isInf && b.isInf && a.sign != b.sign) {
|
|
627
|
+
return vec2u(0x7fc00000u, 0u);
|
|
628
|
+
}
|
|
629
|
+
return select(vec2u(bBits, 0u), vec2u(aBits, 0u), a.isInf);
|
|
630
|
+
}
|
|
631
|
+
if (a.isZero && b.isZero) {
|
|
632
|
+
return vec2u((a.sign & b.sign) << 31u, 0u);
|
|
633
|
+
}
|
|
634
|
+
if (a.isZero) {
|
|
635
|
+
return vec2u(bBits, 0u);
|
|
636
|
+
}
|
|
637
|
+
if (b.isZero) {
|
|
638
|
+
return vec2u(aBits, 0u);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
let exponentDifference = select(
|
|
642
|
+
b.baseExponent - a.baseExponent,
|
|
643
|
+
a.baseExponent - b.baseExponent,
|
|
644
|
+
a.baseExponent >= b.baseExponent
|
|
645
|
+
);
|
|
646
|
+
|
|
647
|
+
// Beyond half an ulp, rounding cannot change the larger operand. Returning
|
|
648
|
+
// the smaller operand intact also avoids an unbounded integer alignment.
|
|
649
|
+
// At a power-of-two boundary the spacing below the larger operand is half
|
|
650
|
+
// the spacing above it, so an opposite-sign gap-25 operand can still change
|
|
651
|
+
// the rounded high limb. Gap 26 is the first universally safe early-out.
|
|
652
|
+
if (exponentDifference > 25) {
|
|
653
|
+
if (fp64_f32_magnitude_compare(aBits, bBits) >= 0) {
|
|
654
|
+
return vec2u(aBits, bBits);
|
|
655
|
+
}
|
|
656
|
+
return vec2u(bBits, aBits);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
let commonBaseExponent = min(a.baseExponent, b.baseExponent);
|
|
660
|
+
let aMagnitude = fp64_u64_shift_left(
|
|
661
|
+
vec2u(0u, a.significand),
|
|
662
|
+
u32(a.baseExponent - commonBaseExponent)
|
|
663
|
+
);
|
|
664
|
+
let bMagnitude = fp64_u64_shift_left(
|
|
665
|
+
vec2u(0u, b.significand),
|
|
666
|
+
u32(b.baseExponent - commonBaseExponent)
|
|
667
|
+
);
|
|
668
|
+
|
|
669
|
+
var resultSign = a.sign;
|
|
670
|
+
var resultMagnitude: vec2u;
|
|
671
|
+
if (a.sign == b.sign) {
|
|
672
|
+
resultMagnitude = fp64_u64_add(aMagnitude, bMagnitude);
|
|
673
|
+
} else {
|
|
674
|
+
let comparison = fp64_u64_compare(aMagnitude, bMagnitude);
|
|
675
|
+
if (comparison == 0) {
|
|
676
|
+
return vec2u(0u, 0u);
|
|
677
|
+
}
|
|
678
|
+
if (comparison > 0) {
|
|
679
|
+
resultMagnitude = fp64_u64_sub(aMagnitude, bMagnitude);
|
|
680
|
+
} else {
|
|
681
|
+
resultSign = b.sign;
|
|
682
|
+
resultMagnitude = fp64_u64_sub(bMagnitude, aMagnitude);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
return fp64_split_accumulator_bits(resultSign, resultMagnitude, commonBaseExponent);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
fn fp64_two_sum_integer(a: f32, b: f32) -> vec2f {
|
|
690
|
+
let resultBits = fp64_two_sum_integer_bits(bitcast<u32>(a), bitcast<u32>(b));
|
|
691
|
+
return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
fn fp64_multiply_significands(a: u32, b: u32) -> vec2u {
|
|
695
|
+
let aLow = a & 0xffffu;
|
|
696
|
+
let aHigh = a >> 16u;
|
|
697
|
+
let bLow = b & 0xffffu;
|
|
698
|
+
let bHigh = b >> 16u;
|
|
699
|
+
let lowProduct = aLow * bLow;
|
|
700
|
+
let crossProduct = aLow * bHigh + aHigh * bLow;
|
|
701
|
+
let highProduct = aHigh * bHigh;
|
|
702
|
+
|
|
703
|
+
var result = vec2u(0u, lowProduct);
|
|
704
|
+
result = fp64_u64_add(
|
|
705
|
+
result,
|
|
706
|
+
fp64_u64_shift_left(vec2u(0u, crossProduct), 16u)
|
|
707
|
+
);
|
|
708
|
+
result = fp64_u64_add(result, vec2u(highProduct, 0u));
|
|
709
|
+
return result;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
fn fp64_two_prod_integer_bits(aBits: u32, bBits: u32) -> vec2u {
|
|
713
|
+
let a = fp64_decode_f32_bits(aBits);
|
|
714
|
+
let b = fp64_decode_f32_bits(bBits);
|
|
715
|
+
let resultSign = a.sign ^ b.sign;
|
|
716
|
+
|
|
717
|
+
if (a.isNan || b.isNan || ((a.isZero || b.isZero) && (a.isInf || b.isInf))) {
|
|
718
|
+
return vec2u(0x7fc00000u, 0u);
|
|
719
|
+
}
|
|
720
|
+
if (a.isInf || b.isInf) {
|
|
721
|
+
return vec2u((resultSign << 31u) | 0x7f800000u, resultSign << 31u);
|
|
722
|
+
}
|
|
723
|
+
if (a.isZero || b.isZero) {
|
|
724
|
+
return vec2u(resultSign << 31u, resultSign << 31u);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
let magnitude = fp64_multiply_significands(a.significand, b.significand);
|
|
728
|
+
return fp64_split_accumulator_bits(
|
|
729
|
+
resultSign,
|
|
730
|
+
magnitude,
|
|
731
|
+
a.baseExponent + b.baseExponent
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
fn fp64_two_prod_integer(a: f32, b: f32) -> vec2f {
|
|
736
|
+
let resultBits = fp64_two_prod_integer_bits(bitcast<u32>(a), bitcast<u32>(b));
|
|
737
|
+
return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
fn fp64_round_add_integer(a: f32, b: f32) -> f32 {
|
|
741
|
+
return fp64_two_sum_integer(a, b).x;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
fn fp64_round_mul_integer(a: f32, b: f32) -> f32 {
|
|
745
|
+
return fp64_two_prod_integer(a, b).x;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
749
|
+
fn fp64_f32_finite_exponent(value: Fp64F32Bits) -> i32 {
|
|
750
|
+
let mostSignificantBit = 31u - countLeadingZeros(value.significand);
|
|
751
|
+
return value.baseExponent + i32(mostSignificantBit);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
fn fp64_scale_f32_integer(value: f32, exponent: i32) -> f32 {
|
|
755
|
+
let decoded = fp64_decode_f32_bits(bitcast<u32>(value));
|
|
756
|
+
if (decoded.isZero || decoded.isInf || decoded.isNan) {
|
|
757
|
+
return value;
|
|
758
|
+
}
|
|
759
|
+
let resultBits = fp64_make_f32_bits_from_u64(
|
|
760
|
+
decoded.sign,
|
|
761
|
+
vec2u(0u, decoded.significand),
|
|
762
|
+
decoded.baseExponent + exponent
|
|
763
|
+
);
|
|
764
|
+
return bitcast<f32>(resultBits);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Divide normalized significands so the hardware operation cannot overflow,
|
|
768
|
+
// underflow, or flush a subnormal result. Reapply the exponent with integer
|
|
769
|
+
// packing, which also produces subnormal correction limbs without relying on
|
|
770
|
+
// floating-point arithmetic to preserve them.
|
|
771
|
+
fn fp64_divide_f32_integer(aValue: f32, bValue: f32) -> f32 {
|
|
772
|
+
let a = fp64_decode_f32_bits(bitcast<u32>(aValue));
|
|
773
|
+
let b = fp64_decode_f32_bits(bitcast<u32>(bValue));
|
|
774
|
+
if (a.isZero || b.isZero || a.isInf || b.isInf || a.isNan || b.isNan) {
|
|
775
|
+
return aValue / bValue;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
let aMostSignificantBit = 31u - countLeadingZeros(a.significand);
|
|
779
|
+
let bMostSignificantBit = 31u - countLeadingZeros(b.significand);
|
|
780
|
+
let normalizedABits = fp64_make_f32_bits_from_u64(
|
|
781
|
+
a.sign,
|
|
782
|
+
vec2u(0u, a.significand),
|
|
783
|
+
-i32(aMostSignificantBit)
|
|
784
|
+
);
|
|
785
|
+
let normalizedBBits = fp64_make_f32_bits_from_u64(
|
|
786
|
+
b.sign,
|
|
787
|
+
vec2u(0u, b.significand),
|
|
788
|
+
-i32(bMostSignificantBit)
|
|
789
|
+
);
|
|
790
|
+
let normalizedQuotient = bitcast<f32>(normalizedABits) / bitcast<f32>(normalizedBBits);
|
|
791
|
+
let quotient = fp64_decode_f32_bits(bitcast<u32>(normalizedQuotient));
|
|
792
|
+
let exponentShift =
|
|
793
|
+
a.baseExponent + i32(aMostSignificantBit) -
|
|
794
|
+
b.baseExponent - i32(bMostSignificantBit);
|
|
795
|
+
let quotientBits = fp64_make_f32_bits_from_u64(
|
|
796
|
+
quotient.sign,
|
|
797
|
+
vec2u(0u, quotient.significand),
|
|
798
|
+
quotient.baseExponent + exponentShift
|
|
799
|
+
);
|
|
800
|
+
return bitcast<f32>(quotientBits);
|
|
801
|
+
}
|
|
802
|
+
#endif
|
|
803
|
+
|
|
804
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
805
|
+
fn split(a: f32) -> vec2f {
|
|
806
|
+
let aBits = bitcast<u32>(a);
|
|
807
|
+
let decoded = fp64_decode_f32_bits(aBits);
|
|
808
|
+
if (decoded.isZero || decoded.isInf || decoded.isNan) {
|
|
809
|
+
return vec2f(a, 0.0);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
var roundedHigh = decoded.significand >> 12u;
|
|
813
|
+
let remainder = decoded.significand & 0xfffu;
|
|
814
|
+
if (remainder > 0x800u || (remainder == 0x800u && (roundedHigh & 1u) == 1u)) {
|
|
815
|
+
roundedHigh = roundedHigh + 1u;
|
|
816
|
+
}
|
|
817
|
+
var highMagnitude = vec2u(0u, roundedHigh << 12u);
|
|
818
|
+
var highBits = fp64_make_f32_bits_from_u64(
|
|
819
|
+
decoded.sign,
|
|
820
|
+
highMagnitude,
|
|
821
|
+
decoded.baseExponent
|
|
822
|
+
);
|
|
823
|
+
// Rounding the high limb of a maximum-exponent value can overflow even
|
|
824
|
+
// though the original value is finite. Truncate only in that boundary case
|
|
825
|
+
// so split remains an exact finite decomposition.
|
|
826
|
+
if (fp64_decode_f32_bits(highBits).isInf) {
|
|
827
|
+
roundedHigh = decoded.significand >> 12u;
|
|
828
|
+
highMagnitude = vec2u(0u, roundedHigh << 12u);
|
|
829
|
+
highBits = fp64_make_f32_bits_from_u64(
|
|
830
|
+
decoded.sign,
|
|
831
|
+
highMagnitude,
|
|
832
|
+
decoded.baseExponent
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
let lowBits = fp64_make_residual_f32_bits(
|
|
836
|
+
decoded.sign,
|
|
837
|
+
vec2u(0u, decoded.significand),
|
|
838
|
+
decoded.baseExponent,
|
|
839
|
+
highBits
|
|
840
|
+
);
|
|
841
|
+
return vec2f(bitcast<f32>(highBits), bitcast<f32>(lowBits));
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
fn split2(a: vec2f) -> vec2f {
|
|
845
|
+
var result = split(a.x);
|
|
846
|
+
result.y = fp64_round_add_integer(result.y, a.y);
|
|
847
|
+
return result;
|
|
848
|
+
}
|
|
849
|
+
#endif
|
|
850
|
+
|
|
851
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
852
|
+
fn quickTwoSum(a: f32, b: f32) -> vec2f {
|
|
853
|
+
return fp64_two_sum_integer(a, b);
|
|
854
|
+
}
|
|
855
|
+
#endif
|
|
856
|
+
|
|
857
|
+
fn twoSum(a: f32, b: f32) -> vec2f {
|
|
858
|
+
return fp64_two_sum_integer(a, b);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
fn twoSub(a: f32, b: f32) -> vec2f {
|
|
862
|
+
let bBits = bitcast<u32>(b) ^ 0x80000000u;
|
|
863
|
+
let resultBits = fp64_two_sum_integer_bits(bitcast<u32>(a), bBits);
|
|
864
|
+
return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
868
|
+
fn twoSqr(a: f32) -> vec2f {
|
|
869
|
+
return fp64_two_prod_integer(a, a);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
fn twoProd(a: f32, b: f32) -> vec2f {
|
|
873
|
+
return fp64_two_prod_integer(a, b);
|
|
874
|
+
}
|
|
875
|
+
#endif
|
|
876
|
+
|
|
877
|
+
fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
878
|
+
var sum = fp64_two_sum_integer(a.x, b.x);
|
|
879
|
+
let lowSum = fp64_two_sum_integer(a.y, b.y);
|
|
880
|
+
sum.y = fp64_round_add_integer(sum.y, lowSum.x);
|
|
881
|
+
sum = fp64_two_sum_integer(sum.x, sum.y);
|
|
882
|
+
sum.y = fp64_round_add_integer(sum.y, lowSum.y);
|
|
883
|
+
return fp64_two_sum_integer(sum.x, sum.y);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
887
|
+
let negatedB = vec2f(
|
|
888
|
+
bitcast<f32>(bitcast<u32>(b.x) ^ 0x80000000u),
|
|
889
|
+
bitcast<f32>(bitcast<u32>(b.y) ^ 0x80000000u)
|
|
890
|
+
);
|
|
891
|
+
return sum_fp64(a, negatedB);
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
895
|
+
var product = fp64_two_prod_integer(a.x, b.x);
|
|
896
|
+
let crossProduct1 = fp64_round_mul_integer(a.x, b.y);
|
|
897
|
+
product.y = fp64_round_add_integer(product.y, crossProduct1);
|
|
898
|
+
product = fp64_two_sum_integer(product.x, product.y);
|
|
899
|
+
let crossProduct2 = fp64_round_mul_integer(a.y, b.x);
|
|
900
|
+
product.y = fp64_round_add_integer(product.y, crossProduct2);
|
|
901
|
+
return fp64_two_sum_integer(product.x, product.y);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
905
|
+
fn fp64_scale_fp64_integer(value: vec2f, exponent: i32) -> vec2f {
|
|
906
|
+
let high = fp64_scale_f32_integer(value.x, exponent);
|
|
907
|
+
let low = fp64_scale_f32_integer(value.y, exponent);
|
|
908
|
+
return sum_fp64(vec2f(high, 0.0), vec2f(low, 0.0));
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
fn fp64_div_fp64_normalized(a: vec2f, b: vec2f) -> vec2f {
|
|
912
|
+
let quotientHigh = fp64_divide_f32_integer(a.x, b.x);
|
|
913
|
+
var quotient = vec2f(quotientHigh, 0.0);
|
|
914
|
+
|
|
915
|
+
let remainder = sub_fp64(a, mul_fp64(b, quotient));
|
|
916
|
+
let quotientLow = fp64_divide_f32_integer(remainder.x, b.x);
|
|
917
|
+
quotient = sum_fp64(quotient, vec2f(quotientLow, 0.0));
|
|
918
|
+
|
|
919
|
+
let secondRemainder = sub_fp64(a, mul_fp64(b, quotient));
|
|
920
|
+
let correction = fp64_divide_f32_integer(secondRemainder.x, b.x);
|
|
921
|
+
return sum_fp64(quotient, vec2f(correction, 0.0));
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
925
|
+
let decodedA = fp64_decode_f32_bits(bitcast<u32>(a.x));
|
|
926
|
+
let decodedB = fp64_decode_f32_bits(bitcast<u32>(b.x));
|
|
927
|
+
if (
|
|
928
|
+
decodedA.isZero || decodedB.isZero ||
|
|
929
|
+
decodedA.isInf || decodedB.isInf ||
|
|
930
|
+
decodedA.isNan || decodedB.isNan
|
|
931
|
+
) {
|
|
932
|
+
return fp64_div_fp64_normalized(a, b);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
let exponentA = fp64_f32_finite_exponent(decodedA);
|
|
936
|
+
let exponentB = fp64_f32_finite_exponent(decodedB);
|
|
937
|
+
// Correct the quotient near unity so b * q and the remainder stay clear of
|
|
938
|
+
// both f32 underflow and overflow. The exponent difference is applied once.
|
|
939
|
+
let normalizedA = fp64_scale_fp64_integer(a, -exponentA);
|
|
940
|
+
let normalizedB = fp64_scale_fp64_integer(b, -exponentB);
|
|
941
|
+
let normalizedQuotient = fp64_div_fp64_normalized(normalizedA, normalizedB);
|
|
942
|
+
return fp64_scale_fp64_integer(normalizedQuotient, exponentA - exponentB);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
fn fp64_sqrt_fp64_normalized(a: vec2f) -> vec2f {
|
|
946
|
+
let estimate = sqrt(a.x);
|
|
947
|
+
let difference = sub_fp64(a, fp64_two_prod_integer(estimate, estimate)).x;
|
|
948
|
+
let denominator = fp64_round_add_integer(estimate, estimate);
|
|
949
|
+
let correction = fp64_divide_f32_integer(difference, denominator);
|
|
950
|
+
return sum_fp64(vec2f(estimate, 0.0), vec2f(correction, 0.0));
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
fn sqrt_fp64(a: vec2f) -> vec2f {
|
|
954
|
+
let decoded = fp64_decode_f32_bits(bitcast<u32>(a.x));
|
|
955
|
+
let decodedLow = fp64_decode_f32_bits(bitcast<u32>(a.y));
|
|
956
|
+
if (decoded.isZero && decodedLow.isZero) {
|
|
957
|
+
return vec2f(0.0, 0.0);
|
|
958
|
+
}
|
|
959
|
+
if (decoded.sign == 1u) {
|
|
960
|
+
let nanValue = fp64_nan(a.x);
|
|
961
|
+
return vec2f(nanValue, nanValue);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (decoded.isInf || decoded.isNan) {
|
|
965
|
+
return fp64_sqrt_fp64_normalized(a);
|
|
966
|
+
}
|
|
967
|
+
let exponent = fp64_f32_finite_exponent(decoded);
|
|
968
|
+
// An even scale lets the final square-root rescale use an integer exponent.
|
|
969
|
+
let evenExponent = exponent - (exponent & 1);
|
|
970
|
+
let normalizedA = fp64_scale_fp64_integer(a, -evenExponent);
|
|
971
|
+
let normalizedRoot = fp64_sqrt_fp64_normalized(normalizedA);
|
|
972
|
+
return fp64_scale_fp64_integer(normalizedRoot, evenExponent / 2);
|
|
973
|
+
}
|
|
974
|
+
#endif
|
|
525
975
|
`;var lt=`struct Fp64ArithmeticUniforms {
|
|
526
976
|
ONE: f32,
|
|
527
977
|
SPLIT: f32,
|
|
@@ -529,11 +979,608 @@ vec2 sqrt_fp64(vec2 a) {
|
|
|
529
979
|
|
|
530
980
|
@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
|
|
531
981
|
|
|
982
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
983
|
+
struct Fp64Bits {
|
|
984
|
+
sign: u32,
|
|
985
|
+
exponent: i32,
|
|
986
|
+
significand: vec2u,
|
|
987
|
+
isZero: bool,
|
|
988
|
+
isInf: bool,
|
|
989
|
+
isNan: bool,
|
|
990
|
+
};
|
|
991
|
+
#endif
|
|
992
|
+
|
|
993
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
532
994
|
fn fp64_nan(seed: f32) -> f32 {
|
|
533
995
|
let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
|
|
534
996
|
return bitcast<f32>(nanBits);
|
|
535
997
|
}
|
|
998
|
+
#endif
|
|
999
|
+
|
|
1000
|
+
fn fp64_u64_is_zero(value: vec2u) -> bool {
|
|
1001
|
+
return value.x == 0u && value.y == 0u;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
fn fp64_u64_compare(a: vec2u, b: vec2u) -> i32 {
|
|
1005
|
+
if (a.x != b.x) {
|
|
1006
|
+
return select(-1, 1, a.x > b.x);
|
|
1007
|
+
}
|
|
1008
|
+
if (a.y != b.y) {
|
|
1009
|
+
return select(-1, 1, a.y > b.y);
|
|
1010
|
+
}
|
|
1011
|
+
return 0;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
fn fp64_u64_add(a: vec2u, b: vec2u) -> vec2u {
|
|
1015
|
+
let low = a.y + b.y;
|
|
1016
|
+
let carry = select(0u, 1u, low < a.y);
|
|
1017
|
+
return vec2u(a.x + b.x + carry, low);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
fn fp64_u64_sub(a: vec2u, b: vec2u) -> vec2u {
|
|
1021
|
+
let borrow = select(0u, 1u, a.y < b.y);
|
|
1022
|
+
return vec2u(a.x - b.x - borrow, a.y - b.y);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
fn fp64_u64_shift_left(value: vec2u, shift: u32) -> vec2u {
|
|
1026
|
+
if (shift == 0u) {
|
|
1027
|
+
return value;
|
|
1028
|
+
}
|
|
1029
|
+
if (shift < 32u) {
|
|
1030
|
+
return vec2u((value.x << shift) | (value.y >> (32u - shift)), value.y << shift);
|
|
1031
|
+
}
|
|
1032
|
+
if (shift == 32u) {
|
|
1033
|
+
return vec2u(value.y, 0u);
|
|
1034
|
+
}
|
|
1035
|
+
if (shift < 64u) {
|
|
1036
|
+
return vec2u(value.y << (shift - 32u), 0u);
|
|
1037
|
+
}
|
|
1038
|
+
return vec2u(0u);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
fn fp64_u64_shift_right(value: vec2u, shift: u32) -> vec2u {
|
|
1042
|
+
if (shift == 0u) {
|
|
1043
|
+
return value;
|
|
1044
|
+
}
|
|
1045
|
+
if (shift < 32u) {
|
|
1046
|
+
return vec2u(value.x >> shift, (value.y >> shift) | (value.x << (32u - shift)));
|
|
1047
|
+
}
|
|
1048
|
+
if (shift == 32u) {
|
|
1049
|
+
return vec2u(0u, value.x);
|
|
1050
|
+
}
|
|
1051
|
+
if (shift < 64u) {
|
|
1052
|
+
return vec2u(0u, value.x >> (shift - 32u));
|
|
1053
|
+
}
|
|
1054
|
+
return vec2u(0u);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
fn fp64_u64_get_bit(value: vec2u, bitIndex: u32) -> bool {
|
|
1058
|
+
if (bitIndex >= 64u) {
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
if (bitIndex >= 32u) {
|
|
1062
|
+
return ((value.x >> (bitIndex - 32u)) & 1u) != 0u;
|
|
1063
|
+
}
|
|
1064
|
+
return ((value.y >> bitIndex) & 1u) != 0u;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
fn fp64_u64_has_bits_below(value: vec2u, bitCount: u32) -> bool {
|
|
1068
|
+
if (bitCount == 0u) {
|
|
1069
|
+
return false;
|
|
1070
|
+
}
|
|
1071
|
+
if (bitCount >= 64u) {
|
|
1072
|
+
return !fp64_u64_is_zero(value);
|
|
1073
|
+
}
|
|
1074
|
+
if (bitCount > 32u) {
|
|
1075
|
+
let highBitCount = bitCount - 32u;
|
|
1076
|
+
let highMask = (1u << highBitCount) - 1u;
|
|
1077
|
+
return value.y != 0u || (value.x & highMask) != 0u;
|
|
1078
|
+
}
|
|
1079
|
+
if (bitCount == 32u) {
|
|
1080
|
+
return value.y != 0u;
|
|
1081
|
+
}
|
|
1082
|
+
let lowMask = (1u << bitCount) - 1u;
|
|
1083
|
+
return (value.y & lowMask) != 0u;
|
|
1084
|
+
}
|
|
536
1085
|
|
|
1086
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
1087
|
+
fn fp64_u64_shift_right_sticky(value: vec2u, shift: u32) -> vec2u {
|
|
1088
|
+
var shifted = fp64_u64_shift_right(value, shift);
|
|
1089
|
+
if (fp64_u64_has_bits_below(value, shift)) {
|
|
1090
|
+
shifted.y = shifted.y | 1u;
|
|
1091
|
+
}
|
|
1092
|
+
return shifted;
|
|
1093
|
+
}
|
|
1094
|
+
#endif
|
|
1095
|
+
|
|
1096
|
+
fn fp64_u64_count_leading_zeros(value: vec2u) -> u32 {
|
|
1097
|
+
if (value.x != 0u) {
|
|
1098
|
+
return countLeadingZeros(value.x);
|
|
1099
|
+
}
|
|
1100
|
+
return 32u + countLeadingZeros(value.y);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
fn fp64_round_shift_right_to_u32(value: vec2u, shift: u32) -> u32 {
|
|
1104
|
+
if (shift == 0u) {
|
|
1105
|
+
return value.y;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
let truncated = fp64_u64_shift_right(value, shift);
|
|
1109
|
+
var rounded = truncated.y;
|
|
1110
|
+
let guard = fp64_u64_get_bit(value, shift - 1u);
|
|
1111
|
+
let hasTrailingBits = fp64_u64_has_bits_below(value, shift - 1u);
|
|
1112
|
+
if (guard && (hasTrailingBits || (rounded & 1u) == 1u)) {
|
|
1113
|
+
rounded = rounded + 1u;
|
|
1114
|
+
}
|
|
1115
|
+
return rounded;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
1119
|
+
fn fp64_round_shift_right(value: vec2u, shift: u32) -> vec2u {
|
|
1120
|
+
if (shift == 0u) {
|
|
1121
|
+
return value;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
var rounded = fp64_u64_shift_right(value, shift);
|
|
1125
|
+
let guard = fp64_u64_get_bit(value, shift - 1u);
|
|
1126
|
+
let hasTrailingBits = fp64_u64_has_bits_below(value, shift - 1u);
|
|
1127
|
+
if (guard && (hasTrailingBits || (rounded.y & 1u) == 1u)) {
|
|
1128
|
+
rounded = fp64_u64_add(rounded, vec2u(0u, 1u));
|
|
1129
|
+
}
|
|
1130
|
+
return rounded;
|
|
1131
|
+
}
|
|
1132
|
+
#endif
|
|
1133
|
+
|
|
1134
|
+
fn fp64_make_f32_bits_from_u64(sign: u32, significand: vec2u, baseExponent: i32) -> u32 {
|
|
1135
|
+
if (fp64_u64_is_zero(significand)) {
|
|
1136
|
+
return sign << 31u;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
let leadingZeros = fp64_u64_count_leading_zeros(significand);
|
|
1140
|
+
let mostSignificantBit = 63u - leadingZeros;
|
|
1141
|
+
var exponent = baseExponent + i32(mostSignificantBit);
|
|
1142
|
+
|
|
1143
|
+
if (exponent > 127) {
|
|
1144
|
+
return (sign << 31u) | 0x7f800000u;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
if (exponent >= -126) {
|
|
1148
|
+
let shift = i32(mostSignificantBit) - 23;
|
|
1149
|
+
var significand24: u32;
|
|
1150
|
+
if (shift > 0) {
|
|
1151
|
+
significand24 = fp64_round_shift_right_to_u32(significand, u32(shift));
|
|
1152
|
+
} else {
|
|
1153
|
+
significand24 = fp64_u64_shift_left(significand, u32(-shift)).y;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
if (significand24 >= 0x1000000u) {
|
|
1157
|
+
significand24 = significand24 >> 1u;
|
|
1158
|
+
exponent = exponent + 1;
|
|
1159
|
+
if (exponent > 127) {
|
|
1160
|
+
return (sign << 31u) | 0x7f800000u;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
return (sign << 31u) | (u32(exponent + 127) << 23u) | (significand24 & 0x7fffffu);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
let scaleExponent = baseExponent + 149;
|
|
1168
|
+
var mantissa: u32;
|
|
1169
|
+
if (scaleExponent >= 0) {
|
|
1170
|
+
mantissa = fp64_u64_shift_left(significand, u32(scaleExponent)).y;
|
|
1171
|
+
} else {
|
|
1172
|
+
mantissa = fp64_round_shift_right_to_u32(significand, u32(-scaleExponent));
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (mantissa >= 0x800000u) {
|
|
1176
|
+
return (sign << 31u) | 0x00800000u;
|
|
1177
|
+
}
|
|
1178
|
+
return (sign << 31u) | mantissa;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
1182
|
+
fn fp64_decode_bits(bits: vec2u) -> Fp64Bits {
|
|
1183
|
+
let sign = bits.x >> 31u;
|
|
1184
|
+
let exponentBits = (bits.x >> 20u) & 0x7ffu;
|
|
1185
|
+
let fractionHigh = bits.x & 0xfffffu;
|
|
1186
|
+
let fractionLow = bits.y;
|
|
1187
|
+
let fraction = vec2u(fractionHigh, fractionLow);
|
|
1188
|
+
|
|
1189
|
+
if (exponentBits == 0x7ffu) {
|
|
1190
|
+
let isInf = fp64_u64_is_zero(fraction);
|
|
1191
|
+
return Fp64Bits(sign, 0, vec2u(0u), false, isInf, !isInf);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
if (exponentBits == 0u) {
|
|
1195
|
+
let isZero = fp64_u64_is_zero(fraction);
|
|
1196
|
+
return Fp64Bits(sign, -1022, fraction, isZero, false, false);
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
return Fp64Bits(sign, i32(exponentBits) - 1023, vec2u((1u << 20u) | fractionHigh, fractionLow), false, false, false);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
fn fp64_finite_magnitude_compare(a: Fp64Bits, b: Fp64Bits) -> i32 {
|
|
1203
|
+
if (a.exponent != b.exponent) {
|
|
1204
|
+
return select(-1, 1, a.exponent > b.exponent);
|
|
1205
|
+
}
|
|
1206
|
+
return fp64_u64_compare(a.significand, b.significand);
|
|
1207
|
+
}
|
|
1208
|
+
#endif
|
|
1209
|
+
|
|
1210
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
1211
|
+
struct Fp64RawF32Bits {
|
|
1212
|
+
sign: u32,
|
|
1213
|
+
baseExponent: i32,
|
|
1214
|
+
significand: u32,
|
|
1215
|
+
isZero: bool,
|
|
1216
|
+
isInf: bool,
|
|
1217
|
+
isNan: bool,
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
// Decode an f32 as (-1)^sign * significand * 2^baseExponent. This shared
|
|
1221
|
+
// integer representation lets normalization remain independent of the
|
|
1222
|
+
// selected double-single arithmetic implementation.
|
|
1223
|
+
fn fp64_decode_raw_f32_bits(bits: u32) -> Fp64RawF32Bits {
|
|
1224
|
+
let sign = bits >> 31u;
|
|
1225
|
+
let exponentBits = (bits >> 23u) & 0xffu;
|
|
1226
|
+
let fraction = bits & 0x7fffffu;
|
|
1227
|
+
|
|
1228
|
+
if (exponentBits == 0xffu) {
|
|
1229
|
+
return Fp64RawF32Bits(sign, 0, 0u, false, fraction == 0u, fraction != 0u);
|
|
1230
|
+
}
|
|
1231
|
+
if (exponentBits == 0u) {
|
|
1232
|
+
return Fp64RawF32Bits(sign, -149, fraction, fraction == 0u, false, false);
|
|
1233
|
+
}
|
|
1234
|
+
return Fp64RawF32Bits(
|
|
1235
|
+
sign,
|
|
1236
|
+
i32(exponentBits) - 150,
|
|
1237
|
+
0x800000u | fraction,
|
|
1238
|
+
false,
|
|
1239
|
+
false,
|
|
1240
|
+
false
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
fn fp64_raw_f32_magnitude_compare(aBits: u32, bBits: u32) -> i32 {
|
|
1245
|
+
let aMagnitude = aBits & 0x7fffffffu;
|
|
1246
|
+
let bMagnitude = bBits & 0x7fffffffu;
|
|
1247
|
+
if (aMagnitude == bMagnitude) {
|
|
1248
|
+
return 0;
|
|
1249
|
+
}
|
|
1250
|
+
return select(-1, 1, aMagnitude > bMagnitude);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
fn fp64_make_raw_residual_f32_bits(
|
|
1254
|
+
exactSign: u32,
|
|
1255
|
+
exactMagnitude: vec2u,
|
|
1256
|
+
exactBaseExponent: i32,
|
|
1257
|
+
highBits: u32
|
|
1258
|
+
) -> u32 {
|
|
1259
|
+
if (fp64_u64_is_zero(exactMagnitude)) {
|
|
1260
|
+
return 0u;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
let high = fp64_decode_raw_f32_bits(highBits);
|
|
1264
|
+
if (high.isInf || high.isNan) {
|
|
1265
|
+
return 0u;
|
|
1266
|
+
}
|
|
1267
|
+
if (high.isZero) {
|
|
1268
|
+
return fp64_make_f32_bits_from_u64(exactSign, exactMagnitude, exactBaseExponent);
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
let commonBaseExponent = min(exactBaseExponent, high.baseExponent);
|
|
1272
|
+
let exactShift = exactBaseExponent - commonBaseExponent;
|
|
1273
|
+
let highShift = high.baseExponent - commonBaseExponent;
|
|
1274
|
+
if (exactShift >= 64 || highShift >= 64) {
|
|
1275
|
+
return 0u;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
let exactAligned = fp64_u64_shift_left(exactMagnitude, u32(exactShift));
|
|
1279
|
+
let highAligned = fp64_u64_shift_left(vec2u(0u, high.significand), u32(highShift));
|
|
1280
|
+
let comparison = fp64_u64_compare(exactAligned, highAligned);
|
|
1281
|
+
if (comparison == 0) {
|
|
1282
|
+
return 0u;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
var residualSign = exactSign;
|
|
1286
|
+
var residualMagnitude: vec2u;
|
|
1287
|
+
if (comparison > 0) {
|
|
1288
|
+
residualMagnitude = fp64_u64_sub(exactAligned, highAligned);
|
|
1289
|
+
} else {
|
|
1290
|
+
residualSign = exactSign ^ 1u;
|
|
1291
|
+
residualMagnitude = fp64_u64_sub(highAligned, exactAligned);
|
|
1292
|
+
}
|
|
1293
|
+
return fp64_make_f32_bits_from_u64(
|
|
1294
|
+
residualSign,
|
|
1295
|
+
residualMagnitude,
|
|
1296
|
+
commonBaseExponent
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
fn fp64_split_raw_accumulator_bits(
|
|
1301
|
+
sign: u32,
|
|
1302
|
+
magnitude: vec2u,
|
|
1303
|
+
baseExponent: i32
|
|
1304
|
+
) -> vec2u {
|
|
1305
|
+
if (fp64_u64_is_zero(magnitude)) {
|
|
1306
|
+
return vec2u(0u);
|
|
1307
|
+
}
|
|
1308
|
+
let highBits = fp64_make_f32_bits_from_u64(sign, magnitude, baseExponent);
|
|
1309
|
+
let rawLowBits = fp64_make_raw_residual_f32_bits(sign, magnitude, baseExponent, highBits);
|
|
1310
|
+
let lowBits = select(rawLowBits, 0u, (rawLowBits & 0x7fffffffu) == 0u);
|
|
1311
|
+
if ((highBits & 0x7fffffffu) == 0u && (lowBits & 0x7fffffffu) == 0u) {
|
|
1312
|
+
return vec2u(0u);
|
|
1313
|
+
}
|
|
1314
|
+
return vec2u(highBits, lowBits);
|
|
1315
|
+
}
|
|
1316
|
+
#endif
|
|
1317
|
+
|
|
1318
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
1319
|
+
// Round an arithmetic accumulator to binary64 before splitting it. The
|
|
1320
|
+
// aligned add/subtract paths retain three guard bits plus a sticky bit, which
|
|
1321
|
+
// is sufficient for round-to-nearest-even at the binary64 boundary.
|
|
1322
|
+
fn fp64_split_binary64_accumulator_bits(
|
|
1323
|
+
sign: u32,
|
|
1324
|
+
magnitude: vec2u,
|
|
1325
|
+
baseExponent: i32
|
|
1326
|
+
) -> vec2u {
|
|
1327
|
+
if (fp64_u64_is_zero(magnitude)) {
|
|
1328
|
+
return vec2u(0u);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
let mostSignificantBit = 63u - fp64_u64_count_leading_zeros(magnitude);
|
|
1332
|
+
let exponent = baseExponent + i32(mostSignificantBit);
|
|
1333
|
+
if (exponent > 1023) {
|
|
1334
|
+
return vec2u((sign << 31u) | 0x7f800000u, 0u);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
var roundedMagnitude = magnitude;
|
|
1338
|
+
var roundedBaseExponent = baseExponent;
|
|
1339
|
+
if (exponent >= -1022) {
|
|
1340
|
+
if (mostSignificantBit > 52u) {
|
|
1341
|
+
let shift = mostSignificantBit - 52u;
|
|
1342
|
+
roundedMagnitude = fp64_round_shift_right(magnitude, shift);
|
|
1343
|
+
roundedBaseExponent = baseExponent + i32(shift);
|
|
1344
|
+
}
|
|
1345
|
+
} else {
|
|
1346
|
+
let shift = -1074 - baseExponent;
|
|
1347
|
+
if (shift > 0) {
|
|
1348
|
+
roundedMagnitude = fp64_round_shift_right(magnitude, u32(shift));
|
|
1349
|
+
roundedBaseExponent = -1074;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
if (fp64_u64_is_zero(roundedMagnitude)) {
|
|
1354
|
+
return vec2u(0u);
|
|
1355
|
+
}
|
|
1356
|
+
return fp64_split_raw_accumulator_bits(sign, roundedMagnitude, roundedBaseExponent);
|
|
1357
|
+
}
|
|
1358
|
+
#endif
|
|
1359
|
+
|
|
1360
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
1361
|
+
fn fp64_add_raw_f32_bits(aBits: u32, bBits: u32) -> vec2u {
|
|
1362
|
+
let a = fp64_decode_raw_f32_bits(aBits);
|
|
1363
|
+
let b = fp64_decode_raw_f32_bits(bBits);
|
|
1364
|
+
|
|
1365
|
+
if (a.isNan || b.isNan) {
|
|
1366
|
+
return vec2u(0x7fc00000u, 0u);
|
|
1367
|
+
}
|
|
1368
|
+
if (a.isInf || b.isInf) {
|
|
1369
|
+
if (a.isInf && b.isInf && a.sign != b.sign) {
|
|
1370
|
+
return vec2u(0x7fc00000u, 0u);
|
|
1371
|
+
}
|
|
1372
|
+
return select(vec2u(bBits, 0u), vec2u(aBits, 0u), a.isInf);
|
|
1373
|
+
}
|
|
1374
|
+
if (a.isZero && b.isZero) {
|
|
1375
|
+
return vec2u(0u);
|
|
1376
|
+
}
|
|
1377
|
+
if (a.isZero) {
|
|
1378
|
+
return vec2u(bBits, 0u);
|
|
1379
|
+
}
|
|
1380
|
+
if (b.isZero) {
|
|
1381
|
+
return vec2u(aBits, 0u);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
let exponentDifference = abs(a.baseExponent - b.baseExponent);
|
|
1385
|
+
if (exponentDifference > 25) {
|
|
1386
|
+
if (fp64_raw_f32_magnitude_compare(aBits, bBits) >= 0) {
|
|
1387
|
+
return vec2u(aBits, bBits);
|
|
1388
|
+
}
|
|
1389
|
+
return vec2u(bBits, aBits);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
let commonBaseExponent = min(a.baseExponent, b.baseExponent);
|
|
1393
|
+
let aMagnitude = fp64_u64_shift_left(
|
|
1394
|
+
vec2u(0u, a.significand),
|
|
1395
|
+
u32(a.baseExponent - commonBaseExponent)
|
|
1396
|
+
);
|
|
1397
|
+
let bMagnitude = fp64_u64_shift_left(
|
|
1398
|
+
vec2u(0u, b.significand),
|
|
1399
|
+
u32(b.baseExponent - commonBaseExponent)
|
|
1400
|
+
);
|
|
1401
|
+
|
|
1402
|
+
var resultSign = a.sign;
|
|
1403
|
+
var resultMagnitude: vec2u;
|
|
1404
|
+
if (a.sign == b.sign) {
|
|
1405
|
+
resultMagnitude = fp64_u64_add(aMagnitude, bMagnitude);
|
|
1406
|
+
} else {
|
|
1407
|
+
let comparison = fp64_u64_compare(aMagnitude, bMagnitude);
|
|
1408
|
+
if (comparison == 0) {
|
|
1409
|
+
return vec2u(0u);
|
|
1410
|
+
}
|
|
1411
|
+
if (comparison > 0) {
|
|
1412
|
+
resultMagnitude = fp64_u64_sub(aMagnitude, bMagnitude);
|
|
1413
|
+
} else {
|
|
1414
|
+
resultSign = b.sign;
|
|
1415
|
+
resultMagnitude = fp64_u64_sub(bMagnitude, aMagnitude);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
return fp64_split_raw_accumulator_bits(
|
|
1420
|
+
resultSign,
|
|
1421
|
+
resultMagnitude,
|
|
1422
|
+
commonBaseExponent
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
#endif
|
|
1426
|
+
|
|
1427
|
+
#ifndef LUMA_FP64_F32_INPUT_ONLY
|
|
1428
|
+
fn fp64_add_aligned_magnitudes_to_fp64_bits(
|
|
1429
|
+
sign: u32,
|
|
1430
|
+
larger: Fp64Bits,
|
|
1431
|
+
smaller: Fp64Bits
|
|
1432
|
+
) -> vec2u {
|
|
1433
|
+
let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
|
|
1434
|
+
let smallSignificand = fp64_u64_shift_right_sticky(
|
|
1435
|
+
fp64_u64_shift_left(smaller.significand, 3u),
|
|
1436
|
+
u32(larger.exponent - smaller.exponent)
|
|
1437
|
+
);
|
|
1438
|
+
let resultSignificand = fp64_u64_add(largeSignificand, smallSignificand);
|
|
1439
|
+
return fp64_split_binary64_accumulator_bits(
|
|
1440
|
+
sign,
|
|
1441
|
+
resultSignificand,
|
|
1442
|
+
larger.exponent - 55
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
fn fp64_sub_aligned_magnitudes_to_fp64_bits(
|
|
1447
|
+
sign: u32,
|
|
1448
|
+
larger: Fp64Bits,
|
|
1449
|
+
smaller: Fp64Bits
|
|
1450
|
+
) -> vec2u {
|
|
1451
|
+
let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
|
|
1452
|
+
let smallSignificand = fp64_u64_shift_right_sticky(
|
|
1453
|
+
fp64_u64_shift_left(smaller.significand, 3u),
|
|
1454
|
+
u32(larger.exponent - smaller.exponent)
|
|
1455
|
+
);
|
|
1456
|
+
let resultSignificand = fp64_u64_sub(largeSignificand, smallSignificand);
|
|
1457
|
+
return fp64_split_binary64_accumulator_bits(
|
|
1458
|
+
sign,
|
|
1459
|
+
resultSignificand,
|
|
1460
|
+
larger.exponent - 55
|
|
1461
|
+
);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
fn fp64_add_aligned_magnitudes_to_f32_bits(sign: u32, larger: Fp64Bits, smaller: Fp64Bits) -> u32 {
|
|
1465
|
+
let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
|
|
1466
|
+
let smallSignificand = fp64_u64_shift_right_sticky(
|
|
1467
|
+
fp64_u64_shift_left(smaller.significand, 3u),
|
|
1468
|
+
u32(larger.exponent - smaller.exponent)
|
|
1469
|
+
);
|
|
1470
|
+
let resultSignificand = fp64_u64_add(largeSignificand, smallSignificand);
|
|
1471
|
+
return fp64_make_f32_bits_from_u64(sign, resultSignificand, larger.exponent - 55);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
fn fp64_sub_aligned_magnitudes_to_f32_bits(sign: u32, larger: Fp64Bits, smaller: Fp64Bits) -> u32 {
|
|
1475
|
+
let largeSignificand = fp64_u64_shift_left(larger.significand, 3u);
|
|
1476
|
+
let smallSignificand = fp64_u64_shift_right_sticky(
|
|
1477
|
+
fp64_u64_shift_left(smaller.significand, 3u),
|
|
1478
|
+
u32(larger.exponent - smaller.exponent)
|
|
1479
|
+
);
|
|
1480
|
+
let resultSignificand = fp64_u64_sub(largeSignificand, smallSignificand);
|
|
1481
|
+
return fp64_make_f32_bits_from_u64(sign, resultSignificand, larger.exponent - 55);
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
// Subtract two raw binary64 values and round the exact result once to f32.
|
|
1485
|
+
// The input words are canonical high/low words: .x contains sign/exponent/high
|
|
1486
|
+
// fraction bits, and .y contains the low 32 fraction bits.
|
|
1487
|
+
fn sub_fp64u32_to_f32_bits(aBits: vec2u, bBits: vec2u) -> u32 {
|
|
1488
|
+
let a = fp64_decode_bits(aBits);
|
|
1489
|
+
let b = fp64_decode_bits(bBits);
|
|
1490
|
+
let bSubtractionSign = b.sign ^ 1u;
|
|
1491
|
+
|
|
1492
|
+
if (a.isNan || b.isNan) {
|
|
1493
|
+
return 0x7fc00000u;
|
|
1494
|
+
}
|
|
1495
|
+
if (a.isInf && b.isInf) {
|
|
1496
|
+
if (a.sign == bSubtractionSign) {
|
|
1497
|
+
return (a.sign << 31u) | 0x7f800000u;
|
|
1498
|
+
}
|
|
1499
|
+
return 0x7fc00000u;
|
|
1500
|
+
}
|
|
1501
|
+
if (a.isInf) {
|
|
1502
|
+
return (a.sign << 31u) | 0x7f800000u;
|
|
1503
|
+
}
|
|
1504
|
+
if (b.isInf) {
|
|
1505
|
+
return (bSubtractionSign << 31u) | 0x7f800000u;
|
|
1506
|
+
}
|
|
1507
|
+
if (a.isZero && b.isZero) {
|
|
1508
|
+
return select(0u, 0x80000000u, a.sign == 1u && b.sign == 0u);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
let magnitudeComparison = fp64_finite_magnitude_compare(a, b);
|
|
1512
|
+
if (a.sign == bSubtractionSign) {
|
|
1513
|
+
if (magnitudeComparison >= 0) {
|
|
1514
|
+
return fp64_add_aligned_magnitudes_to_f32_bits(a.sign, a, b);
|
|
1515
|
+
}
|
|
1516
|
+
return fp64_add_aligned_magnitudes_to_f32_bits(a.sign, b, a);
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
if (magnitudeComparison == 0) {
|
|
1520
|
+
return 0u;
|
|
1521
|
+
}
|
|
1522
|
+
if (magnitudeComparison > 0) {
|
|
1523
|
+
return fp64_sub_aligned_magnitudes_to_f32_bits(a.sign, a, b);
|
|
1524
|
+
}
|
|
1525
|
+
return fp64_sub_aligned_magnitudes_to_f32_bits(bSubtractionSign, b, a);
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
fn sub_fp64u32_to_f32(aBits: vec2u, bBits: vec2u) -> f32 {
|
|
1529
|
+
return bitcast<f32>(sub_fp64u32_to_f32_bits(aBits, bBits));
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
// Subtract two raw binary64 values, round once to binary64, then split the
|
|
1533
|
+
// result into normalized f32 limbs. Finite results must fit within the f32
|
|
1534
|
+
// exponent range; larger magnitudes map to infinity and smaller magnitudes
|
|
1535
|
+
// map to zero. The input words use canonical high/low word order.
|
|
1536
|
+
fn sub_fp64u32_to_fp64_bits(aBits: vec2u, bBits: vec2u) -> vec2u {
|
|
1537
|
+
let a = fp64_decode_bits(aBits);
|
|
1538
|
+
let b = fp64_decode_bits(bBits);
|
|
1539
|
+
let bSubtractionSign = b.sign ^ 1u;
|
|
1540
|
+
|
|
1541
|
+
if (a.isNan || b.isNan) {
|
|
1542
|
+
return vec2u(0x7fc00000u, 0u);
|
|
1543
|
+
}
|
|
1544
|
+
if (a.isInf && b.isInf) {
|
|
1545
|
+
if (a.sign == bSubtractionSign) {
|
|
1546
|
+
return vec2u((a.sign << 31u) | 0x7f800000u, 0u);
|
|
1547
|
+
}
|
|
1548
|
+
return vec2u(0x7fc00000u, 0u);
|
|
1549
|
+
}
|
|
1550
|
+
if (a.isInf) {
|
|
1551
|
+
return vec2u((a.sign << 31u) | 0x7f800000u, 0u);
|
|
1552
|
+
}
|
|
1553
|
+
if (b.isInf) {
|
|
1554
|
+
return vec2u((bSubtractionSign << 31u) | 0x7f800000u, 0u);
|
|
1555
|
+
}
|
|
1556
|
+
if (a.isZero && b.isZero) {
|
|
1557
|
+
return vec2u(0u);
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
let magnitudeComparison = fp64_finite_magnitude_compare(a, b);
|
|
1561
|
+
if (a.sign == bSubtractionSign) {
|
|
1562
|
+
if (magnitudeComparison >= 0) {
|
|
1563
|
+
return fp64_add_aligned_magnitudes_to_fp64_bits(a.sign, a, b);
|
|
1564
|
+
}
|
|
1565
|
+
return fp64_add_aligned_magnitudes_to_fp64_bits(a.sign, b, a);
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
if (magnitudeComparison == 0) {
|
|
1569
|
+
return vec2u(0u);
|
|
1570
|
+
}
|
|
1571
|
+
if (magnitudeComparison > 0) {
|
|
1572
|
+
return fp64_sub_aligned_magnitudes_to_fp64_bits(a.sign, a, b);
|
|
1573
|
+
}
|
|
1574
|
+
return fp64_sub_aligned_magnitudes_to_fp64_bits(bSubtractionSign, b, a);
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
fn sub_fp64u32_to_fp64(aBits: vec2u, bBits: vec2u) -> vec2f {
|
|
1578
|
+
let resultBits = sub_fp64u32_to_fp64_bits(aBits, bBits);
|
|
1579
|
+
return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
|
|
1580
|
+
}
|
|
1581
|
+
#endif
|
|
1582
|
+
|
|
1583
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
537
1584
|
fn fp64_runtime_zero() -> f32 {
|
|
538
1585
|
return fp64arithmetic.ONE * 0.0;
|
|
539
1586
|
}
|
|
@@ -545,7 +1592,11 @@ fn prevent_fp64_optimization(value: f32) -> f32 {
|
|
|
545
1592
|
return value;
|
|
546
1593
|
#endif
|
|
547
1594
|
}
|
|
1595
|
+
#endif
|
|
548
1596
|
|
|
1597
|
+
#ifdef LUMA_FP64_INTEGER_ARITHMETIC
|
|
1598
|
+
${ft}
|
|
1599
|
+
#else
|
|
549
1600
|
fn split(a: f32) -> vec2f {
|
|
550
1601
|
let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
|
|
551
1602
|
let t = prevent_fp64_optimization(a * splitValue);
|
|
@@ -696,6 +1747,7 @@ fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
|
696
1747
|
return prod;
|
|
697
1748
|
}
|
|
698
1749
|
|
|
1750
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
699
1751
|
fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
700
1752
|
let xn = prevent_fp64_optimization(1.0 / b.x);
|
|
701
1753
|
let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
|
|
@@ -728,7 +1780,98 @@ fn sqrt_fp64(a: vec2f) -> vec2f {
|
|
|
728
1780
|
return sum_fp64(vec2f(yn, 0.0), prod);
|
|
729
1781
|
#endif
|
|
730
1782
|
}
|
|
731
|
-
|
|
1783
|
+
#endif
|
|
1784
|
+
#endif
|
|
1785
|
+
|
|
1786
|
+
#ifndef LUMA_FP64_PREDICATE_ONLY
|
|
1787
|
+
fn fp64_f32_bits_is_nan(bits: u32) -> bool {
|
|
1788
|
+
return (bits & 0x7fffffffu) > 0x7f800000u;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
fn fp64_f32_bits_is_inf(bits: u32) -> bool {
|
|
1792
|
+
return (bits & 0x7fffffffu) == 0x7f800000u;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
fn fp64_compare_f32_bits(aBits: u32, bBits: u32) -> i32 {
|
|
1796
|
+
let aMagnitude = aBits & 0x7fffffffu;
|
|
1797
|
+
let bMagnitude = bBits & 0x7fffffffu;
|
|
1798
|
+
if (aMagnitude == 0u && bMagnitude == 0u) {
|
|
1799
|
+
return 0;
|
|
1800
|
+
}
|
|
1801
|
+
let aSign = aBits >> 31u;
|
|
1802
|
+
let bSign = bBits >> 31u;
|
|
1803
|
+
if (aSign != bSign) {
|
|
1804
|
+
return select(1, -1, aSign == 1u);
|
|
1805
|
+
}
|
|
1806
|
+
if (aMagnitude == bMagnitude) {
|
|
1807
|
+
return 0;
|
|
1808
|
+
}
|
|
1809
|
+
let magnitudeComparison = select(-1, 1, aMagnitude > bMagnitude);
|
|
1810
|
+
return select(magnitudeComparison, -magnitudeComparison, aSign == 1u);
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
// Normalize an arbitrary pair of finite f32 limbs with integer accumulation.
|
|
1814
|
+
// This is independent of LUMA_FP64_INTEGER_ARITHMETIC and canonicalizes every
|
|
1815
|
+
// representation of zero to vec2f(+0.0, +0.0).
|
|
1816
|
+
fn normalize_fp64(value: vec2f) -> vec2f {
|
|
1817
|
+
let resultBits = fp64_add_raw_f32_bits(bitcast<u32>(value.x), bitcast<u32>(value.y));
|
|
1818
|
+
return vec2f(bitcast<f32>(resultBits.x), bitcast<f32>(resultBits.y));
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
fn is_nan_fp64(value: vec2f) -> bool {
|
|
1822
|
+
let normalized = normalize_fp64(value);
|
|
1823
|
+
return fp64_f32_bits_is_nan(bitcast<u32>(normalized.x)) ||
|
|
1824
|
+
fp64_f32_bits_is_nan(bitcast<u32>(normalized.y));
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
fn is_finite_fp64(value: vec2f) -> bool {
|
|
1828
|
+
let normalized = normalize_fp64(value);
|
|
1829
|
+
let highBits = bitcast<u32>(normalized.x);
|
|
1830
|
+
let lowBits = bitcast<u32>(normalized.y);
|
|
1831
|
+
return !fp64_f32_bits_is_nan(highBits) && !fp64_f32_bits_is_nan(lowBits) &&
|
|
1832
|
+
!fp64_f32_bits_is_inf(highBits) && !fp64_f32_bits_is_inf(lowBits);
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
// Returns -1, 0, or 1. NaN is unordered and returns 0; call is_nan_fp64 or
|
|
1836
|
+
// is_finite_fp64 first when 0 must mean a finite zero.
|
|
1837
|
+
fn sign_fp64(value: vec2f) -> i32 {
|
|
1838
|
+
let normalized = normalize_fp64(value);
|
|
1839
|
+
let highBits = bitcast<u32>(normalized.x);
|
|
1840
|
+
let lowBits = bitcast<u32>(normalized.y);
|
|
1841
|
+
if (fp64_f32_bits_is_nan(highBits) || fp64_f32_bits_is_nan(lowBits)) {
|
|
1842
|
+
return 0;
|
|
1843
|
+
}
|
|
1844
|
+
if ((highBits & 0x7fffffffu) != 0u) {
|
|
1845
|
+
return select(1, -1, (highBits >> 31u) == 1u);
|
|
1846
|
+
}
|
|
1847
|
+
if ((lowBits & 0x7fffffffu) != 0u) {
|
|
1848
|
+
return select(1, -1, (lowBits >> 31u) == 1u);
|
|
1849
|
+
}
|
|
1850
|
+
return 0;
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// Compares double-single values and returns -1, 0, or 1. NaN is unordered
|
|
1854
|
+
// and returns 0; callers that require equality semantics must first check
|
|
1855
|
+
// is_nan_fp64 or is_finite_fp64.
|
|
1856
|
+
fn compare_fp64(a: vec2f, b: vec2f) -> i32 {
|
|
1857
|
+
let normalizedA = normalize_fp64(a);
|
|
1858
|
+
let normalizedB = normalize_fp64(b);
|
|
1859
|
+
let aHighBits = bitcast<u32>(normalizedA.x);
|
|
1860
|
+
let aLowBits = bitcast<u32>(normalizedA.y);
|
|
1861
|
+
let bHighBits = bitcast<u32>(normalizedB.x);
|
|
1862
|
+
let bLowBits = bitcast<u32>(normalizedB.y);
|
|
1863
|
+
if (fp64_f32_bits_is_nan(aHighBits) || fp64_f32_bits_is_nan(aLowBits) ||
|
|
1864
|
+
fp64_f32_bits_is_nan(bHighBits) || fp64_f32_bits_is_nan(bLowBits)) {
|
|
1865
|
+
return 0;
|
|
1866
|
+
}
|
|
1867
|
+
let highComparison = fp64_compare_f32_bits(aHighBits, bHighBits);
|
|
1868
|
+
if (highComparison != 0) {
|
|
1869
|
+
return highComparison;
|
|
1870
|
+
}
|
|
1871
|
+
return fp64_compare_f32_bits(aLowBits, bLowBits);
|
|
1872
|
+
}
|
|
1873
|
+
#endif
|
|
1874
|
+
`;var ut=`const vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08);
|
|
732
1875
|
const vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09);
|
|
733
1876
|
const vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8);
|
|
734
1877
|
const vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7);
|
|
@@ -1397,7 +2540,7 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
|
|
|
1397
2540
|
vec4_dot_fp64(a, tmp, out_val[i]);
|
|
1398
2541
|
}
|
|
1399
2542
|
}
|
|
1400
|
-
`;var
|
|
2543
|
+
`;var sr={ONE:1,SPLIT:4097},ct={name:"fp64arithmetic",source:lt,fs:ye,vs:ye,defaultUniforms:sr,uniformTypes:{ONE:"f32",SPLIT:"f32"},fp64ify:te,fp64LowPart:xe,fp64ifyMatrix4:be},ie={name:"fp64",vs:ut,dependencies:[ct],fp64ify:te,fp64LowPart:xe,fp64ifyMatrix4:be};var re=d(_(),1);var pt=`const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097);
|
|
1401
2544
|
layout(std140) uniform project64Uniforms {
|
|
1402
2545
|
vec2 scale;
|
|
1403
2546
|
mat4 viewProjectionMatrix;
|
|
@@ -1470,7 +2613,7 @@ return project_position_to_clipspace(
|
|
|
1470
2613
|
position, position64xyLow, offset, commonPosition
|
|
1471
2614
|
);
|
|
1472
2615
|
}
|
|
1473
|
-
`;var{fp64ify:
|
|
2616
|
+
`;var{fp64ify:ar,fp64ifyMatrix4:fr}=ie,ne={name:"project64",dependencies:[re.project,ie],vs:pt,getUniforms:ur,uniformTypes:{scale:"vec2<f32>",viewProjectionMatrix:"mat4x4<f32>",viewProjectionMatrix64Low:"mat4x4<f32>"}},lr=(0,re._memoize)(cr);function ur(i){if(i&&"viewport"in i){let{viewProjectionMatrix:e,scale:t}=i.viewport;return lr({viewProjectionMatrix:e,scale:t})}return{}}function cr({viewProjectionMatrix:i,scale:e}){let t=fr(i),r=new Float32Array(16),n=new Float32Array(16);for(let o=0;o<4;o++)for(let s=0;s<4;s++){let a=4*o+s,f=4*s+o;r[f]=t[2*a],n[f]=t[2*a+1]}return{scale:ar(e),viewProjectionMatrix:[...r],viewProjectionMatrix64Low:[...n]}}var oe=class extends dt.LayerExtension{getShaders(){let{coordinateSystem:e}=this.props;if(e!=="lnglat"&&e!=="default")throw new Error("fp64: coordinateSystem must be LNGLAT");return{modules:[ne]}}draw(e,t){let{viewport:r}=e.context;this.setShaderModuleProps({project64:{viewport:r}})}};oe.extensionName="Fp64Extension";var _t=oe;var R=d(_(),1);var mt={inject:{"vs:#decl":`
|
|
1474
2617
|
in vec2 instanceDashArrays;
|
|
1475
2618
|
#ifdef HIGH_PRECISION_DASH
|
|
1476
2619
|
in float instanceDashOffsets;
|
|
@@ -1522,7 +2665,7 @@ discard;
|
|
|
1522
2665
|
}
|
|
1523
2666
|
}
|
|
1524
2667
|
}
|
|
1525
|
-
`}},
|
|
2668
|
+
`}},ht={inject:{"vs:#decl":`
|
|
1526
2669
|
in vec2 instanceDashArrays;
|
|
1527
2670
|
out vec2 vDashArray;
|
|
1528
2671
|
`,"vs:#main-end":`
|
|
@@ -1564,7 +2707,7 @@ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
|
|
|
1564
2707
|
fragColor = picking_filterPickingColor(fragColor);
|
|
1565
2708
|
fragColor = picking_filterHighlightColor(fragColor);
|
|
1566
2709
|
}
|
|
1567
|
-
`}},
|
|
2710
|
+
`}},gt={inject:{"vs:#decl":`
|
|
1568
2711
|
in vec2 instanceDashArrays;
|
|
1569
2712
|
out vec2 vDashArray;
|
|
1570
2713
|
`,"vs:#main-end":`
|
|
@@ -1703,14 +2846,14 @@ isInside = step(-1.0, vPathPosition.x) * step(vPathPosition.x, 1.0);
|
|
|
1703
2846
|
if (isInside == 0.0) {
|
|
1704
2847
|
discard;
|
|
1705
2848
|
}
|
|
1706
|
-
`}};var
|
|
2849
|
+
`}};var pr={getDashArray:{type:"accessor",value:[0,0]},getOffset:{type:"accessor",value:0},dashJustified:!1,dashGapPickable:!1},C=class extends R.LayerExtension{constructor({dash:e=!1,offset:t=!1,highPrecisionDash:r=!1}={}){super({dash:e||r,offset:t,highPrecisionDash:r})}getLayerType(e){if("pathTesselator"in e.state)return"path";let t=e.constructor.layerName;return t==="ScatterplotLayer"?"scatterplot":t==="TextBackgroundLayer"?"textBackground":null}isEnabled(e){return this.getLayerType(e)!==null}getShaders(e){let t=e.getLayerType(this);if(!t)return null;if(t==="scatterplot"||t==="textBackground")return e.opts.dash?{modules:[{name:"pathStyle",inject:t==="scatterplot"?ht.inject:gt.inject,uniformTypes:{dashGapPickable:"i32"}}]}:null;let r={},n={};e.opts.dash&&(r=(0,R._mergeShaders)(r,mt),e.opts.highPrecisionDash&&(n.HIGH_PRECISION_DASH=!0)),e.opts.offset&&(r=(0,R._mergeShaders)(r,vt));let{inject:o}=r;return{modules:[{name:"pathStyle",inject:o,uniformTypes:{dashAlignMode:"f32",dashGapPickable:"i32"}}],defines:n}}initializeState(e,t){let r=this.getAttributeManager(),n=t.getLayerType(this);!r||!n||(t.opts.dash&&r.addInstanced({instanceDashArrays:{size:2,accessor:"getDashArray"},...n==="path"&&t.opts.highPrecisionDash?{instanceDashOffsets:{size:1,accessor:"getPath",transform:t.getDashOffsets.bind(this)}}:{}}),n==="path"&&t.opts.offset&&r.addInstanced({instanceOffsets:{size:1,accessor:"getOffset"}}))}updateState(e,t){if(t.isEnabled(this)&&t.opts.dash){let r=t.getLayerType(this);if(r==="scatterplot"||r==="textBackground"){let n={dashGapPickable:!!this.props.dashGapPickable};this.setShaderModuleProps({pathStyle:n})}else{let n={dashAlignMode:this.props.dashJustified?1:0,dashGapPickable:!!this.props.dashGapPickable};this.setShaderModuleProps({pathStyle:n})}}}getDashOffsets(e){let t=[0],r=this.props.positionFormat==="XY"?2:3,n=Array.isArray(e[0]),o=n?e.length:e.length/r,s,a;for(let f=0;f<o-1;f++)s=n?e[f]:e.slice(f*r,f*r+r),s=this.projectPosition(s),f>0&&(t[f]=t[f-1]+ee.dist(a,s)),a=s;return t[o-1]=0,t}};C.defaultProps=pr;C.extensionName="PathStyleExtension";var xt=C;var Pt=d(_(),1);var F=d(_(),1),bt=`layout(std140) uniform fillUniforms {
|
|
1707
2850
|
vec2 patternTextureSize;
|
|
1708
2851
|
bool patternEnabled;
|
|
1709
2852
|
bool patternMask;
|
|
1710
2853
|
vec2 uvCoordinateOrigin;
|
|
1711
2854
|
vec2 uvCoordinateOrigin64Low;
|
|
1712
2855
|
} fill;
|
|
1713
|
-
`,
|
|
2856
|
+
`,dr=`
|
|
1714
2857
|
in vec4 fillPatternFrames;
|
|
1715
2858
|
in float fillPatternScales;
|
|
1716
2859
|
in vec2 fillPatternOffsets;
|
|
@@ -1718,10 +2861,10 @@ in vec2 fillPatternOffsets;
|
|
|
1718
2861
|
out vec2 fill_uv;
|
|
1719
2862
|
out vec4 fill_patternBounds;
|
|
1720
2863
|
out vec4 fill_patternPlacement;
|
|
1721
|
-
`,
|
|
1722
|
-
${
|
|
1723
|
-
${
|
|
1724
|
-
`,
|
|
2864
|
+
`,_r=`
|
|
2865
|
+
${bt}
|
|
2866
|
+
${dr}
|
|
2867
|
+
`,mr=`
|
|
1725
2868
|
uniform sampler2D fill_patternTexture;
|
|
1726
2869
|
|
|
1727
2870
|
in vec4 fill_patternBounds;
|
|
@@ -1729,10 +2872,10 @@ in vec4 fill_patternPlacement;
|
|
|
1729
2872
|
in vec2 fill_uv;
|
|
1730
2873
|
|
|
1731
2874
|
const float FILL_UV_SCALE = 512.0 / 40000000.0;
|
|
1732
|
-
`,
|
|
1733
|
-
${
|
|
1734
|
-
${
|
|
1735
|
-
`,
|
|
2875
|
+
`,hr=`
|
|
2876
|
+
${bt}
|
|
2877
|
+
${mr}
|
|
2878
|
+
`,gr={"vs:DECKGL_FILTER_GL_POSITION":`
|
|
1736
2879
|
fill_uv = geometry.position.xy;
|
|
1737
2880
|
`,"vs:DECKGL_FILTER_COLOR":`
|
|
1738
2881
|
if (fill.patternEnabled) {
|
|
@@ -1754,7 +2897,7 @@ ${mo}
|
|
|
1754
2897
|
color.rgb = patternColor.rgb;
|
|
1755
2898
|
}
|
|
1756
2899
|
}
|
|
1757
|
-
`};function
|
|
2900
|
+
`};function vr(i){if(!i)return{};let e={};if("fillPatternTexture"in i){let{fillPatternTexture:t}=i;e.fill_patternTexture=t,e.patternTextureSize=[t.width,t.height]}if("project"in i){let{fillPatternMask:t=!0,fillPatternEnabled:r=!0}=i,n=F.project.getUniforms(i.project),{commonOrigin:o}=n,s=[(0,F.fp64LowPart)(o[0]),(0,F.fp64LowPart)(o[1])];e.uvCoordinateOrigin=o.slice(0,2),e.uvCoordinateOrigin64Low=s,e.patternMask=t,e.patternEnabled=r}return e}var yt={name:"fill",vs:_r,fs:hr,inject:gr,dependencies:[F.project],getUniforms:vr,uniformTypes:{patternTextureSize:"vec2<f32>",patternEnabled:"i32",patternMask:"i32",uvCoordinateOrigin:"vec2<f32>",uvCoordinateOrigin64Low:"vec2<f32>"}};var xr={fillPatternEnabled:!0,fillPatternAtlas:{type:"image",value:null,async:!0,parameters:{lodMaxClamp:0}},fillPatternMapping:{type:"object",value:{},async:!0},fillPatternMask:!0,getFillPattern:{type:"accessor",value:i=>i.pattern},getFillPatternScale:{type:"accessor",value:1},getFillPatternOffset:{type:"accessor",value:[0,0]}},k=class extends Pt.LayerExtension{constructor({pattern:e=!1}={}){super({pattern:e})}isEnabled(e){return e.getAttributeManager()!==null&&!("pathTesselator"in e.state)}getShaders(e){return e.isEnabled(this)?{modules:[e.opts.pattern&&yt].filter(Boolean)}:null}initializeState(e,t){if(!t.isEnabled(this))return;let r=this.getAttributeManager();t.opts.pattern&&r.add({fillPatternFrames:{size:4,stepMode:"dynamic",accessor:"getFillPattern",transform:t.getPatternFrame.bind(this)},fillPatternScales:{size:1,stepMode:"dynamic",accessor:"getFillPatternScale",defaultValue:1},fillPatternOffsets:{size:2,stepMode:"dynamic",accessor:"getFillPatternOffset"}}),this.setState({emptyTexture:this.context.device.createTexture({data:new Uint8Array(4),width:1,height:1})})}updateState({props:e,oldProps:t},r){r.isEnabled(this)&&e.fillPatternMapping&&e.fillPatternMapping!==t.fillPatternMapping&&this.getAttributeManager().invalidate("getFillPattern")}draw(e,t){if(!t.isEnabled(this))return;let{fillPatternAtlas:r,fillPatternEnabled:n,fillPatternMask:o}=this.props,s={project:e.shaderModuleProps.project,fillPatternEnabled:n,fillPatternMask:o,fillPatternTexture:r||this.state.emptyTexture};this.setShaderModuleProps({fill:s})}finalizeState(){this.state.emptyTexture?.delete()}getPatternFrame(e){let{fillPatternMapping:t}=this.getCurrentLayer().props,r=t&&t[e];return r?[r.x,r.y,r.width,r.height]:[0,0,0,0]}};k.defaultProps=xr;k.extensionName="FillStyleExtension";var Et=k;var Mt=d(_(),1),br={clipBounds:[0,0,1,1],clipByInstance:void 0},Ft=`
|
|
1758
2901
|
layout(std140) uniform clipUniforms {
|
|
1759
2902
|
vec4 bounds;
|
|
1760
2903
|
} clip;
|
|
@@ -1762,7 +2905,7 @@ layout(std140) uniform clipUniforms {
|
|
|
1762
2905
|
bool clip_isInBounds(vec2 position) {
|
|
1763
2906
|
return position.x >= clip.bounds[0] && position.y >= clip.bounds[1] && position.x < clip.bounds[2] && position.y < clip.bounds[3];
|
|
1764
2907
|
}
|
|
1765
|
-
`,
|
|
2908
|
+
`,yr={name:"clip",vs:Ft,uniformTypes:{bounds:"vec4<f32>"}},Pr={"vs:#decl":`
|
|
1766
2909
|
out float clip_isVisible;
|
|
1767
2910
|
`,"vs:DECKGL_FILTER_GL_POSITION":`
|
|
1768
2911
|
clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
|
|
@@ -1770,7 +2913,7 @@ out float clip_isVisible;
|
|
|
1770
2913
|
in float clip_isVisible;
|
|
1771
2914
|
`,"fs:DECKGL_FILTER_COLOR":`
|
|
1772
2915
|
if (clip_isVisible < 0.5) discard;
|
|
1773
|
-
`},
|
|
2916
|
+
`},Er={name:"clip",fs:Ft,uniformTypes:{bounds:"vec4<f32>"}},Mr={"vs:#decl":`
|
|
1774
2917
|
out vec2 clip_commonPosition;
|
|
1775
2918
|
`,"vs:DECKGL_FILTER_GL_POSITION":`
|
|
1776
2919
|
clip_commonPosition = geometry.position.xy;
|
|
@@ -1778,7 +2921,7 @@ out vec2 clip_commonPosition;
|
|
|
1778
2921
|
in vec2 clip_commonPosition;
|
|
1779
2922
|
`,"fs:DECKGL_FILTER_COLOR":`
|
|
1780
2923
|
if (!clip_isInBounds(clip_commonPosition)) discard;
|
|
1781
|
-
`},
|
|
2924
|
+
`},N=class extends Mt.LayerExtension{getShaders(){let e="instancePositions"in this.getAttributeManager().attributes;return this.props.clipByInstance!==void 0&&(e=!!this.props.clipByInstance),this.state.clipByInstance=e,this.context.device.type==="webgpu"?{}:e?{modules:[yr],inject:Pr}:{modules:[Er],inject:Mr}}draw(){let{clipBounds:e}=this.props,t={};if(this.state.clipByInstance)t.bounds=e;else{let r=this.projectPosition([e[0],e[1],0]),n=this.projectPosition([e[2],e[3],0]);t.bounds=[Math.min(r[0],n[0]),Math.min(r[1],n[1]),Math.max(r[0],n[0]),Math.max(r[1],n[1])]}this.context.device.type==="webgpu"&&(t.enabled=!0,t.mode=this.state.clipByInstance?"instance":"geometry"),this.setShaderModuleProps({clip:t})}};N.defaultProps=br;N.extensionName="ClipExtension";var At=N;var Ot=d(_(),1);var St=d(_(),1),Fr=`
|
|
1782
2925
|
in float collisionPriorities;
|
|
1783
2926
|
|
|
1784
2927
|
uniform sampler2D collision_texture;
|
|
@@ -1826,7 +2969,7 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
|
|
|
1826
2969
|
float W = 2.0 * floatN + 1.0;
|
|
1827
2970
|
return pow(accumulator / (W * W), 2.2);
|
|
1828
2971
|
}
|
|
1829
|
-
`,
|
|
2972
|
+
`,Ar={"vs:#decl":`
|
|
1830
2973
|
float collision_fade = 1.0;
|
|
1831
2974
|
`,"vs:DECKGL_FILTER_GL_POSITION":`
|
|
1832
2975
|
if (collision.sort) {
|
|
@@ -1845,21 +2988,21 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
|
|
|
1845
2988
|
}
|
|
1846
2989
|
`,"vs:DECKGL_FILTER_COLOR":`
|
|
1847
2990
|
color.a *= collision_fade;
|
|
1848
|
-
`},
|
|
2991
|
+
`},Sr=i=>{if(!i||!("dummyCollisionMap"in i))return{};let{enabled:e,collisionFBO:t,drawToCollisionMap:r,dummyCollisionMap:n}=i;return{enabled:e&&!r,sort:!!r,collision_texture:!r&&t?t.colorAttachments[0]:n}},Tt={name:"collision",dependencies:[St.project],vs:Fr,inject:Ar,getUniforms:Sr,uniformTypes:{sort:"i32",enabled:"i32"}};var Lt=d(_(),1);var Bt=d(_(),1),D=class extends Bt._LayersPass{renderCollisionMap(e,t){let n=[0,0,0,0],o=[1,1,e.width-2,e.height-2];this.render({...t,clearColor:n,scissorRect:o,target:e,pass:"collision"})}getLayerParameters(e,t,r){return{...e.props.parameters,blend:!1,depthWriteEnabled:!0,depthCompare:"less-equal"}}getShaderModuleProps(){return{collision:{drawToCollisionMap:!0},picking:{isActive:1,isAttribute:!1},lighting:{enabled:!1}}}};var Pe=2,z=class{constructor(){this.id="collision-filter-effect",this.props=null,this.useInPicking=!0,this.order=1,this.channels={},this.collisionFBOs={}}setup(e){this.context=e;let{device:t}=e;this.dummyCollisionMap=t.createTexture({width:1,height:1}),this.collisionFilterPass=new D(t,{id:"default-collision-filter"})}preRender({effects:e,layers:t,layerFilter:r,viewports:n,onViewportActive:o,views:s,isPicking:a,preRenderStats:f={}}){let{device:l}=this.context;if(a)return;let c=t.filter(({props:{visible:g,collisionEnabled:B}})=>g&&B);if(c.length===0){this.channels={};return}let u=e?.filter(g=>g.useInPicking&&f[g.id]),p=f["mask-effect"]?.didRender,m=this._groupByCollisionGroup(l,c),h=n[0],P=!this.lastViewport||!this.lastViewport.equals(h)||p;for(let g in m){let B=this.collisionFBOs[g],ce=m[g],[pe,de]=l.canvasContext.getPixelSize();B.resize({width:pe/Pe,height:de/Pe}),this._render(ce,{effects:u,layerFilter:r,onViewportActive:o,views:s,viewport:h,viewportChanged:P})}}_render(e,{effects:t,layerFilter:r,onViewportActive:n,views:o,viewport:s,viewportChanged:a}){let{collisionGroup:f}=e,l=this.channels[f];if(!l)return;let c=a||e===l||!(0,Lt._deepEqual)(l.layers,e.layers,1)||e.layerBounds.some((u,p)=>!M(u,l.layerBounds[p]))||e.allLayersLoaded!==l.allLayersLoaded||e.layers.some(u=>u.props.transitions);if(this.channels[f]=e,c){this.lastViewport=s;let u=this.collisionFBOs[f];this.collisionFilterPass.renderCollisionMap(u,{pass:"collision-filter",isPicking:!0,layers:e.layers,effects:t,layerFilter:r,viewports:s?[s]:[],onViewportActive:n,views:o,shaderModuleProps:{collision:{enabled:!0,dummyCollisionMap:this.dummyCollisionMap},project:{devicePixelRatio:u.device.canvasContext.getDevicePixelRatio()/Pe}}})}}_groupByCollisionGroup(e,t){let r={};for(let n of t){let o=n.props.collisionGroup,s=r[o];s||(s={collisionGroup:o,layers:[],layerBounds:[],allLayersLoaded:!0},r[o]=s),s.layers.push(n),s.layerBounds.push(n.getBounds()),n.isLoaded||(s.allLayersLoaded=!1)}for(let n of Object.keys(r))this.collisionFBOs[n]||this.createFBO(e,n),this.channels[n]||(this.channels[n]=r[n]);for(let n of Object.keys(this.collisionFBOs))r[n]||this.destroyFBO(n);return r}getShaderModuleProps(e){let{collisionGroup:t,collisionEnabled:r}=e.props,{collisionFBOs:n,dummyCollisionMap:o}=this,s=n[t];return{collision:{enabled:r&&!!s,collisionFBO:s,dummyCollisionMap:o}}}cleanup(){this.dummyCollisionMap&&(this.dummyCollisionMap.delete(),this.dummyCollisionMap=void 0),this.channels={};for(let e of Object.keys(this.collisionFBOs))this.destroyFBO(e);this.collisionFBOs={},this.lastViewport=void 0}createFBO(e,t){let{width:r,height:n}=e.getDefaultCanvasContext().canvas,o=e.createTexture({format:"rgba8unorm",width:r,height:n,sampler:{minFilter:"nearest",magFilter:"nearest",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}}),s=e.createTexture({format:"depth16unorm",width:r,height:n});this.collisionFBOs[t]=e.createFramebuffer({id:`collision-${t}`,width:r,height:n,colorAttachments:[o],depthStencilAttachment:s})}destroyFBO(e){let t=this.collisionFBOs[e];t.colorAttachments[0]?.destroy(),t.depthStencilAttachment?.destroy(),t.destroy(),delete this.collisionFBOs[e]}};var Tr={getCollisionPriority:{type:"accessor",value:0},collisionEnabled:!0,collisionGroup:{type:"string",value:"default"},collisionTestProps:{}},V=class extends Ot.LayerExtension{getShaders(){return{modules:[Tt]}}draw({shaderModuleProps:e}){e.collision?.drawToCollisionMap&&(this.props=this.clone(this.props.collisionTestProps).props)}initializeState(e,t){if(this.getAttributeManager()===null)return;this.context.deck?._addDefaultEffect(new z),this.getAttributeManager().add({collisionPriorities:{size:1,stepMode:"dynamic",accessor:"getCollisionPriority"}})}getNeedsPickingBuffer(){return this.props.collisionEnabled}};V.defaultProps=Tr;V.extensionName="CollisionFilterExtension";var wt=V;var y=d(_(),1);var It=d(_(),1),Rt=`layout(std140) uniform maskUniforms {
|
|
1849
2992
|
vec4 bounds;
|
|
1850
2993
|
highp int channel;
|
|
1851
2994
|
bool enabled;
|
|
1852
2995
|
bool inverted;
|
|
1853
2996
|
bool maskByInstance;
|
|
1854
2997
|
} mask;
|
|
1855
|
-
`,
|
|
2998
|
+
`,Br=`
|
|
1856
2999
|
vec2 mask_getCoords(vec4 position) {
|
|
1857
3000
|
return (position.xy - mask.bounds.xy) / (mask.bounds.zw - mask.bounds.xy);
|
|
1858
3001
|
}
|
|
1859
|
-
`,
|
|
1860
|
-
${
|
|
1861
|
-
${
|
|
1862
|
-
`,
|
|
3002
|
+
`,Lr=`
|
|
3003
|
+
${Rt}
|
|
3004
|
+
${Br}
|
|
3005
|
+
`,Or=`
|
|
1863
3006
|
uniform sampler2D mask_texture;
|
|
1864
3007
|
|
|
1865
3008
|
bool mask_isInBounds(vec2 texCoords) {
|
|
@@ -1884,10 +3027,10 @@ bool mask_isInBounds(vec2 texCoords) {
|
|
|
1884
3027
|
return maskValue < 0.5;
|
|
1885
3028
|
}
|
|
1886
3029
|
}
|
|
1887
|
-
`,
|
|
1888
|
-
${
|
|
1889
|
-
${
|
|
1890
|
-
`,
|
|
3030
|
+
`,wr=`
|
|
3031
|
+
${Rt}
|
|
3032
|
+
${Or}
|
|
3033
|
+
`,Ir={"vs:#decl":`
|
|
1891
3034
|
out vec2 mask_texCoords;
|
|
1892
3035
|
`,"vs:#main-end":`
|
|
1893
3036
|
vec4 mask_common_position;
|
|
@@ -1909,15 +3052,15 @@ in vec2 mask_texCoords;
|
|
|
1909
3052
|
|
|
1910
3053
|
if (!mask) discard;
|
|
1911
3054
|
}
|
|
1912
|
-
`},
|
|
1913
|
-
`),
|
|
3055
|
+
`},Rr=i=>i&&"maskMap"in i?{mask_texture:i.maskMap}:i||{},Ct={name:"mask",dependencies:[It.project],vs:Lr,fs:wr,inject:Ir,getUniforms:Rr,uniformTypes:{bounds:"vec4<f32>",channel:"i32",enabled:"i32",inverted:"i32",maskByInstance:"i32"}};var Me=d(_(),1);var kt=d(_(),1),Cr={blendColorOperation:"subtract",blendColorSrcFactor:"zero",blendColorDstFactor:"one",blendAlphaOperation:"subtract",blendAlphaSrcFactor:"zero",blendAlphaDstFactor:"one"},U=class extends kt._LayersPass{constructor(e,t){super(e,t);let{mapSize:r=2048}=t;this.maskMap=e.createTexture({format:"rgba8unorm",width:r,height:r,sampler:{minFilter:"linear",magFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}}),this.fbo=e.createFramebuffer({id:"maskmap",width:r,height:r,colorAttachments:[this.maskMap]})}render(e){let t=2**e.channel,r=[255,255,255,255];super.render({...e,clearColor:r,colorMask:t,target:this.fbo,pass:"mask"})}getLayerParameters(e,t,r){return{...e.props.parameters,blend:!0,depthCompare:"always",...Cr}}shouldDrawLayer(e){return e.props.operation.includes("mask")}delete(){this.fbo.delete(),this.maskMap.delete()}};var j=d(_(),1),Ee=new j.WebMercatorViewport({width:1,height:1,longitude:0,latitude:0,zoom:0});function G(i){let[e,t]=Ee.projectPosition(i);return[e,t]}function se(i){return i.isGeospatial?Ee:i}function A(i,e){let t=[1/0,1/0,-1/0,-1/0];for(let r of i){let n=r.getBounds();if(n){let o=r.projectPosition(n[0],{viewport:e,autoOffset:!1}),s=r.projectPosition(n[1],{viewport:e,autoOffset:!1});t[0]=Math.min(t[0],o[0]),t[1]=Math.min(t[1],o[1]),t[2]=Math.max(t[2],s[0]),t[3]=Math.max(t[3],s[1])}}return Number.isFinite(t[0])?t:null}var kr=2048;function S(i){let{bounds:e,viewport:t,border:r=0}=i,{isGeospatial:n}=t;if(e[2]<=e[0]||e[3]<=e[1])return null;let o=n?Ee.unprojectPosition([(e[0]+e[2])/2,(e[1]+e[3])/2,0]):t.unprojectPosition([(e[0]+e[2])/2,(e[1]+e[3])/2,0]),{width:s,height:a,zoom:f}=i;if(f===void 0){s=s-r*2,a=a-r*2;let l=Math.min(s/(e[2]-e[0]),a/(e[3]-e[1]));f=Math.min(Math.log2(l),20)}else if(!s||!a){let l=2**f;s=Math.round(Math.abs(e[2]-e[0])*l),a=Math.round(Math.abs(e[3]-e[1])*l);let c=kr-r*2;if(s>c||a>c){let u=c/Math.max(s,a);s=Math.round(s*u),a=Math.round(a*u),f+=Math.log2(u)}}return n?new j.WebMercatorViewport({id:t.id,x:r,y:r,width:s,height:a,longitude:o[0],latitude:o[1],zoom:f,orthographic:!0}):new j.OrthographicViewport({id:t.id,x:r,y:r,width:s,height:a,target:o,zoom:f,flipY:!1})}function Nr(i,e){let t;if(e&&e.length===2){let[o,s]=e,a=i.getBounds({z:o}),f=i.getBounds({z:s});t=[Math.min(a[0],f[0]),Math.min(a[1],f[1]),Math.max(a[2],f[2]),Math.max(a[3],f[3])]}else t=i.getBounds();let r=i.projectPosition(t.slice(0,2)),n=i.projectPosition(t.slice(2,4));return[r[0],r[1],n[0],n[1]]}function T(i,e,t){if(!i)return[0,0,1,1];let r=Nr(e,t),n=Dr(r);return i[2]-i[0]<=n[2]-n[0]&&i[3]-i[1]<=n[3]-n[1]?i:[Math.max(i[0],n[0]),Math.max(i[1],n[1]),Math.min(i[2],n[2]),Math.min(i[3],n[3])]}function Dr(i){let e=i[2]-i[0],t=i[3]-i[1],r=(i[0]+i[2])/2,n=(i[1]+i[3])/2;return[r-e,n-t,r+e,n+t]}var H=class{constructor(){this.id="mask-effect",this.props=null,this.useInPicking=!0,this.order=0,this.channels=[],this.masks=null}setup({device:e}){this.dummyMaskMap=e.createTexture({width:1,height:1}),this.maskPass=new U(e,{id:"default-mask"}),this.maskMap=this.maskPass.maskMap}preRender({layers:e,layerFilter:t,viewports:r,onViewportActive:n,views:o,effects:s,isPicking:a}){let f=!1;if(a)return{didRender:f};let l=e.filter(m=>m.props.visible&&m.props.operation.includes("mask"));if(l.length===0)return this.masks=null,this.channels.length=0,{didRender:f};this.masks={};let c=this._sortMaskChannels(l),u=r[0],p=!this.lastViewport||!this.lastViewport.equals(u);if(u.resolution!==void 0)return Me.log.warn("MaskExtension is not supported in GlobeView")(),{didRender:f};for(let m in c){let h=this._renderChannel(c[m],{layerFilter:t,onViewportActive:n,views:o,effects:s,viewport:u,viewportChanged:p});f||(f=h)}return{didRender:f}}_renderChannel(e,{layerFilter:t,onViewportActive:r,views:n,effects:o,viewport:s,viewportChanged:a}){let f=!1,l=this.channels[e.index];if(!l)return f;let c=e===l||e.layers.length!==l.layers.length||e.layers.some((u,p)=>u!==l.layers[p]||u.props.transitions)||e.layerBounds.some((u,p)=>u!==l.layerBounds[p]);if(e.bounds=l.bounds,e.maskBounds=l.maskBounds,this.channels[e.index]=e,c||a){this.lastViewport=s;let u=A(e.layers,s);if(e.bounds=u&&T(u,s),c||!M(e.bounds,l.bounds)){let{maskPass:p,maskMap:m}=this,h=u&&S({bounds:e.bounds,viewport:s,width:m.width,height:m.height,border:1});e.maskBounds=h?h.getBounds():[0,0,1,1],p.render({pass:"mask",channel:e.index,layers:e.layers,layerFilter:t,viewports:h?[h]:[],onViewportActive:r,views:n,effects:o,shaderModuleProps:{project:{devicePixelRatio:1}}}),f=!0}}return this.masks[e.id]={index:e.index,bounds:e.maskBounds,coordinateOrigin:e.coordinateOrigin,coordinateSystem:e.coordinateSystem},f}_sortMaskChannels(e){let t={},r=0;for(let n of e){let{id:o}=n.root,s=t[o];if(!s){if(++r>4){Me.log.warn("Too many mask layers. The max supported is 4")();continue}s={id:o,index:this.channels.findIndex(a=>a?.id===o),layers:[],layerBounds:[],coordinateOrigin:n.root.props.coordinateOrigin,coordinateSystem:n.root.props.coordinateSystem},t[o]=s}s.layers.push(n),s.layerBounds.push(n.getBounds())}for(let n=0;n<4;n++){let o=this.channels[n];(!o||!(o.id in t))&&(this.channels[n]=null)}for(let n in t){let o=t[n];o.index<0&&(o.index=this.channels.findIndex(s=>!s),this.channels[o.index]=o)}return t}getShaderModuleProps(){return{mask:{maskMap:this.masks?this.maskMap:this.dummyMaskMap,maskChannels:this.masks}}}cleanup(){this.dummyMaskMap&&(this.dummyMaskMap.delete(),this.dummyMaskMap=void 0),this.maskPass&&(this.maskPass.delete(),this.maskPass=void 0,this.maskMap=void 0),this.lastViewport=void 0,this.masks=null,this.channels.length=0}};var zr={maskId:"",maskByInstance:void 0,maskInverted:!1},q=class extends y.LayerExtension{initializeState(){this.context.deck?._addDefaultEffect(new H)}getShaders(){let e="instancePositions"in this.getAttributeManager().attributes;return this.props.maskByInstance!==void 0&&(e=!!this.props.maskByInstance),this.state.maskByInstance=e,{modules:[Ct]}}draw({context:e,shaderModuleProps:t}){let r={};r.maskByInstance=!!this.state.maskByInstance;let{maskId:n,maskInverted:o}=this.props,{maskChannels:s}=t.mask||{},{viewport:a}=e;if(s&&s[n]){let{index:f,bounds:l,coordinateOrigin:c}=s[n],{coordinateSystem:u}=s[n];r.enabled=!0,r.channel=f,r.inverted=o,u===y.COORDINATE_SYSTEM.DEFAULT&&(u=a.isGeospatial?y.COORDINATE_SYSTEM.LNGLAT:y.COORDINATE_SYSTEM.CARTESIAN);let p={modelMatrix:null,fromCoordinateOrigin:c,fromCoordinateSystem:u},m=this.projectPosition([l[0],l[1],0],p),h=this.projectPosition([l[2],l[3],0],p);r.bounds=[m[0],m[1],h[0],h[1]]}else n&&y.log.warn(`Could not find a mask layer with id: ${n}`)(),r.enabled=!1;this.setShaderModuleProps({mask:r})}};q.defaultProps=zr;q.extensionName="MaskExtension";var Nt=q;var Wt=d(_(),1);var qt=d(_(),1);var Fe=d(_(),1),v={NONE:0,WRITE_HEIGHT_MAP:1,USE_HEIGHT_MAP:2,USE_COVER:3,USE_COVER_ONLY:4,SKIP:5},Vr=Object.keys(v).map(i=>`const float TERRAIN_MODE_${i} = ${v[i]}.0;`).join(`
|
|
3056
|
+
`),Dt=Vr+`
|
|
1914
3057
|
layout(std140) uniform terrainUniforms {
|
|
1915
3058
|
float mode;
|
|
1916
3059
|
vec4 bounds;
|
|
1917
3060
|
} terrain;
|
|
1918
3061
|
|
|
1919
3062
|
uniform sampler2D terrain_map;
|
|
1920
|
-
`,
|
|
3063
|
+
`,W={name:"terrain",dependencies:[Fe.project],vs:`${Dt}
|
|
1921
3064
|
out vec3 commonPos;
|
|
1922
3065
|
// In globe mode, absolute Mercator position for terrain FBO UV lookups
|
|
1923
3066
|
out vec2 terrainMercPos;
|
|
@@ -1930,7 +3073,7 @@ vec2 terrain_globe_to_mercator(vec3 globePosition) {
|
|
|
1930
3073
|
float y = atanh(sinLat);
|
|
1931
3074
|
return (vec2(x, y) + PI) * WORLD_SCALE;
|
|
1932
3075
|
}
|
|
1933
|
-
`,fs:`${
|
|
3076
|
+
`,fs:`${Dt}in vec2 terrainMercPos;
|
|
1934
3077
|
in float terrainHeight;`,inject:{"vs:#main-start":`
|
|
1935
3078
|
if (terrain.mode == TERRAIN_MODE_SKIP) {
|
|
1936
3079
|
gl_Position = vec4(0.0);
|
|
@@ -1987,6 +3130,6 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
|
|
|
1987
3130
|
}
|
|
1988
3131
|
return;
|
|
1989
3132
|
}
|
|
1990
|
-
`},getUniforms:(r={})=>{if(!r.dummyHeightMap)return{};if("terrainSkipRender"in r||"drawToTerrainHeightMap"in r){let{drawToTerrainHeightMap:e,heightMap:t,heightMapBounds:o,dummyHeightMap:i,terrainCover:s,useTerrainHeightMap:a,terrainSkipRender:n}=r,l=Fe.project.getUniforms(r.project),{commonOrigin:c}=l,p=n?g.SKIP:g.NONE,f=i,u=null;if(e)p=g.WRITE_HEIGHT_MAP,u=o;else if(a&&t)p=g.USE_HEIGHT_MAP,f=t,u=o;else if(s){let h=(r.isPicking?s.getPickingFramebuffer():s.getRenderFramebuffer())?.colorAttachments[0].texture;r.isPicking&&(p=g.SKIP),h?(f=h,p=p===g.SKIP?g.USE_COVER_ONLY:g.USE_COVER,u=s.bounds):r.isPicking&&!n&&(p=g.NONE)}return{mode:p,terrain_map:f,bounds:u?[u[0]-c[0],u[1]-c[1],u[2]-u[0],u[3]-u[1]]:[0,0,0,0]}}return{mode:g.NONE,terrain_map:r.dummyHeightMap,bounds:[0,0,0,0]}},uniformTypes:{mode:"f32",bounds:"vec4<f32>"}};var Dt=d(_(),1);function Y(r,e){return r.createFramebuffer({id:e.id,colorAttachments:[r.createTexture({id:e.id,...e.float&&{format:"rgba32float",type:5126},dimension:"2d",width:1,height:1,sampler:e.interpolate===!1?{minFilter:"nearest",magFilter:"nearest"}:{minFilter:"linear",magFilter:"linear"}})]})}var ne=class{constructor(e){this.isDirty=!0,this.renderViewport=null,this.bounds=null,this.layers=[],this.targetBounds=null,this.targetBoundsCommon=null,this.targetLayer=e,this.tile=zt(e)}get id(){return this.targetLayer.id}get isActive(){return Boolean(this.targetLayer.getCurrentLayer())}shouldUpdate({targetLayer:e,viewport:t,layers:o,layerNeedsRedraw:i}){e&&(this.targetLayer=e);let s=t?this._updateViewport(t):!1,a=o?this._updateLayers(o):!1;if(i){for(let n of this.layers)if(i[n]){a=!0;break}}return a||s}_updateLayers(e){let t=!1;if(e=this.tile?jo(this.tile,e):e,e.length!==this.layers.length)t=!0;else for(let o=0;o<e.length;o++)if(e[o].id!==this.layers[o]){t=!0;break}return t&&(this.layers=e.map(o=>o.id)),t}_updateViewport(e){let t=this.targetLayer,o=!1;if(this.tile&&"boundingBox"in this.tile){if(!this.targetBounds){o=!0,this.targetBounds=this.tile.boundingBox;let s=H(this.targetBounds[0]),a=H(this.targetBounds[1]);this.targetBoundsCommon=[s[0],s[1],a[0],a[1]]}}else this.targetBounds!==t.getBounds()&&(o=!0,this.targetBounds=t.getBounds(),this.targetBoundsCommon=T([t],ae(e)));if(!this.targetBoundsCommon)return!1;let i=Math.ceil(e.zoom+.5);if(this.tile)this.bounds=this.targetBoundsCommon;else{let s=this.renderViewport?.zoom;o=o||i!==s;let a=e instanceof Dt._GlobeViewport?this.targetBoundsCommon:A(this.targetBoundsCommon,e),n=this.bounds;o=o||!n||a.some((l,c)=>l!==n[c]),this.bounds=a}return o&&(this.renderViewport=O({bounds:this.bounds,zoom:i,viewport:e})),o}getRenderFramebuffer(){return!this.renderViewport||this.layers.length===0?null:(this.fbo||(this.fbo=Y(this.targetLayer.context.device,{id:this.id})),this.fbo)}getPickingFramebuffer(){return!this.renderViewport||this.layers.length===0&&!this.targetLayer.props.pickable?null:(this.pickingFbo||(this.pickingFbo=Y(this.targetLayer.context.device,{id:`${this.id}-picking`,interpolate:!1})),this.pickingFbo)}filterLayers(e){return e.filter(({id:t})=>this.layers.includes(t))}delete(){let{fbo:e,pickingFbo:t}=this;e&&(e.colorAttachments[0].destroy(),e.destroy()),t&&(t.colorAttachments[0].destroy(),t.destroy())}};function jo(r,e){return e.filter(t=>{let o=zt(t);return o?Uo(r.boundingBox,o.boundingBox):!0})}function zt(r){for(;r;){let{tile:e}=r.props;if(e)return e;r=r.parent}return null}function Uo(r,e){return r&&e?r[0][0]<e[1][0]&&e[0][0]<r[1][0]&&r[0][1]<e[1][1]&&e[0][1]<r[1][1]:!1}var Vt=d(_(),1),Go={blendColorOperation:"max",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"max",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one"},le=class extends Vt._LayersPass{getRenderableLayers(e,t){let{layers:o}=t,i=[],s=this._getDrawLayerParams(e,t,!0);for(let a=0;a<o.length;a++){let n=o[a];!n.isComposite&&s[a].shouldDrawLayer&&i.push(n)}return i}renderHeightMap(e,t){let o=e.getRenderFramebuffer(),i=e.renderViewport;!o||!i||(o.resize(i),this.render({...t,target:o,pass:"terrain-height-map",layers:t.layers,viewports:[i],effects:[],clearColor:[0,0,0,0]}))}renderTerrainCover(e,t){let o=e.getRenderFramebuffer(),i=e.renderViewport;if(!o||!i)return;let s=e.filterLayers(t.layers);o.resize(i),this.render({...t,target:o,pass:`terrain-cover-${e.id}`,layers:s,viewports:[i],clearColor:[0,0,0,0]})}getLayerParameters(e,t,o){return{...e.props.parameters,blend:!0,depthCompare:"always",...e.props.operation.includes("terrain")&&Go}}getShaderModuleProps(e,t,o){return{terrain:{project:o.project}}}};var jt=d(_(),1),ce=class extends jt._PickLayersPass{constructor(){super(...arguments),this.drawParameters={}}getRenderableLayers(e,t){let{layers:o}=t,i=[];this.drawParameters={},this._resetColorEncoder(t.pickZ);let s=this._getDrawLayerParams(e,t);for(let a=0;a<o.length;a++){let n=o[a];!n.isComposite&&s[a].shouldDrawLayer&&(i.push(n),this.drawParameters[n.id]=s[a].layerParameters)}return i}renderTerrainCover(e,t){let o=e.getPickingFramebuffer(),i=e.renderViewport;if(!o||!i)return;let s=e.filterLayers(t.layers),a=e.targetLayer;a.props.pickable&&s.unshift(a),o.resize(i);let l=this.drawParameters[a.id]?.blendColor?.[3]??0;this.render({...t,pickingFBO:o,pass:`terrain-cover-picking-${e.id}`,layers:s,viewports:[i],cullRect:void 0,deviceRect:i,pickZ:!1,clearColor:[0,0,0,l]})}getLayerParameters(e,t,o){let i;return this.drawParameters[e.id]?i=this.drawParameters[e.id]:(i=super.getLayerParameters(e,t,o),i.blend=!0),{...i,depthCompare:"always",blendAlphaSrcFactor:"constant"}}getShaderModuleProps(e,t,o){return{...super.getShaderModuleProps(e,t,o),terrain:{project:o.project}}}};var Gt=d(_(),1),Ut=2048,$=class{static isSupported(e){return e.isTextureFormatRenderable("rgba32float")}constructor(e){this.renderViewport=null,this.bounds=null,this.layers=[],this.layersBounds=[],this.layersBoundsCommon=null,this.lastViewport=null,this.device=e}getRenderFramebuffer(){return this.renderViewport?(this.fbo||(this.fbo=Y(this.device,{id:"height-map",float:!0})),this.fbo):null}shouldUpdate({layers:e,viewport:t}){let o=e.length!==this.layers.length||e.some((s,a)=>s!==this.layers[a]||s.props.transitions||s.getBounds()!==this.layersBounds[a]);o&&(this.layers=e,this.layersBounds=e.map(s=>s.getBounds()),this.layersBoundsCommon=T(e,ae(t)));let i=!this.lastViewport||!t.equals(this.lastViewport);if(!this.layersBoundsCommon)this.renderViewport=null;else if(o||i){let s=t instanceof Gt._GlobeViewport?this.layersBoundsCommon:A(this.layersBoundsCommon,t);if(s[2]<=s[0]||s[3]<=s[1])return this.renderViewport=null,!1;this.bounds=s,this.lastViewport=t;let a=t.scale,n=(s[2]-s[0])*a,l=(s[3]-s[1])*a,c=t.isGeospatial?H([t.longitude??0,t.latitude??0]):[t.center[0],t.center[1]];return this.renderViewport=n>0||l>0?O({bounds:[c[0]-1,c[1]-1,c[0]+1,c[1]+1],zoom:t.zoom,width:Math.min(n,Ut),height:Math.min(l,Ut),viewport:t}):null,!0}return!1}delete(){this.fbo&&(this.fbo.colorAttachments[0].delete(),this.fbo.delete())}};var fe=class{constructor(){this.id="terrain-effect",this.props=null,this.useInPicking=!0,this.isPicking=!1,this.isDrapingEnabled=!1,this.terrainCovers=new Map}setup({device:e,deck:t}){this.dummyHeightMap=e.createTexture({width:1,height:1,data:new Uint8Array([0,0,0,0])}),this.terrainPass=new le(e,{id:"terrain"}),this.terrainPickingPass=new ce(e,{id:"terrain-picking"}),$.isSupported(e)?this.heightMap=new $(e):Ht.log.warn("Terrain offset mode is not supported by this browser")(),t._addDefaultShaderModule(K)}preRender(e){if(e.pickZ){this.isDrapingEnabled=!1;return}let{viewports:t}=e,o=e.pass.startsWith("picking");this.isPicking=o,this.isDrapingEnabled=!0;let i=t[0],s=(o?this.terrainPickingPass:this.terrainPass).getRenderableLayers(i,e),a=s.filter(c=>c.props.operation.includes("terrain"));if(a.length===0)return;o||s.filter(p=>p.state.terrainDrawMode==="offset").length>0&&this._updateHeightMap(a,i,e);let n=s.filter(c=>c.state.terrainDrawMode==="drape"),l=e.effects?.filter(c=>c!==this);this._updateTerrainCovers(a,n,i,{...e,effects:l})}getShaderModuleProps(e,t){if(e.props.operation.includes("mask"))return{terrain:{dummyHeightMap:this.dummyHeightMap}};let{terrainDrawMode:o}=e.state,i=this.isDrapingEnabled?this.terrainCovers.get(e.id)??null:null;return this.isPicking&&e.props.operation.includes("terrain")&&(e.state._hasPickingCover=Boolean(i?.getPickingFramebuffer())),{terrain:{project:t.project,isPicking:this.isPicking,heightMap:this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture||null,heightMapBounds:this.heightMap?.bounds,dummyHeightMap:this.dummyHeightMap,terrainCover:i,useTerrainHeightMap:o==="offset",terrainSkipRender:o==="drape"||!e.props.operation.includes("draw")}}}cleanup({deck:e}){this.dummyHeightMap&&(this.dummyHeightMap.delete(),this.dummyHeightMap=void 0),this.heightMap&&(this.heightMap.delete(),this.heightMap=void 0);for(let t of this.terrainCovers.values())t.delete();this.terrainCovers.clear(),e._removeDefaultShaderModule(K)}_updateHeightMap(e,t,o){!this.heightMap||!this.heightMap.shouldUpdate({layers:e,viewport:t})||this.terrainPass.renderHeightMap(this.heightMap,{...o,layers:e,shaderModuleProps:{terrain:{heightMapBounds:this.heightMap.bounds,dummyHeightMap:this.dummyHeightMap,drawToTerrainHeightMap:!0},project:{devicePixelRatio:1}}})}_updateTerrainCovers(e,t,o,i){let s={};for(let a of t)a.state.terrainCoverNeedsRedraw&&(s[a.id]=!0,a.state.terrainCoverNeedsRedraw=!1);for(let a of this.terrainCovers.values())a.isDirty=a.isDirty||a.shouldUpdate({layerNeedsRedraw:s});for(let a of e)this._updateTerrainCover(a,t,o,i);this.isPicking||this._pruneTerrainCovers()}_updateTerrainCover(e,t,o,i){let s=this.isPicking?this.terrainPickingPass:this.terrainPass,a=this.terrainCovers.get(e.id);a||(a=new ne(e),this.terrainCovers.set(e.id,a));try{let n=a.shouldUpdate({targetLayer:e,viewport:o,layers:t});(this.isPicking||a.isDirty||n)&&(s.renderTerrainCover(a,{...i,layers:t,shaderModuleProps:{terrain:{dummyHeightMap:this.dummyHeightMap,terrainSkipRender:!1},project:{devicePixelRatio:1}}}),this.isPicking||(a.isDirty=!1))}catch(n){e.raiseError(n,`Error rendering terrain cover ${a.id}`)}}_pruneTerrainCovers(){let e=[];for(let[t,o]of this.terrainCovers)o.isActive||e.push(t);for(let t of e)this.terrainCovers.delete(t)}};var Ho={terrainDrawMode:void 0},Z=class extends qt.LayerExtension{getShaders(){return{modules:[K]}}initializeState(){this.context.deck?._addDefaultEffect(new fe)}updateState(e){let{props:t,oldProps:o}=e;if(this.state.terrainDrawMode&&t.terrainDrawMode===o.terrainDrawMode&&t.extruded===o.extruded)return;let{terrainDrawMode:i}=t;if(!i){let s=this.props.extruded,a=this.getAttributeManager()?.attributes,n=a&&"instancePositions"in a;i=s||n?"offset":"drape"}this.setState({terrainDrawMode:i})}onNeedsRedraw(){let e=this.state;e.terrainDrawMode==="drape"&&(e.terrainCoverNeedsRedraw=!0)}};Z.defaultProps=Ho;Z.extensionName="TerrainExtension";var Wt=Z;return Xt(J);})();
|
|
3133
|
+
`},getUniforms:(i={})=>{if(!i.dummyHeightMap)return{};if("terrainSkipRender"in i||"drawToTerrainHeightMap"in i){let{drawToTerrainHeightMap:e,heightMap:t,heightMapBounds:r,dummyHeightMap:n,terrainCover:o,useTerrainHeightMap:s,terrainSkipRender:a}=i,f=Fe.project.getUniforms(i.project),{commonOrigin:l}=f,c=a?v.SKIP:v.NONE,u=n,p=null;if(e)c=v.WRITE_HEIGHT_MAP,p=r;else if(s&&t)c=v.USE_HEIGHT_MAP,u=t,p=r;else if(o){let h=(i.isPicking?o.getPickingFramebuffer():o.getRenderFramebuffer())?.colorAttachments[0].texture;i.isPicking&&(c=v.SKIP),h?(u=h,c=c===v.SKIP?v.USE_COVER_ONLY:v.USE_COVER,p=o.bounds):i.isPicking&&!a&&(c=v.NONE)}return{mode:c,terrain_map:u,bounds:p?[p[0]-l[0],p[1]-l[1],p[2]-p[0],p[3]-p[1]]:[0,0,0,0]}}return{mode:v.NONE,terrain_map:i.dummyHeightMap,bounds:[0,0,0,0]}},uniformTypes:{mode:"f32",bounds:"vec4<f32>"}};var zt=d(_(),1);function Y(i,e){return i.createFramebuffer({id:e.id,colorAttachments:[i.createTexture({id:e.id,...e.float&&{format:"rgba32float",type:5126},dimension:"2d",width:1,height:1,sampler:e.interpolate===!1?{minFilter:"nearest",magFilter:"nearest"}:{minFilter:"linear",magFilter:"linear"}})]})}var ae=class{constructor(e){this.isDirty=!0,this.renderViewport=null,this.bounds=null,this.layers=[],this.targetBounds=null,this.targetBoundsCommon=null,this.targetLayer=e,this.tile=Vt(e)}get id(){return this.targetLayer.id}get isActive(){return!!this.targetLayer.getCurrentLayer()}shouldUpdate({targetLayer:e,viewport:t,layers:r,layerNeedsRedraw:n}){e&&(this.targetLayer=e);let o=t?this._updateViewport(t):!1,s=r?this._updateLayers(r):!1;if(n){for(let a of this.layers)if(n[a]){s=!0;break}}return s||o}_updateLayers(e){let t=!1;if(e=this.tile?Ur(this.tile,e):e,e.length!==this.layers.length)t=!0;else for(let r=0;r<e.length;r++)if(e[r].id!==this.layers[r]){t=!0;break}return t&&(this.layers=e.map(r=>r.id)),t}_updateViewport(e){let t=this.targetLayer,r=!1;if(this.tile&&"boundingBox"in this.tile){if(!this.targetBounds){r=!0,this.targetBounds=this.tile.boundingBox;let o=G(this.targetBounds[0]),s=G(this.targetBounds[1]);this.targetBoundsCommon=[o[0],o[1],s[0],s[1]]}}else this.targetBounds!==t.getBounds()&&(r=!0,this.targetBounds=t.getBounds(),this.targetBoundsCommon=A([t],se(e)));if(!this.targetBoundsCommon)return!1;let n=Math.ceil(e.zoom+.5);if(this.tile)this.bounds=this.targetBoundsCommon;else{let o=this.renderViewport?.zoom;r=r||n!==o;let s=e instanceof zt._GlobeViewport?this.targetBoundsCommon:T(this.targetBoundsCommon,e),a=this.bounds;r=r||!a||s.some((f,l)=>f!==a[l]),this.bounds=s}return r&&(this.renderViewport=S({bounds:this.bounds,zoom:n,viewport:e})),r}getRenderFramebuffer(){return!this.renderViewport||this.layers.length===0?null:(this.fbo||(this.fbo=Y(this.targetLayer.context.device,{id:this.id})),this.fbo)}getPickingFramebuffer(){return!this.renderViewport||this.layers.length===0&&!this.targetLayer.props.pickable?null:(this.pickingFbo||(this.pickingFbo=Y(this.targetLayer.context.device,{id:`${this.id}-picking`,interpolate:!1})),this.pickingFbo)}filterLayers(e){return e.filter(({id:t})=>this.layers.includes(t))}delete(){let{fbo:e,pickingFbo:t}=this;e&&(e.colorAttachments[0].destroy(),e.destroy()),t&&(t.colorAttachments[0].destroy(),t.destroy())}};function Ur(i,e){return e.filter(t=>{let r=Vt(t);return r?jr(i.boundingBox,r.boundingBox):!0})}function Vt(i){for(;i;){let{tile:e}=i.props;if(e)return e;i=i.parent}return null}function jr(i,e){return i&&e?i[0][0]<e[1][0]&&e[0][0]<i[1][0]&&i[0][1]<e[1][1]&&e[0][1]<i[1][1]:!1}var Ut=d(_(),1),Gr={blendColorOperation:"max",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"max",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one"},fe=class extends Ut._LayersPass{getRenderableLayers(e,t){let{layers:r}=t,n=[],o=this._getDrawLayerParams(e,t,!0);for(let s=0;s<r.length;s++){let a=r[s];!a.isComposite&&o[s].shouldDrawLayer&&n.push(a)}return n}renderHeightMap(e,t){let r=e.getRenderFramebuffer(),n=e.renderViewport;!r||!n||(r.resize(n),this.render({...t,target:r,pass:"terrain-height-map",layers:t.layers,viewports:[n],effects:[],clearColor:[0,0,0,0]}))}renderTerrainCover(e,t){let r=e.getRenderFramebuffer(),n=e.renderViewport;if(!r||!n)return;let o=e.filterLayers(t.layers);r.resize(n),this.render({...t,target:r,pass:`terrain-cover-${e.id}`,layers:o,viewports:[n],clearColor:[0,0,0,0]})}getLayerParameters(e,t,r){return{...e.props.parameters,blend:!0,depthCompare:"always",...e.props.operation.includes("terrain")&&Gr}}getShaderModuleProps(e,t,r){return{terrain:{project:r.project}}}};var jt=d(_(),1),le=class extends jt._PickLayersPass{constructor(){super(...arguments),this.drawParameters={}}getRenderableLayers(e,t){let{layers:r}=t,n=[];this.drawParameters={},this._resetColorEncoder(t.pickZ);let o=this._getDrawLayerParams(e,t);for(let s=0;s<r.length;s++){let a=r[s];!a.isComposite&&o[s].shouldDrawLayer&&(n.push(a),this.drawParameters[a.id]=o[s].layerParameters)}return n}renderTerrainCover(e,t){let r=e.getPickingFramebuffer(),n=e.renderViewport;if(!r||!n)return;let o=e.filterLayers(t.layers),s=e.targetLayer;s.props.pickable&&o.unshift(s),r.resize(n);let f=this.drawParameters[s.id]?.blendColor?.[3]??0;this.render({...t,pickingFBO:r,pass:`terrain-cover-picking-${e.id}`,layers:o,viewports:[n],cullRect:void 0,deviceRect:n,pickZ:!1,clearColor:[0,0,0,f]})}getLayerParameters(e,t,r){let n;return this.drawParameters[e.id]?n=this.drawParameters[e.id]:(n=super.getLayerParameters(e,t,r),n.blend=!0),{...n,depthCompare:"always",blendAlphaSrcFactor:"constant"}}getShaderModuleProps(e,t,r){return{...super.getShaderModuleProps(e,t,r),terrain:{project:r.project}}}};var Ht=d(_(),1),Gt=2048,K=class{static isSupported(e){return e.isTextureFormatRenderable("rgba32float")}constructor(e){this.renderViewport=null,this.bounds=null,this.layers=[],this.layersBounds=[],this.layersBoundsCommon=null,this.lastViewport=null,this.device=e}getRenderFramebuffer(){return this.renderViewport?(this.fbo||(this.fbo=Y(this.device,{id:"height-map",float:!0})),this.fbo):null}shouldUpdate({layers:e,viewport:t}){let r=e.length!==this.layers.length||e.some((o,s)=>o!==this.layers[s]||o.props.transitions||o.getBounds()!==this.layersBounds[s]);r&&(this.layers=e,this.layersBounds=e.map(o=>o.getBounds()),this.layersBoundsCommon=A(e,se(t)));let n=!this.lastViewport||!t.equals(this.lastViewport);if(!this.layersBoundsCommon)this.renderViewport=null;else if(r||n){let o=t instanceof Ht._GlobeViewport?this.layersBoundsCommon:T(this.layersBoundsCommon,t);if(o[2]<=o[0]||o[3]<=o[1])return this.renderViewport=null,!1;this.bounds=o,this.lastViewport=t;let s=t.scale,a=(o[2]-o[0])*s,f=(o[3]-o[1])*s,l=t.isGeospatial?G([t.longitude??0,t.latitude??0]):[t.center[0],t.center[1]];return this.renderViewport=a>0||f>0?S({bounds:[l[0]-1,l[1]-1,l[0]+1,l[1]+1],zoom:t.zoom,width:Math.min(a,Gt),height:Math.min(f,Gt),viewport:t}):null,!0}return!1}delete(){this.fbo&&(this.fbo.colorAttachments[0].delete(),this.fbo.delete())}};var ue=class{constructor(){this.id="terrain-effect",this.props=null,this.useInPicking=!0,this.isPicking=!1,this.isDrapingEnabled=!1,this.terrainCovers=new Map}setup({device:e,deck:t}){this.dummyHeightMap=e.createTexture({width:1,height:1,data:new Uint8Array([0,0,0,0])}),this.terrainPass=new fe(e,{id:"terrain"}),this.terrainPickingPass=new le(e,{id:"terrain-picking"}),K.isSupported(e)?this.heightMap=new K(e):qt.log.warn("Terrain offset mode is not supported by this browser")(),t._addDefaultShaderModule(W)}preRender(e){if(e.pickZ){this.isDrapingEnabled=!1;return}let{viewports:t}=e,r=e.pass.startsWith("picking");this.isPicking=r,this.isDrapingEnabled=!0;let n=t[0],o=(r?this.terrainPickingPass:this.terrainPass).getRenderableLayers(n,e),s=o.filter(l=>l.props.operation.includes("terrain"));if(s.length===0)return;r||o.filter(c=>c.state.terrainDrawMode==="offset").length>0&&this._updateHeightMap(s,n,e);let a=o.filter(l=>l.state.terrainDrawMode==="drape"),f=e.effects?.filter(l=>l!==this);this._updateTerrainCovers(s,a,n,{...e,effects:f})}getShaderModuleProps(e,t){if(e.props.operation.includes("mask"))return{terrain:{dummyHeightMap:this.dummyHeightMap}};let{terrainDrawMode:r}=e.state,n=this.isDrapingEnabled?this.terrainCovers.get(e.id)??null:null;return this.isPicking&&e.props.operation.includes("terrain")&&(e.state._hasPickingCover=!!n?.getPickingFramebuffer()),{terrain:{project:t.project,isPicking:this.isPicking,heightMap:this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture||null,heightMapBounds:this.heightMap?.bounds,dummyHeightMap:this.dummyHeightMap,terrainCover:n,useTerrainHeightMap:r==="offset",terrainSkipRender:r==="drape"||!e.props.operation.includes("draw")}}}cleanup({deck:e}){this.dummyHeightMap&&(this.dummyHeightMap.delete(),this.dummyHeightMap=void 0),this.heightMap&&(this.heightMap.delete(),this.heightMap=void 0);for(let t of this.terrainCovers.values())t.delete();this.terrainCovers.clear(),e._removeDefaultShaderModule(W)}_updateHeightMap(e,t,r){!this.heightMap||!this.heightMap.shouldUpdate({layers:e,viewport:t})||this.terrainPass.renderHeightMap(this.heightMap,{...r,layers:e,shaderModuleProps:{terrain:{heightMapBounds:this.heightMap.bounds,dummyHeightMap:this.dummyHeightMap,drawToTerrainHeightMap:!0},project:{devicePixelRatio:1}}})}_updateTerrainCovers(e,t,r,n){let o={};for(let s of t)s.state.terrainCoverNeedsRedraw&&(o[s.id]=!0,s.state.terrainCoverNeedsRedraw=!1);for(let s of this.terrainCovers.values())s.isDirty=s.isDirty||s.shouldUpdate({layerNeedsRedraw:o});for(let s of e)this._updateTerrainCover(s,t,r,n);this.isPicking||this._pruneTerrainCovers()}_updateTerrainCover(e,t,r,n){let o=this.isPicking?this.terrainPickingPass:this.terrainPass,s=this.terrainCovers.get(e.id);s||(s=new ae(e),this.terrainCovers.set(e.id,s));try{let a=s.shouldUpdate({targetLayer:e,viewport:r,layers:t});(this.isPicking||s.isDirty||a)&&(o.renderTerrainCover(s,{...n,layers:t,shaderModuleProps:{terrain:{dummyHeightMap:this.dummyHeightMap,terrainSkipRender:!1},project:{devicePixelRatio:1}}}),this.isPicking||(s.isDirty=!1))}catch(a){e.raiseError(a,`Error rendering terrain cover ${s.id}`)}}_pruneTerrainCovers(){let e=[];for(let[t,r]of this.terrainCovers)r.isActive||e.push(t);for(let t of e)this.terrainCovers.delete(t)}};var Hr={terrainDrawMode:void 0},Z=class extends Wt.LayerExtension{getShaders(){return{modules:[W]}}initializeState(){this.context.deck?._addDefaultEffect(new ue)}updateState(e){let{props:t,oldProps:r}=e;if(this.state.terrainDrawMode&&t.terrainDrawMode===r.terrainDrawMode&&t.extruded===r.extruded)return;let{terrainDrawMode:n}=t;if(!n){let o=this.props.extruded,s=this.getAttributeManager()?.attributes,a=s&&"instancePositions"in s;n=o||a?"offset":"drape"}this.setState({terrainDrawMode:n})}onNeedsRedraw(){let e=this.state;e.terrainDrawMode==="drape"&&(e.terrainCoverNeedsRedraw=!0)}};Z.defaultProps=Hr;Z.extensionName="TerrainExtension";var Yt=Z;return Xt($);})();
|
|
1991
3134
|
return __exports__;
|
|
1992
3135
|
});
|