#### Archived

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

# View Matrix from location / rotation details

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

## 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 on other sites
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 origoD3DXMatrixRotationY(&RY, -camera_rotation.y); // Rotate world and camera so that the camera faces down the zy-planeD3DXMatrixRotationX(&RX, -camera_rotation.x); // Pitch the world and camera so that the camera direction is aligned with the z-axisD3DXMatrixRotationZ(&RZ, -camera_rotation.z); // Roll the world and cameraD3DXMatrixMultiply(&View, &View, &RY); // Combine the transforms into oneD3DXMatrixMultiply(&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 directionD3DMATRIX 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 oneD3DXMatrixMultiply(&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 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 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 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 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 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 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 on other sites
To set up the Z-Buffer correctly, it needs to be set up before the device is created. Don''t know why, but it worked for me

altair
altair734@yahoo.com
biggins.mit.edu/altair734

##### 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 ?

1. 1
Rutin
71
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633428
• Total Posts
3011822
• ### Who's Online (See full list)

There are no registered users currently online

×