2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 11:07:44 +00:00

Work on CPathCamera

This commit is contained in:
Jack Andersen
2018-06-25 19:24:31 -10:00
parent 21b25f72a3
commit 68504f5c3a
6 changed files with 339 additions and 16 deletions

View File

@@ -4,6 +4,7 @@
#include "CBallCamera.hpp"
#include "World/CScriptCameraHint.hpp"
#include "World/CPlayer.hpp"
#include "World/CScriptDoor.hpp"
#include "GameGlobalObjects.hpp"
#include "TCastTo.hpp"
@@ -18,7 +19,7 @@ CPathCamera::CPathCamera(TUniqueId uid, std::string_view name, const CEntityInfo
CCameraManager::NearPlane(),
CCameraManager::FarPlane(),
CCameraManager::Aspect(), kInvalidUniqueId, 0, 0)
, x188_spline(flags & 1), x1dc_(f1), x1e0_(f2), x1e4_(f3), x1e8_initPos(initPos)
, x188_spline(flags & 1), x1dc_lengthExtent(f1), x1e0_(f2), x1e4_(f3), x1e8_initPos(initPos)
, x1ec_flags(flags), x1f0_(f4), x1f4_(f5)
{
}
@@ -68,7 +69,7 @@ void CPathCamera::Think(float dt, CStateManager& mgr)
SetTranslation(xf.origin);
if (x1ec_flags & 0x20)
sub8012DD3C(mgr);
ClampToClosedDoor(mgr);
zeus::CVector3f tmp = ballLook - GetTranslation();
tmp.z = 0.f;
@@ -81,28 +82,171 @@ void CPathCamera::Think(float dt, CStateManager& mgr)
void CPathCamera::ProcessInput(const CFinalInput&, CStateManager& mgr)
{
// Empty
}
static const CMaterialFilter kLineOfSightFilter =
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough});
void CPathCamera::Reset(const zeus::CTransform&, CStateManager& mgr)
{
CPlayer& player = mgr.GetPlayer();
float f23 = x188_spline.FindClosestLengthAlongSpline(0.f, player.GetTranslation() + g_tweakPlayer->GetPlayerBallHalfExtent());
zeus::CVector3f playerPt = player.GetTranslation() +
zeus::CVector3f(0.f, 0.f, g_tweakPlayer->GetPlayerBallHalfExtent());
float closestLength = x188_spline.FindClosestLengthOnSpline(0.f, playerPt);
float f25 = std::max(0.f, f23 - x1dc_);
float negLength = std::max(0.f, closestLength - x1dc_lengthExtent);
zeus::CVector3f negPoint = x188_spline.GetInterpolatedSplinePointByLength(negLength).origin;
zeus::CTransform xf = x188_spline.GetInterpolatedSplinePointByLength(f25);
float posLength = std::min(x188_spline.GetLength(), closestLength + x1dc_lengthExtent);
zeus::CVector3f posPoint = x188_spline.GetInterpolatedSplinePointByLength(posLength).origin;
float f1 = x188_spline.GetLength();
zeus::CTransform camXf = mgr.GetCameraManager()->GetBallCamera()->GetTransform();
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr);
bool neg = false;
if (x1e8_initPos == EInitialSplinePosition::BallCamBasis)
{
zeus::CVector3f tmp = playerPt - negPoint;
if (tmp.canBeNormalized())
{
if (tmp.normalized().dot(camXf.basis[1]) > 0.f)
neg = true;
}
}
else
{
neg = x1e8_initPos == EInitialSplinePosition::Negative;
}
#if 0
zeus::CVector3f camToSpline = splinePt - camXf.origin;
mgr.RayStaticIntersection(camXf.origin, camToSpline.normalized(), camToSpline.magnitude(), kLineOfSightFilter);
zeus::CVector3f camToSpline2 = splinePt2 - camXf.origin;
mgr.RayStaticIntersection(camXf.origin, camToSpline2.normalized(), camToSpline2.magnitude(), kLineOfSightFilter);
#endif
zeus::CVector3f viewPoint;
if (neg)
{
x1d4_pos = negLength;
viewPoint = negPoint;
}
else
{
x1d4_pos = posLength;
viewPoint = posPoint;
}
if (x1e8_initPos == EInitialSplinePosition::ClampBasis)
{
if (x188_spline.ClampLength(playerPt, false, kLineOfSightFilter, mgr) <= negLength)
{
x1d4_pos = negLength;
viewPoint = negPoint;
}
else
{
x1d4_pos = posLength;
viewPoint = posPoint;
}
}
SetTransform(zeus::lookAt(viewPoint, mgr.GetCameraManager()->GetBallCamera()->GetFixedLookPos()));
}
zeus::CTransform CPathCamera::MoveAlongSpline(float, CStateManager& mgr)
zeus::CTransform CPathCamera::MoveAlongSpline(float t, CStateManager& mgr)
{
return {};
zeus::CTransform ret = x34_transform;
x1d8_time = x188_spline.FindClosestLengthOnSpline(x1d8_time, mgr.GetPlayer().GetTranslation());
float f30 = x1dc_lengthExtent;
if (x1ec_flags & 0x8)
{
zeus::CVector3f splineToPlayer = mgr.GetPlayer().GetTranslation() -
x188_spline.GetInterpolatedSplinePointByLength(x1d8_time).origin;
float distToPlayer = 0.f;
if (splineToPlayer.canBeNormalized())
distToPlayer = splineToPlayer.magnitude();
f30 *= 1.f - std::sin(zeus::degToRad(zeus::clamp(0.f, (distToPlayer - x1f0_) / (x1f4_ - x1f0_), 1.f) * 90.f));
}
float newPos;
if (x188_spline.IsClosedLoop())
{
float lenA = x188_spline.ValidateLength(x1d8_time + f30);
newPos = x188_spline.ValidateLength(x1d8_time - f30);
float disp = std::fabs(x1d4_pos - x1d8_time);
float remLen = x188_spline.GetLength() - disp;
if (x1d4_pos > x1d8_time)
{
if (disp <= remLen)
newPos = lenA;
}
else
{
if (disp > remLen)
newPos = lenA;
}
}
else
{
if (x1d4_pos > x1d8_time)
newPos = x188_spline.ValidateLength(x1d8_time + f30);
else
newPos = x188_spline.ValidateLength(x1d8_time - f30);
}
if (x1ec_flags & 0x2)
{
x1d4_pos = newPos;
ret = x188_spline.GetInterpolatedSplinePointByLength(x1d4_pos);
}
else
{
if (x188_spline.IsClosedLoop())
{
float absDelta = std::fabs(newPos - x1d4_pos);
if (absDelta > x188_spline.GetLength() - absDelta)
absDelta = x188_spline.GetLength() - absDelta;
float tBias = zeus::clamp(-1.f, absDelta / x1e4_, 1.f) * x1e0_ * t;
float tmpAbs = std::fabs(x1d4_pos - newPos);
float absDelta2 = x188_spline.GetLength() - tmpAbs;
if (x1d4_pos > newPos)
{
if (tmpAbs <= absDelta2)
tBias *= -1.f;
}
else
{
if (tmpAbs > absDelta2)
tBias *= -1.f;
}
x1d4_pos = x188_spline.ValidateLength(x1d4_pos + tBias);
}
else
{
x1d4_pos = x188_spline.ValidateLength(
zeus::clamp(-1.f, (newPos - x1d4_pos) / x1e4_, 1.f) * x1e0_ * t + x1d4_pos);
}
ret = x188_spline.GetInterpolatedSplinePointByLength(x1d4_pos);
}
return ret;
}
void CPathCamera::sub8012DD3C(CStateManager& )
void CPathCamera::ClampToClosedDoor(CStateManager& mgr)
{
if (TCastToConstPtr<CScriptDoor> door =
mgr.GetObjectById(mgr.GetCameraManager()->GetBallCamera()->GetTooCloseActorId()))
{
if (!door->IsOpen() && CBallCamera::IsBallNearDoor(GetTranslation(), mgr))
{
x1d4_pos = (x1d4_pos > x1d8_time) ?
x1d8_time - x1dc_lengthExtent : x1d8_time + x1dc_lengthExtent;
SetTranslation(x188_spline.GetInterpolatedSplinePointByLength(x1d4_pos).origin);
}
}
}
}