📄 playercamera.cpp
字号:
// ----------------------------------------------------------------------- //
//
// 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 + -