📄 playercamera.cpp
字号:
case SOUTHWEST:
if(bClockwise)
SetCameraState(WEST);
else
SetCameraState(SOUTH);
break;
case SOUTH:
if(bClockwise)
SetCameraState(SOUTHWEST);
else
SetCameraState(SOUTHEAST);
break;
default:
break;
}
}
*/
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::MoveCameraToPosition()
//
// PURPOSE: Move the camera to a position over a time period
//
// ----------------------------------------------------------------------- //
void CPlayerCamera::MoveCameraToPosition(DVector pos, DVector vStartPos, DFLOAT deltaTime)
{
if (!m_pClientDE || !m_hTarget) return;
DFLOAT nCurrentTime = m_pClientDE->GetTime();
// Handle transition
if (m_eCameraMode == GOINGFIRSTPERSON || m_eCameraMode == GOINGCHASE || m_eCameraMode == DEATH)
{
if (nCurrentTime > m_fTransitionStart + m_fTransitionTime)
{
switch (m_eCameraMode)
{
case GOINGFIRSTPERSON:
m_eCameraMode = FIRSTPERSON;
break;
case GOINGCHASE:
m_eCameraMode = CHASE;
break;
}
}
else
{
// vStartPos is starting pos, pos is the position we want
DFLOAT percentage = (nCurrentTime - m_fTransitionStart) / (m_fTransitionTime);
DVector vMagnitude;
VEC_SUB (vMagnitude, pos, vStartPos);
VEC_MULSCALAR (vMagnitude, vMagnitude, percentage);
VEC_ADD (pos, vStartPos, vMagnitude);
}
}
DVector dir;
VEC_SUB(dir, pos, m_vPos);
DFLOAT multiplier = 1.0f; // 0.5f;
DVector toMove;
VEC_MULSCALAR(toMove, dir, multiplier);
DFLOAT moveMag;
if(m_bSlide)
{
moveMag = VEC_MAG(toMove);
if(moveMag > VEC_MAG(dir))
moveMag = VEC_MAG(dir);
if (toMove.x != 0.0f || toMove.y != 0.0f || toMove.z != 0.0f)
{
VEC_NORM(toMove);
}
VEC_MULSCALAR(toMove, toMove, moveMag);
VEC_ADD(m_vPos, m_vPos, toMove);
}
else
{
VEC_COPY(m_vPos, pos);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::FindOptimalCameraPosition()
//
// PURPOSE: Find the optimal camera position
//
// ----------------------------------------------------------------------- //
DVector CPlayerCamera::FindFirstPersonCameraPosition(DVector vPos, DVector vF)
{
DVector vTemp;
VEC_MULSCALAR(vTemp, vF, m_TargetFirstPersonOffset.x);
VEC_ADD(vPos, vPos, vTemp);
vPos.y += m_TargetFirstPersonOffset.y;
return vPos;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::FindOptimalCameraPosition()
//
// PURPOSE: Find the optimal camera position
//
// ----------------------------------------------------------------------- //
DVector CPlayerCamera::FindOptimalCameraPosition()
{
DVector pos;
VEC_INIT(pos);
if (!m_pClientDE || !m_hTarget) return pos;
DVector up, right, forward, dir;
DFLOAT distToOptimal;
DVector TargetPlusOffset;
DVector vTargetPos;
m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos);
DRotation rRot;
m_pClientDE->GetObjectRotation(m_hTarget, &rRot);
if (Equal(vTargetPos, m_vLastTargetPos) && Equal(rRot, m_rLastTargetRot) && m_eCameraMode != DEATH)
{
return m_vLastOptPos;
}
else
{
VEC_COPY(m_vLastTargetPos, vTargetPos);
ROT_COPY(m_rLastTargetRot, rRot);
}
DVector vTemp;
if (m_eCameraMode == DEATH)
{
VEC_COPY(vTemp, m_TargetDeathOffset);
}
else
{
VEC_COPY(vTemp, m_TargetChaseOffset);
}
VEC_ADD(vTemp, vTargetPos, vTemp);
VEC_COPY(TargetPlusOffset, vTemp);
m_pClientDE->GetRotationVectors(&rRot, &up, &right, &forward);
// pos = TargetPlusOffset + right*m_OptX + up*m_OptY + forward*m_OptZ;
DVector vTemp1, vTemp2;
if (m_eCameraMode == DEATH)
{
VEC_MULSCALAR(vTemp, right, m_DeathOptX);
VEC_MULSCALAR(vTemp2, forward, m_DeathOptZ);
}
else
{
VEC_MULSCALAR(vTemp, right, m_OptX);
VEC_MULSCALAR(vTemp2, forward, m_OptZ);
}
VEC_MULSCALAR(vTemp1, up, m_OptY);
ClientIntersectQuery iQuery;
ClientIntersectInfo iInfo;
VEC_ADD(vTemp, vTemp, vTemp1);
VEC_ADD(vTemp, vTemp, vTemp2);
VEC_ADD(pos, TargetPlusOffset, vTemp);
VEC_SUB(vTemp, TargetPlusOffset, pos);
distToOptimal = VEC_MAG(vTemp);
VEC_SUB(dir, pos, TargetPlusOffset);
VEC_NORM(dir);
VEC_COPY(iQuery.m_From, TargetPlusOffset);
VEC_COPY(iQuery.m_To, pos);
if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
{
VEC_SUB(vTemp, iInfo.m_Point, TargetPlusOffset);
// If there was something in the way, move in front of that thing.
if (VEC_MAG(vTemp) < distToOptimal)
{
VEC_ADD(pos, iInfo.m_Point, iInfo.m_Plane.m_Normal);
}
}
#ifdef DOING_EXTRA_CHECKS
// Make sure we aren't clipping into walls...
DFLOAT fClipDistance = 100.0f; // 15.0f;
DBOOL bClipRightIssues = DTRUE;
DBOOL bClipUpIssues = DTRUE;
// Check for walls to the right...
VEC_MULSCALAR(vTemp, right, fClipDistance);
VEC_ADD(vTemp, pos, vTemp);
VEC_COPY(iQuery.m_From, pos);
VEC_COPY(iQuery.m_To, vTemp);
if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
{
VEC_SUB(vTemp, iInfo.m_Point, pos);
DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));
VEC_MULSCALAR(vTemp, right, -fDist)
VEC_ADD(pos, pos, vTemp);
}
else
{
bClipRightIssues = DFALSE;
}
// If we didn't adjust for a wall to the right, check walls to the left...
if (!bClipRightIssues)
{
VEC_MULSCALAR(vTemp, right, -fClipDistance);
VEC_ADD(vTemp, pos, vTemp);
VEC_COPY(iQuery.m_From, pos);
VEC_COPY(iQuery.m_To, vTemp);
if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
{
VEC_SUB(vTemp, iInfo.m_Point, pos);
DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));
VEC_MULSCALAR(vTemp, right, fDist)
VEC_ADD(pos, pos, vTemp);
}
}
// Check for ceilings...
VEC_MULSCALAR(vTemp, up, fClipDistance);
VEC_ADD(vTemp, pos, vTemp);
VEC_COPY(iQuery.m_From, pos);
VEC_COPY(iQuery.m_To, vTemp);
if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
{
VEC_SUB(vTemp, iInfo.m_Point, pos);
DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));
VEC_MULSCALAR(vTemp, up, -fDist)
VEC_ADD(pos, pos, vTemp);
}
else
{
bClipUpIssues = DFALSE;
}
// If we didn't hit any ceilings, check for floors...
if (!bClipUpIssues)
{
VEC_MULSCALAR(vTemp, up, -fClipDistance);
VEC_ADD(vTemp, pos, vTemp);
VEC_COPY(iQuery.m_From, pos);
VEC_COPY(iQuery.m_To, vTemp);
if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
{
VEC_SUB(vTemp, iInfo.m_Point, pos);
DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));
VEC_MULSCALAR(vTemp, up, fDist)
VEC_ADD(pos, pos, vTemp);
}
}
#endif // DOING_EXTRA_CHECKS
VEC_COPY(m_vLastOptPos, pos);
return pos;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::PrintVector()
//
// PURPOSE: Print it!
//
// ----------------------------------------------------------------------- //
void CPlayerCamera::PrintVector(DVector v)
{
if (!m_pClientDE) return;
char buf[50];
sprintf(buf, "x = %f, y = %f, z = %f", v.x, v.y, v.z);
m_pClientDE->CPrint(buf);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::StartCircle()
//
// PURPOSE: Start the circle...jerk!
//
// ----------------------------------------------------------------------- //
void CPlayerCamera::StartCircle()
{
if (!m_pClientDE || !m_hTarget) return;
/*
if(m_eCameraMode == DEATH)
{
m_CircleHeightOffset = HeightOffset;
m_CircleRadius = Radius;
m_CircleHeightOffset = PointAtOffset;
m_CircleTime = Time;
m_bStartCircle = DFALSE;
DVector vTargetPos, up, right, forward;
DRotation rRot;
m_pClientDE->GetObjectRotation(m_hTarget, &rRot);
m_pClientDE->GetRotationVectors(&rRot, &up, &right, &forward);
m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos);
*/
// SaveState();
// SaveCameraMode();
//GetClientShell().CPrint("Going circle");
// m_eCameraMode = CIRCLING;
m_CircleStartTime = m_pClientDE->GetTime();
/*
// m_Pos.Copy(m_Target.m_Pos + right*0 + up*m_CircleHeightOffset - forward*m_CircleRadius);
DVector vTemp, vTemp1;
VEC_MULSCALAR(vTemp, forward, m_CircleRadius);
VEC_MULSCALAR(vTemp1, up, m_CircleHeightOffset);
VEC_SUB(vTemp, vTemp1, vTemp);
VEC_ADD(m_vPos, vTargetPos, vTemp);
// PointAtPosition(m_Target.m_Pos+CreateVector(0,m_CircleHeightOffset,0), m_Target.m_Angles, m_Pos);
VEC_SET(vTemp, 0.0f, m_CircleHeightOffset, 0.0f);
VEC_ADD(vTemp, vTargetPos, vTemp);
PointAtPosition(vTemp, rRot, m_vPos);
// m_SaveAnglesY = m_Angles.y;
}
*/
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::CircleAroundTarget()
//
// PURPOSE: Circle the target
//
// ----------------------------------------------------------------------- //
void CPlayerCamera::CircleAroundTarget()
{
if (!m_pClientDE || !m_hTarget) return;
DVector vTargetPos;
DRotation rRot;
DVector vU, vR, vF;
DFLOAT fTimeDelta = m_pClientDE->GetTime() - m_CircleStartTime;
DFLOAT fAngle = fTimeDelta * DEFAULT_ROTATE_SPEED; // * MATH_PI * 2;
fAngle = (DFLOAT)fmod(fAngle, MATH_PI*2);
m_pClientDE->GetObjectRotation(m_hTarget, &rRot);
m_pClientDE->EulerRotateY(&rRot, fAngle);
m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos);
VEC_MULSCALAR(vF, vF, -m_CameraDistBack*1.2f)
// VEC_ADD(vTargetPos, vTargetPos, vF);
m_DeathOptX = vF.x;
m_DeathOptZ = vF.z;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::VCompare()
//
// PURPOSE: Compare two vectors
//
// ----------------------------------------------------------------------- //
DBOOL CPlayerCamera::VCompare(DVector a, DVector b)
{
if((fabs(a.x - b.x) > 5.0f) || (fabs(a.y - b.y) > 5.0f) || (fabs(a.z - b.z) > 5.0f))
return DFALSE;
else
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CPlayerCamera::AttachToObject()
//
// PURPOSE: Attach camera to an object
//
// ----------------------------------------------------------------------- //
void CPlayerCamera::AttachToObject(HLOCALOBJ hObj)
{
m_hTarget = hObj;
// Initialize our position to that of the object...
if (hObj && m_pClientDE)
{
m_pClientDE->GetObjectPos(hObj, &m_vPos);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -