⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game_camera.cpp

📁 我做的毕业设计
💻 CPP
字号:
#include "Game_User.h"
CCamera::CCamera(LPDIRECT3DDEVICE9 pDevice, LPD3DXVECTOR3 pos)
{	
	m_bTrackMode	= FALSE;
	m_pDevice		= pDevice;
	m_Yaw			= 0;
	m_Pitch			= 0;
	m_vPos			= *pos;
	m_Distance		= 200;
	m_pCursor		= NULL;

	//计算屏幕宽度,高度
	D3DSURFACE_DESC   m_d3dsdBackBuffer; 
	LPDIRECT3DSURFACE9 pBackBuffer = NULL;
	//从设备交换链中取得后台缓冲
	m_pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
	//取得表面的信息
	pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
	m_scrWidth = (float)m_d3dsdBackBuffer.Width;
	m_scrHeight = (float)m_d3dsdBackBuffer.Height; 
}

CCamera::~CCamera()
{
  // SAFE_RELEASE(m_pKeyFrameInterpolator);
   m_pDevice = NULL;
}
//更新3D变换矩阵
void CCamera::Update3DMatrix(float timeNow)
{	
	if(m_bTrackMode) UpdateFromTracked(timeNow);
	D3DXMATRIX matView;
	D3DXVECTOR3 vLookAt;
	GetLookAt(&vLookAt);//获得观察点坐标
	D3DXMatrixLookAtLH(&matView,&m_vPos,&vLookAt,&D3DXVECTOR3(0,1,0));
	m_pDevice->SetTransform(D3DTS_VIEW,&matView);
	m_matView = matView;
	D3DXMATRIX matProjection;
	D3DXMatrixPerspectiveFovLH(&matProjection,D3DX_PI/4,1.0,1.0f,12000.0f);
	m_pDevice->SetTransform(D3DTS_PROJECTION,&matProjection);
	m_matProjection = matProjection;
	m_pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
}

//更新2D变换矩阵
//使用屏幕坐标系(0,0)~(1,1);
void CCamera::Update2DMatrix()
{
//	RECT rect;
//	m_pDevice->GetScissorRect(&rect);
	D3DXMATRIX matOrtho;	
	D3DXMATRIX matIdentity;
//	D3DVIEWPORT9 viewPort;
	//Retrieves the viewport parameters currently set for the device.
//	m_pDevice->GetViewport(&viewPort);

	//设置正交投影矩阵
	//m_pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); 
	D3DXMatrixOrthoLH(&matOrtho,m_scrWidth ,m_scrHeight, 0.0f, 1000.0f);
	D3DXMatrixIdentity(&matIdentity);
	
	m_pDevice->SetTransform(D3DTS_PROJECTION, &matOrtho);
	m_pDevice->SetTransform(D3DTS_WORLD, &matIdentity);	//WORDTRANS留给各个渲染对象使用
    m_pDevice->SetTransform(D3DTS_VIEW, &matIdentity);

}

void CCamera::SetYawPitch(float yaw,float pitch)
{
	m_Yaw = yaw;
	m_Pitch = pitch;
}

//摄像机绕着观察点旋转,上下偏转
void CCamera::YawPitchAt(float yaw,float pitch)
{
	//沿着观察点变化
	D3DXVECTOR3 vLookAt;
	GetLookAt(&vLookAt);	//先保存变换前的焦点坐标

	m_Yaw+=yaw;											//改变偏位角度
	if(m_Pitch-pitch<D3DX_PI/3.0f&& m_Pitch-pitch>-D3DX_PI/2.0f)
		//改变仰角
		m_Pitch-=pitch;
	//跟SetLookAt()做的一样操作
	m_vPos.x=vLookAt.x-m_Distance*cosf(m_Pitch)*sinf(m_Yaw);	//更新摄像机坐标
	m_vPos.y=vLookAt.y-m_Distance*sinf(m_Pitch);				//更新摄像机坐标
	m_vPos.z=vLookAt.z-m_Distance*cosf(m_Pitch)*cosf(m_Yaw);	

}		//水平方向角度,仰角

//沿着观察点变换方位
void CCamera::YawPitchPos(float yaw,float pitch)
{	
	m_Yaw += yaw;
	if(m_Pitch+pitch > D3DX_PI*0.49f)	
	{ 
		m_Pitch = D3DX_PI*0.49f; 
		return;
	}
	if(m_Pitch+pitch < -D3DX_PI*0.49f) 
	{ 
		m_Pitch = -D3DX_PI*0.49f; 
		return;
	}
	m_Pitch += pitch;
};

//移动,向前/侧向移动,主要用于自由摄像机
void CCamera::MoveRelative(float dSide,float dForward)
{
	D3DXVECTOR3 vDir;//方向向量(单位向量)
	D3DXVECTOR3 vSide;//right向量
	vDir.x=cosf(m_Pitch)*sinf(m_Yaw);
	vDir.y=sinf(m_Pitch);
	vDir.z=cosf(m_Pitch)*cosf(m_Yaw);

	D3DXVec3Cross(&vSide,&D3DXVECTOR3(0,1,0),&vDir);

	if(m_Distance-dForward >0)
	{
		m_Distance += dForward; 
		m_vPos += vDir*dForward + vSide*dSide;
	}
}

void CCamera::AimTo(D3DVECTOR *pLookAt)
{
	D3DVECTOR vDir;
	vDir.x=pLookAt->x-m_vPos.x;
	vDir.y=pLookAt->y-m_vPos.y;
	vDir.z=pLookAt->z-m_vPos.z;
	D3DXVec3Normalize((D3DXVECTOR3*)&vDir,(D3DXVECTOR3*)&vDir);
	m_Pitch=acos(vDir.y);
	if(vDir.z!=0 )	
		m_Yaw=atan(vDir.z/vDir.x); 
	else 
		m_Yaw=D3DX_PI/2;
}

void CCamera::AddRotationKey(float time,float yaw,float pitch)
{	
	D3DXQUATERNION qX(-sin(pitch/2), 0, 0,cos(pitch/2));
	D3DXQUATERNION qY(0,sin(yaw/2), 0, cos(yaw/2));
	D3DXKEY_QUATERNION qKey={time,qX*qY};
}

void CCamera::AddRotationKey(float time,const D3DXQUATERNION  &vRotation)
{
	D3DXKEY_QUATERNION keyV;
	keyV.Time=time;
	keyV.Value=vRotation; 

}

HRESULT CCamera::UpdateFromTracked(float Time)
{	//从轨迹更新摄象机坐标和方向
	D3DXQUATERNION  R;
	D3DXVECTOR3		T;
	
	R.x=-R.x;		//GetSRT Bug? 这里可能有问题
	R.y=-R.y;
	R.z=-R.z;

	m_vPos=T;  

	D3DVECTOR zAixes={	2*R.x*R.z+2*R.y*R.w,
						2*R.y*R.z-2*R.x*R.w,
						1-(2*R.x*R.x+2*R.y*R.y)};

	m_Yaw=atan2(zAixes.x,zAixes.z);
	m_Pitch=asinf(zAixes.y);

	return S_OK;
}

void CCamera::GetRayOrigDir(D3DXVECTOR3* vPickRayOrig, D3DXVECTOR3* vPickRayDir, CTerrain* m_pMesh)
{
	/*方向矢量
	DIRview.x = (2*screenPt.x/screenWidth-1)/projMatrix._m11;
	DIRview.y = (2*screenPt.y/screenHeight-1)/projMatrix._m22;
	DIRview.z = 1;*/

	//计算屏幕空间的坐标(-1,-1)~(1,1)
	D3DXVECTOR3 v;
	POINT p= m_pCursor->GetPosition();
	v.x =  ( (2* p.x  / m_scrWidth  ) - 1) / m_matProjection._11;
	v.y =  -( (2* p.y  / m_scrHeight ) - 1) / m_matProjection._22;
	v.z =  1.0f;

	//获得视图变换矩阵的逆矩阵
	D3DXMATRIXA16 matView, m, matWorld;
	matWorld = (m_pMesh->m_matWorld);
	matView = matWorld * m_matView;
	D3DXMatrixInverse( &m, NULL, &matView);

	//把上述坐标转换成世界坐标
	vPickRayDir->x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
	vPickRayDir->y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
	vPickRayDir->z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
	vPickRayOrig->x = m._41;
	vPickRayOrig->y = m._42;
	vPickRayOrig->z = m._43;
}

void CCamera::GetRayOrigDirFormTerrain(D3DXVECTOR3* vPickRayOrig, D3DXVECTOR3* vPickRayDir, CTerrain* pTerrain)
{
	//计算屏幕空间的坐标(-1,-1)~(1,1)
	D3DXVECTOR3 v;
	POINT p= m_pCursor->GetPosition();
	v.x =  ( (2* p.x  / m_scrWidth  ) - 1) / m_matProjection._11;
	v.y =  -( (2* p.y  / m_scrHeight ) - 1) / m_matProjection._22;
	v.z =  1.0f;

	//获得视图变换矩阵的逆矩阵
	D3DXMATRIXA16 matView, m, matWorld;
	matWorld = (pTerrain->m_matWorld);
	matView = matWorld * m_matView;
	D3DXMatrixInverse( &m, NULL, &matView);

	//把上述坐标转换成世界坐标
	vPickRayDir->x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
	vPickRayDir->y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
	vPickRayDir->z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
	vPickRayOrig->x = m._41;
	vPickRayOrig->y = m._42;
	vPickRayOrig->z = m._43;
};

void CCamera::GetRayOrigDirFormMesh(D3DXVECTOR3* vPickRayOrig, D3DXVECTOR3* vPickRayDir, CMesh* pMesh)
{
	//计算屏幕空间的坐标(-1,-1)~(1,1)
	D3DXVECTOR3 v;
	POINT p= m_pCursor->GetPosition();
	v.x =  ( (2* p.x  / m_scrWidth  ) - 1) / m_matProjection._11;
	v.y =  -( (2* p.y  / m_scrHeight ) - 1) / m_matProjection._22;
	v.z =  1.0f;

	//获得视图变换矩阵的逆矩阵
	D3DXMATRIXA16 matView, m, matWorld;
	matWorld = (pMesh->m_p1MatMesh);
	matView = matWorld * m_matView;
	D3DXMatrixInverse( &m, NULL, &matView);

	//把上述坐标转换成世界坐标
	vPickRayDir->x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
	vPickRayDir->y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
	vPickRayDir->z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
	vPickRayOrig->x = m._41;
	vPickRayOrig->y = m._42;
	vPickRayOrig->z = m._43;
};
void CCamera::GetRayOrigDirFormSkinMesh(D3DXVECTOR3* vPickRayOrig, D3DXVECTOR3* vPickRayDir, CSkinMesh* pSkinMesh)
{
	//计算屏幕空间的坐标(-1,-1)~(1,1)
	D3DXVECTOR3 v;
	POINT p= m_pCursor->GetPosition();
	v.x =  ( (2* p.x  / m_scrWidth  ) - 1) / m_matProjection._11;
	v.y =  -( (2* p.y  / m_scrHeight ) - 1) / m_matProjection._22;
	v.z =  1.0f;

	//获得视图变换矩阵的逆矩阵
	D3DXMATRIXA16 matView, m, matWorld;
	matWorld = (pSkinMesh->m_matWorld);
	matView = matWorld * m_matView;
	D3DXMatrixInverse( &m, NULL, &matView);

	//把上述坐标转换成世界坐标
	vPickRayDir->x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
	vPickRayDir->y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
	vPickRayDir->z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
	vPickRayOrig->x = m._41;
	vPickRayOrig->y = m._42;
	vPickRayOrig->z = m._43;
};

void CCamera::GetRayOrigDir(D3DXVECTOR3* vPickRayOrig, D3DXVECTOR3* vPickRayDir)
{
	*vPickRayOrig = m_vPos;
	D3DXVECTOR3 v;
	POINT p= m_pCursor->GetPosition();
	v.x =  ( (2* p.x  / m_scrWidth  ) - 1) / m_matProjection._11;
	v.y =  -( (2* p.y  / m_scrHeight ) - 1) / m_matProjection._22;
	v.z =  1.0f;

	//获得视图变换矩阵的逆矩阵
	D3DXMATRIXA16  m;
	D3DXMatrixInverse(&m, NULL, &m_matView);

	//把上述坐标转换成世界坐标
	vPickRayDir->x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
	vPickRayDir->y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
	vPickRayDir->z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -