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

📄 ccamera.cpp

📁 一个DXD制作的读取QUAKE的BSP结构的Demo可以参考
💻 CPP
字号:
/*
   Class Name:

      CCamera.

   Created by:

      Allen Sherrod (Programming Ace of www.UltimateGameProgramming.com).

   Description:

      This class represents a camera in a 3D scene.
*/


#include"CCamera.h"


CCamera::CCamera()
{
   // Initialize variables...
   mPos = CVector4(0.0f, 0.0f, 0.0f);
   mView = CVector4(0.0f, 0.0f, 0.0f);
   mUp = CVector4(0.0f, 0.0f, 0.0f);
   mStrafe = CVector4(0.0f, 0.0f, 0.0f);

   currentRotationAngle = 0.0f;
}


void CCamera::SetCamera(float x, float y, float z,
                        float xv, float yv, float zv,
                        float xu, float yu, float zu)
{
   // Here we set the camera to the values sent in to us.  This is mostly used to set up a
   // default position.
   mPos = CVector4(x, y, z);
   mView = CVector4(xv, yv, zv);
   mUp = CVector4(xu, yu, zu);
}

void CCamera::GetDirection(CVector4 &Direction)
{
   // The look direction is the view (where we are looking) minus the position (where we are).
   Direction = mView - mPos;
}


void CCamera::MoveCamera(float speed)
{
   // Moving the camera requires a little more then adding 1 to the z or subracting 1.
   // First we need to get the direction at which we are looking.
   CVector4 Direction;

   // Get the direction and store it in the object Direction.
   GetDirection(Direction);

   Direction.Normal();

   // Call UpdateCamera to move our camera in the direction we want.
   UpdateCamera(Direction, speed);

   // NOTE if the camera moves too slow try increasing the UP and DOWN values in the header.
   // The camera is frame based so it will move differently for you.
}


void CCamera::UpdateCamera(CVector4 Direction, float speed)
{
   // Move the camera on the X and Z axis.
	mPos.x += Direction.x * speed;
   mPos.y += Direction.y * speed;
	mPos.z += Direction.z * speed;

   // Move the view along with the position
	mView.x += Direction.x * speed;
   mView.y += Direction.y * speed;
	mView.z += Direction.z * speed;
}


void CCamera::StrafeCam(float speed)
{
   CalculateStrafe();                           // Calculate the straft direction.
   UpdateCamera(mStrafe, speed);                // Then add it to the camera's position.
}


void CCamera::CalculateStrafe()
{
   CVector4 Direction;
   CVector4 Cross;
   float magnitude = 0.0;

   // Strafing is just like moving the camera forward and backward.  First we will get the
   // direction we are looking.
   GetDirection(Direction);

   // Now if we were to call UpdateCamera() we will be moving the camera foward or backwards.
   // We don't want that here.  We want to strafe.  To do so we have to get the cross product
   // of our direction and Up direction view.  The up was set in SetCamera to be 1 positive
   // y.  That is because anything positive on the y is considered up.  After we get the
   // cross product we can save it to the strafe variables so that can be added to the
   // camera using UpdateCamera().

   // Get the cross product of the direction we are looking and the up direction.
   Cross.CrossProduct(Direction, mUp);

   // Normalize it.
   Cross.Normal();

   // Save our strafe (cross product) values in the mStrafe object.
   mStrafe = Cross;
}


void CCamera::RotateCamera(float AngleDir, CVector4 Speed)
{
   CVector4 newDir;
   CVector4 LookDirection;
   float CosineAngle, SineAngle = 0.0;

   // First we will need to calculate the cos and sine of our angle.  I created two macros to
   // do this in the CCamera.h header file called GET_COS and GET_SINE.  To use the macros
   // we just send in the variable we ant to store the results and the angle we need to
   // calculate.
	GET_COS(CosineAngle, AngleDir);
   GET_SINE(SineAngle, AngleDir);

	// Next get the look direction (where we are looking) just like in the move camera function.
   GetDirection(LookDirection);

	// Calculate the new X position.
	newDir.x = (CosineAngle + (1 - CosineAngle) * Speed.x) * LookDirection.x;
	newDir.x += ((1 - CosineAngle) * Speed.x * Speed.y - Speed.z * SineAngle)* LookDirection.y;
	newDir.x += ((1 - CosineAngle) * Speed.x * Speed.z + Speed.y * SineAngle) * LookDirection.z;

	// Calculate the new Y position.
	newDir.y = ((1 - CosineAngle) * Speed.x * Speed.y + Speed.z * SineAngle) * LookDirection.x;
	newDir.y += (CosineAngle + (1 - CosineAngle) * Speed.y) * LookDirection.y;
	newDir.y += ((1 - CosineAngle) * Speed.y * Speed.z - Speed.x * SineAngle) * LookDirection.z;

	// Calculate the new Z position.
	newDir.z = ((1 - CosineAngle) * Speed.x * Speed.z - Speed.y * SineAngle) * LookDirection.x;
	newDir.z += ((1 - CosineAngle) * Speed.y * Speed.z + Speed.x * SineAngle) * LookDirection.y;
	newDir.z += (CosineAngle + (1 - CosineAngle) * Speed.z) * LookDirection.z;


	// Last we add the new rotations to the old view to correctly rotate the camera.
   mView = mPos + newDir;
}


void CCamera::RotateByMouse(int mousePosX, int mousePosY, int midX, int midY)
{
	float yDirection = 0.0f;         // Direction angle.
	float yRotation = 0.0f;          // Rotation angle.

	// If the mouseX and mouseY are at the middle of the screen then we can't rotate the view.
	if((mousePosX == midX) && (mousePosY == midY))
      return;

	// Next we get the direction of each axis.  We divide by 1000 to get a smaller value back.
	yDirection = (float)((midX - mousePosX)) / 1000.0f;		
	yRotation = (float)((midY - mousePosY)) / 1000.0f;		

	// We use curentRotX to help use keep the camera from rotating too far in either direction.
	currentRotationAngle -= yRotation;  

	// Stop the camera from going to high...
	if(currentRotationAngle > 1.5f)
      {
		   currentRotationAngle = 1.5f;
         return;
      }

	// Stop the camera from going to low...
	if(currentRotationAngle < -1.5f)
		{
         currentRotationAngle = -1.5f;
         return;
      }

   // Next we get the axis which is a perpendicular vector of the view direction and up values.
   // We use the cross product of that to get the axis then we normalize it.
   CVector4 Axis;
   Axis.CrossProduct(mView - mPos, mUp);
   Axis.Normal();

   // Rotate the camera.
   RotateCamera(yRotation, CVector4(Axis.x, Axis.y, Axis.z));
   RotateCamera(-yDirection, CVector4(0, 1, 0));
}


// Copyright May 2003
// All Rights Reserved!
// Allen Sherrod
// ProgrammingAce@UltimateGameProgramming.com
// www.UltimateGameProgramming.com

⌨️ 快捷键说明

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