📄 camera.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 + -