📄 camera.cpp
字号:
CVector3 vNewView;
// Get the view vector (The direction we are facing)
CVector3 vView = m_vView - m_vPosition;
// Calculate the sine and cosine of the angle once
float cosTheta = (float)cos(angle);
float sinTheta = (float)sin(angle);
// Find the new x position for the new rotated point
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;
// Find the new y position for the new rotated point
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;
// Find the new z position for the new rotated point
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;
// Now we just add the newly rotated vector to our position to set
// our new rotated view of our camera.
m_vView = m_vPosition + vNewView;
}
///////////////////////////////// STRAFE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This strafes the camera left and right depending on the speed (-/+)
/////
///////////////////////////////// STRAFE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::StrafeCamera(float speed)
{
// Add the strafe vector to our position
m_vPosition.x += m_vStrafe.x * speed;
m_vPosition.z += m_vStrafe.z * speed;
// Add the strafe vector to our view
m_vView.x += m_vStrafe.x * speed;
m_vView.z += m_vStrafe.z * speed;
}
///////////////////////////////// MOVE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This will move the camera forward or backward depending on the speed
/////
///////////////////////////////// MOVE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::MoveCamera(float speed)
{
// Get the current view vector (the direction we are looking)
CVector3 vVector = m_vView - m_vPosition;
vVector = Normalize(vVector);
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// We don't add anything to this section, but we delete the code that
// has the m_vPosition.y and m_vView.y effected. We deleted those 2 lines.
m_vPosition.x += vVector.x * speed; // Add our acceleration to our position's X
m_vPosition.z += vVector.z * speed; // Add our acceleration to our position's Z
m_vView.x += vVector.x * speed; // Add our acceleration to our view's X
m_vView.z += vVector.z * speed; // Add our acceleration to our view's Z
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
}
//////////////////////////// CHECK FOR MOVEMENT \\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function handles the input faster than in the WinProc()
/////
//////////////////////////// CHECK FOR MOVEMENT \\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::CheckForMovement()
{
// Once we have the frame interval, we find the current speed
float speed = (float)(kSpeed * g_FrameInterval);
// Store the last position and view of the camera
CVector3 vOldPosition = Position();
CVector3 vOldView = View();
// Use a flag to see if we movement backwards or not
bool bMovedBack = false;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Here is where we subtract the gravity acceleration from our velocity vector.
// We then add that velocity vector to our camera to effect our camera (or player)
// This is also how we handle the jump velocity when we hit space bar.
// Notice that we multiply the gravity by the frame interval (dt). This makes
// it so faster video cards don't do a 2 frame jump, while TNT2 cards do 20 frames :)
// This is necessary to make every computer use the same movement and jump speed.
g_vVelocity.y -= (float)(kGravity * g_FrameInterval);
m_vPosition = m_vPosition + g_vVelocity;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Check if we hit the Up arrow or the 'w' key
if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80) {
// Move our camera forward by a positive SPEED
MoveCamera(speed);
}
// Check if we hit the Down arrow or the 's' key
if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80) {
// Move our camera backward by a negative SPEED
MoveCamera(-speed);
bMovedBack = true;
}
// Check if we hit the Left arrow or the 'a' key
if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80) {
// Strafe the camera left
StrafeCamera(-speed);
}
// Check if we hit the Right arrow or the 'd' key
if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80) {
// Strafe the camera right
StrafeCamera(speed);
}
// Now that we moved, let's get the current position and test our movement
// vector against the level data to see if there is a collision.
CVector3 vCurrentPosition = Position();
// Check for collision with AABB's and grab the new position
CVector3 vNewPosition = g_Level.TraceBox(vOldPosition, vCurrentPosition,
CVector3(-20, -50, -20), CVector3(20, 50, 20));
// Check if we collided and we moved backwards
if(g_Level.Collided() && bMovedBack)
{
// If or x or y didn't move, then we are backed into a wall so restore the view vector
if(vNewPosition.x == vOldPosition.x || vNewPosition.z == vOldPosition.z)
m_vView = vOldView;
}
// Set the new position that was returned from our trace function
m_vPosition = vNewPosition;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// After we check for collision, we only want to add the velocity vector to
// our view vector when we are falling. If we aren't on the ground then
// we don't want to push the the camera view down to the ground. It's okay
// if the position goes down because the collision detection fixes that so
// we don't go through the ground, however, it's not natural to push the view
// down too. Well, assuming is strong enough to push our face down to the ground :)
if(!g_Level.IsOnGround())
m_vView = m_vView + g_vVelocity;
else
{
// If we ARE on the ground, we want to get rid of the jump acceleration
// that we add when the user hits the space bar. Below we check to see
// if our velocity is below 0 then we are done with our jump and can just
// float back to the ground by the gravity. We do also add our gravity
// acceleration to the velocity every frame, so this resets this to zero
// for that as well.
if(g_vVelocity.y < 0)
g_vVelocity.y = 0;
}
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
}
///////////////////////////////// UPDATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This updates the camera's view and strafe vector
/////
///////////////////////////////// UPDATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::Update()
{
// Initialize a variable for the cross product result
CVector3 vCross = Cross(m_vView - m_vPosition, m_vUpVector);
// Normalize the strafe vector
m_vStrafe = Normalize(vCross);
// Move the camera's view by the mouse
SetViewByMouse();
// This checks to see if the keyboard was pressed
CheckForMovement();
// Calculate our frame rate and set our frame interval for time based movement
CalculateFrameRate();
}
///////////////////////////////// LOOK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This updates the camera according to the
/////
///////////////////////////////// LOOK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CCamera::Look()
{
// Give openGL our camera position, then camera view, then camera up vector
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);
}
/////////////////////////////////////////////////////////////////////////////////
//
// * QUICK NOTES *
//
// We changed some code in MoveCamera() and CheckForMovement(). Now we have a
// constant gravity acceleration pushing us down to the ground (like in real life).
// We just fly around now, since we got rid of the code for fly mode. If you want
// to go anywhere now, you have to walk there or jump there :)
//
//
// Ben Humphrey (DigiBen)
// Game Programmer
// DigiBen@GameTutorials.com
// Co-Web Host of www.GameTutorials.com
//
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -