Skip to main content
GameDev.net gamedev.net
🔒 Locked

wierd FP camera

Started by TheUmpteenth Jun 18, 2007 at 9:23 AM 3 replies 600+ views
Original Post
TheUmpteenth
TheUmpteenth
having some problems with a first person camera. managed this quite nicely in openGL, but messing around with DirectX now, and i'm getting wierd results. When I point my camera above a certian elevation, it flips, rather than stopping, and after that, my movement goes skew whiff. also, I don't move along the view vector, but on a flat plane. very wierd. also, I don't know how to put code into boxes for the forum, so if you could tell me that, it'd help... here's some of my camera class, if it helps you void cCamera::SetViewByMouse() { D3DXVECTOR3 Moved=m_diControl.CheckForMouseMove(); D3DXMATRIX matRotation; //if no movement occurred, exit function if (Moved==D3DXVECTOR3(0,0,0)) return; else { int nXDiff = (Moved.x); int nYDiff = (Moved.y); if( nYDiff != 0 ) { D3DXMatrixRotationAxis( &matRotation, &m_vRight, D3DXToRadian((float)nYDiff / 3.0f)); D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation ); D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation ); } if( nXDiff != 0 ) { D3DXMatrixRotationAxis( &matRotation, &m_vUpVector, D3DXToRadian((float)nXDiff / 3.0f) ); D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation ); D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation ); } } } void cCamera::MoveCamera(float speed) { // Add the strafe vector to our position m_vEyePos.x += m_vTargetPos.x * speed; m_vEyePos.z += m_vTargetPos.z * speed; } void cCamera::StrafeCamera(float speed) { // Add the strafe vector to our position m_vEyePos.x += m_vRight.x * speed; m_vEyePos.z += m_vRight.z * speed; } void cCamera::Update(LPDIRECT3DDEVICE9 p_dx_Device, float fTime) { // Initialize a variable for the cross product result D3DXVECTOR3 vCross = Cross(m_vTargetPos - m_vEyePos, m_vUpVector); // Normalize the strafe vector m_vRight = Normalize(vCross); // Move the camera's view by the mouse SetViewByMouse(); // This checks to see if the keyboard was pressed CheckForMovement(fTime); D3DXMatrixLookAtLH(&m_mView, &m_vEyePos, &m_vTargetPos, &m_vUpVector); //this is truly gammy // UpdateViewMatrix(p_dx_Device); //this function works better -? } void cCamera::UpdateViewMatrix(LPDIRECT3DDEVICE9 p_dx_Device) { D3DXMatrixIdentity( &m_mView ); D3DXVec3Normalize( &m_vTargetPos, &m_vTargetPos ); D3DXVec3Cross( &m_vRight, &m_vUpVector, &m_vTargetPos ); D3DXVec3Normalize( &m_vRight, &m_vRight ); D3DXVec3Cross( &m_vUpVector, &m_vTargetPos, &m_vRight ); D3DXVec3Normalize( &m_vUpVector, &m_vUpVector ); m_mView._11 = m_vRight.x; m_mView._12 = m_vUpVector.x; m_mView._13 = m_vTargetPos.x; m_mView._14 = 0.0f; m_mView._21 = m_vRight.y; m_mView._22 = m_vUpVector.y; m_mView._23 = m_vTargetPos.y; m_mView._24 = 0.0f; m_mView._31 = m_vRight.z; m_mView._32 = m_vUpVector.z; m_mView._33 = m_vTargetPos.z; m_mView._34 = 0.0f; m_mView._41 = -D3DXVec3Dot( &m_vEyePos, &m_vRight ); m_mView._42 = -D3DXVec3Dot( &m_vEyePos, &m_vUpVector ); m_mView._43 = -D3DXVec3Dot( &m_vEyePos, &m_vTargetPos ); m_mView._44 = 1.0f; p_dx_Device->SetTransform( D3DTS_VIEW, &m_mView ); }
Chad Smith
Chad Smith
here it is in the box:

void cCamera::SetViewByMouse(){D3DXVECTOR3 Moved=m_diControl.CheckForMouseMove();D3DXMATRIX matRotation;//if no movement occurred, exit functionif (Moved==D3DXVECTOR3(0,0,0))return;else{int nXDiff = (Moved.x);int nYDiff = (Moved.y);if( nYDiff != 0 ){D3DXMatrixRotationAxis( &matRotation, &m_vRight, D3DXToRadian((float)nYDiff / 3.0f));D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation );D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation );}if( nXDiff != 0 ){D3DXMatrixRotationAxis( &matRotation, &m_vUpVector, D3DXToRadian((float)nXDiff / 3.0f) );D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation );D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation );}}}void cCamera::MoveCamera(float speed){// Add the strafe vector to our positionm_vEyePos.x += m_vTargetPos.x * speed;m_vEyePos.z += m_vTargetPos.z * speed;}void cCamera::StrafeCamera(float speed){// Add the strafe vector to our positionm_vEyePos.x += m_vRight.x * speed;m_vEyePos.z += m_vRight.z * speed;}void cCamera::Update(LPDIRECT3DDEVICE9 p_dx_Device, float fTime){// Initialize a variable for the cross product resultD3DXVECTOR3 vCross = Cross(m_vTargetPos - m_vEyePos, m_vUpVector);// Normalize the strafe vectorm_vRight = Normalize(vCross);// Move the camera's view by the mouseSetViewByMouse();// This checks to see if the keyboard was pressedCheckForMovement(fTime);D3DXMatrixLookAtLH(&m_mView, &m_vEyePos, &m_vTargetPos, &m_vUpVector); //this is truly gammy// UpdateViewMatrix(p_dx_Device); //this function works better -?}void cCamera::UpdateViewMatrix(LPDIRECT3DDEVICE9 p_dx_Device){D3DXMatrixIdentity( &m_mView );D3DXVec3Normalize( &m_vTargetPos, &m_vTargetPos );D3DXVec3Cross( &m_vRight, &m_vUpVector, &m_vTargetPos );D3DXVec3Normalize( &m_vRight, &m_vRight );D3DXVec3Cross( &m_vUpVector, &m_vTargetPos, &m_vRight );D3DXVec3Normalize( &m_vUpVector, &m_vUpVector );m_mView._11 = m_vRight.x;m_mView._12 = m_vUpVector.x;m_mView._13 = m_vTargetPos.x;m_mView._14 = 0.0f;m_mView._21 = m_vRight.y;m_mView._22 = m_vUpVector.y;m_mView._23 = m_vTargetPos.y;m_mView._24 = 0.0f;m_mView._31 = m_vRight.z;m_mView._32 = m_vUpVector.z;m_mView._33 = m_vTargetPos.z;m_mView._34 = 0.0f;m_mView._41 = -D3DXVec3Dot( &m_vEyePos, &m_vRight );m_mView._42 = -D3DXVec3Dot( &m_vEyePos, &m_vUpVector );m_mView._43 = -D3DXVec3Dot( &m_vEyePos, &m_vTargetPos );m_mView._44 = 1.0f;p_dx_Device->SetTransform( D3DTS_VIEW, &m_mView );}


To do that then just put your code between [ source] and [/ source] tags, but without the spaces.

TheUmpteenth
TheUmpteenth
thanks for that, Chad. still can't find the camera problem though. ;)
TheUmpteenth
TheUmpteenth
done a little more work on the code, but I'm still having camera problems. It seems tha now I have a pivot in my elevation axis (Y) so that when i rotate the camera up/down it rotates around this axis. This would be perfect, except that the axis doesnt rotate left/right when I do.

It's strange, as far as I can see it would either be the up vector or the right vector which isn't moving, but I've got a feeling that is the lookat vector (represented as m_vTargetPos).

HELP!

update view matrix
void cCamera::UpdateViewMatrix(LPDIRECT3DDEVICE9 p_dx_Device){	D3DXMatrixIdentity( &m_mView );	D3DXVec3Normalize( &m_vTargetPos, &m_vTargetPos );	D3DXVec3Cross( &m_vRight, &m_vUpVector, &m_vTargetPos );	D3DXVec3Normalize( &m_vRight, &m_vRight );	D3DXVec3Cross( &m_vUpVector, &m_vTargetPos, &m_vRight );	D3DXVec3Normalize( &m_vUpVector, &m_vUpVector );	m_mView._11 = m_vRight.x;	m_mView._12 = m_vUpVector.x;	m_mView._13 = m_vTargetPos.x;	m_mView._14 = 0.0f;	m_mView._21 = m_vRight.y;	m_mView._22 = m_vUpVector.y;	m_mView._23 = m_vTargetPos.y;	m_mView._24 = 0.0f;	m_mView._31 = m_vRight.z;	m_mView._32 = m_vUpVector.z;	m_mView._33 = m_vTargetPos.z;	m_mView._34 = 0.0f;	m_mView._41 = -D3DXVec3Dot( &m_vEyePos, &m_vRight );	m_mView._42 = -D3DXVec3Dot( &m_vEyePos, &m_vUpVector );	m_mView._43 = -D3DXVec3Dot( &m_vEyePos, &m_vTargetPos );	m_mView._44 =  1.0f;	p_dx_Device->SetTransform( D3DTS_VIEW, &m_mView ); }


set view by mouse
void cCamera::SetViewByMouse(){	D3DXVECTOR3 Moved=m_diControl.CheckForMouseMove();	D3DXMATRIX matRotation;	//if no movement occurred, exit function	if (Moved==D3DXVECTOR3(0,0,0))		return;	else	{		int nXDiff = (Moved.x);		int nYDiff = (Moved.y);		if( nYDiff != 0 || nXDiff != 0 )		{			D3DXMatrixRotationYawPitchRoll(&matRotation, D3DXToRadian((float)nXDiff / 3.0f), 										D3DXToRadian((float)nYDiff / 3.0f),	0);			D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation );			D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation );			D3DXVec3TransformCoord( &m_vRight, &m_vRight, &matRotation );		}	}}
TheUmpteenth
TheUmpteenth
for anyone watching this thread, I got it to work properly.

heres the fixed code

void cCamera::UpdateViewMatrix(LPDIRECT3DDEVICE9 p_dx_Device){	D3DXMatrixIdentity( &m_mView );	D3DXVec3Normalize( &m_vTargetPos, &m_vTargetPos );	D3DXVec3Cross( &m_vRight, &m_vUpVector, &m_vTargetPos );	D3DXVec3Normalize( &m_vRight, &m_vRight );	D3DXVec3Cross( &m_vUpVector, &m_vTargetPos, &m_vRight );	D3DXVec3Normalize( &m_vUpVector, &m_vUpVector );	m_mView._11 = m_vRight.x;	m_mView._12 = m_vUpVector.x;	m_mView._13 = m_vTargetPos.x;	m_mView._14 = 0.0f;	m_mView._21 = m_vRight.y;	m_mView._22 = m_vUpVector.y;	m_mView._23 = m_vTargetPos.y;	m_mView._24 = 0.0f;	m_mView._31 = m_vRight.z;	m_mView._32 = m_vUpVector.z;	m_mView._33 = m_vTargetPos.z;	m_mView._34 = 0.0f;	m_mView._41 = D3DXVec3Dot( &m_vEyePos, &m_vRight );	m_mView._42 = D3DXVec3Dot( &m_vEyePos, &m_vUpVector );	m_mView._43 = D3DXVec3Dot( &m_vEyePos, &m_vTargetPos );	m_mView._44 =  1.0f;	p_dx_Device->SetTransform( D3DTS_VIEW, &m_mView ); 	m_vUpVector=D3DXVECTOR3(0,1,0);}


&&

void cCamera::SetViewByMouse(){	D3DXVECTOR3 Moved=m_diControl.CheckForMouseMove();	D3DXMATRIX matRotation;	//if no movement occurred, exit function	if (Moved==D3DXVECTOR3(0,0,0))		return;	else	{		int nXDiff = (Moved.x);		int nYDiff = (Moved.y);		if( nXDiff != 0 )		{			D3DXMatrixRotationAxis(&matRotation, &m_vUpVector, D3DXToRadian((float)nXDiff / 3.0f));			D3DXVec3TransformCoord( &m_vRight, &m_vRight, &matRotation );			//D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation );			D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation );		}		if( nYDiff != 0 )		{			D3DXMatrixRotationAxis(&matRotation, &m_vRight, D3DXToRadian((float)nYDiff / 3.0f));			//D3DXVec3TransformCoord( &m_vRight, &m_vRight, &matRotation );			D3DXVec3TransformCoord( &m_vUpVector, &m_vUpVector, &matRotation );			D3DXVec3TransformCoord( &m_vTargetPos, &m_vTargetPos, &matRotation );		}	}}


(Y rotation only effects R and L vectors, X rotation only effects U and L vectors, no one single rotation)
Also reset U vector at each iteration, although this is dodgy in my mind.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.