From 4601ad19bd6fa60fc82168d7f9bdf0bcbb3c4d22 Mon Sep 17 00:00:00 2001 From: Manfred Cheung Date: Wed, 16 Aug 2023 13:29:22 -0400 Subject: [PATCH] Add picking on CurvedPath edge type --- .../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);