mirror of https://github.com/AxioDL/metaforce.git
Work on CBallCamera
This commit is contained in:
parent
16f6307642
commit
96c17ba729
|
@ -536,7 +536,7 @@ void CBallCamera::UpdateTransform(const zeus::CVector3f& lookDir, const zeus::CV
|
|||
SetTranslation(pos);
|
||||
}
|
||||
|
||||
zeus::CVector3f CBallCamera::ConstrainYawAngle(const CPlayer& player, float angleVel, float maxAngle, float dt,
|
||||
zeus::CVector3f CBallCamera::ConstrainYawAngle(const CPlayer& player, float distance, float yawSpeed, float dt,
|
||||
CStateManager& mgr) const
|
||||
{
|
||||
zeus::CVector3f playerToCamFlat = GetTranslation() - player.GetTranslation();
|
||||
|
@ -563,8 +563,8 @@ zeus::CVector3f CBallCamera::ConstrainYawAngle(const CPlayer& player, float angl
|
|||
float angleProj = zeus::clamp(-1.f, playerToCamFlat.dot(-lookDir), 1.f);
|
||||
if (angleProj >= 1.f)
|
||||
return -lookDir;
|
||||
return zeus::CQuaternion::lookAt(playerToCamFlat, -lookDir, angleVel * dt *
|
||||
zeus::clamp(0.f, std::acos(angleProj) / maxAngle, 1.f)).transform(playerToCamFlat);
|
||||
return zeus::CQuaternion::lookAt(playerToCamFlat, -lookDir, distance * dt *
|
||||
zeus::clamp(0.f, std::acos(angleProj) / yawSpeed, 1.f)).transform(playerToCamFlat);
|
||||
}
|
||||
|
||||
void CBallCamera::CheckFailsafe(float dt, CStateManager& mgr)
|
||||
|
@ -933,44 +933,230 @@ void CBallCamera::UpdateUsingFreeLook(float dt, CStateManager& mgr)
|
|||
x36c_ = 0;
|
||||
}
|
||||
|
||||
zeus::CVector3f CBallCamera::InterpolateCameraElevation(const zeus::CVector3f& camPos) const
|
||||
zeus::CVector3f CBallCamera::InterpolateCameraElevation(const zeus::CVector3f& camPos)
|
||||
{
|
||||
return {};
|
||||
if (x1a0_elevation < 2.f)
|
||||
return camPos;
|
||||
|
||||
zeus::CVector3f ret = camPos;
|
||||
if (!x18c_31_ && x350_.HasMaterial(EMaterialTypes::Floor))
|
||||
{
|
||||
x3d4_ = 1.f;
|
||||
ret.z = x3d8_ = GetTranslation().z;
|
||||
}
|
||||
else if (x3d4_ > 0.f)
|
||||
{
|
||||
ret.z = (camPos.z - x3d8_) * (1.f - zeus::clamp(0.f, x3d4_, 1.f)) + x3d8_;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
zeus::CVector3f CBallCamera::CalculateCollidersCentroid(const std::vector<CCameraCollider>& colliderList, int w1) const
|
||||
{
|
||||
return {};
|
||||
if (colliderList.size() < 3)
|
||||
return zeus::CVector3f::skForward;
|
||||
|
||||
int r10 = 0;
|
||||
const CCameraCollider* prevCol = &colliderList.back();
|
||||
float f6 = 0.f;
|
||||
float f7 = 0.f;
|
||||
float f8 = 0.f;
|
||||
for (const CCameraCollider& col : colliderList)
|
||||
{
|
||||
if (prevCol->x4c_occlusionCount < 2 && col.x4c_occlusionCount < 2)
|
||||
{
|
||||
float f3 = prevCol->x50_scale * prevCol->x8_.z;
|
||||
float f1 = prevCol->x50_scale * col.x8_.x;
|
||||
float f4 = prevCol->x50_scale * prevCol->x8_.x;
|
||||
float f5 = prevCol->x50_scale * col.x8_.z;
|
||||
|
||||
float f2 = f4 * f5 - f1 * f3;
|
||||
f6 += f2;
|
||||
f7 += f2 * (f1 + f4);
|
||||
f8 += f2 * (f5 + f3);
|
||||
}
|
||||
else
|
||||
{
|
||||
r10 += 1;
|
||||
}
|
||||
prevCol = &col;
|
||||
}
|
||||
|
||||
if (r10 / float(colliderList.size()) <= x330_)
|
||||
{
|
||||
return zeus::CVector3f::skForward;
|
||||
}
|
||||
else if (0.f != f6)
|
||||
{
|
||||
float f2 = 3.f * f6;
|
||||
return {f7 / f2, 0.f, f8 / f2};
|
||||
}
|
||||
|
||||
return {0.f, 2.f, 0.f};
|
||||
}
|
||||
|
||||
zeus::CVector3f CBallCamera::ApplyColliders()
|
||||
{
|
||||
return {};
|
||||
zeus::CVector3f smallCentroid = CalculateCollidersCentroid(x264_smallColliders, x2c4_);
|
||||
zeus::CVector3f mediumCentroid = CalculateCollidersCentroid(x274_mediumColliders, x2c8_);
|
||||
zeus::CVector3f largeCentroid = CalculateCollidersCentroid(x284_largeColliders, x2cc_);
|
||||
|
||||
if (smallCentroid.y == 0.f)
|
||||
x2a0_ = smallCentroid;
|
||||
else
|
||||
x2a0_ = zeus::CVector3f::skZero;
|
||||
|
||||
float centroidX = x2a0_.x;
|
||||
float centroidZ = x2a0_.z;
|
||||
|
||||
if (mediumCentroid.y == 0.f)
|
||||
x2ac_ = mediumCentroid;
|
||||
else
|
||||
x2ac_ = zeus::CVector3f::skZero;
|
||||
|
||||
centroidX += x2ac_.x;
|
||||
centroidZ += x2ac_.z;
|
||||
|
||||
if (largeCentroid.y == 0.f)
|
||||
x2b8_ = largeCentroid;
|
||||
else
|
||||
x2b8_ = zeus::CVector3f::skZero;
|
||||
|
||||
centroidX += x2b8_.x;
|
||||
centroidZ += x2b8_.z;
|
||||
|
||||
if (x18c_31_)
|
||||
centroidX /= 1.5f;
|
||||
centroidZ /= 3.f;
|
||||
|
||||
if (!x18c_31_ && x368_ == kInvalidUniqueId)
|
||||
{
|
||||
float f26 = 1.5f;
|
||||
float f27 = 1.f;
|
||||
if (x350_.HasMaterial(EMaterialTypes::Floor))
|
||||
f27 += 2.f * x358_;
|
||||
if (x350_.HasMaterial(EMaterialTypes::Wall))
|
||||
f26 += 3.f * zeus::clamp(0.f, x358_ - 0.25f, 1.f);
|
||||
centroidX *= f26;
|
||||
centroidZ *= f27;
|
||||
}
|
||||
|
||||
if (!x18c_28_)
|
||||
return zeus::CVector3f::skZero;
|
||||
|
||||
if (std::fabs(centroidX) < 0.05f)
|
||||
centroidX = 0.f;
|
||||
if (std::fabs(centroidZ) < 0.05f)
|
||||
centroidZ = 0.f;
|
||||
|
||||
if (x18c_31_)
|
||||
centroidZ *= 0.5f;
|
||||
|
||||
return {centroidX, 0.f, centroidZ};
|
||||
}
|
||||
|
||||
void CBallCamera::UpdateColliders(const zeus::CTransform& xf, std::vector<CCameraCollider>& colliderList, int& r6,
|
||||
int r7, float f1, const rstl::reserved_vector<TUniqueId, 1024>& nearList, float f2,
|
||||
int r7, float f1, const rstl::reserved_vector<TUniqueId, 1024>& nearList, float dt,
|
||||
CStateManager& mgr)
|
||||
{
|
||||
|
||||
if (r6 < colliderList.size())
|
||||
{
|
||||
x310_ = {0.f, g_tweakBall->GetBallCameraOffset().y, g_tweakPlayer->GetPlayerBallHalfExtent()};
|
||||
x310_.y *= x308_;
|
||||
x31c_ = mgr.GetPlayer().GetMoveDir() * x310_.y;
|
||||
x31c_.z = x310_.z;
|
||||
x31c_ += mgr.GetPlayer().GetTranslation();
|
||||
zeus::CTransform xd0 = zeus::lookAt(xf.origin, x31c_);
|
||||
float f26 = 1.f / f1;
|
||||
for (int i=0 ; i<r7 ; ++i)
|
||||
{
|
||||
zeus::CVector3f x19c = colliderList[r6].x14_;
|
||||
zeus::CVector3f x1a8 = xd0.rotate(x19c) + xd0.origin;
|
||||
if ((colliderList[r6].x2c_ - x1a8).magnitude() < 0.1f)
|
||||
{
|
||||
x19c = colliderList[r6].x8_;
|
||||
x1a8 = colliderList[r6].x2c_;
|
||||
}
|
||||
zeus::CVector3f x1b4 = x1a8 - xd0.origin;
|
||||
float mag = x1b4.magnitude();
|
||||
if (x1b4.canBeNormalized())
|
||||
{
|
||||
x1b4.normalize();
|
||||
TUniqueId intersectId = kInvalidUniqueId;
|
||||
CRayCastResult result =
|
||||
mgr.RayWorldIntersection(intersectId, xd0.origin, x1b4, mag + colliderList[r6].x4_radius,
|
||||
BallCameraFilter, nearList);
|
||||
if (result.IsValid())
|
||||
{
|
||||
zeus::CVector3f x214 = x1b4 * (result.GetT() - colliderList[r6].x4_radius);
|
||||
x1a8 = x214 + xd0.origin;
|
||||
x19c = xd0.getRotation().inverse() * x214;
|
||||
}
|
||||
}
|
||||
colliderList[r6].x2c_ = x1a8;
|
||||
colliderList[r6].x8_ = x19c;
|
||||
zeus::CVector3f end = x1b4 * mag * f26;
|
||||
end = end * x308_ + x31c_;
|
||||
colliderList[r6].x20_ = end;
|
||||
if (mgr.RayCollideWorld(x1a8, end, nearList, BallCameraFilter, nullptr))
|
||||
colliderList[r6].x4c_occlusionCount = 0;
|
||||
else
|
||||
colliderList[r6].x4c_occlusionCount += 1;
|
||||
r6 += 1;
|
||||
if (r6 == colliderList.size())
|
||||
r6 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBallCamera::AvoidGeometry(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
zeus::CVector3f CBallCamera::AvoidGeometry(const zeus::CTransform& xf,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
float dt, CStateManager& mgr)
|
||||
{
|
||||
|
||||
switch (x328_)
|
||||
{
|
||||
case 0:
|
||||
UpdateColliders(xf, x264_smallColliders, x2d0_, 1, 4.f, nearList, dt, mgr);
|
||||
break;
|
||||
case 1:
|
||||
UpdateColliders(xf, x274_mediumColliders, x2d4_, 3, 4.f, nearList, dt, mgr);
|
||||
break;
|
||||
case 2:
|
||||
UpdateColliders(xf, x284_largeColliders, x2d8_, 4, 4.f, nearList, dt, mgr);
|
||||
break;
|
||||
case 3:
|
||||
UpdateColliders(xf, x284_largeColliders, x2d8_, 4, 4.f, nearList, dt, mgr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
void CBallCamera::AvoidGeometryFull(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
x328_ += 1;
|
||||
if (x328_ >= 4)
|
||||
x328_ = 0;
|
||||
|
||||
return ApplyColliders();
|
||||
}
|
||||
|
||||
zeus::CVector3f CBallCamera::AvoidGeometryFull(const zeus::CTransform& xf,
|
||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
float dt, CStateManager& mgr)
|
||||
{
|
||||
|
||||
UpdateColliders(xf, x264_smallColliders, x2d0_, x264_smallColliders.size(), 4.f, nearList, dt, mgr);
|
||||
UpdateColliders(xf, x274_mediumColliders, x2d4_, x274_mediumColliders.size(), 4.f, nearList, dt, mgr);
|
||||
UpdateColliders(xf, x284_largeColliders, x2d8_, x284_largeColliders.size(), 4.f, nearList, dt, mgr);
|
||||
return ApplyColliders();
|
||||
}
|
||||
|
||||
zeus::CAABox CBallCamera::CalculateCollidersBoundingBox(const std::vector<CCameraCollider>& colliderList,
|
||||
CStateManager& mgr) const
|
||||
{
|
||||
return {};
|
||||
zeus::CAABox aabb;
|
||||
for (const CCameraCollider& col : colliderList)
|
||||
aabb.accumulateBounds(col.x2c_);
|
||||
aabb.accumulateBounds(mgr.GetPlayer().GetTranslation());
|
||||
return aabb;
|
||||
}
|
||||
|
||||
int CBallCamera::CountObscuredColliders(const std::vector<CCameraCollider>& colliderList) const
|
||||
|
@ -984,12 +1170,285 @@ int CBallCamera::CountObscuredColliders(const std::vector<CCameraCollider>& coll
|
|||
|
||||
void CBallCamera::UpdateCollidersDistances(std::vector<CCameraCollider>& colliderList, float f1, float f2, float f3)
|
||||
{
|
||||
|
||||
float f31 = f3;
|
||||
for (CCameraCollider& col : colliderList)
|
||||
{
|
||||
float f23 = std::cos(f31) * f2;
|
||||
if (f31 > M_PIF / 2.f)
|
||||
f23 *= 0.25f;
|
||||
col.x14_ = {std::sin(f31) * f1, 0.f, f23};
|
||||
f31 += 2.f * M_PIF / float(colliderList.size());
|
||||
}
|
||||
}
|
||||
|
||||
void CBallCamera::UpdateUsingColliders(float dt, CStateManager& mgr)
|
||||
{
|
||||
if (mgr.GetPlayer().GetBombJumpCount() == 1)
|
||||
return;
|
||||
|
||||
zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition();
|
||||
|
||||
if (mgr.GetPlayer().GetBombJumpCount() == 2)
|
||||
{
|
||||
zeus::CVector3f xa60 = x1d8_ - GetTranslation();
|
||||
if (x18d_26_)
|
||||
xa60 = ballPos - GetTranslation();
|
||||
|
||||
if (xa60.canBeNormalized())
|
||||
{
|
||||
xa60.normalize();
|
||||
UpdateTransform(xa60, GetTranslation(), dt, mgr);
|
||||
}
|
||||
}
|
||||
else if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Unmorphed ||
|
||||
x18d_25_)
|
||||
{
|
||||
zeus::CTransform x8e0 = x34_transform;
|
||||
zeus::CVector3f f28 = GetTranslation();
|
||||
x2c4_ = CountObscuredColliders(x264_smallColliders);
|
||||
x2c8_ = CountObscuredColliders(x274_mediumColliders);
|
||||
x2cc_ = CountObscuredColliders(x284_largeColliders);
|
||||
zeus::CVector3f xa78 = {0.f, 0.f, GetTranslation().z - ballPos.z};
|
||||
zeus::CVector3f xa6c = GetTranslation() - ballPos;
|
||||
xa6c.z = 0.f;
|
||||
float f25 = 0.f;
|
||||
if (xa6c.canBeNormalized())
|
||||
f25 = xa6c.magnitude();
|
||||
else
|
||||
xa6c = -mgr.GetPlayer().GetMoveDir();
|
||||
xa78 = GetTranslation() - xa78;
|
||||
zeus::CTransform x910;
|
||||
if ((xa78 - ballPos).canBeNormalized())
|
||||
x910 = zeus::lookAt(ballPos, xa78);
|
||||
float distance = x214_ballCameraSpring.ApplyDistanceSpring(x190_curMinDistance, f25, (3.f + x308_) * dt);
|
||||
zeus::CVector3f xa84 = ballPos - GetTranslation();
|
||||
xa84.z = 0.f;
|
||||
if (xa84.canBeNormalized())
|
||||
{
|
||||
xa84.normalize();
|
||||
if (std::fabs(std::acos(zeus::clamp(-1.f, xa84.dot(mgr.GetPlayer().GetMoveDir()), 1.f))) >
|
||||
zeus::degToRad(150.f) && mgr.GetPlayer().GetVelocity().canBeNormalized())
|
||||
{
|
||||
distance = x214_ballCameraSpring.
|
||||
ApplyDistanceSpring(x308_ * (x19c_backwardsDistance -x190_curMinDistance) +
|
||||
x190_curMinDistance, f25, 3.f * dt);
|
||||
}
|
||||
}
|
||||
x334_ = CalculateCollidersBoundingBox(x284_largeColliders, mgr);
|
||||
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||
mgr.BuildNearList(nearList, x334_, BallCameraFilter,
|
||||
TCastToConstPtr<CActor>(mgr.GetObjectById(x46c_collisionActorId)).GetPtr());
|
||||
if (!x18c_31_ && x368_ == kInvalidUniqueId)
|
||||
{
|
||||
if (x34c_ > 0.f || x350_.HasMaterial(EMaterialTypes::Floor) || x350_.HasMaterial(EMaterialTypes::Wall))
|
||||
{
|
||||
x32c_ += 2.f * dt;
|
||||
if (x32c_ < 2.f)
|
||||
x32c_ = 2.f;
|
||||
if (x32c_ > 2.f)
|
||||
x32c_ = 2.f;
|
||||
UpdateCollidersDistances(x264_smallColliders, 2.31f * x32c_, 2.31f * x32c_ * 0.5f, -M_PIF / 2.f);
|
||||
UpdateCollidersDistances(x274_mediumColliders, 4.62f * x32c_, 4.62f * x32c_ * 0.5f, -M_PIF / 2.f);
|
||||
UpdateCollidersDistances(x284_largeColliders, 7.f * x32c_, 7.f * x32c_ * 0.5f, -M_PIF / 2.f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float f1 = 1.f;
|
||||
if (x18d_24_ && mgr.GetPlayer().GetMoveSpeed() < 1.f)
|
||||
f1 = 0.25f;
|
||||
x32c_ += (f1 - x32c_) * dt * 2.f;
|
||||
UpdateCollidersDistances(x264_smallColliders, x32c_ * 2.31f, x32c_ * 2.31f, -M_PIF / 2.f);
|
||||
UpdateCollidersDistances(x274_mediumColliders, x32c_ * 4.62f, x32c_ * 4.62f, -M_PIF / 2.f);
|
||||
UpdateCollidersDistances(x284_largeColliders, x32c_ * 7.f, x32c_ * 7.f, -M_PIF / 2.f);
|
||||
}
|
||||
|
||||
float elevation = x1a0_elevation;
|
||||
bool r27 = !ConstrainElevationAndDistance(elevation, distance, dt, mgr);
|
||||
zeus::CVector3f xa9c = x910.rotate({0.f, distance, elevation});
|
||||
|
||||
if (TCastToConstPtr<CScriptDoor> door = mgr.GetObjectById(x3dc_tooCloseActorId))
|
||||
{
|
||||
if (!door->x2a8_26_)
|
||||
{
|
||||
if (x400_state == EBallCameraState::Three)
|
||||
{
|
||||
zeus::CVector3f xaa8 = GetTranslation() - ballPos;
|
||||
if (xaa8.canBeNormalized())
|
||||
xaa8.normalize();
|
||||
else
|
||||
xaa8 = GetTransform().basis[1];
|
||||
if (std::fabs(f25 - x430_boostElevation) < 1.f)
|
||||
{
|
||||
xaa8 = ConstrainYawAngle(mgr.GetPlayer(), g_tweakBall->GetBallCameraBoostDistance(),
|
||||
g_tweakBall->GetBallCameraBoostYawSpeed(), dt, mgr);
|
||||
}
|
||||
xaa8.normalize();
|
||||
xaa8.z = 0.f;
|
||||
xaa8 = xaa8 * distance;
|
||||
xaa8.z = 1.f;
|
||||
xa9c = xaa8;
|
||||
r27 = false;
|
||||
}
|
||||
if (x18c_25_ && (x400_state == EBallCameraState::Two || x188_behaviour == EBallCameraBehaviour::One))
|
||||
{
|
||||
zeus::CVector3f xab4 = GetTranslation() - ballPos;
|
||||
if (xab4.canBeNormalized())
|
||||
xab4.normalize();
|
||||
else
|
||||
xab4 = GetTransform().basis[1];
|
||||
if (std::fabs(f25 - x404_chaseElevation) < 3.f)
|
||||
{
|
||||
xab4 = ConstrainYawAngle(mgr.GetPlayer(), g_tweakBall->GetBallCameraChaseDistance(),
|
||||
g_tweakBall->GetBallCameraChaseYawSpeed(), dt, mgr);
|
||||
}
|
||||
xab4.z = 0.f;
|
||||
xab4.normalize();
|
||||
xab4 = xab4 * distance;
|
||||
xab4.z = 2.736f;
|
||||
xa9c = xab4;
|
||||
r27 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x188_behaviour == EBallCameraBehaviour::Two)
|
||||
{
|
||||
xa9c = x45c_;
|
||||
if (x18c_27_)
|
||||
{
|
||||
zeus::CVector3f xac0 = x45c_;
|
||||
if (xac0.canBeNormalized())
|
||||
xac0.normalize();
|
||||
else
|
||||
xac0 = -mgr.GetPlayer().GetMoveDir();
|
||||
TUniqueId intersectId = kInvalidUniqueId;
|
||||
CRayCastResult result =
|
||||
mgr.RayWorldIntersection(intersectId, ballPos, xac0, distance, BallCameraFilter, nearList);
|
||||
if (result.IsValid())
|
||||
xa9c = xac0 * result.GetT() * 0.9f;
|
||||
}
|
||||
r27 = false;
|
||||
}
|
||||
|
||||
distance = xa9c.magnitude();
|
||||
zeus::CVector3f xacc = ballPos + xa9c;
|
||||
float d = 0.f;
|
||||
if (DetectCollision(ballPos, xacc, 0.3f, d, mgr))
|
||||
{
|
||||
if (d >= 1.f)
|
||||
{
|
||||
xa9c = xa9c.normalized() * d;
|
||||
xacc = ballPos + xa9c;
|
||||
}
|
||||
else
|
||||
{
|
||||
xa9c = ballPos + GetTranslation();
|
||||
xacc = GetTranslation();
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CTransform x940 = zeus::lookAt(xacc, x1d8_);
|
||||
zeus::CTransform x970 = zeus::lookAt(GetTranslation(), x1d8_);
|
||||
x1e4_ = x940;
|
||||
x940 = x970;
|
||||
zeus::CVector3f xad8;
|
||||
if (x18d_25_ || !x18c_31_)
|
||||
xad8 = AvoidGeometryFull(x940, nearList, dt, mgr);
|
||||
else
|
||||
xad8 = AvoidGeometry(x940, nearList, dt, mgr);
|
||||
|
||||
zeus::CVector3f xae4 = GetTranslation() - ballPos;
|
||||
xae4.z = 0.f;
|
||||
if (xae4.magnitude() < 2.f)
|
||||
{
|
||||
if (x18c_31_ && x478_ > 2)
|
||||
xad8 = xad8 / float(x478_);
|
||||
if (d < 3.f)
|
||||
{
|
||||
xad8 = xad8 * 0.25f;
|
||||
if (x18c_31_ && x478_ > 0)
|
||||
xad8 = xad8 * x308_;
|
||||
}
|
||||
if (d < 1.f)
|
||||
xad8 = zeus::CVector3f::skZero;
|
||||
}
|
||||
|
||||
zeus::CVector3f xaf0 = x940.rotate(xad8) + xacc - ballPos;
|
||||
if (xaf0.canBeNormalized())
|
||||
xaf0.normalize();
|
||||
zeus::CVector3f f27 = xaf0 * distance + ballPos;
|
||||
|
||||
if (x188_behaviour == EBallCameraBehaviour::Six)
|
||||
if (TCastToConstPtr<CPathCamera> cam = mgr.GetObjectById(mgr.GetCameraManager()->GetPathCameraId()))
|
||||
f27 = cam->GetTranslation();
|
||||
|
||||
xaf0 = x294_ - f27;
|
||||
float f24 = xaf0.magnitude();
|
||||
if (xaf0.canBeNormalized())
|
||||
xaf0.normalize();
|
||||
|
||||
x294_ = xaf0 * x228_ballCameraCentroidSpring.ApplyDistanceSpring(0.f, f24, dt) + f27;
|
||||
zeus::CVector3f xafc = f28 - x294_;
|
||||
f24 = xafc.magnitude();
|
||||
if (xafc.canBeNormalized())
|
||||
xafc.normalize();
|
||||
|
||||
float f1 = x250_ballCameraCentroidDistanceSpring.ApplyDistanceSpring(0.f, f24, (x18d_28_ ? 3.f : 1.f) * dt);
|
||||
if (x400_state == EBallCameraState::Three)
|
||||
f1 = x448_ballCameraBoostSpring.ApplyDistanceSpring(0.f, f24, dt);
|
||||
else if (x18c_25_ && (x400_state == EBallCameraState::Two || x188_behaviour == EBallCameraBehaviour::One))
|
||||
f1 = x41c_ballCameraChaseSpring.ApplyDistanceSpring(0.f, f24, dt);
|
||||
|
||||
zeus::CVector3f xb08 = xafc * f1 + x294_;
|
||||
if (mgr.GetPlayer().GetMorphBall()->GetSpiderBallState() != CMorphBall::ESpiderBallState::Active &&
|
||||
!x18e_24_ && mgr.GetPlayer().GetVelocity().z > 8.f)
|
||||
{
|
||||
zeus::CVector3f delta = xb08 - f28;
|
||||
delta.z = zeus::clamp(-0.1f * dt, delta.z, 0.1f * dt);
|
||||
xb08 = f28 + delta;
|
||||
}
|
||||
|
||||
if (r27 && x400_state != EBallCameraState::Four)
|
||||
xb08 = InterpolateCameraElevation(xb08);
|
||||
|
||||
if (x18d_29_)
|
||||
xb08.z = elevation + ballPos.z;
|
||||
|
||||
if (xae4.magnitude() < 2.f)
|
||||
{
|
||||
if (xb08.z < 2.f + ballPos.z)
|
||||
xb08.z = 2.f + ballPos.z;
|
||||
x214_ballCameraSpring.Reset();
|
||||
}
|
||||
|
||||
xb08 = ClampElevationToWater(xb08, mgr);
|
||||
if (xae4.magnitude() < 2.f && x3dc_tooCloseActorId != kInvalidUniqueId && x3e0_tooCloseActorDist < 5.f)
|
||||
if (TCastToConstPtr<CScriptDoor> door = mgr.GetObjectById(x3dc_tooCloseActorId))
|
||||
if (!door->x2a8_26_)
|
||||
xb08 = GetTranslation();
|
||||
|
||||
float backupZ = xb08.z;
|
||||
xb08 = MoveCollisionActor(xb08, dt, mgr);
|
||||
|
||||
if (x18c_31_ && x478_ > 0)
|
||||
{
|
||||
xb08.z = backupZ;
|
||||
xb08 = MoveCollisionActor(xb08, dt, mgr);
|
||||
}
|
||||
|
||||
zeus::CVector3f xb14 = x1d8_ - xb08;
|
||||
if (x18d_26_)
|
||||
xb14 = ballPos - xb08;
|
||||
if (xb14.canBeNormalized())
|
||||
{
|
||||
xb14.normalize();
|
||||
UpdateTransform(xb14, xb08, dt, mgr);
|
||||
}
|
||||
|
||||
if (x470_ > 0.f)
|
||||
x470_ -= dt;
|
||||
}
|
||||
}
|
||||
|
||||
void CBallCamera::UpdateUsingSpindleCameras(float dt, CStateManager& mgr)
|
||||
|
@ -1046,9 +1505,9 @@ void CBallCamera::ActivateFailsafe(float dt, CStateManager& mgr)
|
|||
|
||||
}
|
||||
|
||||
void CBallCamera::ConstrainElevationAndDistance(float& elevation, float& distance, float f1, CStateManager& mgr)
|
||||
bool CBallCamera::ConstrainElevationAndDistance(float& elevation, float& distance, float dt, CStateManager& mgr)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
zeus::CVector3f CBallCamera::FindDesiredPosition(float distance, float elevation,
|
||||
|
|
|
@ -124,12 +124,12 @@ private:
|
|||
zeus::CVector3f x2a0_ = zeus::CVector3f::skUp;
|
||||
zeus::CVector3f x2ac_ = zeus::CVector3f::skUp;
|
||||
zeus::CVector3f x2b8_ = zeus::CVector3f::skUp;
|
||||
u32 x2c4_ = 0;
|
||||
u32 x2c8_ = 0;
|
||||
u32 x2cc_ = 0;
|
||||
u32 x2d0_ = 0;
|
||||
u32 x2d4_ = 0;
|
||||
u32 x2d8_ = 0;
|
||||
int x2c4_ = 0;
|
||||
int x2c8_ = 0;
|
||||
int x2cc_ = 0;
|
||||
int x2d0_ = 0;
|
||||
int x2d4_ = 0;
|
||||
int x2d8_ = 0;
|
||||
zeus::CVector3f x2dc_;
|
||||
float x2e8_ = 0.f;
|
||||
float x2ec_ = 0.f;
|
||||
|
@ -193,7 +193,7 @@ private:
|
|||
bool ShouldResetSpline(CStateManager& mgr) const;
|
||||
void UpdatePlayerMovement(float dt, CStateManager& mgr);
|
||||
void UpdateTransform(const zeus::CVector3f& lookDir, const zeus::CVector3f& pos, float dt, CStateManager& mgr);
|
||||
zeus::CVector3f ConstrainYawAngle(const CPlayer& player, float angleVel, float maxAngle, float dt,
|
||||
zeus::CVector3f ConstrainYawAngle(const CPlayer& player, float distance, float yawSpeed, float dt,
|
||||
CStateManager& mgr) const;
|
||||
void CheckFailsafe(float dt, CStateManager& mgr);
|
||||
void UpdateObjectTooCloseId(CStateManager& mgr);
|
||||
|
@ -205,15 +205,15 @@ private:
|
|||
zeus::CVector3f TweenVelocity(const zeus::CVector3f& curVel, const zeus::CVector3f& newVel, float rate, float dt);
|
||||
zeus::CVector3f MoveCollisionActor(const zeus::CVector3f& pos, float dt, CStateManager& mgr);
|
||||
void UpdateUsingFreeLook(float dt, CStateManager& mgr);
|
||||
zeus::CVector3f InterpolateCameraElevation(const zeus::CVector3f& camPos) const;
|
||||
zeus::CVector3f InterpolateCameraElevation(const zeus::CVector3f& camPos);
|
||||
zeus::CVector3f CalculateCollidersCentroid(const std::vector<CCameraCollider>& colliderList, int w1) const;
|
||||
zeus::CVector3f ApplyColliders();
|
||||
void UpdateColliders(const zeus::CTransform& xf, std::vector<CCameraCollider>& colliderList, int& r6, int r7,
|
||||
float f1, const rstl::reserved_vector<TUniqueId, 1024>& nearList, float f2,
|
||||
float f1, const rstl::reserved_vector<TUniqueId, 1024>& nearList, float dt,
|
||||
CStateManager& mgr);
|
||||
void AvoidGeometry(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
zeus::CVector3f AvoidGeometry(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
float dt, CStateManager& mgr);
|
||||
void AvoidGeometryFull(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
zeus::CVector3f AvoidGeometryFull(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||
float dt, CStateManager& mgr);
|
||||
zeus::CAABox CalculateCollidersBoundingBox(const std::vector<CCameraCollider>& colliderList,
|
||||
CStateManager& mgr) const;
|
||||
|
@ -228,7 +228,7 @@ private:
|
|||
bool SplineIntersectTest(CMaterialList& intersectMat, CStateManager& mgr) const;
|
||||
static bool IsBallNearDoor(const zeus::CVector3f& pos, CStateManager& mgr);
|
||||
void ActivateFailsafe(float dt, CStateManager& mgr);
|
||||
void ConstrainElevationAndDistance(float& elevation, float& distance, float f1, CStateManager& mgr);
|
||||
bool ConstrainElevationAndDistance(float& elevation, float& distance, float dt, CStateManager& mgr);
|
||||
zeus::CVector3f FindDesiredPosition(float distance, float elevation, const zeus::CVector3f& dir, CStateManager& mgr);
|
||||
static bool DetectCollision(const zeus::CVector3f& from, const zeus::CVector3f& to, float margin,
|
||||
float& d, CStateManager& mgr);
|
||||
|
|
|
@ -20,7 +20,33 @@ void CCameraSpline::CalculateKnots(TUniqueId cameraId, const std::vector<SConnec
|
|||
if (lastConn)
|
||||
{
|
||||
TCastToPtr<CScriptCameraWaypoint> waypoint = mgr.ObjectById(mgr.GetIdForScript(lastConn->x8_objId));
|
||||
//if (waypoint)
|
||||
x14_wpTracker.clear();
|
||||
x14_wpTracker.reserve(4);
|
||||
while (waypoint)
|
||||
{
|
||||
auto search = std::find_if(x14_wpTracker.begin(), x14_wpTracker.end(),
|
||||
[&waypoint](const auto& a) { return a == waypoint->GetUniqueId(); });
|
||||
if (search == x14_wpTracker.end())
|
||||
{
|
||||
x14_wpTracker.push_back(waypoint->GetUniqueId());
|
||||
waypoint = mgr.ObjectById(waypoint->GetRandomNextWaypointId(mgr));
|
||||
}
|
||||
}
|
||||
Reset(x14_wpTracker.size());
|
||||
x14_wpTracker.clear();
|
||||
|
||||
waypoint = mgr.ObjectById(mgr.GetIdForScript(lastConn->x8_objId));
|
||||
while (waypoint)
|
||||
{
|
||||
auto search = std::find_if(x14_wpTracker.begin(), x14_wpTracker.end(),
|
||||
[&waypoint](const auto& a) { return a == waypoint->GetUniqueId(); });
|
||||
if (search == x14_wpTracker.end())
|
||||
{
|
||||
x14_wpTracker.push_back(waypoint->GetUniqueId());
|
||||
AddKnot(waypoint->GetTranslation(), waypoint->GetTransform().basis[1]);
|
||||
waypoint = mgr.ObjectById(waypoint->GetRandomNextWaypointId(mgr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class CCameraSpline
|
|||
{
|
||||
friend class CBallCamera;
|
||||
std::vector<zeus::CVector3f> x4_positions;
|
||||
std::vector<TUniqueId> x14_;
|
||||
std::vector<TUniqueId> x14_wpTracker;
|
||||
std::vector<float> x24_t;
|
||||
std::vector<zeus::CVector3f> x34_directions;
|
||||
float x44_length = 0.f;
|
||||
|
|
|
@ -117,6 +117,8 @@ public:
|
|||
TCastToPtr() = default;
|
||||
TCastToPtr(CEntity* p);
|
||||
TCastToPtr(CEntity& p);
|
||||
TCastToPtr<T>& operator=(CEntity& p);
|
||||
TCastToPtr<T>& operator=(CEntity* p);
|
||||
|
||||
''')
|
||||
|
||||
|
@ -139,6 +141,8 @@ public:
|
|||
TCastToConstPtr() = default;
|
||||
TCastToConstPtr(const CEntity* p) : TCastToPtr<T>(const_cast<CEntity*>(p)) {}
|
||||
TCastToConstPtr(const CEntity& p) : TCastToPtr<T>(const_cast<CEntity&>(p)) {}
|
||||
TCastToConstPtr<T>& operator=(const CEntity& p) { TCastToPtr<T>::operator=(const_cast<CEntity&>(p)); return *this; }
|
||||
TCastToConstPtr<T>& operator=(const CEntity* p) { TCastToPtr<T>::operator=(const_cast<CEntity*>(p)); return *this; }
|
||||
const T* GetPtr() const { return TCastToPtr<T>::ptr; }
|
||||
operator const T*() const { return GetPtr(); }
|
||||
const T& operator*() const { return *GetPtr(); }
|
||||
|
@ -169,6 +173,12 @@ TCastToPtr<T>::TCastToPtr(CEntity* p) { p->Accept(*this); }
|
|||
template <class T>
|
||||
TCastToPtr<T>::TCastToPtr(CEntity& p) { p.Accept(*this); }
|
||||
|
||||
template <class T>
|
||||
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity* p) { p->Accept(*this); return *this; }
|
||||
|
||||
template <class T>
|
||||
TCastToPtr<T>& TCastToPtr<T>::operator=(CEntity& p) { p.Accept(*this); return *this; }
|
||||
|
||||
''')
|
||||
|
||||
for tp in CENTITY_TYPES:
|
||||
|
|
|
@ -678,6 +678,7 @@ public:
|
|||
const zeus::CVector3f& GetMoveDir() const { return x50c_moveDir; }
|
||||
const zeus::CVector3f& GetLeaveMorphDir() const { return x518_leaveMorphDir; }
|
||||
u32 GetBombJumpCount() const { return x9d0_bombJumpCount; }
|
||||
float GetMoveSpeed() const { return x4f8_moveSpeed; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CScriptCameraWaypoint.hpp"
|
||||
#include "CActorParameters.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -27,4 +28,24 @@ void CScriptCameraWaypoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
|
|||
SendScriptMsgs(EScriptObjectState::Arrived, mgr, EScriptObjectMessage::None);
|
||||
}
|
||||
|
||||
TUniqueId CScriptCameraWaypoint::GetRandomNextWaypointId(CStateManager& mgr) const
|
||||
{
|
||||
std::vector<TUniqueId> candidateIds;
|
||||
for (const SConnection& conn : x20_conns)
|
||||
{
|
||||
if (conn.x0_state == EScriptObjectState::Arrived && conn.x4_msg == EScriptObjectMessage::Next)
|
||||
{
|
||||
TUniqueId uid = mgr.GetIdForScript(conn.x8_objId);
|
||||
if (uid == kInvalidUniqueId)
|
||||
continue;
|
||||
candidateIds.push_back(uid);
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateIds.empty())
|
||||
return kInvalidUniqueId;
|
||||
|
||||
return candidateIds[mgr.GetActiveRandom()->Range(0, s32(candidateIds.size() - 1))];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const {}
|
||||
void Render(const CStateManager&) const {}
|
||||
TUniqueId GetRandomNextWaypointId(CStateManager& mgr) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue