Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Directx 9] To get mouse coordinates from 2d to 3d space

155 views
Skip to first unread message

SixOfOne

unread,
Nov 13, 2007, 3:24:18 PM11/13/07
to
Hello everyone,

1) What I have :

- I'm writing a little 3d engine with DirectX 9 [not managed, with the old
D3DFramework] (installed : Dx9.0c + august sdk), whitch do same as Visio (m$
software) in 3d.
- I'm using Direct3d
- I'm in a left-handed perspective
- All my objects are on a plane xOy, z coordinate = 0.0 or very closed to
0.0 (i know everytime the z coordinate)
- Translate camera is permetted (move vEye and vLookAt at same time),
rotation is permetted (only around the z axis, with vUp = (0.0, 0.0, -0.1))
- I already made my picking function, then i know exactly the object clicked
(selected)


2) My problem :

- I have to drag'n'drop (translate in my xOy plane) objects placed in my
world. All objects are in z coordinate egal to zero, they never translate in
this axis.
- I get correct mouse coordinates in my 2d space (render window, in fact it
is a panel in a MFC form, i'm in windowed mode in a MFC application)
- I know my world, view and projection matrix, and my viewport (800 x 600,
min=3.0 max=80.0)

- After reading papers on the internet, i tried many and many solutions...
but still never find the right solution...

- For instance, I draw a little square witch "show" the calculated 3d of the
mouse. When the mouse is at (0,0) the sqare is exactly at the good position
(just under my mouse), the more and more I move my mouse far of the center,
the more and more the distance between my mouse and my little square is big
!

- I tried using UnProject... not better than my other solutions.

My code (yes, nobody is dreaming, it is really Delphi ;)) -it is close to
c++- :

function T3BNScene.ScreenToWorld3(fScreenPt: TPoint): TD3DXVector3;
var
vPixel2d : TD3DXVector3;
vPixel3d : td3dxvector3;
ViewPort : TD3DViewport9;

begin

vPixel2d.x := ( fScreenPt.x * 2.0 / m_d3dsdBackBuffer.Width - 1 );
vPixel2d.y := -( fScreenPt.y * 2.0 / m_d3dsdBackBuffer.Height - 1 );
vPixel2d.z := 0.0;

vPixel2d.x := fScreenPt.x;
vPixel2d.y := fScreenPt.y;
vPixel2d.z := 0.0;

D3DXVec3UnProject( vPixel3d, vPixel2d, ViewPort, m_matProj, m_matView,
m_matWorld );

// I tried to put the z coordinate at the Near z : and it works,
// My little rectangle object follow my mouse
// but if I put zero for z : what a big difference !
vPixel3d.z := ( m_Camera2[_iActiveCamera].vPosition.z + 3.0 );

result := vPixel3d;

end;


To resume : With this function, I get good coordinates at the Near plane of
the frustrum (where the eye of the camera is placed), but i need to find
coordinates under those at the level z=0.0. Like I "project" a normal vector
(of the near frustrum plane) from this point to the z=0.0 plan. How can i do
this miracle please ?

English is not my mother tongue, I hope beeing clear...

Many thanks by advance ;) SixOfOne.


SixOfOne

unread,
Nov 14, 2007, 1:20:56 PM11/14/07
to
Updates :

This afternoon I tried the following code with still not good result...

function T3BNScene.ScreenToWorld3(fScreenPt: TPoint): TD3DXVector3;
var
vPixel2d : TD3DXVector3;

vPixel3d : TD3DXVector3;
ViewPort : TD3DViewport9;

fDet : Single;

mat_Final,
mat_invWorld,
mat_invView,
mat_invProj : TD3DXMatrix;

begin

with m_pd3dDevice do
getviewport( ViewPort );

vPixel2d.x := fScreenPt.x;
vPixel2d.y := fScreenPt.y;
vPixel2d.z := 0.0;

D3DXVec3UnProject( vPixel3d, vPixel2d, ViewPort, m_matProj, m_matView,
m_matWorld );

D3DXMatrixIdentity( mat_Final ); // To init (not needed)
D3DXMatrixMultiply( mat_Final, m_matProj, m_matView );
D3DXMatrixMultiply( mat_Final, mat_Final, m_matWorld );
fDet := 0.0;
D3DXMatrixInverse( mat_Final, @fDet, mat_Final );
D3DXVec3TransformCoord( vPixel3d, vPixel3d, mat_Final );

result := vPixel3d;

end;

I tried different order of the matrix multiplication of Proj, View and
World... nothing change with signification.


Richard [Microsoft Direct3D MVP]

unread,
Nov 14, 2007, 1:36:45 PM11/14/07
to
[Please do not mail me a copy of your followup]

"SixOfOne" <guitton-...@club-internet.fr> spake the secret code
<473a07e8$0$21144$7a62...@news.club-internet.fr> thusly:

>- For instance, I draw a little square witch "show" the calculated 3d of the
>mouse. When the mouse is at (0,0) the sqare is exactly at the good position
>(just under my mouse), the more and more I move my mouse far of the center,
>the more and more the distance between my mouse and my little square is big

This indicates a scaling problem. Is the distance always *twice* as
big as what it should be?
--
"The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download
<http://www.xmission.com/~legalize/book/download/index.html>

Legalize Adulthood! <http://blogs.xmission.com/legalize/>

SixOfOne

unread,
Nov 14, 2007, 4:05:45 PM11/14/07
to
it seems to be a : 2 pow x... the difference increase bigger the mouse goes
far away from (0,0)


Richard [Microsoft Direct3D MVP]

unread,
Nov 15, 2007, 1:36:24 PM11/15/07
to
[Please do not mail me a copy of your followup]

"SixOfOne" <guitton-...@club-internet.fr> spake the secret code

<473b631d$0$21145$7a62...@news.club-internet.fr> thusly:

>it seems to be a : 2 pow x... the difference increase bigger the mouse goes
>far away from (0,0)

Yeah, but 2*1 = 2 and 2*2 = 4 so just a simple scaling factor
increases the distance as the mouse gets farther from the origin.

SixOfOne

unread,
Nov 15, 2007, 2:28:28 PM11/15/07
to
First, many thanks for trying help me ;)

Indeed ! But for instance, I dont understand what is this factor !


Richard [Microsoft Direct3D MVP]

unread,
Nov 16, 2007, 9:42:17 AM11/16/07
to
[Please do not mail me a copy of your followup]

Well, it seems that you're applying a scaling factor that shouldn't be
there. Re-examine your matrices carefully, paying attention to
scaling. Compue what the matrices should be by hand and work out the
computation to ensure that you've got it correct. Once you've got it
correct by hand, then examine your code where you're computing the
matrices and find which one doesn't match.

SixOfOne

unread,
Nov 21, 2007, 3:55:44 PM11/21/07
to
Solved ! Many thanks for your help !

I submit to you what i do : (not optimized, code is in progress, but it
works fine)

function ScreenToWorld(AIndex: integer; fScreenPt: TPoint): TD3DXVector3;
var
vPixel2d : TD3DXVector3;
vObjectPos : TD3DXVector3;
ViewPort : TD3DViewport9;

begin

// Mouse 2d coordinates


vPixel2d.x := fScreenPt.x;
vPixel2d.y := fScreenPt.y;
vPixel2d.z := 0.0;

with m_pd3dDevice do
getviewport( ViewPort );

// Coordinates of my selected object
vObjectPos := TMonRectangle( _lObjectList.Items[ AIndex ] ).vPos;

// Project coordinate from 3d space to screen space
D3DXVec3Project( vObjectPos, vObjectPos, ViewPort, m_matProj, m_matView,
m_matWorld );

// Giving mouse coordinates to barycentric point of the object
vObjectPos.x := vPixel2d.x;
vObjectPos.y := vPixel2d.y;

// Projet new coordinates from Screen space to 3d space
D3DXVec3UnProject( vObjectPos, vObjectPos, ViewPort, m_matProj, m_matView,
m_matWorld );

// Here, I put myself the z coordinate of the object
// because I remark the z value changes
// For my software all objects always stay at the same z value
vObjectPos.z := -1.4;

// I return the new position of the object in the 3d space
result := vObjectPos;

end;

That all !

One last point is to solve : that center the object on the new position, i
have to solve how computing the little offset between real clicked point and
center of the object.


0 new messages