@deck.gl/extensions 8.9.8 → 8.9.10
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/dist.dev.js +19 -7
- package/dist/es5/terrain/height-map-builder.js +6 -0
- package/dist/es5/terrain/height-map-builder.js.map +1 -1
- package/dist/es5/terrain/shader-module.js +1 -1
- package/dist/es5/terrain/shader-module.js.map +1 -1
- package/dist/es5/terrain/terrain-cover.js +12 -8
- package/dist/es5/terrain/terrain-cover.js.map +1 -1
- package/dist/es5/utils/projection-utils.js +2 -0
- package/dist/es5/utils/projection-utils.js.map +1 -1
- package/dist/esm/terrain/height-map-builder.js +6 -0
- package/dist/esm/terrain/height-map-builder.js.map +1 -1
- package/dist/esm/terrain/shader-module.js +1 -1
- package/dist/esm/terrain/shader-module.js.map +1 -1
- package/dist/esm/terrain/terrain-cover.js +12 -8
- package/dist/esm/terrain/terrain-cover.js.map +1 -1
- package/dist/esm/utils/projection-utils.js +2 -0
- package/dist/esm/utils/projection-utils.js.map +1 -1
- package/dist.min.js +17 -16
- package/package.json +2 -2
- package/src/terrain/height-map-builder.ts +5 -0
- package/src/terrain/shader-module.ts +1 -0
- package/src/terrain/terrain-cover.ts +24 -19
- package/src/utils/projection-utils.ts +2 -0
- package/typed/brushing/brushing.js +83 -0
- package/typed/brushing/shader-module.js +116 -0
- package/typed/clip/clip.js +114 -0
- package/typed/collide/collide-effect.d.ts +1 -1
- package/typed/collide/collide-effect.d.ts.map +1 -1
- package/typed/collide/collide-pass.d.ts +0 -1
- package/typed/collide/collide-pass.d.ts.map +1 -1
- package/typed/collide/collide.d.ts +0 -1
- package/typed/collide/collide.d.ts.map +1 -1
- package/typed/collide/shader-module.d.ts.map +1 -1
- package/typed/data-filter/aggregator.js +98 -0
- package/typed/data-filter/data-filter.js +159 -0
- package/typed/data-filter/shader-module.js +152 -0
- package/typed/fill-style/fill-style.js +152 -0
- package/typed/fill-style/shaders.glsl.js +95 -0
- package/typed/fp64/fp64.js +34 -0
- package/typed/fp64/project64.glsl.js +100 -0
- package/typed/fp64/project64.js +50 -0
- package/typed/index.js +9 -0
- package/typed/mask/mask.js +48 -0
- package/typed/mask/shader-module.js +73 -0
- package/typed/path-style/path-style.js +107 -0
- package/typed/path-style/shaders.glsl.js +93 -0
- package/typed/terrain/height-map-builder.d.ts.map +1 -1
- package/typed/terrain/height-map.d.ts +27 -0
- package/typed/terrain/height-map.d.ts.map +1 -0
- package/typed/terrain/shader-module-offset.d.ts +4 -0
- package/typed/terrain/shader-module-offset.d.ts.map +1 -0
- package/typed/terrain/shader-module-source.d.ts +4 -0
- package/typed/terrain/shader-module-source.d.ts.map +1 -0
- package/typed/terrain/shader-module.d.ts.map +1 -1
- package/typed/terrain/terrain-cover.d.ts.map +1 -1
- package/typed/utils/projection-utils.d.ts.map +1 -1
- package/typed/effect-order.d.ts +0 -6
- package/typed/effect-order.d.ts.map +0 -1
|
@@ -60,6 +60,7 @@ commonPos = geometry.position.xyz;
|
|
|
60
60
|
if (terrain_mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
|
|
61
61
|
vec2 texCoords = (commonPos.xy - terrain_bounds.xy) / terrain_bounds.zw;
|
|
62
62
|
position = vec4(texCoords * 2.0 - 1.0, 0.0, 1.0);
|
|
63
|
+
commonPos.z += project_uCommonOrigin.z;
|
|
63
64
|
}
|
|
64
65
|
if (terrain_mode == TERRAIN_MODE_USE_HEIGHT_MAP) {
|
|
65
66
|
vec3 anchor = geometry.worldPosition;
|
|
@@ -5,11 +5,8 @@ import type {Layer, Viewport} from '@deck.gl/core';
|
|
|
5
5
|
import {createRenderTarget} from './utils';
|
|
6
6
|
import {joinLayerBounds, makeViewport, getRenderBounds, Bounds} from '../utils/projection-utils';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
type NonGeoBoundingBox = {left: number; top: number; right: number; bottom: number};
|
|
11
|
-
type Tile2DHeader = {
|
|
12
|
-
bbox: GeoBoundingBox | NonGeoBoundingBox;
|
|
8
|
+
type TileHeader = {
|
|
9
|
+
boundingBox: [min: number[], max: number[]];
|
|
13
10
|
};
|
|
14
11
|
|
|
15
12
|
/**
|
|
@@ -31,7 +28,7 @@ export class TerrainCover {
|
|
|
31
28
|
private fbo?: Framebuffer;
|
|
32
29
|
private pickingFbo?: Framebuffer;
|
|
33
30
|
private layers: string[] = [];
|
|
34
|
-
private tile:
|
|
31
|
+
private tile: TileHeader | null;
|
|
35
32
|
/** Cached version of targetLayer.getBounds() */
|
|
36
33
|
private targetBounds: [number[], number[]] | null = null;
|
|
37
34
|
/** targetBounds in cartesian space */
|
|
@@ -111,7 +108,21 @@ export class TerrainCover {
|
|
|
111
108
|
const targetLayer = this.targetLayer;
|
|
112
109
|
let shouldRedraw = false;
|
|
113
110
|
|
|
114
|
-
if (this.
|
|
111
|
+
if (this.tile && 'boundingBox' in this.tile) {
|
|
112
|
+
if (!this.targetBounds) {
|
|
113
|
+
shouldRedraw = true;
|
|
114
|
+
this.targetBounds = this.tile.boundingBox;
|
|
115
|
+
|
|
116
|
+
const bottomLeftCommon = viewport.projectPosition(this.targetBounds[0]);
|
|
117
|
+
const topRightCommon = viewport.projectPosition(this.targetBounds[1]);
|
|
118
|
+
this.targetBoundsCommon = [
|
|
119
|
+
bottomLeftCommon[0],
|
|
120
|
+
bottomLeftCommon[1],
|
|
121
|
+
topRightCommon[0],
|
|
122
|
+
topRightCommon[1]
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
} else if (this.targetBounds !== targetLayer.getBounds()) {
|
|
115
126
|
// console.log('bounds changed', this.bounds, '>>', newBounds);
|
|
116
127
|
shouldRedraw = true;
|
|
117
128
|
this.targetBounds = targetLayer.getBounds();
|
|
@@ -188,18 +199,18 @@ export class TerrainCover {
|
|
|
188
199
|
* Remove layers that do not overlap with the current terrain cover.
|
|
189
200
|
* This implementation only has effect when a TileLayer is overlaid on top of a TileLayer
|
|
190
201
|
*/
|
|
191
|
-
function getIntersectingLayers(sourceTile:
|
|
202
|
+
function getIntersectingLayers(sourceTile: TileHeader, layers: Layer[]): Layer[] {
|
|
192
203
|
return layers.filter(layer => {
|
|
193
204
|
const tile = getTile(layer);
|
|
194
205
|
if (tile) {
|
|
195
|
-
return intersect(sourceTile.
|
|
206
|
+
return intersect(sourceTile.boundingBox, tile.boundingBox);
|
|
196
207
|
}
|
|
197
208
|
return true;
|
|
198
209
|
});
|
|
199
210
|
}
|
|
200
211
|
|
|
201
212
|
/** If layer is the descendent of a TileLayer, return the corresponding tile. */
|
|
202
|
-
function getTile(layer: Layer):
|
|
213
|
+
function getTile(layer: Layer): TileHeader | null {
|
|
203
214
|
while (layer) {
|
|
204
215
|
// @ts-expect-error tile may not exist
|
|
205
216
|
const {tile} = layer.props;
|
|
@@ -211,15 +222,9 @@ function getTile(layer: Layer): Tile2DHeader | null {
|
|
|
211
222
|
return null;
|
|
212
223
|
}
|
|
213
224
|
|
|
214
|
-
function intersect(
|
|
215
|
-
b1
|
|
216
|
-
|
|
217
|
-
): boolean {
|
|
218
|
-
if ('west' in b1 && 'west' in b2) {
|
|
219
|
-
return b1.west < b2.east && b2.west < b1.east && b1.south < b2.north && b2.south < b1.north;
|
|
220
|
-
}
|
|
221
|
-
if ('left' in b1 && 'left' in b2) {
|
|
222
|
-
return b1.left < b2.right && b2.left < b1.right && b1.top < b2.bottom && b2.top < b1.bottom;
|
|
225
|
+
function intersect(b1?: [number[], number[]], b2?: [number[], number[]]): boolean {
|
|
226
|
+
if (b1 && b2) {
|
|
227
|
+
return b1[0][0] < b2[1][0] && b2[0][0] < b1[1][0] && b1[0][1] < b2[1][1] && b2[0][1] < b1[1][1];
|
|
223
228
|
}
|
|
224
229
|
return false;
|
|
225
230
|
}
|
|
@@ -90,6 +90,7 @@ export function makeViewport(opts: {
|
|
|
90
90
|
// Geospatial viewports may not be web-mercator
|
|
91
91
|
return isGeospatial
|
|
92
92
|
? new WebMercatorViewport({
|
|
93
|
+
id: viewport.id,
|
|
93
94
|
x: border,
|
|
94
95
|
y: border,
|
|
95
96
|
width,
|
|
@@ -100,6 +101,7 @@ export function makeViewport(opts: {
|
|
|
100
101
|
orthographic: true
|
|
101
102
|
})
|
|
102
103
|
: new OrthographicViewport({
|
|
104
|
+
id: viewport.id,
|
|
103
105
|
x: border,
|
|
104
106
|
y: border,
|
|
105
107
|
width,
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
// in the Software without restriction, including without limitation the rights
|
|
6
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
// furnished to do so, subject to the following conditions:
|
|
9
|
+
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in
|
|
11
|
+
// all copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
// THE SOFTWARE.
|
|
20
|
+
import { LayerExtension } from '@deck.gl/core';
|
|
21
|
+
import shaderModule from './shader-module';
|
|
22
|
+
const defaultProps = {
|
|
23
|
+
getBrushingTarget: { type: 'accessor', value: [0, 0] },
|
|
24
|
+
brushingTarget: 'source',
|
|
25
|
+
brushingEnabled: true,
|
|
26
|
+
brushingRadius: 10000
|
|
27
|
+
};
|
|
28
|
+
export default class BrushingExtension extends LayerExtension {
|
|
29
|
+
getShaders(extension) {
|
|
30
|
+
return {
|
|
31
|
+
modules: [shaderModule]
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
initializeState(context, extension) {
|
|
35
|
+
const attributeManager = this.getAttributeManager();
|
|
36
|
+
if (attributeManager) {
|
|
37
|
+
attributeManager.add({
|
|
38
|
+
brushingTargets: {
|
|
39
|
+
size: 2,
|
|
40
|
+
accessor: 'getBrushingTarget',
|
|
41
|
+
// Hack: extension's defaultProps is not merged with the layer's defaultProps,
|
|
42
|
+
// So we can't use the standard accessor when the prop is undefined
|
|
43
|
+
update: !this.props.getBrushingTarget && extension.useConstantTargetPositions,
|
|
44
|
+
shaderAttributes: {
|
|
45
|
+
brushingTargets: {
|
|
46
|
+
divisor: 0
|
|
47
|
+
},
|
|
48
|
+
instanceBrushingTargets: {
|
|
49
|
+
divisor: 1
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Trigger redraw when mouse moves
|
|
56
|
+
// TODO - expose this in a better way
|
|
57
|
+
extension.onMouseMove = () => {
|
|
58
|
+
this.getCurrentLayer().setNeedsRedraw();
|
|
59
|
+
};
|
|
60
|
+
if (this.context.deck) {
|
|
61
|
+
this.context.deck.eventManager.on({
|
|
62
|
+
pointermove: extension.onMouseMove,
|
|
63
|
+
pointerleave: extension.onMouseMove
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
finalizeState(extension) {
|
|
68
|
+
// Remove event listeners
|
|
69
|
+
if (this.context.deck) {
|
|
70
|
+
this.context.deck.eventManager.off({
|
|
71
|
+
pointermove: extension.onMouseMove,
|
|
72
|
+
pointerleave: extension.onMouseMove
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
useConstantTargetPositions(attribute) {
|
|
77
|
+
attribute.constant = true;
|
|
78
|
+
attribute.value = new Float32Array(2);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
BrushingExtension.extensionName = 'BrushingExtension';
|
|
83
|
+
BrushingExtension.defaultProps = defaultProps;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Copyright (c) 2015-2017 Uber Technologies, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
// in the Software without restriction, including without limitation the rights
|
|
6
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
// furnished to do so, subject to the following conditions:
|
|
9
|
+
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in
|
|
11
|
+
// all copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
// THE SOFTWARE.
|
|
20
|
+
import { project } from '@deck.gl/core';
|
|
21
|
+
const vs = `
|
|
22
|
+
uniform bool brushing_enabled;
|
|
23
|
+
uniform int brushing_target;
|
|
24
|
+
uniform vec2 brushing_mousePos;
|
|
25
|
+
uniform float brushing_radius;
|
|
26
|
+
|
|
27
|
+
#ifdef NON_INSTANCED_MODEL
|
|
28
|
+
attribute vec2 brushingTargets;
|
|
29
|
+
#else
|
|
30
|
+
attribute vec2 instanceBrushingTargets;
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
varying float brushing_isVisible;
|
|
34
|
+
|
|
35
|
+
bool brushing_isPointInRange(vec2 position) {
|
|
36
|
+
if (!brushing_enabled) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
vec2 source_commonspace = project_position(position);
|
|
40
|
+
vec2 target_commonspace = project_position(brushing_mousePos);
|
|
41
|
+
float distance = length((target_commonspace - source_commonspace) / project_uCommonUnitsPerMeter.xy);
|
|
42
|
+
|
|
43
|
+
return distance <= brushing_radius;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
bool brushing_arePointsInRange(vec2 sourcePos, vec2 targetPos) {
|
|
47
|
+
return brushing_isPointInRange(sourcePos) || brushing_isPointInRange(targetPos);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void brushing_setVisible(bool visible) {
|
|
51
|
+
brushing_isVisible = float(visible);
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
const fs = `
|
|
55
|
+
uniform bool brushing_enabled;
|
|
56
|
+
varying float brushing_isVisible;
|
|
57
|
+
`;
|
|
58
|
+
const TARGET = {
|
|
59
|
+
source: 0,
|
|
60
|
+
target: 1,
|
|
61
|
+
custom: 2,
|
|
62
|
+
source_target: 3
|
|
63
|
+
};
|
|
64
|
+
const inject = {
|
|
65
|
+
'vs:DECKGL_FILTER_GL_POSITION': `
|
|
66
|
+
vec2 brushingTarget;
|
|
67
|
+
vec2 brushingSource;
|
|
68
|
+
if (brushing_target == 3) {
|
|
69
|
+
brushingTarget = geometry.worldPositionAlt.xy;
|
|
70
|
+
brushingSource = geometry.worldPosition.xy;
|
|
71
|
+
} else if (brushing_target == 0) {
|
|
72
|
+
brushingTarget = geometry.worldPosition.xy;
|
|
73
|
+
} else if (brushing_target == 1) {
|
|
74
|
+
brushingTarget = geometry.worldPositionAlt.xy;
|
|
75
|
+
} else {
|
|
76
|
+
#ifdef NON_INSTANCED_MODEL
|
|
77
|
+
brushingTarget = brushingTargets;
|
|
78
|
+
#else
|
|
79
|
+
brushingTarget = instanceBrushingTargets;
|
|
80
|
+
#endif
|
|
81
|
+
}
|
|
82
|
+
bool visible;
|
|
83
|
+
if (brushing_target == 3) {
|
|
84
|
+
visible = brushing_arePointsInRange(brushingSource, brushingTarget);
|
|
85
|
+
} else {
|
|
86
|
+
visible = brushing_isPointInRange(brushingTarget);
|
|
87
|
+
}
|
|
88
|
+
brushing_setVisible(visible);
|
|
89
|
+
`,
|
|
90
|
+
'fs:DECKGL_FILTER_COLOR': `
|
|
91
|
+
if (brushing_enabled && brushing_isVisible < 0.5) {
|
|
92
|
+
discard;
|
|
93
|
+
}
|
|
94
|
+
`
|
|
95
|
+
};
|
|
96
|
+
export default {
|
|
97
|
+
name: 'brushing',
|
|
98
|
+
dependencies: [project],
|
|
99
|
+
vs,
|
|
100
|
+
fs,
|
|
101
|
+
inject,
|
|
102
|
+
getUniforms: opts => {
|
|
103
|
+
if (!opts || !opts.viewport) {
|
|
104
|
+
return {};
|
|
105
|
+
}
|
|
106
|
+
const { brushingEnabled = true, brushingRadius = 10000, brushingTarget = 'source', mousePosition, viewport } = opts;
|
|
107
|
+
return {
|
|
108
|
+
brushing_enabled: Boolean(brushingEnabled && mousePosition && viewport.containsPixel(mousePosition)),
|
|
109
|
+
brushing_radius: brushingRadius,
|
|
110
|
+
brushing_target: TARGET[brushingTarget] || 0,
|
|
111
|
+
brushing_mousePos: mousePosition
|
|
112
|
+
? viewport.unproject([mousePosition.x - viewport.x, mousePosition.y - viewport.y])
|
|
113
|
+
: [0, 0]
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
// in the Software without restriction, including without limitation the rights
|
|
6
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
// furnished to do so, subject to the following conditions:
|
|
9
|
+
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in
|
|
11
|
+
// all copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
// THE SOFTWARE.
|
|
20
|
+
import { LayerExtension } from '@deck.gl/core';
|
|
21
|
+
const defaultProps = {
|
|
22
|
+
clipBounds: [0, 0, 1, 1]
|
|
23
|
+
};
|
|
24
|
+
const shaderFunction = `
|
|
25
|
+
uniform vec4 clip_bounds;
|
|
26
|
+
|
|
27
|
+
bool clip_isInBounds(vec2 position) {
|
|
28
|
+
return position.x >= clip_bounds[0] && position.y >= clip_bounds[1] && position.x < clip_bounds[2] && position.y < clip_bounds[3];
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
/*
|
|
32
|
+
* The vertex-shader version clips geometries by their anchor position
|
|
33
|
+
* e.g. ScatterplotLayer - show if the center of a circle is within bounds
|
|
34
|
+
*/
|
|
35
|
+
const shaderModuleVs = {
|
|
36
|
+
name: 'clip-vs',
|
|
37
|
+
vs: shaderFunction
|
|
38
|
+
};
|
|
39
|
+
const injectionVs = {
|
|
40
|
+
'vs:#decl': `
|
|
41
|
+
varying float clip_isVisible;
|
|
42
|
+
`,
|
|
43
|
+
'vs:DECKGL_FILTER_GL_POSITION': `
|
|
44
|
+
clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
|
|
45
|
+
`,
|
|
46
|
+
'fs:#decl': `
|
|
47
|
+
varying float clip_isVisible;
|
|
48
|
+
`,
|
|
49
|
+
'fs:DECKGL_FILTER_COLOR': `
|
|
50
|
+
if (clip_isVisible < 0.5) discard;
|
|
51
|
+
`
|
|
52
|
+
};
|
|
53
|
+
/*
|
|
54
|
+
* The fragment-shader version clips pixels at the bounds
|
|
55
|
+
* e.g. PolygonLayer - show the part of the polygon that intersect with the bounds
|
|
56
|
+
*/
|
|
57
|
+
const shaderModuleFs = {
|
|
58
|
+
name: 'clip-fs',
|
|
59
|
+
fs: shaderFunction
|
|
60
|
+
};
|
|
61
|
+
const injectionFs = {
|
|
62
|
+
'vs:#decl': `
|
|
63
|
+
varying vec2 clip_commonPosition;
|
|
64
|
+
`,
|
|
65
|
+
'vs:DECKGL_FILTER_GL_POSITION': `
|
|
66
|
+
clip_commonPosition = geometry.position.xy;
|
|
67
|
+
`,
|
|
68
|
+
'fs:#decl': `
|
|
69
|
+
varying vec2 clip_commonPosition;
|
|
70
|
+
`,
|
|
71
|
+
'fs:DECKGL_FILTER_COLOR': `
|
|
72
|
+
if (!clip_isInBounds(clip_commonPosition)) discard;
|
|
73
|
+
`
|
|
74
|
+
};
|
|
75
|
+
export default class ClipExtension extends LayerExtension {
|
|
76
|
+
getShaders() {
|
|
77
|
+
// If `clipByInstance: true`, the entire object is shown/hidden based on its anchor position (done by vertex shader)
|
|
78
|
+
// Otherwise, the object is trimmed by the clip bounds (done by fragment shader)
|
|
79
|
+
// Default behavior: consider a layer instanced if it has attribute `instancePositions`
|
|
80
|
+
let clipByInstance = 'instancePositions' in this.getAttributeManager().attributes;
|
|
81
|
+
// Users can override by setting the `clipByInstance` prop
|
|
82
|
+
if ('clipByInstance' in this.props) {
|
|
83
|
+
clipByInstance = this.props.clipByInstance;
|
|
84
|
+
}
|
|
85
|
+
this.state.clipByInstance = clipByInstance;
|
|
86
|
+
return clipByInstance
|
|
87
|
+
? {
|
|
88
|
+
modules: [shaderModuleVs],
|
|
89
|
+
inject: injectionVs
|
|
90
|
+
}
|
|
91
|
+
: {
|
|
92
|
+
modules: [shaderModuleFs],
|
|
93
|
+
inject: injectionFs
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
draw({ uniforms }) {
|
|
97
|
+
const { clipBounds = defaultProps.clipBounds } = this.props;
|
|
98
|
+
if (this.state.clipByInstance) {
|
|
99
|
+
uniforms.clip_bounds = clipBounds;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const corner0 = this.projectPosition([clipBounds[0], clipBounds[1], 0]);
|
|
103
|
+
const corner1 = this.projectPosition([clipBounds[2], clipBounds[3], 0]);
|
|
104
|
+
uniforms.clip_bounds = [
|
|
105
|
+
Math.min(corner0[0], corner1[0]),
|
|
106
|
+
Math.min(corner0[1], corner1[1]),
|
|
107
|
+
Math.max(corner0[0], corner1[0]),
|
|
108
|
+
Math.max(corner0[1], corner1[1])
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
ClipExtension.extensionName = 'ClipExtension';
|
|
114
|
+
ClipExtension.defaultProps = defaultProps;
|
|
@@ -10,7 +10,7 @@ export default class CollideEffect implements Effect {
|
|
|
10
10
|
private collideFBOs;
|
|
11
11
|
private dummyCollideMap?;
|
|
12
12
|
private lastViewport?;
|
|
13
|
-
preRender(gl: WebGLRenderingContext, { effects: allEffects, layers, layerFilter, viewports, onViewportActive, views,
|
|
13
|
+
preRender(gl: WebGLRenderingContext, { effects: allEffects, layers, layerFilter, viewports, onViewportActive, views, isPicking, preRenderStats }: PreRenderOptions): void;
|
|
14
14
|
private _render;
|
|
15
15
|
/**
|
|
16
16
|
* Group layers by collideGroup
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collide-effect.d.ts","sourceRoot":"","sources":["../../src/collide/collide-effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAgB,SAAS,EAAmB,MAAM,eAAe,CAAC;AAGrF,OAAO,KAAK,EAAC,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAW,MAAM,eAAe,CAAC;AAoB7E,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,MAAM;IAClD,EAAE,SAAoB;IACtB,KAAK,OAAQ;IACb,YAAY,UAAQ;IACpB,KAAK,SAAK;IAEV,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,eAAe,CAAC,CAAY;IACpC,OAAO,CAAC,YAAY,CAAC,CAAW;IAEhC,SAAS,CACP,EAAE,EAAE,qBAAqB,EACzB,EACE,OAAO,EAAE,UAAU,EACnB,MAAM,EACN,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,
|
|
1
|
+
{"version":3,"file":"collide-effect.d.ts","sourceRoot":"","sources":["../../src/collide/collide-effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAgB,SAAS,EAAmB,MAAM,eAAe,CAAC;AAGrF,OAAO,KAAK,EAAC,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAW,MAAM,eAAe,CAAC;AAoB7E,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,MAAM;IAClD,EAAE,SAAoB;IACtB,KAAK,OAAQ;IACb,YAAY,UAAQ;IACpB,KAAK,SAAK;IAEV,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,eAAe,CAAC,CAAY;IACpC,OAAO,CAAC,YAAY,CAAC,CAAW;IAEhC,SAAS,CACP,EAAE,EAAE,qBAAqB,EACzB,EACE,OAAO,EAAE,UAAU,EACnB,MAAM,EACN,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,cAAmB,EACpB,EAAE,gBAAgB,GAClB,IAAI;IAuDP,OAAO,CAAC,OAAO;IA0Df;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAsC5B,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG;QACjC,UAAU,EAAE,WAAW,CAAC;QACxB,eAAe,EAAE,SAAS,CAAC;KAC5B;IAMD,OAAO,IAAI,IAAI;IAaf,SAAS,CAAC,EAAE,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM;IAyBzD,UAAU,CAAC,YAAY,EAAE,MAAM;CAQhC"}
|
|
@@ -3,7 +3,6 @@ import { _LayersPass as LayersPass, LayersPassRenderOptions } from '@deck.gl/cor
|
|
|
3
3
|
declare type CollidePassRenderOptions = LayersPassRenderOptions & {};
|
|
4
4
|
export default class CollidePass extends LayersPass {
|
|
5
5
|
renderCollideMap(target: Framebuffer, options: CollidePassRenderOptions): any;
|
|
6
|
-
shouldDrawLayer(layer: any): any;
|
|
7
6
|
getModuleParameters(): {
|
|
8
7
|
drawToCollideMap: boolean;
|
|
9
8
|
pickingActive: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collide-pass.d.ts","sourceRoot":"","sources":["../../src/collide/collide-pass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAiB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAC,WAAW,IAAI,UAAU,EAAE,uBAAuB,EAAC,MAAM,eAAe,CAAC;AAEjF,aAAK,wBAAwB,GAAG,uBAAuB,GAAG,EAAE,CAAC;AAE7D,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,UAAU;IACjD,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"collide-pass.d.ts","sourceRoot":"","sources":["../../src/collide/collide-pass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAiB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAC,WAAW,IAAI,UAAU,EAAE,uBAAuB,EAAC,MAAM,eAAe,CAAC;AAEjF,aAAK,wBAAwB,GAAG,uBAAuB,GAAG,EAAE,CAAC;AAE7D,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,UAAU;IACjD,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,wBAAwB;IAmBvE,mBAAmB;;;;;;CASpB"}
|
|
@@ -33,7 +33,6 @@ export default class CollideExtension extends LayerExtension {
|
|
|
33
33
|
collideTestProps: {};
|
|
34
34
|
};
|
|
35
35
|
static extensionName: string;
|
|
36
|
-
isEnabled(layer: Layer<CollideExtensionProps>): boolean;
|
|
37
36
|
getShaders(this: Layer<CollideExtensionProps>): any;
|
|
38
37
|
draw(this: Layer<CollideExtensionProps>, { uniforms, context, moduleParameters }: any): void;
|
|
39
38
|
initializeState(this: Layer<CollideExtensionProps>, context: LayerContext, extension: this): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collide.d.ts","sourceRoot":"","sources":["../../src/collide/collide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,cAAc,EAAC,MAAM,eAAe,CAAC;AAW5E,oBAAY,qBAAqB,CAAC,KAAK,GAAG,GAAG,IAAI;IAC/C;;OAEG;IACH,kBAAkB,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE7C;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,CAAC;CACvB,CAAC;AAEF,iDAAiD;AACjD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc;IAC1D,MAAM,CAAC,YAAY;;;;;;;;;;;MAAgB;IACnC,MAAM,CAAC,aAAa,SAAsB;IAE1C,
|
|
1
|
+
{"version":3,"file":"collide.d.ts","sourceRoot":"","sources":["../../src/collide/collide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,cAAc,EAAC,MAAM,eAAe,CAAC;AAW5E,oBAAY,qBAAqB,CAAC,KAAK,GAAG,GAAG,IAAI;IAC/C;;OAEG;IACH,kBAAkB,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE7C;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,CAAC,EAAE,EAAE,CAAC;CACvB,CAAC;AAEF,iDAAiD;AACjD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc;IAC1D,MAAM,CAAC,YAAY;;;;;;;;;;;MAAgB;IACnC,MAAM,CAAC,aAAa,SAAsB;IAE1C,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,GAAG;IAKnD,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,EAAC,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAC,EAAE,GAAG;IAanF,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,qBAAqB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI;IAkB1F,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,OAAO;CAGnE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-module.d.ts","sourceRoot":"","sources":["../../src/collide/shader-module.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,aAAa,IAAI,YAAY,EAAC,MAAM,eAAe,CAAC;;
|
|
1
|
+
{"version":3,"file":"shader-module.d.ts","sourceRoot":"","sources":["../../src/collide/shader-module.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,aAAa,IAAI,YAAY,EAAC,MAAM,eAAe,CAAC;;AAwGjE,wBAMkB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Model, Texture2D, Framebuffer, isWebGL2 } from '@luma.gl/core';
|
|
2
|
+
import GL from '@luma.gl/constants';
|
|
3
|
+
const AGGREGATE_VS = `\
|
|
4
|
+
#define SHADER_NAME data-filter-vertex-shader
|
|
5
|
+
|
|
6
|
+
#ifdef FLOAT_TARGET
|
|
7
|
+
attribute float filterIndices;
|
|
8
|
+
attribute float filterPrevIndices;
|
|
9
|
+
#else
|
|
10
|
+
attribute vec2 filterIndices;
|
|
11
|
+
attribute vec2 filterPrevIndices;
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
varying vec4 vColor;
|
|
15
|
+
const float component = 1.0 / 255.0;
|
|
16
|
+
|
|
17
|
+
void main() {
|
|
18
|
+
#ifdef FLOAT_TARGET
|
|
19
|
+
dataFilter_value *= float(filterIndices != filterPrevIndices);
|
|
20
|
+
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
|
|
21
|
+
vColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
22
|
+
#else
|
|
23
|
+
// Float texture is not supported: pack result into 4 channels x 256 px x 64px
|
|
24
|
+
dataFilter_value *= float(filterIndices.x != filterPrevIndices.x);
|
|
25
|
+
float col = filterIndices.x;
|
|
26
|
+
float row = filterIndices.y * 4.0;
|
|
27
|
+
float channel = floor(row);
|
|
28
|
+
row = fract(row);
|
|
29
|
+
vColor = component * vec4(bvec4(channel == 0.0, channel == 1.0, channel == 2.0, channel == 3.0));
|
|
30
|
+
gl_Position = vec4(col * 2.0 - 1.0, row * 2.0 - 1.0, 0.0, 1.0);
|
|
31
|
+
#endif
|
|
32
|
+
gl_PointSize = 1.0;
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
const AGGREGATE_FS = `\
|
|
36
|
+
#define SHADER_NAME data-filter-fragment-shader
|
|
37
|
+
precision highp float;
|
|
38
|
+
|
|
39
|
+
varying vec4 vColor;
|
|
40
|
+
|
|
41
|
+
void main() {
|
|
42
|
+
if (dataFilter_value < 0.5) {
|
|
43
|
+
discard;
|
|
44
|
+
}
|
|
45
|
+
gl_FragColor = vColor;
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
export function supportsFloatTarget(gl) {
|
|
49
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#Support_for_float_textures_doesnt_mean_you_can_render_into_them!
|
|
50
|
+
return (gl.getExtension('EXT_float_blend') &&
|
|
51
|
+
// WebGL 2
|
|
52
|
+
(gl.getExtension('EXT_color_buffer_float') ||
|
|
53
|
+
// WebGL 1
|
|
54
|
+
gl.getExtension('WEBGL_color_buffer_float')));
|
|
55
|
+
}
|
|
56
|
+
// A 1x1 framebuffer object that encodes the total count of filtered items
|
|
57
|
+
export function getFramebuffer(gl, useFloatTarget) {
|
|
58
|
+
if (useFloatTarget) {
|
|
59
|
+
return new Framebuffer(gl, {
|
|
60
|
+
width: 1,
|
|
61
|
+
height: 1,
|
|
62
|
+
attachments: {
|
|
63
|
+
[GL.COLOR_ATTACHMENT0]: new Texture2D(gl, {
|
|
64
|
+
format: isWebGL2(gl) ? GL.RGBA32F : GL.RGBA,
|
|
65
|
+
type: GL.FLOAT,
|
|
66
|
+
mipmaps: false
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return new Framebuffer(gl, {
|
|
72
|
+
width: 256,
|
|
73
|
+
height: 64,
|
|
74
|
+
depth: false
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Increments the counter based on dataFilter_value
|
|
78
|
+
export function getModel(gl, shaderOptions, useFloatTarget) {
|
|
79
|
+
shaderOptions.defines.NON_INSTANCED_MODEL = 1;
|
|
80
|
+
if (useFloatTarget) {
|
|
81
|
+
shaderOptions.defines.FLOAT_TARGET = 1;
|
|
82
|
+
}
|
|
83
|
+
return new Model(gl, {
|
|
84
|
+
id: 'data-filter-aggregation-model',
|
|
85
|
+
vertexCount: 1,
|
|
86
|
+
isInstanced: false,
|
|
87
|
+
drawMode: GL.POINTS,
|
|
88
|
+
vs: AGGREGATE_VS,
|
|
89
|
+
fs: AGGREGATE_FS,
|
|
90
|
+
...shaderOptions
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export const parameters = {
|
|
94
|
+
blend: true,
|
|
95
|
+
blendFunc: [GL.ONE, GL.ONE, GL.ONE, GL.ONE],
|
|
96
|
+
blendEquation: [GL.FUNC_ADD, GL.FUNC_ADD],
|
|
97
|
+
depthTest: false
|
|
98
|
+
};
|