# help with ui mouse intersection

This topic is 4355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

hi, i have one problem with my UI and that problem is this. i think i am caluclating my intersection wrong. when i have a button in my window, i cant click everywhere on that button. only half of that button i can click on.

void UIControl::getAbsPos(D3DXVECTOR2 *position)
{
position->x += this->getX();
position->y += this->getY();

if(this->parent)
this->parent->getAbsPos(position);
}

bool UIControl::cursorIntersection(int x, int y)
{
D3DXVECTOR2 cabs;
cabs.x = 0;
cabs.y = 0;

this->getAbsPos(&cabs);

if((x >= cabs.x) && (x <= (cabs.x + this->getWidth())))
if((y >= cabs.y) && y <= ((cabs.y + this->getHeight())))
return true;

return false;
}

//in a message loop
if(this->cursorIntersection(LOWORD(lParam), HIWORD(lParam))
{
//code
}



##### Share on other sites
help me...............

##### Share on other sites
why are you += here?:

position->x += this->getX();
position->y += this->getY();

##### Share on other sites
Quote:
 Original post by rgirard413why are you += here?:position->x += this->getX();position->y += this->getY();

otherwise it screws up the window positions.

##### Share on other sites
Quote:
 Original post by 31337noobwhen i have a button in my window, i cant click everywhere on that button. only half of that button i can click on.

To investigate the problem furthur...:

What half is active, and where is the button located than?

How does the active area change if you re-locate the button a little bit?

Where is the origin of the co-ordinate system in use (left top, left bottom, middle of the window), and is the origin of the x,y parameters the same?

(I assume the following to play no role, since most often a control is missed totally if this would be wrong.) To what direction do the co-ordinates grow? (Say, do your pointer co-ordinates grow in the same direction as the control's co-ordinates do?)

Quote:
 Original post by 31337noobi think i am caluclating my intersection wrong.

The snippet you've posted seems me correct. I expect the problem to be caused elsewhere.

##### Share on other sites
Quote:
Original post by haegarr
Quote:
 Original post by 31337noobwhen i have a button in my window, i cant click everywhere on that button. only half of that button i can click on.

To investigate the problem furthur...:

What half is active, and where is the button located than?

How does the active area change if you re-locate the button a little bit?

Where is the origin of the co-ordinate system in use (left top, left bottom, middle of the window), and is the origin of the x,y parameters the same?

(I assume the following to play no role, since most often a control is missed totally if this would be wrong.) To what direction do the co-ordinates grow? (Say, do your pointer co-ordinates grow in the same direction as the control's co-ordinates do?)

Quote:
 Original post by 31337noobi think i am caluclating my intersection wrong.

The snippet you've posted seems me correct. I expect the problem to be caused elsewhere.

How does the active area change if you re-locate the button a little bit?
it does change but still doesnt get the whole button

Where is the origin of the co-ordinate system in use (left top, left bottom, middle of the window), and is the origin of the x,y parameters the same?

top-left

##### Share on other sites
Quote:
 Original post by 31337noobHow does the active area change if you re-locate the button a little bit? it does change but still doesnt get the whole button

Ok, but the question is _how_ does it change. E.g. if you shift the button to the right / bottom (say you increase the value of getX() / getY()), does the active area grow or shrink? Does it grow / shrink exactly by the amount of the shift? So you can determine whether there is an absolute or a relative border.

Is the active area always to the right / bottom? Is the button totally active if you shift it far enough into one of the quadrants? Then you may have a sign resp. origin problem.

Since the posted code isn't IMHO sufficient to locate the problem, I suggest you to do the following: Restrict the UIControl to have none or at most one parent. Locate it so that it is in (0,0) and covers the whole window area. Set a breakpoint into UIControl::cursorIntersection, and investigate the values of x,y and cabs for various clicks. Then you should follow the questions above. From the results you could determine the cause of the problem.

##### Share on other sites
ok, here is what i know so far.

i put the parent window at (0,0) and the button at (0,0)

when i move the window to the bottom of the screen, i can go below the picture of the button and it can be clicked on. how can that happen if i am not even on the button. ok, now if i move the window to the top left, i can click on the very top of the button but i cant click on the bottom of the button or the right part of the button. now if i move the window to the right, i still cant click on the right part of the button.

i do know why it doesnt register the right part though. the width and height is a little off.

so i think the problem is the absoulte function.

so what do you think?

what do i do next?

i bet if we get the abs thing working the whole thing will be working.

##### Share on other sites
ok, this is werider. i just found out it doesnt do this werid problem when its in fullscreen. ok so how can i deal with it when its not in fullscreen.

so what do i do?

##### Share on other sites
Quote:
 ok, this is werider. i just found out it doesnt do this werid problem when its in fullscreen. ok so how can i deal with it when its not in fullscreen.

Just a quick glance at your post..

in fullscreen mode, dx screen coordinates are same as windows screen coordinate, whereas, in windowed mode, dx screen coord. are not equal to windows screen coord. you might be missing clicking on button just because of that.

##### Share on other sites
In fullscreen screen mode the mouse co-ordinates and the window co-ordinates are the same. This let me think that the co-ordinates you use may be related to the screen and not to the window. (EDIT: Ahem, Taha Ansari was quicker in stating this :)

(1) In UIControl::cursorIntersection do a cout on x and y. Position the button in the upper left corner of the window. Compile, run, and move the window to the upper left corner of the screen. Click in the upper left corner of the button. Are the printed co-ordinates near at zero, or else are their values in the range of the border thicknesses of the window? If so, you have first to subtract the window's border thicknesses from x and y. (You said, 0,0 is in the upper left corner, right?)

(2) Now click in the lower right corner of the button. If you subtract the printed values from those printed earlier at clicking in the upper left corner, are the differences as big as the size of the button?

(3) The window being in the upper left corner. Click on the center of the button and remember the printed values. Then move the window to the lower right corner of the screen. Click again on the center of the button. Do the printed values change significantly (say more than a few pixels)? If so, then the mouse co-ordinates are screen related, and not window related, and you have to subtract the window position from x and y.

(4) Please post more of the code that is related to the problem.

##### Share on other sites
ok, i have a picture thats 100,50 and i did what you said. i put my mouse at the upper left hand corner and i get 0,0 and then i move my mouse the lower right of the button and i get 127,61. i think directx just drawn the sprite a little bigger then 100,50. its the same in fullscreen the width is bigger and so is the height

##### Share on other sites
when i move my window to the lower-right, the intersection is all wrong. its like it shifts down alot.

##### Share on other sites
Are your getX and getY functions relative to the origin or to the parent window? Because if they are relative to the parent window your getAbsPos function is wrong.

##### Share on other sites
Quote:
 Original post by 31337noobok, i have a picture thats 100,50 and i did what you said. i put my mouse at the upper left hand corner and i get 0,0 and then i move my mouse the lower right of the button and i get 127,61. i think directx just drawn the sprite a little bigger then 100,50. its the same in fullscreen the width is bigger and so is the height

That sounds that not the mouse is the problem (at least not alone) but the projection set-up. Please post that piece of code (also of interest is the VIEW matrix set-up). Good would be an orthogonal projection with a widht/height equally to the width/height of the window, so that you could work with pixel co-ordinates directly. But I expect your set-up being something other, independent on the window size.

[Edited by - haegarr on December 21, 2005 1:03:12 PM]

##### Share on other sites
Quote:
Original post by haegarr
Quote:
 Original post by 31337noobok, i have a picture thats 100,50 and i did what you said. i put my mouse at the upper left hand corner and i get 0,0 and then i move my mouse the lower right of the button and i get 127,61. i think directx just drawn the sprite a little bigger then 100,50. its the same in fullscreen the width is bigger and so is the height

That sounds that not the mouse is the problem (at least not alone) but the projection set-up. Please post that piece of code (also of interest is the VIEW matrix set-up). Good would be an orthogonal projection with a widht/height equally to the width/height of the window, so that you could work with pixel co-ordinates directly. But I expect your set-up being something other, independent on the window size.

do you mean this?

D3DXMATRIX projMatrix;D3DXMatrixPerspectiveFovLH( &projMatrix, D3DX_PI / 4, (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight, 1.0f, 5000.0f);this->pDevice->SetTransform( D3DTS_PROJECTION, &projMatrix );

do you?

##### Share on other sites
Quote:
 Original post by 31337noobdo you?

Yes, in part. (Sorry, I was busy yesterday.)

Perhaps I lack enough knowledge of what you are doing with your app. However, I assume you are making a GUI, maybe a kind of 2D overlay or something similar?

You set-up a perspective projection. As you'll already know, perspective projections do a depth scaling; there is only one specific distance where the depth scaling is 1. Now it depends: Either you want to have your GUI element like a bill board integrated into the scene. That is, it faces always the camera, but it should be hidden by "normal" 3D scene elements (say, a tree trunk in front of the button should hide it). Then using perspective transformation is ok. However, in this case you have to consider perspective depth shortening also for your mouse click, since the click occurs onto the plane where depth shortening is 1 but does track all depth values on a straight line _not_ perpendicular to the screen! In other words, in such a case you have to scale your click co-ordinates depending on the GUI element's depth value before comparing them with the button co-ordinates.

Or (the more likely case): Your GUI is always in front of the 3D scene, like an overlay (e.g. a HUD) or a GUI even without 3D in behind. Your wish is to draw 2D GUI elements with pixel accuracy. (All of the following belongs to this case).

In such case I suggest not to use the perspective projection at all (also it is possible, too), but to use the orthogonal projection. This kind of projection has the advantage that it does not show any depth scaling. You could set it up using the D3DXMatrixOrthoLH function. Without proven, I assume something like
D3DXMatrixOrthoLH(&projMatrix,widhtInPixels,heightInPixels,-1,1);
should be possible (you could also take into account of using the "OffCenter" variant of this routine).

However, in the case of ortho projection you also have to set-up a suitable view matrix. I suggest the view matrix to do 2 things (you have to ignore the second thing if you use the "OffCenter" variant of projection): mirror the y axis since you want the y co-ordinate system of the GUI to grow from top to bottom, right?
D3DXMatrixScaling(&viewScale,1,-1,1);
computes such a matrix. But notice that doing so will probably require texture co-ordinates to be adapted, too). You also wants the origin to be located in the upper left corner, instead of the center of the screen, so you also have to translate the view by
D3DXMatrixTranslation(&viewTranslate,widhtInPixels/2,0.5f*heightInPixels/2,0);
(please notice that I write this from mind, not copying it from a tested app).

After setting up the view matrix from the proper product of those stuff above, it should be possible to push GUI geometry in a co-ordinate system (0,0,0) in the upper left and (widht-1,height-1,0) in the lower right corner. Render the GUI elements without depth test and in back to front order to get the overlapping right.

[Edited by - haegarr on December 23, 2005 4:15:35 AM]

##### Share on other sites
i will try that. oh, just to let you know, i am using the ID3DXSprite class.

what i am doing is i am making a game engine

##### Share on other sites
so, what is the difference between projection and ortho?

##### Share on other sites
here it try out for yourself.

you maybe can see what is wrong with it if you see it in action.

here try it out

make sure you have the dec 2005 runtime dll's of directx9

##### Share on other sites
that is using projection by the way. i still have to try out ortho.

##### Share on other sites
did anyone try the demo?

##### Share on other sites
Quote:
 Original post by 31337noobso, what is the difference between projection and ortho?

Your question isn't totally correct: Projection is the general term, and "ortho" projection is just a special kind of projection. In the given sense projection means to reduce the dimensionality of 3 (the scene) downto 2 (the screen). Think of a ray racer: All locations of the 3D scene hit by a particular ray are mapped onto the same pixel of the screen, where simply the nearest hit hides the other ones.

There are many different kinds of projections. Usually the _perspective_ projection is used to display 3D scenes. Perspective projection does the depth shortening, so that more distant objects appear smaller than nearer objects does. The projectors (a name of the aforementioned rays) emanate at a single origin, namely the location of the camera, and spread out into the scene. This could be expressed in principle (although more complicated in the APIs) by scaling the x,y co-ordinates by the depth value (after transformation into the camera space):
x' := x/z
y' := y/z
In this example only at z=1 there is no scaling; all other z values will grwo/shrink the co-ordinates.

The _orthogonal_ projection uses projectors that are parallel and orthogonal to the screen (so they don't have a common origin). The scaling could be expressed by
x' := x
y' := y
and hence any size is depth independent. That makes the orthogonal projection more suitable for normal (i.e. pixel accurate) GUI rendering.

[Edited by - haegarr on December 25, 2005 8:47:10 AM]

##### Share on other sites

This topic is 4355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628710
• Total Posts
2984325

• 23
• 11
• 9
• 13
• 14