Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Camera FOV rework #3139

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/main/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ CVar* gfx_shadow_quality;
CVar* gfx_skidmarks_mode;
CVar* gfx_sight_range;
CVar* gfx_camera_height;
CVar* gfx_camera_speed;
CVar* gfx_fov_external;
CVar* gfx_fov_external_default;
CVar* gfx_fov_internal;
Expand Down
1 change: 1 addition & 0 deletions source/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ extern CVar* gfx_shadow_quality;
extern CVar* gfx_skidmarks_mode;
extern CVar* gfx_sight_range;
extern CVar* gfx_camera_height;
extern CVar* gfx_camera_speed;
extern CVar* gfx_fov_external;
extern CVar* gfx_fov_external_default;
extern CVar* gfx_fov_internal;
Expand Down
109 changes: 75 additions & 34 deletions source/main/gfx/camera/CameraManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,13 @@ CameraManager::CameraManager() :
, m_splinecam_mo(0)
, m_splinecam_spline_pos(0.5f)
, m_staticcam_force_update(false)
, m_staticcam_fov_exponent(1.0f)
, m_cam_rot_x(0.0f)
, m_cam_rot_y(0.3f)
, m_cam_dist(5.f)
, m_cam_dist_min(0.f)
, m_cam_dist_max(0.f)
, m_cam_target_direction(0.f)
, m_cam_target_pitch(0.f)
, m_cam_ratio (11.f)
, m_cam_look_at(Ogre::Vector3::ZERO)
, m_cam_look_at_last(Ogre::Vector3::ZERO)
, m_cam_look_at_smooth(Ogre::Vector3::ZERO)
Expand Down Expand Up @@ -145,7 +143,7 @@ void CameraManager::ReCreateCameraNode()
this->CreateCameraNode();
}

bool CameraManager::EvaluateSwitchBehavior()
bool CameraManager::evaluateSwitchBehavior()
{
switch(m_current_behavior)
{
Expand Down Expand Up @@ -199,7 +197,6 @@ void CameraManager::UpdateCurrentBehavior()
}

case CAMERA_BEHAVIOR_STATIC:
m_staticcam_fov_exponent = App::gfx_static_cam_fov_exp->getFloat();
this->UpdateCameraBehaviorStatic();
return;

Expand Down Expand Up @@ -255,7 +252,7 @@ void CameraManager::UpdateInputEvents(float dt) // Called every frame

if ( m_current_behavior < CAMERA_BEHAVIOR_END && App::GetInputEngine()->getEventBoolValueBounce(EV_CAMERA_CHANGE) )
{
if ( (m_current_behavior == CAMERA_BEHAVIOR_INVALID) || this->EvaluateSwitchBehavior() )
if ( (m_current_behavior == CAMERA_BEHAVIOR_INVALID) || this->evaluateSwitchBehavior() )
{
this->switchToNextBehavior();
}
Expand Down Expand Up @@ -335,21 +332,19 @@ void CameraManager::ResetCurrentBehavior()
{
m_cam_rot_y = 0.1f;
m_cam_dist = 0.1f;
m_cam_ratio = 0.0f;
}
else
{
m_cam_rot_y = 0.3f;
m_cam_dist = 5.0f;
m_cam_ratio = 11.0f;
}
m_cam_dist_min = 0;
m_cam_target_pitch = 0.0f;
return;
}

case CAMERA_BEHAVIOR_STATIC:
m_staticcam_fov_exponent = 1.0f;
m_staticcam_fov_exp_current = 1.0f;
App::gfx_static_cam_fov_exp->setVal(1.0f);
return;

Expand Down Expand Up @@ -564,7 +559,24 @@ bool CameraManager::mouseMoved(const OIS::MouseEvent& _arg)

return CameraManager::CameraBehaviorOrbitMouseMoved(_arg);
}
case CAMERA_BEHAVIOR_STATIC: return CameraBehaviorStaticMouseMoved(_arg);
case CAMERA_BEHAVIOR_STATIC:
{
const OIS::MouseState ms = _arg.state;

if (ms.buttonDown(OIS::MB_Right))
{
// Note: `gfx_static_cam_fov_exp` is the desired (target) value; current (smooth) value is `m_staticcam_fov_exp_current`

float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.00002f : 0.0002f;
float exp = App::gfx_static_cam_fov_exp->getFloat();
exp += ms.Z.rel * scale;
exp = Math::Clamp(exp, 0.8f, 1.50f);
App::gfx_static_cam_fov_exp->setVal(exp);
return true;
}

return false;
}
case CAMERA_BEHAVIOR_VEHICLE: return CameraBehaviorOrbitMouseMoved(_arg);
case CAMERA_BEHAVIOR_VEHICLE_SPLINE: return this->CameraBehaviorVehicleSplineMouseMoved(_arg);
case CAMERA_BEHAVIOR_VEHICLE_CINECAM: return CameraBehaviorOrbitMouseMoved(_arg);
Expand Down Expand Up @@ -786,9 +798,7 @@ void CameraManager::UpdateCameraBehaviorStatic()
}
}

static float fovExp = m_staticcam_fov_exponent;
fovExp = (1.0f / (m_cam_ratio + 1.0f)) * m_staticcam_fov_exponent + (m_cam_ratio / (m_cam_ratio + 1.0f)) * fovExp;

float fovExp = this->smoothFloat(m_staticcam_fov_exp_current, App::gfx_static_cam_fov_exp->getFloat(), m_cct_dt, App::gfx_camera_speed->getFloat());
float camDist = m_staticcam_position.distance(m_staticcam_look_at);
float fov = atan2(20.0f, std::pow(camDist, fovExp));

Expand All @@ -797,22 +807,6 @@ void CameraManager::UpdateCameraBehaviorStatic()
App::GetCameraManager()->GetCamera()->setFOVy(Radian(fov));
}

bool CameraManager::CameraBehaviorStaticMouseMoved(const OIS::MouseEvent& _arg)
{
const OIS::MouseState ms = _arg.state;

if (ms.buttonDown(OIS::MB_Right))
{
float scale = RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LMENU) ? 0.00002f : 0.0002f;
m_staticcam_fov_exponent += ms.Z.rel * scale;
m_staticcam_fov_exponent = Math::Clamp(m_staticcam_fov_exponent, 0.8f, 1.50f);
App::gfx_static_cam_fov_exp->setVal(m_staticcam_fov_exponent);
return true;
}

return false;
}

void CameraManager::CameraBehaviorOrbitUpdate()
{
if (RoR::App::GetInputEngine()->getEventBoolValueBounce(EV_CAMERA_LOOKBACK))
Expand Down Expand Up @@ -916,7 +910,7 @@ void CameraManager::CameraBehaviorOrbitUpdate()
Vector3 precedingLookAt = m_cam_look_at_smooth_last + camDisplacement;
Vector3 precedingPosition = this->GetCameraNode()->getPosition() + camDisplacement;

Vector3 camPosition = (1.0f / (m_cam_ratio + 1.0f)) * desiredPosition + (m_cam_ratio / (m_cam_ratio + 1.0f)) * precedingPosition;
Vector3 camPosition = this->smoothVector3(precedingPosition, desiredPosition, m_cct_dt, App::gfx_camera_speed->getFloat());

if (App::GetGameContext()->GetTerrain()->GetCollisions() && App::GetGameContext()->GetTerrain()->GetCollisions()->forcecam)
{
Expand All @@ -931,7 +925,7 @@ void CameraManager::CameraBehaviorOrbitUpdate()
this->GetCameraNode()->setPosition(camPosition);
}

m_cam_look_at_smooth = (1.0f / (m_cam_ratio + 1.0f)) * m_cam_look_at + (m_cam_ratio / (m_cam_ratio + 1.0f)) * precedingLookAt;
m_cam_look_at_smooth = this->smoothVector3(precedingLookAt, m_cam_look_at, m_cct_dt, App::gfx_camera_speed->getFloat());

m_cam_look_at_last = m_cam_look_at;
m_cam_look_at_smooth_last = m_cam_look_at_smooth;
Expand Down Expand Up @@ -1068,8 +1062,6 @@ void CameraManager::UpdateCameraBehaviorVehicle()
m_cam_target_pitch = -asin(dir.dotProduct(Vector3::UNIT_Y));
}

m_cam_ratio = 1.0f / (m_cct_dt * 4.0f);

m_cam_dist_min = std::min(m_cct_player_actor->getMinimalCameraRadius() * 2.0f, 33.0f);

m_cam_look_at = m_cct_player_actor->getPosition();
Expand Down Expand Up @@ -1185,8 +1177,6 @@ bool CameraManager::CameraBehaviorVehicleSplineMouseMoved( const OIS::MouseEven
{
const OIS::MouseState ms = _arg.state;

m_cam_ratio = 1.0f / (m_cct_dt * 4.0f);

if (RoR::App::GetInputEngine()->isKeyDown(OIS::KC_LCONTROL) && ms.buttonDown(OIS::MB_Right))
{
Real splinePosDiff = ms.X.rel * std::max(0.00005f, m_splinecam_spline_len * 0.0000001f);
Expand Down Expand Up @@ -1365,3 +1355,54 @@ void CameraManager::CameraBehaviorVehicleSplineUpdateSplineDisplay()
}
m_splinecam_mo->end();
}

void CameraManager::switchDirectlyToBehavior(CameraBehaviors new_behavior, int index)
{
// Not all behaviors are the same; some are 'toggled' and some 'cycled'.
// * Cycled (see `EV_COMMON_CAMERA_BEHAVIOR_CYCLE`): Character, Static, Vehicle, Vehicle Spline ~ can be changed freely via `switchBehavior()`
// * Toggled (see `EV_COMMON_CAMERA_BEHAVIOR_TOGGLE`): Free, Fixed ~ must be changed via `ToggleCameraBehavior()` to keep history for hotkeys.
// --------------------------------------------------------------------------------------------------

switch (new_behavior)
{
case CameraManager::CAMERA_BEHAVIOR_FREE:
case CameraManager::CAMERA_BEHAVIOR_FIXED:
this->ToggleCameraBehavior(new_behavior);
break;

case CameraManager::CAMERA_BEHAVIOR_VEHICLE_CINECAM:
this->switchBehavior(new_behavior);
break;

default:
this->switchBehavior(new_behavior);
break;
}
}

float CameraManager::smoothFloat(float current, float target, float dt, float speed) const
{
return current + (target - current) * speed * dt;
}

Ogre::Vector3 CameraManager::smoothVector3(const Ogre::Vector3& current, const Ogre::Vector3& target, float dt, float speed) const
{
return current + (target - current) * speed * dt;
}

std::string RoR::ToLocalizedString(CameraManager::CameraBehaviors behavior)
{
switch (behavior)
{
case CameraManager::CAMERA_BEHAVIOR_CHARACTER: return _LC("CameraBehavior", "Character");
case CameraManager::CAMERA_BEHAVIOR_STATIC: return _LC("CameraBehavior", "Static");
case CameraManager::CAMERA_BEHAVIOR_VEHICLE: return _LC("CameraBehavior", "Vehicle");
case CameraManager::CAMERA_BEHAVIOR_VEHICLE_SPLINE: return _LC("CameraBehavior", "Vehicle Spline");
case CameraManager::CAMERA_BEHAVIOR_VEHICLE_CINECAM: return _LC("CameraBehavior", "Vehicle CineCam");
case CameraManager::CAMERA_BEHAVIOR_FREE: return _LC("CameraBehavior", "Free");
case CameraManager::CAMERA_BEHAVIOR_FIXED: return _LC("CameraBehavior", "Fixed");
case CameraManager::CAMERA_BEHAVIOR_ISOMETRIC: return _LC("CameraBehavior", "Isometric");
case CameraManager::CAMERA_BEHAVIOR_INVALID: return _LC("CameraBehavior", "Invalid");
default: return "";
}
}
13 changes: 9 additions & 4 deletions source/main/gfx/camera/CameraManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ class CameraManager
void ReCreateCameraNode(); //!< Needed since we call `Ogre::SceneManager::ClearScene()` after end of sim. session

void switchToNextBehavior();
bool EvaluateSwitchBehavior();
bool evaluateSwitchBehavior();
void switchDirectlyToBehavior(CameraBehaviors new_behavior, int index = -1);

protected:

Expand All @@ -89,7 +90,6 @@ class CameraManager
void ResetCurrentBehavior();
void DeactivateCurrentBehavior();
void UpdateCameraBehaviorStatic();
bool CameraBehaviorStaticMouseMoved(const OIS::MouseEvent& _arg);
void UpdateCameraBehaviorFree();
void UpdateCameraBehaviorFixed();
void UpdateCameraBehaviorVehicle();
Expand All @@ -103,6 +103,10 @@ class CameraManager
void CameraBehaviorVehicleSplineUpdateSplineDisplay();
void CreateCameraNode();

// Helper functions
float smoothFloat(float current, float target, float dt, float speed) const;
Ogre::Vector3 smoothVector3(const Ogre::Vector3& current, const Ogre::Vector3& target, float dt, float speed) const;

Ogre::Camera* m_camera;
Ogre::SceneNode* m_camera_node;

Expand All @@ -123,15 +127,14 @@ class CameraManager
float m_cam_dist;
float m_cam_dist_min;
float m_cam_dist_max;
float m_cam_ratio;
Ogre::Vector3 m_cam_look_at;
bool m_cam_limit_movement;
Ogre::Vector3 m_cam_look_at_last;
Ogre::Vector3 m_cam_look_at_smooth;
Ogre::Vector3 m_cam_look_at_smooth_last;
// Static cam attributes
bool m_staticcam_force_update;
float m_staticcam_fov_exponent;
float m_staticcam_fov_exp_current = 1.f; //!< Smoothed value; target is cvar `gfx_static_cam_fox_exp`
Ogre::Radian m_staticcam_previous_fov;
Ogre::Vector3 m_staticcam_look_at;
Ogre::Vector3 m_staticcam_position;
Expand All @@ -152,4 +155,6 @@ class CameraManager
/// @} // addtogroup Camera
/// @} // addtogroup Gfx

std::string ToLocalizedString(CameraManager::CameraBehaviors behavior);

} // namespace RoR
Loading