Clear unknowns in LegoPathBoundary (#1730)
Some checks failed
Analyze / ${{ matrix.who }} annotations (CONFIG) (push) Has been cancelled
Analyze / ${{ matrix.who }} annotations (ISLE) (push) Has been cancelled
Analyze / ${{ matrix.who }} annotations (LEGO1) (push) Has been cancelled
Build / Download original binaries (push) Has been cancelled
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) Has been cancelled
Build / Current ${{ matrix.toolchain.name }} (map[name:MSVC setup-cmake:true setup-msvc:true setup-ninja:true shell:sh]) (push) Has been cancelled
Build / MSVC 4.20 (push) Has been cancelled
Build / MSVC 4.20 (BETA10) (push) Has been cancelled
Format / C++ (push) Has been cancelled
Naming / C++ (push) Has been cancelled
Build / Verify decomp (push) Has been cancelled
Build / Upload artifacts (push) Has been cancelled

This commit is contained in:
Fabian Neundorf 2026-01-25 20:48:36 +01:00 committed by GitHub
parent a251424b10
commit 5e7a787af0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 97 additions and 90 deletions

View File

@ -45,9 +45,15 @@ class LegoPathBoundary : public LegoWEGEdge {
LegoPathActor* p_actor, LegoPathActor* p_actor,
LegoPathBoundary*& p_boundary, LegoPathBoundary*& p_boundary,
LegoOrientedEdge*& p_edge, LegoOrientedEdge*& p_edge,
float& p_unk0xe4 float& p_scale
);
MxU32 Intersect(
float p_scale,
Vector3& p_oldPos,
Vector3& p_newPos,
Vector3& p_intersectionPoint,
LegoOrientedEdge*& p_edge
); );
MxU32 Intersect(float p_scale, Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, LegoOrientedEdge*& p_edge);
MxU32 AddPresenterIfInRange(LegoAnimPresenter* p_presenter); MxU32 AddPresenterIfInRange(LegoAnimPresenter* p_presenter);
MxU32 RemovePresenter(LegoAnimPresenter* p_presenter); MxU32 RemovePresenter(LegoAnimPresenter* p_presenter);

View File

@ -87,7 +87,7 @@ void LegoPathBoundary::SwitchBoundary(
LegoPathActor* p_actor, LegoPathActor* p_actor,
LegoPathBoundary*& p_boundary, LegoPathBoundary*& p_boundary,
LegoOrientedEdge*& p_edge, LegoOrientedEdge*& p_edge,
float& p_unk0xe4 float& p_scale
) )
{ {
LegoOrientedEdge* e = p_edge; LegoOrientedEdge* e = p_edge;
@ -99,7 +99,7 @@ void LegoPathBoundary::SwitchBoundary(
newBoundary = p_boundary; newBoundary = p_boundary;
} }
MxS32 local10 = 0; MxS32 availableEdgeCount = 0;
MxU8 userNavFlag; MxU8 userNavFlag;
if (e->BETA_1004a830(*newBoundary, 1)) { if (e->BETA_1004a830(*newBoundary, 1)) {
@ -111,38 +111,38 @@ void LegoPathBoundary::SwitchBoundary(
do { do {
p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*newBoundary); p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*newBoundary);
LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); LegoPathBoundary* otherBoundary = (LegoPathBoundary*) p_edge->OtherFace(newBoundary);
if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) { if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*otherBoundary, 1))) {
local10++; availableEdgeCount++;
} }
} while (p_edge != e); } while (p_edge != e);
MxBool localc = TRUE; MxBool countCounterclockwise = TRUE;
MxS32 local8 = local10 - 1; MxS32 selectedEdgeIndex = availableEdgeCount - 1;
if (local10 <= 1) { if (availableEdgeCount <= 1) {
local8 = 0; selectedEdgeIndex = 0;
} }
else if (local10 == 2) { else if (availableEdgeCount == 2) {
local8 = 1; selectedEdgeIndex = 1;
} }
else { else {
p_actor->VTable0xa4(localc, local8); p_actor->VTable0xa4(countCounterclockwise, selectedEdgeIndex);
} }
while (local8 > 0) { while (selectedEdgeIndex > 0) {
if (localc) { if (countCounterclockwise) {
p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*newBoundary); p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*newBoundary);
} }
else { else {
p_edge = (LegoOrientedEdge*) p_edge->GetClockwiseEdge(*newBoundary); p_edge = (LegoOrientedEdge*) p_edge->GetClockwiseEdge(*newBoundary);
} }
LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); LegoPathBoundary* otherBoundary = (LegoPathBoundary*) p_edge->OtherFace(newBoundary);
if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) { if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*otherBoundary, 1))) {
local8--; selectedEdgeIndex--;
} }
} }
@ -157,7 +157,7 @@ void LegoPathBoundary::SwitchBoundary(
p_boundary->AddActor(p_actor); p_boundary->AddActor(p_actor);
} }
else { else {
p_unk0xe4 = 1.0 - p_unk0xe4; p_scale = 1.0 - p_scale;
} }
} }
else { else {
@ -174,7 +174,7 @@ void LegoPathBoundary::SwitchBoundary(
p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*p_boundary); p_edge = (LegoOrientedEdge*) p_edge->GetCounterclockwiseEdge(*p_boundary);
} }
p_unk0xe4 = 1.0 - p_unk0xe4; p_scale = 1.0 - p_scale;
} }
} }
@ -182,127 +182,128 @@ void LegoPathBoundary::SwitchBoundary(
// FUNCTION: BETA10 0x100b1adc // FUNCTION: BETA10 0x100b1adc
MxU32 LegoPathBoundary::Intersect( MxU32 LegoPathBoundary::Intersect(
float p_scale, float p_scale,
Vector3& p_point1, Vector3& p_oldPos,
Vector3& p_point2, Vector3& p_newPos,
Vector3& p_point3, Vector3& p_intersectionPoint,
LegoOrientedEdge*& p_edge LegoOrientedEdge*& p_edge
) )
{ {
LegoOrientedEdge* e = NULL; LegoOrientedEdge* e = NULL;
float localc; float minHitDistance;
MxU32 local10 = 0; MxU32 normalizedCalculated = 0;
float len = 0.0f; float len = 0.0f;
Mx3DPointFloat vec; Mx3DPointFloat direction;
for (MxS32 i = 0; i < m_numEdges; i++) { for (MxS32 i = 0; i < m_numEdges; i++) {
LegoOrientedEdge* edge = (LegoOrientedEdge*) m_edges[i]; LegoOrientedEdge* edge = (LegoOrientedEdge*) m_edges[i];
if (p_point2.Dot(m_edgeNormals[i], p_point2) + m_edgeNormals[i][3] <= -1e-07) { if (p_newPos.Dot(m_edgeNormals[i], p_newPos) + m_edgeNormals[i][3] <= -1e-07) {
if (local10 == 0) { if (normalizedCalculated == FALSE) {
local10 = 1; normalizedCalculated = TRUE;
vec = p_point2; direction = p_newPos;
vec -= p_point1; direction -= p_oldPos;
len = vec.LenSquared(); len = direction.LenSquared();
if (len <= 0.0f) { if (len <= 0.0f) {
return 0; return 0;
} }
len = sqrt(len); len = sqrt(len);
vec /= len; direction /= len;
} }
float dot = vec.Dot(vec, m_edgeNormals[i]); float dot = direction.Dot(direction, m_edgeNormals[i]);
if (dot != 0.0f) { if (dot != 0.0f) {
float local34 = (-m_edgeNormals[i][3] - p_point1.Dot(p_point1, m_edgeNormals[i])) / dot; float hitDistance = (-m_edgeNormals[i][3] - p_oldPos.Dot(p_oldPos, m_edgeNormals[i])) / dot;
if (local34 >= -0.001 && local34 <= len && (e == NULL || local34 < localc)) { if (hitDistance >= -0.001 && hitDistance <= len && (e == NULL || hitDistance < minHitDistance)) {
e = edge; e = edge;
localc = local34; minHitDistance = hitDistance;
} }
} }
} }
} }
if (e != NULL) { if (e != NULL) {
if (localc < 0.0f) { if (minHitDistance < 0.0f) {
localc = 0.0f; minHitDistance = 0.0f;
} }
Mx3DPointFloat local50; Mx3DPointFloat startToPosition;
Mx3DPointFloat local70; Mx3DPointFloat edgeNormal;
Vector3* local5c = e->CWVertex(*this); Vector3* start = e->CWVertex(*this);
p_point3 = vec; p_intersectionPoint = direction;
p_point3 *= localc; p_intersectionPoint *= minHitDistance;
p_point3 += p_point1; p_intersectionPoint += p_oldPos;
local50 = p_point2; startToPosition = p_newPos;
local50 -= *local5c; startToPosition -= *start;
e->GetFaceNormal(*this, local70); e->GetFaceNormal(*this, edgeNormal);
float local58 = local50.Dot(local50, local70); float projection = startToPosition.Dot(startToPosition, edgeNormal);
LegoOrientedEdge* local54 = NULL; LegoOrientedEdge* candidateEdge = NULL;
if (local58 < 0.0f) { if (projection < 0.0f) {
Mx3DPointFloat local84; Mx3DPointFloat candidateEdgeNormal;
for (LegoOrientedEdge* local88 = (LegoOrientedEdge*) e->GetClockwiseEdge(*this); e != local88; for (LegoOrientedEdge* cwEdge = (LegoOrientedEdge*) e->GetClockwiseEdge(*this); e != cwEdge;
local88 = (LegoOrientedEdge*) local88->GetClockwiseEdge(*this)) { cwEdge = (LegoOrientedEdge*) cwEdge->GetClockwiseEdge(*this)) {
local88->GetFaceNormal(*this, local84); cwEdge->GetFaceNormal(*this, candidateEdgeNormal);
if (local84.Dot(local84, local70) <= 0.9) { if (candidateEdgeNormal.Dot(candidateEdgeNormal, edgeNormal) <= 0.9) {
break; break;
} }
Vector3* local90 = local88->CWVertex(*this); Vector3* candidateStart = cwEdge->CWVertex(*this);
Mx3DPointFloat locala4(p_point3); Mx3DPointFloat candidateToIntersection(p_intersectionPoint);
locala4 -= *local90; candidateToIntersection -= *candidateStart;
float local8c = locala4.Dot(locala4, local84); float candidateProjection = candidateToIntersection.Dot(candidateToIntersection, candidateEdgeNormal);
if (local8c > local58 && local8c < local88->m_length) { if (candidateProjection > projection && candidateProjection < cwEdge->m_length) {
local54 = local88; candidateEdge = cwEdge;
local58 = local8c; projection = candidateProjection;
local70 = local84; edgeNormal = candidateEdgeNormal;
local5c = local90; start = candidateStart;
} }
} }
} }
else { else {
if (e->m_length < local58) { if (e->m_length < projection) {
Mx3DPointFloat localbc; Mx3DPointFloat candidateEdgeNormal;
for (LegoOrientedEdge* locala8 = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this); e != locala8; for (LegoOrientedEdge* ccwEdge = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this); e != ccwEdge;
locala8 = (LegoOrientedEdge*) locala8->GetCounterclockwiseEdge(*this)) { ccwEdge = (LegoOrientedEdge*) ccwEdge->GetCounterclockwiseEdge(*this)) {
locala8->GetFaceNormal(*this, localbc); ccwEdge->GetFaceNormal(*this, candidateEdgeNormal);
if (localbc.Dot(localbc, local70) <= 0.9) { if (candidateEdgeNormal.Dot(candidateEdgeNormal, edgeNormal) <= 0.9) {
break; break;
} }
Vector3* localc4 = locala8->CWVertex(*this); Vector3* candidateStart = ccwEdge->CWVertex(*this);
Mx3DPointFloat locald8(p_point3); Mx3DPointFloat candidateToIntersection(p_intersectionPoint);
locald8 -= *localc4; candidateToIntersection -= *candidateStart;
float localc0 = locald8.Dot(locald8, localbc); float candidateProjection =
candidateToIntersection.Dot(candidateToIntersection, candidateEdgeNormal);
if (localc0 < local58 && localc0 >= 0.0f) { if (candidateProjection < projection && candidateProjection >= 0.0f) {
local54 = locala8; candidateEdge = ccwEdge;
local58 = localc0; projection = candidateProjection;
local70 = localbc; edgeNormal = candidateEdgeNormal;
local5c = localc4; start = candidateStart;
} }
} }
} }
} }
if (local54 != NULL) { if (candidateEdge != NULL) {
e = local54; e = candidateEdge;
} }
if (local58 <= 0.0f) { if (projection <= 0.0f) {
if (!e->GetMask0x03()) { if (!e->GetMask0x03()) {
p_edge = (LegoOrientedEdge*) e->GetClockwiseEdge(*this); p_edge = (LegoOrientedEdge*) e->GetClockwiseEdge(*this);
} }
@ -310,18 +311,18 @@ MxU32 LegoPathBoundary::Intersect(
p_edge = e; p_edge = e;
} }
p_point3 = *local5c; p_intersectionPoint = *start;
return 2; return 2;
} }
else if (local58 > 0.0f && e->m_length > local58) { else if (projection > 0.0f && e->m_length > projection) {
p_point3 = local70; p_intersectionPoint = edgeNormal;
p_point3 *= local58; p_intersectionPoint *= projection;
p_point3 += *local5c; p_intersectionPoint += *start;
p_edge = e; p_edge = e;
return 1; return 1;
} }
else { else {
p_point3 = *e->CCWVertex(*this); p_intersectionPoint = *e->CCWVertex(*this);
if (!e->GetMask0x03()) { if (!e->GetMask0x03()) {
p_edge = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this); p_edge = (LegoOrientedEdge*) e->GetCounterclockwiseEdge(*this);