void CNetPlayerInput::DoSetState(const SSerializedPlayerInput& input ) { m_newInterpolation |= (input.position != m_curInput.position) || (input.deltaMovement != m_curInput.deltaMovement); const bool wasSprinting = m_curInput.sprint; m_curInput = input; CHANGED_NETWORK_STATE(m_pPlayer, CPlayer::ASPECT_INPUT_CLIENT ); if(wasSprinting != input.sprint) { SInputEventData inputEventData( SInputEventData::EInputEvent_Sprint, m_pPlayer->GetEntityId(), CCryName("sprint"), input.sprint ? eAAM_OnPress : eAAM_OnRelease, 0.f ); m_pPlayer->StateMachineHandleEventMovement( SStateEventPlayerInput( &inputEventData ) ); } // 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; 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,atan2_tpl(-localVDir.x,localVDir.y)); moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime()); } moveRequest.SetPseudoSpeed(CalculatePseudoSpeed()); moveRequest.SetAllowStrafing(input.allowStrafing); m_pPlayer->GetMovementController()->RequestMovement(moveRequest); #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 }
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 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 }
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(); }
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 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(); }
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,atan2_tpl(-localVDir.x,localVDir.y)); moveRequest.AddDeltaRotation(deltaAngles*gEnv->pTimer->GetFrameTime()); } const float fNetAimLerpFactor = g_pGameCVars->pl_netAimLerpFactor; //Vector slerp produces artifacts here, using a per-component lerp instead Vec3 vCurrentRight = m_lookDir.cross(Vec3Constants<float>::fVec3_OneZ); Vec3 vCurrentProjected = -(vCurrentRight.cross(Vec3Constants<float>::fVec3_OneZ)); vCurrentRight.Normalize(); vCurrentProjected.Normalize(); Vec3 vNewRight = m_curInput.lookDirection.cross(Vec3Constants<float>::fVec3_OneZ); Vec3 vNewProjected = -(vNewRight.cross(Vec3Constants<float>::fVec3_OneZ)); vNewProjected.Normalize(); float fRotZDirDot = vNewProjected.dot(vCurrentRight); float fRotZDot = vNewProjected.dot(vCurrentProjected); float fRotZ = acos_tpl(fRotZDot); fRotZ = AngleWrap_PI(fRotZ); float fRotZFinal = -fsgnf(fRotZDirDot) * fRotZ * fNetAimLerpFactor; float fCurrentAngle = acos_tpl(Vec3Constants<float>::fVec3_OneZ.dot(m_lookDir)); float fNewAngle = acos_tpl(Vec3Constants<float>::fVec3_OneZ.dot(m_curInput.lookDirection)); float fRotXFinal = (fNewAngle - fCurrentAngle) * -fNetAimLerpFactor; //Rotate around X first, as we have already generated the right vector Vec3 vNewLookDir = m_lookDir.GetRotated(vCurrentRight, fRotXFinal); m_lookDir = vNewLookDir.GetRotated(Vec3Constants<float>::fVec3_OneZ, fRotZFinal); 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); moveRequest.SetPseudoSpeed(CalculatePseudoSpeed()); 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 0 if (m_pPlayer->m_netSetPosition) { SPredictedCharacterStates charStates; charStates.states[0].position = m_pPlayer->GetEntity()->GetPos(); charStates.states[0].orientation = m_pPlayer->GetEntity()->GetRotation(); charStates.states[0].deltatime = 0.0f; charStates.states[1].position = m_pPlayer->m_netCurrentLocation; charStates.states[1].orientation = m_pPlayer->GetEntity()->GetRotation(); charStates.states[1].deltatime = gEnv->pTimer->GetFrameTime(); charStates.states[2].position = m_pPlayer->m_netDesiredLocation; charStates.states[2].orientation = m_pPlayer->GetEntity()->GetRotation(); charStates.states[2].deltatime = m_pPlayer->m_netLerpTime; charStates.nStates = 3; moveRequest.SetPrediction(charStates); } #endif //0 #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(); }