Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

kieren_j

View Matrix from location / rotation details

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. Thanks for the help with the normal calculations, I wrote a function that calculates them Anyway, I''d like to know if you can help me; I want to be able to create a view matrix from these details: D3DVECTOR camera_location; // pos. in 3d space D3DVECTOR camera_rotation; // rotation angles in radians Does anybody know how it''s done (do you have any code)? All the examples in the D3DIM SDK use D3DUtil_SetViewMatrix to set up view matrices. However, this requires a "look at" point - which I don''t know how to calculate. So what sort of a matrix would I need to form? Are there functions already designed for this? I''d also like to be able to calculate a "forward direction" vector, so that I can move the camera forward by scaling it by a movement value. ! Thanks !

Share this post


Link to post
Share on other sites
Advertisement
The matrix you''ll want to compute goes like this:


D3DMATRIX View, RY, RX, RZ;


D3DXMatrixTranslation(&View, -camera_location.x, -camera_location.y, -camera_location.z); // Move world and camera to origo
D3DXMatrixRotationY(&RY, -camera_rotation.y); // Rotate world and camera so that the camera faces down the zy-plane
D3DXMatrixRotationX(&RX, -camera_rotation.x); // Pitch the world and camera so that the camera direction is aligned with the z-axis
D3DXMatrixRotationZ(&RZ, -camera_rotation.z); // Roll the world and camera


D3DXMatrixMultiply(&View, &View, &RY); // Combine the transforms into one
D3DXMatrixMultiply(&View, &View, &RX);
D3DXMatrixMultiply(&View, &View, &RZ);


I''m not sure if you''re allowed to use the same matrix as input and output in D3DXMatrixMultiply but I don''t think it is a problem as the manual doesn''t say anything about it.

To compute the forward direction you can inverse the view matrix and then transform the vector (0,0,1) with it. This will give you a point that is one unit infront of the camera. If you omit the translation part you will get a vector that points in the cameras direction and is of unit length.


// Compute forward direction
D3DMATRIX Rot, RY, RX;


D3DXMatrixRotationZ(&Rot, camera_rotation.z); // Roll the camera (Doesn''t affect the forward direction)
D3DXMatrixRotationX(&RX, camera_rotation.x); // Pitch the camera
D3DXMatrixRotationY(&RY, camera_rotation.y); // Rotate the camera


D3DXMatrixMultiply(&Rot, &Rot, &RX); // Combine the transforms into one
D3DXMatrixMultiply(&Rot, &Rot, &RY);


D3DXVECTOR3 Fwd = {0,0,1};
D3DXVec3TransformCoord(&Fwd, &Fwd, &Rot);



Again I''m not sure if you can use the same parameter as input and output.

If you include the translation part in the above matrix you can easily compute the "look at" position. But it''s unnecessary work as D3DUtil_SetViewMatrix() or D3DXMatrixLookAt() will only use it to compute the forward direction of your camera.


Share this post


Link to post
Share on other sites
Thanks - with your help and page 1026 of the Black Art book, I''ve managed to create suitable matrices and a forward vector.
However, I''m having trouble setting up a z-buffer; even though I copied the code from the D3DIM tutorial "adding a depth buffer", it just doesn''t seem to work, and the IDirect3DDevice7::Clear method fails with "D3DERR_ZBUFFER_NOT_PRESENT" when called with the D3DCLEAR_ZBUFFER flag. The thing is I can''t tell where I am going wrong, because through all the stages of initialization I do error checking.

Take a look at my code?:
(BTW Spellbound, I''m using D3DIM in plain old C++ rather than D3DX or whatever it''s called)

Enumeration Callback
This code always displays the "worked" message box, and when I check the bit depth it''s 16

static HRESULT WINAPI EnumZBufferCallback( DDPIXELFORMAT* pddpf,
VOID* pddpfDesired )
{
/*
* Find a z-buffer
*/
if( pddpf->dwFlags == DDPF_ZBUFFER )
{
/*
* Copy details and we''re done
*/
MessageBox(GetForegroundWindow(), "Worked", "Information", MB_OK / MB_ICONINFORMATION);
memcpy( pddpfDesired, pddpf, sizeof(DDPIXELFORMAT) );
return D3DENUMRET_CANCEL;
}

/*
* Keep searching
*/
return D3DENUMRET_OK;
}


Creation code
This code never displays a message box (apart from in very high resolutions, where the zbuffer can''t be created in video memory - but even then the system memory method works)

DDPIXELFORMAT ddpfZBuffer;

/*
* Get a buffer format
*/
if (D3D_OK != lpd3d->EnumZBufferFormats(pDeviceGUID, EnumZBufferCallback, (VOID*)&ddpfZBuffer))
MessageBox(GetForegroundWindow(), "Couldn''t enumerate z-buffer formats", "Error", MB_OK / MB_ICONERROR);

/*
* Create z-buffer description
*/
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS / DDSD_WIDTH / DDSD_HEIGHT / DDSD_PIXELFORMAT;
ddsd.dwWidth = rScreen.right;
ddsd.dwHeight = rScreen.bottom;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
if (IsEqualIID(pDeviceGUID, IID_IDirect3DHALDevice))
ddsd.ddsCaps.dwCaps /= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps /= DDSCAPS_SYSTEMMEMORY;
memcpy(&ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT));

/*
* Create z-buffer
*/
if (DD_OK != lpdd->CreateSurface(&ddsd, &lpZBuffer, NULL))
{
/*
* Failed; if in video memory, try it in system memory
*/
if (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
{
MessageBox(GetForegroundWindow(), "Couldn''t create z-buffer in video memory, trying system memory", "Error", MB_OK / MB_ICONERROR);
ddsd.ddsCaps.dwCaps -= DDSCAPS_VIDEOMEMORY;
ddsd.ddsCaps.dwCaps /= DDSCAPS_SYSTEMMEMORY;
if (DD_OK != lpdd->CreateSurface(&ddsd, &lpZBuffer, NULL))
MessageBox(GetForegroundWindow(), "Couldn''t create z-buffer in system memory", "Error", MB_OK / MB_ICONERROR);
else
MessageBox(GetForegroundWindow(), "Using z-buffer in system memory", "Information", MB_OK / MB_ICONINFORMATION);
}
}

/*
* Attatch the z-buffer to the backbuffer
*/
if (DD_OK != lpBuffer->AddAttachedSurface(lpZBuffer))
MessageBox(GetForegroundWindow(), "Couldn''t attach z-buffer", "Error", MB_OK / MB_ICONERROR);



After all this, I use lpDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, TRUE); to turn on z-buffer usage. Hmm.....maybe I need to put this after a BeginScene() command?

Anyway, any ideas?
Thanks!

Share this post


Link to post
Share on other sites
Hang on a sec, my view matrix doesn''t work properly after all. Here''s the D3DIM code I made based on what you said:


void ApplyCamera(void)
{
/*
* Positions, rotates, and applies the view matrix
*/
D3DMATRIX RY, RX, RZ;

ZeroMemory(&matView, sizeof(matView));
/////// CREATE IDENTITY MATRIX
matView._11 = matView._22 = matView._33 = matView._44 = 1.0f;
/////// CREATE TRANSFORM MATRIX
matView._41 = -camera_location.x;
matView._42 = -camera_location.y;
matView._43 = -camera_location.z;

/////// CREATE ROTATE MATRICES
D3DUtil_SetRotateXMatrix(RX, -camera_rotation.x);
D3DUtil_SetRotateYMatrix(RY, -camera_rotation.y);
D3DUtil_SetRotateZMatrix(RZ, -camera_rotation.z);

/////// APPLY ROTATE MATRICES
D3DMath_MatrixMultiply(matView, RX, matView);
D3DMath_MatrixMultiply(matView, RY, matView);
D3DMath_MatrixMultiply(matView, RZ, matView);

lpDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView);
}


When I run this, adding to the "z" value of the camera location moves it backwards; this is not what I want to happen. Is this because the code inverts the vector? The rotation is also reversed. And, the view still doesn''t seem to rotate around the viewpoint.


Thanks

P.S. I say the movement is "reversed", because before I had this view matrix, when I added to the "z" component of objects, they moved further away.
P.P.S. Any ideas on that zbuffer, anyone?

Share this post


Link to post
Share on other sites
quote:

(BTW Spellbound, I'm using D3DIM in plain old C++ rather than D3DX or whatever it's called)



I noticed that, but unless you are using DX6 or older there is no need to _not_ to use D3DX it doesn't impose any overhead. And personally I find it a lot easier to use the documented features of D3DX than using the undocumented features of the D3DFrameWork.

I don't have time right now to go through your code, but I noticed that on your viewmatrix calculations you reverse the order if the matrix concatenations. This is a no-no. Matrices must be multiplied in a specific order. I don't have time to go into why either, if you really want to know then ask again.

you should do it like this:


void ApplyCamera(void)
{
/*
* Positions, rotates, and applies the view matrix
*/
D3DMATRIX RY, RX, RZ;

ZeroMemory(&matView, sizeof(matView));
/////// CREATE IDENTITY MATRIX
matView._11 = matView._22 = matView._33 = matView._44 = 1.0f;


/////// CREATE TRANSFORM MATRIX
matView._41 = -camera_location.x;
matView._42 = -camera_location.y;
matView._43 = -camera_location.z;


/////// CREATE ROTATE MATRICES
D3DUtil_SetRotateXMatrix(RX, -camera_rotation.x);
D3DUtil_SetRotateYMatrix(RY, -camera_rotation.y);
D3DUtil_SetRotateZMatrix(RZ, -camera_rotation.z);


/////// APPLY ROTATE MATRICES
D3DMath_MatrixMultiply(matView, matView, RY);
D3DMath_MatrixMultiply(matView, matView, RX);
D3DMath_MatrixMultiply(matView, matView, RZ);

lpDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView);
}


Edited by - Spellbound on 3/16/00 4:05:49 PM

Share this post


Link to post
Share on other sites
Hey thanks! That works now.
The reason I''m not using D3DX is because I''m trying to create a D3DIM-only engine (i.e. any "helper" functions are my own).

But I still have that z-buffer problem (see a couple of posts ago) - doesn''t anybody have any idea?

Thanks

Share this post


Link to post
Share on other sites
Has nobody else had this problem?
Please, I''m really stuck here; my objects are showing triangles from the back of them on the front of them!

thanks!

Share this post


Link to post
Share on other sites
If you aren''t using D3DX in DX7 you should. I think D3DX is optimized for Intel and AMD specific instructions. This speeds up the code. Therefore being faster than yours. Just a suggestion.

Share this post


Link to post
Share on other sites
But, D3DX won''t read .x files ... anyone knows of a free-for-use and "easy to connect to" full blast 3D file loader ?

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!