//------------------------------------------------------------------------------------ // Adjust the aim dir before we pass it to the torsoAim pose modifier, this allows us // to have the weapon deviate from the camera in certain circumstances // Should only be called once per frame as it time-steps internal vars //------------------------------------------------------------------------------------ void CLocalPlayerComponent::AdjustTorsoAimDir(float fFrameTime, Vec3 &aimDir) { const f32 HALF_PI = gf_PI * 0.5f; float newElevLimit = HALF_PI; const f32 MIN_FLATTEN_LEVEL = -0.3f; const f32 MAX_FLATTEN_LEVEL = -0.1f; const f32 TARGET_FLATTEN_ELEV = -0.2f; const f32 LIMIT_CHANGE_RATE = HALF_PI; if (g_pGameCVars->pl_swimAlignArmsToSurface && m_rPlayer.IsSwimming() && (m_rPlayer.m_playerStateSwim_WaterTestProxy.GetRelativeWaterLevel() > MIN_FLATTEN_LEVEL)) { newElevLimit = (m_rPlayer.m_playerStateSwim_WaterTestProxy.GetRelativeWaterLevel() - MIN_FLATTEN_LEVEL) / (MAX_FLATTEN_LEVEL - MIN_FLATTEN_LEVEL); newElevLimit = LERP(gf_PI * 0.5f, TARGET_FLATTEN_ELEV, clamp_tpl(newElevLimit, 0.0f, 1.0f)); } float limitDelta = LIMIT_CHANGE_RATE * fFrameTime; float limitDiff = newElevLimit - m_stapElevLimit; float smoothedLimit = (float) fsel(fabs_tpl(limitDiff) - limitDelta, m_stapElevLimit + (fsgnf(limitDiff) * limitDelta), newElevLimit); m_stapElevLimit = smoothedLimit; if (smoothedLimit < HALF_PI) { //--- Need to limit, convert to yaw & elev, limit & then convert back float yaw, elev; float xy = aimDir.GetLengthSquared2D(); if (xy > 0.001f) { yaw = atan2_tpl(aimDir.y,aimDir.x); elev = asin_tpl(clamp_tpl(aimDir.z, -1.f, +1.f)); } else { yaw = 0.f; elev = (float)fsel(aimDir.z, +1.f, -1.f) * (gf_PI*0.5f); } elev = min(elev, smoothedLimit); float sinYaw, cosYaw; float sinElev, cosElev; sincos_tpl(yaw, &sinYaw, &cosYaw); sincos_tpl(elev, &sinElev, &cosElev); aimDir.x = cosYaw * cosElev; aimDir.y = sinYaw * cosElev; aimDir.z = sinElev; } }
void CPlayerRotation::ProcessTargetAssistance( IItem* pCurrentPlayerItem ) { // aim assistance float targetAimAssistAngleFollowH; float targetAimAssistAngleFollowV; float targetAimAssistAngleScale; IPlayerInput * pIPlayerInput = m_player.GetPlayerInput(); float absInput = 0.0f; float aimAssistPowerFactor = 1.0f; bool isUsingDedicatedInput = gEnv->IsDedicated(); #if (USE_DEDICATED_INPUT) isUsingDedicatedInput |= g_pGameCVars->g_playerUsesDedicatedInput ? true : false; #endif if(pIPlayerInput && !isUsingDedicatedInput) { CRY_ASSERT(pIPlayerInput->GetType() == IPlayerInput::PLAYER_INPUT); CPlayerInput * pPlayerInput = static_cast<CPlayerInput*>(pIPlayerInput); const Ang3 rawDeltas = pPlayerInput->GetRawControllerInput(); absInput = min((fabsf(rawDeltas.x) + fabsf(rawDeltas.z)) * 1.4f, 1.0f); aimAssistPowerFactor = 2.0f - absInput; } //Gather weapon info before processing target aim assistance bool playerWeaponIsRequestingSnap = false; CWeapon* pWeapon = GetCurrentWeapon( pCurrentPlayerItem ); if (pWeapon) { playerWeaponIsRequestingSnap = pWeapon->ShouldSnapToTarget(); } IMovementController* pMovementController = m_player.GetMovementController(); CRY_ASSERT(pMovementController); SMovementState moveState; pMovementController->GetMovementState(moveState); Vec3 playerView[4] = { m_viewQuat.GetColumn0(), // Right m_viewQuat.GetColumn1(), // Forward m_viewQuat.GetColumn2(), // Up moveState.eyePosition // Pos }; IVehicle* pVehicle = m_player.GetLinkedVehicle(); if (pVehicle) { Vec3 up(0.f,0.f,1.f); playerView[1] = moveState.eyeDirection; // Forward playerView[0] = (playerView[1].cross(up)).GetNormalizedSafe(); // Right playerView[2] = playerView[0].cross(playerView[1]); // Up } float fZoomAmount = 0.0f; TargetAimAssistance(pWeapon, targetAimAssistAngleFollowH, targetAimAssistAngleFollowV, targetAimAssistAngleScale, fZoomAmount, playerView); targetAimAssistAngleScale = powf(targetAimAssistAngleScale, aimAssistPowerFactor); //TODO: Fix so it's not using auto aim unless selected float fFollowAssistScale = (absInput * (1.0f - fZoomAmount)) + min(absInput * fZoomAmount * __fres(g_pGameCVars->aim_assistInputForFullFollow_Ironsight), 1.0f); m_deltaAngles.z = (m_deltaAngles.z * targetAimAssistAngleScale) + (absInput * targetAimAssistAngleFollowH); m_deltaAngles.x = (m_deltaAngles.x * targetAimAssistAngleScale) + (absInput * targetAimAssistAngleFollowV); const bool snapToTarget = (!gEnv->bMultiplayer && playerWeaponIsRequestingSnap && !m_snap_target_dir.IsZero()); const EntityId closeCombatSnapTargetId = g_pGame->GetAutoAimManager().GetCloseCombatSnapTarget(); if (closeCombatSnapTargetId) { Vec3 snapDirection = GetCloseCombatSnapTargetDirection(closeCombatSnapTargetId); if (!snapDirection.IsZero()) { const float blendSpeed = clamp_tpl( g_pGameCVars->pl_melee.melee_snap_blend_speed , 0.0f, 1.0f); m_deltaAngles.z = -asin_tpl(snapDirection * m_viewQuat.GetColumn0()) * blendSpeed; m_deltaAngles.x = asin_tpl(snapDirection * m_viewQuat.GetColumn2()) * blendSpeed; } } else if (snapToTarget) { const float zoomInTime = pWeapon->GetZoomInTime(); const float blendFactor = clamp_tpl(pow_tpl((1.0f-zoomInTime),2.0f), 0.0f, 1.0f); m_deltaAngles.z = -asin_tpl(m_snap_target_dir * m_viewQuat.GetColumn0()) * blendFactor; m_deltaAngles.x = asin_tpl(m_snap_target_dir * m_viewQuat.GetColumn2()) * blendFactor; } m_currently_snapping = playerWeaponIsRequestingSnap; #if !defined(_RELEASE) if(g_pGameCVars->ctrlr_OUTPUTDEBUGINFO) { float white[] = {1,1,1,1}; gEnv->pRenderer->Draw2dLabel( 20, 100, 1.4f, white, false, "Aim Acceleration & Assist\n absInput: %.6f", absInput ); } #endif }