From ef7b3608b0c465baa916de196c1c2721bc8aac55 Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Thu, 20 Feb 2020 00:03:00 +0800 Subject: [PATCH] =?UTF-8?q?improvement:=20=E4=BF=AE=E5=A4=8D=E6=8F=90?= =?UTF-8?q?=E9=AB=98=E6=8B=BE=E5=8F=96=E6=80=A7=E8=83=BD10=E5=80=8D+?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/interaction/PickingService.ts | 56 ++++++++++++++----- packages/layers/src/point/models/fill.ts | 2 +- .../layers/src/point/shaders/fill_vert.glsl | 2 +- stories/Layers/components/PointImage.tsx | 4 +- 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/packages/core/src/services/interaction/PickingService.ts b/packages/core/src/services/interaction/PickingService.ts index 551ad1ec0c..cc27a7eb6d 100644 --- a/packages/core/src/services/interaction/PickingService.ts +++ b/packages/core/src/services/interaction/PickingService.ts @@ -18,6 +18,7 @@ import { gl } from '../renderer/gl'; import { IFramebuffer } from '../renderer/IFramebuffer'; import { IPickingService } from './IPickingService'; +const PICKSCALE = 10.0; @injectable() export default class PickingService implements IPickingService { @inject(TYPES.IRendererService) @@ -64,23 +65,52 @@ export default class PickingService implements IPickingService { return; } this.alreadyInPicking = true; - const layers = this.layerService.getLayers(); - layers - .filter((layer) => layer.needPick()) - .reverse() - .forEach(async (layer) => { - await this.pickingLayer(layer, target); // 可以实现是否向下触发 - }); + await this.pickingLayers(target); this.layerService.renderLayers(); this.alreadyInPicking = false; } + private async pickingLayers(target: IInteractionTarget) { + const { getViewportSize, useFramebuffer, clear } = this.rendererService; + const { width, height } = getViewportSize(); + if (this.width !== width || this.height !== height) { + this.pickingFBO.resize({ + width: Math.round(width / PICKSCALE), + height: Math.round(height / PICKSCALE), + }); + this.width = width; + this.height = height; + } + + useFramebuffer(this.pickingFBO, () => { + const layers = this.layerService.getLayers(); + layers + .filter((layer) => layer.needPick()) + .reverse() + .forEach((layer) => { + clear({ + framebuffer: this.pickingFBO, + color: [0, 0, 0, 0], + stencil: 0, + depth: 1, + }); + + layer.hooks.beforePickingEncode.call(); + layer.renderModels(); + layer.hooks.afterPickingEncode.call(); + this.pickFromPickingFBO(layer, target); + }); + }); + } private async pickingLayer(layer: ILayer, target: IInteractionTarget) { const { getViewportSize, useFramebuffer, clear } = this.rendererService; const { width, height } = getViewportSize(); if (this.width !== width || this.height !== height) { - this.pickingFBO.resize({ width, height }); + this.pickingFBO.resize({ + width: Math.round(width / PICKSCALE), + height: Math.round(height / PICKSCALE), + }); this.width = width; this.height = height; } @@ -124,17 +154,15 @@ export default class PickingService implements IPickingService { return; } let pickedColors: Uint8Array | undefined; - pickedColors = readPixels({ - x: Math.round(xInDevicePixel), + x: Math.round(xInDevicePixel / PICKSCALE), // 视口坐标系原点在左上,而 WebGL 在左下,需要翻转 Y 轴 - y: Math.round(height - (y + 1) * window.devicePixelRatio), + y: Math.round((height - (y + 1) * window.devicePixelRatio) / PICKSCALE), width: 1, height: 1, data: new Uint8Array(1 * 1 * 4), framebuffer: this.pickingFBO, }); - if ( pickedColors[0] !== 0 || pickedColors[1] !== 0 || @@ -220,13 +248,13 @@ export default class PickingService implements IPickingService { ) { const [r, g, b] = pickedColors; layer.hooks.beforeHighlight.call([r, g, b]); - this.layerService.renderLayers(); + // this.layerService.renderLayers(); } private selectFeature(layer: ILayer, pickedColors: Uint8Array | undefined) { const [r, g, b] = pickedColors; layer.hooks.beforeSelect.call([r, g, b]); - this.layerService.renderLayers(); + // this.layerService.renderLayers(); } private selectFeatureHandle( diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index 33778bfb14..da221ea52c 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -87,7 +87,7 @@ export default class FillModel extends BaseModel { vertex: number[], attributeIdx: number, ) => { - const extrude = [-1, -1, 1, -1, 1, 1, -1, 1]; + const extrude = [1, 1, -1, 1, -1, -1, 1, -1]; const extrudeIndex = (attributeIdx % 4) * 2; return [extrude[extrudeIndex], extrude[extrudeIndex + 1]]; }, diff --git a/packages/layers/src/point/shaders/fill_vert.glsl b/packages/layers/src/point/shaders/fill_vert.glsl index cf0e996ea2..6482ae442c 100644 --- a/packages/layers/src/point/shaders/fill_vert.glsl +++ b/packages/layers/src/point/shaders/fill_vert.glsl @@ -24,7 +24,7 @@ void main() { // radius(16-bit) v_radius = a_Size; - vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width)); + vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width)) * -1.; vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0)); gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0)); diff --git a/stories/Layers/components/PointImage.tsx b/stories/Layers/components/PointImage.tsx index 4213f159ca..35c9222604 100644 --- a/stories/Layers/components/PointImage.tsx +++ b/stories/Layers/components/PointImage.tsx @@ -46,9 +46,9 @@ export default class PointImage extends React.Component { y: 'latitude', }, }) - .shape('circle') + .shape('triangle') .color('red') - .active(false) + .active(true) .size(20); scene.addLayer(imageLayer); i++;