Manually transforming 3d world coords into 2d screen coords

Started by
7 comments, last by Cybertron 22 years, 2 months ago
This is basically what I need to do to solve my UI dillema, I need to transform the 3d world coordinates into a 2D position on the screen for input!
Advertisement
Well, take the position of a single point, this will require some thinking,

You have 3 orthogonal projection planes, one the camera, and the world transform.

If you were to try to convert from world space into 2D coords on the screen, you would take and transform the 3D point by the inverses of the matrices.

Another thing that I heard is that if you have a point in the form:
x,y,z,w

you get 2D coords by:
nx = w*x;
ny = w*y;

Unfortunately I forgot where I heard about this .

-------
Happy Coding!
Homepage: www.pcwebvia.f2s.com CVS1.0 will be released soon here.
www.bytamin-c.com
-------Homepage: http://www.pclx.com
I''ve posted a more detailed description of this here in the past - a search in this forum should reveal more detailed info and source code.

1. Transform the 3D coordinates by the world matrix
2. Transform the 3D coordinates by the view matrix
3. Expand coordinates to homogenous form with a W=1 component
4. Transform the 4D coordinates by the projection matrix
5. Divide X, Y and Z by W to go from homogenous back to 3D
6. Multiply coords by half the viewport size
7. Add half the viewport size to coords

The matrices can be concatenated and the coordinates passed in homogenous form from the start.


Alternatively you can use an orthogonal projection matrix with your 3D geometry so that the Z coordinate has no affect on the X,Y position.


--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

I was bored one day and i wrote a short tut on taking a 3d point onto a 2d screen. It might not be what you want but check it out and see.

[Edited by - kmsixpence on October 17, 2005 7:35:29 PM]
Thanks!!! I followed S1CA instructions on another post, but it still wasn''t correct. the last 3 steps he said were what solved it

6. Multiply coords by half the viewport size
7. Add half the viewport size to coords

I was uisng some wierd viewport matrix and didn''t add half (makes sense :p)

Thanks so much!
I did actually post working (& tested) code on the board at some stage..., but you got it working anyway which is good.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Using D3DX you could also make use of the D3DXVec3Project function, which looks like:
D3DXVECTOR3* D3DXVec3Project(  D3DXVECTOR3* pOut,  CONST D3DXVECTOR3* pV  CONST D3DVIEWPORT8* pViewport,  CONST D3DXMATRIX* pProjection  CONST D3DXMATRIX* pView,  CONST D3DXMATRIX* pWorld);  

pOut is the newly projected coordinates (x, y, z)
pV is the source coordinates in object space
pViewport is the current viewport settings
pProjection is the projection transformation matrix
pView is the view transformation matrix
pWorld is the world transformation matrix

A sample use would be:
D3DXVECTOR3 vecScreen, vecSource(0.0f, 10.0f, 0.0f);D3DXMATRIX matWorld, matProjection, matView;D3DVIEWPORT8 vpScreen;pD3DDevice->GetTransform(D3DTS_WORLD, &matWorld);pD3DDevice->GetTransform(D3DTS_VIEW, &matView);pD3DDevice->GetTransform(D3DTS_PROJECTION, &matProjection);pD3DDevice->GetViewport(&vpScreen);D3DXVec3Project(&vecScreen, &vecSource, &vpScreen, &matProjection, &matView, &matWorld);// Screen Coordinates = vecScreen.x and vecScreen.y 



Jim Adams
Cool, DX8 has already taken care of it. Too bad I need to use DX7

Doing it myself is still good, because I know what it is doing

well now the UI works PERFECTLY, yahoo! not bad for my first week of actually using D3d :p
the first thing, "x_s = x/w" or "x_s = x*rhw" NOT "x_s = w*x".
but you must have got this already, otherwise it wouldnt be working

second, if you want exact match, to get the -1 to +1 rangt to screen-coordinates, you should go

x_vp = float(x_s*float(vp_width/2)+0.5)+(vp_width/2);

or similar.
otherwise ~50% of your coordinates will wrong by 1 pixel.

bye,

--- foobar
We push more polygons before breakfast than most people do in a day
--- foobarWe push more polygons before breakfast than most people do in a day

This topic is closed to new replies.

Advertisement