Implement CScriptSpecialFunction::ThinkSpinnerController

Former-commit-id: d26a30f186
This commit is contained in:
Henrique Gemignani Passos Lima 2022-10-03 14:55:03 +03:00
parent 8d5f1bb546
commit 16e4de9bfe
10 changed files with 65 additions and 42 deletions

View File

@ -1309,8 +1309,8 @@ GetAnimationManager__9CAnimDataFv:
/* 8002A500 00027460 90 04 00 04 */ stw r0, 4(r4)
/* 8002A504 00027464 4E 80 00 20 */ blr
.global sub_8002a508
sub_8002a508:
.global SetPhase__9CAnimDataFf
SetPhase__9CAnimDataFf:
/* 8002A508 00027468 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8002A50C 0002746C 7C 08 02 A6 */ mflr r0
/* 8002A510 00027470 90 01 00 14 */ stw r0, 0x14(r1)
@ -9688,4 +9688,3 @@ lbl_803CCD20:
.asciz " has invalid initial animation, so defaulting to first.\n"
.balign 4
.4byte 0

View File

@ -1807,7 +1807,7 @@ lbl_801508E0:
/* 801508F8 0014D858 EF 40 00 72 */ fmuls f26, f0, f1
/* 801508FC 0014D85C C0 22 9D 9C */ lfs f1, lbl_805ABABC@sda21(r2)
/* 80150900 0014D860 80 63 00 10 */ lwz r3, 0x10(r3)
/* 80150904 0014D864 4B ED 9C 05 */ bl sub_8002a508
/* 80150904 0014D864 4B ED 9C 05 */ bl SetPhase__9CAnimDataFf
/* 80150908 0014D868 80 7F 00 64 */ lwz r3, 0x64(r31)
/* 8015090C 0014D86C C0 22 9D B4 */ lfs f1, lbl_805ABAD4@sda21(r2)
/* 80150910 0014D870 80 63 00 10 */ lwz r3, 0x10(r3)

View File

@ -6,7 +6,12 @@
#include "Kyoto/Math/CVector2f.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "math.h"
static bool close_enough(const CVector2f& a, const CVector2f& b, f32 epsilon = 0.001f);
static bool close_enough(const CVector3f& a, const CVector3f& b, f32 epsilon = 0.001f);
inline bool close_enough(float a, float b, f32 epsilon = 0.001f) {
return fabs(a - b) < epsilon;
}
#endif // __CLOSEENOUGH_HPP__

View File

@ -91,20 +91,21 @@ public:
// Render__9CAnimDataCFRC13CSkinnedModelRC11CModelFlagsRCQ24rstl37optional_object<18CVertexMorphEffect>PCf
// RenderAuxiliary__9CAnimDataCFRC14CFrustumPlanes
// RecalcPoseBuilder__9CAnimDataCFPC13CCharAnimTime
// GetAnimationDuration__9CAnimDataCFi
float GetAnimationDuration(int animIn) const;
// GetAnimTimeRemaining__9CAnimDataCFRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>
// IsAnimTimeRemaining__9CAnimDataCFfRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>
// GetLocatorTransform__9CAnimDataCFRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>PC13CCharAnimTime
// GetLocatorTransform__9CAnimDataCF6CSegIdPC13CCharAnimTime
// CalcPlaybackAlignmentParms__9CAnimDataFRC18CAnimPlaybackParmsRCQ24rstl25ncrc_ptr<13CAnimTreeNode>
// SetRandomPlaybackRate__9CAnimDataFR9CRandom16
// SetPlaybackRate__9CAnimDataFf
void SetPlaybackRate(float set);
// MultiplyPlaybackRate__9CAnimDataFf
// GetTimeOfUserEvent__9CAnimDataCF14EUserEventTypeRC13CCharAnimTime
// GetAdvancementDeltas__9CAnimDataCFRC13CCharAnimTimeRC13CCharAnimTime
// Touch__9CAnimDataCFRC13CSkinnedModeli
// InitializeEffects__9CAnimDataFR13CStateManagerRC9CVector3f
// SetPhase__9CAnimDataFf -> SetPhase__11IAnimReaderFf
void SetPhase(float ph);
// AddAdditiveAnimation__9CAnimDataFUifbb
// DelAdditiveAnimation__9CAnimDataFUi
// IsAdditiveAnimationActive__9CAnimDataCFUi
@ -119,6 +120,7 @@ public:
// GetAnimationManager__9CAnimDataFv
// SetPoseValid__9CAnimDataFb
u16 GetDefaultAnimation() const { return x208_defaultAnim; }
// GetCharacterInfo__9CAnimDataCFv
// GetCharLayoutInfo__9CAnimDataCFv
// GetDeltaRotation__9CAnimDataCFv

View File

@ -5,16 +5,15 @@
#include "Kyoto/Math/CVector3f.hpp"
class CAxisAngle {
class CAxisAngle : CVector3f {
public:
CAxisAngle(f32 x, f32 y, f32 z) : x(x), y(y), z(z) {}
CAxisAngle(const CAxisAngle& other) : x(other.x), y(other.y), z(other.z) {}
CAxisAngle(f32 x, f32 y, f32 z) : CVector3f(x, y, z) {}
CAxisAngle(const CAxisAngle& other) : CVector3f(other) {}
static const CAxisAngle& Identity();
const CVector3f& GetVector() const;
private:
// maybe CUnitVector3f?
f32 x, y, z;
};
CHECK_SIZEOF(CAxisAngle, 0xc)

View File

@ -40,6 +40,6 @@ private:
bool xb4_24_updatesEnabled : 1;
bool xb4_25_anySystemsDrawnWithModel : 1;
};
CHECK_SIZEOF(CParticleDatabase, 0xb5)
CHECK_SIZEOF(CParticleDatabase, 0xb8)
#endif

View File

@ -69,6 +69,7 @@ public:
void MoveCollisionPrimitive(const CVector3f&);
void SetVelocityWR(const CVector3f&);
void SetAngularVelocityWR(const CAxisAngle& angVel);
CAxisAngle GetAngularVelocityOR() const;
void ClearForcesAndTorques();
void Stop();

View File

@ -152,6 +152,7 @@ public:
CTransform4f CreateTransformFromMovementDirection() const;
EPlayerOrbitState GetOrbitState() const { return x304_orbitState; }
const CVector3f& GetMovementDirection() const { return x50c_moveDir; }
EPlayerMorphBallState GetMorphballTransitionState() const { return x2f8_morphBallState; }
void SetHudDisable(float staticTimer, float outSpeed, float inSpeed);
void IncrementPhazon();
void DecrementPhazon();

View File

@ -67,6 +67,8 @@ public:
TUniqueId GetWaypoint(CStateManager& mgr);
TUniqueId GetNext(TUniqueId uid, CStateManager& mgr);
void SetControlledAnimation(bool controlled) { x356_25_controlledAnimation = controlled; }
static void AddRider(rstl::vector< SRiders >& riders, TUniqueId riderId,
const CPhysicsActor* ridee, CStateManager& mgr);
static TEntityList BuildNearListFromRiders(CStateManager& mgr,

View File

@ -1,6 +1,7 @@
#include "MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp"
#include "MetroidPrime/CActorParameters.hpp"
#include "MetroidPrime/CAnimData.hpp"
#include "MetroidPrime/CEnvFxManager.hpp"
#include "MetroidPrime/CMain.hpp"
#include "MetroidPrime/CStateManager.hpp"
@ -9,8 +10,10 @@
#include "MetroidPrime/Player/CGameState.hpp"
#include "MetroidPrime/Player/CPlayer.hpp"
#include "MetroidPrime/Player/CPlayerState.hpp"
#include "MetroidPrime/ScriptObjects/CScriptPlatform.hpp"
#include "MetroidPrime/TCastTo.hpp"
#include "Collision/CMaterialFilter.hpp"
#include "Kyoto/Audio/CSfxManager.hpp"
@ -19,9 +22,20 @@
#include "Kyoto/Math/CRelAngle.hpp"
#include "Kyoto/Math/CUnitVector3f.hpp"
#include "Kyoto/Math/CVector2i.hpp"
#include "Kyoto/Math/CloseEnough.hpp"
#include "Runtime/w_fmod.h"
#include "rstl/math.hpp"
namespace rstl {
static int string_find(const string& haystack, const string& needle, int) {
// TODO: proper implementation
return 0;
}
}
CScriptSpecialFunction::CScriptSpecialFunction(
TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf,
ESpecialFunction func, const rstl::string& lcName, float f1, float f2, float f3, float f4,
@ -710,8 +724,8 @@ void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr)
void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr,
ESpinnerControllerMode mode) {
// rstl::string_find is found in CScriptSpecialFunction.s as sub_80150d98
// const bool allowWrap = rstl::string_find(xec_locatorName, "AllowWrap") != std::string::npos;
// const bool noBackward = rstl::string_find(xec_locatorName, "NoBackward") != std::string::npos;
const bool allowWrap = rstl::string_find(xec_locatorName, rstl::string_l("AllowWrap"), 0) != -1;
const bool noBackward = rstl::string_find(xec_locatorName, rstl::string_l("NoBackward"), 0) != -1;
const float pointOneByDt = 0.1f * dt;
const float twoByDt = 2.f * dt;
@ -721,11 +735,11 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
continue;
}
/*
const auto search = mgr.GetIdListForScript(conn->x8_objId);
for (auto it = search.first; it != search.second; ++it) {
if (const TCastToPtr<CScriptPlatform> plat = mgr.ObjectById((*it).second)) {
if (plat->HasModelData() && plat->GetModelData()->HasAnimData()) {
const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId);
if (it.first != it.second) {
TUniqueId uid = it.first->second;
if (CScriptPlatform* plat = TCastToPtr< CScriptPlatform >(mgr.ObjectById(uid))) {
if (plat->HasModelData() && plat->GetModelData()->GetAnimationData()) {
plat->SetControlledAnimation(true);
if (!x1e4_24_spinnerInitializedXf) {
x13c_spinnerInitialXf = plat->GetTransform();
@ -737,16 +751,17 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (mode == kSCM_Zero) {
if (x1e4_25_spinnerCanMove) {
const CPlayer& pl = mgr.GetPlayer();
const CVector3f angVel = pl.GetAngularVelocityOR().getVector();
const CPlayer& pl = *mgr.GetPlayer();
const CVector3f angVel = pl.GetAngularVelocityOR().GetVector();
float mag = 0.f;
if (angVel.canBeNormalized()) {
mag = angVel.magnitude();
if (angVel.CanBeNormalized()) {
mag = angVel.Magnitude();
}
const float spinImpulse =
(pl.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ?
0.025f * mag : 0.f); if (spinImpulse >= x180_) { SendScriptMsgs(kSS_Play, mgr, kSM_None);
(pl.GetMorphballTransitionState() == CPlayer::kMS_Morphed ? 0.025f * mag : 0.f);
if (spinImpulse >= x180_) {
SendScriptMsgs(kSS_Play, mgr, kSM_None);
}
x180_ = spinImpulse;
@ -764,7 +779,7 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (!noBackward) {
x138_ -= f29;
if (std::fabs(x16c_) < dt) {
if (CMath::AbsF(x16c_) < dt) {
x16c_ = 0.f;
} else {
x16c_ -= (dt * (x16c_ <= 0.f ? -1.f : 1.f));
@ -773,21 +788,21 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
}
if (allowWrap) {
x138_ = std::fmod(x138_, 1.f);
x138_ = fmod(x138_, 1.f);
if (x138_ < 0.f) {
x138_ += 1.f;
}
} else {
x138_ = zeus::clamp(0.f, x138_, 1.f);
x138_ = CMath::Clamp(0.f, x138_, 1.f);
}
bool r23 = true;
f28 = x138_ - f28; // always 0?
if (zeus::close_enough(x138_, 1.f, FLT_EPSILON)) {
if (close_enough(x138_, 1.f, FLT_EPSILON)) {
if (!x1e4_27_sfx3Played) {
if (x174_sfx3 != 0xFFFF) {
CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), {}, true, false, 0x7F,
kInvalidAreaId);
CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), CVector3f::Zero(), true, false,
0x7F, kInvalidAreaId.value);
}
x1e4_27_sfx3Played = true;
@ -799,11 +814,11 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
x1e4_27_sfx3Played = false;
}
if (zeus::close_enough(x138_, 0.f, FLT_EPSILON)) {
if (close_enough(x138_, 0.f, FLT_EPSILON)) {
if (!x1e4_26_sfx2Played) {
if (x172_sfx2 != 0xFFFF) {
CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), {}, true, false, 0x7F,
kInvalidAreaId);
CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), CVector3f::Zero(), true, false,
0x7F, kInvalidAreaId.value);
}
x1e4_26_sfx2Played = true;
@ -818,25 +833,24 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (r23) {
if (x170_sfx1 != 0xFFFF) {
x184_.AddValue(0.f <= f28 ? 100 : 0x7f);
const std::optional<float> avg = x184_.GetAverage();
const rstl::optional_object< float > avg = x184_.GetAverage();
AddOrUpdateEmitter(0.f <= f28 ? x108_float4 : 1.f, x178_sfxHandle, x170_sfx1,
GetTranslation(), avg.value());
GetTranslation(), avg.data());
}
} else {
DeleteEmitter(x178_sfxHandle);
}
CAnimData* animData = plat->GetModelData()->GetAnimationData();
CAnimData* animData = plat->ModelData()->AnimationData();
const float dur = animData->GetAnimationDuration(animData->GetDefaultAnimation()) * x138_;
animData->SetPhase(0.f);
animData->SetPlaybackRate(1.f);
const SAdvancementDeltas& deltas = plat->UpdateAnimation(dur, mgr, true);
plat->SetTransform(x13c_spinnerInitialXf *
deltas.xc_rotDelta.toTransform(deltas.x0_posDelta));
// Redundant copy is needed
SAdvancementDeltas deltas = plat->UpdateAnimation(dur, mgr, true);
plat->SetTransform(x13c_spinnerInitialXf * deltas.xc_rotDelta.BuildTransform4f(deltas.x0_posDelta));
}
}
}
*/
}
}