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

📄 camera.cpp

📁 小型的3D游戏引擎
💻 CPP
字号:
#include <windows.h>
#include <gl/glu.h>
#include "global.h"
#include "Camera.h"

#define kSpeed	15.0f

float angle = 1.570796327f;									

static GcCamera * camera = 0;

GcCamera * ActiveCamera()
{
    return camera;
}


///////////////////////////////////////////////////////////////////////////////////////////////

GcCamera::GcCamera()
{
	// Default values
	position = GcVector3(0.0, 0.0, 0.0);
	view = GcVector3(0.0, 1.0, 0.5);
	up  = GcVector3(0.0, 0.0, 1.0);

	SetScreen(800, 600); // FIX ME: Better init of screen size
}

///////////////////////////////////////////////////////////////////////////////////////////////

GcCamera::~GcCamera()
{
	// Destroying the camera object
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetCamera(GcVector3 &sPos, GcVector3 &sView, GcVector3 &sUp)
{
	// Set the position
	position = sPos;
	view = sView;
	up = sUp;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetCamera(float posX, float posY, float posZ,
				  		float viewX, float viewY, float viewZ,
						float upX, float upY, float upZ)
{
	// Set the position
	position = GcVector3(posX, posY, posZ);
	view	 = GcVector3(viewX, viewY, viewZ);
	up		 = GcVector3(upX, upY, upZ);
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetPostion(GcVector3 &pos)
{
	// Set the position
	position = pos;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetPostion(float x, float y, float z)
{
	// Set the position
	position = GcVector3(x, y, z);
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetView(GcVector3 &sView)
{
	// Set the view
	view = sView;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetView(float x, float y, float z)
{
	// Set the view
	view = GcVector3(x, y, z);
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetUp(GcVector3 &sUp)
{
	// Set the view
	up = sUp;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetUp(float x, float y, float z)
{
	// Set the view
	up = GcVector3(x, y, z);
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetRight(GcVector3 &sRight)
{
	// Set the view
	right = sRight;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::SetRight(float x, float y, float z)
{
	// Set the view
	right = GcVector3(x, y, z);
}


///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::MoveFrwBack(float speed)
{
	// Extract the true view for used in claculations
	GcVector3 temp = view - position;

	// Normalize the vectoe
	temp.Normalize();
	
	// Calculate the position
	position += temp * speed;
	view += temp * speed;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::MoveUpDown(float speed)
{
	// Calculate the position
	position += up * speed;
	view += up * speed;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::MoveDir(GcVector3 dir, float dist)
{
	// Claculate the position
	position += dir * dist;
	view += dir * dist;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::Strafe(float speed)
{
	// The right vector is calculated globably since it's needed other where

	// Calculate the new position
	position += right * speed;
	view += right * speed;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::Rotate(float angle, float x, float y, float z)
{
	// The new view
	GcVector3 newView;

	// Extract the current view
	GcVector3 tempView = view - position;		

	// Calculate the sine and cosine of the angle once
	float cosV = float(cos(angle));
	float sinV = float(sin(angle));

	// Find the new x position for the new rotated point
	newView.x  = (cosV + (1 - cosV) * x * x)		* tempView.x;
	newView.x += ((1 - cosV) * x * y - z * sinV)	* tempView.y;
	newView.x += ((1 - cosV) * x * z + y * sinV)	* tempView.z;

	// Find the new y position for the new rotated point
	newView.y  = ((1 - cosV) * x * y + z * sinV)	* tempView.x;
	newView.y += (cosV + (1 - cosV) * y * y)		* tempView.y;
	newView.y += ((1 - cosV) * y * z - x * sinV)	* tempView.z;

	// Find the new z position for the new rotated point
	newView.z  = ((1 - cosV) * x * z - y * sinV)	* tempView.x;
	newView.z += ((1 - cosV) * y * z + x * sinV)	* tempView.y;
	newView.z += (cosV + (1 - cosV) * z * z)		* tempView.z;

	// Set the new view
	view = newView + position;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::Roll(float angle)
{
	// Claculate the new up vector
	up.x = float(cos(angle));
	up.y = float(sin(angle));
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::Update() 
{
	// Claculate the right vector
	right = view - position;
	right.Normalize(up);

	// Set the camera in the world
	gluLookAt(position.x, position.y, position.z,	
			  view.x, view.y, view.z,	
			  up.x, up.y, up.z);

	// Update the frustum
	if(!KEYDOWN('5')) {
		frustum.Extract();
	}
	
	camera = this;
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::MouseLook()
{
	POINT mousePos;
	int middleX = m_screenWidth  >> 1;	
	int middleY = m_screenHeight >> 1;		
	float angleY = 0.0f;						
	float angleZ = 0.0f;							
	
	// Get the mouse's current X,Y position
	GetCursorPos(&mousePos);						
	
	// If our cursor is still in the middle, we never moved... so don't update the screen
	if( (mousePos.x == middleX) && (mousePos.y == middleY) ) return;

	// Set the mouse position to the middle of our window
	SetCursorPos(middleX, middleY);							

	// Get the direction the mouse moved in, but bring the number down to a reasonable amount
	angleY = (float)((middleX - mousePos.x)) / 1000.0f;		
	angleZ = (float)((middleY - mousePos.y)) / 1000.0f;		

	// Rotate around our perpendicular axis and along the y-axis
	Rotate(angleZ, right.x, right.y, right.z);
	Rotate(angleY, 0, 1, 0);
}

///////////////////////////////////////////////////////////////////////////////////////////////

void GcCamera::CheckMovement(float speed)
{
	/* User input */

	if(KEYDOWN('W')) {				

		// Move forward
		MoveFrwBack(speed);				
	}

	if(KEYDOWN('S')) 
	{	
		
		// Move backward
		MoveFrwBack(-speed);				
	}

	if(KEYDOWN('A')) 
	{			
		// Strafe left
		Strafe(-speed);
	}

	if(KEYDOWN('D')) 
	{			
		// Strafe right
		Strafe(speed);
	}

	if(KEYDOWN(VK_UP))
	{
		// Move up
		MoveUpDown(speed);
	}

	if(KEYDOWN(VK_DOWN))
	{
		// Move donw
		MoveUpDown(-speed);
	}

	if(KEYDOWN(VK_RIGHT))
	{
		angle += 0.05f;

		if(angle > 6.283185307f)
		{
			angle = 0;
		}

		// Roll to the right
		Roll(angle);
	}

	if(KEYDOWN(VK_LEFT))
	{
		angle -= 0.05f;

		if(angle < -6.283185307f)
		{
			angle = 0;
		}

		// Roll to the left
		Roll(angle);
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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