From 87d7b619bfb54ec0f95daeea96cc86e8c1b0e416 Mon Sep 17 00:00:00 2001 From: Mathias Paulin Date: Thu, 16 Dec 2021 15:16:02 +0100 Subject: [PATCH] temporary fix (because it's an hack) of issue #837 --- Shaders/Picking/PickingPoints.geom.glsl | 62 +++++++++++++++++++++---- src/Engine/Rendering/Renderer.cpp | 12 ++++- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/Shaders/Picking/PickingPoints.geom.glsl b/Shaders/Picking/PickingPoints.geom.glsl index f1aede72765..ba2081ffe36 100644 --- a/Shaders/Picking/PickingPoints.geom.glsl +++ b/Shaders/Picking/PickingPoints.geom.glsl @@ -1,8 +1,5 @@ #include "TransformStructs.glsl" -layout( points ) in; -layout( points, max_vertices = 1 ) out; - in gl_PerVertex { vec4 gl_Position; float gl_PointSize; @@ -16,11 +13,16 @@ out gl_PerVertex { float gl_ClipDistance[]; }; +layout( points ) in; +layout( triangle_strip, max_vertices = 4 ) out; + layout( location = 0 ) in vec3 in_position[]; layout( location = 1 ) in vec3 in_normal[]; layout( location = 2 ) in vec3 in_eye[]; uniform Transform transform; +// 0.01 : default value, but will be set when rendering point cloud for picking +uniform float pointCloudSplatRadius = 0.01; layout( location = 0 ) out vec3 out_position; layout( location = 1 ) out vec3 out_normal; @@ -29,12 +31,52 @@ layout( location = 3 ) flat out int out_eltID; layout( location = 4 ) out vec3 out_eltCoords; void main() { - gl_Position = transform.proj * transform.view * vec4( in_position[0], 1 ); - out_position = in_position[0]; - out_normal = in_normal[0]; - out_eye = in_eye[0]; - out_eltID = gl_PrimitiveIDIn; - out_eltCoords = vec3( 1, 0, 0 ); - EmitVertex(); + vec3 eye = -transform.view[3].xyz * mat3( transform.view ); + + // if no normal is provided, splats are aligned with the screen plane + vec3 normal = in_normal[0]; + if ( length( normal ) < 0.1 ) { normal = normalize( eye - in_position[0] ); } + + // orthonormal basis {u, v, normal} + vec3 u = vec3( 1, 0, 0 ); + if ( abs( normal.x ) > 1e-3 ) { u = normalize( vec3( -normal.z / normal.x, 0, 1 ) ); } + vec3 v = normalize( cross( normal, u ) ); + + // (-1,+1) (0,+1) (+1,+1) + // +-------+-------+ + // |1 | 3| + // | | | + // | | | + // (-1,0) +-------+-------+ (+1,0) + // | | | + // | | | + // |0 | 2| + // +-------+-------+ + // (-1,-1) (0,-1) (+1,-1) + + // quad corners + vec3 point[4]; + point[0] = in_position[0] - pointCloudSplatRadius * ( u + v ); + point[1] = point[0] + pointCloudSplatRadius * u * 2; + point[2] = point[0] + pointCloudSplatRadius * v * 2; + point[3] = point[0] + pointCloudSplatRadius * ( u + v ) * 2; + + // uv coordinates + vec2 uv[4]; + uv[0] = vec2( -1, -1 ); + uv[1] = vec2( -1, +1 ); + uv[2] = vec2( +1, -1 ); + uv[3] = vec2( +1, +1 ); + + for ( int idx = 0; idx < 4; ++idx ) + { + gl_Position = transform.proj * transform.view * vec4( point[idx], 1 ); + out_position = point[idx]; + out_normal = normal; + out_eye = in_eye[0]; + out_eltID = gl_PrimitiveIDIn; + out_eltCoords = vec3( 1, 0, 0 ); + EmitVertex(); + } EndPrimitive(); } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 6d789f9c972..8639671e16e 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -17,6 +17,10 @@ #include #include +// temporary fix for issue #837 +#include + + #include #include @@ -473,7 +477,13 @@ void Renderer::renderForPicking( Core::Matrix4 N = M.inverse().transpose(); pickingShaders[i]->setUniform( "transform.model", M ); pickingShaders[i]->setUniform( "transform.worldNormal", N ); - + // hack to pick point cloud (issue ##837) + auto pointCloud = dynamic_cast( ro->getComponent() ); + if ( pointCloud ) + { + pickingShaders[i]->setUniform( "pointCloudSplatRadius", + pointCloud->getSplatSize() / 2.f ); + } // render ro->getMesh()->render( pickingShaders[i] ); }