Click to See Complete Forum and Search --> : Quick hover detection algorithm


ganzpopp
May 2nd, 2008, 12:29 PM
Hi there,

I wrote a neat program which has 2D objects displayed in a view window. I wrote some methodology to detect whether the mouse cursor is hovering any of the objects.

Main problem is that the hover checking functions eat up a lot of CPU power. Are there any good solutions for this. I simplified checking by precalculating bounding boxes and visibility, but this does not help as much as I want.

Any suggestions or links are welcome! Thanks.

Ps. the program is written in a MFC+SDL combination. While MFC is apparently very good in detecting clicks and hover, I can't reproduce this quality myself.

Zachm
May 4th, 2008, 02:58 AM
You can utilize the power of the graphics card and use the selection buffer for doing the hit-test.
See this (http://gpwiki.org/index.php/OpenGL:Tutorials:Picking) tutorial on Picking with openGL and SDL.

Regards,
Zachm

ganzpopp
May 6th, 2008, 09:40 AM
Thanks! That was what I was looking for, except that I'm not using OpenGL at the moment.

Any other suggestions?

Lindley
May 6th, 2008, 10:59 AM
I'm fairly certain GL_SELECT is old and unofficially deprecated anyway.

The "modern" way to do this is to render each object in a different color to the back buffer, then read back the relevant portion of the buffer without calling SwapBuffers. However, this may be slow to do for a simple hover, since all geometry must be "drawn" each mouse movement even if most of it is outside the relevant area (controlled by projection matrices).

As an alternative, *if* the drawn scene is static, you can do the draw-different color thing once, read back the entire image to RAM, and then your test is a simple table lookup. You'll have to do the render/readback again every time the scene changes, of course.

srelu
May 7th, 2008, 06:18 AM
There are many ways to solve the problem. Not knowing details about your application to exploit certain specific details and not knowing what are you trying to achieve I'll suggest a general method. Nonstandard, but very fast.

Create (in a memory DC) a mask for your window, in fact a bitmap having the exact size of your window. (It's not to be displayed on the screen.)
In that mask, make the background black RGB(0,0,0).
Draw in it the exact shape of your first control with RGB(1,0,0).
Draw in it the exact shape of your second control with RGB(2,0,0).
Draw in it the exact shape of your third control with RGB(3,0,0).
And so on...
Handle the WM_MOUSEMOVE message. Take the point parameter and check what color is the pixel at the same position in the memory DC using GetPixel.
If the red component of the pixel is 0, you're on the background.
If the red component of the pixel is 153, you're on the 153-th control.

You can get up to 255 controls with this technique. If not enough you may use the green and blue components of the RGB.

After you have the definitive layout of your window, you can keep a bitmap resource with the mask and just load it.

It takes one single call to GetPixel to find out the index of any of your controls, no matter how many they are. I don't think you can dream about something faster.

Mike Harnad
May 8th, 2008, 08:48 AM
You may find the methodology in this MSDN article (http://msdn.microsoft.com/en-us/magazine/cc163585.aspx) useful.

Lindley
May 8th, 2008, 01:06 PM
Well, all three of us have suggested the same thing (essentially), so it must be the way to go.....

ganzpopp
May 19th, 2008, 05:53 AM
I must be able to implement one of these methods, so I'll give it a try!

Thanks very much!