www.pudn.com > Gimcrack-v0.0051-Source.zip > camera.cpp


#include  
#include  
#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); 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////////////////////////