| 105 | } |
| 106 | |
| 107 | static ObjAndPick pickRenderObjectImpl( const Viewport& v, std::span<VisualObject* const> objects, const Viewport::PickRenderObjectParams& params ) |
| 108 | { |
| 109 | auto& viewer = getViewerInstance(); |
| 110 | |
| 111 | // Maybe block pick by the ImGuiMenu. |
| 112 | if ( auto menu = viewer.getMenuPlugin(); menu && menu->anyImGuiWindowIsHovered() ) |
| 113 | return {}; |
| 114 | if ( auto menu = viewer.getMenuPlugin(); menu && menu->anyUiObjectIsHovered() ) |
| 115 | return {}; |
| 116 | |
| 117 | const auto& mousePos = viewer.mouseController().getMousePos(); |
| 118 | Vector2f vp; |
| 119 | if ( params.point ) |
| 120 | { |
| 121 | vp.x = params.point->x; |
| 122 | vp.y = params.point->y; |
| 123 | } |
| 124 | else |
| 125 | { |
| 126 | auto vec3 = viewer.screenToViewport( Vector3f( float( mousePos.x ), float( mousePos.y ), 0.f ), v.id ); |
| 127 | vp.x = vec3.x; |
| 128 | vp.y = vec3.y; |
| 129 | } |
| 130 | |
| 131 | int radius = params.pickRadius >= 0 ? params.pickRadius : viewer.glPickRadius; |
| 132 | |
| 133 | if ( radius == 0 ) |
| 134 | return v.multiPickObjects( objects, { vp }, params.baseRenderParams ).front(); |
| 135 | else |
| 136 | { |
| 137 | std::vector<Vector2f> pixels; |
| 138 | pixels.reserve( sqr( 2 * radius + 1 ) ); |
| 139 | pixels.push_back( vp ); |
| 140 | for ( int i = -int( radius ); i <= int( radius ); i++ ) |
| 141 | for ( int j = -int( radius ); j <= int( radius ); j++ ) |
| 142 | { |
| 143 | if ( i == 0 && j == 0 ) |
| 144 | continue; |
| 145 | if ( i * i + j * j <= radius * radius + 1 ) |
| 146 | pixels.push_back( Vector2f( vp.x + i, vp.y + j ) ); |
| 147 | } |
| 148 | auto res = v.multiPickObjects( objects, pixels, params.baseRenderParams ); |
| 149 | if ( res.empty() ) |
| 150 | return {}; |
| 151 | if ( params.exactPickFirst && bool( res.front().first ) ) |
| 152 | return res.front(); |
| 153 | int minIndex = int( res.size() ); |
| 154 | float minZ = FLT_MAX; |
| 155 | for ( int i = 0; i < res.size(); ++i ) |
| 156 | { |
| 157 | const auto& [obj, pick] = res[i]; |
| 158 | if ( !obj ) |
| 159 | continue; |
| 160 | if ( pick.zBuffer < minZ ) |
| 161 | { |
| 162 | minZ = pick.zBuffer; |
| 163 | minIndex = i; |
| 164 | } |
no test coverage detected