From ccf33575db364bc472cdea20ee2820a0e6cdb06b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 13 May 2024 08:39:43 -0400 Subject: [PATCH] Implement/match LegoPathController::FUN_10046050 (#916) --- .../lego/legoomni/include/legopathboundary.h | 17 ++++- .../legoomni/include/legopathcontroller.h | 3 + .../legoomni/src/paths/legopathcontroller.cpp | 67 ++++++++++++++++++- LEGO1/lego/sources/geom/legounkown100db7f4.h | 4 ++ LEGO1/mxgeometry/mxgeometry3d.h | 2 + 5 files changed, 89 insertions(+), 4 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h index 7ce0e200..7d300feb 100644 --- a/LEGO1/lego/legoomni/include/legopathboundary.h +++ b/LEGO1/lego/legoomni/include/legopathboundary.h @@ -15,7 +15,10 @@ struct LegoPathActorSetCompare { }; struct LegoAnimPresenterSetCompare { - MxBool operator()(const LegoAnimPresenter* p_lhs, const LegoAnimPresenter* p_rhs) const { return 0; } + MxBool operator()(const LegoAnimPresenter* p_lhs, const LegoAnimPresenter* p_rhs) const + { + return (MxS32) p_lhs < (MxS32) p_rhs; + } }; typedef set LegoPathActorSet; @@ -83,6 +86,18 @@ class LegoPathBoundary : public LegoWEGEdge { // TEMPLATE: LEGO1 0x10045dd0 // _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Insert +// TEMPLATE: LEGO1 0x10046310 +// _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::insert + +// TEMPLATE: LEGO1 0x10046580 +// _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Lrotate + +// TEMPLATE: LEGO1 0x100465e0 +// _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Rrotate + +// TEMPLATE: LEGO1 0x1004a7a0 +// _Construct + // GLOBAL: LEGO1 0x100f11a4 // _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Nil diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 23e6c740..aeb8c03c 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -142,6 +142,9 @@ class LegoPathController : public MxCore { // TEMPLATE: LEGO1 0x10045830 // set >::~set > +// TEMPLATE: LEGO1 0x10046640 +// _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::find + // TEMPLATE: LEGO1 0x100468c0 // _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Ubound diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 5e5d5451..bc692002 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -226,7 +226,7 @@ MxResult LegoPathController::FUN_10045c20( return SUCCESS; } -// STUB: LEGO1 0x10046050 +// FUNCTION: LEGO1 0x10046050 // FUNCTION: BETA10 0x100b6f35 MxResult LegoPathController::FUN_10046050( LegoPathActor* p_actor, @@ -235,8 +235,69 @@ MxResult LegoPathController::FUN_10046050( Vector3& p_direction ) { - // TODO - return SUCCESS; + LegoPathBoundary* boundary = NULL; + float time = Timer()->GetTime(); + + if (p_actor->GetController() != NULL) { + p_actor->GetController()->RemoveActor(p_actor); + p_actor->SetController(NULL); + } + + for (MxS32 i = 0; i < m_numL; i++) { + LegoPathBoundary& b = m_boundaries[i]; + LegoAnimPresenterSet& presenters = b.GetPresenters(); + LegoAnimPresenter* presenter = p_presenter; + + if (presenters.find(presenter) != presenters.end()) { + MxS32 j; + + for (j = 0; j < b.GetNumEdges(); j++) { + Mx4DPointFloat normal(*b.GetEdgeNormal(j)); + + if (p_position.Dot(&p_position, &normal) + normal[3] < 0.0f) { + break; + } + } + + if (b.GetNumEdges() == j) { + if (boundary != NULL) { + return FAILURE; + } + + boundary = &b; + } + } + } + + if (boundary == NULL) { + return FAILURE; + } + + for (MxS32 j = 0; j < boundary->GetNumEdges(); j++) { + LegoUnknown100db7f4* edge = (LegoUnknown100db7f4*) boundary->GetEdges()[j]; + + if (edge->GetMask0x03()) { + Mx3DPointFloat vec; + + if (((LegoUnknown100db7f4*) edge->GetClockwiseEdge(boundary))->FUN_1002ddc0(*boundary, vec) == SUCCESS && + vec.Dot(&vec, &p_direction) < 0.0f) { + edge = + (LegoUnknown100db7f4*) edge->GetCounterclockwiseEdge(boundary)->GetCounterclockwiseEdge(boundary); + } + + if (!edge->GetMask0x03()) { + return FAILURE; + } + + if (p_actor->VTable0x84(boundary, time, p_position, p_direction, *edge, 0.5f) == SUCCESS) { + p_actor->SetController(this); + m_actors.insert(p_actor); + return SUCCESS; + } + } + } + + return FAILURE; } // FUNCTION: LEGO1 0x100466a0 diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index be51e2d1..0a609d51 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -10,6 +10,8 @@ struct LegoUnknown100db7f4 : public LegoEdge { public: enum { + c_bit1 = 0x01, + c_bit2 = 0x02, c_bit3 = 0x04, c_bit4 = 0x08 }; @@ -32,6 +34,8 @@ struct LegoUnknown100db7f4 : public LegoEdge { return SUCCESS; } + LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } + // SYNTHETIC: LEGO1 0x1009a6c0 // LegoUnknown100db7f4::`scalar deleting destructor' diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 2fc02932..a214e25a 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -57,6 +57,8 @@ class Mx4DPointFloat : public Vector4 { m_elements[3] = p_a; } + inline Mx4DPointFloat(const Mx4DPointFloat& p_other) : Vector4(m_elements) { EqualsImpl(p_other.m_data); } + // FUNCTION: LEGO1 0x10003200 virtual void operator=(const Vector4& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x98