Clear unknowns in LegoPathController (#1724)
Some checks are pending
Analyze / ${{ matrix.who }} annotations (CONFIG) (push) Waiting to run
Analyze / ${{ matrix.who }} annotations (ISLE) (push) Waiting to run
Analyze / ${{ matrix.who }} annotations (LEGO1) (push) Waiting to run
Build / Download original binaries (push) Waiting to run
Build / Current ${{ matrix.toolchain.name }} (map[clang-tidy:true msys-env:mingw-w64-i686 msystem:mingw32 name:msys2 mingw32 shell:msys2 {0} werror:true]) (push) Waiting to run
Build / Current ${{ matrix.toolchain.name }} (map[name:MSVC setup-cmake:true setup-msvc:true setup-ninja:true shell:sh]) (push) Waiting to run
Build / MSVC 4.20 (push) Waiting to run
Build / MSVC 4.20 (BETA10) (push) Waiting to run
Build / Verify decomp (push) Blocked by required conditions
Build / Upload artifacts (push) Blocked by required conditions
Format / C++ (push) Waiting to run
Naming / C++ (push) Waiting to run

This commit is contained in:
Fabian Neundorf 2026-01-18 21:31:56 +01:00 committed by GitHub
parent 01c92d1966
commit e05cb05983
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 116 additions and 115 deletions

View File

@ -104,13 +104,13 @@ class LegoPathController : public MxCore {
); );
MxResult PlaceActor(LegoPathActor* p_actor); MxResult PlaceActor(LegoPathActor* p_actor);
MxResult RemoveActor(LegoPathActor* p_actor); MxResult RemoveActor(LegoPathActor* p_actor);
void FUN_100468f0(LegoAnimPresenter* p_presenter); void AddPresenterIfInRange(LegoAnimPresenter* p_presenter);
void RemovePresenterFromBoundaries(LegoAnimPresenter* p_presenter); void RemovePresenterFromBoundaries(LegoAnimPresenter* p_presenter);
MxResult FUN_10046b30(LegoPathBoundary*& p_boundaries, MxS32& p_numL); MxResult GetBoundaries(LegoPathBoundary*& p_boundaries, MxS32& p_numL);
LegoPathBoundary* GetPathBoundary(const char* p_name); LegoPathBoundary* GetPathBoundary(const char* p_name);
void Enable(MxBool p_enable); void Enable(MxBool p_enable);
void FUN_10046bb0(LegoWorld* p_world); void SetWorld(LegoWorld* p_world);
MxResult FUN_10048310( MxResult FindPath(
LegoPathEdgeContainer* p_grec, LegoPathEdgeContainer* p_grec,
const Vector3& p_oldPosition, const Vector3& p_oldPosition,
const Vector3& p_oldDirection, const Vector3& p_oldDirection,
@ -119,17 +119,17 @@ class LegoPathController : public MxCore {
const Vector3& p_newDirection, const Vector3& p_newDirection,
LegoPathBoundary* p_newBoundary, LegoPathBoundary* p_newBoundary,
LegoU8 p_mask, LegoU8 p_mask,
MxFloat* p_param9 MxFloat* p_distance
); );
MxS32 FUN_1004a240( MxS32 GetNextPathEdge(
LegoPathEdgeContainer& p_grec, LegoPathEdgeContainer& p_grec,
Vector3& p_v1, Vector3& p_position,
Vector3& p_v2, Vector3& p_direction,
float p_f1, float p_f1,
LegoOrientedEdge*& p_edge, LegoOrientedEdge*& p_edge,
LegoPathBoundary*& p_boundary LegoPathBoundary*& p_boundary
); );
MxResult FUN_1004a380( MxResult FindIntersectionBoundary(
Vector3& p_param1, Vector3& p_param1,
Vector3& p_param2, Vector3& p_param2,
Mx3DPointFloat* p_param3, Mx3DPointFloat* p_param3,
@ -154,7 +154,7 @@ class LegoPathController : public MxCore {
static LegoPathBoundary* GetControlBoundaryB(MxS32 p_index) { return g_ctrlBoundariesB[p_index].m_boundary; } static LegoPathBoundary* GetControlBoundaryB(MxS32 p_index) { return g_ctrlBoundariesB[p_index].m_boundary; }
private: private:
void FUN_10046970(); void AnimateActors();
MxResult Read(LegoStorage* p_storage); MxResult Read(LegoStorage* p_storage);
MxResult ReadStructs(LegoStorage* p_storage); MxResult ReadStructs(LegoStorage* p_storage);
MxResult ReadEdges(LegoStorage* p_storage); MxResult ReadEdges(LegoStorage* p_storage);
@ -174,7 +174,7 @@ class LegoPathController : public MxCore {
} }
// FUNCTION: BETA10 0x100c17a0 // FUNCTION: BETA10 0x100c17a0
static MxU32 FUN_100c17a0(MxFloat p_v1, MxFloat p_v2, MxFloat p_a, MxFloat p_b) static MxU32 BothSameComparison(MxFloat p_v1, MxFloat p_v2, MxFloat p_a, MxFloat p_b)
{ {
assert(IsBetween(p_v1, p_a, p_b)); assert(IsBetween(p_v1, p_a, p_b));
assert(IsBetween(p_v2, p_a, p_b)); assert(IsBetween(p_v2, p_a, p_b));
@ -202,8 +202,8 @@ class LegoPathController : public MxCore {
static CtrlBoundary* g_ctrlBoundariesA; static CtrlBoundary* g_ctrlBoundariesA;
static CtrlEdge* g_ctrlEdgesA; static CtrlEdge* g_ctrlEdgesA;
static const char* g_unk0x100f42f0[]; static const char* g_ctrlBoundariesNamesA[];
static const char* g_unk0x100f4330[]; static const char* g_ctrlBoundariesNamesB[];
static CtrlBoundary* g_ctrlBoundariesB; static CtrlBoundary* g_ctrlBoundariesB;
static CtrlEdge* g_ctrlEdgesB; static CtrlEdge* g_ctrlEdgesB;
}; };

View File

@ -410,7 +410,7 @@ void Act2Actor::FindPath(MxU32 p_location)
newDirection = g_brickstrLocations[p_location].m_direction; newDirection = g_brickstrLocations[p_location].m_direction;
LegoPathBoundary* newBoundary = m_pathController->GetPathBoundary(g_brickstrLocations[p_location].m_boundary); LegoPathBoundary* newBoundary = m_pathController->GetPathBoundary(g_brickstrLocations[p_location].m_boundary);
MxResult sts = m_pathController->FUN_10048310( MxResult sts = m_pathController->FindPath(
m_grec, m_grec,
m_roi->GetWorldPosition(), m_roi->GetWorldPosition(),
m_roi->GetWorldDirection(), m_roi->GetWorldDirection(),

View File

@ -345,7 +345,7 @@ MxResult Act3Cop::FUN_10040360()
assert(grec); assert(grec);
MxFloat local34; MxFloat local34;
if (m_pathController->FUN_10048310( if (m_pathController->FindPath(
grec, grec,
local2c, local2c,
local20, local20,
@ -383,7 +383,7 @@ MxResult Act3Cop::FUN_10040360()
MxFloat locald8; MxFloat locald8;
LegoPathEdgeContainer *local138, *local134, *local140, *local13c; // unused LegoPathEdgeContainer *local138, *local134, *local140, *local13c; // unused
if (m_pathController->FUN_10048310( if (m_pathController->FindPath(
r2, r2,
local2c, local2c,
local20, local20,
@ -423,7 +423,7 @@ MxResult Act3Cop::FUN_10040360()
MxFloat local100; MxFloat local100;
LegoPathEdgeContainer *local150, *local14c; // unused LegoPathEdgeContainer *local150, *local14c; // unused
if (m_pathController->FUN_10048310( if (m_pathController->FindPath(
grec, grec,
local2c, local2c,
local20, local20,
@ -823,7 +823,7 @@ MxResult Act3Brickster::FUN_100417c0()
MxFloat locald8; MxFloat locald8;
LegoPathEdgeContainer *local16c, *local168, *local174, *local170; // unused LegoPathEdgeContainer *local16c, *local168, *local174, *local170; // unused
if (m_pathController->FUN_10048310( if (m_pathController->FindPath(
r2, r2,
local28, local28,
local20, local20,
@ -907,7 +907,7 @@ MxResult Act3Brickster::FUN_100417c0()
MxFloat local13c; MxFloat local13c;
LegoPathEdgeContainer *local1c0, *local1bc; // unused LegoPathEdgeContainer *local1c0, *local1bc; // unused
if (m_pathController->FUN_10048310( if (m_pathController->FindPath(
grec, grec,
local28, local28,
local20, local20,

View File

@ -358,7 +358,7 @@ void LegoWorld::AddPresenterIfInRange(LegoAnimPresenter* p_presenter)
LegoPathController* controller; LegoPathController* controller;
while (cursor.Next(controller)) { while (cursor.Next(controller)) {
controller->FUN_100468f0(p_presenter); controller->AddPresenterIfInRange(p_presenter);
} }
} }
@ -377,7 +377,7 @@ void LegoWorld::RemovePresenterFromBoundaries(LegoAnimPresenter* p_presenter)
// FUNCTION: LEGO1 0x1001ff80 // FUNCTION: LEGO1 0x1001ff80
void LegoWorld::AddPath(LegoPathController* p_controller) void LegoWorld::AddPath(LegoPathController* p_controller)
{ {
p_controller->FUN_10046bb0(this); p_controller->SetWorld(this);
m_pathControllerList.Append(p_controller); m_pathControllerList.Append(p_controller);
} }
@ -411,7 +411,7 @@ MxResult LegoWorld::GetCurrPathInfo(LegoPathBoundary** p_boundaries, MxS32& p_nu
return FAILURE; return FAILURE;
} }
return controller->FUN_10046b30(*p_boundaries, p_numL); return controller->GetBoundaries(*p_boundaries, p_numL);
} }
// FUNCTION: LEGO1 0x10020220 // FUNCTION: LEGO1 0x10020220

View File

@ -635,7 +635,7 @@ MxResult LegoPathActor::VTable0x9c()
local20 = 0; local20 = 0;
Mx3DPointFloat vec; Mx3DPointFloat vec;
switch (m_pathController->FUN_1004a240(*m_grec, local34, local48, m_unk0xe4, m_destEdge, m_boundary)) { switch (m_pathController->GetNextPathEdge(*m_grec, local34, local48, m_unk0xe4, m_destEdge, m_boundary)) {
case 0: case 0:
case 1: case 1:
break; break;

View File

@ -12,10 +12,10 @@ DECOMP_SIZE_ASSERT(LegoPathController::CtrlBoundary, 0x08)
DECOMP_SIZE_ASSERT(LegoPathController::CtrlEdge, 0x08) DECOMP_SIZE_ASSERT(LegoPathController::CtrlEdge, 0x08)
// GLOBAL: LEGO1 0x100d7cc8 // GLOBAL: LEGO1 0x100d7cc8
MxU32 g_unk0x100d7cc8[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0}; MxU32 g_ctrlEdgesNamesA[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0};
// GLOBAL: LEGO1 0x100d7d08 // GLOBAL: LEGO1 0x100d7d08
MxU32 g_unk0x100d7d08[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; MxU32 g_ctrlEdgesNamesB[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// GLOBAL: LEGO1 0x100f42e8 // GLOBAL: LEGO1 0x100f42e8
// GLOBAL: BETA10 0x101f25f0 // GLOBAL: BETA10 0x101f25f0
@ -26,7 +26,7 @@ LegoPathController::CtrlBoundary* LegoPathController::g_ctrlBoundariesA = NULL;
LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesA = NULL; LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesA = NULL;
// GLOBAL: LEGO1 0x100f42f0 // GLOBAL: LEGO1 0x100f42f0
const char* LegoPathController::g_unk0x100f42f0[] = { const char* LegoPathController::g_ctrlBoundariesNamesA[] = {
"edg03_21", "edg03_21",
"edg03_23", "edg03_23",
"edg03_30", "edg03_30",
@ -46,7 +46,7 @@ const char* LegoPathController::g_unk0x100f42f0[] = {
}; };
// GLOBAL: LEGO1 0x100f4330 // GLOBAL: LEGO1 0x100f4330
const char* LegoPathController::g_unk0x100f4330[] = { const char* LegoPathController::g_ctrlBoundariesNamesB[] = {
"edg03_06", "edg03_06",
"edg03_21", "edg03_21",
"edg03_30", "edg03_30",
@ -101,23 +101,23 @@ MxResult LegoPathController::Create(MxU8* p_data, const Vector3& p_location, con
LegoPathBoundary& boundary = m_boundaries[i]; LegoPathBoundary& boundary = m_boundaries[i];
MxS32 j; MxS32 j;
for (j = 0; j < sizeOfArray(g_unk0x100f42f0); j++) { for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesA); j++) {
if (!strcmpi(g_unk0x100f42f0[j], boundary.GetName())) { if (!strcmpi(g_ctrlBoundariesNamesA[j], boundary.GetName())) {
g_ctrlBoundariesA[j].m_controller = this; g_ctrlBoundariesA[j].m_controller = this;
g_ctrlBoundariesA[j].m_boundary = &boundary; g_ctrlBoundariesA[j].m_boundary = &boundary;
MxU32 edge = g_unk0x100d7cc8[j]; MxU32 edge = g_ctrlEdgesNamesA[j];
g_ctrlEdgesA[j].m_controller = this; g_ctrlEdgesA[j].m_controller = this;
g_ctrlEdgesA[j].m_edge = boundary.GetEdges()[edge]; g_ctrlEdgesA[j].m_edge = boundary.GetEdges()[edge];
} }
} }
for (j = 0; j < sizeOfArray(g_unk0x100f4330); j++) { for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesB); j++) {
if (!strcmpi(g_unk0x100f4330[j], boundary.GetName())) { if (!strcmpi(g_ctrlBoundariesNamesB[j], boundary.GetName())) {
g_ctrlBoundariesB[j].m_controller = this; g_ctrlBoundariesB[j].m_controller = this;
g_ctrlBoundariesB[j].m_boundary = &boundary; g_ctrlBoundariesB[j].m_boundary = &boundary;
g_ctrlEdgesB[j].m_controller = this; g_ctrlEdgesB[j].m_controller = this;
g_ctrlEdgesB[j].m_edge = boundary.GetEdges()[g_unk0x100d7d08[j]]; g_ctrlEdgesB[j].m_edge = boundary.GetEdges()[g_ctrlEdgesNamesB[j]];
} }
} }
} }
@ -163,7 +163,7 @@ void LegoPathController::Destroy()
m_numE = 0; m_numE = 0;
MxS32 j; MxS32 j;
for (j = 0; j < sizeOfArray(g_unk0x100f42f0); j++) { for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesA); j++) {
if (g_ctrlBoundariesA[j].m_controller == this) { if (g_ctrlBoundariesA[j].m_controller == this) {
g_ctrlBoundariesA[j].m_controller = NULL; g_ctrlBoundariesA[j].m_controller = NULL;
g_ctrlBoundariesA[j].m_boundary = NULL; g_ctrlBoundariesA[j].m_boundary = NULL;
@ -175,7 +175,7 @@ void LegoPathController::Destroy()
} }
} }
for (j = 0; j < sizeOfArray(g_unk0x100f4330); j++) { for (j = 0; j < sizeOfArray(g_ctrlBoundariesNamesB); j++) {
if (g_ctrlBoundariesB[j].m_controller == this) { if (g_ctrlBoundariesB[j].m_controller == this) {
g_ctrlBoundariesB[j].m_controller = NULL; g_ctrlBoundariesB[j].m_controller = NULL;
g_ctrlBoundariesB[j].m_boundary = NULL; g_ctrlBoundariesB[j].m_boundary = NULL;
@ -192,7 +192,7 @@ void LegoPathController::Destroy()
// FUNCTION: BETA10 0x100b6d60 // FUNCTION: BETA10 0x100b6d60
MxResult LegoPathController::Tickle() MxResult LegoPathController::Tickle()
{ {
FUN_10046970(); AnimateActors();
return SUCCESS; return SUCCESS;
} }
@ -343,7 +343,7 @@ MxResult LegoPathController::RemoveActor(LegoPathActor* p_actor)
// FUNCTION: LEGO1 0x100468f0 // FUNCTION: LEGO1 0x100468f0
// FUNCTION: BETA10 0x100b72f7 // FUNCTION: BETA10 0x100b72f7
void LegoPathController::FUN_100468f0(LegoAnimPresenter* p_presenter) void LegoPathController::AddPresenterIfInRange(LegoAnimPresenter* p_presenter)
{ {
for (MxS32 i = 0; i < m_numL; i++) { for (MxS32 i = 0; i < m_numL; i++) {
if (!(m_boundaries[i].m_flags & LegoWEGEdge::c_bit3)) { if (!(m_boundaries[i].m_flags & LegoWEGEdge::c_bit3)) {
@ -363,7 +363,7 @@ void LegoPathController::RemovePresenterFromBoundaries(LegoAnimPresenter* p_pres
// FUNCTION: LEGO1 0x10046970 // FUNCTION: LEGO1 0x10046970
// FUNCTION: BETA10 0x100b73d8 // FUNCTION: BETA10 0x100b73d8
void LegoPathController::FUN_10046970() void LegoPathController::AnimateActors()
{ {
float time = Timer()->GetTime(); float time = Timer()->GetTime();
@ -381,7 +381,7 @@ void LegoPathController::FUN_10046970()
} }
// FUNCTION: LEGO1 0x10046b30 // FUNCTION: LEGO1 0x10046b30
MxResult LegoPathController::FUN_10046b30(LegoPathBoundary*& p_boundaries, MxS32& p_numL) MxResult LegoPathController::GetBoundaries(LegoPathBoundary*& p_boundaries, MxS32& p_numL)
{ {
p_boundaries = m_boundaries; p_boundaries = m_boundaries;
p_numL = m_numL; p_numL = m_numL;
@ -403,7 +403,7 @@ LegoPathBoundary* LegoPathController::GetPathBoundary(const char* p_name)
// FUNCTION: LEGO1 0x10046bb0 // FUNCTION: LEGO1 0x10046bb0
// FUNCTION: BETA10 0x100b75bc // FUNCTION: BETA10 0x100b75bc
void LegoPathController::FUN_10046bb0(LegoWorld* p_world) void LegoPathController::SetWorld(LegoWorld* p_world)
{ {
for (MxS32 i = 0; i < m_numT; i++) { for (MxS32 i = 0; i < m_numT; i++) {
m_structs[i].SetWorld(p_world); m_structs[i].SetWorld(p_world);
@ -430,10 +430,10 @@ MxResult LegoPathController::Init()
return FAILURE; return FAILURE;
} }
g_ctrlBoundariesA = new CtrlBoundary[sizeOfArray(g_unk0x100f42f0)]; g_ctrlBoundariesA = new CtrlBoundary[sizeOfArray(g_ctrlBoundariesNamesA)];
g_ctrlEdgesA = new CtrlEdge[sizeOfArray(g_unk0x100f42f0)]; g_ctrlEdgesA = new CtrlEdge[sizeOfArray(g_ctrlBoundariesNamesA)];
g_ctrlBoundariesB = new CtrlBoundary[sizeOfArray(g_unk0x100f4330)]; g_ctrlBoundariesB = new CtrlBoundary[sizeOfArray(g_ctrlBoundariesNamesB)];
g_ctrlEdgesB = new CtrlEdge[sizeOfArray(g_unk0x100f4330)]; g_ctrlEdgesB = new CtrlEdge[sizeOfArray(g_ctrlBoundariesNamesB)];
return SUCCESS; return SUCCESS;
} }
@ -758,7 +758,7 @@ MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx4DPointFloat&
// FUNCTION: LEGO1 0x10048310 // FUNCTION: LEGO1 0x10048310
// FUNCTION: BETA10 0x100b8911 // FUNCTION: BETA10 0x100b8911
MxResult LegoPathController::FUN_10048310( MxResult LegoPathController::FindPath(
LegoPathEdgeContainer* p_grec, LegoPathEdgeContainer* p_grec,
const Vector3& p_oldPosition, const Vector3& p_oldPosition,
const Vector3& p_oldDirection, const Vector3& p_oldDirection,
@ -767,7 +767,7 @@ MxResult LegoPathController::FUN_10048310(
const Vector3& p_newDirection, const Vector3& p_newDirection,
LegoPathBoundary* p_newBoundary, LegoPathBoundary* p_newBoundary,
LegoU8 p_mask, LegoU8 p_mask,
MxFloat* p_param9 MxFloat* p_distance
) )
{ {
p_grec->m_position = p_newPosition; p_grec->m_position = p_newPosition;
@ -788,7 +788,7 @@ MxResult LegoPathController::FUN_10048310(
LegoPathCtrlEdgeSet pathCtrlEdgeSet(m_pfsE); LegoPathCtrlEdgeSet pathCtrlEdgeSet(m_pfsE);
MxFloat local14 = 999999.0f; MxFloat minDistance = 999999.0f;
p_grec->SetPath(FALSE); p_grec->SetPath(FALSE);
@ -802,8 +802,8 @@ MxResult LegoPathController::FUN_10048310(
if (p_newBoundary == otherFace) { if (p_newBoundary == otherFace) {
float dist; float dist;
if ((dist = edge->DistanceToMidpoint(p_oldPosition) + edge->DistanceToMidpoint(p_newPosition)) < if ((dist = edge->DistanceToMidpoint(p_oldPosition) + edge->DistanceToMidpoint(p_newPosition)) <
local14) { minDistance) {
local14 = dist; minDistance = dist;
p_grec->erase(p_grec->begin(), p_grec->end()); p_grec->erase(p_grec->begin(), p_grec->end());
p_grec->SetPath(TRUE); p_grec->SetPath(TRUE);
p_grec->push_back(LegoBoundaryEdge(edge, p_oldBoundary)); p_grec->push_back(LegoBoundaryEdge(edge, p_oldBoundary));
@ -823,8 +823,8 @@ MxResult LegoPathController::FUN_10048310(
if (!p_grec->HasPath()) { if (!p_grec->HasPath()) {
while (pathCtrlEdgeSet.size() > 0) { while (pathCtrlEdgeSet.size() > 0) {
LegoBEWithMidpoint edgeWithFloat; LegoBEWithMidpoint edgeWithMidpoint;
MxFloat local70 = 999999.0f; MxFloat minDist = 999999.0f;
boundarySetItA = boundarySetItB = boundarySet.begin(); boundarySetItA = boundarySetItB = boundarySet.begin();
@ -854,13 +854,13 @@ MxResult LegoPathController::FUN_10048310(
float dist; float dist;
if ((dist = pfs->m_edge->DistanceToMidpoint(p_newPosition) + pfs->m_distanceToMidpoint) < if ((dist = pfs->m_edge->DistanceToMidpoint(p_newPosition) + pfs->m_distanceToMidpoint) <
local70) { minDist) {
edgeWithFloat.m_edge = NULL; edgeWithMidpoint.m_edge = NULL;
local70 = dist; minDist = dist;
// TODO: Match // TODO: Match
if (dist < local14) { if (dist < minDistance) {
local14 = dist; minDistance = dist;
p_grec->erase(p_grec->begin(), p_grec->end()); p_grec->erase(p_grec->begin(), p_grec->end());
p_grec->SetPath(TRUE); p_grec->SetPath(TRUE);
@ -881,9 +881,9 @@ MxResult LegoPathController::FUN_10048310(
float dist; float dist;
if ((dist = edge->DistanceBetweenMidpoints(*e) + if ((dist = edge->DistanceBetweenMidpoints(*e) +
(*boundarySetItA)->m_distanceToMidpoint) < local70) { (*boundarySetItA)->m_distanceToMidpoint) < minDist) {
local70 = dist; minDist = dist;
edgeWithFloat = LegoBEWithMidpoint(edge, bOther, *boundarySetItA, dist); edgeWithMidpoint = LegoBEWithMidpoint(edge, bOther, *boundarySetItA, dist);
} }
} }
} }
@ -904,9 +904,9 @@ MxResult LegoPathController::FUN_10048310(
} }
} }
if (edgeWithFloat.m_edge != NULL) { if (edgeWithMidpoint.m_edge != NULL) {
pathCtrlEdgeSet.erase(edgeWithFloat.m_edge); pathCtrlEdgeSet.erase(edgeWithMidpoint.m_edge);
boundaryList.push_back(edgeWithFloat); boundaryList.push_back(edgeWithMidpoint);
boundarySet.insert(&boundaryList.back()); boundarySet.insert(&boundaryList.back());
} }
else { else {
@ -936,8 +936,8 @@ MxResult LegoPathController::FUN_10048310(
} }
} }
if (p_param9 != NULL) { if (p_distance != NULL) {
*p_param9 = local14; *p_distance = minDistance;
} }
return SUCCESS; return SUCCESS;
@ -948,18 +948,18 @@ MxResult LegoPathController::FUN_10048310(
// FUNCTION: LEGO1 0x1004a240 // FUNCTION: LEGO1 0x1004a240
// FUNCTION: BETA10 0x100b9160 // FUNCTION: BETA10 0x100b9160
MxS32 LegoPathController::FUN_1004a240( MxS32 LegoPathController::GetNextPathEdge(
LegoPathEdgeContainer& p_grec, LegoPathEdgeContainer& p_grec,
Vector3& p_v1, Vector3& p_position,
Vector3& p_v2, Vector3& p_direction,
float p_f1, float p_f1,
LegoOrientedEdge*& p_edge, LegoOrientedEdge*& p_edge,
LegoPathBoundary*& p_boundary LegoPathBoundary*& p_boundary
) )
{ {
if (p_grec.size() == 0) { if (p_grec.size() == 0) {
p_v1 = p_grec.m_position; p_position = p_grec.m_position;
p_v2 = p_grec.m_direction; p_direction = p_grec.m_direction;
p_boundary = p_grec.m_boundary; p_boundary = p_grec.m_boundary;
p_grec.SetPath(FALSE); p_grec.SetPath(FALSE);
return 1; return 1;
@ -970,28 +970,28 @@ MxS32 LegoPathController::FUN_1004a240(
p_grec.pop_front(); p_grec.pop_front();
Mx3DPointFloat vec; Mx3DPointFloat vec;
p_v1 = *p_edge->CCWVertex(*p_boundary); p_position = *p_edge->CCWVertex(*p_boundary);
p_v1 -= *p_edge->CWVertex(*p_boundary); p_position -= *p_edge->CWVertex(*p_boundary);
p_v1 *= p_f1; p_position *= p_f1;
p_v1 += *p_edge->CWVertex(*p_boundary); p_position += *p_edge->CWVertex(*p_boundary);
p_edge->GetFaceNormal(*p_boundary, vec); p_edge->GetFaceNormal(*p_boundary, vec);
p_v2.EqualsCross(*p_boundary->GetUp(), vec); p_direction.EqualsCross(*p_boundary->GetUp(), vec);
return 0; return 0;
} }
// FUNCTION: LEGO1 0x1004a380 // FUNCTION: LEGO1 0x1004a380
// FUNCTION: BETA10 0x100b957f // FUNCTION: BETA10 0x100b957f
MxResult LegoPathController::FUN_1004a380( MxResult LegoPathController::FindIntersectionBoundary(
Vector3& p_param1, Vector3& p_location,
Vector3& p_param2, Vector3& p_direction,
Mx3DPointFloat* p_param3, Mx3DPointFloat* p_coefficients,
LegoPathBoundary*& p_boundary, LegoPathBoundary*& p_boundary,
MxFloat& p_param5 MxFloat& p_apexParameter
) )
{ {
MxFloat param5 = p_param5; MxFloat originalApexParameter = p_apexParameter;
Mx3DPointFloat local24; Mx3DPointFloat intersectionPoint;
MxU32 local8 = TRUE; MxU32 solutionNotFound = TRUE;
for (MxS32 i = 0; i < m_numL; i++) { for (MxS32 i = 0; i < m_numL; i++) {
if (m_boundaries[i].m_flags & LegoPathBoundary::c_bit3) { if (m_boundaries[i].m_flags & LegoPathBoundary::c_bit3) {
@ -999,75 +999,76 @@ MxResult LegoPathController::FUN_1004a380(
} }
LegoPathBoundary* b = &m_boundaries[i]; LegoPathBoundary* b = &m_boundaries[i];
Mx4DPointFloat* unk0x14 = b->GetUp(); Mx4DPointFloat* up = b->GetUp();
float local28 = p_param3[0].Dot(p_param3[0], *unk0x14); float coeffADotUp = p_coefficients[0].Dot(p_coefficients[0], *up);
if (local28 < 0.001 && local28 > -0.001) { if (coeffADotUp < 0.001 && coeffADotUp > -0.001) {
continue; continue;
} }
float local2c = p_param3[1].Dot(p_param3[1], *unk0x14); float coeffBDotUp = p_coefficients[1].Dot(p_coefficients[1], *up);
float local34 = p_param3[2].Dot(p_param3[2], *unk0x14) + unk0x14->index_operator(3); float coeffCDotUp = p_coefficients[2].Dot(p_coefficients[2], *up) + up->index_operator(3);
float local3c = local2c * local2c - local34 * local28 * 4.0f; float quadraticDiscriminant = coeffBDotUp * coeffBDotUp - coeffCDotUp * coeffADotUp * 4.0f;
if (local3c < -0.001) { if (quadraticDiscriminant < -0.001) {
continue; continue;
} }
if (local3c < 0.0f) { if (quadraticDiscriminant < 0.0f) {
local3c = 0.0f; quadraticDiscriminant = 0.0f;
} }
else { else {
local3c = sqrt(local3c); quadraticDiscriminant = sqrt(quadraticDiscriminant);
} }
float local38 = (local3c - local2c) / (local28 * 2.0f); float intersectionParameter = (quadraticDiscriminant - coeffBDotUp) / (coeffADotUp * 2.0f);
float local44 = (-local3c - local2c) / (local28 * 2.0f); float alternativeIntersectionParameter = (-quadraticDiscriminant - coeffBDotUp) / (coeffADotUp * 2.0f);
if (!IsBetween(local38, 0.0f, param5)) { if (!IsBetween(intersectionParameter, 0.0f, originalApexParameter)) {
if (IsBetween(local44, 0.0f, param5)) { if (IsBetween(alternativeIntersectionParameter, 0.0f, originalApexParameter)) {
local38 = local44; intersectionParameter = alternativeIntersectionParameter;
} }
else { else {
continue; continue;
} }
} }
if (local8 || FUN_100c17a0(local38, p_param5, 0.0f, param5)) { if (solutionNotFound ||
Mx3DPointFloat local58(p_param3[0]); BothSameComparison(intersectionParameter, p_apexParameter, 0.0f, originalApexParameter)) {
Mx3DPointFloat tSqrA(p_coefficients[0]);
local58 *= local38 * local38; tSqrA *= intersectionParameter * intersectionParameter;
local24 = p_param3[1]; intersectionPoint = p_coefficients[1];
local24 *= local38; intersectionPoint *= intersectionParameter;
local24 += p_param3[2]; intersectionPoint += p_coefficients[2];
local24 += local58; intersectionPoint += tSqrA;
assert(b->GetNumEdges() > 1); assert(b->GetNumEdges() > 1);
MxS32 j; MxS32 j;
for (j = b->GetNumEdges() - 1; j >= 0; j--) { for (j = b->GetNumEdges() - 1; j >= 0; j--) {
Mx4DPointFloat* local60 = b->GetEdgeNormal(j); Mx4DPointFloat* edgeNormal = b->GetEdgeNormal(j);
if (local24.Dot(*local60, local24) + local60->index_operator(3) < -0.001) { if (intersectionPoint.Dot(*edgeNormal, intersectionPoint) + edgeNormal->index_operator(3) < -0.001) {
break; break;
} }
} }
if (j < 0) { if (j < 0) {
Mx3DPointFloat local74(p_param1); Mx3DPointFloat direction(p_location);
local74 -= local24; direction -= intersectionPoint;
if (local74.Dot(local74, *unk0x14) >= 0.0f) { if (direction.Dot(direction, *up) >= 0.0f) {
p_param5 = local38; p_apexParameter = intersectionParameter;
p_boundary = b; p_boundary = b;
local8 = FALSE; solutionNotFound = FALSE;
} }
} }
} }
} }
if (local8) { if (solutionNotFound) {
p_param5 = param5; p_apexParameter = originalApexParameter;
return FAILURE; return FAILURE;
} }

View File

@ -335,7 +335,7 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location,
} }
MxFloat unk0x19c = *m_pizzas[nextPizza].GetApexParameter(); MxFloat unk0x19c = *m_pizzas[nextPizza].GetApexParameter();
if (p_controller->FUN_1004a380( if (p_controller->FindIntersectionBoundary(
p_location, p_location,
p_direction, p_direction,
m_pizzas[nextPizza].GetCoefficients(), m_pizzas[nextPizza].GetCoefficients(),
@ -390,7 +390,7 @@ MxResult Act3::ShootDonut(LegoPathController* p_controller, Vector3& p_location,
} }
MxFloat unk0x19c = *m_donuts[nextDonut].GetApexParameter(); MxFloat unk0x19c = *m_donuts[nextDonut].GetApexParameter();
if (p_controller->FUN_1004a380( if (p_controller->FindIntersectionBoundary(
p_location, p_location,
p_direction, p_direction,
m_donuts[nextDonut].GetCoefficients(), m_donuts[nextDonut].GetCoefficients(),