void CPlayerRotation::ProcessNormal()
{
	m_upVector = Vec3::CreateSlerp(m_upVector, m_stats.upVector, min(5.0f * m_frameTime, 1.0f));
	//create a matrix perpendicular to the ground
	Vec3 up(m_upVector);
	//..or perpendicular to the linked object Z
	SLinkStats *pLinkStats = &m_player.m_linkStats;

	if (pLinkStats->linkID && pLinkStats->flags & LINKED_FREELOOK)
	{
		IEntity *pLinked = pLinkStats->GetLinked();

		if (pLinked)
		{
			up = pLinked->GetRotation().GetColumn2();
		}
	}

	Vec3 right(m_baseQuat.GetColumn0());
	Vec3 forward((up % right).GetNormalized());
	CHECKQNAN_VEC(up);
	CHECKQNAN_VEC(right);
	CHECKQNAN_VEC(forward);
	m_baseQuat = Quat(Matrix33::CreateFromVectors(forward % up, forward, up));
	//CHECKQNAN_MAT33(m_baseMtx);
	m_baseQuat *= Quat::CreateRotationZ(m_deltaAngles.z);
	//m_baseQuat.Normalize();
	m_viewQuat = m_baseQuat *
				 Quat::CreateRotationX(GetLocalPitch() + m_deltaAngles.x) *
				 Quat::CreateRotationY(m_viewRoll);
	//m_viewQuat.Normalize();
	//CHECKQNAN_MAT33(m_viewMtx);
}
示例#2
0
void CPlayerRotation::ProcessFinalViewEffects( float minAngle, float maxAngle )
{
	if (!m_player.IsClient())
	{
		m_viewQuatFinal = m_viewQuat;
	}
	else
	{
		Ang3 viewAngleOffset = m_frameViewAnglesOffset;

		float currentViewPitch = GetLocalPitch();
		float newPitch = clamp_tpl(currentViewPitch + viewAngleOffset.x, minAngle, maxAngle);
		viewAngleOffset.x = newPitch - currentViewPitch;

		m_viewQuatFinal = m_viewQuat * Quat::CreateRotationXYZ(viewAngleOffset);
	}

}
示例#3
0
void CPlayerRotation::ClampAngles()
{
	{
		//cap up/down looking
		float minAngle,maxAngle;
		GetStanceAngleLimits(minAngle,maxAngle);

		float currentViewPitch=GetLocalPitch();
		float newPitch = currentViewPitch + m_deltaAngles.x;

		if(newPitch < minAngle)
			newPitch = minAngle;
		else if(newPitch > maxAngle)
			newPitch = maxAngle;

		m_deltaAngles.x = newPitch - currentViewPitch;

	}

	{
		//further limit the view if necessary
		float limitV = m_params.vLimitRangeV;
		float limitH = m_params.vLimitRangeH;
		Vec3  limitDir = m_params.vLimitDir;
		float limitVUp = m_params.vLimitRangeVUp;
		float limitVDown = m_params.vLimitRangeVDown;

		if(m_player.m_stats.isFrozen.Value())
		{
			float clampMin = g_pGameCVars->cl_frozenAngleMin;
			float clampMax = g_pGameCVars->cl_frozenAngleMax;
			float frozenLimit = DEG2RAD(clampMin + (clampMax-clampMin)*(1.f-m_player.GetFrozenAmount(true)));

			if(limitV == 0 || limitV>frozenLimit)
				limitV = frozenLimit;

			if(limitH == 0 || limitH>frozenLimit)
				limitH = frozenLimit;

			if(g_pGameCVars->cl_debugFreezeShake)
			{
				static float color[] = {1,1,1,1};
				gEnv->pRenderer->Draw2dLabel(100,200,1.5,color,false,"limit: %f", RAD2DEG(frozenLimit));
			}
		}

		if(m_player.m_stats.isOnLadder)
		{
			limitDir = -m_player.m_stats.ladderOrientation;
			limitH = DEG2RAD(40.0f);
		}

		if((limitH+limitV+limitVUp+limitVDown) && limitDir.len2()>0.1f)
		{
			//A matrix is built around the view limit, and then the player view angles are checked with it.
			//Later, if necessary the upVector could be made customizable.
			Vec3 forward(limitDir);
			Vec3 up(m_baseQuat.GetColumn2());
			Vec3 right(-(up % forward));
			right.Normalize();

			Matrix33 limitMtx;
			limitMtx.SetFromVectors(right,forward,right%forward);
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(m_player.GetEntity()->GetWorldPos(), ColorB(0,0,255,255), m_player.GetEntity()->GetWorldPos() + limitMtx.GetColumn(0), ColorB(0,0,255,255));
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(m_player.GetEntity()->GetWorldPos(), ColorB(0,255,0,255), m_player.GetEntity()->GetWorldPos() + limitMtx.GetColumn(1), ColorB(0,255,0,255));
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(m_player.GetEntity()->GetWorldPos(), ColorB(255,0,0,255), m_player.GetEntity()->GetWorldPos() + limitMtx.GetColumn(2), ColorB(255,0,0,255));
			limitMtx.Invert();

			Vec3 localDir(limitMtx * m_viewQuat.GetColumn1());
//			Vec3 localDir(limitMtx * m_player.GetEntity()->GetWorldRotation().GetColumn1());

			Ang3 limit;

			if(limitV)
			{
				limit.x = asinf(localDir.z) + m_deltaAngles.x;

				float deltaX(limitV - fabs(limit.x));

				if(deltaX < 0.0f)
					m_deltaAngles.x += deltaX*(limit.x>0.0f?1.0f:-1.0f);
			}

			if(limitVUp || limitVDown)
			{
				limit.x = asinf(localDir.z) + m_deltaAngles.x;

				if(limit.x>=limitVUp && limitVUp!=0)
				{
					float deltaXUp(limitVUp - limit.x);
					m_deltaAngles.x += deltaXUp;
				}

				if(limit.x<=limitVDown && limitVDown!=0)
				{
					float deltaXDown(limitVDown - limit.x);
					m_deltaAngles.x += deltaXDown;
				}
			}

			if(limitH)
			{
				limit.z = cry_atan2f(-localDir.x,localDir.y) + m_deltaAngles.z;

				float deltaZ(limitH - fabs(limit.z));

				if(deltaZ < 0.0f)
					m_deltaAngles.z += deltaZ*(limit.z>0.0f?1.0f:-1.0f);
			}
		}
	}
}
示例#4
0
void CPlayerRotation::ClampAngles( float minAngle, float maxAngle )
{
	//Cap up/down looking
	{
		const float currentViewPitch = GetLocalPitch();
		const float newPitch = clamp_tpl(currentViewPitch + m_deltaAngles.x, minAngle, maxAngle);
		m_deltaAngles.x = newPitch - currentViewPitch;
	}

	//Further limit the view if necessary
	{
		const SViewLimitParams& viewLimits = m_player.m_params.viewLimits;

		const Vec3  limitDir = viewLimits.GetViewLimitDir();

		if (limitDir.len2() < 0.1f)
			return;
		
		const float limitV = viewLimits.GetViewLimitRangeV();
		const float limitH = viewLimits.GetViewLimitRangeH();
		const float limitVUp = viewLimits.GetViewLimitRangeVUp();
		const float limitVDown = viewLimits.GetViewLimitRangeVDown();

		if ((limitH+limitV+fabsf(limitVUp)+fabsf(limitVDown)) > 0.0f)
		{
			//A matrix is built around the view limit, and then the player view angles are checked with it.
			//Later, if necessary the upVector could be made customizable.
			const Vec3 forward(limitDir);
			const Vec3 up(m_baseQuat.GetColumn2());
			const Vec3 right((-(up % forward)).GetNormalized());

			Matrix33 limitMtx;
			limitMtx.SetFromVectors(right,forward,right%forward);
			limitMtx.Invert();

			const Vec3 localDir(limitMtx * m_viewQuat.GetColumn1());

			Ang3 limit;

			if (limitV)
			{
				limit.x = asinf(localDir.z) + m_deltaAngles.x;

				const float deltaX(limitV - fabs(limit.x));

				m_deltaAngles.x = m_deltaAngles.x + (float)__fsel(deltaX, 0.0f, deltaX * (float)__fsel(limit.x, 1.0f, -1.0f));
			}

			if (limitVUp || limitVDown)
			{
				limit.x = asinf(localDir.z) + m_deltaAngles.x;

				const float deltaXUp(limitVUp - limit.x);
				float fNewDeltaX = m_deltaAngles.x;

				const float fDeltaXUpIncrement = (float)__fsel( deltaXUp, 0.0f, deltaXUp);
				fNewDeltaX = fNewDeltaX + (float)__fsel(-fabsf(limitVUp), 0.0f, fDeltaXUpIncrement);

				const float deltaXDown(limitVDown - limit.x);

				const float fDeltaXDownIncrement = (float)__fsel( deltaXDown, deltaXDown, 0.0f);
				fNewDeltaX = fNewDeltaX + (float)__fsel(-fabsf(limitVDown), 0.0f, fDeltaXDownIncrement);

				m_deltaAngles.x = fNewDeltaX;
			}

			if (limitH)
			{
				limit.z = atan2_tpl(-localDir.x,localDir.y) + m_deltaAngles.z;

				const float deltaZ(limitH - fabs(limit.z));

				m_deltaAngles.z = m_deltaAngles.z + (float)__fsel(deltaZ, 0.0f, deltaZ * (float)__fsel(limit.z, 1.0f, -1.0f));
			}
		}
	}
}
示例#5
0
void CPlayerRotation::ProcessNormal()
{
	m_upVector = Vec3::CreateSlerp(m_upVector,m_stats.upVector,min(5.0f*m_frameTime, 1.0f));

	//create a matrix perpendicular to the ground
	Vec3 up(m_upVector);
	//..or perpendicular to the linked object Z
	SLinkStats *pLinkStats = &m_player.m_linkStats;
	if (pLinkStats->linkID && pLinkStats->flags & LINKED_FREELOOK)
	{
		IEntity *pLinked = pLinkStats->GetLinked();
		if (pLinked)
			up = pLinked->GetRotation().GetColumn2();
	}
	
	Vec3 right(m_baseQuat.GetColumn0());
	Vec3 forward((up % right).GetNormalized());

	CHECKQNAN_VEC(up);
	CHECKQNAN_VEC(right);
	CHECKQNAN_VEC(forward);

	m_baseQuat = Quat(Matrix33::CreateFromVectors(forward % up,forward,up));
	
	
	//CHECKQNAN_MAT33(m_baseMtx);

	// todo: if this works apply the delta yaw from VR input as well...
	//CryLogAlways("Engine Delta yaw: %f", m_deltaAngles.z);

	
	 m_baseQuat *= Quat::CreateRotationZ(m_deltaAngles.z);
	//m_baseQuat.Normalize();

	m_viewQuat = m_baseQuat * 
		Quat::CreateRotationX(GetLocalPitch() + m_deltaAngles.x) * 
		Quat::CreateRotationY(m_viewRoll);


	

	// Apply view data from trackers, base matrix probably includes yaw orientation already... (not totally ok but for now)
	if (m_player.IsClient() && g_vr->initialized())
	{	
		// base engine yaw that new read deltas should be applied onto for all tracking devices
		float baseYaw = m_baseQuat.GetRotZ();
		
		g_vr->update(baseYaw);	

		Ang3 angle;
		
		g_vr->headOrientation(angle);

		// apply the tracked yaw delta 
		m_baseQuat *= Quat::CreateRotationZ(angle.z - baseYaw);

		float baseYawAfter = m_baseQuat.GetRotZ();
		
		m_viewQuat = m_baseQuat * 
			Quat::CreateRotationX(angle.x) * 
			Quat::CreateRotationY(angle.y);
	}
	
	//m_viewQuat.Normalize();

	//CHECKQNAN_MAT33(m_viewMtx);
}