camera rotation killing me!?

Started by
8 comments, last by stereotypical 19 years, 6 months ago
hey there im new to this directx, im trying to do a fps like camera, but only using keyboards without mouse, its a tutorial im learning from, ive used the same way but it can only move front,back,strafe left and right but somehow when i rotate left and right i still find my self looking at the same object.............. but after pressing left or right i can move towards where the camera is facing but somehow on my screen the object is still there so i know that the camera rotates but im not looking at where the camera is rotating, its as if im moving side ways towards where the camera is looking but my eyes are looking towards the object!! can someone help out here........ heres some snippet i dunno wats wrong, can someone help please?


	D3DXVECTOR3 vecEyePoint;    // The eye point
    D3DXVECTOR3 vecLookatPoint; // The camera look-at target
    D3DXVECTOR3 vecUp;          // The current world's up
    D3DXMATRIX matRotationX;    // The matrix that rotates around the x-axis
    D3DXMATRIX matRotationY;    // The matrix that rotates around the y-axis
    D3DXMATRIX matRotation;     // The matrix that rotates around the x and y-axis
    D3DXMATRIX matWorld;        // The world transformation matrix
    D3DXMATRIX matView;         // The view transformation matrix


	 D3DXMatrixRotationX(&matRotationX, D3DXToRadian(g_fAngleX));
    D3DXMatrixRotationY(&matRotationY, D3DXToRadian(g_fAngleY));
    D3DXMatrixMultiply(&matRotation, &matRotationY, &matRotationX);
    D3DXMatrixMultiply(&matView, &matView, &matRotation);

		 vecEyePoint    = D3DXVECTOR3(g_fPosX, g_fPosY, g_fPosZ);
    vecLookatPoint = D3DXVECTOR3(g_fPosX, g_fPosY, g_fPosZ + 0.1f);
    vecUp          = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
    D3DXMatrixLookAtLH(&matView, &vecEyePoint, &vecLookatPoint, &vecUp);
	 m_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);

//##########################################################
 D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/2.5, 1.25f, 1.0f, 2000.0f);
    m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
//##########################################################

//keyboard input is below

void CGame::ProcessKeyboard()
{

const float KEYBOARD_MOVING_SPEED   = 0.1f;
const float KEYBOARD_ROTATION_SPEED = 2.0f;

//###########################################################################
	#define KEYUP(rgbBuffer, dwOffset) !(rgbBuffer[dwOffset] & 0x80)
    #define KEYDOWN(rgbBuffer, dwOffset) (rgbBuffer[dwOffset] & 0x80)

//    BYTE rgbKeyboard[256];
 //   memset(rgbKeyboard, '\0', sizeof(rgbKeyboard));
	
//#########################################################################3
    BYTE KeyboardState[256]; 

  
    if(FAILED(m_pKeyboard->GetDeviceState(sizeof(KeyboardState),(LPVOID)&KeyboardState)))
    { 
		return; 
    } 
 
	if(KEYDOWN(KeyboardState, DIK_ESCAPE))
	{
        //Escape key pressed. Quit game.
		m_fQuit = true;
	}



//#########################################################################3
	    // Move forward
    if (KEYDOWN(KeyboardState, DIK_UP) || KEYDOWN(KeyboardState, DIK_W))
    {
        g_fPosX -= sinf(D3DXToRadian(g_fAngleY)) * KEYBOARD_MOVING_SPEED;
        g_fPosZ += cosf(D3DXToRadian(g_fAngleY)) * KEYBOARD_MOVING_SPEED;
    }

	 // Move back
    if (KEYDOWN(KeyboardState, DIK_DOWN) || KEYDOWN(KeyboardState, DIK_S))
    {
        g_fPosX += sinf(D3DXToRadian(g_fAngleY)) * KEYBOARD_MOVING_SPEED;
        g_fPosZ -= cosf(D3DXToRadian(g_fAngleY)) * KEYBOARD_MOVING_SPEED;
    }

    // Strafe left
    if (KEYDOWN(KeyboardState, DIK_A))
    {
        g_fPosX -= sinf(D3DXToRadian(g_fAngleY + 90.0f)) * KEYBOARD_MOVING_SPEED;
        g_fPosZ += cosf(D3DXToRadian(g_fAngleY + 90.0f)) * KEYBOARD_MOVING_SPEED;
    }

    // Strafe right
    if (KEYDOWN(KeyboardState, DIK_D))
    {
        g_fPosX -= sinf(D3DXToRadian(g_fAngleY - 90.0f)) * KEYBOARD_MOVING_SPEED;
        g_fPosZ += cosf(D3DXToRadian(g_fAngleY - 90.0f)) * KEYBOARD_MOVING_SPEED;
    }

    // Turn left
    if (KEYDOWN(KeyboardState, DIK_LEFT))
    {
        g_fAngleY += KEYBOARD_ROTATION_SPEED;

        if (g_fAngleY >= 360.0f)
        {
            g_fAngleY = g_fAngleY - 360.0f;
        }
    }

    // Turn right
    if (KEYDOWN(KeyboardState, DIK_RIGHT))
    {
        g_fAngleY -= KEYBOARD_ROTATION_SPEED;

        if (g_fAngleY < 0.0f)
        {
            g_fAngleY = 360.0f + g_fAngleY;
        }
    }
}

Advertisement
Try using this code:

void CCamera::Update(void){	this->m_cView._14 = this->m_cView._24 = this->           m_cView._34 = 0.0f;	this->m_cView._44 = 1.0f;	this->m_cView._11 = this->m_cRight.x;	this->m_cView._21 = this->m_cRight.y;	this->m_cView._31 = this->m_cRight.z;	this->m_cView._41 = - vec3_Dot(&this->m_cRight, &this         ->m_cPos);	this->m_cView._12 = this->m_cUp.x;	this->m_cView._22 = this->m_cUp.y;	this->m_cView._32 = this->m_cUp.z;	this->m_cView._42 = - vec3_Dot(&this->m_cUp, &this->           m_cPos);	this->m_cView._13 = this->m_cDir.x;	this->m_cView._23 = this->m_cDir.y;	this->m_cView._33 = this->m_cDir.z;	this->m_cView._43 = - vec3_Dot(&this->m_cDir, &this->          m_cPos);	return ;}void CCamera::RotRel(float fRotRelX, float fRotRelY){	Matrix4x4 cMatX, cMatY;	this->m_fRotX += fRotRelX;	this->m_fRotY += fRotRelY;	// Avoid overflow	if (this->m_fRotX > 2 * pi)		this->m_fRotX -= (2 * pi);	else		if (this->m_fRotX < - 2 * pi)			this->m_fRotX += (2 * pi);	if (this->m_fRotY > 2 * pi)		this->m_fRotY -= (2 * pi);	else		if (this->m_fRotY < - 2 * pi)			this->m_fRotY += (2 * pi);	this->m_cRight	= Vector3(1.0f, 0.0f, 0.0f);	this->m_cUp	= Vector3(0.0f, 1.0f, 0.0f);	this->m_cDir	= Vector3(0.0f, 0.0f, 1.0f);	m44_RotAxis(&cMatY, this->m_fRotY, &this->m_cUp);	vec3_TransfCoord(&this->m_cRight, &this->m_cRight,           &cMatY);	vec3_TransfCoord(&this->m_cDir, &this->m_cDir, &cMatY);	m44_RotAxis(&cMatX, this->m_fRotX, &this->m_cRight);	vec3_TransfCoord(&this->m_cUp, &this->m_cUp, &cMatX);	vec3_TransfCoord(&this->m_cDir, &this->m_cDir, &cMatX);            	vec3_Norm(&this->m_cDir, &this->m_cDir);	this->m_cRight = *vec3_Cross(&this->m_cRight, &this->           m_cUp, &this->m_cDir);	vec3_Norm(&this->m_cRight, &this->m_cRight);	this->m_cUp = *vec3_Cross(&this->m_cUp, &this->m_cDir,           &this->m_cRight);	vec3_Norm(&this->m_cUp, &this->m_cUp);	this->Update();	return ;}void CCamera::MoveRel(float fMoveRel){	this->m_cPos += (this->m_cDir * fMoveRel);	this->Update();	return ;}


If you want to use it, note the following:
- The camera has 4 vectors: Up, Right, Direction and Position
- I use my own matrix and vector functions / types. You must replace them by the according d3dx functions.
- The move function can only move in camera direction.
- Everytime the user presses the "move forward" key, you call MoveRel().
- Everytime the user presses a rotate key, you call RotRel()
- For any further questions please post.
thanks for your reply.........
im gonna try it out then.....
but i would like to fix the one that im using.......im not so sure bout urs but i'll give it a try......
the one im using doesnt update the camera when it rotates.......i still find myself looking at the same place......but i know the camera actually rotates because when i press left and try to move forward it move towards where the camera is facing but it doesnt LOOK at where it is facing.......i can move to where its facing but not look! it somehow doesnt update where im looking at it keeps looking at the same place where i started........if anyone has any idea's please help.......

anyway im gonna try the codes that u gave thanks a lot......

:( i cant seem to understand your codes Jensi its kinda complicating.....


can someone tell me why isnt my camera updating when i turn left or right?? the camera turns but it doesnt look at the direction it turns...... it keeps looking at the same place where it started........ im sure someone can help me.......

thanks
Are you creating a new matrix properley every time your camera moves or rotates?

The camera matrix is created using a line that looks similar to this

D3DXMatrixLookAtLH (&MatCamera, &CamPosition, &CameraLook, &CameraUp);

Where
-MatCamera is the matrix which is created.
-CamPosition is the new position of the camera.
-CamLook is the point the camera is looking at (you might not have done this right. It's not just the rotated vector but it's the rotated vec + the camera position)
-CameraUp is the up axis for the camera. This is often a "constant" of (0.0f, 1.0f, 0.0f)
I think your are not rotating because following code overwrite your rotating information.

D3DXMatrixLookAtLH(&matView, &vecEyePoint, &vecLookatPoint, &vecUp);

Try this:
D3DXMatrixLookAtLH(&matView, &vecEyePoint, &vecLookatPoint, &vecUp);
D3DXMatrixMultiply(&matView, &matView, &matRotation);
Ok, I could have this wrong, but it looks like you calculate your look at vector by adding 1 to the z direction of the position vector. This means that your camera will always be looking zward.
What you probably want to do is rotate the look at vector around the camera position.

In general I like to use an AffineTransform (D3DXMatrixAffineTransformation - which allows you to specify a rotation as a quaternion and a center point to rotate around) to generate a matrix and tne TransformCoordinate (D3DXVec3TransformCoord) to transform my verts. There are probably much simpler ways.

You could also generate the position of the lookat using the trig functions.

Either way you have to do more than add 1 to z to get a rotation.

Hope this helps.

I think I can put this in more basic language for you. When you us a LookAt matrix, you have to define the point that you're looking at...which means when you strafe, you have to continuosly calculate the point directly in front of you. If you strafe but you're always looking at the same point, then you're getting two seperate camera movements, strafing to the side and then rotating back to the center. There are other ways to create a camera matrix.

This may be useful to you...viewmatrix.m[3] defines the view position. Try incrementing or decrementing cameramatrix.m[3][0] to strafe left and right. This way you can move your camera without calcutating a lookat point every time.

If you're using the D3DX framework, the Camera class needs a lot of work. As is, it will only generate a view matrix with a lookat point. You have to get the view matrix and then change it as described above.
you should checkout the fps camera tut at Game Tutorials for DirectX 9. they include full source code. It works really well. I used it as a base until I figured out how fps cameras work and gradually replaced the math functions,etc with my own.

Looking at your source the lookat looks strange. it is supposed to be forward vector + world location of the camera. the up vector is 0,1,0 (since y+ is up) - in which you have right. forward could be 0,0,1 initially.

Good luck man.
wow!! thanks so much for your replies............
im gonna try out wat u guys said..........

i'll msg soon once i figure this out! :)

thanks again!

This topic is closed to new replies.

Advertisement