@deck.gl/extensions 9.0.0-beta.2 → 9.0.0-beta.4

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.
Files changed (244) hide show
  1. package/dist/brushing/brushing-extension.js +80 -0
  2. package/{typed → dist}/brushing/shader-module.d.ts +1 -1
  3. package/{typed → dist}/brushing/shader-module.d.ts.map +1 -1
  4. package/dist/{esm/brushing → brushing}/shader-module.js +24 -30
  5. package/dist/clip/clip-extension.js +117 -0
  6. package/{typed → dist}/collision-filter/collision-filter-effect.d.ts.map +1 -1
  7. package/dist/collision-filter/collision-filter-effect.js +193 -0
  8. package/dist/collision-filter/collision-filter-extension.js +49 -0
  9. package/{typed → dist}/collision-filter/collision-filter-pass.d.ts.map +1 -1
  10. package/dist/collision-filter/collision-filter-pass.js +25 -0
  11. package/dist/{esm/collision-filter → collision-filter}/shader-module.js +17 -24
  12. package/dist/data-filter/aggregator.js +104 -0
  13. package/{typed → dist}/data-filter/data-filter-extension.d.ts +36 -5
  14. package/dist/data-filter/data-filter-extension.d.ts.map +1 -0
  15. package/dist/data-filter/data-filter-extension.js +243 -0
  16. package/{typed → dist}/data-filter/shader-module.d.ts +1 -1
  17. package/dist/data-filter/shader-module.d.ts.map +1 -0
  18. package/dist/data-filter/shader-module.js +187 -0
  19. package/dist/dist.dev.js +1847 -13033
  20. package/dist/fill-style/fill-style-extension.js +118 -0
  21. package/dist/{esm/fill-style → fill-style}/shaders.glsl.js +37 -43
  22. package/dist/fp64/fp64-extension.js +35 -0
  23. package/dist/{esm/fp64 → fp64}/project64.glsl.js +19 -1
  24. package/dist/fp64/project64.js +50 -0
  25. package/dist/index.cjs +2814 -0
  26. package/dist/index.cjs.map +7 -0
  27. package/dist/index.d.ts +19 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +11 -0
  30. package/{typed → dist}/mask/mask-effect.d.ts +1 -1
  31. package/dist/mask/mask-effect.d.ts.map +1 -0
  32. package/dist/mask/mask-effect.js +194 -0
  33. package/dist/mask/mask-extension.js +57 -0
  34. package/{typed → dist}/mask/mask-pass.d.ts.map +1 -1
  35. package/dist/mask/mask-pass.js +44 -0
  36. package/dist/{esm/mask → mask}/shader-module.js +18 -21
  37. package/dist/path-style/path-style-extension.js +111 -0
  38. package/dist/{esm/path-style → path-style}/shaders.glsl.js +20 -13
  39. package/{typed → dist}/terrain/height-map-builder.d.ts +1 -1
  40. package/dist/terrain/height-map-builder.d.ts.map +1 -0
  41. package/dist/terrain/height-map-builder.js +104 -0
  42. package/{typed → dist}/terrain/shader-module.d.ts +2 -2
  43. package/dist/terrain/shader-module.d.ts.map +1 -0
  44. package/dist/terrain/shader-module.js +139 -0
  45. package/{typed → dist}/terrain/terrain-cover.d.ts +1 -1
  46. package/dist/terrain/terrain-cover.d.ts.map +1 -0
  47. package/dist/terrain/terrain-cover.js +187 -0
  48. package/{typed → dist}/terrain/terrain-effect.d.ts +1 -1
  49. package/dist/terrain/terrain-effect.d.ts.map +1 -0
  50. package/dist/terrain/terrain-effect.js +184 -0
  51. package/dist/terrain/terrain-extension.js +44 -0
  52. package/{typed → dist}/terrain/terrain-pass.d.ts +2 -2
  53. package/dist/terrain/terrain-pass.d.ts.map +1 -0
  54. package/dist/terrain/terrain-pass.js +61 -0
  55. package/{typed → dist}/terrain/terrain-picking-pass.d.ts +1 -1
  56. package/dist/terrain/terrain-picking-pass.d.ts.map +1 -0
  57. package/dist/terrain/terrain-picking-pass.js +66 -0
  58. package/dist/terrain/utils.js +21 -0
  59. package/{typed → dist}/utils/debug.d.ts.map +1 -1
  60. package/dist/utils/debug.js +50 -0
  61. package/dist/utils/projection-utils.js +153 -0
  62. package/dist.min.js +104 -208
  63. package/package.json +19 -12
  64. package/src/collision-filter/collision-filter-effect.ts +12 -8
  65. package/src/collision-filter/collision-filter-pass.ts +1 -3
  66. package/src/data-filter/data-filter-extension.ts +136 -29
  67. package/src/data-filter/shader-module.ts +31 -3
  68. package/src/mask/mask-effect.ts +0 -1
  69. package/src/mask/mask-pass.ts +1 -3
  70. package/src/terrain/terrain-effect.ts +8 -2
  71. package/src/terrain/terrain-pass.ts +2 -5
  72. package/src/terrain/terrain-picking-pass.ts +1 -3
  73. package/src/utils/debug.ts +1 -2
  74. package/dist/es5/brushing/brushing-extension.js +0 -108
  75. package/dist/es5/brushing/brushing-extension.js.map +0 -1
  76. package/dist/es5/brushing/shader-module.js +0 -50
  77. package/dist/es5/brushing/shader-module.js.map +0 -1
  78. package/dist/es5/clip/clip-extension.js +0 -98
  79. package/dist/es5/clip/clip-extension.js.map +0 -1
  80. package/dist/es5/collision-filter/collision-filter-effect.js +0 -294
  81. package/dist/es5/collision-filter/collision-filter-effect.js.map +0 -1
  82. package/dist/es5/collision-filter/collision-filter-extension.js +0 -109
  83. package/dist/es5/collision-filter/collision-filter-extension.js.map +0 -1
  84. package/dist/es5/collision-filter/collision-filter-pass.js +0 -79
  85. package/dist/es5/collision-filter/collision-filter-pass.js.map +0 -1
  86. package/dist/es5/collision-filter/shader-module.js +0 -39
  87. package/dist/es5/collision-filter/shader-module.js.map +0 -1
  88. package/dist/es5/data-filter/aggregator.js +0 -79
  89. package/dist/es5/data-filter/aggregator.js.map +0 -1
  90. package/dist/es5/data-filter/data-filter-extension.js +0 -236
  91. package/dist/es5/data-filter/data-filter-extension.js.map +0 -1
  92. package/dist/es5/data-filter/shader-module.js +0 -122
  93. package/dist/es5/data-filter/shader-module.js.map +0 -1
  94. package/dist/es5/fill-style/fill-style-extension.js +0 -190
  95. package/dist/es5/fill-style/fill-style-extension.js.map +0 -1
  96. package/dist/es5/fill-style/shaders.glsl.js +0 -59
  97. package/dist/es5/fill-style/shaders.glsl.js.map +0 -1
  98. package/dist/es5/fp64/fp64-extension.js +0 -55
  99. package/dist/es5/fp64/fp64-extension.js.map +0 -1
  100. package/dist/es5/fp64/project64.glsl.js +0 -9
  101. package/dist/es5/fp64/project64.glsl.js.map +0 -1
  102. package/dist/es5/fp64/project64.js +0 -52
  103. package/dist/es5/fp64/project64.js.map +0 -1
  104. package/dist/es5/index.js +0 -88
  105. package/dist/es5/index.js.map +0 -1
  106. package/dist/es5/mask/mask-effect.js +0 -279
  107. package/dist/es5/mask/mask-effect.js.map +0 -1
  108. package/dist/es5/mask/mask-extension.js +0 -113
  109. package/dist/es5/mask/mask-extension.js.map +0 -1
  110. package/dist/es5/mask/mask-pass.js +0 -106
  111. package/dist/es5/mask/mask-pass.js.map +0 -1
  112. package/dist/es5/mask/shader-module.js +0 -38
  113. package/dist/es5/mask/shader-module.js.map +0 -1
  114. package/dist/es5/path-style/path-style-extension.js +0 -169
  115. package/dist/es5/path-style/path-style-extension.js.map +0 -1
  116. package/dist/es5/path-style/shaders.glsl.js +0 -25
  117. package/dist/es5/path-style/shaders.glsl.js.map +0 -1
  118. package/dist/es5/terrain/height-map-builder.js +0 -111
  119. package/dist/es5/terrain/height-map-builder.js.map +0 -1
  120. package/dist/es5/terrain/shader-module.js +0 -86
  121. package/dist/es5/terrain/shader-module.js.map +0 -1
  122. package/dist/es5/terrain/terrain-cover.js +0 -256
  123. package/dist/es5/terrain/terrain-cover.js.map +0 -1
  124. package/dist/es5/terrain/terrain-effect.js +0 -326
  125. package/dist/es5/terrain/terrain-effect.js.map +0 -1
  126. package/dist/es5/terrain/terrain-extension.js +0 -94
  127. package/dist/es5/terrain/terrain-extension.js.map +0 -1
  128. package/dist/es5/terrain/terrain-pass.js +0 -121
  129. package/dist/es5/terrain/terrain-pass.js.map +0 -1
  130. package/dist/es5/terrain/terrain-picking-pass.js +0 -124
  131. package/dist/es5/terrain/terrain-picking-pass.js.map +0 -1
  132. package/dist/es5/terrain/utils.js +0 -35
  133. package/dist/es5/terrain/utils.js.map +0 -1
  134. package/dist/es5/utils/debug.js +0 -71
  135. package/dist/es5/utils/debug.js.map +0 -1
  136. package/dist/es5/utils/projection-utils.js +0 -168
  137. package/dist/es5/utils/projection-utils.js.map +0 -1
  138. package/dist/esm/brushing/brushing-extension.js +0 -68
  139. package/dist/esm/brushing/brushing-extension.js.map +0 -1
  140. package/dist/esm/brushing/shader-module.js.map +0 -1
  141. package/dist/esm/clip/clip-extension.js +0 -86
  142. package/dist/esm/clip/clip-extension.js.map +0 -1
  143. package/dist/esm/collision-filter/collision-filter-effect.js +0 -246
  144. package/dist/esm/collision-filter/collision-filter-effect.js.map +0 -1
  145. package/dist/esm/collision-filter/collision-filter-extension.js +0 -75
  146. package/dist/esm/collision-filter/collision-filter-extension.js.map +0 -1
  147. package/dist/esm/collision-filter/collision-filter-pass.js +0 -32
  148. package/dist/esm/collision-filter/collision-filter-pass.js.map +0 -1
  149. package/dist/esm/collision-filter/shader-module.js.map +0 -1
  150. package/dist/esm/data-filter/aggregator.js +0 -102
  151. package/dist/esm/data-filter/aggregator.js.map +0 -1
  152. package/dist/esm/data-filter/data-filter-extension.js +0 -189
  153. package/dist/esm/data-filter/data-filter-extension.js.map +0 -1
  154. package/dist/esm/data-filter/shader-module.js +0 -164
  155. package/dist/esm/data-filter/shader-module.js.map +0 -1
  156. package/dist/esm/fill-style/fill-style-extension.js +0 -156
  157. package/dist/esm/fill-style/fill-style-extension.js.map +0 -1
  158. package/dist/esm/fill-style/shaders.glsl.js.map +0 -1
  159. package/dist/esm/fp64/fp64-extension.js +0 -20
  160. package/dist/esm/fp64/fp64-extension.js.map +0 -1
  161. package/dist/esm/fp64/project64.glsl.js.map +0 -1
  162. package/dist/esm/fp64/project64.js +0 -43
  163. package/dist/esm/fp64/project64.js.map +0 -1
  164. package/dist/esm/index.js +0 -11
  165. package/dist/esm/index.js.map +0 -1
  166. package/dist/esm/mask/mask-effect.js +0 -228
  167. package/dist/esm/mask/mask-effect.js.map +0 -1
  168. package/dist/esm/mask/mask-extension.js +0 -83
  169. package/dist/esm/mask/mask-extension.js.map +0 -1
  170. package/dist/esm/mask/mask-pass.js +0 -58
  171. package/dist/esm/mask/mask-pass.js.map +0 -1
  172. package/dist/esm/mask/shader-module.js.map +0 -1
  173. package/dist/esm/path-style/path-style-extension.js +0 -130
  174. package/dist/esm/path-style/path-style-extension.js.map +0 -1
  175. package/dist/esm/path-style/shaders.glsl.js.map +0 -1
  176. package/dist/esm/terrain/height-map-builder.js +0 -86
  177. package/dist/esm/terrain/height-map-builder.js.map +0 -1
  178. package/dist/esm/terrain/shader-module.js +0 -127
  179. package/dist/esm/terrain/shader-module.js.map +0 -1
  180. package/dist/esm/terrain/terrain-cover.js +0 -212
  181. package/dist/esm/terrain/terrain-cover.js.map +0 -1
  182. package/dist/esm/terrain/terrain-effect.js +0 -219
  183. package/dist/esm/terrain/terrain-effect.js.map +0 -1
  184. package/dist/esm/terrain/terrain-extension.js +0 -59
  185. package/dist/esm/terrain/terrain-extension.js.map +0 -1
  186. package/dist/esm/terrain/terrain-pass.js +0 -71
  187. package/dist/esm/terrain/terrain-pass.js.map +0 -1
  188. package/dist/esm/terrain/terrain-picking-pass.js +0 -73
  189. package/dist/esm/terrain/terrain-picking-pass.js.map +0 -1
  190. package/dist/esm/terrain/utils.js +0 -19
  191. package/dist/esm/terrain/utils.js.map +0 -1
  192. package/dist/esm/utils/debug.js +0 -61
  193. package/dist/esm/utils/debug.js.map +0 -1
  194. package/dist/esm/utils/projection-utils.js +0 -134
  195. package/dist/esm/utils/projection-utils.js.map +0 -1
  196. package/typed/data-filter/data-filter-extension.d.ts.map +0 -1
  197. package/typed/data-filter/shader-module.d.ts.map +0 -1
  198. package/typed/index.d.ts +0 -19
  199. package/typed/index.d.ts.map +0 -1
  200. package/typed/mask/mask-effect.d.ts.map +0 -1
  201. package/typed/terrain/height-map-builder.d.ts.map +0 -1
  202. package/typed/terrain/shader-module.d.ts.map +0 -1
  203. package/typed/terrain/terrain-cover.d.ts.map +0 -1
  204. package/typed/terrain/terrain-effect.d.ts.map +0 -1
  205. package/typed/terrain/terrain-pass.d.ts.map +0 -1
  206. package/typed/terrain/terrain-picking-pass.d.ts.map +0 -1
  207. /package/{typed → dist}/brushing/brushing-extension.d.ts +0 -0
  208. /package/{typed → dist}/brushing/brushing-extension.d.ts.map +0 -0
  209. /package/{typed → dist}/clip/clip-extension.d.ts +0 -0
  210. /package/{typed → dist}/clip/clip-extension.d.ts.map +0 -0
  211. /package/{typed → dist}/collision-filter/collision-filter-effect.d.ts +0 -0
  212. /package/{typed → dist}/collision-filter/collision-filter-extension.d.ts +0 -0
  213. /package/{typed → dist}/collision-filter/collision-filter-extension.d.ts.map +0 -0
  214. /package/{typed → dist}/collision-filter/collision-filter-pass.d.ts +0 -0
  215. /package/{typed → dist}/collision-filter/shader-module.d.ts +0 -0
  216. /package/{typed → dist}/collision-filter/shader-module.d.ts.map +0 -0
  217. /package/{typed → dist}/data-filter/aggregator.d.ts +0 -0
  218. /package/{typed → dist}/data-filter/aggregator.d.ts.map +0 -0
  219. /package/{typed → dist}/fill-style/fill-style-extension.d.ts +0 -0
  220. /package/{typed → dist}/fill-style/fill-style-extension.d.ts.map +0 -0
  221. /package/{typed → dist}/fill-style/shaders.glsl.d.ts +0 -0
  222. /package/{typed → dist}/fill-style/shaders.glsl.d.ts.map +0 -0
  223. /package/{typed → dist}/fp64/fp64-extension.d.ts +0 -0
  224. /package/{typed → dist}/fp64/fp64-extension.d.ts.map +0 -0
  225. /package/{typed → dist}/fp64/project64.d.ts +0 -0
  226. /package/{typed → dist}/fp64/project64.d.ts.map +0 -0
  227. /package/{typed → dist}/fp64/project64.glsl.d.ts +0 -0
  228. /package/{typed → dist}/fp64/project64.glsl.d.ts.map +0 -0
  229. /package/{typed → dist}/mask/mask-extension.d.ts +0 -0
  230. /package/{typed → dist}/mask/mask-extension.d.ts.map +0 -0
  231. /package/{typed → dist}/mask/mask-pass.d.ts +0 -0
  232. /package/{typed → dist}/mask/shader-module.d.ts +0 -0
  233. /package/{typed → dist}/mask/shader-module.d.ts.map +0 -0
  234. /package/{typed → dist}/path-style/path-style-extension.d.ts +0 -0
  235. /package/{typed → dist}/path-style/path-style-extension.d.ts.map +0 -0
  236. /package/{typed → dist}/path-style/shaders.glsl.d.ts +0 -0
  237. /package/{typed → dist}/path-style/shaders.glsl.d.ts.map +0 -0
  238. /package/{typed → dist}/terrain/terrain-extension.d.ts +0 -0
  239. /package/{typed → dist}/terrain/terrain-extension.d.ts.map +0 -0
  240. /package/{typed → dist}/terrain/utils.d.ts +0 -0
  241. /package/{typed → dist}/terrain/utils.d.ts.map +0 -0
  242. /package/{typed → dist}/utils/debug.d.ts +0 -0
  243. /package/{typed → dist}/utils/projection-utils.d.ts +0 -0
  244. /package/{typed → dist}/utils/projection-utils.d.ts.map +0 -0
package/package.json CHANGED
@@ -2,7 +2,8 @@
2
2
  "name": "@deck.gl/extensions",
3
3
  "description": "Plug-and-play functionalities for deck.gl layers",
4
4
  "license": "MIT",
5
- "version": "9.0.0-beta.2",
5
+ "type": "module",
6
+ "version": "9.0.0-beta.4",
6
7
  "publishConfig": {
7
8
  "access": "public"
8
9
  },
@@ -16,13 +17,19 @@
16
17
  "type": "git",
17
18
  "url": "https://github.com/visgl/deck.gl.git"
18
19
  },
19
- "main": "dist/es5/index.js",
20
- "module": "dist/esm/index.js",
21
- "types": "typed/index.d.ts",
20
+ "types": "dist/index.d.ts",
21
+ "main": "dist/index.cjs",
22
+ "module": "dist/index.js",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "require": "./dist/index.cjs"
28
+ }
29
+ },
22
30
  "files": [
23
31
  "dist",
24
32
  "src",
25
- "typed",
26
33
  "dist.min.js"
27
34
  ],
28
35
  "sideEffects": false,
@@ -32,17 +39,17 @@
32
39
  },
33
40
  "dependencies": {
34
41
  "@babel/runtime": "^7.0.0",
35
- "@luma.gl/shadertools": "9.0.0-beta.1"
42
+ "@luma.gl/shadertools": "9.0.0-beta.4"
36
43
  },
37
44
  "peerDependencies": {
38
45
  "@deck.gl/core": "^9.0.0-alpha",
39
- "@luma.gl/constants": "9.0.0-beta.1",
40
- "@luma.gl/core": "9.0.0-beta.1",
41
- "@luma.gl/engine": "9.0.0-beta.1",
42
- "@luma.gl/shadertools": "9.0.0-beta.1",
43
- "@luma.gl/webgl": "9.0.0-beta.1",
46
+ "@luma.gl/constants": "9.0.0-beta.4",
47
+ "@luma.gl/core": "9.0.0-beta.4",
48
+ "@luma.gl/engine": "9.0.0-beta.4",
49
+ "@luma.gl/shadertools": "9.0.0-beta.4",
50
+ "@luma.gl/webgl": "9.0.0-beta.4",
44
51
  "@math.gl/core": "^4.0.0",
45
52
  "@math.gl/web-mercator": "^4.0.0"
46
53
  },
47
- "gitHead": "ed132efaf84a75ea71c89dd8555b6ffc1fe839d5"
54
+ "gitHead": "7063cbec75a5fbcefc51f33f6e2488134533d34a"
48
55
  }
@@ -1,5 +1,4 @@
1
1
  import {Device, Framebuffer, Texture} from '@luma.gl/core';
2
- import {WEBGLRenderbuffer} from '@luma.gl/webgl';
3
2
  import {equals} from '@math.gl/core';
4
3
  import {_deepEqual as deepEqual} from '@deck.gl/core';
5
4
  import type {Effect, Layer, PreRenderOptions, Viewport} from '@deck.gl/core';
@@ -244,18 +243,23 @@ export default class CollisionFilterEffect implements Effect {
244
243
  }
245
244
  });
246
245
 
247
- const depthBuffer = new WEBGLRenderbuffer(
248
- // @ts-expect-error TODO v9 needs to be WebGLDevice
249
- device,
250
- {format: 'depth16unorm', width, height}
251
- );
246
+ // @ts-ignore
247
+ const depthStencilAttachment = device.createTexture({
248
+ format: 'depth16unorm',
249
+ width,
250
+ height,
251
+ mipmaps: false,
252
+
253
+ // TODO fix getWebGLTextureParameters() in luma to avoid passing deprecated parameters
254
+ dataFormat: 6402, // gl.DEPTH_COMPONENT
255
+ type: 5125 // gl.UNSIGNED_INT
256
+ });
252
257
  this.collisionFBOs[collisionGroup] = device.createFramebuffer({
253
258
  id: `collision-${collisionGroup}`,
254
259
  width,
255
260
  height,
256
261
  colorAttachments: [collisionMap],
257
- // @ts-expect-error TODO v9 doesn't handle renderbuffers well
258
- depthStencilAttachment: depthBuffer
262
+ depthStencilAttachment
259
263
  });
260
264
  }
261
265
 
@@ -1,5 +1,4 @@
1
1
  import {Framebuffer} from '@luma.gl/core';
2
- import {withGLParameters} from '@luma.gl/webgl';
3
2
  import {_LayersPass as LayersPass, LayersPassRenderOptions} from '@deck.gl/core';
4
3
 
5
4
  type CollisionFilterPassRenderOptions = LayersPassRenderOptions & {};
@@ -9,8 +8,7 @@ export default class CollisionFilterPass extends LayersPass {
9
8
  const padding = 1;
10
9
  const clearColor = [0, 0, 0, 0];
11
10
 
12
- return withGLParameters(
13
- this.device,
11
+ return this.device.withParametersWebGL(
14
12
  {
15
13
  scissorTest: true,
16
14
  scissor: [padding, padding, target.width - 2 * padding, target.height - 2 * padding],
@@ -18,32 +18,40 @@
18
18
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  // THE SOFTWARE.
20
20
 
21
- import {readPixelsToArray, clear, withGLParameters} from '@luma.gl/webgl';
22
21
  import {GL} from '@luma.gl/constants';
23
22
  import type {Framebuffer} from '@luma.gl/core';
24
23
  import type {Model} from '@luma.gl/engine';
25
24
  import type {Layer, LayerContext, Accessor, UpdateParameters} from '@deck.gl/core';
26
- import {LayerExtension} from '@deck.gl/core';
25
+ import {_deepEqual as deepEqual, LayerExtension, log} from '@deck.gl/core';
27
26
  import {shaderModule, shaderModule64} from './shader-module';
28
27
  import * as aggregator from './aggregator';
29
28
 
30
29
  const defaultProps = {
31
30
  getFilterValue: {type: 'accessor', value: 0},
31
+ getFilterCategory: {type: 'accessor', value: 0},
32
32
  onFilteredItemsChange: {type: 'function', value: null, optional: true},
33
33
 
34
34
  filterEnabled: true,
35
35
  filterRange: [-1, 1],
36
36
  filterSoftRange: null,
37
+ filterCategories: [0],
37
38
  filterTransformSize: true,
38
39
  filterTransformColor: true
39
40
  };
40
41
 
42
+ type FilterCategory = number | string;
43
+
41
44
  export type DataFilterExtensionProps<DataT = any> = {
42
45
  /**
43
46
  * Accessor to retrieve the value for each object that it will be filtered by.
44
47
  * Returns either a number (if `filterSize: 1`) or an array of numbers.
45
48
  */
46
49
  getFilterValue?: Accessor<DataT, number | number[]>;
50
+ /**
51
+ * Accessor to retrieve the category (`number | string`) for each object that it will be filtered by.
52
+ * Returns either a single category (if `filterSize: 1`) or an array of categories.
53
+ */
54
+ getFilterCategory?: Accessor<DataT, FilterCategory | FilterCategory[]>;
47
55
  /**
48
56
  * Enable/disable the data filter. If the data filter is disabled, all objects are rendered.
49
57
  * @default true
@@ -71,6 +79,11 @@ export type DataFilterExtensionProps<DataT = any> = {
71
79
  * @default true
72
80
  */
73
81
  filterTransformColor?: boolean;
82
+ /**
83
+ * The categories which define whether an object should be rendered.
84
+ * @default []
85
+ */
86
+ filterCategories: FilterCategory[] | FilterCategory[][];
74
87
  /**
75
88
  * Only called if the `countItems` option is enabled.
76
89
  */
@@ -83,21 +96,26 @@ export type DataFilterExtensionProps<DataT = any> = {
83
96
  };
84
97
 
85
98
  type DataFilterExtensionOptions = {
99
+ /**
100
+ * The size of the category filter (number of columns to filter by). The category filter can show/hide data based on 1-4 properties of each object.
101
+ * @default 1
102
+ */
103
+ categorySize?: 1 | 2 | 3 | 4;
86
104
  /**
87
105
  * The size of the filter (number of columns to filter by). The data filter can show/hide data based on 1-4 numeric properties of each object.
88
106
  * @default 1
89
107
  */
90
- filterSize: number;
108
+ filterSize?: 1 | 2 | 3 | 4;
91
109
  /**
92
110
  * Use 64-bit precision instead of 32-bit.
93
111
  * @default false
94
112
  */
95
- fp64: boolean;
113
+ fp64?: boolean;
96
114
  /**
97
115
  * If `true`, reports the number of filtered objects with the `onFilteredItemsChange` callback.
98
116
  * @default `false`.
99
117
  */
100
- countItems: boolean;
118
+ countItems?: boolean;
101
119
  };
102
120
 
103
121
  const DATA_TYPE_FROM_SIZE = {
@@ -112,25 +130,15 @@ export default class DataFilterExtension extends LayerExtension<DataFilterExtens
112
130
  static defaultProps = defaultProps;
113
131
  static extensionName = 'DataFilterExtension';
114
132
 
115
- constructor({
116
- filterSize = 1,
117
- fp64 = false,
118
- countItems = false
119
- }: Partial<DataFilterExtensionOptions> = {}) {
120
- if (!DATA_TYPE_FROM_SIZE[filterSize]) {
121
- throw new Error('filterSize out of range');
122
- }
123
-
124
- super({filterSize, fp64, countItems});
125
- }
126
-
127
133
  getShaders(this: Layer<DataFilterExtensionProps>, extension: this): any {
128
- const {filterSize, fp64} = extension.opts;
134
+ const {categorySize, filterSize, fp64} = extension.opts;
129
135
 
130
136
  return {
131
137
  modules: [fp64 ? shaderModule64 : shaderModule],
132
138
  defines: {
133
- DATAFILTER_TYPE: DATA_TYPE_FROM_SIZE[filterSize],
139
+ DATACATEGORY_TYPE: DATA_TYPE_FROM_SIZE[categorySize || 1],
140
+ DATACATEGORY_CHANNELS: categorySize,
141
+ DATAFILTER_TYPE: DATA_TYPE_FROM_SIZE[filterSize || 1],
134
142
  DATAFILTER_DOUBLE: Boolean(fp64)
135
143
  }
136
144
  };
@@ -138,11 +146,13 @@ export default class DataFilterExtension extends LayerExtension<DataFilterExtens
138
146
 
139
147
  initializeState(this: Layer<DataFilterExtensionProps>, context: LayerContext, extension: this) {
140
148
  const attributeManager = this.getAttributeManager();
149
+ const {categorySize, filterSize, fp64} = extension.opts;
150
+
141
151
  if (attributeManager) {
142
152
  attributeManager.add({
143
153
  filterValues: {
144
- size: extension.opts.filterSize,
145
- type: extension.opts.fp64 ? GL.DOUBLE : GL.FLOAT,
154
+ size: filterSize,
155
+ type: fp64 ? GL.DOUBLE : GL.FLOAT,
146
156
  accessor: 'getFilterValue',
147
157
  shaderAttributes: {
148
158
  filterValues: {
@@ -152,6 +162,23 @@ export default class DataFilterExtension extends LayerExtension<DataFilterExtens
152
162
  divisor: 1
153
163
  }
154
164
  }
165
+ },
166
+ filterCategoryValues: {
167
+ size: categorySize,
168
+ type: GL.FLOAT,
169
+ accessor: 'getFilterCategory',
170
+ transform:
171
+ categorySize === 1
172
+ ? d => extension._getCategoryKey.call(this, d, 0)
173
+ : d => d.map((x, i) => extension._getCategoryKey.call(this, x, i)),
174
+ shaderAttributes: {
175
+ filterCategoryValues: {
176
+ divisor: 0
177
+ },
178
+ instanceFilterCategoryValues: {
179
+ divisor: 1
180
+ }
181
+ }
155
182
  }
156
183
  });
157
184
  }
@@ -195,44 +222,74 @@ export default class DataFilterExtension extends LayerExtension<DataFilterExtens
195
222
 
196
223
  updateState(
197
224
  this: Layer<DataFilterExtensionProps>,
198
- {props, oldProps}: UpdateParameters<Layer<DataFilterExtensionProps>>
225
+ {props, oldProps, changeFlags}: UpdateParameters<Layer<DataFilterExtensionProps>>,
226
+ extension: this
199
227
  ) {
228
+ const attributeManager = this.getAttributeManager();
229
+ const {categorySize} = extension.opts;
200
230
  if (this.state.filterModel) {
201
- const attributeManager = this.getAttributeManager();
202
231
  const filterNeedsUpdate =
203
232
  // attributeManager must be defined for filterModel to be set
204
233
  attributeManager!.attributes.filterValues.needsUpdate() ||
234
+ attributeManager!.attributes.filterCategoryValues?.needsUpdate() ||
205
235
  props.filterEnabled !== oldProps.filterEnabled ||
206
236
  props.filterRange !== oldProps.filterRange ||
207
- props.filterSoftRange !== oldProps.filterSoftRange;
237
+ props.filterSoftRange !== oldProps.filterSoftRange ||
238
+ props.filterCategories !== oldProps.filterCategories;
208
239
  if (filterNeedsUpdate) {
209
240
  this.setState({filterNeedsUpdate});
210
241
  }
211
242
  }
243
+ if (attributeManager?.attributes.filterCategoryValues) {
244
+ // Update bitmask if accessor or selected categories has changed
245
+ const categoryBitMaskNeedsUpdate =
246
+ attributeManager.attributes.filterCategoryValues.needsUpdate() ||
247
+ !deepEqual(props.filterCategories, oldProps.filterCategories, 2);
248
+ if (categoryBitMaskNeedsUpdate) {
249
+ this.setState({categoryBitMaskNeedsUpdate});
250
+ }
251
+
252
+ // Need to recreate category map if categorySize has changed
253
+ const resetCategories = changeFlags.dataChanged;
254
+ if (resetCategories) {
255
+ this.setState({
256
+ categoryMap: Array(categorySize)
257
+ .fill(0)
258
+ .map(() => ({}))
259
+ });
260
+ attributeManager.attributes.filterCategoryValues.setNeedsUpdate('categoryMap');
261
+ }
262
+ }
212
263
  }
213
264
 
214
265
  draw(this: Layer<DataFilterExtensionProps>, params: any, extension: this) {
215
266
  const filterFBO = this.state.filterFBO as Framebuffer;
216
267
  const filterModel = this.state.filterModel as Model;
217
268
  const filterNeedsUpdate = this.state.filterNeedsUpdate as boolean;
269
+ const categoryBitMaskNeedsUpdate = this.state.categoryBitMaskNeedsUpdate as boolean;
218
270
 
219
271
  const {onFilteredItemsChange} = this.props;
272
+
273
+ if (categoryBitMaskNeedsUpdate) {
274
+ extension._updateCategoryBitMask.call(this, params, extension);
275
+ }
220
276
  if (filterNeedsUpdate && onFilteredItemsChange && filterModel) {
221
277
  const {
222
- attributes: {filterValues, filterIndices}
278
+ attributes: {filterValues, filterCategoryValues, filterIndices}
223
279
  } = this.getAttributeManager()!;
224
280
  filterModel.setVertexCount(this.getNumInstances());
225
281
 
226
- clear(this.context.device, {framebuffer: filterFBO, color: [0, 0, 0, 0]});
282
+ this.context.device.clearWebGL({framebuffer: filterFBO, color: [0, 0, 0, 0]});
227
283
 
228
284
  filterModel.updateModuleSettings(params.moduleParameters);
229
285
  // @ts-expect-error filterValue and filterIndices should always have buffer value
230
286
  filterModel.setAttributes({
231
287
  ...filterValues.getValue(),
288
+ ...filterCategoryValues?.getValue(),
232
289
  ...filterIndices?.getValue()
233
290
  });
234
- withGLParameters(
235
- filterModel.device,
291
+ filterModel.setUniforms(params.uniforms);
292
+ filterModel.device.withParametersWebGL(
236
293
  {
237
294
  framebuffer: filterFBO,
238
295
  // ts-ignore 'readonly' cannot be assigned to the mutable type '[GLBlendEquation, GLBlendEquation]'
@@ -243,7 +300,7 @@ export default class DataFilterExtension extends LayerExtension<DataFilterExtens
243
300
  filterModel.draw(this.context.renderPass);
244
301
  }
245
302
  );
246
- const color = readPixelsToArray(filterFBO);
303
+ const color = filterModel.device.readPixelsToArrayWebGL(filterFBO);
247
304
  let count = 0;
248
305
  for (let i = 0; i < color.length; i++) {
249
306
  count += color[i];
@@ -262,4 +319,54 @@ export default class DataFilterExtension extends LayerExtension<DataFilterExtens
262
319
  filterFBO?.destroy();
263
320
  filterModel?.destroy();
264
321
  }
322
+
323
+ /**
324
+ * Updates the bitmask used on the GPU to perform the filter based on the
325
+ * `filterCategories` prop. The mapping between categories and bit in the bitmask
326
+ * is performed by `_getCategoryKey()`
327
+ */
328
+ _updateCategoryBitMask(
329
+ this: Layer<DataFilterExtensionProps>,
330
+ params: any,
331
+ extension: this
332
+ ): void {
333
+ const {categorySize} = extension.opts;
334
+ const {filterCategories} = this.props;
335
+ const categoryBitMask = new Uint32Array([0, 0, 0, 0]);
336
+ const categoryFilters = (
337
+ categorySize === 1 ? [filterCategories] : filterCategories
338
+ ) as FilterCategory[][];
339
+ const maxCategories = categorySize === 1 ? 128 : categorySize === 2 ? 64 : 32;
340
+ for (let c = 0; c < categoryFilters.length; c++) {
341
+ const categoryFilter = categoryFilters[c];
342
+ for (const category of categoryFilter) {
343
+ const key = extension._getCategoryKey.call(this, category, c);
344
+ if (key < maxCategories) {
345
+ const channel = c * (maxCategories / 32) + Math.floor(key / 32);
346
+ categoryBitMask[channel] += Math.pow(2, key % 32); // 1 << key fails for key > 30
347
+ } else {
348
+ log.warn(`Exceeded maximum number of categories (${maxCategories})`)();
349
+ }
350
+ }
351
+ }
352
+ /* eslint-disable-next-line camelcase */
353
+ params.uniforms.filter_categoryBitMask = categoryBitMask;
354
+ this.state.categoryBitMaskNeedsUpdate = false;
355
+ }
356
+
357
+ /**
358
+ * Returns an index of bit in the bitmask for a given category. If the category has
359
+ * not yet been assigned a bit, a new one is assigned.
360
+ */
361
+ _getCategoryKey(
362
+ this: Layer<DataFilterExtensionProps>,
363
+ category: FilterCategory,
364
+ channel: number
365
+ ) {
366
+ const categoryMap = (this.state.categoryMap as Record<FilterCategory, number>[])[channel];
367
+ if (!(category in categoryMap)) {
368
+ categoryMap[category] = Object.keys(categoryMap).length;
369
+ }
370
+ return categoryMap[category];
371
+ }
265
372
  }
@@ -12,13 +12,16 @@ uniform DATAFILTER_TYPE filter_max;
12
12
  uniform bool filter_useSoftMargin;
13
13
  uniform bool filter_enabled;
14
14
  uniform bool filter_transformSize;
15
+ uniform ivec4 filter_categoryBitMask;
15
16
 
16
17
  #ifdef NON_INSTANCED_MODEL
17
18
  #define DATAFILTER_ATTRIB filterValues
18
19
  #define DATAFILTER_ATTRIB_64LOW filterValues64Low
20
+ #define DATACATEGORY_ATTRIB filterCategoryValues
19
21
  #else
20
22
  #define DATAFILTER_ATTRIB instanceFilterValues
21
23
  #define DATAFILTER_ATTRIB_64LOW instanceFilterValues64Low
24
+ #define DATACATEGORY_ATTRIB instanceFilterCategoryValues
22
25
  #endif
23
26
 
24
27
  in DATAFILTER_TYPE DATAFILTER_ATTRIB;
@@ -28,6 +31,7 @@ in DATAFILTER_TYPE DATAFILTER_ATTRIB;
28
31
  uniform DATAFILTER_TYPE filter_min64High;
29
32
  uniform DATAFILTER_TYPE filter_max64High;
30
33
  #endif
34
+ in DATACATEGORY_TYPE DATACATEGORY_ATTRIB;
31
35
 
32
36
  out float dataFilter_value;
33
37
 
@@ -43,7 +47,7 @@ float dataFilter_reduceValue(vec3 value) {
43
47
  float dataFilter_reduceValue(vec4 value) {
44
48
  return min(min(value.x, value.y), min(value.z, value.w));
45
49
  }
46
- void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax) {
50
+ void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax, DATACATEGORY_TYPE category) {
47
51
  if (filter_enabled) {
48
52
  if (filter_useSoftMargin) {
49
53
  dataFilter_value = dataFilter_reduceValue(
@@ -55,6 +59,29 @@ void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFrom
55
59
  step(filter_min, valueFromMin) * step(valueFromMax, filter_max)
56
60
  );
57
61
  }
62
+
63
+ #if DATACATEGORY_CHANNELS == 1 // One 128-bit mask
64
+ int dataFilter_masks = filter_categoryBitMask[int(category / 32.0)];
65
+ #elif DATACATEGORY_CHANNELS == 2 // Two 64-bit masks
66
+ ivec2 dataFilter_masks = ivec2(
67
+ filter_categoryBitMask[int(category.x / 32.0)],
68
+ filter_categoryBitMask[int(category.y / 32.0) + 2]
69
+ );
70
+ #elif DATACATEGORY_CHANNELS == 3 // Three 32-bit masks
71
+ ivec3 dataFilter_masks = filter_categoryBitMask.xyz;
72
+ #else // Four 32-bit masks
73
+ ivec4 dataFilter_masks = filter_categoryBitMask;
74
+ #endif
75
+
76
+ // Shift mask and extract relevant bits
77
+ DATACATEGORY_TYPE dataFilter_bits = DATACATEGORY_TYPE(dataFilter_masks) / pow(DATACATEGORY_TYPE(2.0), mod(category, 32.0));
78
+ dataFilter_bits = mod(floor(dataFilter_bits), 2.0);
79
+
80
+ #if DATACATEGORY_CHANNELS == 1
81
+ if(dataFilter_bits == 0.0) dataFilter_value = 0.0;
82
+ #else
83
+ if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0.0)))) dataFilter_value = 0.0;
84
+ #endif
58
85
  } else {
59
86
  dataFilter_value = 1.0;
60
87
  }
@@ -138,10 +165,11 @@ const inject = {
138
165
  #ifdef DATAFILTER_DOUBLE
139
166
  dataFilter_setValue(
140
167
  DATAFILTER_ATTRIB - filter_min64High + DATAFILTER_ATTRIB_64LOW,
141
- DATAFILTER_ATTRIB - filter_max64High + DATAFILTER_ATTRIB_64LOW
168
+ DATAFILTER_ATTRIB - filter_max64High + DATAFILTER_ATTRIB_64LOW,
169
+ DATACATEGORY_ATTRIB
142
170
  );
143
171
  #else
144
- dataFilter_setValue(DATAFILTER_ATTRIB, DATAFILTER_ATTRIB);
172
+ dataFilter_setValue(DATAFILTER_ATTRIB, DATAFILTER_ATTRIB, DATACATEGORY_ATTRIB);
145
173
  #endif
146
174
  `,
147
175
 
@@ -1,6 +1,5 @@
1
1
  import {Layer, Viewport, Effect, PreRenderOptions, CoordinateSystem, log} from '@deck.gl/core';
2
2
  import type {Device, Texture} from '@luma.gl/core';
3
- // import {readPixelsToArray} from '@luma.gl/webgl-legacy';
4
3
  import {equals} from '@math.gl/core';
5
4
  import MaskPass from './mask-pass';
6
5
  import {joinLayerBounds, getRenderBounds, makeViewport, Bounds} from '../utils/projection-utils';
@@ -1,5 +1,4 @@
1
1
  import type {Device, Framebuffer, Texture} from '@luma.gl/core';
2
- import {withGLParameters} from '@luma.gl/webgl';
3
2
  import {GL} from '@luma.gl/constants';
4
3
  import {_LayersPass as LayersPass, LayersPassRenderOptions} from '@deck.gl/core';
5
4
 
@@ -42,8 +41,7 @@ export default class MaskPass extends LayersPass {
42
41
  colorMask[options.channel] = true;
43
42
  const clearColor = [255, 255, 255, 255];
44
43
 
45
- return withGLParameters(
46
- this.device,
44
+ return this.device.withParametersWebGL(
47
45
  {
48
46
  blend: true,
49
47
  blendFunc: [GL.ZERO, GL.ONE],
@@ -65,7 +65,8 @@ export class TerrainEffect implements Effect {
65
65
  return;
66
66
  }
67
67
 
68
- const {viewports, isPicking = false} = opts;
68
+ const {viewports} = opts;
69
+ const isPicking = opts.pass.startsWith('picking');
69
70
  this.isPicking = isPicking;
70
71
  this.isDrapingEnabled = true;
71
72
 
@@ -201,7 +202,12 @@ export class TerrainEffect implements Effect {
201
202
  devicePixelRatio: 1
202
203
  }
203
204
  });
204
- terrainCover.isDirty = false;
205
+
206
+ if (!this.isPicking) {
207
+ // IsDirty refers to the normal fbo, not the picking fbo.
208
+ // Only mark it as not dirty if the normal fbo was updated.
209
+ terrainCover.isDirty = false;
210
+ }
205
211
  }
206
212
  } catch (err) {
207
213
  terrainLayer.raiseError(err as Error, `Error rendering terrain cover ${terrainCover.id}`);
@@ -1,4 +1,3 @@
1
- import {withGLParameters} from '@luma.gl/webgl';
2
1
  import {GL} from '@luma.gl/constants';
3
2
  import {Layer, Viewport, _LayersPass as LayersPass, LayersPassRenderOptions} from '@deck.gl/core';
4
3
  import type {HeightMapBuilder} from './height-map-builder';
@@ -33,8 +32,7 @@ export class TerrainPass extends LayersPass {
33
32
 
34
33
  target.resize(viewport);
35
34
 
36
- withGLParameters(
37
- this.device,
35
+ this.device.withParametersWebGL(
38
36
  {
39
37
  clearColor: [0, 0, 0, 0],
40
38
  blend: true,
@@ -66,8 +64,7 @@ export class TerrainPass extends LayersPass {
66
64
  const layers = terrainCover.filterLayers(opts.layers!);
67
65
  target.resize(viewport);
68
66
 
69
- withGLParameters(
70
- this.device,
67
+ this.device.withParametersWebGL(
71
68
  {
72
69
  clearColor: [0, 0, 0, 0],
73
70
  depthTest: false
@@ -4,7 +4,6 @@ import {
4
4
  LayersPassRenderOptions,
5
5
  _PickLayersPass as PickLayersPass
6
6
  } from '@deck.gl/core';
7
- import {withGLParameters} from '@luma.gl/webgl';
8
7
  import type {TerrainCover} from './terrain-cover';
9
8
 
10
9
  export type TerrainPickingPassRenderOptions = LayersPassRenderOptions & {
@@ -54,8 +53,7 @@ export class TerrainPickingPass extends PickLayersPass {
54
53
  }
55
54
  target.resize(viewport);
56
55
 
57
- withGLParameters(
58
- this.device,
56
+ this.device.withParametersWebGL(
59
57
  {
60
58
  depthTest: false
61
59
  },
@@ -1,7 +1,6 @@
1
1
  /* global document */
2
2
 
3
3
  import {Framebuffer} from '@luma.gl/core';
4
- import {readPixelsToArray} from '@luma.gl/webgl';
5
4
 
6
5
  /** Debug utility to draw FBO contents onto screen */
7
6
  // eslint-disable-next-line
@@ -9,7 +8,7 @@ export const debugFBO = function (
9
8
  fbo: Framebuffer,
10
9
  {minimap, opaque}: {minimap?: boolean; opaque?: boolean} = {}
11
10
  ) {
12
- const color = readPixelsToArray(fbo);
11
+ const color = fbo.device.readPixelsToArrayWebGL(fbo);
13
12
  let canvas = document.getElementById('fbo-canvas') as HTMLCanvasElement;
14
13
  const canvasHeight = (minimap ? 2 : 1) * fbo.height;
15
14
  if (!canvas) {