# How to detect mouse hovering over a point

**URL:** <https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027>\
**Category:** Using Cinder\
**Created:** [July 24, 2022, 3:43am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027 "2022-07-24T03:43:05Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![metric\_tensor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/metric_tensor/32/993_2.png) [@metric\_tensor](https://discourse.libcinder.org/u/metric_tensor)\
**Post date:** [July 24, 2022, 3:43am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/1 "2022-07-24T03:43:05Z")

</div>

Newbie question…

I am working on a space game and basically have a point cloud representing stars in a VboMesh:

```auto
    _mesh = gl::VboMesh::create(positions.size(), GL_POINTS, { layout });
    _mesh->bufferAttrib(geom::POSITION, positions.size() * sizeof(vec3), positions.data());   
    _mesh->bufferAttrib(geom::COLOR, colors.size() * sizeof(vec4), colors.data());
    _shader = gl::getStockShader(gl::ShaderDef().color());
    _batch = gl::Batch::create(_mesh, _shader);

```

I would like to assign an ID of some sort to each point and detect if the mouse is hovering over ( or near ) to the point and fetch it’s ID so that I can display some data about the selected star. What is the best way to go about this?

 ![image (1)](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/1X/f4cf32c33334652e11e649263a16693cb74601a1.png)

Thanks!

---

<div class="post-metadata">

**Author:** ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)\
**Post date:** [July 24, 2022, 5:59am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/2 "2022-07-24T05:59:36Z")

</div>

Few different ways to go about it. Given the amount of particles involved a straight linear search is probably not going to work (i’d try it first though, as performance intuitions are very often proven wrong by profiling), so failing that you could:

1. Stuff all your points into some kind of acceleration structure like a Kd-tree / Octree and query it
2. Assign a colour ID to each particle and write it to a separate colour attachment in a `gl::Fbo` and query that using mouse coordinates (possibly inaccurate due to the size of the particles)
3. If you’re on windows (i.e later versions of OpenGL), you could pass your mouse coordinates as a uniform to your shader and do a screen space proximity check at render time and write the result to an SSBO (this could be done with an fbo in a pinch if on older gl (i.e macOS))

---

<div class="post-metadata">

**Author:** ![metric\_tensor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/metric_tensor/32/993_2.png) [@metric\_tensor](https://discourse.libcinder.org/u/metric_tensor)\
**Post date:** [July 24, 2022, 1:46pm UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/3 "2022-07-24T13:46:06Z")

</div>

Thanks, I do have them in a Kd-tree for nearest neighbor and range searches, I will investigate further.

I am running on Windows, option 3 looks interesting as well.

---

<div class="post-metadata">

**Author:** ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)\
**Post date:** [July 24, 2022, 2:53pm UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/4 "2022-07-24T14:53:43Z")

</div>

Just did a quick test using [PCL’s](https://github.com/PointCloudLibrary/pcl) search [API](https://pointclouds.org/documentation/classpcl_1_1octree_1_1_octree_point_cloud_search.html#a1ddd57369f5f45e6edfed84c281621e5) and it’s totally fast enough for interactive usage and only took about 10 lines of code to implement 🙂

 ![image](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/1X/393f11eb63119cc8d7daa4b98dee10b0387d84b2.jpeg)

---

<div class="post-metadata">

**Author:** ![metric\_tensor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/metric_tensor/32/993_2.png) [@metric\_tensor](https://discourse.libcinder.org/u/metric_tensor)\
**Post date:** [July 24, 2022, 3:29pm UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/5 "2022-07-24T15:29:20Z")

</div>

I didn’t know about PCL, thanks!

---

<div class="post-metadata">

**Author:** ![metric\_tensor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/metric_tensor/32/993_2.png) [@metric\_tensor](https://discourse.libcinder.org/u/metric_tensor)\
**Post date:** [July 25, 2022, 4:27am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/6 "2022-07-25T04:27:13Z")

</div>

Did you calculate your origin and direction using CameraPesp::generateRay(mouse, getWindowSize())? I think I am missing a piece. My scaling is off in the y direction (screen space). The further I get from the center of screen in the y direction the bigger the error is. In other words my mouse has to be higher than the actual point to detect it ( or lower than the actual point in below the center of the screen ). Note this is not an issue in the x direction.

 ![snip](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/1X/97535b89ad00cc4b0bbfbb31465eefc71badeb08.png)  
ie. the blue circle is the mouse cursor position and the green circle is the selected point.

---

<div class="post-metadata">

**Author:** ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)\
**Post date:** [July 25, 2022, 8:29am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/7 "2022-07-25T08:29:31Z")

</div>

Yep, this is the entirety of my intersection function:

```cpp
void PointSpriteApp::mouseMove ( MouseEvent event )
{
    Ray r = _camera.generateRay( event.getPos(), getWindowSize() );
    Eigen::Vector3f o { &r.getOrigin().x };
    Eigen::Vector3f d { &r.getDirection().x };
    
    Timer t{true};
    pcl::Indices indices;
    bool hit = _octree.getIntersectedVoxelIndices(o, d, indices) > 0;
    
    if ( hit )
    {
        auto c = _camera.getEyePoint();
        std::sort( indices.begin(), indices.end(), [=] ( auto& ai, auto& bi )
        {
            auto& a = _positions[ai];
            auto& b = _positions[bi];
            
            return glm::distance2(a, c) < glm::distance2(b, c);
        } );
        _index = indices.back();
        _geometry->getGlslProg()->uniform( "uIndex", _index );
    }else
    {
        _index = -1;
    }
    
    std::cout << "Searched " << _positions.size() << " points in " << (t.getSeconds() * 1000.0f) << "ms" << std::endl;
}

```

~~Are you on a high-dpi or scaled display by any chance? If so you might want to use `app::toPixels ( getWindowSize() )` to compensate for the scale ratio.~~ Just tested this, has no effect. Sorry.

---

<div class="post-metadata">

**Author:** ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)\
**Post date:** [July 25, 2022, 9:09am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/8 "2022-07-25T09:09:15Z")

</div>

Wondering if this has to do with your tree resolution, do you have any way to visualise it? If the voxels are larger towards the extremities due to your stars being more sparse out there, it makes sense that the voxel center would deviate more from the actual point the further away from the middle you get.

---

<div class="post-metadata">

**Author:** ![metric\_tensor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/metric_tensor/32/993_2.png) [@metric\_tensor](https://discourse.libcinder.org/u/metric_tensor)\
**Post date:** [July 25, 2022, 4:01pm UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/9 "2022-07-25T16:01:22Z")

</div>

Tonight after work I think I will drop the tree and try a brute force method to confirm everything else is good.

---

<div class="post-metadata">

**Author:** ![metric\_tensor](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/metric_tensor/32/993_2.png) [@metric\_tensor](https://discourse.libcinder.org/u/metric_tensor)\
**Post date:** [July 28, 2022, 4:42am UTC](https://discourse.libcinder.org/t/how-to-detect-mouse-hovering-over-a-point/2027/10 "2022-07-28T04:42:13Z")

</div>

Found an interesting result, still investigating but if I use the alternate function for GenerateRay it seems to work correctly

```auto
    float u = _mouse.x / (float)getWindowWidth();
    float v = _mouse.y / (float)getWindowHeight();
    Ray ray = _cam.camera().generateRay(u, 1.0f - v, _cam.camera().getAspectRatio());
    Ray ray2 = _cam.camera().generateRay(_mouse, _app->getWindowSize());

```

In other words `ray` works correctly but `ray2` does not. Comparing the two there are small differences in the `mDirection` and` mInvDirection` vector between the two ray objects. Everything else appears to be equal.

 ![ray](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/1X/addc96a6d8117f01a460e376f9f83569fa223a86.png)  
 ![ray2](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/2X/8/892335a88e776504ecf6246ef945a70599e710c0.png)
