📄 camera.cpp
字号:
//***********************************************************************//
// //
// - "Talk to me like I'm a 3 year old!" Programming Lessons - //
// //
// $Author: DigiBen DigiBen@GameTutorials.com //
// //
// $Program: BSP Loader 6 //
// //
// $Description: This adds gravity, jumping and walking up steps //
// //
// $Date: 9/30/04 //
// //
//***********************************************************************//
#include "main.h"
#include "Camera.h"
#include "Quake3Bsp.h"
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// In our CheckForMovement() function we add some code to add gravity and velocity
// to our camera. We also get rid of the ability to move along the Y-Axis by the
// view vector. That way we just go up only if we jump or go up some stairs/slopes.
//
//
// Since we need the velocity vector for our camera, let's extern this here
extern CVector3 g_vVelocity;
// Changed the speed from 300 because of the frame interval change in CalculateFrameRate()
#define kSpeed 200.0f
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Our global float that stores the elapsed time between the current and last frame
double g_FrameInterval = 0.0f;
// Extern the level object so we can call collision detection calls
extern CQuake3BSP g_Level;
///////////////////////////////// CALCULATE FRAME RATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function calculates the frame rate and time intervals between frames
/////
///////////////////////////////// CALCULATE FRAME RATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CalculateFrameRate()
{
static double framesPerSecond = 0.0f; // This will store our fps
static double lastTime = 0.0f; // This will hold the time from the last frame
static char strFrameRate[50] = {0}; // We will store the string here for the window title
static double frameTime = 0.0f; // This stores the last frame's time
// Get the current time in seconds
double currentTime = timeGetTime() * 0.001f;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// We added a small value to the frame interval to account for some video
// cards (Radeon's) with fast computers falling through the floor without it.
// Here we store the elapsed time between the current and last frame,
// then keep the current frame in our static variable for the next frame.
g_FrameInterval = currentTime - frameTime + 0.005f;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
frameTime = currentTime;
// Increase the frame counter
++framesPerSecond;
// Now we want to subtract the current time by the last time that was stored
// to see if the time elapsed has been over a second, which means we found our FPS.
if( currentTime - lastTime > 1.0f )
{
// Here we set the lastTime to the currentTime
lastTime = currentTime;
// Copy the frames per second into a string to display in the window title bar
sprintf(strFrameRate, "Current Frames Per Second: %d", int(framesPerSecond));
// Set the window title bar to our string
SetWindowText(g_hWnd, strFrameRate);
// Reset the frames per second
framesPerSecond = 0;
}
}
/////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This returns a perpendicular vector from 2 given vectors by taking the cross product.
/////
/////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
CVector3 Cross(CVector3 vVector1, CVector3 vVector2)
{
CVector3 vNormal;
// Calculate the cross product with the non communitive equation
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 the cross product
return vNormal;
}
/////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This returns the magnitude of a vector
/////
/////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
float Magnitude(CVector3 vNormal)
{
// Here is the equation: magnitude = sqrt(V.x^2 + V.y^2 + V.z^2) : Where V is the vector
return (float)sqrt( (vNormal.x * vNormal.x) +
(vNormal.y * vNormal.y) +
(vNormal.z * vNormal.z) );
}
/////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This returns a normalize vector (A vector exactly of length 1)
/////
/////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
CVector3 Normalize(CVector3 vVector)
{
// Get the magnitude of our normal
float magnitude = Magnitude(vVector);
// Now that we have the magnitude, we can divide our vector by that magnitude.
// That will make our vector a total length of 1.
vVector = vVector / magnitude;
// Finally, return our normalized vector
return vVector;
}
///////////////////////////////// CCAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This is the class constructor
/////
///////////////////////////////// CCAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
CCamera::CCamera()
{
CVector3 vZero = CVector3(0.0, 0.0, 0.0); // Init a vVector to 0 0 0 for our position
CVector3 vView = CVector3(0.0, 1.0, 0.5); // Init a starting view vVector (looking up and out the screen)
CVector3 vUp = CVector3(0.0, 0.0, 1.0); // Init a standard up vVector (Rarely ever changes)
m_vPosition = vZero; // Init the position to zero
m_vView = vView; // Init the view to a std starting view
m_vUpVector = vUp; // Init the UpVector
}
///////////////////////////////// POSITION CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function sets the camera's position and view and up vVector.
/////
///////////////////////////////// POSITION CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
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);
// The code above just makes it cleaner to set the variables.
// Otherwise we would have to set each variable x y and z.
m_vPosition = vPosition; // Assign the position
m_vView = vView; // Assign the view
m_vUpVector = vUpVector; // Assign the up vector
}
///////////////////////////////// SET VIEW BY MOUSE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This allows us to look around using the mouse, like in most first person games.
/////
///////////////////////////////// SET VIEW BY MOUSE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::SetViewByMouse()
{
POINT mousePos; // This is a window structure that holds an X and Y
int middleX = SCREEN_WIDTH >> 1; // This is a binary shift to get half the width
int middleY = SCREEN_HEIGHT >> 1; // This is a binary shift to get half the height
float angleY = 0.0f; // This is the direction for looking up or down
float angleZ = 0.0f; // This will be the value we need to rotate around the Y axis (Left and Right)
static float currentRotX = 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) ) / 500.0f;
angleZ = (float)( (middleY - mousePos.y) ) / 500.0f;
// Here we keep track of the current rotation (for up and down) so that
// we can restrict the camera from doing a full 360 loop.
currentRotX -= angleZ;
// To find the axis we need to rotate around for up and down
// movements, we need to get a perpendicular vector from the
// camera's view vector and up vector. This will be the axis.
CVector3 vAxis = Cross(m_vView - m_vPosition, m_vUpVector);
vAxis = Normalize(vAxis);
// Rotate around our perpendicular axis and along the y-axis
RotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
RotateView(angleY, 0, 1, 0);
}
///////////////////////////////// ROTATE VIEW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This rotates the view around the position using an axis-angle rotation
/////
///////////////////////////////// ROTATE VIEW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::RotateView(float angle, float x, float y, float z)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -