From da48dfb40dfc553eaca5bed9436d1a8846a3a519 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 28 May 2024 15:23:23 -0400 Subject: [PATCH] Implement/match LegoAnimPresenter::FUN_1006b140 (#963) --- .../lego/legoomni/include/legoanimpresenter.h | 12 +-- .../legoomni/src/video/legoanimpresenter.cpp | 52 +++++++++++- LEGO1/realtime/matrix.h | 82 ++++++++++++++++++- 3 files changed, 136 insertions(+), 10 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index d9d97bb5..d7cc4cb2 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -84,11 +84,11 @@ public: const char* GetActionObjectName(); inline void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; } + inline void SetUnknown0x0cTo1() { m_unk0x9c = 1; } + inline void SetUnknown0xa0(MxMatrix* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } inline LegoAnim* GetAnimation() { return m_anim; } - friend class LegoPathBoundary; - protected: void Init(); void Destroy(MxBool p_fromDestructor); @@ -128,9 +128,11 @@ protected: undefined m_unk0x97; // 0x97 LegoAnimSubstMap* m_substMap; // 0x98 MxS16 m_unk0x9c; // 0x9c - undefined4* m_unk0xa0; // 0xa0 - float m_unk0xa4; // 0xa4 - Mx3DPointFloat m_unk0xa8; // 0xa8 + MxMatrix* m_unk0xa0; // 0xa0 + +public: + float m_unk0xa4; // 0xa4 + Mx3DPointFloat m_unk0xa8; // 0xa8 }; // clang-format off diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 503c6282..11aa7f40 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -121,7 +121,7 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor) } if (m_unk0xa0 != NULL) { - delete m_unk0xa0; // TODO + delete m_unk0xa0; } Init(); @@ -699,11 +699,57 @@ MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und) return SUCCESS; } -// STUB: LEGO1 0x1006b140 +// FUNCTION: LEGO1 0x1006b140 // FUNCTION: BETA10 0x100507e0 MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) { - // TODO + if (p_roi == NULL) { + return FAILURE; + } + + MxMatrix* mn = new MxMatrix(); + MxMatrix local58; + const Matrix4& local2world = p_roi->GetLocal2World(); + MxMatrix* local5c; + MxU32 i; + + if (FUN_1006afc0(local5c, 0.0f) != SUCCESS) { + goto done; + } + + for (i = 1; i <= m_roiMapSize; i++) { + if (m_roiMap[i] == p_roi) { + if (local5c[i].Unknown(local58) != SUCCESS) { + goto done; + } + + break; + } + } + + { + ((Matrix4*) mn)->Product(local58, local2world); + SetUnknown0xa0(mn); + delete[] local5c; + SetUnknown0x0cTo1(); + + MxMatrix local140(*m_unk0x78); + MxMatrix localf8; + + localf8.Product(local140, *m_unk0xa0); + ((Matrix4&) *m_unk0x78) = localf8; + return SUCCESS; + } + +done: + if (mn != NULL) { + delete mn; + } + + if (local5c != NULL) { + delete[] local5c; + } + return FAILURE; } diff --git a/LEGO1/realtime/matrix.h b/LEGO1/realtime/matrix.h index 82c3166a..df2260ea 100644 --- a/LEGO1/realtime/matrix.h +++ b/LEGO1/realtime/matrix.h @@ -16,6 +16,7 @@ struct UnknownMatrixType { // SIZE 0x08 class Matrix4 { public: + // FUNCTION: LEGO1 0x10004500 inline Matrix4(float (*p_data)[4]) { SetData(p_data); } // Note: virtual function overloads appear in the virtual table @@ -107,6 +108,9 @@ public: // FUNCTION: LEGO1 0x10002530 virtual void Product(const Matrix4& p_a, const Matrix4& p_b) { Product(p_a.m_data, p_b.m_data); } // vtable+0x38 + inline virtual void ToQuaternion(Vector4& p_resultQuat); // vtable+0x40 + inline virtual int FromQuaternion(const Vector4& p_vec); // vtable+0x44 + // FUNCTION: LEGO1 0x100a0ff0 inline void Scale(const float& p_x, const float& p_y, const float& p_z) { @@ -141,8 +145,17 @@ public: } } - inline virtual void ToQuaternion(Vector4& p_resultQuat); // vtable+0x40 - inline virtual int FromQuaternion(const Vector4& p_vec); // vtable+0x44 + inline int Unknown(Matrix4& p_mat); + + // FUNCTION: LEGO1 0x1006b500 + inline void Swap(int p_d1, int p_d2) + { + for (int i = 0; i < 4; i++) { + float e = m_data[p_d1][i]; + m_data[p_d1][i] = m_data[p_d2][i]; + m_data[p_d2][i] = e; + } + } float* operator[](int idx) { return m_data[idx]; } const float* operator[](int idx) const { return m_data[idx]; } @@ -241,4 +254,69 @@ inline int Matrix4::FromQuaternion(const Vector4& p_vec) return -1; } +// FUNCTION: BETA10 0x1005a590 +inline int Matrix4::Unknown(Matrix4& p_mat) +{ + float local5c[4][4]; + Matrix4 localc(local5c); + + ((Matrix4&) localc) = *this; + p_mat.SetIdentity(); + + for (int i = 0; i < 4; i++) { + int local1c = i; + int local10; + + for (local10 = i + 1; local10 < 4; local10++) { + if (fabs(localc[local1c][i]) < fabs(localc[local10][i])) { + local1c = local10; + } + } + + if (local1c != i) { + localc.Swap(local1c, i); + p_mat.Swap(local1c, i); + } + + if (localc[i][i] < 0.001f && localc[i][i] > -0.001f) { + return -1; + } + + float local60 = localc[i][i]; + int local18; + + for (local18 = 0; local18 < 4; local18++) { + p_mat[i][local18] /= local60; + } + + for (local18 = 0; local18 < 4; local18++) { + localc[i][local18] /= local60; + } + + for (local10 = 0; local10 < 4; local10++) { + if (i != local10) { + float afStack70[4]; + + for (local18 = 0; local18 < 4; local18++) { + afStack70[local18] = p_mat[i][local18] * localc[local10][i]; + } + + for (local18 = 0; local18 < 4; local18++) { + p_mat[local10][local18] -= afStack70[local18]; + } + + for (local18 = 0; local18 < 4; local18++) { + afStack70[local18] = localc[i][local18] * localc[local10][i]; + } + + for (local18 = 0; local18 < 4; local18++) { + localc[local10][local18] -= afStack70[local18]; + } + } + } + } + + return 0; +} + #endif // MATRIX_H