From b27821c5eb1c9eb5b69acda11ab77c7cda018ca9 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Thu, 15 Sep 2016 17:56:46 -0700 Subject: [PATCH] Implement CPlayerCameraBob --- Runtime/Camera/CCameraManager.cpp | 32 ++--- Runtime/Camera/CCameraManager.hpp | 2 + Runtime/World/CPlayer.hpp | 2 + Runtime/World/CPlayerCameraBob.cpp | 201 ++++++++++++++++++++++++++++- Runtime/World/CPlayerCameraBob.hpp | 65 +++++++--- 5 files changed, 267 insertions(+), 35 deletions(-) diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index 2f207cf65..0da7c0764 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -1,5 +1,6 @@ #include "CCameraManager.hpp" #include "CCameraShakeData.hpp" +#include "CFirstPersonCamera.hpp" #include "Audio/CSfxManager.hpp" #include "CGameCamera.hpp" #include "CStateManager.hpp" @@ -10,11 +11,9 @@ namespace urde { -CCameraManager::CCameraManager(TUniqueId curCameraId) -: x0_curCameraId(curCameraId) +CCameraManager::CCameraManager(TUniqueId curCameraId) : x0_curCameraId(curCameraId) { - CSfxManager::AddListener(CSfxManager::ESfxChannels::One, - zeus::CVector3f::skZero, zeus::CVector3f::skZero, + CSfxManager::AddListener(CSfxManager::ESfxChannels::One, zeus::CVector3f::skZero, zeus::CVector3f::skZero, {1.f, 0.f, 0.f}, {0.f, 0.f, 1.f}, 50.f, 50.f, 1000.f, 1, 0x7f); } @@ -32,7 +31,7 @@ zeus::CTransform CCameraManager::GetCurrentCameraTransform(const CStateManager& void CCameraManager::RemoveCameraShaker(int id) { - for (auto it=x18_shakers.begin() ; it != x18_shakers.end() ; ++it) + for (auto it = x18_shakers.begin(); it != x18_shakers.end(); ++it) if (it->x20_shakerId == id) { x18_shakers.erase(it); @@ -47,10 +46,7 @@ int CCameraManager::AddCameraShaker(const CCameraShakeData& data) return x2c_lastShakeId; } -void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr) -{ - x4_cineCameras.push_back(id); -} +void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr) { x4_cineCameras.push_back(id); } void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId) { @@ -67,11 +63,10 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr) { const CGameCamera* camera = GetCurrentCamera(stateMgr); zeus::CVector3f heading = camera->GetTransform().basis * zeus::CVector3f{0.f, 1.f, 0.f}; - CSfxManager::UpdateListener(camera->GetTransform().origin, zeus::CVector3f::skZero, - heading, {0.f, 0.f, 1.f}, 0x7f); + CSfxManager::UpdateListener(camera->GetTransform().origin, zeus::CVector3f::skZero, heading, {0.f, 0.f, 1.f}, 0x7f); x30_shakeOffset = zeus::CVector3f::skZero; - for (auto it=x18_shakers.begin() ; it != x18_shakers.end() ;) + for (auto it = x18_shakers.begin(); it != x18_shakers.end();) { if (it->x1c_curTime >= it->x18_duration) { @@ -106,12 +101,11 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr) if (water) { // TODO: Finish - zeus::CColor tmpColor; // Get from water + zeus::CColor tmpColor; // Get from water zeus::CVector2f tmpVector; // Get from camera x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, tmpColor, tmpVector); stateMgr.GetCameraFilterPass(4).SetFilter(CCameraFilterPass::EFilterType::Multiply, - CCameraFilterPass::EFilterShape::Fullscreen, - 0.f, tmpColor, -1); + CCameraFilterPass::EFilterShape::Fullscreen, 0.f, tmpColor, -1); } x86_26_inWater = true; } @@ -137,6 +131,13 @@ const CGameCamera* CCameraManager::GetCurrentCamera(const CStateManager& stateMg return static_cast(camList->GetObjectById(GetCurrentCameraId())); } +float CCameraManager::sub80009148() const +{ + const zeus::CVector3f uVec = x7c_fpCamera->GetTransform().upVector(); + return 1.f - std::min(std::fabs(std::min(std::fabs(uVec.y * uVec.x * uVec.z * zeus::kUpVec.y + zeus::kUpVec.x + + zeus::kUpVec.z), 1.f) / std::cos(zeus::degToRad(30.f))), 1.f); +} + void CCameraManager::ResetCameras(CStateManager& mgr) { zeus::CTransform xf = mgr.GetPlayer().CreateTransformFromMovementDirection(); @@ -148,5 +149,4 @@ void CCameraManager::ResetCameras(CStateManager& mgr) camObj->Reset(xf, mgr); } } - } diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp index 302514dd0..d0e1ff8ac 100644 --- a/Runtime/Camera/CCameraManager.hpp +++ b/Runtime/Camera/CCameraManager.hpp @@ -73,6 +73,8 @@ public: CFirstPersonCamera* GetFirstPersonCamera() { return x7c_fpCamera; } CBallCamera* GetBallCamera() { return x80_ballCamera; } + + float sub80009148() const; }; } diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index a7c7900ba..9c2a1c866 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -22,6 +22,7 @@ class CPlayer : public CPhysicsActor { friend class CStateManager; friend class CFirstPersonCamera; + friend class CPlayerCameraBob; public: enum class EPlayerScanState { @@ -74,6 +75,7 @@ private: : x0_(a), x4_(b), x8_(c), xc_(d), x1c_(e) {} }; + bool x38c_; bool x3dc_; std::unique_ptr x490_gun; std::unique_ptr x768_morphball; diff --git a/Runtime/World/CPlayerCameraBob.cpp b/Runtime/World/CPlayerCameraBob.cpp index 50f7138c3..f20571257 100644 --- a/Runtime/World/CPlayerCameraBob.cpp +++ b/Runtime/World/CPlayerCameraBob.cpp @@ -1,4 +1,8 @@ #include "CPlayerCameraBob.hpp" +#include "World/CPlayer.hpp" +#include "CStateManager.hpp" +#include "Camera/CCameraManager.hpp" +#include "zeus/Math.hpp" namespace urde { @@ -16,12 +20,206 @@ float CPlayerCameraBob::kViewWanderSpeedMax = 0.3f; float CPlayerCameraBob::kViewWanderRollVariation = 0.3f; float CPlayerCameraBob::kGunBobMagnitude = 0.3f; float CPlayerCameraBob::kHelmetBobMagnitude = 2.f; +const float CPlayerCameraBob::kLandingBobDamping = 2.f * zeus::sqrtF(150.f); CPlayerCameraBob::CPlayerCameraBob(ECameraBobType type, const zeus::CVector2f& vec, float f1) - : x0_type(type), x4_vec(vec), xc_(f1) +: x0_type(type), x4_vec(vec), xc_(f1) { } +zeus::CTransform CPlayerCameraBob::GetViewWanderTransform() const { return xd0_viewWanderXf; } + +zeus::CVector3f CPlayerCameraBob::GetHelmetBobTranslation() const +{ + + return {kHelmetBobMagnitude * x2c_cameraBobTransform.origin.x, + kHelmetBobMagnitude * x2c_cameraBobTransform.origin.y, + kHelmetBobMagnitude * (x2c_cameraBobTransform.origin.z - x78_)}; +} + +zeus::CTransform CPlayerCameraBob::GetGunBobTransformation() const +{ + return zeus::CTransform::Translate((1.f + kGunBobMagnitude) * x2c_cameraBobTransform.origin); +} + +zeus::CTransform CPlayerCameraBob::GetCameraBobTransformation() const { return x2c_cameraBobTransform; } + +void CPlayerCameraBob::SetPlayerVelocity(const zeus::CVector3f& velocity) +{ + x5c_playerVelocity = velocity; + x68_ = zeus::min(x68_, velocity.z); +} + +void CPlayerCameraBob::SetBobMagnitude(float magnitude) { x10_bobMagnitude = zeus::clamp(0.f, magnitude, 1.f); } + +void CPlayerCameraBob::SetBobTimeScale(float ts) { x18_bobTimeScale = zeus::clamp(0.f, ts, 1.f); } + +void CPlayerCameraBob::ResetCameraBobTime() { x1c_bobTime = 0.f; } + +void CPlayerCameraBob::SetState(CPlayerCameraBob::ECameraBobState state, CStateManager& mgr) +{ + if (x24_curState == state) + return; + + x20_oldState = x24_curState; + x24_curState = state; + if (x20_oldState == ECameraBobState::Two) + { + x28_applyLandingTrans = true; + x68_ = std::min(x68_, -35.f); + x29_ = (x68_ >= -30.f); + if (x29_) + x74_ += x68_; + else + { + x6c_ += x68_; + x68_ = 0.f; + } + } + + if (x24_curState == ECameraBobState::Three && x100_ != 0.f) + InitViewWander(mgr); +} + +void CPlayerCameraBob::InitViewWander(CStateManager& mgr) +{ + x7c_wanderPoints[0] = {0.f, 1.f, 0.f}; + x7c_wanderPoints[1] = x7c_wanderPoints[0]; + x7c_wanderPoints[2] = x7c_wanderPoints[0]; + x7c_wanderPoints[3] = CalculateRandomViewWanderPosition(mgr); + xb0_wanderPitches[0] = 0.f; + xb0_wanderPitches[1] = xb0_wanderPitches[0]; + xb0_wanderPitches[2] = xb0_wanderPitches[0]; + xb0_wanderPitches[3] = CalculateRandomViewWanderPitch(mgr); + + xc8_viewWanderSpeed = + (kViewWanderSpeedMax - kViewWanderRadius) * kViewWanderRadius + mgr.GetActiveRandom()->Float(); + xc4_wanderTime = 0.f; + xcc_wanderIndex = 0; +} + +void CPlayerCameraBob::UpdateViewWander(float dt, CStateManager& mgr) +{ + zeus::CVector3f pt = zeus::getCatmullRomSplinePoint( + x7c_wanderPoints[xcc_wanderIndex], x7c_wanderPoints[(xcc_wanderIndex + 1) & 3], + x7c_wanderPoints[(xcc_wanderIndex + 2) & 3], x7c_wanderPoints[(xcc_wanderIndex + 3) & 3], dt); + + pt.x *= x100_; + pt.z *= x100_; + zeus::CTransform orient = zeus::CTransform::RotateY(( + zeus::getCatmullRomSplinePoint(xb0_wanderPitches[xcc_wanderIndex], xb0_wanderPitches[(xcc_wanderIndex + 1) & 3], + xb0_wanderPitches[(xcc_wanderIndex + 2) & 3], + xb0_wanderPitches[(xcc_wanderIndex + 3) & 3], dt) * + x100_)); + xd0_viewWanderXf = zeus::lookAt(pt, zeus::CVector3f::skZero, zeus::kUpVec) * orient; + + xc4_wanderTime = (xc8_viewWanderSpeed * xc4_wanderTime) + dt; + if (xc4_wanderTime > 1.f) + { + x7c_wanderPoints[xcc_wanderIndex] = CalculateRandomViewWanderPosition(mgr); + xb0_wanderPitches[xcc_wanderIndex] = CalculateRandomViewWanderPitch(mgr); + xc8_viewWanderSpeed = + ((kViewWanderSpeedMax - kViewWanderSpeedMin) * kViewWanderSpeedMin) + mgr.GetActiveRandom()->Float(); + xcc_wanderIndex = (xcc_wanderIndex + 1) & 3; + xc4_wanderTime -= 1.f; + } +} + +void CPlayerCameraBob::Update(float dt, CStateManager& mgr) +{ + x1c_bobTime = (dt * x1c_bobTime) + x18_bobTimeScale; + float landSpring = kLandingBobSpringConstant; + float landDampen = kLandingBobDamping; + if (x28_applyLandingTrans) + { + landDampen = 4.f * zeus::sqrtF(40.f); + landSpring = 40.f; + } + + x6c_ = dt * x6c_ + -(landSpring * -(landDampen * x6c_) - x28_applyLandingTrans); + x70_landingTranslation = x6c_ * x28_applyLandingTrans + dt; + x74_ = dt * x74_ + -(80.f * -((6.f * zeus::sqrtF(80.f)) * x74_) - x78_); + x78_ = x74_ * x78_ + dt; + if (std::fabs(x6c_) < 0.0049f && std::fabs(x70_landingTranslation) < 0.0049f && std::fabs(x78_) < 0.0049f) + { + x28_applyLandingTrans = false; + x28_applyLandingTrans = 0.f; + x78_ = 0.f; + } + + if (x24_curState == ECameraBobState::Three) + x104_ = 1.f; + else + x104_ = 0.f; + + float f1 = mgr.GetCameraManager()->sub80009148(); + x70_landingTranslation *= f1; + x78_ *= f1; + x104_ *= f1; + if (mgr.GetPlayer().x38c_) + { + x70_landingTranslation *= 0.2f; + x78_ *= 0.2f; + x104_ *= 0.4f; + } + + x100_ = kTargetMagnitudeTrackingRate * x100_ + (x104_ - x100_); + x100_ = std::max(x100_, 0.f); + float tmp = x14_; + x14_ = kTargetMagnitudeTrackingRate * tmp + (x10_bobMagnitude - tmp); + UpdateViewWander(dt, mgr); + x78_ = tmp; + + x2c_cameraBobTransform = GetViewWanderTransform() * CalculateCameraBobTransformation() * + zeus::lookAt(zeus::CVector3f::skZero, {0.f, 2.f, x78_}, zeus::kUpVec); +} + +zeus::CVector3f CPlayerCameraBob::CalculateRandomViewWanderPosition(CStateManager& mgr) +{ + const float angle = (2.f * (M_PIF * mgr.GetActiveRandom()->Float())); + const float bias = kViewWanderRadius * mgr.GetActiveRandom()->Float(); + return {(bias * std::sin(angle)), 1.f, (bias * std::cos(angle))}; +} + +float CPlayerCameraBob::CalculateRandomViewWanderPitch(CStateManager& mgr) +{ + return zeus::degToRad((2.f * (mgr.GetActiveRandom()->Float() - 0.5f)) * kViewWanderRollVariation); +} + +void CPlayerCameraBob::CalculateMovingTranslation(float& x, float& y) const +{ + if (x0_type == ECameraBobType::Zero) + { + double c = ((M_PIF * 2.f) * std::fmod(x1c_bobTime, 2.0f * xc_) / xc_); + x = (x14_ * x4_vec.x) * std::sin(c); + y = (x14_ * x4_vec.y) * (std::fabs(std::cos(c * .5)) * std::cos(c * .5)); + } + else if (x0_type == ECameraBobType::One) + { + float fX = std::fmod(x1c_bobTime, 2.f * xc_); + if (fX > xc_) + x = (2.f - (fX / xc_)) * (x14_ * x4_vec.x); + else + x = ((fX / xc_)) * (x14_ * x4_vec.x); + + float sY = std::sin(std::fmod((M_PI * fX) / xc_, M_PI)); + y = (((1.f - sY) * (x14_ * x4_vec.y)) * (0.5f * (-((sY * 1.f) - sY) * (x14_ * x4_vec.y)))) + 0.5f; + } +} + +float CPlayerCameraBob::CalculateLandingTranslation() const { return x70_landingTranslation; } + +zeus::CTransform CPlayerCameraBob::CalculateCameraBobTransformation() const +{ + float x = 0.f; + float y = 0.f; + CalculateMovingTranslation(x, y); + if (x28_applyLandingTrans) + y += CalculateLandingTranslation(); + + return zeus::CTransform::Translate(x, 0.f, y); +} + void CPlayerCameraBob::ReadTweaks(CInputStream& in) { if (in.hasError()) @@ -42,5 +240,4 @@ void CPlayerCameraBob::ReadTweaks(CInputStream& in) kGunBobMagnitude = in.readFloatBig(); kHelmetBobMagnitude = in.readFloatBig(); } - } diff --git a/Runtime/World/CPlayerCameraBob.hpp b/Runtime/World/CPlayerCameraBob.hpp index dfc00257f..293634a91 100644 --- a/Runtime/World/CPlayerCameraBob.hpp +++ b/Runtime/World/CPlayerCameraBob.hpp @@ -9,6 +9,7 @@ namespace urde { +class CStateManager; class CPlayerCameraBob { public: @@ -17,6 +18,20 @@ public: Zero, One }; + + enum class ECameraBobState + { + Zero, + One, + Two, + Three, + Four, + Five, + Six, + Seven, + Eight + }; + private: static float kCameraBobExtentX; static float kCameraBobExtentY; @@ -32,38 +47,54 @@ private: static float kViewWanderRollVariation; static float kGunBobMagnitude; static float kHelmetBobMagnitude; + static const float kLandingBobDamping; ECameraBobType x0_type; zeus::CVector2f x4_vec; float xc_; - float x10_ = 0.f; + float x10_bobMagnitude = 0.f; float x14_ = 0.f; - float x18_ = 0.f; - float x1c_ = 0.f; - u32 x20_ = 8; - u32 x24_ = 8; - bool x28_ = false; + float x18_bobTimeScale = 0.f; + float x1c_bobTime = 0.f; + ECameraBobState x20_oldState = ECameraBobState::Eight; + ECameraBobState x24_curState = ECameraBobState::Eight; + bool x28_applyLandingTrans = false; bool x29_ = false; - zeus::CTransform x2c_; - float x5c_ = 0.f; - float x60_ = 0.f; - float x64_ = 0.f; + zeus::CTransform x2c_cameraBobTransform; + zeus::CVector3f x5c_playerVelocity; float x68_ = 0.f; float x6c_ = 0.f; - float x70_ = 0.f; + float x70_landingTranslation = 0.f; float x74_ = 0.f; float x78_ = 0.f; - zeus::CVector3f x7c_[4] = {zeus::CVector3f{0.f, 1.f, 0.f}}; - float xb0_[4] = {0.f}; - float xc4_ = 0.f; - float xc8_ = 0.1f; - u32 xcc_ = 0; - zeus::CTransform xd0_; + zeus::CVector3f x7c_wanderPoints[4] = {zeus::CVector3f{0.f, 1.f, 0.f}}; + float xb0_wanderPitches[4] = {0.f}; + float xc4_wanderTime = 0.f; + float xc8_viewWanderSpeed = kViewWanderSpeedMin; + u32 xcc_wanderIndex = 0; + zeus::CTransform xd0_viewWanderXf; float x100_ = FLT_EPSILON; float x104_ = 0.f; public: CPlayerCameraBob(ECameraBobType type, const zeus::CVector2f& vec, float); + zeus::CTransform GetViewWanderTransform() const; + zeus::CVector3f GetHelmetBobTranslation() const; + zeus::CTransform GetGunBobTransformation() const; + zeus::CTransform GetCameraBobTransformation() const; + void SetPlayerVelocity(const zeus::CVector3f& velocity); + void SetBobMagnitude(float); + void SetBobTimeScale(float); + void ResetCameraBobTime(); + void SetState(ECameraBobState, CStateManager&); + void InitViewWander(CStateManager&); + void UpdateViewWander(float, CStateManager&); + void Update(float, CStateManager &); + zeus::CVector3f CalculateRandomViewWanderPosition(CStateManager&); + float CalculateRandomViewWanderPitch(CStateManager&); + void CalculateMovingTranslation(float& x, float& y) const; + float CalculateLandingTranslation() const; + zeus::CTransform CalculateCameraBobTransformation() const; static void ReadTweaks(CInputStream& in); };