mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
set_fov: Add support for time-based transitions (#9705)
This commit is contained in:
parent
ac368af4fe
commit
e0ea87f1f3
8 changed files with 123 additions and 34 deletions
|
@ -86,6 +86,51 @@ Camera::~Camera()
|
|||
m_wieldmgr->drop();
|
||||
}
|
||||
|
||||
void Camera::notifyFovChange()
|
||||
{
|
||||
LocalPlayer *player = m_client->getEnv().getLocalPlayer();
|
||||
assert(player);
|
||||
|
||||
PlayerFovSpec spec = player->getFov();
|
||||
|
||||
/*
|
||||
* Update m_old_fov_degrees first - it serves as the starting point of the
|
||||
* upcoming transition.
|
||||
*
|
||||
* If an FOV transition is already active, mark current FOV as the start of
|
||||
* the new transition. If not, set it to the previous transition's target FOV.
|
||||
*/
|
||||
if (m_fov_transition_active)
|
||||
m_old_fov_degrees = m_curr_fov_degrees;
|
||||
else
|
||||
m_old_fov_degrees = m_server_sent_fov ? m_target_fov_degrees : m_cache_fov;
|
||||
|
||||
/*
|
||||
* Update m_server_sent_fov next - it corresponds to the target FOV of the
|
||||
* upcoming transition.
|
||||
*
|
||||
* Set it to m_cache_fov, if server-sent FOV is 0. Otherwise check if
|
||||
* server-sent FOV is a multiplier, and multiply it with m_cache_fov instead
|
||||
* of overriding.
|
||||
*/
|
||||
if (spec.fov == 0.0f) {
|
||||
m_server_sent_fov = false;
|
||||
m_target_fov_degrees = m_cache_fov;
|
||||
} else {
|
||||
m_server_sent_fov = true;
|
||||
m_target_fov_degrees = spec.is_multiplier ? m_cache_fov * spec.fov : spec.fov;
|
||||
}
|
||||
|
||||
if (spec.transition_time > 0.0f)
|
||||
m_fov_transition_active = true;
|
||||
|
||||
// If FOV smooth transition is active, initialize required variables
|
||||
if (m_fov_transition_active) {
|
||||
m_transition_time = spec.transition_time;
|
||||
m_fov_diff = m_target_fov_degrees - m_old_fov_degrees;
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera::successfullyCreated(std::string &error_message)
|
||||
{
|
||||
if (!m_playernode) {
|
||||
|
@ -462,33 +507,38 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, f32 tool_r
|
|||
m_camera_position = my_cp;
|
||||
|
||||
/*
|
||||
* Apply server-sent FOV. If server doesn't enforce FOV,
|
||||
* check for zoom and set to zoom FOV.
|
||||
* Otherwise, default to m_cache_fov
|
||||
* Apply server-sent FOV, instantaneous or smooth transition.
|
||||
* If not, check for zoom and set to zoom FOV.
|
||||
* Otherwise, default to m_cache_fov.
|
||||
*/
|
||||
if (m_fov_transition_active) {
|
||||
// Smooth FOV transition
|
||||
// Dynamically calculate FOV delta based on frametimes
|
||||
f32 delta = (frametime / m_transition_time) * m_fov_diff;
|
||||
m_curr_fov_degrees += delta;
|
||||
|
||||
f32 fov_degrees;
|
||||
PlayerFovSpec fov_spec = player->getFov();
|
||||
if (fov_spec.fov > 0.0f) {
|
||||
// If server-sent FOV is a multiplier, multiply
|
||||
// it with m_cache_fov instead of overriding
|
||||
if (fov_spec.is_multiplier)
|
||||
fov_degrees = m_cache_fov * fov_spec.fov;
|
||||
else
|
||||
fov_degrees = fov_spec.fov;
|
||||
// Mark transition as complete if target FOV has been reached
|
||||
if ((m_fov_diff > 0.0f && m_curr_fov_degrees >= m_target_fov_degrees) ||
|
||||
(m_fov_diff < 0.0f && m_curr_fov_degrees <= m_target_fov_degrees)) {
|
||||
m_fov_transition_active = false;
|
||||
m_curr_fov_degrees = m_target_fov_degrees;
|
||||
}
|
||||
} else if (m_server_sent_fov) {
|
||||
// Instantaneous FOV change
|
||||
m_curr_fov_degrees = m_target_fov_degrees;
|
||||
} else if (player->getPlayerControl().zoom && player->getZoomFOV() > 0.001f) {
|
||||
// Player requests zoom, apply zoom FOV
|
||||
fov_degrees = player->getZoomFOV();
|
||||
m_curr_fov_degrees = player->getZoomFOV();
|
||||
} else {
|
||||
// Set to client's selected FOV
|
||||
fov_degrees = m_cache_fov;
|
||||
m_curr_fov_degrees = m_cache_fov;
|
||||
}
|
||||
fov_degrees = rangelim(fov_degrees, 1.0f, 160.0f);
|
||||
m_curr_fov_degrees = rangelim(m_curr_fov_degrees, 1.0f, 160.0f);
|
||||
|
||||
// FOV and aspect ratio
|
||||
const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
|
||||
m_aspect = (f32) window_size.X / (f32) window_size.Y;
|
||||
m_fov_y = fov_degrees * M_PI / 180.0;
|
||||
m_fov_y = m_curr_fov_degrees * M_PI / 180.0;
|
||||
// Increase vertical FOV on lower aspect ratios (<16:10)
|
||||
m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect)));
|
||||
m_fov_x = 2 * atan(m_aspect * tan(0.5 * m_fov_y));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue