[source lang="cpp"]
D3DXVECTOR3 ModelView::ScreenToZPlane(int X,int Y)
{
float Fx=(-Eye.z)*tan((Pi/3)/2); // compute halfwidth of frustrum at Z=0
float Fy=(-Eye.z)*tan((Pi/3)/2); // compute halfheight of frustrum at Z=0
RECT R;
GetClientRect(RenderHw,&R); // the viewport
float Vx=float(R.right)/2; // halfwidth of viewport
float Vy=float(R.bottom)/2; // halfheight of viewport
float Nx=float(X)-Vx; // translate reference system from 0,0 = top-left
float Ny=float(Y)-Vy; // to 0,0 = middle
Nx=Nx/Vx; // normalise coordinates between
Ny=-Ny/Vy; // -1.0f to +1.0f
D3DXVECTOR3 S(Nx*Fx,Ny*Fy,0); // scale normalised coords by frustrum half dims
S.x+=(Eye.x*2.0f); // add camera translation now we
S.y+=(Eye.y*2.0f); // are in world coords
// if anyone can explain why I have to multiply the eye coordinates by two, you
// can have a cookie when I have enough money to buy some
return S;
}
[/source]
The first two lines were the key. Once I found out that I could compute the half sizes of the frustrum for a given value of Z, everything sort of fell into place.
So, in the little 3D model view, bottom right in the last entry, you can now hold down Ctrl and drag the view about with the mouse (hence the need for the above), rotate the model around the world centre and scroll in and out with the mousewheel.
Since the scrolling and view dragging is already implemented in the orthogonal view windows, that's basically the overall navigation features done now (until something breaks).
It's actually quite hard to do 3D graphics programming when you are
- stupid and
- know next to nothing about maths
but it keeps me off the streets.
Should get some money on Monday now apparently but my driving licence still hasn't come back from DVLA so I'm still not in a position to get a usable bank account so better hope I don't get a job by mistake. If sodding GPO have lost my licence in the post or stolen it, nobody is responsible and I'll have to pay about GBP20 plus the cost of some passport photos to get a new licence.
I love being British.