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

📄 playercamera.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : PlayerCamera.cpp
//
// PURPOSE : PlayerCamera - Implementation
//
// CREATED : 10/5/97
//
// ----------------------------------------------------------------------- //

#include "PlayerCamera.h"
#include "cpp_client_de.h"
#include "SharedDefs.h"
#include <stdio.h>
#include <math.h>

// Camera's distance back from the player's position
#define DEFAULT_CAMERA_DIST_BACK	90
// Camera's distance up from the player's position
#define DEFAULT_CAMERA_DIST_UP		35
// Camera's distance back from the player's position but at a 45 degree angle
// (for example, if the camera is looking at the player from the southeast position)
#define DEFAULT_CAMERA_DIST_DIAG	90

// Camera's X offset from the player when it is in the MLOOK state
#define DEFAULT_CAMERA_DIST_MLOOK_X	0
// Camera's Y offset from the player when it is in the MLOOK state
#define DEFAULT_CAMERA_DIST_MLOOK_Y 10
// Camera's Z offset from the player when it is in the MLOOK state
#define DEFAULT_CAMERA_DIST_MLOOK_Z 29

#define DEFAULT_ROTATE_SPEED		0.8f	// angular velocity


DBOOL Equal(DVector & v1, DVector & v2)
{
	DVector v;
	VEC_SUB(v, v1, v2);
	return DBOOL(VEC_MAG(v) < 1.0f);
}

DBOOL Equal(DRotation & r1, DRotation & r2)
{
	DBOOL bRet = DTRUE;

	if (r1.m_Vec.x != r2.m_Vec.x || r1.m_Vec.y != r2.m_Vec.y ||
		r1.m_Vec.z != r2.m_Vec.z || r1.m_Spin != r2.m_Spin)
	{
		bRet = DFALSE;
	}

	return bRet;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerCamera::CPlayerCamera()
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //

CPlayerCamera::CPlayerCamera()
{
	m_hTarget			= DNULL;
	m_pClientDE			= DNULL;

	ROT_INIT(m_rRotation);
	VEC_INIT(m_vPos);
	VEC_INIT(m_vLastTargetPos);
	VEC_INIT(m_vLastOptPos);
	ROT_INIT(m_rLastTargetRot);

//	m_eOrientation		= SOUTH;
//	m_eSaveOrientation	= SOUTH;
	
	m_CameraDistBack	= DEFAULT_CAMERA_DIST_BACK;
	m_CameraDistUp		= DEFAULT_CAMERA_DIST_UP;
	m_CameraDistDiag	= DEFAULT_CAMERA_DIST_DIAG;

	m_OptX				= 0.0f;
//	m_OptY				= 0.0f;
//	m_OptZ				= 0.0f;
	m_OptY				= m_CameraDistUp;
	m_OptZ				= -m_CameraDistBack;
	m_CircleStartTime	= 0.0f;
	m_SaveAnglesY		= 0.0f;

	m_bSlide			= DTRUE;
	
	m_bStartCircle			= DFALSE;
	m_CircleHeightOffset	= 0.0f;
	m_CircleRadius			= 75.0f;
	m_CircleTime			= 3.0f;
	m_bRestoreFirstPerson	= DFALSE;

	m_fTransitionStart	= 0.0f;
	m_fTransitionTime = 1.0f;

	m_eCameraMode			= FIRSTPERSON;
	m_eSaveCameraMode		= FIRSTPERSON;

	VEC_INIT(m_TargetFirstPersonOffset);
	VEC_INIT(m_TargetChaseOffset);
	VEC_INIT(m_TargetPointAtOffset);
	VEC_INIT(m_TargetDeathOffset);
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerCamera::CameraUpdate()
//
//	PURPOSE:	Update the position & orientation of the camera based 
//				on the target
//
// ----------------------------------------------------------------------- //

void CPlayerCamera::CameraUpdate(DFLOAT deltaTime)
{
	if (!m_pClientDE || !m_hTarget) return;


	DRotation rRot;
	DVector vOpt, vPos;

	m_pClientDE->GetObjectPos(m_hTarget, &vPos);
	m_pClientDE->GetObjectRotation(m_hTarget, &rRot);
	
	DVector vU, vR, vF;
	m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	if(m_hTarget)
	{
//		if(m_eOrientation == HOLD)
//			return;

		switch(m_eCameraMode)
		{
			case CHASE:
			break;
			
			case GOINGFIRSTPERSON:
			{
//				DVector vTemp;
//				VEC_MULSCALAR(vTemp, vF, m_TargetFirstPersonOffset.x);
//				VEC_ADD(vPos, vPos, vTemp);
//				vPos.y += m_TargetFirstPersonOffset.y;

				VEC_COPY(vOpt, FindFirstPersonCameraPosition(vPos, vF));
	
				MoveCameraToPosition(vOpt, FindOptimalCameraPosition(), deltaTime);
				PointAtPosition(vOpt, rRot, m_vPos);
				//PointInDirection(m_Target.m_Angles);
				return;
			}	
			break;

			case GOINGCHASE:
			{
				VEC_COPY(vOpt, FindFirstPersonCameraPosition(vPos, vF));
	
				MoveCameraToPosition(FindOptimalCameraPosition(), vOpt, deltaTime);
				PointAtPosition(vOpt, rRot, m_vPos);
				//PointInDirection(m_Target.m_Angles);
				return;
			}	
			break;

			case DEATH:
			{
				CircleAroundTarget();

				VEC_COPY(vOpt, FindFirstPersonCameraPosition(vPos, vF));
	
				MoveCameraToPosition(FindOptimalCameraPosition(), vOpt, deltaTime);
				PointAtPosition(vOpt, rRot, m_vPos);
				return;
			}
			break;
/*
			case CIRCLING:
			{
				CircleAroundTarget();
				return;
			}
			break;
*/
			case FIRSTPERSON:
			{
				DVector vTemp;
				VEC_MULSCALAR(vTemp, vF, m_TargetFirstPersonOffset.x);
				VEC_ADD(vPos, vPos, vTemp);
				vPos.y += m_TargetFirstPersonOffset.y;

				VEC_COPY(m_vPos, vPos);

				PointInDirection(rRot);
				return;
			}
			break;
			
			case SCRIPT:
				return;
			break;

			default:
				return;
		}

		VEC_COPY(vOpt, FindOptimalCameraPosition());

		// Move the camera to the optimal position
		// (it will slide or not depending on the m_bSlide param)
		MoveCameraToPosition(vOpt, vOpt, deltaTime);

		// Either point the camera at the player or MLOOK
//		if(m_eOrientation == MLOOK)
//		{
//			ROT_COPY(m_rRotation, rRot);
//		}
//		else
		{
			DVector vTemp;
			VEC_ADD(vTemp, vPos, m_TargetPointAtOffset);
			PointAtPosition(vTemp, rRot, vOpt);
		}
	}
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerCamera::Apply()
//
//	PURPOSE:	Matrix apply function
//
// ----------------------------------------------------------------------- //

DVector CPlayerCamera::Apply(DVector right, DVector up, DVector forward, DVector copy)
{
	DVector target;
	
	target.x = copy.x*right.x + copy.y*right.y + copy.z*right.z;
	target.y = copy.x*up.x + copy.y*up.y + copy.z*up.z;
	target.z = copy.x*forward.x + copy.y*forward.y + copy.z*forward.z;

	return target;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerCamera::PointAtPosition()
//
//	PURPOSE:	Point the camera at a position from a position
//
// ----------------------------------------------------------------------- //

void CPlayerCamera::PointAtPosition(DVector pos, DRotation rRot, DVector pointFrom)
{
	if (!m_pClientDE) return;

//	m_pServerDE->GetObjectPos(m_hObject, &vPos);
//	vTargetPos.y = vPos.y; // Don't look up/down.

	DVector vDir;
	VEC_SUB(vDir, pos, pointFrom);
	VEC_NORM(vDir);

	m_pClientDE->AlignRotation(&m_rRotation, &vDir, NULL);

	//m_Angles.Copy(m_Target.m_Angles);
	
	//m_Angles.z = angles.z;
	//m_Angles.x = angles.x;
/*	DVector vAngles;
	VEC_INIT(vAngles);

	m_rRotation = rRot;


	DFLOAT diffX = pos.x - m_vPos.x;
	DFLOAT diffY = pos.z - m_vPos.z;
	vAngles.y = (DFLOAT)atan2(diffX, diffY);

	DVector		target, copy;
	DVector	up, right, forward;

	m_pClientDE->GetRotationVectors(&m_rRotation, &up, &right, &forward);

	VEC_SUB(copy, pos, pointFrom);

	target = Apply(right, up, forward, copy);

	diffX = target.z;
	diffY = target.y;

	//DFLOAT temp = -ATan2(diffY,diffX);
	//if(Abs(temp - m_Angles.x) < .5)

	vAngles.x = (DFLOAT)-atan2(diffY, diffX);

	//PrintVector(pos);
	//GetClientShell().CPrint("X = " + RealStr(m_Angles.x));

	DRotation rOldRot;
	ROT_COPY(rOldRot, m_rRotation);

	m_pClientDE->SetupEuler(&m_rRotation, vAngles.x, vAngles.y, vAngles.z);

	// Make sure rotation is valid...

	m_pClientDE->GetRotationVectors(&m_rRotation, &up, &right, &forward);
	if (up.y < 0) ROT_COPY(m_rRotation, rOldRot);
*/
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerCamera::SetCameraState()
//
//	PURPOSE:	Set the state/orientation of the camera
//
// ----------------------------------------------------------------------- //
/*
void CPlayerCamera::SetCameraState(CameraState eOrientation)
{
	switch(eOrientation)
	{
		case SOUTHEAST:
			m_OptX = m_CameraDistDiag;
			m_OptY = m_CameraDistUp;
			m_OptZ = -m_CameraDistDiag;
		break;

		case EAST:
			m_OptX = m_CameraDistBack;
			m_OptY = m_CameraDistUp;
			m_OptZ = 0;
		break;

		case NORTHEAST:
			m_OptX = m_CameraDistDiag;
			m_OptY = m_CameraDistUp;
			m_OptZ = m_CameraDistDiag;
		break;

		case NORTH:
			m_OptX = 0;
			m_OptY = m_CameraDistUp;
			m_OptZ = m_CameraDistBack;
		break;

		case NORTHWEST:
			m_OptX = -m_CameraDistDiag;
			m_OptY = m_CameraDistUp;
			m_OptZ = m_CameraDistDiag;
		break;

		case WEST:
			m_OptX = -m_CameraDistBack;
			m_OptY = m_CameraDistUp;
			m_OptZ = 0;
		break;

		case SOUTHWEST:
			m_OptX = -m_CameraDistDiag;
			m_OptY = m_CameraDistUp;
			m_OptZ = -m_CameraDistDiag;
		break;

		case SOUTH:
			m_OptX = 0;
			m_OptY = m_CameraDistUp;
			m_OptZ = -m_CameraDistBack;
		break;

		case MLOOK:
			m_OptX = DEFAULT_CAMERA_DIST_MLOOK_X;
			m_OptY = DEFAULT_CAMERA_DIST_MLOOK_Y;
			m_OptZ = DEFAULT_CAMERA_DIST_MLOOK_Z;
		break;

		default:
		break;
	}

	m_eOrientation = eOrientation;

}
*/

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CPlayerCamera::RotateCameraState()
//
//	PURPOSE:	Rotate the camera clockwise or counterclockwise around 
//				the target
//
// ----------------------------------------------------------------------- //
/*
void CPlayerCamera::RotateCameraState(DBOOL bClockwise)
{
	switch(m_eOrientation)
	{
		case SOUTHEAST:
			if(bClockwise)
				SetCameraState(SOUTH);
			else
				SetCameraState(EAST);
		break;

		case EAST:
			if(bClockwise)
				SetCameraState(SOUTHEAST);
			else
				SetCameraState(NORTHEAST);
		break;

		case NORTHEAST:
			if(bClockwise)
				SetCameraState(EAST);
			else
				SetCameraState(NORTH);
		break;

		case NORTH:
			if(bClockwise)
				SetCameraState(NORTHEAST);
			else
				SetCameraState(NORTHWEST);
		break;

		case NORTHWEST:
			if(bClockwise)
				SetCameraState(NORTH);
			else
				SetCameraState(WEST);
		break;

		case WEST:
			if(bClockwise)
				SetCameraState(NORTHWEST);
			else
				SetCameraState(SOUTHWEST);
		break;

⌨️ 快捷键说明

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