Skip to content
Open
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
4 changes: 4 additions & 0 deletions data/gui/dialogs/custom_camera_settings.stkgui
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
<checkbox id="use_soccer_camera"/>
<spacer width="1%" height="100%" />
<label height="100%" text_align="left" I18N="In the ui/camera screen" text="Follow ball in soccer mode"/>
<spacer width="3%" height="100%" />
<checkbox id="use_camera_shake"/>
<spacer width="1%" height="100%" />
<label height="100%" text_align="left" I18N="In the ui/camera screen" text="Enable camera shake"/>
</div>
</div>

Expand Down
15 changes: 15 additions & 0 deletions src/config/user_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,11 @@ namespace UserConfigParams
PARAM_DEFAULT( BoolUserConfigParam(false, "reverse-look-use-soccer-cam",
"Use ball camera in soccer mode, instead of reverse") );

PARAM_PREFIX BoolUserConfigParam m_camera_use_shake
PARAM_DEFAULT(BoolUserConfigParam(true, "shake",
&m_camera_normal,
"Shakes the camera when reaching high speeds on ground"));

// ---- The present camera (default: Standard)
PARAM_PREFIX IntUserConfigParam m_camera_present
PARAM_DEFAULT( IntUserConfigParam(1, "camera-present",
Expand Down Expand Up @@ -1122,6 +1127,11 @@ namespace UserConfigParams
&m_standard_camera_settings,
"Use ball camera in soccer mode, instead of reverse"));

PARAM_PREFIX BoolUserConfigParam m_standard_camera_use_shake
PARAM_DEFAULT(BoolUserConfigParam(false, "shake",
&m_standard_camera_settings,
"Shakes the camera when reaching high speeds on ground"));

// ---- Drone chase camera settings
PARAM_PREFIX GroupUserConfigParam m_drone_camera_settings
PARAM_DEFAULT( GroupUserConfigParam(
Expand Down Expand Up @@ -1214,6 +1224,11 @@ namespace UserConfigParams
&m_saved_camera_settings,
"Use ball camera in soccer mode, instead of reverse"));

PARAM_PREFIX BoolUserConfigParam m_saved_camera_use_shake
PARAM_DEFAULT(BoolUserConfigParam(false, "shake",
&m_saved_camera_settings,
"Shakes the camera when reaching high speeds on ground"));

// camera in artist mode
PARAM_PREFIX GroupUserConfigParam m_camera
PARAM_DEFAULT( GroupUserConfigParam("camera",
Expand Down
40 changes: 37 additions & 3 deletions src/graphics/camera/camera_normal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "karts/kart_properties.hpp"
#include "karts/skidding.hpp"
#include "tracks/track.hpp"
#include "guiengine/modaldialog.hpp"

// ============================================================================
/** Constructor for the normal camera. This is the only camera constructor
Expand Down Expand Up @@ -61,6 +62,11 @@ CameraNormal::CameraNormal(Camera::CameraType type, int camera_index,
m_kart_position = btVector3(0, 0, 0);
m_kart_rotation = btQuaternion(0, 0, 0, 1);
m_last_smooth_mode = Mode::CM_NORMAL;
m_shaking_time = 0.0f;
m_shaking_frequency = 0.02f;
m_shaking_magnitude = 0.0f;
m_shaking_offset = Vec3(0., 0., 0.);
m_shaking_target = Vec3(0., 0., 0.);
reset();
m_camera->setNearValue(1.0f);

Expand Down Expand Up @@ -141,10 +147,11 @@ void CameraNormal::moveCamera(float dt, bool smooth, float cam_angle, float dist
m_camera_offset += (wanted_camera_offset - m_camera_offset) * delta;

// next target
Vec3 current_target = btt(Vec3(0, 0.5f, 0));
// shake offset applied so that the camera doesn't fully target the player during shake
Vec3 current_target = btt(Vec3(0, 0.5f, 0) + m_shaking_offset);
// new required position of camera
current_position = kart_camera_position_with_offset.toIrrVector();

current_position = kart_camera_position_with_offset.toIrrVector() + m_shaking_offset.toIrrVector();
//Log::info("CAM_DEBUG", "OFFSET: %f %f %f TRANSFORMED %f %f %f TARGET %f %f %f",
// wanted_camera_offset.x(), wanted_camera_offset.y(), wanted_camera_offset.z(),
// kart_camera_position_with_offset.x(), kart_camera_position_with_offset.y(),
Expand Down Expand Up @@ -312,6 +319,33 @@ void CameraNormal::update(float dt)

getCameraSettings(getMode(), &above_kart, &cam_angle, &side_way,
&distance, &smoothing, &cam_roll_angle);

// If the kart speed is higher than engine speed, apply camera shake.
// The shake intensity is higher at higher speeds.
float kart_speed = m_kart->getSpeed();
m_shaking_magnitude = clamp<float>(powf((kart_speed - m_kart->getKartProperties()->getEngineMaxSpeed()) / 7.0 , 5.0) , 0.0f, 1.0f) * MAX_SHAKING_MAGNITUDE;

bool is_game_paused = GUIEngine::GameState::GAME && GUIEngine::ModalDialog::isADialogActive() && World::getWorld();
bool apply_camera_shake = !is_game_paused && UserConfigParams::m_camera_use_shake && m_shaking_magnitude > 0.0f && m_kart->isOnGround();

if(apply_camera_shake)
{
if(m_shaking_time > m_shaking_frequency)
{
m_shaking_time = 0.0f;
m_shaking_target = Vec3(
(rand() / static_cast<float>(RAND_MAX)) * 2.0f - 1.0f,
(rand() / static_cast<float>(RAND_MAX)) * 2.0f - 1.0f,
(rand() / static_cast<float>(RAND_MAX)) * 2.0f - 1.0f
) * m_shaking_magnitude;
}
float t = min_<float>(m_shaking_time / m_shaking_frequency, 1.0f);
m_shaking_offset = m_shaking_offset.lerp(m_shaking_target, t);
m_shaking_time += dt;
}
else {
m_shaking_offset = 0.0f;
}

// If an explosion is happening, stop moving the camera,
// but keep it target on the kart.
Expand Down
18 changes: 18 additions & 0 deletions src/graphics/camera/camera_normal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ class CameraNormal : public Camera
/** Factor of the effects of steering in camera aim. */
float m_rotation_range;

/** Time, in seconds, for a single shake. */
float m_shaking_frequency;

/** The intensity of the shake. */
float m_shaking_magnitude;

/** Time elapsed after the single shake started, in seconds. */
float m_shaking_time;

/** Displacement from the exact camera location due to shaking. */
Vec3 m_shaking_offset;

/** The displacement the current camera shake aims to reach. */
Vec3 m_shaking_target;

/** The maximum camera shake intensity. */
const float MAX_SHAKING_MAGNITUDE = 0.016f;

Vec3 m_camera_offset;

Mode m_last_smooth_mode;
Expand Down
9 changes: 9 additions & 0 deletions src/states_screens/dialogs/custom_camera_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void CustomCameraSettingsDialog::beforeAddingWidgets()
getWidget<SpinnerWidget>("smooth_position")->setFloatValue(UserConfigParams::m_standard_camera_forward_smooth_position);
getWidget<SpinnerWidget>("smooth_rotation")->setFloatValue(UserConfigParams::m_standard_camera_forward_smooth_rotation);
getWidget<CheckBoxWidget>("use_soccer_camera")->setState(UserConfigParams::m_standard_reverse_look_use_soccer_cam);
getWidget<CheckBoxWidget>("use_camera_shake")->setState(UserConfigParams::m_standard_camera_use_shake);
}
else if (UserConfigParams::m_camera_present == 2) // Drone chase camera
{
Expand All @@ -101,6 +102,7 @@ void CustomCameraSettingsDialog::beforeAddingWidgets()
getWidget<SpinnerWidget>("smooth_position")->setFloatValue(UserConfigParams::m_saved_camera_forward_smooth_position);
getWidget<SpinnerWidget>("smooth_rotation")->setFloatValue(UserConfigParams::m_saved_camera_forward_smooth_rotation);
getWidget<CheckBoxWidget>("use_soccer_camera")->setState(UserConfigParams::m_saved_reverse_look_use_soccer_cam);
getWidget<CheckBoxWidget>("use_camera_shake")->setState(UserConfigParams::m_saved_camera_use_shake);
}
#endif
}
Expand All @@ -125,6 +127,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
UserConfigParams::m_camera_forward_smooth_position = getWidget<SpinnerWidget>("smooth_position")->getFloatValue();
UserConfigParams::m_camera_forward_smooth_rotation = getWidget<SpinnerWidget>("smooth_rotation")->getFloatValue();
UserConfigParams::m_reverse_look_use_soccer_cam = getWidget<CheckBoxWidget>("use_soccer_camera")->getState();
UserConfigParams::m_camera_use_shake = getWidget<CheckBoxWidget>("use_camera_shake")->getState();

if (UserConfigParams::m_camera_present == 1) // Standard camera, only smoothing and follow soccer is customizable
{
Expand All @@ -136,6 +139,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
UserConfigParams::m_standard_camera_backward_distance = UserConfigParams::m_camera_backward_distance;
UserConfigParams::m_standard_camera_backward_up_angle = UserConfigParams::m_camera_backward_up_angle;
UserConfigParams::m_standard_reverse_look_use_soccer_cam = UserConfigParams::m_reverse_look_use_soccer_cam;
UserConfigParams::m_standard_camera_use_shake = UserConfigParams::m_camera_use_shake;
}
else if (UserConfigParams::m_camera_present == 2) // Drone chase camera, only smoothing and follow soccer is customizable
{
Expand All @@ -158,6 +162,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
UserConfigParams::m_saved_camera_backward_distance = UserConfigParams::m_camera_backward_distance;
UserConfigParams::m_saved_camera_backward_up_angle = UserConfigParams::m_camera_backward_up_angle;
UserConfigParams::m_saved_reverse_look_use_soccer_cam = UserConfigParams::m_reverse_look_use_soccer_cam;
UserConfigParams::m_saved_camera_use_shake = UserConfigParams::m_camera_use_shake;
}
OptionsScreenDisplay::getInstance()->updateCamera();
m_self_destroy = true;
Expand All @@ -175,6 +180,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
UserConfigParams::m_camera_backward_distance = 2.0;
UserConfigParams::m_camera_backward_up_angle = 10;
UserConfigParams::m_reverse_look_use_soccer_cam = false;
UserConfigParams::m_camera_use_shake = true;
}
else if (UserConfigParams::m_camera_present == 2) // Drone chase camera
{
Expand All @@ -186,6 +192,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
UserConfigParams::m_camera_backward_distance = 2.0;
UserConfigParams::m_camera_backward_up_angle = 10;
UserConfigParams::m_reverse_look_use_soccer_cam = false;
UserConfigParams::m_camera_use_shake = false;
}
else // Custom camera
{
Expand All @@ -197,6 +204,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
UserConfigParams::m_camera_backward_distance = UserConfigParams::m_saved_camera_backward_distance;
UserConfigParams::m_camera_backward_up_angle = UserConfigParams::m_saved_camera_backward_up_angle;
UserConfigParams::m_reverse_look_use_soccer_cam = UserConfigParams::m_saved_reverse_look_use_soccer_cam;
UserConfigParams::m_camera_use_shake = UserConfigParams::m_saved_camera_use_shake;
}
getWidget<SpinnerWidget>("fov")->setValue(UserConfigParams::m_camera_fov);
getWidget<SpinnerWidget>("camera_distance")->setFloatValue(UserConfigParams::m_camera_distance);
Expand All @@ -206,6 +214,7 @@ GUIEngine::EventPropagation CustomCameraSettingsDialog::processEvent(const std::
getWidget<SpinnerWidget>("backward_camera_distance")->setFloatValue(UserConfigParams::m_camera_backward_distance);
getWidget<SpinnerWidget>("backward_camera_angle")->setValue(UserConfigParams::m_camera_backward_up_angle);
getWidget<CheckBoxWidget>("use_soccer_camera")->setState(UserConfigParams::m_reverse_look_use_soccer_cam);
getWidget<CheckBoxWidget>("use_camera_shake")->setState(UserConfigParams::m_camera_use_shake);
}
else if (selection == "cancel")
{
Expand Down