Sign in to follow this  
ThatHippieFromBethlehem

help implementing a limit view to avoid upside down

Recommended Posts

Hi, I've been messing around with this and I can't seem to wrap my head around it.

 

I want to set and angle limit of 90 and -90 degrees to avoid upside down view. Any ideas on how I should go about?


#include "Camera.h"

Camera* gCamera = 0;

Camera::Camera()

{

D3DXMatrixIdentity(&m_matView);

D3DXMatrixIdentity(&m_matProj);

m_vEyePoint = D3DXVECTOR3(0.0f, 0.0f, 0.0f);

m_vRight = D3DXVECTOR3(1.0f, 0.0f, 0.0f);

m_vUp = D3DXVECTOR3(0.0f, 1.0f, 0.0f);

m_vForward = D3DXVECTOR3(0.0f, 0.0f, 1.0f);


mSpeed = 0.2f;

mDXInput = new DXInput() ;

}

const



D3DXMATRIX& Camera::GetViewMatrix() const

{



return m_matView;

}

const



D3DXMATRIX& Camera::GetProjMatrix() const

{



return m_matProj;

}

void



Camera::SetViewParams(D3DXVECTOR3& pos, D3DXVECTOR3& target, D3DXVECTOR3& up)

{



D3DXVECTOR3 L = target - pos;

D3DXVec3Normalize(&L, &L);

D3DXVECTOR3 R;

D3DXVec3Cross(&R, &up, &L);

D3DXVec3Normalize(&R, &R);

D3DXVECTOR3 U;

D3DXVec3Cross(&U, &L, &R);

D3DXVec3Normalize(&U, &U);

m_vEyePoint = pos;

m_vRight = R;

m_vUp = U;

m_vForward = L;

BuildViewMatrix();

}

void



Camera::SetProjParams(float fov, float aspect, float nearZ, float farZ)

{

D3DXMatrixPerspectiveFovLH(&m_matProj, fov, aspect, nearZ, farZ);

}

void



Camera::Update(float dt, float offsetHeight)

{

mDXInput->Update() ;


D3DXVECTOR3 dir(0.0f, 0.0f, 0.0f);



if( mDXInput->KeyDown(DIK_W) )

dir += m_vForward;



if( mDXInput->KeyDown(DIK_S) )

dir -= m_vForward;



if( mDXInput->KeyDown(DIK_D) )

dir += m_vRight;



if( mDXInput->KeyDown(DIK_A) )

dir -= m_vRight;



D3DXVec3Normalize(&dir, &dir);

D3DXVECTOR3 newPos = m_vEyePoint + dir * mSpeed * dt;


m_vEyePoint = newPos ;



if (m_vEyePoint.y < 2.0f)

{

m_vEyePoint.y = 2.0f ;

}



if (m_vEyePoint.y > 2.0f)

{

m_vEyePoint.y = 2.0f ;

}


float pitch = mDXInput->MouseDY() / 360.0f;

float yAngle = mDXInput->MouseDX() / 360.0f;


D3DXMATRIX R;

D3DXMatrixRotationAxis(&R, &m_vRight, pitch);

D3DXVec3TransformCoord(&m_vForward, &m_vForward, &R);

D3DXVec3TransformCoord(&m_vUp, &m_vUp, &R);


D3DXMatrixRotationY(&R, yAngle);

D3DXVec3TransformCoord(&m_vRight, &m_vRight, &R);

D3DXVec3TransformCoord(&m_vForward, &m_vForward, &R);


BuildViewMatrix();

}

void



Camera::BuildViewMatrix()

{


D3DXVec3Normalize(&m_vForward, &m_vForward);

D3DXVec3Cross(&m_vUp, &m_vForward, &m_vRight);

D3DXVec3Normalize(&m_vUp, &m_vUp);

D3DXVec3Cross(&m_vRight, &m_vUp, &m_vForward);

D3DXVec3Normalize(&m_vRight, &m_vRight);


float x = -D3DXVec3Dot(&m_vEyePoint, &m_vRight);



float y = -D3DXVec3Dot(&m_vEyePoint, &m_vUp);



float z = -D3DXVec3Dot(&m_vEyePoint, &m_vForward);

m_matView(0,0) = m_vRight.x;

m_matView(1,0) = m_vRight.y;

m_matView(2,0) = m_vRight.z;

m_matView(3,0) = x;

m_matView(0,1) = m_vUp.x;

m_matView(1,1) = m_vUp.y;

m_matView(2,1) = m_vUp.z;

m_matView(3,1) = y;

m_matView(0,2) = m_vForward.x;

m_matView(1,2) = m_vForward.y;

m_matView(2,2) = m_vForward.z;

m_matView(3,2) = z;

m_matView(0,3) = 0.0f;

m_matView(1,3) = 0.0f;

m_matView(2,3) = 0.0f;

m_matView(3,3) = 1.0f;

}

const



D3DXVECTOR3 Camera::GetLookAt() const

{



return m_vForward ;

}

const



D3DXVECTOR3 Camera::GetEyePoint() const

{



return m_vEyePoint ;

}

const



D3DXVECTOR3 Camera::GetUpVector() const

{



return m_vUp ;

}

Edited by ThatHippieFromBethlehem

Share this post


Link to post
Share on other sites
JordanBonser    839

This is a pretty simplistic method but it seems to work. You could store the accumulated pitch whenever you get it from the DXInput, and then check before applying the pitch whether the new value will be more than your pre-defined min and max values (i.e. -90.0, 90.0 ).  

Share this post


Link to post
Share on other sites

Hi JB,

 

Can you check my logic?

float Max = 90.0f;
float Min = -90.0f;
float pitch  = mDXInput->MouseDY() / 360;
float patch; //So I should store pitch value here?

if (pitch == Max || pitch == Min )
	{
        //block mouse? /ignore input till check passes /don't update view if input from mouse is higher than 90 or lower than -90?
        }
else
	{
        //Keep going?
	}



Share this post


Link to post
Share on other sites
JordanBonser    839
 
you would want to store the pitch value as a member variable for your camera class, or somewhere that it will persist through the lifetime of your camera. 
 

For the check you would want to add the current pitch and the pitch value from DXInput and compare that to your min and max.

 

something along those lines (PseudoCode):  

float mousePitch = mDXInput->MouseDY() / 360.0
float newPitch = mousePitch + mStoredPitch;

if( newPitch <= Max || newPitch >= Min )
{
   mStoredPitch = newPitch;
   //Perform the operations to alter the cameras pitch.
} 

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