Work on CBallCamera

This commit is contained in:
Jack Andersen 2017-10-13 20:34:57 -10:00
parent 16f6307642
commit 96c17ba729
8 changed files with 552 additions and 34 deletions

View File

@ -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,
float dt, CStateManager& mgr)
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;
}
x328_ += 1;
if (x328_ >= 4)
x328_ = 0;
return ApplyColliders();
}
void CBallCamera::AvoidGeometryFull(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
float dt, CStateManager& mgr)
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,

View File

@ -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,16 +205,16 @@ 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,
float dt, CStateManager& mgr);
void AvoidGeometryFull(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
float dt, CStateManager& mgr);
zeus::CVector3f AvoidGeometry(const zeus::CTransform& xf, const rstl::reserved_vector<TUniqueId, 1024>& nearList,
float dt, CStateManager& mgr);
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;
int CountObscuredColliders(const std::vector<CCameraCollider>& colliderList) 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);

View File

@ -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));
}
}
}
}

View File

@ -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;

View File

@ -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:

View File

@ -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; }
};
}

View File

@ -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))];
}
}

View File

@ -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;
};
}