Work on CScriptCameraHint and CCameraManager

This commit is contained in:
Jack Andersen 2017-10-05 21:29:56 -10:00
parent c46010256c
commit 0f68e2ba3f
18 changed files with 762 additions and 118 deletions

View File

@ -27,10 +27,10 @@ struct CTweakGame final : ITweakGame
Value<float> x44_rippleIntentityPoison;
Value<float> x48_rippleIntensityLava;
Value<float> x4c_fluidEnvBumpScale;
Value<float> x50_unknown14;
Value<float> x54_unknown15;
Value<float> x58_unknown16;
Value<float> x5c_unknown17;
Value<float> x50_waterFogDistanceBase;
Value<float> x54_waterFogDistanceRange;
Value<float> x58_gravityWaterFogDistanceBase;
Value<float> x5c_gravityWaterFogDistanceRange;
Value<float> x60_hardmodeDamageMult;
Value<float> x64_hardmodeWeaponMult;

View File

@ -40,4 +40,34 @@ void CBallCamera::TeleportCamera(const zeus::CVector3f& pos, CStateManager& mgr)
}
void CBallCamera::TeleportCamera(const zeus::CTransform& xf, CStateManager& mgr)
{
}
void CBallCamera::ResetToTweaks(CStateManager& mgr)
{
}
void CBallCamera::UpdateLookAtPosition(float offset, CStateManager& mgr)
{
}
zeus::CTransform CBallCamera::UpdateLookDirection(const zeus::CVector3f& dir, CStateManager& mgr)
{
return {};
}
void CBallCamera::ApplyCameraHint(CStateManager& mgr)
{
}
void CBallCamera::ResetPosition()
{
}
}

View File

@ -20,22 +20,45 @@ public:
};
enum class EBallCameraBehaviour
{
Zero,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight
};
private:
zeus::CVector3f x1d8_;
TUniqueId x3dc_tooCloseActorId = kInvalidUniqueId;
float x3e0_ = 10000.f;
EBallCameraState x400_state;
float x470_;
float x474_;
public:
CBallCamera(TUniqueId, TUniqueId, const zeus::CTransform& xf, float, float, float, float);
void Accept(IVisitor& visitor);
void ProcessInput(const CFinalInput&, CStateManager& mgr);
void Reset(const zeus::CTransform&, CStateManager& mgr);
EBallCameraState GetState() const { return x400_state; }
void SetState(EBallCameraState state, CStateManager& mgr);
bool TransitionFromMorphBallState(CStateManager& mgr);
TUniqueId GetTooCloseActorId() const { return x3dc_tooCloseActorId; }
float GetX3E0() const { return x3e0_; }
void TeleportCamera(const zeus::CVector3f& pos, CStateManager& mgr);
void TeleportCamera(const zeus::CTransform& xf, CStateManager& mgr);
const zeus::CVector3f& GetX1D8() const { return x1d8_; }
void ResetToTweaks(CStateManager& mgr);
void UpdateLookAtPosition(float offset, CStateManager& mgr);
zeus::CTransform UpdateLookDirection(const zeus::CVector3f& dir, CStateManager& mgr);
void SetX470(float f) { x470_ = f; }
void SetX474(float f) { x474_ = f; }
void ApplyCameraHint(CStateManager& mgr);
void ResetPosition();
};
}

View File

@ -10,6 +10,8 @@
#include "CBallCamera.hpp"
#include "CInterpolationCamera.hpp"
#include "World/CScriptCameraHint.hpp"
#include "CPathCamera.hpp"
#include "World/CScriptSpindleCamera.hpp"
namespace urde
{
@ -58,10 +60,10 @@ int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx)
{
x14_shakers.emplace_back(data);
x14_shakers.back().xbc_shakerId = ++x2c_lastShakeId;
if (!xa0_24_)
if (!xa0_24_pendingRumble)
{
xa0_24_ = true;
x90_ = 0.5f;
xa0_24_pendingRumble = true;
x90_rumbleCooldown = 0.5f;
}
if (sfx && data.x0_duration > 0.f)
{
@ -97,65 +99,6 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr)
UpdateListener(stateMgr);
UpdateRumble(dt, stateMgr);
UpdateFog(dt, stateMgr);
#if 0
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);
x30_shakeOffset = zeus::CVector3f::skZero;
for (auto it = x18_shakers.begin(); it != x18_shakers.end();)
{
if (it->x1c_curTime >= it->x18_duration)
{
it = x18_shakers.erase(it);
continue;
}
x30_shakeOffset += it->GeneratePoint(dt, *stateMgr.GetActiveRandom());
++it;
}
if (x18_shakers.size())
{
if (!xa0_25_rumbling || xa0_24_)
{
stateMgr.GetRumbleManager().Rumble(ERumbleFxId::Seven, stateMgr, ERumblePriority::Two);
xa0_25_rumbling = true;
}
}
else
{
xa0_25_rumbling = false;
if (x84_rumbleId != -1)
{
stateMgr.GetRumbleManager().StopRumble(x84_rumbleId);
x84_rumbleId = -1;
}
}
if (x74_fluidCounter)
{
const CScriptWater* water = TCastToConstPtr<CScriptWater>(stateMgr.GetObjectById(x78_fluidId));
if (water)
{
// TODO: Finish
zeus::CColor tmpColor; // Get from water
zeus::CVector2f tmpVector; // Get from camera
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, tmpColor, tmpVector);
stateMgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply,
CCameraFilterPass::EFilterShape::Fullscreen, 0.f, tmpColor, -1);
}
xa0_26_inWater = true;
}
else
{
xa0_26_inWater = false;
x3c_fog.DisableFog();
stateMgr.GetCameraFilterPass(4).DisableFilter(dt);
}
x3c_fog.Update(dt);
#endif
}
CGameCamera* CCameraManager::GetCurrentCamera(CStateManager& stateMgr) const
@ -210,9 +153,359 @@ float CCameraManager::sub80009148() const
std::cos(zeus::degToRad(30.f))), 1.f);
}
void CCameraManager::SetPathCamera(TUniqueId id, CStateManager& mgr)
{
xa4_pathCamId = id;
if (TCastToPtr<CPathCamera> cam = mgr.ObjectById(id))
{
cam->Reset(GetCurrentCameraTransform(mgr), mgr);
x80_ballCamera->TeleportCamera(cam->GetTransform(), mgr);
}
}
void CCameraManager::SetSpindleCamera(TUniqueId id, CStateManager& mgr)
{
xa2_spindleCamId = id;
if (TCastToPtr<CScriptSpindleCamera> cam = mgr.ObjectById(id))
{
cam->Reset(GetCurrentCameraTransform(mgr), mgr);
x80_ballCamera->TeleportCamera(cam->GetTransform(), mgr);
}
}
void CCameraManager::InterpolateToBallCamera(const zeus::CTransform& xf, TUniqueId camId,
const zeus::CVector3f& lookDir, float f1, float f2, float f3,
bool b1, CStateManager& mgr)
{
if (!IsInFirstPersonCamera())
{
x88_interpCamera->SetInterpolation(xf, lookDir, f1, f2, f3, camId, b1, mgr);
if (!ShouldBypassInterpolation())
SetCurrentCameraId(x88_interpCamera->GetUniqueId(), mgr);
}
}
void CCameraManager::RestoreHintlessCamera(CStateManager& mgr)
{
TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(xa6_camHintId);
zeus::CTransform ballCamXf = x80_ballCamera->GetTransform();
xa6_camHintId = kInvalidUniqueId;
xa8_hintPriority = 1000;
if (hint)
{
zeus::CVector3f camToPlayerFlat = mgr.GetPlayer().GetTranslation() - ballCamXf.origin;
camToPlayerFlat.z = 0.f;
if (camToPlayerFlat.canBeNormalized())
camToPlayerFlat.normalize();
else
camToPlayerFlat = mgr.GetPlayer().GetMoveDir();
x80_ballCamera->ResetToTweaks(mgr);
x80_ballCamera->UpdateLookAtPosition(0.f, mgr);
if (!mgr.GetPlayer().IsMorphBallTransitioning() &&
hint->GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Zero)
{
if ((hint->GetHint().GetOverrideFlags() & 0x1000) != 0)
{
x80_ballCamera->SetX474(hint->GetHint().GetX4C());
x80_ballCamera->SetX470(hint->GetHint().GetX5C());
}
else
{
x80_ballCamera->TeleportCamera(x80_ballCamera->UpdateLookDirection(camToPlayerFlat, mgr), mgr);
InterpolateToBallCamera(ballCamXf, x80_ballCamera->GetUniqueId(), x80_ballCamera->GetX1D8(),
hint->GetHint().GetX5C(), hint->GetHint().GetX4C(), hint->GetHint().GetX50(),
((hint->GetHint().GetOverrideFlags() >> 11) & 0x1) != 0, mgr);
}
}
}
}
void CCameraManager::SkipBallCameraCinematic(CStateManager& mgr)
{
if (IsInCinematicCamera())
{
x80_ballCamera->TeleportCamera(GetLastCineCamera(mgr)->GetTransform(), mgr);
x80_ballCamera->SetFovInterpolation(GetLastCineCamera(mgr)->GetFov(), x80_ballCamera->GetFov(), 1.f, 0.f);
SkipCinematic(mgr);
SetCurrentCameraId(x80_ballCamera->GetUniqueId(), mgr);
}
}
void CCameraManager::ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr)
{
if (x80_ballCamera->GetState() == CBallCamera::EBallCameraState::Four)
{
x80_ballCamera->SetState(CBallCamera::EBallCameraState::Zero, mgr);
mgr.GetPlayer().SetCameraState(CPlayer::EPlayerCameraState::Ball, mgr);
}
TCastToPtr<CScriptCameraHint> oldHint = mgr.ObjectById(xa6_camHintId);
xa6_camHintId = hint.GetUniqueId();
xa8_hintPriority = hint.GetPriority();
zeus::CTransform camXf = GetCurrentCameraTransform(mgr);
x80_ballCamera->ApplyCameraHint(mgr);
if ((hint.GetHint().GetOverrideFlags() & 0x20) != 0)
x80_ballCamera->ResetPosition();
switch (hint.GetHint().GetBehaviourType())
{
case CBallCamera::EBallCameraBehaviour::Six:
case CBallCamera::EBallCameraBehaviour::Seven:
SetPathCamera(hint.GetDelegatedCamera(), mgr);
break;
case CBallCamera::EBallCameraBehaviour::Eight:
SetSpindleCamera(hint.GetDelegatedCamera(), mgr);
break;
default:
SetPathCamera(kInvalidUniqueId, mgr);
SetSpindleCamera(kInvalidUniqueId, mgr);
break;
}
if ((hint.GetHint().GetOverrideFlags() & 0x2000) != 0)
SkipBallCameraCinematic(mgr);
x80_ballCamera->UpdateLookAtPosition(0.f, mgr);
if ((hint.GetHint().GetOverrideFlags() & 0x20) == 0 &&
(hint.GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Zero ||
(oldHint && oldHint->GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Zero)))
{
InterpolateToBallCamera(camXf, x80_ballCamera->GetUniqueId(), x80_ballCamera->GetX1D8(),
hint.GetHint().GetX58(), hint.GetHint().GetX4C(), hint.GetHint().GetX50(),
((hint.GetHint().GetOverrideFlags() >> 10) & 0x1) != 0, mgr);
}
}
void CCameraManager::UpdateCameraHints(float, CStateManager& mgr)
{
bool r27 = false;
for (auto it = xac_cameraHints.begin() ; it != xac_cameraHints.end() ;)
{
if (!TCastToPtr<CScriptCameraHint>(mgr.ObjectById(it->second)))
{
r27 = true;
it = xac_cameraHints.erase(it);
continue;
}
++it;
}
bool r26 = false;
for (TUniqueId id : x2b0_inactiveCameraHints)
{
if (TCastToConstPtr<CScriptCameraHint> hint = mgr.GetObjectById(id))
{
if (hint->GetHelperCount() == 0 || hint->GetInactive())
{
for (auto it = xac_cameraHints.begin() ; it != xac_cameraHints.end() ; ++it)
{
if (it->second == id)
{
xac_cameraHints.erase(it);
if (xa6_camHintId == id)
{
r26 = true;
SetPathCamera(kInvalidUniqueId, mgr);
SetSpindleCamera(kInvalidUniqueId, mgr);
}
break;
}
}
}
}
}
x2b0_inactiveCameraHints.clear();
bool r25 = false;
for (TUniqueId id : x334_activeCameraHints)
{
if (TCastToConstPtr<CScriptCameraHint> hint = mgr.GetObjectById(id))
{
bool newActiveHint = false;
for (auto it = xac_cameraHints.begin() ; it != xac_cameraHints.end() ; ++it)
{
if (it->second == id)
{
newActiveHint = true;
break;
}
}
if (!newActiveHint)
{
r25 = true;
xac_cameraHints.emplace_back(hint->GetPriority(), id);
}
}
}
x334_activeCameraHints.clear();
if (r26 || r25 || r27)
{
std::sort(xac_cameraHints.begin(), xac_cameraHints.end(),
[](const auto& a, const auto& b) { return a.first < b.first; });
zeus::CTransform ballCamXf = x80_ballCamera->GetTransform();
if ((r26 || r27) && xac_cameraHints.empty())
{
RestoreHintlessCamera(mgr);
return;
}
bool r26b = false;
CScriptCameraHint* foundHint = nullptr;
for (auto& h : xac_cameraHints)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(h.second))
{
foundHint = hint.GetPtr();
r26b = true;
break;
}
}
if (!r26b)
RestoreHintlessCamera(mgr);
bool r25b = false;
if (foundHint && r26b)
{
if ((foundHint->GetHint().GetOverrideFlags() & 0x80) != 0 && xac_cameraHints.size() > 1)
{
zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition();
if ((foundHint->GetHint().GetOverrideFlags() & 0x100) != 0)
{
zeus::CVector3f camToBall = ballPos - ballCamXf.origin;
if (camToBall.canBeNormalized())
camToBall.normalize();
else
camToBall = ballCamXf.basis[1];
for (auto it = xac_cameraHints.begin() + 1 ; it != xac_cameraHints.end() ; ++it)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(it->second))
{
if ((hint->GetHint().GetOverrideFlags() & 0x80) != 0 && hint->GetPriority() ==
foundHint->GetPriority() &&
hint->GetAreaIdAlways() == foundHint->GetAreaIdAlways())
{
zeus::CVector3f hintToBall = ballPos - foundHint->GetTranslation();
if (hintToBall.canBeNormalized())
hintToBall.normalize();
else
hintToBall = foundHint->GetTransform().basis[1];
float camHintDot = zeus::clamp(-1.f, camToBall.dot(hintToBall), 1.f);
zeus::CVector3f thisHintToBall = ballPos - hint->GetTranslation();
if (thisHintToBall.canBeNormalized())
thisHintToBall.normalize();
else
thisHintToBall = hint->GetTransform().basis[1];
float camThisHintDot = zeus::clamp(-1.f, camToBall.dot(thisHintToBall), 1.f);
if (camThisHintDot > camHintDot)
foundHint = hint.GetPtr();
}
else
{
break;
}
}
else
{
break;
}
}
}
else
{
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(foundHint->GetFirstHelper()))
{
zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition();
zeus::CVector3f f26 = act->GetTranslation() - ballPos;
zeus::CVector3f ballToHelper = f26;
if (ballToHelper.canBeNormalized())
ballToHelper.normalize();
else
ballToHelper = foundHint->GetTransform().basis[1];
for (auto it = xac_cameraHints.begin() + 1 ; it != xac_cameraHints.end() ; ++it)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(it->second))
{
if ((hint->GetHint().GetOverrideFlags() & 0x80) != 0 && hint->GetPriority() ==
foundHint->GetPriority() &&
hint->GetAreaIdAlways() == foundHint->GetAreaIdAlways())
{
zeus::CVector3f hintToHelper = act->GetTranslation() - foundHint->GetTranslation();
if (hintToHelper.canBeNormalized())
hintToHelper.normalize();
else
hintToHelper = foundHint->GetTransform().basis[1];
float ballHintDot = zeus::clamp(-1.f, ballToHelper.dot(hintToHelper), 1.f);
zeus::CVector3f thisBallToHelper = f26;
if (thisBallToHelper.canBeNormalized())
thisBallToHelper.normalize();
else
thisBallToHelper = hint->GetTransform().basis[1];
zeus::CVector3f thisHintToHelper = act->GetTranslation() - hint->GetTranslation();
if (thisHintToHelper.canBeNormalized())
thisHintToHelper.normalize();
else
thisHintToHelper = hint->GetTransform().basis[1];
float thisBallHintDot =
zeus::clamp(-1.f, thisBallToHelper.dot(thisHintToHelper), 1.f);
if (thisBallHintDot > ballHintDot)
foundHint = hint.GetPtr();
}
else
{
break;
}
}
else
{
break;
}
}
}
}
if (foundHint->GetUniqueId() != xa6_camHintId)
r25b = true;
}
else if (xa6_camHintId != foundHint->GetUniqueId())
{
if (foundHint->GetHint().GetBehaviourType() == CBallCamera::EBallCameraBehaviour::Three)
{
if ((foundHint->GetHint().GetOverrideFlags() & 0x20) != 0)
{
x80_ballCamera->TeleportCamera(
zeus::lookAt(foundHint->GetTranslation(), x80_ballCamera->GetX1D8()), mgr);
}
DeleteCameraHint(foundHint->GetUniqueId(), mgr);
if ((foundHint->GetHint().GetOverrideFlags() & 0x2000) != 0)
SkipBallCameraCinematic(mgr);
r25b = false;
}
else
{
r25b = true;
}
}
if (r25b)
ApplyCameraHint(*foundHint, mgr);
}
}
}
void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
@ -221,8 +514,7 @@ void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
for (CEntity* ent : gcList)
{
TCastToPtr<CGameCamera> gc(ent);
if (gc)
if (TCastToPtr<CGameCamera> gc = ent)
{
gc->Think(dt, mgr);
gc->UpdatePerspective(dt);
@ -233,19 +525,83 @@ void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
return;
TUniqueId camId = GetLastCameraId();
const CGameCamera* cam = TCastToConstPtr<CGameCamera>(mgr.GetObjectById(camId));
if (cam != nullptr)
if (const CGameCamera* cam = TCastToConstPtr<CGameCamera>(mgr.GetObjectById(camId)))
x3bc_curFov = cam->GetFov();
}
void CCameraManager::UpdateFog(float, CStateManager&)
void CCameraManager::UpdateFog(float dt, CStateManager& mgr)
{
if (x98_fogDensitySpeed != 0.f)
{
x94_fogDensityFactor += dt * x98_fogDensitySpeed;
if ((x98_fogDensitySpeed > 0.f) ? x94_fogDensityFactor > x9c_fogDensityFactorTarget :
x94_fogDensityFactor < x9c_fogDensityFactorTarget)
{
x94_fogDensityFactor = x9c_fogDensityFactorTarget;
x98_fogDensitySpeed = 0.f;
}
}
void CCameraManager::UpdateRumble(float, CStateManager&)
if (x74_fluidCounter)
{
if (TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(x78_fluidId))
{
zeus::CVector2f zRange(GetCurrentCamera(mgr)->GetNearClipDistance(),
CalculateFogDensity(mgr, water.GetPtr()));
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, water->GetFogColor(), zRange);
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal)
mgr.GetCameraFilterPass(4).DisableFilter(0.f);
else
mgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply, EFilterShape::Fullscreen,
0.f, water->GetFogColor(), {});
}
xa0_26_inWater = true;
}
else if (xa0_26_inWater)
{
mgr.GetCameraManager()->x3c_fog.DisableFog();
mgr.GetCameraFilterPass(4).DisableFilter(0.f);
xa0_26_inWater = false;
}
x3c_fog.Update(dt);
}
void CCameraManager::UpdateRumble(float dt, CStateManager& mgr)
{
x30_shakeOffset = zeus::CVector3f::skZero;
for (auto it = x14_shakers.begin() ; it != x14_shakers.end() ;)
{
CCameraShakeData& shaker = *it;
shaker.Update(dt, mgr);
if (shaker.x4_curTime >= shaker.x0_duration)
{
it = x14_shakers.erase(it);
continue;
}
x30_shakeOffset += shaker.GetPoint();
++it;
}
if (!x14_shakers.empty() && !xa0_25_rumbling && xa0_24_pendingRumble)
{
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Six, 1.f, ERumblePriority::Two);
xa0_25_rumbling = true;
}
if (x90_rumbleCooldown > 0.f)
{
x90_rumbleCooldown -= dt;
}
else if (xa0_25_rumbling)
{
xa0_24_pendingRumble = false;
xa0_25_rumbling = false;
}
if (mgr.GetPlayer().GetCameraState() != CPlayer::EPlayerCameraState::FirstPerson &&
!IsInCinematicCamera())
x30_shakeOffset = zeus::CVector3f::skZero;
}
void CCameraManager::UpdateListener(CStateManager& mgr)
@ -256,14 +612,14 @@ void CCameraManager::UpdateListener(CStateManager& mgr)
float CCameraManager::CalculateFogDensity(CStateManager& mgr, const CScriptWater* water)
{
float f31 = water->GetFluidPlane().GetAlpha();
float f1 = 0;
float distanceFactor = 1.f - water->GetFluidPlane().GetAlpha();
float distance = 0;
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit))
f1 = (g_tweakPlayer->GetPlayerTranslationFriction(4) * g_tweakPlayer->GetPlayerTranslationFriction(3)) + f31;
distance = g_tweakGame->x5c_gravityWaterFogDistanceRange * distanceFactor + g_tweakGame->x58_gravityWaterFogDistanceBase;
else
f1 = (g_tweakPlayer->GetPlayerTranslationFriction(6) * g_tweakPlayer->GetPlayerTranslationFriction(5)) + f31;
distance = g_tweakGame->x54_waterFogDistanceRange * distanceFactor + g_tweakGame->x50_waterFogDistanceBase;
return f1 * x94_;
return distance * x94_fogDensityFactor;
}
void CCameraManager::ResetCameras(CStateManager& mgr)
@ -364,9 +720,33 @@ void CCameraManager::AddActiveCameraHint(TUniqueId id, CStateManager& mgr)
{
auto search = std::find_if(x334_activeCameraHints.begin(), x334_activeCameraHints.end(),
[id](TUniqueId tid) { return tid == id; });
if (search == x334_activeCameraHints.end() && xac_ != 64 &&
if (search == x334_activeCameraHints.end() && xac_cameraHints.size() != 64 &&
x334_activeCameraHints.size() != 64)
x334_activeCameraHints.push_back(id);
}
}
TUniqueId CCameraManager::GetLastCineCameraId() const
{
if (x4_cineCameras.empty())
return kInvalidUniqueId;
return x4_cineCameras.back();
}
const CCinematicCamera* CCameraManager::GetLastCineCamera(CStateManager& mgr) const
{
return static_cast<const CCinematicCamera*>(mgr.GetObjectById(GetLastCineCameraId()));
}
const CScriptCameraHint* CCameraManager::GetCameraHint(CStateManager& mgr) const
{
return TCastToConstPtr<CScriptCameraHint>(mgr.GetObjectById(xa6_camHintId)).GetPtr();
}
bool CCameraManager::HasCameraHint(CStateManager& mgr) const
{
if (xac_cameraHints.empty() || xa6_camHintId == kInvalidUniqueId)
return false;
return mgr.GetObjectById(xa6_camHintId) != nullptr;
}
}

View File

@ -15,6 +15,8 @@ class CCameraShakeData;
class CScriptWater;
class CInterpolationCamera;
class CFinalInput;
class CScriptCameraHint;
class CCinematicCamera;
class CCameraManager
{
@ -35,28 +37,27 @@ class CCameraManager
CBallCamera* x80_ballCamera = nullptr;
s16 x84_rumbleId = -1;
CInterpolationCamera* x88_interpCamera = nullptr;
float x90_ = 0.f;
float x94_ = 1.f;
float x98_ = 0.f;
float x9c_ = 1.f;
float x90_rumbleCooldown = 0.f;
float x94_fogDensityFactor = 1.f;
float x98_fogDensitySpeed = 0.f;
float x9c_fogDensityFactorTarget = 1.f;
union
{
struct
{
bool xa0_24_ : 1;
bool xa0_24_pendingRumble : 1;
bool xa0_25_rumbling : 1;
bool xa0_26_inWater : 1;
};
u8 _dummy1 = 0;
};
TUniqueId xa2_ = kInvalidUniqueId;
TUniqueId xa4_ = kInvalidUniqueId;
TUniqueId xa6_ = kInvalidUniqueId;
u32 xa8_ = 1000;
u32 xac_ = 0;
TUniqueId xa2_spindleCamId = kInvalidUniqueId;
TUniqueId xa4_pathCamId = kInvalidUniqueId;
TUniqueId xa6_camHintId = kInvalidUniqueId;
s32 xa8_hintPriority = 1000;
rstl::reserved_vector<std::pair<s32, TUniqueId>, 64> xac_cameraHints;
rstl::reserved_vector<TUniqueId, 64> x2b0_inactiveCameraHints;
rstl::reserved_vector<TUniqueId, 64> x334_activeCameraHints;
@ -71,6 +72,16 @@ class CCameraManager
};
float x3bc_curFov = 60.f;
void SetPathCamera(TUniqueId id, CStateManager& mgr);
void SetSpindleCamera(TUniqueId id, CStateManager& mgr);
void RestoreHintlessCamera(CStateManager& mgr);
void InterpolateToBallCamera(const zeus::CTransform& xf, TUniqueId camId, const zeus::CVector3f& lookDir,
float f1, float f2, float f3, bool b1, CStateManager& mgr);
static constexpr bool ShouldBypassInterpolation() { return false; }
void SkipBallCameraCinematic(CStateManager& mgr);
void ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr);
public:
CCameraManager(TUniqueId curCameraId=kInvalidUniqueId);
@ -117,11 +128,11 @@ public:
float sub80009148() const;
void UpdateCameraHints(float, CStateManager&);
void ThinkCameras(float, CStateManager&);
void UpdateFog(float, CStateManager&);
void UpdateRumble(float, CStateManager&);
void UpdateListener(CStateManager&);
void UpdateCameraHints(float dt, CStateManager& mgr);
void ThinkCameras(float dt, CStateManager& mgr);
void UpdateFog(float dt, CStateManager& mgr);
void UpdateRumble(float dt, CStateManager& mgr);
void UpdateListener(CStateManager& mgr);
float CalculateFogDensity(CStateManager&, const CScriptWater*);
@ -138,6 +149,13 @@ public:
void AddInactiveCameraHint(TUniqueId id, CStateManager& mgr);
void AddActiveCameraHint(TUniqueId id, CStateManager& mgr);
TUniqueId GetLastCineCameraId() const;
TUniqueId GetSpindleCameraId() const { return xa2_spindleCamId; }
TUniqueId GetPathCameraId() const { return xa4_pathCamId; }
const CCinematicCamera* GetLastCineCamera(CStateManager& mgr) const;
const CScriptCameraHint* GetCameraHint(CStateManager& mgr) const;
bool HasCameraHint(CStateManager& mgr) const;
};
}

View File

@ -79,6 +79,16 @@ CCameraShakeData CCameraShakeData::BuildPhazonCameraShakeData(float duration, fl
SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 0.5f))};
}
void CCameraShakeData::Update(float dt, CStateManager& mgr)
{
}
zeus::CVector3f CCameraShakeData::GetPoint() const
{
return {x8_shaker1.x38_value, x44_shaker2.x38_value, x80_shaker3.x38_value};
}
float CCameraShakeData::GetSomething() const
{
float ret = 0.f;

View File

@ -7,6 +7,7 @@
namespace urde
{
class CRandom16;
class CStateManager;
struct SCameraShakePoint
{
@ -29,7 +30,7 @@ class CCameraShakerComponent
friend class CCameraShakeData;
u32 x4_w1 = 0;
SCameraShakePoint x8_sp1, x20_sp2;
float x38_ = 0.f;
float x38_value = 0.f;
public:
CCameraShakerComponent() = default;
CCameraShakerComponent(u32 w1, const SCameraShakePoint& sp1, const SCameraShakePoint& sp2)
@ -41,7 +42,7 @@ class CCameraShakeData
{
friend class CCameraManager;
float x0_duration;
float x4_ = 0.f;
float x4_curTime = 0.f;
CCameraShakerComponent x8_shaker1;
CCameraShakerComponent x44_shaker2;
CCameraShakerComponent x80_shaker3;
@ -62,6 +63,8 @@ public:
const zeus::CVector3f& sfxPos);
static CCameraShakeData BuildPhazonCameraShakeData(float duration, float magnitude);
//zeus::CVector3f GeneratePoint(float dt, CRandom16& r);
void Update(float dt, CStateManager& mgr);
zeus::CVector3f GetPoint() const;
float GetSomething() const;
float GetSomething2() const;
void SetShakerId(u32 id) { xbc_shakerId = id; }

View File

@ -44,4 +44,10 @@ void CInterpolationCamera::Think(float, CStateManager& mgr)
}
void CInterpolationCamera::SetInterpolation(const zeus::CTransform& xf, const zeus::CVector3f& lookDir,
float f1, float f2, float f3, TUniqueId camId, bool b1, CStateManager& mgr)
{
}
}

View File

@ -16,6 +16,8 @@ public:
void Render(const CStateManager&) const;
void Reset(const zeus::CTransform&, CStateManager& mgr);
void Think(float, CStateManager &);
void SetInterpolation(const zeus::CTransform& xf, const zeus::CVector3f& lookDir,
float f1, float f2, float f3, TUniqueId camId, bool b1, CStateManager& mgr);
};
}

View File

@ -7,6 +7,7 @@ namespace urde
{
enum class ERumbleFxId
{
Six = 6,
Seven = 7,
Eleven = 11,
Twelve = 12,

View File

@ -675,6 +675,7 @@ public:
float GetDistanceUnderWater() const { return x828_distanceUnderWater; }
TUniqueId GetRidingPlatformId() const { return x82e_ridingPlatform; }
const zeus::CVector3f& GetLastVelocity() const { return x794_lastVelocity; }
const zeus::CVector3f& GetMoveDir() const { return x50c_moveDir; }
};
}

View File

@ -7,14 +7,14 @@ namespace urde
{
CScriptCameraHint::CScriptCameraHint(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, s32 w1,
CBallCamera::EBallCameraBehaviour behaviour, s32 r4, float f1,
const zeus::CTransform& xf, bool active, s32 priority,
CBallCamera::EBallCameraBehaviour behaviour, s32 overrideFlags, float f1,
float f2, float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7,
const zeus::CVector3f& r8, float f4, float f5, float f6, float f7,
float f8, float f9, float f10, float f11, float f12, float f13)
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Unknown),
CActorParameters::None(), kInvalidUniqueId), xe8_w1(w1),
xec_hint(r4, behaviour, f1, f2, f3, r6, r7, r8, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13),
CActorParameters::None(), kInvalidUniqueId), xe8_priority(priority),
xec_hint(overrideFlags, behaviour, f1, f2, f3, r6, r7, r8, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13),
x168_origXf(xf)
{
}

View File

@ -9,7 +9,7 @@ namespace urde
class CCameraHint
{
s32 x4_r4;
s32 x4_overrideFlags;
CBallCamera::EBallCameraBehaviour x8_behaviour;
float xc_f1;
float x10_f2;
@ -29,17 +29,24 @@ class CCameraHint
float x60_f13;
public:
CCameraHint(s32 r4, CBallCamera::EBallCameraBehaviour behaviour, float f1, float f2, float f3,
CCameraHint(s32 overrideFlags, CBallCamera::EBallCameraBehaviour behaviour, float f1, float f2, float f3,
const zeus::CVector3f& r6, const zeus::CVector3f& r7, const zeus::CVector3f& r8, float f4,
float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13)
: x4_r4(r4), x8_behaviour(behaviour), xc_f1(f1), x10_f2(f2), x14_f3(f3), x18_r6(r6), x24_r7(r7),
x30_r8(r8), x3c_f4(f4), x40_f5(f5), x44_f6(f6), x48_f7(f7), x4c_f8(f8), x50_f9(f9), x54_f10(f10),
: x4_overrideFlags(overrideFlags), x8_behaviour(behaviour), xc_f1(f1), x10_f2(f2), x14_f3(f3), x18_r6(r6),
x24_r7(r7), x30_r8(r8), x3c_f4(f4), x40_f5(f5), x44_f6(f6), x48_f7(f7), x4c_f8(f8), x50_f9(f9), x54_f10(f10),
x58_f11(f11), x5c_f12(f12), x60_f13(f13) {}
s32 GetOverrideFlags() const { return x4_overrideFlags; }
CBallCamera::EBallCameraBehaviour GetBehaviourType() const { return x8_behaviour; }
float GetX4C() const { return x4c_f8; }
float GetX50() const { return x50_f9; }
float GetX58() const { return x58_f11; }
float GetX5C() const { return x5c_f12; }
};
class CScriptCameraHint : public CActor
{
s32 xe8_w1;
s32 xe8_priority;
CCameraHint xec_hint;
rstl::reserved_vector<TUniqueId, 8> x150_helpers;
TUniqueId x164_delegatedCamera = kInvalidUniqueId;
@ -50,17 +57,22 @@ class CScriptCameraHint : public CActor
void RemoveHelper(TUniqueId id);
public:
CScriptCameraHint(TUniqueId, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf,
bool active, s32 w1, CBallCamera::EBallCameraBehaviour behaviour, s32 r4, float f1, float f2,
float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7, const zeus::CVector3f& r8,
float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12,
float f13);
bool active, s32 priority, CBallCamera::EBallCameraBehaviour behaviour, s32 overrideFlags,
float f1, float f2, float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7,
const zeus::CVector3f& r8, float f4, float f5, float f6, float f7, float f8, float f9, float f10,
float f11, float f12, float f13);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr);
void ClearIdList() { x150_helpers.clear(); }
void SetInactive(bool inactive) { x166_inactive = inactive; }
bool GetInactive() const { return x166_inactive; }
size_t GetHelperCount() const { return x150_helpers.size(); }
TUniqueId GetFirstHelper() const { return x150_helpers.empty() ? kInvalidUniqueId : x150_helpers[0]; }
s32 GetPriority() const { return xe8_priority; }
const CCameraHint& GetHint() const { return xec_hint; }
TUniqueId GetDelegatedCamera() const { return x164_delegatedCamera; }
};
}

View File

@ -0,0 +1,49 @@
#include "CScriptSpindleCamera.hpp"
#include "Camera/CCameraManager.hpp"
#include "ScriptLoader.hpp"
#include "TCastTo.hpp"
namespace urde
{
SSpindleSegment::SSpindleSegment(CInputStream& in)
: x0_(in.readUint32Big()), x4_paramFlags(ScriptLoader::LoadParameterFlags(in)),
x8_(in.readFloatBig()), xc_(in.readFloatBig()), x10_(in.readFloatBig()), x14_(in.readFloatBig())
{}
CScriptSpindleCamera::CScriptSpindleCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, u32 r9,
float f1, float f2, float f3, float f4, const SSpindleSegment& seg1,
const SSpindleSegment& seg2, const SSpindleSegment& seg3,
const SSpindleSegment& seg4, const SSpindleSegment& seg5,
const SSpindleSegment& seg6, const SSpindleSegment& seg7,
const SSpindleSegment& seg8, const SSpindleSegment& seg9,
const SSpindleSegment& seg10, const SSpindleSegment& seg11,
const SSpindleSegment& seg12, const SSpindleSegment& seg13,
const SSpindleSegment& seg14, const SSpindleSegment& seg15)
: CGameCamera(uid, active, name, info, xf, CCameraManager::ThirdPersonFOV(), CCameraManager::NearPlane(),
CCameraManager::FarPlane(), CCameraManager::Aspect(), kInvalidUniqueId, false, 0),
x188_r9(r9), x1b0_f1(f1), x1b4_f2(f2), x1b8_f3(f2), x1bc_f4(f4), x1c0_seg1(seg1), x1d8_seg2(seg2),
x1f0_seg3(seg3), x208_seg4(seg4), x220_seg5(seg5), x238_seg6(seg6), x250_seg7(seg7),
x268_seg8(seg8), x280_seg9(seg9), x298_seg10(seg10), x2b0_seg11(seg11), x2c8_seg12(seg12),
x2e0_seg13(seg13), x2f8_seg14(seg14), x310_seg15(seg15), x330_lookDir(xf.basis[1])
{
}
void CScriptSpindleCamera::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptSpindleCamera::ProcessInput(const CFinalInput& input, CStateManager& mgr)
{
}
void CScriptSpindleCamera::Reset(const zeus::CTransform& xf, CStateManager& mgr)
{
}
}

View File

@ -0,0 +1,71 @@
#ifndef __URDE_CSCRIPTSPINDLECAMERA_HPP__
#define __URDE_CSCRIPTSPINDLECAMERA_HPP__
#include "Camera/CGameCamera.hpp"
namespace urde
{
struct SSpindleSegment
{
u32 x0_;
u32 x4_paramFlags;
float x8_;
float xc_;
float x10_;
float x14_;
SSpindleSegment(CInputStream& in);
void FixupAngles()
{
x8_ = zeus::degToRad(x8_);
xc_ = zeus::degToRad(xc_);
}
};
class CScriptSpindleCamera : public CGameCamera
{
u32 x188_r9;
u32 x18c_ = 0;
float x1b0_f1;
float x1b4_f2;
float x1b8_f3;
float x1bc_f4;
SSpindleSegment x1c0_seg1;
SSpindleSegment x1d8_seg2;
SSpindleSegment x1f0_seg3;
SSpindleSegment x208_seg4;
SSpindleSegment x220_seg5;
SSpindleSegment x238_seg6;
SSpindleSegment x250_seg7;
SSpindleSegment x268_seg8;
SSpindleSegment x280_seg9;
SSpindleSegment x298_seg10;
SSpindleSegment x2b0_seg11;
SSpindleSegment x2c8_seg12;
SSpindleSegment x2e0_seg13;
SSpindleSegment x2f8_seg14;
SSpindleSegment x310_seg15;
float x328_ = 0.f;
bool x32c_24 = false;
zeus::CVector3f x330_lookDir;
public:
CScriptSpindleCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, u32 r9,
float f1, float f2, float f3, float f4, const SSpindleSegment& seg1,
const SSpindleSegment& seg2, const SSpindleSegment& seg3,
const SSpindleSegment& seg4, const SSpindleSegment& seg5,
const SSpindleSegment& seg6, const SSpindleSegment& seg7,
const SSpindleSegment& seg8, const SSpindleSegment& seg9,
const SSpindleSegment& seg10, const SSpindleSegment& seg11,
const SSpindleSegment& seg12, const SSpindleSegment& seg13,
const SSpindleSegment& seg14, const SSpindleSegment& seg15);
void Accept(IVisitor& visitor);
void ProcessInput(const CFinalInput& input, CStateManager& mgr);
void Reset(const zeus::CTransform& xf, CStateManager& mgr);
};
}
#endif // __URDE_CSCRIPTSPINDLECAMERA_HPP__

View File

@ -44,7 +44,7 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string&
x24c_unmorphVisorRunoffParticleId(unmorphVisorRunoffparticle),
x260_visorRunoffSfx(CSfxManager::TranslateSFXID(visorRunoffSfx)),
x262_unmorphVisorRunoffSfx(CSfxManager::TranslateSFXID(unmorphVisorRunoffSfx)),
x2a4_splashColor(splashColor), x2a8_unkColor(unkColor), x2ac_alphaInTime(alphaInTime), x2b0_alphaOutTime(alphaOutTime),
x2a4_splashColor(splashColor), x2a8_fogColor(unkColor), x2ac_alphaInTime(alphaInTime), x2b0_alphaOutTime(alphaOutTime),
x2b4_alphaInRecip((alphaInTime != 0.f) ? 1.f / alphaInTime : 0.f),
x2b8_alphaOutRecip((alphaOutTime != 0.f) ? 1.f / alphaOutTime : 0.f), x2bc_alpha(alpha), x2c0_tileSize(tileSize)
{

View File

@ -43,7 +43,7 @@ private:
rstl::reserved_vector<std::experimental::optional<TLockedToken<CGenDescription>>, 3> x264_splashEffects;
rstl::reserved_vector<u16, 3> x298_splashSounds;
zeus::CColor x2a4_splashColor;
zeus::CColor x2a8_unkColor;
zeus::CColor x2a8_fogColor;
float x2ac_alphaInTime;
float x2b0_alphaOutTime;
float x2b4_alphaInRecip;
@ -131,6 +131,7 @@ public:
int GetPatchDimensionX() const { return x2d0_patchDimX; }
int GetPatchDimensionY() const { return x2d4_patchDimY; }
bool CanRippleAtPoint(const zeus::CVector3f& point) const;
const zeus::CColor& GetFogColor() const { return x2a8_fogColor; }
};
}

View File

@ -4,10 +4,8 @@
#include "CDamageInfo.hpp"
#include "CFluidUVMotion.hpp"
#include "CGrappleParameters.hpp"
#include "CLightParameters.hpp"
#include "CPatternedInfo.hpp"
#include "CRepulsor.hpp"
#include "CScannableParameters.hpp"
#include "CScriptActor.hpp"
#include "CScriptActorKeyframe.hpp"
#include "CScriptActorRotate.hpp"
@ -56,15 +54,14 @@
#include "CScriptStreamedMusic.hpp"
#include "CScriptSwitch.hpp"
#include "CScriptTimer.hpp"
#include "CScriptTrigger.hpp"
#include "CScriptVisorFlare.hpp"
#include "CScriptWater.hpp"
#include "CScriptWaypoint.hpp"
#include "CScriptWorldTeleporter.hpp"
#include "CScriptSpiderBallAttractionSurface.hpp"
#include "CScriptSpindleCamera.hpp"
#include "CSimplePool.hpp"
#include "CStateManager.hpp"
#include "CVisorParameters.hpp"
#include "CWallCrawlerSwarm.hpp"
#include "CWorld.hpp"
#include "Camera/CCinematicCamera.hpp"
@ -2311,9 +2308,49 @@ CEntity* ScriptLoader::LoadGeemer(CStateManager& mgr, CInputStream& in, int prop
return nullptr;
}
CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{
if (!EnsurePropertyCount(propCount, 24, "SpindleCamera"))
return nullptr;
SActorHead aHead = LoadActorHead(in, mgr);
bool active = in.readBool();
u32 flags = LoadParameterFlags(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
float f4 = in.readFloatBig();
SSpindleSegment seg1(in);
seg1.FixupAngles();
SSpindleSegment seg2(in);
SSpindleSegment seg3(in);
SSpindleSegment seg4(in);
SSpindleSegment seg5(in);
seg5.FixupAngles();
SSpindleSegment seg6(in);
seg6.FixupAngles();
SSpindleSegment seg7(in);
seg7.FixupAngles();
SSpindleSegment seg8(in);
seg8.FixupAngles();
SSpindleSegment seg9(in);
SSpindleSegment seg10(in);
SSpindleSegment seg11(in);
seg11.FixupAngles();
SSpindleSegment seg12(in);
seg12.FixupAngles();
SSpindleSegment seg13(in);
seg13.FixupAngles();
SSpindleSegment seg14(in);
SSpindleSegment seg15(in);
seg15.FixupAngles();
return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform,
active, flags, f1, f2, f3, f4, seg1, seg2, seg3, seg4, seg5, seg6,
seg7, seg8, seg9, seg10, seg11, seg12, seg13, seg14, seg15);
}
CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)