From 64fda5ffc4fa5077896247aeecd6412afc105488 Mon Sep 17 00:00:00 2001 From: Manfred Cheung Date: Thu, 17 Aug 2023 16:36:00 -0400 Subject: [PATCH 1/2] Add picking on CurvedPath edge type (#98) --- .../edges/path/CurvedPath.picking.fs.glsl | 10 ++++++ src/graph/edges/path/CurvedPath.ts | 34 +++++++++++++++++-- src/graph/edges/path/CurvedPath.vs.glsl | 8 ++++- 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/graph/edges/path/CurvedPath.picking.fs.glsl diff --git a/src/graph/edges/path/CurvedPath.picking.fs.glsl b/src/graph/edges/path/CurvedPath.picking.fs.glsl new file mode 100644 index 0000000..d21d74f --- /dev/null +++ b/src/graph/edges/path/CurvedPath.picking.fs.glsl @@ -0,0 +1,10 @@ +#version 300 es +precision highp float; + +flat in vec4 fPickingColor; + +out vec4 fragColor; + +void main() { + fragColor = fPickingColor; +} diff --git a/src/graph/edges/path/CurvedPath.ts b/src/graph/edges/path/CurvedPath.ts index 68f8d6b..e7975dd 100755 --- a/src/graph/edges/path/CurvedPath.ts +++ b/src/graph/edges/path/CurvedPath.ts @@ -1,5 +1,6 @@ import edgeVS from './CurvedPath.vs.glsl'; import edgeFS from './CurvedPath.fs.glsl'; +import pickingFS from './CurvedPath.picking.fs.glsl'; import dataVS from './CurvedPath.data.vs.glsl'; import {App, DrawCall, PicoGL, Program, VertexArray, VertexBuffer} from 'picogl'; @@ -14,7 +15,8 @@ import { } from '../../../renderer/Renderable'; import {Edges} from '../Edges'; import {GraphPoints} from '../../../data/GraphPoints'; -import {PickingManager} from '../../../UX/picking/PickingManager'; +import {PickingColors, PickingEvent, PickingManager} from '../../../UX/picking/PickingManager'; +import {MouseCallback} from '../../../UX/mouse/MouseHandler'; import {GraferContext} from '../../../renderer/GraferContext'; export interface CurvedPathEdgeData { @@ -57,6 +59,12 @@ export class CurvedPath extends Edges protected program: Program; protected drawCall: DrawCall; + protected pickingProgram: Program; + protected pickingDrawCall: DrawCall; + protected pickingColors: PickingColors; + protected pickingVBO: VertexBuffer; + protected pickingHandler: MouseCallback; + protected verticesVBO: VertexBuffer; protected edgesVAO: VertexArray; @@ -90,13 +98,23 @@ export class CurvedPath extends Edges } this.verticesVBO = context.createVertexBuffer(PicoGL.FLOAT, 2, new Float32Array(segmentVertices)); + + this.pickingHandler = this.handlePickingEvent.bind(this); + this.pickingColors = this.pickingManager.allocatePickingColors(data.length); + this.pickingVBO = context.createVertexBuffer(PicoGL.UNSIGNED_BYTE, 4, this.pickingColors.colors); + this.edgesVAO = context.createVertexArray().vertexAttributeBuffer(0, this.verticesVBO); this.configureTargetVAO(this.edgesVAO); + this.edgesVAO.instanceAttributeBuffer(7, this.pickingVBO); const shaders = this.getDrawShaders(); this.program = context.createProgram(shaders.vs, shaders.fs); this.drawCall = context.createDrawCall(this.program, this.edgesVAO).primitive(PicoGL.TRIANGLE_STRIP); + const pickingShaders = this.getPickingShaders(); + this.pickingProgram = context.createProgram(pickingShaders.vs, pickingShaders.fs); + this.pickingDrawCall = context.createDrawCall(this.pickingProgram, this.edgesVAO).primitive(PicoGL.TRIANGLE_STRIP); + this.compute(context, { uGraphPoints: this.dataTexture, }); @@ -118,7 +136,10 @@ export class CurvedPath extends Edges switch (mode) { case RenderMode.PICKING: - // this.pickingDrawCall.draw(); + setDrawCallUniforms(this.pickingDrawCall, uniforms); + setDrawCallUniforms(this.pickingDrawCall, this.localUniforms); + this.pickingDrawCall.uniform('uPicking', true); + this.pickingDrawCall.draw(); break; default: @@ -137,7 +158,7 @@ export class CurvedPath extends Edges protected getPickingShaders(): RenderableShaders { return { vs: edgeVS, - fs: null, // pickingFS, + fs: pickingFS, }; } @@ -180,4 +201,11 @@ export class CurvedPath extends Edges return edgesMappings; } + + protected handlePickingEvent(event: PickingEvent, colorID: number): void { + if (this.picking && this.pickingColors.map.has(colorID)) { + const id = this.idArray[this.pickingColors.map.get(colorID)]; + this.emit(event, id); + } + } } diff --git a/src/graph/edges/path/CurvedPath.vs.glsl b/src/graph/edges/path/CurvedPath.vs.glsl index fc1e181..e6a39fb 100755 --- a/src/graph/edges/path/CurvedPath.vs.glsl +++ b/src/graph/edges/path/CurvedPath.vs.glsl @@ -7,6 +7,9 @@ layout(location=3) in vec3 iControl; layout(location=4) in uint iColorA; layout(location=5) in uint iColorB; layout(location=6) in vec2 iColorMix; +layout(location=7) in uvec4 iPickingColor; + +uniform bool uPicking; uniform mat4 uViewMatrix; uniform mat4 uSceneMatrix; @@ -19,6 +22,7 @@ uniform float uLineWidth; uniform float uSegments; flat out float fLineWidth; +flat out vec4 fPickingColor; out vec3 vColor; out vec2 vProjectedPosition; out float vProjectedW; @@ -35,6 +39,8 @@ vec3 bezier(vec3 p0, vec3 p1, vec3 p2, float t) { } void main() { + fPickingColor = uPicking ? vec4(iPickingColor) / 255.0 : vec4(0.0); + // bezier works fine with 0 > t > 1 float t0 = aVertex.y / uSegments; float t1 = (aVertex.y + 1.0) / uSegments; @@ -57,7 +63,7 @@ void main() { vec2 normal = vec2(-direction.y, direction.x); // calculate the pixel offset - fLineWidth = uLineWidth * uPixelRatio; + fLineWidth = (uPicking ? uLineWidth * 8. : uLineWidth) * uPixelRatio; float offsetWidth = fLineWidth + 0.5; vec4 offset = vec4(((aVertex.x * normal * offsetWidth) / uViewportSize) * b0Projected.w, 0.0, 0.0); From f4d858a265e7e588f2171a828191918988326d05 Mon Sep 17 00:00:00 2001 From: Manfred Cheung Date: Mon, 21 Aug 2023 10:32:03 -0400 Subject: [PATCH 2/2] Add option for edge picking width (#99) --- docs/api/grafer-edges-data.md | 3 ++- src/graph/edges/Edges.ts | 8 ++++++++ src/graph/edges/path/CurvedPath.vs.glsl | 3 ++- src/graph/edges/straight/Straight.vs.glsl | 3 ++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/api/grafer-edges-data.md b/docs/api/grafer-edges-data.md index 5c51bb5..20ab597 100644 --- a/docs/api/grafer-edges-data.md +++ b/docs/api/grafer-edges-data.md @@ -52,4 +52,5 @@ An object containing configuration options for the edges. | brightness | number | Takes a range between -1 to 1. Defaults to 0. | | nearDepth | number | Takes a range between 0 to 1. Defaults to 0. Controls camera near depth. | | farDepth | number | Takes a range between 0 to 1. Defaults to 1. Controls camera far depth. | -| lineWidth | number | Sets the line width of the edges in the layer | +| lineWidth | number | Sets the line width of the edges in the layer. Defaults to 1.5. | +| pickingWidth | number | Sets the width of the edge picking area in the layer where applicable, as a multiplier of the `lineWidth`. Defaults to 8. | diff --git a/src/graph/edges/Edges.ts b/src/graph/edges/Edges.ts index 5fee6d1..ea00f05 100755 --- a/src/graph/edges/Edges.ts +++ b/src/graph/edges/Edges.ts @@ -44,11 +44,19 @@ export abstract class Edges extends LayerRen this.localUniforms.uLineWidth = value; } + public get pickingWidth(): number { + return this.localUniforms.uPickingWidth as number; + } + public set pickingWidth(value: number) { + this.localUniforms.uPickingWidth = value; + } + protected initialize(...args: any[]): void { super.initialize(...args); this.localUniforms = Object.assign({}, this.localUniforms, { uGraphPoints: this.dataTexture, uLineWidth: 1.5, + uPickingWidth: 8, }); } diff --git a/src/graph/edges/path/CurvedPath.vs.glsl b/src/graph/edges/path/CurvedPath.vs.glsl index e6a39fb..ef5f269 100755 --- a/src/graph/edges/path/CurvedPath.vs.glsl +++ b/src/graph/edges/path/CurvedPath.vs.glsl @@ -16,6 +16,7 @@ uniform mat4 uSceneMatrix; uniform mat4 uProjectionMatrix; uniform vec2 uViewportSize; uniform float uPixelRatio; +uniform float uPickingWidth; uniform sampler2D uColorPalette; uniform float uLineWidth; @@ -63,7 +64,7 @@ void main() { vec2 normal = vec2(-direction.y, direction.x); // calculate the pixel offset - fLineWidth = (uPicking ? uLineWidth * 8. : uLineWidth) * uPixelRatio; + fLineWidth = (uPicking ? uLineWidth * uPickingWidth : uLineWidth) * uPixelRatio; float offsetWidth = fLineWidth + 0.5; vec4 offset = vec4(((aVertex.x * normal * offsetWidth) / uViewportSize) * b0Projected.w, 0.0, 0.0); diff --git a/src/graph/edges/straight/Straight.vs.glsl b/src/graph/edges/straight/Straight.vs.glsl index f5430d2..ef6252a 100755 --- a/src/graph/edges/straight/Straight.vs.glsl +++ b/src/graph/edges/straight/Straight.vs.glsl @@ -14,6 +14,7 @@ uniform mat4 uSceneMatrix; uniform mat4 uProjectionMatrix; uniform vec2 uViewportSize; uniform float uPixelRatio; +uniform float uPickingWidth; uniform sampler2D uGraphPoints; uniform sampler2D uColorPalette; @@ -57,7 +58,7 @@ void main() { vec2 screenDirection = normalize(bScreen - aScreen); vec2 perp = vec2(-screenDirection.y, screenDirection.x); - fLineWidth = (uPicking ? uLineWidth * 8. : uLineWidth) * uPixelRatio; + fLineWidth = (uPicking ? uLineWidth * uPickingWidth : uLineWidth) * uPixelRatio; float offsetWidth = fLineWidth + 0.5; vec4 position = aProjected * multA + bProjected * multB; vec4 offset = vec4(((aVertex.x * perp * offsetWidth) / uViewportSize) * position.w, 0.0, 0.0);