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

📄 playercamera.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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 + -