metaforce/Runtime/Camera/CCameraManager.cpp

373 lines
12 KiB
C++
Raw Normal View History

#include "CCameraManager.hpp"
2016-04-16 23:48:29 +00:00
#include "CCameraShakeData.hpp"
2016-09-16 00:56:46 +00:00
#include "CFirstPersonCamera.hpp"
2016-04-17 02:50:45 +00:00
#include "CStateManager.hpp"
#include "World/CScriptWater.hpp"
#include "World/CPlayer.hpp"
2016-10-31 22:56:44 +00:00
#include "GameGlobalObjects.hpp"
2017-01-15 03:07:01 +00:00
#include "TCastTo.hpp"
2017-02-18 02:19:50 +00:00
#include "CCinematicCamera.hpp"
2017-03-24 05:30:16 +00:00
#include "CBallCamera.hpp"
#include "CInterpolationCamera.hpp"
#include "World/CScriptCameraHint.hpp"
2017-01-15 03:07:01 +00:00
namespace urde
{
2016-10-31 22:56:44 +00:00
float CCameraManager::sAspect = 1.42f;
float CCameraManager::sFarPlane = 750.f;
float CCameraManager::sNearPlane = 0.2f;
float CCameraManager::sFirstPersonFOV = 55.f;
float CCameraManager::sThirdPersonFOV = 60.f;
2016-09-16 00:56:46 +00:00
CCameraManager::CCameraManager(TUniqueId curCameraId) : x0_curCameraId(curCameraId)
{
2017-01-23 07:22:17 +00:00
CSfxManager::AddListener(CSfxManager::ESfxChannels::Game, zeus::CVector3f::skZero, zeus::CVector3f::skZero,
2017-09-19 03:59:50 +00:00
{1.f, 0.f, 0.f}, {0.f, 0.f, 1.f}, 50.f, 50.f, 1000.f, 1, 1.f);
sAspect = float(g_Viewport.x8_width / g_Viewport.xc_height);
2016-10-31 22:56:44 +00:00
sFirstPersonFOV = g_tweakGame->GetFirstPersonFOV();
2016-04-17 02:50:45 +00:00
}
2017-07-31 05:19:05 +00:00
bool CCameraManager::IsInFirstPersonCamera() const
{
return x7c_fpCamera->GetUniqueId() == x0_curCameraId;
}
2016-04-17 02:50:45 +00:00
zeus::CVector3f CCameraManager::GetGlobalCameraTranslation(const CStateManager& stateMgr) const
{
2017-02-13 00:00:07 +00:00
TCastToConstPtr<CGameCamera> camera(GetCurrentCamera(stateMgr));
2016-04-17 02:50:45 +00:00
return camera->GetTransform() * x30_shakeOffset;
}
zeus::CTransform CCameraManager::GetCurrentCameraTransform(const CStateManager& stateMgr) const
{
2017-02-13 00:00:07 +00:00
TCastToConstPtr<CGameCamera> camera(GetCurrentCamera(stateMgr));
2016-04-17 02:50:45 +00:00
return camera->GetTransform() * zeus::CTransform::Translate(x30_shakeOffset);
}
void CCameraManager::RemoveCameraShaker(int id)
{
for (auto it = x14_shakers.begin(); it != x14_shakers.end(); ++it)
if (it->xbc_shakerId == id)
2016-04-17 02:50:45 +00:00
{
x14_shakers.erase(it);
2016-04-17 02:50:45 +00:00
break;
}
}
int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx)
2016-04-17 02:50:45 +00:00
{
x14_shakers.emplace_back(data);
x14_shakers.back().xbc_shakerId = ++x2c_lastShakeId;
if (!xa0_24_)
{
xa0_24_ = true;
x90_ = 0.5f;
}
if (sfx && data.x0_duration > 0.f)
{
float vol =zeus::clamp(100.f, std::max(data.GetSomething(), data.GetSomething2()) * 9.f + 100.f, 127.f);
CSfxHandle sfxHandle;
if (data.xc0_flags & 0x1)
sfxHandle = CSfxManager::AddEmitter(1133, data.xc4_sfxPos, zeus::CVector3f::skZero,
vol / 127.f, false, false, 0x7f, kInvalidAreaId);
else
sfxHandle = CSfxManager::SfxStart(1133, vol / 127.f, 0.f, false, 0x7f, false, kInvalidAreaId);
sfxHandle->SetTimeRemaining(data.x0_duration);
}
2016-04-17 02:50:45 +00:00
return x2c_lastShakeId;
}
2016-09-16 00:56:46 +00:00
void CCameraManager::AddCinemaCamera(TUniqueId id, CStateManager& stateMgr) { x4_cineCameras.push_back(id); }
2016-04-17 02:50:45 +00:00
void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId)
{
if (val)
{
++x74_fluidCounter;
x78_fluidId = fluidId;
}
else
--x74_fluidCounter;
}
void CCameraManager::Update(float dt, CStateManager& stateMgr)
{
2017-03-26 05:53:04 +00:00
UpdateCameraHints(dt, stateMgr);
2016-10-31 22:56:44 +00:00
ThinkCameras(dt, stateMgr);
UpdateListener(stateMgr);
UpdateRumble(dt, stateMgr);
UpdateFog(dt, stateMgr);
#if 0
2016-04-17 02:50:45 +00:00
const CGameCamera* camera = GetCurrentCamera(stateMgr);
2016-04-29 10:08:46 +00:00
zeus::CVector3f heading = camera->GetTransform().basis * zeus::CVector3f{0.f, 1.f, 0.f};
2016-09-16 00:56:46 +00:00
CSfxManager::UpdateListener(camera->GetTransform().origin, zeus::CVector3f::skZero, heading, {0.f, 0.f, 1.f}, 0x7f);
2016-04-17 02:50:45 +00:00
x30_shakeOffset = zeus::CVector3f::skZero;
2016-09-16 00:56:46 +00:00
for (auto it = x18_shakers.begin(); it != x18_shakers.end();)
2016-04-17 02:50:45 +00:00
{
if (it->x1c_curTime >= it->x18_duration)
{
it = x18_shakers.erase(it);
continue;
}
2016-08-21 20:39:18 +00:00
x30_shakeOffset += it->GeneratePoint(dt, *stateMgr.GetActiveRandom());
2016-04-17 02:50:45 +00:00
++it;
}
if (x18_shakers.size())
{
2016-10-31 22:56:44 +00:00
if (!xa0_25_rumbling || xa0_24_)
2016-04-17 02:50:45 +00:00
{
stateMgr.GetRumbleManager().Rumble(ERumbleFxId::Seven, stateMgr, ERumblePriority::Two);
2016-10-31 22:56:44 +00:00
xa0_25_rumbling = true;
2016-04-17 02:50:45 +00:00
}
}
else
{
2016-10-31 22:56:44 +00:00
xa0_25_rumbling = false;
2016-04-17 02:50:45 +00:00
if (x84_rumbleId != -1)
{
stateMgr.GetRumbleManager().StopRumble(x84_rumbleId);
x84_rumbleId = -1;
}
}
if (x74_fluidCounter)
{
2017-01-15 03:07:01 +00:00
const CScriptWater* water = TCastToConstPtr<CScriptWater>(stateMgr.GetObjectById(x78_fluidId));
2016-04-17 02:50:45 +00:00
if (water)
{
// TODO: Finish
2016-09-16 00:56:46 +00:00
zeus::CColor tmpColor; // Get from water
2016-04-17 02:50:45 +00:00
zeus::CVector2f tmpVector; // Get from camera
2016-08-08 04:48:18 +00:00
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, tmpColor, tmpVector);
2017-06-01 05:34:24 +00:00
stateMgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply,
2016-09-16 00:56:46 +00:00
CCameraFilterPass::EFilterShape::Fullscreen, 0.f, tmpColor, -1);
2016-04-17 02:50:45 +00:00
}
2016-10-31 22:56:44 +00:00
xa0_26_inWater = true;
2016-04-17 02:50:45 +00:00
}
else
{
2016-10-31 22:56:44 +00:00
xa0_26_inWater = false;
2016-04-17 02:50:45 +00:00
x3c_fog.DisableFog();
stateMgr.GetCameraFilterPass(4).DisableFilter(dt);
}
x3c_fog.Update(dt);
2016-10-31 22:56:44 +00:00
#endif
2016-04-17 02:50:45 +00:00
}
CGameCamera* CCameraManager::GetCurrentCamera(CStateManager& stateMgr) const
2016-04-17 02:50:45 +00:00
{
2016-04-17 05:35:32 +00:00
CObjectList* camList = stateMgr.ObjectListById(EGameObjectList::GameCamera);
return static_cast<CGameCamera*>(camList->GetObjectById(GetCurrentCameraId()));
2016-04-17 02:50:45 +00:00
}
const CGameCamera* CCameraManager::GetCurrentCamera(const CStateManager& stateMgr) const
2016-04-17 02:50:45 +00:00
{
const CObjectList* camList = stateMgr.GetObjectListById(EGameObjectList::GameCamera);
return static_cast<const CGameCamera*>(camList->GetObjectById(GetCurrentCameraId()));
}
2017-03-24 05:30:16 +00:00
void CCameraManager::CreateStandardCameras(CStateManager& stateMgr)
{
TUniqueId fpId = stateMgr.AllocateUniqueId();
x7c_fpCamera = new CFirstPersonCamera(fpId, zeus::CTransform::Identity(),
2017-08-19 06:52:13 +00:00
stateMgr.Player()->GetUniqueId(), g_tweakPlayer->GetOrbitCameraSpeed(),
2017-03-24 05:30:16 +00:00
sFirstPersonFOV, sNearPlane, sFarPlane, sAspect);
stateMgr.AddObject(x7c_fpCamera);
2017-08-19 06:52:13 +00:00
stateMgr.Player()->SetCameraState(CPlayer::EPlayerCameraState::FirstPerson, stateMgr);
2017-03-24 05:30:16 +00:00
SetCurrentCameraId(fpId, stateMgr);
x80_ballCamera = new CBallCamera(stateMgr.AllocateUniqueId(), stateMgr.Player()->GetUniqueId(),
zeus::CTransform::Identity(), sThirdPersonFOV,
sNearPlane, sFarPlane, sAspect);
stateMgr.AddObject(x80_ballCamera);
x88_interpCamera = new CInterpolationCamera(stateMgr.AllocateUniqueId(), zeus::CTransform::Identity());
stateMgr.AddObject(x88_interpCamera);
}
2017-02-18 02:19:50 +00:00
void CCameraManager::SkipCinematic(CStateManager& stateMgr)
{
TUniqueId camId = GetCurrentCameraId();
CCinematicCamera* ent = static_cast<CCinematicCamera*>(stateMgr.ObjectById(camId));
while (ent)
{
ent->SetActive(false);
ent->WasDeactivated(stateMgr);
ent = TCastToPtr<CCinematicCamera>(GetCurrentCamera(stateMgr)).GetPtr();
}
stateMgr.GetPlayer().UpdateCinematicState(stateMgr);
x7c_fpCamera->SkipCinematic();
}
2016-09-16 00:56:46 +00:00
float CCameraManager::sub80009148() const
{
const zeus::CVector3f uVec = x7c_fpCamera->GetTransform().upVector();
2017-02-12 03:51:59 +00:00
return 1.f - std::min(std::fabs(std::min(std::fabs(uVec.dot(zeus::CVector3f::skUp)), 1.f) /
std::cos(zeus::degToRad(30.f))), 1.f);
2016-09-16 00:56:46 +00:00
}
2017-03-26 05:53:04 +00:00
void CCameraManager::UpdateCameraHints(float, CStateManager& mgr)
2016-10-31 22:56:44 +00:00
{
2016-10-31 22:56:44 +00:00
}
void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
{
CGameCameraList gcList = mgr.GetCameraObjectList();
for (CEntity* ent : gcList)
{
2017-01-15 03:59:37 +00:00
TCastToPtr<CGameCamera> gc(ent);
2016-10-31 22:56:44 +00:00
if (gc)
{
gc->Think(dt, mgr);
gc->UpdatePerspective(dt);
}
}
if (IsInCinematicCamera())
return;
TUniqueId camId = GetLastCameraId();
2017-01-15 03:07:01 +00:00
const CGameCamera* cam = TCastToConstPtr<CGameCamera>(mgr.GetObjectById(camId));
2016-10-31 22:56:44 +00:00
2017-08-16 05:34:02 +00:00
if (cam != nullptr)
2016-10-31 22:56:44 +00:00
x3bc_curFov = cam->GetFov();
}
void CCameraManager::UpdateFog(float, CStateManager&)
{
}
void CCameraManager::UpdateRumble(float, CStateManager&)
{
}
void CCameraManager::UpdateListener(CStateManager& mgr)
{
const zeus::CTransform xf = GetCurrentCameraTransform(mgr);
2017-09-19 03:59:50 +00:00
CSfxManager::UpdateListener(xf.origin, zeus::CVector3f::skZero, xf.frontVector(), xf.upVector(), 1.f);
2016-10-31 22:56:44 +00:00
}
float CCameraManager::CalculateFogDensity(CStateManager& mgr, const CScriptWater* water)
{
float f31 = water->GetFluidPlane().GetAlpha();
2016-10-31 22:56:44 +00:00
float f1 = 0;
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit))
f1 = (g_tweakPlayer->GetPlayerTranslationFriction(4) * g_tweakPlayer->GetPlayerTranslationFriction(3)) + f31;
2016-10-31 22:56:44 +00:00
else
f1 = (g_tweakPlayer->GetPlayerTranslationFriction(6) * g_tweakPlayer->GetPlayerTranslationFriction(5)) + f31;
2016-10-31 22:56:44 +00:00
return f1 * x94_;
}
void CCameraManager::ResetCameras(CStateManager& mgr)
{
zeus::CTransform xf = mgr.GetPlayer().CreateTransformFromMovementDirection();
xf.origin = mgr.GetPlayer().GetEyePosition();
2016-08-15 20:58:07 +00:00
for (CEntity* ent : mgr.GetCameraObjectList())
{
2017-01-15 03:59:37 +00:00
TCastToPtr<CGameCamera> camObj(ent);
camObj->Reset(xf, mgr);
}
}
2016-10-15 19:18:50 +00:00
void CCameraManager::SetSpecialCameras(CFirstPersonCamera& fp, CBallCamera& ball)
{
x7c_fpCamera = &fp;
x80_ballCamera = &ball;
}
2017-03-24 05:30:16 +00:00
void CCameraManager::ProcessInput(const CFinalInput& input, CStateManager& stateMgr)
{
for (CEntity* ent : stateMgr.GetCameraObjectList())
{
2017-08-16 05:34:02 +00:00
if (ent == nullptr)
2017-03-24 05:30:16 +00:00
continue;
2017-08-16 05:34:02 +00:00
auto& cam = static_cast<CGameCamera&>(*ent);
2017-03-24 05:30:16 +00:00
if (input.ControllerIdx() != cam.x16c_controllerIdx)
continue;
cam.ProcessInput(input, stateMgr);
}
}
2017-03-26 19:36:07 +00:00
void CCameraManager::RenderCameras(const CStateManager& mgr)
{
for (CEntity* cam : mgr.GetCameraObjectList())
static_cast<CGameCamera*>(cam)->Render(mgr);
}
2017-08-02 07:13:11 +00:00
void CCameraManager::SetupBallCamera(CStateManager& mgr)
{
}
2017-08-18 01:30:15 +00:00
void CCameraManager::SetPlayerCamera(CStateManager& mgr, TUniqueId newCamId)
2017-08-02 07:13:11 +00:00
{
}
2017-08-16 05:34:02 +00:00
float CCameraManager::GetCameraBobMagnitude() const
{
return 1.f - zeus::clamp(-1.f, zeus::clamp(-1.f,
x7c_fpCamera->GetTransform().basis[1].dot(zeus::CVector3f::skUp), 1.f) /
std::cos(2.f * M_PIF / 12.f), 1.f);
}
2017-08-18 01:30:15 +00:00
bool CCameraManager::HasBallCameraInitialPositionHint(CStateManager& mgr) const
{
return false;
}
void CCameraManager::RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr)
{
x4_cineCameras.erase(std::remove(x4_cineCameras.begin(), x4_cineCameras.end(), uid));
}
void CCameraManager::DeleteCameraHint(TUniqueId id, CStateManager& mgr)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(id))
{
auto search = std::find_if(x2b0_inactiveCameraHints.begin(), x2b0_inactiveCameraHints.end(),
[id](TUniqueId tid) { return tid == id; });
if (search == x2b0_inactiveCameraHints.end())
{
hint->ClearIdList();
hint->SetInactive(true);
if (x2b0_inactiveCameraHints.size() != 64)
x2b0_inactiveCameraHints.push_back(id);
}
}
}
void CCameraManager::AddInactiveCameraHint(TUniqueId id, CStateManager& mgr)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(id))
{
auto search = std::find_if(x2b0_inactiveCameraHints.begin(), x2b0_inactiveCameraHints.end(),
[id](TUniqueId tid) { return tid == id; });
if (search == x2b0_inactiveCameraHints.end() &&
x2b0_inactiveCameraHints.size() != 64)
x2b0_inactiveCameraHints.push_back(id);
}
}
void CCameraManager::AddActiveCameraHint(TUniqueId id, CStateManager& mgr)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(id))
{
auto search = std::find_if(x334_activeCameraHints.begin(), x334_activeCameraHints.end(),
[id](TUniqueId tid) { return tid == id; });
if (search == x334_activeCameraHints.end() && xac_ != 64 &&
x334_activeCameraHints.size() != 64)
x334_activeCameraHints.push_back(id);
}
}
}