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

📄 camera.cpp

📁 一个室内场景漫游程序
💻 CPP
字号:

//========================================================
/**
*  @file      Camera.cpp
*
*  项目描述: Quake室内场景实例
*  文件描述:  摄像机类  
*  适用平台: Windows98/2000/NT/XP
*  
*  作者:     WWBOSS
*  电子邮件:  wwboss123@gmail.com
*  创建日期: 2006-08-06	
*  修改日期: 2007-09-01
*
*/     
//========================================================
#include "main.h"
#include "Camera.h"
#include "Quake3Bsp.h"


extern CVector3 g_vVelocity;

#define kSpeed	200.0f		

double g_FrameInterval = 0.0f;

extern CQuake3BSP g_Level;

/** 计算FPS */
void CalculateFrameRate()
{
	static double framesPerSecond   = 0.0f;		
    static double lastTime			= 0.0f;		
	static char strFrameRate[50] = {0};			

	static double frameTime = 0.0f;				

	
    double currentTime = timeGetTime() * 0.001f;				
 	g_FrameInterval = currentTime - frameTime + 0.005f;

	frameTime = currentTime;

    ++framesPerSecond;

   if( currentTime - lastTime > 1.0f )
    {
		
	    lastTime = currentTime;
		
		sprintf(strFrameRate, "Quake室内场景实例 FPS: %d", int(framesPerSecond));

		SetWindowText(g_hWnd, strFrameRate);  /**< 设置标题 */

		framesPerSecond = 0;
    }
}

/** 计算叉积 */												
CVector3 Cross(CVector3 vVector1, CVector3 vVector2)
{
	CVector3 vNormal;	

	
	vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
	vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
	vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));

	return vNormal;										 
}

/** 计算向量的模 */
float Magnitude(CVector3 vNormal)
{
	return (float)sqrt( (vNormal.x * vNormal.x) + 
						(vNormal.y * vNormal.y) + 
						(vNormal.z * vNormal.z) );
}


/** 单位化向量 */
CVector3 Normalize(CVector3 vVector)
{
	
	float magnitude = Magnitude(vVector);				

	vVector = vVector / magnitude;		
	
	return vVector;										
}

CCamera::CCamera()
{
	CVector3 vZero = CVector3(0.0, 0.0, 0.0);		
	CVector3 vView = CVector3(0.0, 1.0, 0.5);		
	CVector3 vUp   = CVector3(0.0, 0.0, 1.0);		

	m_vPosition	= vZero;					
	m_vView		= vView;					
	m_vUpVector	= vUp;					
}


void CCamera::PositionCamera(float positionX, float positionY, float positionZ,
				  		     float viewX,     float viewY,     float viewZ,
							 float upVectorX, float upVectorY, float upVectorZ)
{
	CVector3 vPosition	= CVector3(positionX, positionY, positionZ);
	CVector3 vView		= CVector3(viewX, viewY, viewZ);
	CVector3 vUpVector	= CVector3(upVectorX, upVectorY, upVectorZ);

	m_vPosition = vPosition;					
	m_vView     = vView;					
	m_vUpVector = vUpVector;				
}


void CCamera::SetViewByMouse()
{
	POINT mousePos;									
	int middleX = SCREEN_WIDTH  >> 1;				
	int middleY = SCREEN_HEIGHT >> 1;				
	float angleY = 0.0f;							
	float angleZ = 0.0f;							
	static float currentRotX = 0.0f;
	
	
	GetCursorPos(&mousePos);						
	
	
	if( (mousePos.x == middleX) && (mousePos.y == middleY) ) return;

	SetCursorPos(middleX, middleY);							
	
	angleY = (float)( (middleX - mousePos.x) ) / 500.0f;		
	angleZ = (float)( (middleY - mousePos.y) ) / 500.0f;		

	currentRotX -= angleZ;  

	CVector3 vAxis = Cross(m_vView - m_vPosition, m_vUpVector);
	vAxis = Normalize(vAxis);

	RotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
	RotateView(angleY, 0, 1, 0);
}

void CCamera::RotateView(float angle, float x, float y, float z)
{
	CVector3 vNewView;

	CVector3 vView = m_vView - m_vPosition;		

	float cosTheta = (float)cos(angle);
	float sinTheta = (float)sin(angle);

	vNewView.x  = (cosTheta + (1 - cosTheta) * x * x)		* vView.x;
	vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta)	* vView.y;
	vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta)	* vView.z;

	vNewView.y  = ((1 - cosTheta) * x * y + z * sinTheta)	* vView.x;
	vNewView.y += (cosTheta + (1 - cosTheta) * y * y)		* vView.y;
	vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta)	* vView.z;

	vNewView.z  = ((1 - cosTheta) * x * z - y * sinTheta)	* vView.x;
	vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta)	* vView.y;
	vNewView.z += (cosTheta + (1 - cosTheta) * z * z)		* vView.z;

	m_vView = m_vPosition + vNewView;
}



void CCamera::StrafeCamera(float speed)
{	
	
	m_vPosition.x += m_vStrafe.x * speed;
	m_vPosition.z += m_vStrafe.z * speed;

	m_vView.x += m_vStrafe.x * speed;
	m_vView.z += m_vStrafe.z * speed;
}


void CCamera::MoveCamera(float speed)
{
	CVector3 vVector = m_vView - m_vPosition;
	vVector = Normalize(vVector);

	m_vPosition.x += vVector.x * speed;		
	m_vPosition.z += vVector.z * speed;		
	m_vView.x += vVector.x * speed;			
	m_vView.z += vVector.z * speed;			

}




void CCamera::CheckForMovement()
{	
	float speed = (float)(kSpeed * g_FrameInterval);

	CVector3 vOldPosition = Position();
	CVector3 vOldView = View();

	bool bMovedBack = false;

	g_vVelocity.y -= (float)(kGravity * g_FrameInterval);
	m_vPosition = m_vPosition + g_vVelocity;


	if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80) 
	{				
		MoveCamera(speed);				
	}

	
	if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80) 
	{			
		MoveCamera(-speed);	
		bMovedBack = true;
	}
	
	if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80) 
	{			

		StrafeCamera(-speed);
	}

	
	if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80)
	{			

		StrafeCamera(speed);
	}	

	CVector3 vCurrentPosition = Position();

	CVector3 vNewPosition = g_Level.TraceBox(vOldPosition, vCurrentPosition,
		                                     CVector3(-20, -50, -20), CVector3(20, 50, 20));

	if(g_Level.Collided() && bMovedBack)
	{
		if(vNewPosition.x == vOldPosition.x || vNewPosition.z == vOldPosition.z)
			m_vView = vOldView;		
	}

	m_vPosition = vNewPosition;

	if(!g_Level.IsOnGround())
		m_vView = m_vView + g_vVelocity;
	else
	{
	   if(g_vVelocity.y < 0)
			g_vVelocity.y = 0;
	}

}

/** 更新摄像机 */
void CCamera::Update() 
{
	CVector3 vCross = Cross(m_vView - m_vPosition, m_vUpVector);

	m_vStrafe = Normalize(vCross);

	SetViewByMouse();

	CheckForMovement();
	

	CalculateFrameRate();
}

void CCamera::Look()
{
	gluLookAt(m_vPosition.x, m_vPosition.y, m_vPosition.z,	
			  m_vView.x,	 m_vView.y,     m_vView.z,	
			  m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
}

⌨️ 快捷键说明

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