diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index 897d0615..e830b289 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -11,10 +11,10 @@ class Act2Actor : public LegoAnimActor { public: struct UnknownListStructure { - MxFloat m_unk0x00[3]; // 0x00 - MxFloat m_unk0x0c[3]; // 0x0c - const char* m_unk0x18; // 0x18 - undefined m_unk0x1c; // 0x1c + MxFloat m_position[3]; // 0x00 + MxFloat m_direction[3]; // 0x0c + const char* m_boundary; // 0x18 + undefined m_unk0x1c; // 0x1c }; Act2Actor(); diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 10185666..17ad51e3 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -119,13 +119,13 @@ class LegoPathController : public MxCore { ); MxResult FUN_10048310( LegoPathEdgeContainer* p_grec, - const Vector3& p_position, - const Vector3& p_direction, - LegoPathBoundary* p_boundary1, - const Vector3& p_param5, - const Vector3& p_param6, - LegoPathBoundary* p_boundary2, - MxBool p_param8, + const Vector3& p_oldPosition, + const Vector3& p_oldDirection, + LegoPathBoundary* p_oldBoundary, + const Vector3& p_newPosition, + const Vector3& p_newDirection, + LegoPathBoundary* p_newBoundary, + LegoU8 p_mask, MxFloat* p_param9 ); diff --git a/LEGO1/lego/legoomni/include/legopathedgecontainer.h b/LEGO1/lego/legoomni/include/legopathedgecontainer.h index c133122c..a88d7cab 100644 --- a/LEGO1/lego/legoomni/include/legopathedgecontainer.h +++ b/LEGO1/lego/legoomni/include/legopathedgecontainer.h @@ -6,10 +6,20 @@ #include "mxtypes.h" class LegoPathBoundary; +struct LegoPathCtrlEdge; struct LegoUnknown100db7f4; // SIZE 0x08 struct LegoBoundaryEdge { + LegoBoundaryEdge() {} + + // FUNCTION: BETA10 0x100bd620 + LegoBoundaryEdge(LegoUnknown100db7f4* p_edge, LegoPathBoundary* p_boundary) + { + m_edge = p_edge; + m_boundary = p_boundary; + } + LegoUnknown100db7f4* m_edge; // 0x00 LegoPathBoundary* m_boundary; // 0x04 @@ -17,6 +27,44 @@ struct LegoBoundaryEdge { int operator<(LegoBoundaryEdge) const { return 0; } }; +// SIZE 0x10 +struct LegoBoundaryEdgeWithFloat { + LegoBoundaryEdgeWithFloat() + { + m_edge = NULL; + m_boundary = NULL; + m_unk0x08 = 0; + m_unk0x0c = 0.0f; + } + + // FUNCTION: BETA10 0x100bd9a0 + LegoBoundaryEdgeWithFloat(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary, MxFloat p_unk0x0c) + { + m_edge = p_edge; + m_boundary = p_boundary; + m_unk0x08 = 0; + m_unk0x0c = p_unk0x0c; + } + + LegoPathCtrlEdge* m_edge; // 0x00 + LegoPathBoundary* m_boundary; // 0x04 + undefined4 m_unk0x08; // 0x08 + MxFloat m_unk0x0c; // 0x0c + + int operator==(LegoBoundaryEdgeWithFloat) const { return 0; } + int operator<(LegoBoundaryEdgeWithFloat) const { return 0; } +}; + +struct LegoBoundaryEdgeWithFloatComparator { + // FUNCTION: BETA10 0x100bef80 + bool operator()(LegoBoundaryEdgeWithFloat* const& p_a, LegoBoundaryEdgeWithFloat* const& p_b) const + { + return p_a->m_unk0x0c < p_b->m_unk0x0c; + } +}; + +typedef multiset LegoBoundaryEdgeWithFloatSet; + // SIZE 0x3c struct LegoPathEdgeContainer : public list { enum { @@ -30,9 +78,10 @@ struct LegoPathEdgeContainer : public list { m_flags = 0; } - void SetBit1(MxU32 p_flag) + // FUNCTION: BETA10 0x100bd660 + void SetBit1(MxU32 p_bool) { - if (p_flag) { + if (p_bool) { m_flags |= c_bit1; } else { @@ -40,10 +89,11 @@ struct LegoPathEdgeContainer : public list { } } + // FUNCTION: BETA10 0x1001cb50 MxU32 GetBit1() { return m_flags & c_bit1; } - Mx3DPointFloat m_unk0x0c; // 0x0c - Mx3DPointFloat m_unk0x20; // 0x20 + Mx3DPointFloat m_position; // 0x0c + Mx3DPointFloat m_direction; // 0x20 LegoPathBoundary* m_boundary; // 0x34 MxU8 m_flags; // 0x38 }; diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 1bb3e335..b97c08bc 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -134,8 +134,8 @@ void Act2Actor::SetWorldSpeed(MxFloat p_worldSpeed) // FUNCTION: BETA10 0x1000d4d6 void Act2Actor::FUN_100192a0(undefined4 p_param) { - Mx3DPointFloat local38(0.0, 0.0, 0.0); - Mx3DPointFloat local4c(0.0, 0.0, 0.0); + Mx3DPointFloat newPosition(0.0, 0.0, 0.0); + Mx3DPointFloat newDirection(0.0, 0.0, 0.0); if (m_grec) { delete m_grec; @@ -144,26 +144,25 @@ void Act2Actor::FUN_100192a0(undefined4 p_param) m_grec = new LegoPathEdgeContainer(); assert(m_grec); - local38 = g_unk0x100f0db8[p_param].m_unk0x00; - local4c = g_unk0x100f0db8[p_param].m_unk0x0c; - - LegoPathBoundary* otherBoundary = m_controller->GetPathBoundary(g_unk0x100f0db8[p_param].m_unk0x18); + newPosition = g_unk0x100f0db8[p_param].m_position; + newDirection = g_unk0x100f0db8[p_param].m_direction; + LegoPathBoundary* newBoundary = m_controller->GetPathBoundary(g_unk0x100f0db8[p_param].m_boundary); MxResult sts = m_controller->FUN_10048310( m_grec, m_roi->GetWorldPosition(), m_roi->GetWorldDirection(), m_boundary, - local38, - local4c, - otherBoundary, - TRUE, + newPosition, + newDirection, + newBoundary, + LegoUnknown100db7f4::c_bit1, NULL ); - assert(!sts); + assert(!sts); // == SUCCESS - if (sts) { + if (sts != SUCCESS) { delete m_grec; m_grec = NULL; } diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index e034db98..a7d6796b 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -733,21 +733,129 @@ MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx4DPointFloat& return SUCCESS; } -// STUB: LEGO1 0x10048310 -// STUB: BETA10 0x100b8911 +// FUNCTION: LEGO1 0x10048310 +// FUNCTION: BETA10 0x100b8911 MxResult LegoPathController::FUN_10048310( LegoPathEdgeContainer* p_grec, - const Vector3& p_position, - const Vector3& p_direction, - LegoPathBoundary* p_boundary1, - const Vector3& p_param5, - const Vector3& p_param6, - LegoPathBoundary* p_boundary2, - MxBool p_param8, + const Vector3& p_oldPosition, + const Vector3& p_oldDirection, + LegoPathBoundary* p_oldBoundary, + const Vector3& p_newPosition, + const Vector3& p_newDirection, + LegoPathBoundary* p_newBoundary, + LegoU8 p_mask, MxFloat* p_param9 ) { - // TODO + p_grec->m_position = p_newPosition; + p_grec->m_direction = p_newDirection; + p_grec->m_boundary = p_newBoundary; + + if (p_newBoundary == p_oldBoundary) { + p_grec->SetBit1(TRUE); + } + else { + list boundaryList; + list::iterator boundaryListIt; + + LegoBoundaryEdgeWithFloatSet boundarySet; + LegoBoundaryEdgeWithFloatSet::iterator boundarySetItA; + LegoBoundaryEdgeWithFloatSet::iterator boundarySetItB; + + LegoPathCtrlEdgeSet pathCtrlEdgeSet(m_pfsE); + + MxFloat local14 = 999999.0f; + + p_grec->SetBit1(FALSE); + + for (MxS32 i = 0; i < p_oldBoundary->GetNumEdges(); i++) { + LegoPathCtrlEdge* edge = (LegoPathCtrlEdge*) p_oldBoundary->GetEdges()[i]; + + if (edge->GetMask0x03()) { + LegoPathBoundary* otherFace = (LegoPathBoundary*) edge->OtherFace(p_oldBoundary); + + if (otherFace != NULL && edge->Unknown(*otherFace, p_mask)) { + if (p_newBoundary == otherFace) { + float dist = edge->DistanceToMidpoint(p_oldPosition) + edge->DistanceToMidpoint(p_newPosition); + + if (dist < local14) { + local14 = dist; + p_grec->erase(p_grec->begin(), p_grec->end()); + p_grec->SetBit1(TRUE); + p_grec->push_back(LegoBoundaryEdge(edge, p_oldBoundary)); + } + } + else { + boundaryList.push_back( + LegoBoundaryEdgeWithFloat(edge, p_oldBoundary, edge->DistanceToMidpoint(p_oldPosition)) + ); + boundarySet.insert(&boundaryList.back()); + } + } + } + + pathCtrlEdgeSet.erase(edge); + } + + if (!p_grec->GetBit1()) { + while (pathCtrlEdgeSet.size() != 0) { + LegoBoundaryEdgeWithFloat edgeWithFloat; + MxFloat local70 = 999999.0f; + + boundarySetItA = boundarySetItB = boundarySet.begin(); + + if (boundarySetItB != boundarySet.end()) { + boundarySetItB++; + } + + while (boundarySetItA != boundarySet.end()) { + MxU32 shouldRemove = TRUE; + + LegoUnknown100db7f4* e = (*boundarySetItA)->m_edge; + LegoPathBoundary* b = (*boundarySetItA)->m_boundary; + assert(e && b); + + LegoPathBoundary* bOther = (LegoPathBoundary*) e->OtherFace(b); + assert(bOther); + + if (e->Unknown(*bOther, p_mask)) { + if (bOther == p_newBoundary) { + // TODO + } + else { + // TODO + } + } + + if (shouldRemove) { + boundarySet.erase(boundarySetItA); + } + + if (boundarySetItB == boundarySet.end()) { + break; + } + + boundarySetItA = boundarySetItB; + boundarySetItB++; + } + + if (edgeWithFloat.m_edge == NULL) { + break; + } + + pathCtrlEdgeSet.erase(edgeWithFloat.m_edge); + boundaryList.push_back(edgeWithFloat); + boundarySet.insert(&boundaryList.back()); + } + } + + if (!p_grec->GetBit1()) { + return FAILURE; + } + + // TODO + } + return SUCCESS; } @@ -763,8 +871,8 @@ MxS32 LegoPathController::FUN_1004a240( ) { if (p_grec.size() == 0) { - p_v1 = p_grec.m_unk0x0c; - p_v2 = p_grec.m_unk0x20; + p_v1 = p_grec.m_position; + p_v2 = p_grec.m_direction; p_boundary = p_grec.m_boundary; p_grec.SetBit1(FALSE); return 1; diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index ae877b58..a4ff0822 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -64,6 +64,17 @@ struct LegoUnknown100db7f4 : public LegoEdge { } } + // FUNCTION: BETA10 0x100bd4a0 + LegoFloat DistanceToMidpoint(const Vector3& p_vec) + { + Mx3DPointFloat point(*m_pointA); + ((Vector3&) point).Add(*m_pointB); + ((Vector3&) point).Mul(0.5f); + ((Vector3&) point).Sub(p_vec); + return sqrt(point.LenSquared()); + } + + // FUNCTION: BETA10 0x1001cc60 LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } // SYNTHETIC: LEGO1 0x1009a6c0 diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 8f871474..0e9ebed0 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -286,6 +286,7 @@ class Vector3 : public Vector2 { void Clear() override { memset(m_data, 0, sizeof(float) * 3); } // vtable+0x2c // FUNCTION: LEGO1 0x10003bd0 + // FUNCTION: BETA10 0x10011530 float LenSquared() const override { return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2];