From 54b0bdcabae5f32ceef6255eb0a20b1d9f114f04 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Wed, 9 Jun 2021 23:35:50 +0200 Subject: [PATCH] [ClientPlayer] Added optional view bobbing. --- external/gamekit | 2 +- source/client/core/Config.cpp | 5 +- source/client/core/Config.hpp | 1 + source/client/states/SettingsMenuState.cpp | 6 +- source/client/world/ClientPlayer.cpp | 72 +++++++++++++++++----- source/client/world/ClientPlayer.hpp | 12 +++- 6 files changed, 75 insertions(+), 23 deletions(-) diff --git a/external/gamekit b/external/gamekit index d8d8724b..1de5e4c3 160000 --- a/external/gamekit +++ b/external/gamekit @@ -1 +1 @@ -Subproject commit d8d8724b88bd78b18fe0ee26965d2457bb154941 +Subproject commit 1de5e4c3fe1ee4694bbee3acf86f72633018bc53 diff --git a/source/client/core/Config.cpp b/source/client/core/Config.cpp index e25f438c..53ba2f76 100644 --- a/source/client/core/Config.cpp +++ b/source/client/core/Config.cpp @@ -55,7 +55,8 @@ bool Config::isSmoothLightingEnabled = true; bool Config::isWireframeModeEnabled = false; bool Config::isFullscreenModeEnabled = false; bool Config::isVerticalSyncEnabled = true; -bool Config::isStarRenderingEnabled = true; +bool Config::isStarRenderingEnabled = false; // TODO: Set to 'true' once rendering is optimized +bool Config::isViewBobbingEnabled = false; // TODO: Set to 'true' once the result is OK float Config::cameraFOV = 70.0f; u16 Config::screenWidth = 1600; u16 Config::screenHeight = 1050; @@ -102,6 +103,7 @@ void Config::loadConfigFromFile(const char *filename) { isFullscreenModeEnabled = lua["isFullscreenModeEnabled"].get_or(isFullscreenModeEnabled); isVerticalSyncEnabled = lua["isVerticalSyncEnabled"].get_or(isVerticalSyncEnabled); isStarRenderingEnabled = lua["isStarRenderingEnabled"].get_or(isStarRenderingEnabled); + isViewBobbingEnabled = lua["isViewBobbingEnabled"].get_or(isViewBobbingEnabled); cameraFOV = lua["cameraFOV"].get_or(cameraFOV); screenWidth = lua["screenWidth"].get_or(screenWidth); screenHeight = lua["screenHeight"].get_or(screenHeight); @@ -143,6 +145,7 @@ void Config::saveConfigToFile(const char *filename) { file << "isFullscreenModeEnabled = " << (isFullscreenModeEnabled ? "true" : "false") << std::endl; file << "isVerticalSyncEnabled = " << (isVerticalSyncEnabled ? "true" : "false") << std::endl; file << "isStarRenderingEnabled = " << (isStarRenderingEnabled ? "true" : "false") << std::endl; + file << "isViewBobbingEnabled = " << (isViewBobbingEnabled ? "true" : "false") << std::endl; file << "cameraFOV = " << cameraFOV << std::endl; file << "screenWidth = " << screenWidth << std::endl; file << "screenHeight = " << screenHeight << std::endl; diff --git a/source/client/core/Config.hpp b/source/client/core/Config.hpp index 3af70aa3..4cc26f0f 100644 --- a/source/client/core/Config.hpp +++ b/source/client/core/Config.hpp @@ -51,6 +51,7 @@ namespace Config { extern bool isFullscreenModeEnabled; extern bool isVerticalSyncEnabled; extern bool isStarRenderingEnabled; + extern bool isViewBobbingEnabled; extern float cameraFOV; extern u16 screenWidth; extern u16 screenHeight; diff --git a/source/client/states/SettingsMenuState.cpp b/source/client/states/SettingsMenuState.cpp index f1068c08..7015c1fe 100644 --- a/source/client/states/SettingsMenuState.cpp +++ b/source/client/states/SettingsMenuState.cpp @@ -291,13 +291,15 @@ void SettingsMenuState::addGraphicsButtons() { slider.setText("Mipmap Levels: " + std::to_string(Config::mipmapLevels)); }, 0, 4, Config::mipmapLevels); - addToggleButton("Star Rendering", Config::isStarRenderingEnabled, false); - m_menuWidget.addSlider("FOV: " + std::to_string((int)Config::cameraFOV), [] (SliderWidget &slider, u32) { Config::cameraFOV = (float)slider.getCurrentValue(); slider.setText("FOV: " + std::to_string((int)Config::cameraFOV)); }, 45, 135, (int)Config::cameraFOV); + addToggleButton("Star Rendering", Config::isStarRenderingEnabled, false); + + addToggleButton("View Bobbing", Config::isViewBobbingEnabled, false); + updateWidgetPosition(); } diff --git a/source/client/world/ClientPlayer.cpp b/source/client/world/ClientPlayer.cpp index 123a01be..a9b81a91 100644 --- a/source/client/world/ClientPlayer.cpp +++ b/source/client/world/ClientPlayer.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include "ClientCommandHandler.hpp" @@ -51,22 +52,29 @@ void ClientPlayer::turnH(float angle) { if (m_viewAngleH >= 180.f) m_viewAngleH -= 360.f; if (m_viewAngleH < -180.f) m_viewAngleH += 360.f; - updateCamera(); + // updateCamera(); } void ClientPlayer::turnViewV(float angle) { m_viewAngleV = std::max(std::min(m_viewAngleV + angle, 90.f), -90.f); - updateCamera(); + // updateCamera(); } void ClientPlayer::updateCamera() { - float ch = cosf(m_viewAngleH * gk::DEG_TO_RADf); - float sh = sinf(m_viewAngleH * gk::DEG_TO_RADf); - float cv = cosf(m_viewAngleV * gk::DEG_TO_RADf); - float sv = sinf(m_viewAngleV * gk::DEG_TO_RADf); - float cr = cosf(m_viewAngleRoll * gk::DEG_TO_RADf); - float sr = sinf(m_viewAngleRoll * gk::DEG_TO_RADf); + float viewAngleH = m_viewAngleH; + float viewAngleV = m_viewAngleV; + float viewAngleRoll = m_viewAngleRoll; + + if (Config::isViewBobbingEnabled) + applyViewBobbing(viewAngleH, viewAngleV, viewAngleRoll); + + float ch = cosf(viewAngleH * gk::DEG_TO_RADf); + float sh = sinf(viewAngleH * gk::DEG_TO_RADf); + float cv = cosf(viewAngleV * gk::DEG_TO_RADf); + float sv = sinf(viewAngleV * gk::DEG_TO_RADf); + float cr = cosf(viewAngleRoll * gk::DEG_TO_RADf); + float sr = sinf(viewAngleRoll * gk::DEG_TO_RADf); m_forwardDir = gk::Vector3f{ch * cv, sh * cv, sv}; m_camera.setDirection(m_forwardDir); @@ -76,8 +84,10 @@ void ClientPlayer::updateCamera() { void ClientPlayer::move(float direction) { direction += m_viewAngleH; - m_velocity.x = 0.04f * cosf(direction * gk::DEG_TO_RADf); - m_velocity.y = 0.04f * sinf(direction * gk::DEG_TO_RADf); + constexpr float playerSpeed = 0.0275f; + + m_velocity.x = playerSpeed * cosf(direction * gk::DEG_TO_RADf); + m_velocity.y = playerSpeed * sinf(direction * gk::DEG_TO_RADf); } void ClientPlayer::processInputs() { @@ -119,23 +129,33 @@ void ClientPlayer::updatePosition(const ClientWorld &world) { m_isJumping = true; - if (m_velocity.z < -m_jumpSpeed) // Limit max vertical speed to jump speed + // Limit max vertical speed to jump speed + if (m_velocity.z < -m_jumpSpeed) m_velocity.z = -m_jumpSpeed; } } + // Block player until the chunk loads, unless "no clip" mode is enabled else if (!Config::isNoClipEnabled) { - // Block player until the chunk loads, unless "no clip" mode is enabled - m_velocity = glm::vec3{0.f, 0.f, 0.f}; + m_velocity = gk::Vector3f::Zero; } if (!Config::isNoClipEnabled) checkCollisions(world); + // Reduce velocity while in the air, unless "fly mode" is enabled if (!Config::isFlyModeEnabled && m_velocity.z != 0.f) { - m_velocity.x *= 0.75f; - m_velocity.y *= 0.75f; + m_velocity.x *= 0.65f; + m_velocity.y *= 0.65f; } + // Increase velocity in fly mode + if (Config::isFlyModeEnabled) { + m_velocity.x *= 2.f; + m_velocity.y *= 2.f; + } + + updateCamera(); + setPosition(m_x + m_velocity.x, m_y + m_velocity.y, m_z + m_velocity.z); m_velocity.x = 0.f; @@ -192,7 +212,7 @@ bool passable(const ClientWorld &world, double x, double y, double z) { return !blockState || !blockState->block().id() || !blockState->isCollidable(); } -void ClientPlayer::testPoint(const ClientWorld &world, double x, double y, double z, glm::vec3 &vel) { +void ClientPlayer::testPoint(const ClientWorld &world, double x, double y, double z, gk::Vector3f &vel) { if(!passable(world, x + vel.x, y, z)) vel.x = 0.f; if(!passable(world, x, y + vel.y, z)) vel.y = 0.f; if(!passable(world, x, y, z + vel.z)) { @@ -201,3 +221,23 @@ void ClientPlayer::testPoint(const ClientWorld &world, double x, double y, doubl } } +void ClientPlayer::applyViewBobbing(float &viewAngleH, float &viewAngleV, float &viewAngleRoll) { + if (m_velocity != gk::Vector3f::Zero && m_velocity.z == 0 && !Config::isFlyModeEnabled) { + if (!m_isMoving) { + m_movementStartTime = gk::GameClock::getInstance().getTicks(); + m_isMoving = true; + } + } + else { + m_isMoving = false; + } + + if (m_isMoving) { + // float t = (float)(gk::GameClock::getInstance().getTicks()); + float t = (float)(gk::GameClock::getInstance().getTicks() - m_movementStartTime); + viewAngleH += 0.4f * sinf(t / 150.f); + viewAngleV += 0.4f * sinf(t / 75.f); + viewAngleRoll += 0.3f * -sinf(t / 150.f); + } +} + diff --git a/source/client/world/ClientPlayer.hpp b/source/client/world/ClientPlayer.hpp index b27ef66b..35426ed1 100644 --- a/source/client/world/ClientPlayer.hpp +++ b/source/client/world/ClientPlayer.hpp @@ -66,7 +66,9 @@ class ClientPlayer : public Player { gk::Camera &camera() { return m_camera; } private: - void testPoint(const ClientWorld &world, double x, double y, double z, glm::vec3 &vel); + void testPoint(const ClientWorld &world, double x, double y, double z, gk::Vector3f &vel); + + void applyViewBobbing(float &viewAngleH, float &viewAngleV, float &viewAngleRoll); static ClientPlayer *s_instance; @@ -76,9 +78,13 @@ class ClientPlayer : public Player { gk::Vector3f m_cameraLocalPos; - glm::vec3 m_velocity{0.f}; - bool m_isJumping = false; + gk::Vector3f m_velocity = gk::Vector3f::Zero; + // For view bobbing only + bool m_isMoving = false; + u64 m_movementStartTime = 0; + + bool m_isJumping = false; const float m_jumpSpeed = 0.06f; std::optional m_lastChunkPos;