Exemple #1
0
void CPlayerRotation::Process()
{
	//FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	//
	float forceLookLen2(m_player.m_stats.forceLookVector.len2());
	if (forceLookLen2>0.001f && !g_vr->initialized()) // no forced look in VR please
	{
		float forceLookLen(cry_sqrtf(forceLookLen2));
		Vec3 forceLook(m_player.m_stats.forceLookVector);
		forceLook *= 1.0f/forceLookLen;
		forceLook = m_player.m_viewQuatFinal.GetInverted() * forceLook;

		float smoothSpeed(6.6f * forceLookLen);
		m_deltaAngles.x += asin(forceLook.z) * min(1.0f,m_frameTime*smoothSpeed);
		m_deltaAngles.z += cry_atan2f(-forceLook.x,forceLook.y) * min(1.0f,m_frameTime*smoothSpeed);

		CHECKQNAN_VEC(m_deltaAngles);
	}

	ProcessAngularImpulses();
	ProcessLean();
	
	if (m_stats.inAir && m_stats.inZeroG)
		ProcessFlyingZeroG();
	else if (m_stats.inFreefall.Value()==1)
		ProcessFreeFall();
	else if (m_stats.inFreefall.Value()==2)
		ProcessParachute();
	else
	{
		if(!g_vr->initialized())
		{
			ProcessNormalRoll();
			ClampAngles();
		}
		ProcessNormal();
	}

	//CHECKQNAN_MAT33(m_viewMtx);

	//update freelook when linked to an entity
	SLinkStats *pLinkStats = &m_player.m_linkStats;
	if (pLinkStats->linkID)
	{
		IEntity *pLinked = pLinkStats->GetLinked();
		if (pLinked)
		{
			//at this point m_baseQuat and m_viewQuat contain the previous frame rotation, I'm using them to calculate the delta rotation.
			m_baseQuatLinked *= m_player.m_baseQuat.GetInverted() * m_baseQuat;
			m_viewQuatLinked *= m_player.m_viewQuat.GetInverted() * m_viewQuat;

			m_baseQuat = pLinked->GetRotation() * m_baseQuatLinked;
			m_viewQuat = pLinked->GetRotation() * m_viewQuatLinked;
		}
	}
	//

	m_viewQuatFinal = m_viewQuat; //TEST:  * Quat::CreateRotationXYZ(m_player.m_viewAnglesOffset);
}
void CPlayerRotation::ProcessParachute()
{
	//thats necessary when passing from groundG to normalG
	//m_baseQuat = m_viewQuat;
	Ang3 desiredAngVel(m_deltaAngles.x, m_deltaAngles.y * 0.5f - m_deltaAngles.z * 1.0f, m_deltaAngles.z);
	float rotInertia(7.7f);
	//align to gravity vector
	Vec3 vRef(m_viewQuat.GetInverted() * Vec3(0, 0, 1));
	float alignAngleY = cry_atan2f(vRef.x, vRef.z);
	desiredAngVel.y += alignAngleY * 0.05f;
	Interpolate(m_angularVel, desiredAngVel, rotInertia, m_frameTime);
	Ang3 finalAngle(m_angularVel + m_angularImpulseDelta);
	//limit Z angle
	float viewPitch(GetLocalPitch());
	float zLimit(-1.3f);

	if (viewPitch + finalAngle.x < zLimit)
	{
		finalAngle.x = zLimit - viewPitch;
	}

	m_viewQuat *= Quat::CreateRotationZ(finalAngle.z) * Quat::CreateRotationX(finalAngle.x) * Quat::CreateRotationY(finalAngle.y);
	m_viewQuat.Normalize();
	Vec3 up(Vec3(0, 0, 1));
	Vec3 right(m_viewQuat.GetColumn0());
	Vec3 forward((up % right).GetNormalized());
	m_baseQuat = Quat(Matrix33::CreateFromVectors(forward % up, forward, up));
	//m_viewQuat = m_baseQuat;
	m_viewRoll = 0;
	m_upVector = m_baseQuat.GetColumn2();
}
Exemple #3
0
void CPlayerRotation::ProcessForcedLookDirection( const Quat& lastViewQuat, float frameTime )
{
	const float forceLookLenSqr(m_forceLookVector.len2());
	
	if (forceLookLenSqr < 0.001f)
		return;
	
	const float forceLookLen(cry_sqrtf(forceLookLenSqr));
	Vec3 forceLook(m_forceLookVector);
	forceLook *= (float)__fres(forceLookLen);
	forceLook = lastViewQuat.GetInverted() * forceLook;

	const float smoothSpeed(6.6f * forceLookLen);

	float blendAmount = min(1.0f,frameTime*smoothSpeed);
	if(!m_bForcedLookAtBlendingEnabled)
	{
		blendAmount = 1.0f; 
	}

	m_deltaAngles.x += asinf(forceLook.z) * blendAmount;
	m_deltaAngles.z += cry_atan2f(-forceLook.x,forceLook.y) * blendAmount;

	PR_CHECKQNAN_VEC(m_deltaAngles);
}
Exemple #4
0
void CNetPlayerInput::DoSetState(const SSerializedPlayerInput& input )
{
	m_curInput = input;
	m_pPlayer->GetGameObject()->ChangedNetworkState( INPUT_ASPECT );

	CMovementRequest moveRequest;
	moveRequest.SetStance( (EStance)m_curInput.stance );

	if(IsDemoPlayback())
	{
		Vec3 localVDir(m_pPlayer->GetViewQuatFinal().GetInverted() * m_curInput.lookDirection);
		Ang3 deltaAngles(asin(localVDir.z),0,cry_atan2f(-localVDir.x,localVDir.y));
		moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime());
	}
	//else
	{
		moveRequest.SetLookTarget( m_pPlayer->GetEntity()->GetWorldPos() + 10.0f * m_curInput.lookDirection );
		moveRequest.SetAimTarget(moveRequest.GetLookTarget());
	}

	float pseudoSpeed = 0.0f;
	if (m_curInput.deltaMovement.len2() > 0.0f)
	{
		pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_curInput.sprint);
	}
	moveRequest.SetPseudoSpeed(pseudoSpeed);
	moveRequest.SetAllowStrafing(true);

	float lean=0.0f;
	if (m_curInput.leanl)
		lean-=1.0f;
	if (m_curInput.leanr)
		lean+=1.0f;
	moveRequest.SetLean(lean);

	m_pPlayer->GetMovementController()->RequestMovement(moveRequest);

	// debug..
	if (g_pGameCVars->g_debugNetPlayerInput & 1)
	{
		IPersistantDebug * pPD = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug();
		pPD->Begin( string("net_player_input_") + m_pPlayer->GetEntity()->GetName(), true );
		pPD->AddSphere( moveRequest.GetLookTarget(), 0.5f, ColorF(1,0,1,1), 1.0f );
		//			pPD->AddSphere( moveRequest.GetMoveTarget(), 0.5f, ColorF(1,1,0,1), 1.0f );

		Vec3 wp(m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,2));
		pPD->AddDirection( wp, 1.5f, m_curInput.deltaMovement, ColorF(1,0,0,1), 1.0f );
		pPD->AddDirection( wp, 1.5f, m_curInput.lookDirection, ColorF(0,1,0,1), 1.0f );
	}
}
    void CCoherentUISystem::UpdateHUD()
    {
        static Vec3 lastPosition = Vec3Constants<Vec3::value_type>::fVec3_Zero;
        static float lastRotation = 0;

        CCoherentViewListener* pHUDListener = NULL;
        pHUDListener = ( m_HudViewListener ? m_HudViewListener.get() : NULL );

        if ( pHUDListener )
        {
            CCamera& camera = gEnv->pSystem->GetViewCamera();
            Vec3 viewDir = camera.GetViewdir();
            float rotation = cry_atan2f( viewDir.y, viewDir.x ) * 180.0f / 3.14159f;
            // Adjust rotation so it is the same as in the game
            rotation = -rotation - 135.0f;
            Coherent::UI::View* pView = pHUDListener->GetView();

            if ( pView && pHUDListener->IsReadyForBindings() )
            {
                if ( rotation != lastRotation )
                {
                    pView->TriggerEvent( "SetAbsoluteCompassRotation", rotation );
                    // Adjust the rotation for the map, too...
                    pView->TriggerEvent( "SetPlayerRotationOnMap", rotation - 45.0f );

                    lastRotation = rotation;
                }

                Vec3 cameraPosition = camera.GetPosition();

                if ( ( cameraPosition - lastPosition ).GetLengthSquared() > VEC_EPSILON )
                {
                    pView->TriggerEvent( "SetPlayerPositionOnMap", cameraPosition.x, cameraPosition.y );

                    lastPosition = cameraPosition;
                }
            }
        }
    }
Exemple #6
0
void CNetPlayerInput::DoSetState(const SSerializedPlayerInput& input )
{
	// PLAYERPREDICTION
	m_newInterpolation |= (input.position != m_curInput.position) || (input.deltaMovement != m_curInput.deltaMovement);

	m_curInput = input;
	CHANGED_NETWORK_STATE(m_pPlayer,  IPlayerInput::INPUT_ASPECT );

	// not having these set seems to stop a remote avatars rotation being reflected
	m_curInput.aiming = true;
	m_curInput.allowStrafing = true;
	m_curInput.usinglookik = true;
	// ~PLAYERPREDICTION

	IAIActor* pAIActor = CastToIAIActorSafe(m_pPlayer->GetEntity()->GetAI());
	if (pAIActor)
		pAIActor->GetState().bodystate=input.bodystate;

	CMovementRequest moveRequest;
	moveRequest.SetStance( (EStance)m_curInput.stance );

	if(IsDemoPlayback())
	{
		Vec3 localVDir(m_pPlayer->GetViewQuatFinal().GetInverted() * m_curInput.lookDirection);
		Ang3 deltaAngles(asinf(localVDir.z),0,cry_atan2f(-localVDir.x,localVDir.y));
		moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime());
	}
	{
		if (m_curInput.usinglookik)
			moveRequest.SetLookTarget( m_pPlayer->GetEntity()->GetWorldPos() + 10.0f * m_curInput.lookDirection );
		else
			moveRequest.ClearLookTarget();
		if (m_curInput.aiming)
			moveRequest.SetAimTarget(moveRequest.GetLookTarget());
		else
			moveRequest.ClearAimTarget();
	}
/*
	float pseudoSpeed = 0.0f; 
	if (m_curInput.deltaMovement.len2() > 0.0f)
	{
		pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_curInput.sprint);
	}
	*/
	// PLAYERPREDICTION
	moveRequest.SetPseudoSpeed(CalculatePseudoSpeed());
	// ~PLAYERPREDICTION
	moveRequest.SetAllowStrafing(input.allowStrafing);

	float lean=0.0f;
	if (m_curInput.leanl)
		lean-=1.0f;
	if (m_curInput.leanr)
		lean+=1.0f;
	moveRequest.SetLean(lean);

	m_pPlayer->GetMovementController()->RequestMovement(moveRequest);

	IAnimationGraphState *pState=0;
	if (m_pPlayer->GetAnimatedCharacter())
		pState=m_pPlayer->GetAnimatedCharacter()->GetAnimationGraphState();
		
// PLAYERPREDICTION
	if (pState)
	{
		pState->SetInput(m_pPlayer->m_inputAiming, m_curInput.aiming);
		pState->SetInput(m_pPlayer->m_inputUsingLookIK, m_curInput.usinglookik);
	}

#if !defined(_RELEASE)
	// debug..
	if (g_pGameCVars->g_debugNetPlayerInput & 1)
	{
		IPersistantDebug * pPD = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug();
		pPD->Begin( string("net_player_input_") + m_pPlayer->GetEntity()->GetName(), true );
		pPD->AddSphere( moveRequest.GetLookTarget(), 0.5f, ColorF(1,0,1,1), 1.0f );
		//			pPD->AddSphere( moveRequest.GetMoveTarget(), 0.5f, ColorF(1,1,0,1), 1.0f );

		Vec3 wp(m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,2));
		pPD->AddDirection( wp, 1.5f, m_curInput.deltaMovement, ColorF(1,0,0,1), 1.0f );
		pPD->AddDirection( wp, 1.5f, m_curInput.lookDirection, ColorF(0,1,0,1), 1.0f );
	}
#endif
// ~PLAYERPREDICTION
}
Exemple #7
0
void CNetPlayerInput::UpdateMoveRequest()
{
	CMovementRequest moveRequest;
	SMovementState moveState;
	m_pPlayer->GetMovementController()->GetMovementState(moveState);
	Quat worldRot = m_pPlayer->GetBaseQuat(); // m_pPlayer->GetEntity()->GetWorldRotation();
	Vec3 deltaMovement = worldRot.GetInverted().GetNormalized() * m_curInput.deltaMovement;
	// absolutely ensure length is correct
	deltaMovement = deltaMovement.GetNormalizedSafe(ZERO) * m_curInput.deltaMovement.GetLength();
	moveRequest.AddDeltaMovement( deltaMovement );
	if( IsDemoPlayback() )
	{
		Vec3 localVDir(m_pPlayer->GetViewQuatFinal().GetInverted() * m_curInput.lookDirection);
		Ang3 deltaAngles(asinf(localVDir.z),0,cry_atan2f(-localVDir.x,localVDir.y));
		moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime());
	}
	//else
	{
		//--- Vector slerp actually produces QNans if the vectors are exactly opposite, in that case snap to the target
		if (m_lookDir.Dot(m_curInput.lookDirection) < (float)-0.99f)
		{
			m_lookDir = m_curInput.lookDirection;
		}
		else
		{
			m_lookDir.SetSlerp(m_lookDir, m_curInput.lookDirection, g_pGameCVars->pl_netAimLerpFactor);
		}

		Vec3 distantTarget = moveState.eyePosition + 1000.0f * m_lookDir;
		Vec3 lookTarget = distantTarget;

		if (m_curInput.usinglookik)
			moveRequest.SetLookTarget( lookTarget );
		else
			moveRequest.ClearLookTarget();

		if (m_curInput.aiming)
			moveRequest.SetAimTarget( lookTarget );
		else
			moveRequest.ClearAimTarget();

		if (m_curInput.deltaMovement.GetLengthSquared() > sqr(0.02f)) // 0.2f is almost stopped
			moveRequest.SetBodyTarget( distantTarget );
		else
			moveRequest.ClearBodyTarget();
	}

	moveRequest.SetAllowStrafing(m_curInput.allowStrafing);

	if(m_pPlayer->IsPlayer())
		moveRequest.SetPseudoSpeed(CalculatePseudoSpeed());
	else
		moveRequest.SetPseudoSpeed(m_curInput.pseudoSpeed);

	float lean=0.0f;
	if (m_curInput.leanl)
		lean-=1.0f;
	if (m_curInput.leanr)
		lean+=1.0f;

	if (fabsf(lean)>0.01f)
		moveRequest.SetLean(lean);
	else
		moveRequest.ClearLean();

	moveRequest.SetStance( (EStance)m_curInput.stance );

	m_pPlayer->GetMovementController()->RequestMovement(moveRequest);

	if (m_curInput.sprint)
		m_pPlayer->m_actions |= ACTION_SPRINT;
	else
		m_pPlayer->m_actions &= ~ACTION_SPRINT;

	if (m_curInput.leanl)
		m_pPlayer->m_actions |= ACTION_LEANLEFT;
	else
		m_pPlayer->m_actions &= ~ACTION_LEANLEFT;

	if (m_curInput.leanr)
		m_pPlayer->m_actions |= ACTION_LEANRIGHT;
	else
		m_pPlayer->m_actions &= ~ACTION_LEANRIGHT;

#if !defined(_RELEASE)
	// debug..
	if (g_pGameCVars->g_debugNetPlayerInput & 2)
	{
		IPersistantDebug * pPD = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug();
		pPD->Begin( string("update_player_input_") + m_pPlayer->GetEntity()->GetName(), true );
		Vec3 wp = m_pPlayer->GetEntity()->GetWorldPos();
		wp.z += 2.0f;
		pPD->AddSphere( moveRequest.GetLookTarget(), 0.5f, ColorF(1,0,1,0.3f), 1.0f );
		//		pPD->AddSphere( moveRequest.GetMoveTarget(), 0.5f, ColorF(1,1,0,0.3f), 1.0f );
		pPD->AddDirection( m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,2), 1, m_curInput.deltaMovement, ColorF(1,0,0,0.3f), 1.0f );
	}
#endif

	//m_curInput.deltaMovement.zero();
}
Exemple #8
0
void CPlayerInput::PreUpdate()
{
	CMovementRequest request;
	
	// get rotation into a manageable form
	float mouseSensitivity;
	if (m_pPlayer->InZeroG())
		mouseSensitivity = 0.00333f*MAX(0.01f, g_pGameCVars->cl_sensitivityZeroG);
	else
		mouseSensitivity = 0.00333f*MAX(0.01f, g_pGameCVars->cl_sensitivity);

	mouseSensitivity *= gf_PI / 180.0f;//doesnt make much sense, but after all helps to keep reasonable values for the sensitivity cvars
	//these 2 could be moved to CPlayerRotation
	mouseSensitivity *= m_pPlayer->m_params.viewSensitivity;
	mouseSensitivity *= m_pPlayer->GetMassFactor();
	COffHand * pOffHand=static_cast<COffHand*>(m_pPlayer->GetWeaponByClass(CItem::sOffHandClass));
	if(pOffHand && (pOffHand->GetOffHandState()&eOHS_HOLDING_NPC))
		mouseSensitivity *= pOffHand->GetObjectMassScale();

	// When carrying object/enemy, adapt mouse sensitiviy to feel the weight
	// Designers requested we ignore single-handed objects (1 == m_iCarryingObject)
	if(2 == m_iCarryingObject)
	{
		mouseSensitivity /= 2.0f;
	}

	if(m_fCrouchPressedTime>0.0f)
	{
		float fNow = gEnv->pTimer->GetAsyncTime().GetMilliSeconds();
		if((fNow - m_fCrouchPressedTime) > 300.0f)
		{
			if(m_actions & ACTION_CROUCH)
			{
				m_actions &= ~ACTION_CROUCH;
				m_actions |= ACTION_PRONE;
			}
			m_fCrouchPressedTime = -1.0f;
		}
	}

	Ang3 deltaRotation(m_deltaRotation * mouseSensitivity);

	if (m_pStats->isFrozen.Value() && m_pPlayer->IsPlayer() && m_pPlayer->GetHealth()>0)
	{
		float sMin = g_pGameCVars->cl_frozenSensMin;
		float sMax = g_pGameCVars->cl_frozenSensMax;

		float mult = sMin + (sMax-sMin)*(1.f-m_pPlayer->GetFrozenAmount(true));    
		deltaRotation *= mult;

		m_pPlayer->UpdateUnfreezeInput(m_deltaRotation, m_deltaMovement-m_deltaMovementPrev, mult);
	}

	// apply rotation from xinput controller
	if(!m_bDisabledXIRot)
	{
		// Controller framerate compensation needs frame time! 
		// The constant is to counter for small frame time values.
		// adjust some too small values, should be handled differently later on
		Ang3 xiDeltaRot=m_xi_deltaRotation*gEnv->pTimer->GetFrameTime() * mouseSensitivity * 50.0f;
		SmoothControllerInput(xiDeltaRot);
		ControlCameraMode();

		// Applying aspect modifiers
		if (g_pGameCVars->ctrl_aspectCorrection > 0)
		{
			int vx, vy, vw, vh;
			gEnv->pRenderer->GetViewport(&vx, &vy, &vw, &vh);
			float med=((float)vw+vh)/2.0f;
			float crW=((float)vw)/med;
			float crH=((float)vh)/med;
			xiDeltaRot.x*=g_pGameCVars->ctrl_aspectCorrection == 2 ? crW : crH;
			xiDeltaRot.z*=g_pGameCVars->ctrl_aspectCorrection == 2 ? crH : crW;
		}

		if(g_pGameCVars->cl_invertController)
			xiDeltaRot.x*=-1;

		deltaRotation+=xiDeltaRot;

		IVehicle *pVehicle = m_pPlayer->GetLinkedVehicle();
		if (pVehicle)
		{
			if (m_pPlayer->m_pVehicleClient)
			{
				m_pPlayer->m_pVehicleClient->PreUpdate(pVehicle, m_pPlayer->GetEntityId(), gEnv->pTimer->GetFrameTime());
			}

			//FIXME:not really good
			m_actions = 0;
			m_deltaMovement.Set(0,0,0);
			m_deltaRotation.Set(0,0,0);
		}
	}

	if(m_bUseXIInput)
	{
		m_deltaMovement.x = m_xi_deltaMovement.x;
		m_deltaMovement.y = m_xi_deltaMovement.y;
		m_deltaMovement.z = 0;

		if (m_xi_deltaMovement.len2()>0.0f)
			m_actions |= ACTION_MOVE;
		else
			m_actions &= ~ACTION_MOVE;
	}

	bool animControlled(m_pPlayer->m_stats.animationControlled);

	// If there was a recent serialization, ignore the delta rotation, since it's accumulated over several frames.
	if ((m_lastSerializeFrameID + 2) > gEnv->pRenderer->GetFrameID())
		deltaRotation.Set(0,0,0);

	//if(m_pPlayer->m_stats.isOnLadder)
		//deltaRotation.z = 0.0f;

	const SCVars* pGameCVars = g_pGameCVars;
	if(pGameCVars->cl_cam_orbit != 0 && m_pPlayer->IsClient() && m_pPlayer->IsThirdPerson())
	{
		static bool IsInit = false;
		if (!IsInit)
		{
			m_pPlayer->m_camViewMtxFinal = Matrix33(gEnv->pRenderer->GetCamera().GetViewMatrix());
			IsInit = true;
		}

		float frameTime=gEnv->pTimer->GetFrameTime();
		float frameTimeNormalised=(frameTime>1 ? 1 : frameTime<0.0001f ? 0.0001f : frameTime)*30;	// 1/30th => 1 1/60th =>0.5 etc
		float frameTimeClamped=(frameTime>1 ? 1 : frameTime<0.0001f ? 0.0001f : frameTime);
		m_pCameraInputHelper->UpdateCameraInput(deltaRotation, frameTimeClamped,frameTimeNormalised);	// also modifies deltaRotation.
	}

	if (!animControlled)
		request.AddDeltaRotation( deltaRotation );

	// add some movement...
	if (!m_pStats->isFrozen.Value() && !animControlled)  
		request.AddDeltaMovement( FilterMovement(m_deltaMovement) );

  m_deltaMovementPrev = m_deltaMovement;

	// handle actions
	if (m_actions & ACTION_JUMP)
	{
		if (m_pPlayer->GetStance() != STANCE_PRONE)
			request.SetJump();
		else
			m_actions &= ~ACTION_JUMP;

		//m_actions &= ~ACTION_PRONE;

		/*if (m_pPlayer->GetStance() != STANCE_PRONE)
		{
			if(m_pPlayer->GetStance() == STANCE_STAND || m_pPlayer->TrySetStance(STANCE_STAND))
 				request.SetJump();
		}
		else if(!m_pPlayer->TrySetStance(STANCE_STAND))
			m_actions &= ~ACTION_JUMP;
		else
			m_actions &= ~ACTION_PRONE;*/
	}

	if (m_pPlayer->m_stats.isOnLadder)
	{
		m_actions &= ~ACTION_PRONE;
		m_actions &= ~ACTION_CROUCH;
	}
	
	request.SetStance(FigureOutStance());

	float pseudoSpeed = 0.0f;
	if (m_deltaMovement.len2() > 0.0f)
	{
		pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_pPlayer->m_stats.bSprinting);
	}
	/* design changed: sprinting with controller is removed from full stick up to Left Bumper
	if(m_bUseXIInput && m_xi_deltaMovement.len2() > 0.999f)
	{
		m_actions |= ACTION_SPRINT;
	}
	else if(m_bUseXIInput)
	{
		m_actions &= ~ACTION_SPRINT;
	}*/
	request.SetPseudoSpeed(pseudoSpeed);

	if (m_deltaMovement.GetLength() > 0.1f)
	{
		float moveAngle = (float)RAD2DEG(fabs_tpl(cry_atan2f(-m_deltaMovement.x, fabsf(m_deltaMovement.y)<0.01f?0.01f:m_deltaMovement.y)));
		request.SetAllowStrafing(moveAngle > 20.0f);
	}
	else
	{
		request.SetAllowStrafing(true);
	}

	// send the movement request to the appropriate spot!
	m_pPlayer->m_pMovementController->RequestMovement( request );
	m_pPlayer->m_actions = m_actions;

	// reset things for next frame that need to be
	m_lastMouseRawInput = m_deltaRotation;
	m_deltaRotation = Ang3(0,0,0);

	//static float color[] = {1,1,1,1};    
	//gEnv->pRenderer->Draw2dLabel(100,50,1.5,color,false,"deltaMovement:%f,%f", m_deltaMovement.x,m_deltaMovement.y);
	
	// PLAYERPREDICTION
	m_pPlayer->GetGameObject()->ChangedNetworkState(INPUT_ASPECT);
	// ~PLAYERPREDICTION

}
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);
			}
		}
	}
}
void CPlayerRotation::ProcessFlyingZeroG()
{
	bool bEnableGyroVerticalFade = (g_pGameCVars->pl_zeroGEnableGyroFade > 0);
	bool bEnableGyroSpeedFade = (g_pGameCVars->pl_zeroGEnableGyroFade < 2);

	//thats necessary when passing from groundG to normalG
	m_baseQuat = m_viewQuat;
	assert(m_baseQuat.IsValid());
	//m_baseQuat = Quat::CreateSlerp(m_viewQuat,m_player.GetEntity()->GetRotation() * Quat::CreateRotationZ(gf_PI),0.5f);

	Ang3 desiredAngVel(m_deltaAngles.x,m_deltaAngles.y * 0.3f,m_deltaAngles.z);

	//view recoil in zeroG cause the player to rotate
	desiredAngVel.x += m_viewAnglesOffset.x * 0.1f;
	desiredAngVel.z += m_viewAnglesOffset.z * 0.1f;

	//so once used reset it.
	m_viewAnglesOffset.Set(0,0,0);

	//gyroscope: the gyroscope just apply the right roll speed to compensate the rotation, that way effects like
	//propulsion particles and such can be done easily just by using the angularVel
	float rotInertia(g_pGameCVars->pl_zeroGAimResponsiveness);

	if(m_player.GravityBootsOn() && m_stats.gBootsSpotNormal.len2()>0.01f)
	{
		Vec3 vRef(m_baseQuat.GetInverted() * m_stats.gBootsSpotNormal);
		Ang3 alignAngle(0,0,0);
		alignAngle.y = cry_atan2f(vRef.x, vRef.z);
		alignAngle.x = cry_atan2f(vRef.y, vRef.z);

		desiredAngVel.y += alignAngle.y * 0.05f;
		desiredAngVel.x -= alignAngle.x * 0.05f;
	}

	if(m_actions & ACTION_GYROSCOPE && desiredAngVel.y==0)
	{
		// we want to fade out the gyroscopic effect
		Vec3 vRef(m_baseQuat.GetInverted() * m_stats.zeroGUp);
		Ang3 alignAngle(0,0,0);
		alignAngle.y = cry_atan2f(vRef.x,vRef.z);

		float gyroFade = 1.0f;

		if(bEnableGyroVerticalFade)
		{
			float gyroFadeAngleInner = g_pGameCVars->pl_zeroGGyroFadeAngleInner;
			float gyroFadeAngleOuter = g_pGameCVars->pl_zeroGGyroFadeAngleOuter;
			float gyroFadeAngleSpan = gyroFadeAngleOuter - gyroFadeAngleInner;
			float gyroFadeAngleSpanInv = 1.0f / gyroFadeAngleSpan;
			float viewVerticalAlignment = abs(m_viewQuat.GetFwdZ());
			float viewVerticalAngle = RAD2DEG(cry_asinf(viewVerticalAlignment));
			gyroFade = 1.0f - CLAMP((viewVerticalAngle - gyroFadeAngleInner) * gyroFadeAngleSpanInv, 0.0f, 1.0f);
			gyroFade = cry_powf(gyroFade, g_pGameCVars->pl_zeroGGyroFadeExp);
		}

		float speedFade = 1.0f;

		if(bEnableGyroSpeedFade)
		{
			float speed = m_player.GetLastRequestedVelocity().GetLength();
			speedFade = 1.0f - std::min(1.0f, speed / 5.0f);
		}

		desiredAngVel.y += alignAngle.y * speedFade * gyroFade * m_frameTime * g_pGameCVars->pl_zeroGGyroStrength;

		//rotInertia = 3.0f;
	}

	m_absRoll = fabs(desiredAngVel.y);

	Interpolate(m_angularVel,desiredAngVel,rotInertia,m_frameTime);
	Ang3 finalAngle(m_angularVel + m_angularImpulseDelta);

	m_baseQuat *= Quat::CreateRotationZ(finalAngle.z) * Quat::CreateRotationX(finalAngle.x) * Quat::CreateRotationY(finalAngle.y);
	m_baseQuat.NormalizeSafe();

	/*IEntity *pEnt = m_player.GetEntity();
	Vec3 offsetToCenter(Vec3(0,0,m_player.GetStanceInfo(m_player.GetStance())->heightCollider));
	Vec3 finalPos(pEnt->GetWorldTM() * offsetToCenter);
	Quat newBaseQuat(m_baseQuat * Quat::CreateRotationZ(finalAngle.z) * Quat::CreateRotationX(finalAngle.x) * Quat::CreateRotationY(finalAngle.y));
	Vec3 newPos(pEnt->GetWorldPos() + m_baseQuat * offsetToCenter);
	pEnt->SetPos(pEnt->GetWorldPos() + (finalPos - newPos),ENTITY_XFORM_USER);*/

	//CHECKQNAN_MAT33(m_baseMtx);

	m_viewQuat = m_baseQuat;
	m_viewRoll = 0;
	m_upVector = m_baseQuat.GetColumn2();
}
Exemple #11
0
void CNetPlayerInput::PreUpdate()
{
	IPhysicalEntity * pPhysEnt = m_pPlayer->GetEntity()->GetPhysics();
	if (!pPhysEnt)
		return;

	CMovementRequest moveRequest;
	SMovementState moveState;
	m_pPlayer->GetMovementController()->GetMovementState(moveState);
	Quat worldRot = m_pPlayer->GetBaseQuat(); // m_pPlayer->GetEntity()->GetWorldRotation();
	Vec3 deltaMovement = worldRot.GetInverted().GetNormalized() * m_curInput.deltaMovement;
	// absolutely ensure length is correct
	deltaMovement = deltaMovement.GetNormalizedSafe(ZERO) * m_curInput.deltaMovement.GetLength();
	moveRequest.AddDeltaMovement( deltaMovement );
	if( IsDemoPlayback() )
	{
		Vec3 localVDir(m_pPlayer->GetViewQuatFinal().GetInverted() * m_curInput.lookDirection);
		Ang3 deltaAngles(asin(localVDir.z),0,cry_atan2f(-localVDir.x,localVDir.y));
		moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime());
	}
	//else
	{
		Vec3 distantTarget = moveState.eyePosition + 1000.0f * m_curInput.lookDirection;
		Vec3 lookTarget = distantTarget;
		if (gEnv->bClient && m_pPlayer->GetGameObject()->IsProbablyVisible())
		{
			// post-process aim direction	
			ray_hit hit;
			static const int obj_types = ent_all; // ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_living;
			static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
			bool rayHitAny = 0 != gEnv->pPhysicalWorld->RayWorldIntersection( moveState.eyePosition, 150.0f * m_curInput.lookDirection, obj_types, flags, &hit, 1, pPhysEnt );
			if (rayHitAny)
			{
				lookTarget = hit.pt;
			}

			static float proneDist = 1.0f;
			static float crouchDist = 0.6f;
			static float standDist = 0.3f;

			float dist = standDist;
			if(m_pPlayer->GetStance() == STANCE_CROUCH)
				dist = crouchDist;
			else if(m_pPlayer->GetStance() == STANCE_PRONE)
				dist = proneDist;

			if((lookTarget - moveState.eyePosition).GetLength2D() < dist)
			{
				Vec3 eyeToTarget2d = lookTarget - moveState.eyePosition;
				eyeToTarget2d.z = 0.0f;
				eyeToTarget2d.NormalizeSafe();
				eyeToTarget2d *= dist;
				ray_hit newhit;
				bool rayHitAny = 0 != gEnv->pPhysicalWorld->RayWorldIntersection( moveState.eyePosition + eyeToTarget2d, 3 * Vec3(0,0,-1), obj_types, flags, &newhit, 1, pPhysEnt );
				if (rayHitAny)
				{
					lookTarget = newhit.pt;
				}
			}

			// SNH: new approach. Make sure the aimTarget is at least 1.5m away,
			//	if not, pick a point 1m down the vector instead.
			Vec3 dir = lookTarget - moveState.eyePosition;
			static float minDist = 1.5f;
			if(dir.GetLengthSquared() < minDist)
			{
				lookTarget = moveState.eyePosition + dir.GetNormalizedSafe();
			}

			// draw eye pos for comparison
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(moveState.eyePosition, 0.04f, ColorF(0.3f,0.2f,0.7f,1.0f));
		}

		moveRequest.SetLookTarget( lookTarget );
		moveRequest.SetAimTarget( lookTarget );
		if (m_curInput.deltaMovement.GetLengthSquared() > sqr(0.2f)) // 0.2f is almost stopped
			moveRequest.SetBodyTarget( distantTarget );
		else
			moveRequest.ClearBodyTarget();
	}
	moveRequest.SetAllowStrafing(true);

	float pseudoSpeed = 0.0f;
	if (m_curInput.deltaMovement.len2() > 0.0f)
	{
		pseudoSpeed = m_pPlayer->CalculatePseudoSpeed(m_curInput.sprint);
	}
	moveRequest.SetPseudoSpeed(pseudoSpeed);

	float lean=0.0f;
	if (m_curInput.leanl)
		lean-=1.0f;
	if (m_curInput.leanr)
		lean+=1.0f;

	if (fabsf(lean)>0.01f)
		moveRequest.SetLean(lean);
	else
		moveRequest.ClearLean();

	m_pPlayer->GetMovementController()->RequestMovement(moveRequest);

	if (m_curInput.sprint)
		m_pPlayer->m_actions |= ACTION_SPRINT;
	else
		m_pPlayer->m_actions &= ~ACTION_SPRINT;

	if (m_curInput.leanl)
		m_pPlayer->m_actions |= ACTION_LEANLEFT;
	else
		m_pPlayer->m_actions &= ~ACTION_LEANLEFT;

	if (m_curInput.leanr)
		m_pPlayer->m_actions |= ACTION_LEANRIGHT;
	else
		m_pPlayer->m_actions &= ~ACTION_LEANRIGHT;

	// debug..
	if (g_pGameCVars->g_debugNetPlayerInput & 2)
	{
		IPersistantDebug * pPD = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug();
		pPD->Begin( string("update_player_input_") + m_pPlayer->GetEntity()->GetName(), true );
		Vec3 wp = m_pPlayer->GetEntity()->GetWorldPos();
		wp.z += 2.0f;
		pPD->AddSphere( moveRequest.GetLookTarget(), 0.5f, ColorF(1,0,1,0.3f), 1.0f );
		//		pPD->AddSphere( moveRequest.GetMoveTarget(), 0.5f, ColorF(1,1,0,0.3f), 1.0f );
		pPD->AddDirection( m_pPlayer->GetEntity()->GetWorldPos() + Vec3(0,0,2), 1, m_curInput.deltaMovement, ColorF(1,0,0,0.3f), 1.0f );
	}

	//m_curInput.deltaMovement.zero();
}
Exemple #12
0
void CPlayerRotation::ClampAngles( float minAngle, float maxAngle )
{
	//Cap up/down looking
	{
		const float currentViewPitch = GetLocalPitch();
		const float newPitch = clamp(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 = cry_atan2f(-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));
			}
		}
	}
}