From 38cfad8b174a0c67148a61540c08df1392a431b3 Mon Sep 17 00:00:00 2001 From: Nathan M Gilbert Date: Wed, 27 Mar 2024 15:38:13 -0400 Subject: [PATCH] Implement LegoExtraActor::VTable0x90 (#739) * Implement LegoExtraActor::VTable0x90 * Improve LegoExtraActor::VTable0x90 * Match --------- Co-authored-by: Christian Semmler --- .../lego/legoomni/include/legocarraceactor.h | 12 ++-- LEGO1/lego/legoomni/include/legoextraactor.h | 29 ++++---- LEGO1/lego/legoomni/include/legopathactor.h | 6 +- LEGO1/lego/legoomni/include/legoraceactor.h | 2 +- .../legoomni/src/entity/legocarraceactor.cpp | 2 +- .../lego/legoomni/src/paths/legoanimactor.cpp | 8 +-- .../legoomni/src/paths/legoextraactor.cpp | 66 +++++++++++++++++-- .../lego/legoomni/src/race/legoraceactor.cpp | 2 +- LEGO1/realtime/matrix.h | 24 +++++++ 9 files changed, 120 insertions(+), 31 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocarraceactor.h b/LEGO1/lego/legoomni/include/legocarraceactor.h index aff84b8e..78080c96 100644 --- a/LEGO1/lego/legoomni/include/legocarraceactor.h +++ b/LEGO1/lego/legoomni/include/legocarraceactor.h @@ -27,12 +27,12 @@ class LegoCarRaceActor : public virtual LegoRaceActor { return !strcmp(p_name, LegoCarRaceActor::ClassName()) || LegoRaceActor::IsA(p_name); } - void VTable0x6c() override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 - MxS32 VTable0x90() override; // vtable+0x90 - MxS32 VTable0x94() override; // vtable+0x94 - void VTable0x98() override; // vtable+0x98 - void VTable0x9c() override; // vtable+0x9c + void VTable0x6c() override; // vtable+0x6c + void VTable0x70(float p_float) override; // vtable+0x70 + MxU32 VTable0x90(float, Matrix4&) override; // vtable+0x90 + MxS32 VTable0x94() override; // vtable+0x94 + void VTable0x98() override; // vtable+0x98 + void VTable0x9c() override; // vtable+0x9c virtual void FUN_10080590(); diff --git a/LEGO1/lego/legoomni/include/legoextraactor.h b/LEGO1/lego/legoomni/include/legoextraactor.h index b89332fa..2b2612a6 100644 --- a/LEGO1/lego/legoomni/include/legoextraactor.h +++ b/LEGO1/lego/legoomni/include/legoextraactor.h @@ -9,6 +9,13 @@ // SIZE 0x1dc class LegoExtraActor : public virtual LegoAnimActor { public: + enum Axis { + e_posz, + e_negz, + e_posx, + e_negx + }; + LegoExtraActor(); ~LegoExtraActor() override; @@ -27,15 +34,15 @@ class LegoExtraActor : public virtual LegoAnimActor { void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 void VTable0x68(Mx3DPointFloat& p_point1, Mx3DPointFloat& p_point2, Mx3DPointFloat& p_point3) - override; // vtable+0x68 - void VTable0x6c() override; // vtable+0x6c - void VTable0x70(float) override; // vtable+0x70 - void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 - MxS32 VTable0x90() override; // vtable+0x90 - MxS32 VTable0x94() override; // vtable+0x94 - void VTable0x9c() override; // vtable+0x9c - void VTable0xa4() override; // vtable+0xa4 - void VTable0xc4() override; // vtable+0xc4 + override; // vtable+0x68 + void VTable0x6c() override; // vtable+0x6c + void VTable0x70(float) override; // vtable+0x70 + void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 + MxU32 VTable0x90(float p_float, Matrix4& p_matrix) override; // vtable+0x90 + MxS32 VTable0x94() override; // vtable+0x94 + void VTable0x9c() override; // vtable+0x9c + void VTable0xa4() override; // vtable+0xa4 + void VTable0xc4() override; // vtable+0xc4 virtual MxResult FUN_1002aae0(); @@ -43,9 +50,9 @@ class LegoExtraActor : public virtual LegoAnimActor { // LegoExtraActor::`scalar deleting destructor' private: - undefined4 m_unk0x08; // 0x08 + MxFloat m_scheduledTime; // 0x08 undefined m_unk0x0c; // 0x0c - undefined m_unk0x0d; // 0x0d + MxU8 m_axis; // 0x0d undefined m_unk0x0e; // 0x0e undefined4 m_unk0x10; // 0x10 MxU8 m_unk0x14; // 0x14 diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index a45b93e7..8cdf5b00 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -46,7 +46,7 @@ class LegoPathActor : public LegoActor { virtual void VTable0x8c(); // vtable+0x8c // FUNCTION: LEGO1 0x10002d40 - virtual MxS32 VTable0x90() { return 0; } // vtable+0x90 + virtual MxU32 VTable0x90(float, Matrix4&) { return FALSE; } // vtable+0x90 // FUNCTION: LEGO1 0x10002d50 virtual MxS32 VTable0x94() { return 0; } // vtable+0x94 @@ -97,8 +97,8 @@ class LegoPathActor : public LegoActor { protected: MxFloat m_BADuration; // 0x78 undefined4 m_unk0x7c; // 0x7c - MxFloat m_unk0x80; // 0x80 - MxFloat m_unk0x84; // 0x84 + MxFloat m_actorTime; // 0x80 + MxFloat m_lastTime; // 0x84 LegoPathBoundary* m_boundary; // 0x88 undefined m_unk0x8c[0x14]; // 0x8c MxFloat m_unk0xa0; // 0xa0 diff --git a/LEGO1/lego/legoomni/include/legoraceactor.h b/LEGO1/lego/legoomni/include/legoraceactor.h index 65453d10..0f535fa6 100644 --- a/LEGO1/lego/legoomni/include/legoraceactor.h +++ b/LEGO1/lego/legoomni/include/legoraceactor.h @@ -31,7 +31,7 @@ class LegoRaceActor : public virtual LegoAnimActor { void VTable0x68(Mx3DPointFloat&, Mx3DPointFloat&, Mx3DPointFloat&) override; // vtable+0x68 void VTable0x70(float p_float) override; // vtable+0x70 void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 - MxS32 VTable0x90() override; // vtable+0x90 + MxU32 VTable0x90(float, Matrix4&) override; // vtable+0x90 MxS32 VTable0x94() override; // vtable+0x94 // FUNCTION: LEGO1 0x10014aa0 diff --git a/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp index 8c2eb822..5adc760b 100644 --- a/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp @@ -10,7 +10,7 @@ DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0) const char* g_fuel = "FUEL"; // STUB: LEGO1 0x100141a0 -MxS32 LegoCarRaceActor::VTable0x90() +MxU32 LegoCarRaceActor::VTable0x90(float, Matrix4&) { // TODO return 0; diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index 71745847..27c110f7 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -46,7 +46,7 @@ LegoAnimActor::~LegoAnimActor() MxResult LegoAnimActor::FUN_1001c1f0(float& p_und) { float duration = (float) m_animMaps[m_curAnim]->m_AnimTreePtr->GetDuration(); - p_und = m_unk0x80 - duration * ((MxS32) (m_unk0x80 / duration)); + p_und = m_actorTime - duration * ((MxS32) (m_actorTime / duration)); return SUCCESS; } @@ -65,8 +65,8 @@ void LegoAnimActor::VTable0x74(Matrix4& p_transform) // FUNCTION: LEGO1 0x1001c290 void LegoAnimActor::VTable0x70(float p_float) { - if (m_unk0x84 == 0) { - m_unk0x84 = p_float - 1.0f; + if (m_lastTime == 0) { + m_lastTime = p_float - 1.0f; } if (m_unk0xdc == 0 && !m_userNavFlag && m_worldSpeed <= 0) { @@ -77,7 +77,7 @@ void LegoAnimActor::VTable0x70(float p_float) FUN_1001c360(f, matrix); } - m_unk0x84 = m_unk0x80 = p_float; + m_lastTime = m_actorTime = p_float; } else { LegoPathActor::VTable0x70(p_float); diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index 774d9079..d469a7b2 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -2,11 +2,14 @@ DECOMP_SIZE_ASSERT(LegoExtraActor, 0x1dc) +// GLOBAL: LEGO1 0x10104c18 +Mx3DPointFloat g_unk0x10104c18 = Mx3DPointFloat(0.0f, 2.5f, 0.0f); + // FUNCTION: LEGO1 0x1002a500 LegoExtraActor::LegoExtraActor() { m_unk0x70 = 0.0f; - m_unk0x08 = 0; + m_scheduledTime = 0; m_unk0x0c = 0; m_unk0x0e = 0; m_unk0x14 = 0; @@ -22,10 +25,65 @@ LegoExtraActor::~LegoExtraActor() delete m_unk0x64; } -// STUB: LEGO1 0x1002a720 -MxS32 LegoExtraActor::VTable0x90() +// FUNCTION: LEGO1 0x1002a720 +MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) { - return 0; + switch (m_unk0xdc & 0xff) { + case 0: + case 1: + return TRUE; + case 2: + m_scheduledTime = p_time + 2000.0f; + m_unk0xdc = 3; + m_actorTime += (p_time - m_lastTime) * m_worldSpeed; + m_lastTime = p_time; + return FALSE; + case 3: { + Vector3 positionRef(p_transform[3]); + p_transform = m_roi->GetLocal2World(); + + if (p_time < m_scheduledTime) { + Mx3DPointFloat position; + position = positionRef; + positionRef.Clear(); + + switch (m_axis) { + case e_posz: { + p_transform.RotateZ(0.7f); + break; + } + case e_negz: { + p_transform.RotateZ(-0.7f); + break; + } + case e_posx: { + p_transform.RotateX(0.7f); + break; + } + case e_negx: { + p_transform.RotateX(-0.7f); + break; + } + } + + positionRef = position; + m_actorTime += (p_time - m_lastTime) * m_worldSpeed; + m_lastTime = p_time; + VTable0x74(p_transform); + return FALSE; + } + else { + m_unk0xdc = 0; + m_scheduledTime = 0.0f; + ((Vector3&) positionRef).Sub(&g_unk0x10104c18); // TODO: Fix call + m_roi->FUN_100a58f0(p_transform); + return TRUE; + } + } + + default: + return FALSE; + } } // STUB: LEGO1 0x1002aa90 diff --git a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp index 6221693d..21d9e130 100644 --- a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp +++ b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp @@ -34,7 +34,7 @@ void LegoRaceActor::VTable0x70(float p_float) } // STUB: LEGO1 0x10014ce0 -MxS32 LegoRaceActor::VTable0x90() +MxU32 LegoRaceActor::VTable0x90(float, Matrix4&) { // TODO return 0; diff --git a/LEGO1/realtime/matrix.h b/LEGO1/realtime/matrix.h index 6f96e477..8604e0ce 100644 --- a/LEGO1/realtime/matrix.h +++ b/LEGO1/realtime/matrix.h @@ -114,6 +114,30 @@ class Matrix4 { } } + inline void RotateX(const float& p_angle) + { + float s = sin(p_angle); + float c = cos(p_angle); + float matrix[4][4]; + memcpy(matrix, m_data, sizeof(float) * 16); + for (int i = 0; i < 4; i++) { + m_data[i][1] = matrix[i][1] * c - matrix[i][2] * s; + m_data[i][2] = matrix[i][2] * c + matrix[i][1] * s; + } + } + + inline void RotateZ(const float& p_angle) + { + float s = sin(p_angle); + float c = cos(p_angle); + float matrix[4][4]; + memcpy(matrix, m_data, sizeof(float) * 16); + for (int i = 0; i < 4; i++) { + m_data[i][0] = matrix[i][0] * c - matrix[i][1] * s; + m_data[i][1] = matrix[i][1] * c + matrix[i][0] * s; + } + } + inline virtual void ToQuaternion(Vector4& p_resultQuat); // vtable+0x40 inline virtual int FromQuaternion(const Vector4& p_vec); // vtable+0x44