//////////////////////////////////////////////////////////////////////////// // Camera.cpp // // // // Michael Silverman, 2011 // // Dstributed under the Boost Software Licence, Version 1.0. // // http://www.boost.org/LICENSE_1_0.txt // // http://silverwaregames.com/LICENSE_1_0.txt // // // //////////////////////////////////////////////////////////////////////////// #include "Camera.h" Camera CAMERA; // singleton definition Camera::Camera( bool bFilter /*= true */ ) { m_fFilterAlpha = .1f; m_bFilter = bFilter; m_v3Position = m_v3FilteredPosition = D3DXVECTOR3( 0, 0, 0 ); D3DXQuaternionIdentity( &m_qRotation ); m_qFilteredRotation = m_qRotation; } void Camera::RotYaw( float fTheta ) { D3DXVECTOR3 v3Up( 0.0f, 1.0f, 0.0f ); D3DXQUATERNION qRot; D3DXQuaternionRotationAxis( &qRot, &v3Up, -fTheta ); D3DXQuaternionMultiply( &m_qRotation, &qRot, &m_qRotation ); } void Camera::RotPitch( float fTheta ) { D3DXVECTOR3 v3Right( 1.0f, 0.0f, 0.0f ); D3DXQUATERNION qRot; D3DXQuaternionRotationAxis( &qRot, &v3Right, fTheta ); D3DXQuaternionMultiply( &m_qRotation, &m_qRotation, &qRot ); } void Camera::SetYawPitchRoll( float fYaw, float fPitch, float fRoll ) { D3DXQuaternionRotationYawPitchRoll( &m_qRotation, fYaw, fPitch, fRoll ); } void Camera::SetAxis( const D3DXVECTOR3 &v3LookAt, const D3DXVECTOR3 &v3Up, const D3DXVECTOR3 &v3Right ) { D3DXMATRIX mRotation; D3DXMatrixIdentity( &mRotation ); mRotation(0,0) = v3Right.x; mRotation(0,1) = v3Up.x; mRotation(0,2) = v3LookAt.x; mRotation(1,0) = v3Right.y; mRotation(1,1) = v3Up.y; mRotation(1,2) = v3LookAt.y; mRotation(2,0) = v3Right.z; mRotation(2,1) = v3Up.z; mRotation(2,2) = v3LookAt.z; D3DXQuaternionRotationMatrix( &m_qRotation, &mRotation ); } void Camera::SetRotation( const D3DXQUATERNION &qRotation ) { m_qRotation = qRotation; } void Camera::SetFocalPoint( const D3DXVECTOR3 &v3FocalPoint, const D3DXVECTOR3 &v3Up /*= D3DXVECTOR3(0,1,0) */ ) { SetFocalPointAndPosition( v3FocalPoint, m_v3Position, v3Up ); } void Camera::SetFocalPointAndPosition( const D3DXVECTOR3 &v3FocalPoint, const D3DXVECTOR3 &v3Position, const D3DXVECTOR3 &v3UpVec /*= D3DXVECTOR3(0,1,0) */ ) { m_v3Position = v3Position; D3DXVECTOR3 v3Up, v3Right, v3LookAt = v3FocalPoint - m_v3Position; D3DXVec3Normalize( &v3LookAt, &v3LookAt ); D3DXVec3Cross( &v3Right, &v3UpVec, &v3LookAt ); D3DXVec3Normalize( &v3Right, &v3Right ); D3DXVec3Cross( &v3Up, &v3LookAt, &v3Right ); D3DXVec3Normalize( &v3Up, &v3Up ); SetAxis( v3LookAt, v3Up, v3Right ); } void Camera::SetPosition( const D3DXVECTOR3 &v3Position ) { m_v3Position = v3Position; } void Camera::MoveCamera( const D3DXVECTOR3 &v3Delta ) { m_v3Position += v3Delta; } D3DXVECTOR3 Camera::GetPosition( ) { return m_v3Position; } D3DXVECTOR3 Camera::GetLookAt( ) { D3DXMATRIX mRot; D3DXMatrixRotationQuaternion( &mRot, &m_qRotation ); return D3DXVECTOR3( mRot(0,2), mRot(1,2), mRot(2,2) ); } D3DXVECTOR3 Camera::GetRight( ) { D3DXMATRIX mRot; D3DXMatrixRotationQuaternion( &mRot, &m_qRotation ); return D3DXVECTOR3( mRot(0,0), mRot(1,0), mRot(2,0) ); } D3DXVECTOR3 Camera::GetUp( ) { D3DXMATRIX mRot; D3DXMatrixRotationQuaternion( &mRot, &m_qRotation ); return D3DXVECTOR3( mRot(0,1), mRot(1,1), mRot(2,1) ); } D3DXVECTOR3 Camera::GetRayCastDirection( ) { float fXPercent = GetMouseX( ) / (float)GetWindowWidth( ); float fYPercent = GetMouseY( ) / (float)GetWindowHeight( ); fXPercent -= .5f; fYPercent -= .5f; fXPercent *= 2.0f; fYPercent *= 2.0f; float fScreenAspect = (float)GetWindowWidth( ) / (float)GetWindowHeight( ); float fTanFOV = tan( ( D3DX_PI / 4.0f ) / 2.0f ); float fRightLength = fTanFOV * fXPercent * fScreenAspect; float fUpLength = -fTanFOV * fYPercent; D3DXVECTOR3 v3LookAt, v3Up, v3Right; v3LookAt = GetLookAt( ); v3Up = GetUp( ); v3Right = GetRight( ); D3DXVECTOR3 v3Result = v3LookAt + fRightLength * v3Right + fUpLength * v3Up; D3DXVec3Normalize( &v3Result, &v3Result ); return v3Result; } D3DXMATRIX Camera::GetViewMatrix( ) { D3DXMATRIX mViewMatrix, mTranslation; D3DXVECTOR3 v3Position; D3DXQUATERNION qRotation; D3DXMatrixIdentity( &mViewMatrix ); D3DXMatrixIdentity( &mTranslation ); if( m_bFilter ) { v3Position = m_v3FilteredPosition; qRotation = m_qFilteredRotation; } else { v3Position = m_v3Position; qRotation = m_qRotation; } D3DXMatrixRotationQuaternion( &mViewMatrix, &qRotation ); D3DXMatrixTranslation( &mTranslation, -v3Position.x, -v3Position.y, -v3Position.z ); D3DXMatrixMultiply( &mViewMatrix, &mTranslation, &mViewMatrix ); return mViewMatrix; } void Camera::PrepareForRender() { if( GetRenderDevice( ) ) { GetRenderDevice( )->SetTransform( D3DTS_VIEW, &GetViewMatrix( ) ); // TODO: You may want to pass the view matrix to shaders and other effectx. } } void Camera::Init( ) { SetFocalPointAndPosition( D3DXVECTOR3( 0, 0.0f, 0.0 ), D3DXVECTOR3( 0.0f, 0.0f, -20.0f ) ); if( m_bFilter ) { m_qFilteredRotation = m_qRotation; m_v3FilteredPosition = m_v3Position; }; } void Camera::Update() { if( IsKeyDown('A') ) { D3DXVECTOR3 v3Move = -GetRight(); v3Move *= GetSecFromLastFrame( ) * 10.0f; MoveCamera( v3Move ); } if( IsKeyDown('D') ) { D3DXVECTOR3 v3Move = GetRight(); v3Move *= GetSecFromLastFrame( ) * 10.0f; MoveCamera( v3Move ); } if( IsKeyDown('R') ) { D3DXVECTOR3 v3Move = GetUp(); v3Move *= GetSecFromLastFrame( ) * 10.0f; MoveCamera( v3Move ); } if( IsKeyDown('F') ) { D3DXVECTOR3 v3Move = -GetUp(); v3Move *= GetSecFromLastFrame( ) * 10.0f; MoveCamera( v3Move ); } if( IsKeyDown('W') ) { D3DXVECTOR3 v3Move = GetLookAt(); v3Move *= GetSecFromLastFrame( ) * 10.0f; MoveCamera( v3Move ); } if( IsKeyDown('S') ) { D3DXVECTOR3 v3Move = -GetLookAt(); v3Move *= GetSecFromLastFrame( ) * 10.0f; MoveCamera( v3Move ); } if( IsKeyDown(VK_LEFT) ) { RotYaw( -GetSecFromLastFrame( ) ); } if( IsKeyDown(VK_RIGHT) ) { RotYaw( GetSecFromLastFrame( ) ); } if( IsKeyDown(VK_UP) ) { RotPitch( GetSecFromLastFrame( ) ); } if( IsKeyDown(VK_DOWN) ) { RotPitch( -GetSecFromLastFrame( ) ); } // TODO: Implement your own camera logic here. The camera is currently set up as a WSAD movement with arrow keys as rotation. if( m_bFilter ) { // Compute exponential moving average and store it in the filtered members. D3DXVec3Lerp( &m_v3FilteredPosition, &m_v3FilteredPosition, &m_v3Position, m_fFilterAlpha ); D3DXQuaternionSlerp( &m_qFilteredRotation, &m_qFilteredRotation, &m_qRotation, m_fFilterAlpha ); } } void Camera::SetFiltering( bool bFilter ) { m_bFilter = bFilter; if( m_bFilter ) { m_qFilteredRotation = m_qRotation; m_v3FilteredPosition = m_v3Position; }; }