From 3ca9c255a845bc215fda5ccf7de6afaa03897228 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 17 Dec 2024 14:23:54 -0700 Subject: [PATCH] Implement/match `Act3Brickster::FUN_10042300` --- .../legoomni/include/legopathcontroller.h | 4 +- LEGO1/lego/legoomni/src/actors/act3actors.cpp | 97 ++++++++++++++++++- .../legoomni/src/paths/legopathcontroller.cpp | 62 ------------ LEGO1/lego/sources/geom/legoedge.h | 6 ++ LEGO1/lego/sources/geom/legounkown100db7f4.h | 64 ++++++++++++ LEGO1/mxgeometry/mxgeometry3d.h | 3 + LEGO1/realtime/vector.h | 13 ++- 7 files changed, 177 insertions(+), 72 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 85ef1f9f..37096cc2 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -22,9 +22,7 @@ class Vector3; // VTABLE: LEGO1 0x100d7da8 // SIZE 0x40 -struct LegoPathCtrlEdge : public LegoUnknown100db7f4 { - inline MxU32 FUN_10048c40(const Vector3& p_position); -}; +struct LegoPathCtrlEdge : public LegoUnknown100db7f4 {}; struct LegoPathCtrlEdgeCompare { MxU32 operator()(const LegoPathCtrlEdge* p_lhs, const LegoPathCtrlEdge* p_rhs) const diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 306a6e3b..1fc872e7 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -613,11 +613,102 @@ MxResult Act3Brickster::FUN_100417c0() return SUCCESS; } -// STUB: LEGO1 0x10042300 -// STUB: BETA10 0x1001b017 +// FUNCTION: LEGO1 0x10042300 +// FUNCTION: BETA10 0x1001b017 MxS32 Act3Brickster::FUN_10042300() { - // TODO + Act3* a3 = (Act3*) m_world; + + assert(a3 && a3->m_cop1 && a3->m_cop2); + assert(a3->m_cop1->GetROI() && a3->m_cop2->GetROI() && GetROI()); + + Mx3DPointFloat local64[2]; + Mx3DPointFloat local38; + Mx3DPointFloat local18; + + MxS32 local1c = 0; + float local24[2]; + + local64[0] = a3->m_cop1->GetROI()->GetLocal2World()[3]; + local64[1] = a3->m_cop2->GetROI()->GetLocal2World()[3]; + local38 = GetROI()->GetLocal2World()[3]; + + local18 = local64[0]; + local18 -= local38; + local24[0] = local18.LenSquared(); + + local18 = local64[1]; + local18 -= local38; + local24[1] = local18.LenSquared(); + + if (local24[1] < local24[0]) { + local1c = 1; + } + + if (local24[local1c] < 225.0f) { + m_unk0x38 = 8; + + if (m_grec != NULL) { + delete m_grec; + m_grec = NULL; + } + + if (m_pInfo != NULL) { + m_pInfo = NULL; + } + + assert(m_boundary && m_destEdge && m_roi); + + LegoPathBoundary* boundaries[2]; + LegoUnknown100db7f4* maxE = NULL; + boundaries[0] = m_boundary; + + if (m_destEdge->FUN_10048c40(local38)) { + boundaries[1] = (LegoPathBoundary*) m_destEdge->OtherFace(m_boundary); + } + else { + boundaries[1] = NULL; + } + + float local78, local98; + for (MxS32 i = 0; i < (MxS32) sizeOfArray(boundaries); i++) { + if (boundaries[i] != NULL) { + for (MxS32 j = 0; j < boundaries[i]->GetNumEdges(); j++) { + LegoUnknown100db7f4* e = boundaries[i]->GetEdges()[j]; + + if (e->GetMask0x03()) { + Mx3DPointFloat local94(*e->GetPointA()); + local94 += *e->GetPointB(); + local94 /= 2.0f; + + local18 = local94; + local18 -= local64[local1c]; + local98 = local18.LenSquared(); + + local94 -= local38; + local18 = local64[local1c]; + local18 -= local38; + + if (maxE == NULL || (local18.Dot(&local94, &local18) < 0.0f && local78 < local98)) { + maxE = e; + m_boundary = boundaries[i]; + local78 = local98; + } + } + } + } + } + + assert(maxE); + m_destEdge = maxE; + + if (m_boundary != boundaries[0]) { + m_unk0xe4 = 1.0 - m_unk0xe4; + } + + VTable0x9c(); + } + return -1; } diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index b17f1508..887d19f7 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -920,68 +920,6 @@ MxResult LegoPathController::FUN_10048310( return FAILURE; } -// FUNCTION: LEGO1 0x10048c40 -// FUNCTION: BETA10 0x1001cc90 -inline MxU32 LegoPathCtrlEdge::FUN_10048c40(const Vector3& p_position) -{ - MxFloat localc, local10; - MxU32 result = FALSE; - - if (m_unk0x28[0] > 0.001 || m_unk0x28[0] < -0.001) { - localc = (p_position[0] - (*m_pointA)[0]) / m_unk0x28[0]; - - if (localc < 0 || localc > 1) { - return FALSE; - } - - result = TRUE; - } - else { - if (p_position[0] > (*m_pointA)[0] + 0.001 || p_position[0] < (*m_pointA)[0] - 0.001) { - return FALSE; - } - } - - if (m_unk0x28[1] > 0.001 || m_unk0x28[1] < -0.001) { - local10 = (p_position[1] - (*m_pointA)[1]) / m_unk0x28[1]; - - if (result) { - if (localc > local10 + 0.001 || localc < local10 - 0.001) { - return FALSE; - } - } - else { - result = TRUE; - localc = local10; - } - } - else { - if (p_position[1] > (*m_pointA)[1] + 0.001 || p_position[1] < (*m_pointA)[1] - 0.001) { - return FALSE; - } - } - - if (m_unk0x28[2] > 0.001 || m_unk0x28[2] < -0.001) { - local10 = (p_position[2] - (*m_pointA)[2]) / m_unk0x28[2]; - - if (result) { - if (localc > local10 + 0.001 || localc < local10 - 0.001) { - return FALSE; - } - } - else { - return TRUE; - } - } - else { - if (p_position[2] > (*m_pointA)[2] + 0.001 || p_position[2] < (*m_pointA)[2] - 0.001) { - return FALSE; - } - } - - return TRUE; -} - // FUNCTION: LEGO1 0x1004a240 // FUNCTION: BETA10 0x100b9160 MxS32 LegoPathController::FUN_1004a240( diff --git a/LEGO1/lego/sources/geom/legoedge.h b/LEGO1/lego/sources/geom/legoedge.h index 753d6e11..43740bda 100644 --- a/LEGO1/lego/sources/geom/legoedge.h +++ b/LEGO1/lego/sources/geom/legoedge.h @@ -19,6 +19,12 @@ struct LegoEdge { LegoResult FUN_1002ddc0(LegoWEEdge& p_face, Vector3& p_point); + // FUNCTION: BETA10 0x1001cb80 + Vector3* GetPointA() { return m_pointA; } + + // FUNCTION: BETA10 0x1001cbb0 + Vector3* GetPointB() { return m_pointB; } + // SYNTHETIC: LEGO1 0x1009a4a0 // LegoEdge::`scalar deleting destructor' diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index bd19ee78..ef525932 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -93,6 +93,8 @@ struct LegoUnknown100db7f4 : public LegoEdge { // FUNCTION: BETA10 0x1001cc60 LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } + inline LegoU32 FUN_10048c40(const Vector3& p_position); + // SYNTHETIC: LEGO1 0x1009a6c0 // LegoUnknown100db7f4::`scalar deleting destructor' @@ -101,4 +103,66 @@ struct LegoUnknown100db7f4 : public LegoEdge { float m_unk0x3c; // 0x3c }; +// FUNCTION: LEGO1 0x10048c40 +// FUNCTION: BETA10 0x1001cc90 +inline LegoU32 LegoUnknown100db7f4::FUN_10048c40(const Vector3& p_position) +{ + LegoFloat localc, local10; + LegoU32 result = FALSE; + + if (m_unk0x28[0] > 0.001 || m_unk0x28[0] < -0.001) { + localc = (p_position[0] - (*m_pointA)[0]) / m_unk0x28[0]; + + if (localc < 0 || localc > 1) { + return FALSE; + } + + result = TRUE; + } + else { + if (p_position[0] > (*m_pointA)[0] + 0.001 || p_position[0] < (*m_pointA)[0] - 0.001) { + return FALSE; + } + } + + if (m_unk0x28[1] > 0.001 || m_unk0x28[1] < -0.001) { + local10 = (p_position[1] - (*m_pointA)[1]) / m_unk0x28[1]; + + if (result) { + if (localc > local10 + 0.001 || localc < local10 - 0.001) { + return FALSE; + } + } + else { + result = TRUE; + localc = local10; + } + } + else { + if (p_position[1] > (*m_pointA)[1] + 0.001 || p_position[1] < (*m_pointA)[1] - 0.001) { + return FALSE; + } + } + + if (m_unk0x28[2] > 0.001 || m_unk0x28[2] < -0.001) { + local10 = (p_position[2] - (*m_pointA)[2]) / m_unk0x28[2]; + + if (result) { + if (localc > local10 + 0.001 || localc < local10 - 0.001) { + return FALSE; + } + } + else { + return TRUE; + } + } + else { + if (p_position[2] > (*m_pointA)[2] + 0.001 || p_position[2] < (*m_pointA)[2] - 0.001) { + return FALSE; + } + } + + return TRUE; +} + #endif // __LEGOUNKNOWN100DB7F4_H diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 1cfa82ac..99a44fd3 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -33,6 +33,9 @@ class Mx3DPointFloat : public Vector3 { // FUNCTION: LEGO1 0x10003c10 virtual void operator=(const Vector3& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x88 + // FUNCTION: BETA10 0x10015240 + // ??4Mx3DPointFloat@@QAEAAV0@ABV0@@Z + // FUNCTION: BETA10 0x10013460 float& operator[](int idx) { return m_data[idx]; } diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 02b8d53b..61931304 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -151,12 +151,9 @@ class Vector2 { virtual void SetVector(float* p_other) { EqualsImpl(p_other); } // vtable+0x70 // FUNCTION: LEGO1 0x10002260 + // FUNCTION: BETA10 0x100110c0 virtual void SetVector(const Vector2* p_other) { EqualsImpl(p_other->m_data); } // vtable+0x6c - // SYNTHETIC: LEGO1 0x10010be0 - // SYNTHETIC: BETA10 0x100121e0 - // Vector3::operator= - // SYNTHETIC: BETA10 0x1004af40 // Vector4::operator= @@ -307,6 +304,14 @@ class Vector3 : public Vector2 { return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]; } // vtable+0x40 + // FUNCTION: LEGO1 0x10010be0 + // FUNCTION: BETA10 0x100121e0 + Vector3& operator=(const Vector3& p_other) + { + Vector3::SetVector(&p_other); + return *this; + } + friend class Mx3DPointFloat; };