From 4bcc2b964bc293a0afdecbf21d679b8752b72711 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sat, 10 Jan 2026 20:00:26 +0100 Subject: [PATCH] Clear unknowns in `LegoUnknown` and rename to `LegoSpline` (#1711) --- CMakeLists.txt | 2 +- LEGO1/lego/legoomni/include/legopathactor.h | 4 +- .../lego/legoomni/src/paths/legopathactor.cpp | 6 +- LEGO1/lego/sources/misc/legospline.cpp | 88 +++++++++++++++++++ LEGO1/lego/sources/misc/legospline.h | 27 ++++++ LEGO1/lego/sources/misc/legounknown.cpp | 86 ------------------ LEGO1/lego/sources/misc/legounknown.h | 27 ------ 7 files changed, 121 insertions(+), 119 deletions(-) create mode 100644 LEGO1/lego/sources/misc/legospline.cpp create mode 100644 LEGO1/lego/sources/misc/legospline.h delete mode 100644 LEGO1/lego/sources/misc/legounknown.cpp delete mode 100644 LEGO1/lego/sources/misc/legounknown.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6485e070..0b7cbf0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,11 +189,11 @@ function(add_lego_libraries NAME) add_library(misc${ARG_SUFFIX} STATIC LEGO1/lego/sources/misc/legotexture.cpp + LEGO1/lego/sources/misc/legospline.cpp LEGO1/lego/sources/misc/legostorage.cpp LEGO1/lego/sources/misc/legoimage.cpp LEGO1/lego/sources/misc/legocontainer.cpp LEGO1/lego/sources/misc/legotree.cpp - LEGO1/lego/sources/misc/legounknown.cpp ) list(APPEND list_targets misc${ARG_SUFFIX}) set_property(TARGET misc${ARG_SUFFIX} PROPERTY ARCHIVE_OUTPUT_NAME "misc$<$:d>${ARG_SUFFIX}") diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 2f1d8862..35baafbd 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -2,7 +2,7 @@ #define LEGOPATHACTOR_H #include "legoactor.h" -#include "misc/legounknown.h" +#include "misc/legospline.h" #include "mxtypes.h" struct LegoEdge; @@ -194,7 +194,7 @@ class LegoPathActor : public LegoActor { MxFloat m_actorTime; // 0x80 MxFloat m_lastTime; // 0x84 LegoPathBoundary* m_boundary; // 0x88 - LegoUnknown m_unk0x8c; // 0x8c + LegoSpline m_spline; // 0x8c MxU32 m_actorState; // 0xdc LegoOrientedEdge* m_destEdge; // 0xe0 MxFloat m_unk0xe4; // 0xe4 diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 0b1c0c2f..7233c218 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -81,7 +81,7 @@ MxResult LegoPathActor::VTable0x80(const Vector3& p_point1, Vector3& p_point2, V m_BADuration = sqrtf(m_BADuration); p2 = p_point2; p3 = p_point4; - m_unk0x8c.FUN_1009a140(p_point1, p2, p_point3, p3); + m_spline.SetSpline(p_point1, p2, p_point3, p3); m_BADuration /= 0.001; return SUCCESS; } @@ -354,10 +354,10 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) LegoResult r; if (m_userNavFlag) { - r = m_unk0x8c.FUN_1009a1e0(m_unk0x7c / m_BADuration, p_transform, *m_boundary->GetUp(), 0); + r = m_spline.Evaluate(m_unk0x7c / m_BADuration, p_transform, *m_boundary->GetUp(), FALSE); } else { - r = m_unk0x8c.FUN_1009a1e0(m_unk0x7c / m_BADuration, p_transform, *m_boundary->GetUp(), 1); + r = m_spline.Evaluate(m_unk0x7c / m_BADuration, p_transform, *m_boundary->GetUp(), TRUE); } assert(r == 0); // SUCCESS diff --git a/LEGO1/lego/sources/misc/legospline.cpp b/LEGO1/lego/sources/misc/legospline.cpp new file mode 100644 index 00000000..25562589 --- /dev/null +++ b/LEGO1/lego/sources/misc/legospline.cpp @@ -0,0 +1,88 @@ +#include "legospline.h" + +#include "mxgeometry/mxmatrix.h" + +DECOMP_SIZE_ASSERT(LegoSpline, 0x50) + +// FUNCTION: LEGO1 0x1009a0f0 +LegoSpline::LegoSpline() +{ + for (LegoS32 i = 0; i < sizeOfArray(m_coefficents); i++) { + m_coefficents[i].Clear(); + } +} + +// FUNCTION: LEGO1 0x1009a130 +LegoSpline::~LegoSpline() +{ +} + +// FUNCTION: LEGO1 0x1009a140 +// FUNCTION: BETA10 0x10182c2f +void LegoSpline::SetSpline( + const Vector3& p_start, + const Vector3& p_tangentAtStart, + const Vector3& p_end, + const Vector3& p_tangentAtEnd +) +{ + m_coefficents[0] = p_start; + m_coefficents[1] = p_tangentAtStart; + + for (LegoS32 i = 0; i < 3; i++) { + m_coefficents[2][i] = (p_end[i] - p_start[i]) * 3.0f - p_tangentAtStart[i] * 2.0f - p_tangentAtEnd[i]; + m_coefficents[3][i] = (p_start[i] - p_end[i]) * 2.0f + p_tangentAtEnd[i] + p_tangentAtStart[i]; + } +} + +// FUNCTION: LEGO1 0x1009a1e0 +// FUNCTION: BETA10 0x10182d61 +LegoResult LegoSpline::Evaluate(float p_alpha, Matrix4& p_mat, Vector3& p_up, LegoU32 p_reverse) +{ + Vector3 position(p_mat[3]); + Vector3 right(p_mat[0]); + Vector3 up(p_mat[1]); + Vector3 dir(p_mat[2]); + + if (p_alpha <= 0.001) { + position = m_coefficents[0]; + dir = m_coefficents[1]; + } + else if (p_alpha >= 0.999) { + position = m_coefficents[0]; + position += m_coefficents[1]; + position += m_coefficents[2]; + position += m_coefficents[3]; + + for (LegoS32 i = 0; i < 3; i++) { + dir[i] = m_coefficents[1][i] + m_coefficents[2][i] * 2.0f + m_coefficents[3][i] * 3.0f; + } + } + else { + float alpha_squared = p_alpha * p_alpha; + float alpha_cubed = alpha_squared * p_alpha; + + for (LegoS32 i = 0; i < 3; i++) { + position[i] = m_coefficents[0][i] + m_coefficents[1][i] * p_alpha + m_coefficents[2][i] * alpha_squared + + m_coefficents[3][i] * alpha_cubed; + dir[i] = + m_coefficents[1][i] + m_coefficents[2][i] * p_alpha * 2.0f + m_coefficents[3][i] * alpha_squared * 3.0f; + } + } + + if (p_reverse) { + dir *= -1.0f; + } + + if (dir.Unitize() != 0) { + return FAILURE; + } + + right.EqualsCross(p_up, dir); + if (right.Unitize() != 0) { + return FAILURE; + } + + up.EqualsCross(dir, right); + return SUCCESS; +} diff --git a/LEGO1/lego/sources/misc/legospline.h b/LEGO1/lego/sources/misc/legospline.h new file mode 100644 index 00000000..b504dd7c --- /dev/null +++ b/LEGO1/lego/sources/misc/legospline.h @@ -0,0 +1,27 @@ +#ifndef __LEGOSPLINE_H +#define __LEGOSPLINE_H + +#include "legotypes.h" +#include "mxgeometry/mxgeometry3d.h" + +class Matrix4; + +// SIZE 0x50 +class LegoSpline { +public: + LegoSpline(); + ~LegoSpline(); + + void SetSpline( + const Vector3& p_start, + const Vector3& p_tangentAtStart, + const Vector3& p_end, + const Vector3& p_tangentAtEnd + ); + LegoResult Evaluate(float p_alpha, Matrix4& p_mat, Vector3& p_v, LegoU32 p_reverse); + +private: + Mx3DPointFloat m_coefficents[4]; // 0x00 +}; + +#endif // __LEGOSPLINE_H diff --git a/LEGO1/lego/sources/misc/legounknown.cpp b/LEGO1/lego/sources/misc/legounknown.cpp deleted file mode 100644 index afc22e8f..00000000 --- a/LEGO1/lego/sources/misc/legounknown.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "legounknown.h" - -#include "mxgeometry/mxmatrix.h" - -DECOMP_SIZE_ASSERT(LegoUnknown, 0x50) - -// FUNCTION: LEGO1 0x1009a0f0 -LegoUnknown::LegoUnknown() -{ - for (LegoS32 i = 0; i < sizeOfArray(m_unk0x00); i++) { - m_unk0x00[i].Clear(); - } -} - -// FUNCTION: LEGO1 0x1009a130 -LegoUnknown::~LegoUnknown() -{ -} - -// FUNCTION: LEGO1 0x1009a140 -// FUNCTION: BETA10 0x10182c2f -void LegoUnknown::FUN_1009a140( - const Vector3& p_point1, - const Vector3& p_point2, - const Vector3& p_point3, - const Vector3& p_point4 -) -{ - m_unk0x00[0] = p_point1; - m_unk0x00[1] = p_point2; - - for (LegoS32 i = 0; i < 3; i++) { - m_unk0x00[2][i] = (p_point3[i] - p_point1[i]) * 3.0f - p_point2[i] * 2.0f - p_point4[i]; - m_unk0x00[3][i] = (p_point1[i] - p_point3[i]) * 2.0f + p_point4[i] + p_point2[i]; - } -} - -// FUNCTION: LEGO1 0x1009a1e0 -// FUNCTION: BETA10 0x10182d61 -LegoResult LegoUnknown::FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und) -{ - Vector3 v1(p_mat[3]); - Vector3 v2(p_mat[0]); - Vector3 v3(p_mat[1]); - Vector3 v4(p_mat[2]); - - if (p_f1 <= 0.001) { - v1 = m_unk0x00[0]; - v4 = m_unk0x00[1]; - } - else if (p_f1 >= 0.999) { - v1 = m_unk0x00[0]; - v1 += m_unk0x00[1]; - v1 += m_unk0x00[2]; - v1 += m_unk0x00[3]; - - for (LegoS32 i = 0; i < 3; i++) { - v4[i] = m_unk0x00[1][i] + m_unk0x00[2][i] * 2.0f + m_unk0x00[3][i] * 3.0f; - } - } - else { - float local30 = p_f1 * p_f1; - float local34 = local30 * p_f1; - - for (LegoS32 i = 0; i < 3; i++) { - v1[i] = m_unk0x00[0][i] + m_unk0x00[1][i] * p_f1 + m_unk0x00[2][i] * local30 + m_unk0x00[3][i] * local34; - v4[i] = m_unk0x00[1][i] + m_unk0x00[2][i] * p_f1 * 2.0f + m_unk0x00[3][i] * local30 * 3.0f; - } - } - - if (p_und) { - v4 *= -1.0f; - } - - if (v4.Unitize() != 0) { - return FAILURE; - } - - v2.EqualsCross(p_v, v4); - if (v2.Unitize() != 0) { - return FAILURE; - } - - v3.EqualsCross(v4, v2); - return SUCCESS; -} diff --git a/LEGO1/lego/sources/misc/legounknown.h b/LEGO1/lego/sources/misc/legounknown.h deleted file mode 100644 index c29bbd28..00000000 --- a/LEGO1/lego/sources/misc/legounknown.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __LEGOUNKNOWN_H -#define __LEGOUNKNOWN_H - -#include "legotypes.h" -#include "mxgeometry/mxgeometry3d.h" - -class Matrix4; - -// SIZE 0x50 -class LegoUnknown { -public: - LegoUnknown(); - ~LegoUnknown(); - - void FUN_1009a140( - const Vector3& p_point1, - const Vector3& p_point2, - const Vector3& p_point3, - const Vector3& p_point4 - ); - LegoResult FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und); - -private: - Mx3DPointFloat m_unk0x00[4]; // 0x00 -}; - -#endif // __LEGOUNKNOWN_H