Sign in to follow this  
stereotypical

camera rotation killing me!?

Recommended Posts

stereotypical    127
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;
        }
    }
}

Share this post


Link to post
Share on other sites
JensE    122
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.

Share this post


Link to post
Share on other sites
stereotypical    127
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......

Share this post


Link to post
Share on other sites
stereotypical    127
:( 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

Share this post


Link to post
Share on other sites
de_matt    181
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)

Share this post


Link to post
Share on other sites
s8472    122
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);

Share this post


Link to post
Share on other sites
turnpast    1011
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.

Share this post


Link to post
Share on other sites
danromeo    238
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.

Share this post


Link to post
Share on other sites
vajuras    139
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this