Clear unknowns in LegoROI (#1703)

* Rename FUN_100a9410 to Intersect

* Rename FUN_100a81b0 to ReportError

* Rename FUN_100a9330 to SetColor

* Rename FUN_100a93b0 to SetColorByName

* Rename local10 to radius

* Rename boundingBox variables

* Rename bb point variables

* Rename local4c to rayOrigin

* Rename local17c to intersectionPoint

* Rename local18 to discriminant

* Rename ray-sphere intersection variables

* Rename quadratic equation variables

* Rename local70 to untransformedPoint

* Rename local150 to boxFacePlanes

* Rename local50 to intersectionDistance

* Rename Intersect method arguments

* Clang-format of legoracespecial

* Clang-format of legoroi

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
Sebastian Mischke 2026-01-05 23:38:40 +01:00 committed by GitHub
parent 29dda2c369
commit e9eb2493bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 97 additions and 99 deletions

View File

@ -1388,7 +1388,7 @@ void LegoCarBuild::SetPartColor(MxS32 p_objectId)
m_Paint_Sound->Enable(FALSE);
m_Paint_Sound->Enable(TRUE);
m_selectedPart->FUN_100a93b0(color);
m_selectedPart->SetColorByName(color);
sprintf(buffer, "c_%s", m_selectedPart->GetName());
VariableTable()->SetVariable(buffer, color);
}

View File

@ -502,7 +502,7 @@ inline MxU32 LegoExtraActor::VTable0x6c(
}
}
else {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (HitActor(actor, TRUE) < 0) {
return 0;
}

View File

@ -487,7 +487,7 @@ MxU32 LegoPathActor::VTable0x6c(
LegoROI* roi = actor->GetROI();
if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->m_collideBox)) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->m_collideBox)) {
HitActor(actor, TRUE);
actor->HitActor(this, FALSE);
return 2;

View File

@ -456,14 +456,8 @@ inline MxU32 LegoCarRaceActor::VTable0x6c(
LegoROI* firstROI = (LegoROI*) co->front();
if (firstROI->FUN_100a9410(
p_v1,
p_v2,
p_f1,
p_f2,
p_v3,
m_collideBox && actor->GetCollideBox()
)) {
if (firstROI
->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {
@ -476,14 +470,8 @@ inline MxU32 LegoCarRaceActor::VTable0x6c(
LegoROI* lastROI = (LegoROI*) co->back();
if (lastROI->FUN_100a9410(
p_v1,
p_v2,
p_f1,
p_f2,
p_v3,
m_collideBox && actor->GetCollideBox()
)) {
if (lastROI
->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {
@ -496,7 +484,7 @@ inline MxU32 LegoCarRaceActor::VTable0x6c(
}
}
else {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {
@ -544,7 +532,7 @@ inline MxU32 LegoJetskiRaceActor::VTable0x6c(
LegoROI* roi = actor->GetROI();
if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {

View File

@ -1198,7 +1198,7 @@ MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, fl
len = sqrt(len);
if (len <= m_unk0xa4 + p_f2 && m_roiMapSize != 0 && m_roiMap != NULL) {
for (MxU32 i = 1; i <= m_roiMapSize; i++) {
if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) {
if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) {
return TRUE;
}
}

View File

@ -61,7 +61,7 @@ TextureHandler g_textureHandler = NULL;
// FUNCTION: LEGO1 0x100a81b0
// FUNCTION: BETA10 0x101898c0
// FUNCTION: ALPHA 0x100bb1c0
void LegoROI::FUN_100a81b0(const LegoChar* p_error, ...)
void LegoROI::ReportError(const LegoChar* p_error, ...)
{
// Probably a printf-like debug function that was removed early.
// No known implementation in any of the binaries.
@ -418,7 +418,7 @@ LegoResult LegoROI::ApplyChildAnimationTransformation(
}
}
else {
FUN_100a81b0("%s ROI Not found\n", name);
ReportError("%s ROI Not found\n", name);
#ifdef BETA10
_RPT1(_CRT_ASSERT, "%s ROI Not Found", name);
// Note that the macro inserts an INT3, which breaks the assumption that INT3
@ -582,7 +582,7 @@ LegoResult LegoROI::GetTextureInfo(LegoTextureInfo*& p_textureInfo)
// FUNCTION: LEGO1 0x100a9330
// FUNCTION: BETA10 0x1018b22c
LegoResult LegoROI::FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
LegoResult LegoROI::SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
{
return SetLodColor(p_red, p_green, p_blue, p_alpha);
}
@ -601,11 +601,11 @@ LegoResult LegoROI::SetLodColor(const LegoChar* p_name)
// FUNCTION: LEGO1 0x100a93b0
// FUNCTION: BETA10 0x1018b2c0
LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_name)
LegoResult LegoROI::SetColorByName(const LegoChar* p_name)
{
MxFloat red, green, blue, alpha;
if (ColorAliasLookup(p_name, red, green, blue, alpha)) {
return FUN_100a9330(red, green, blue, alpha);
return SetColor(red, green, blue, alpha);
}
return 0;
@ -613,83 +613,85 @@ LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_name)
// FUNCTION: LEGO1 0x100a9410
// FUNCTION: BETA10 0x1018b324
LegoU32 LegoROI::FUN_100a9410(
Vector3& p_v1,
Vector3& p_v2,
float p_f1,
float p_f2,
Vector3& p_v3,
LegoU32 LegoROI::Intersect(
Vector3& p_rayOrigin,
Vector3& p_rayDirection,
float p_rayLength,
float p_unused,
Vector3& p_intersectionPoint,
LegoBool p_collideBox
)
{
if (p_collideBox) {
Mx3DPointFloat v2(p_v2);
v2 *= p_f1;
v2 += p_v1;
Mx3DPointFloat v2(p_rayDirection);
v2 *= p_rayLength;
v2 += p_rayOrigin;
Mx4DPointFloat localc0;
Mx4DPointFloat local9c;
Mx4DPointFloat local168;
Mx4DPointFloat local70;
Mx4DPointFloat local150[6];
Mx4DPointFloat minPoint;
Mx4DPointFloat maxPoint;
Mx4DPointFloat centerPoint;
Mx4DPointFloat untransformedPoint;
Mx4DPointFloat boxFacePlanes[6];
Vector3 local58(&localc0[0]);
Vector3 locala8(&local9c[0]);
Vector3 local38(&local168[0]);
Vector3 boundingBoxMin(&minPoint[0]);
Vector3 boundingBoxMax(&maxPoint[0]);
Vector3 boundingBoxCenter(&centerPoint[0]);
Mx3DPointFloat local4c(p_v1);
Mx3DPointFloat rayOrigin(p_rayOrigin);
local58 = m_bounding_box.Min();
locala8 = m_bounding_box.Max();
boundingBoxMin = m_bounding_box.Min();
boundingBoxMax = m_bounding_box.Max();
localc0[3] = local9c[3] = local168[3] = 1.0f;
minPoint[3] = maxPoint[3] = centerPoint[3] = 1.0f;
local38 = local58;
local38 += locala8;
local38 *= 0.5f;
boundingBoxCenter = boundingBoxMin;
boundingBoxCenter += boundingBoxMax;
boundingBoxCenter *= 0.5f;
local70 = localc0;
localc0.SetMatrixProduct(local70, (float*) m_local2world.GetData());
untransformedPoint = minPoint;
minPoint.SetMatrixProduct(untransformedPoint, (float*) m_local2world.GetData());
local70 = local9c;
local9c.SetMatrixProduct(local70, (float*) m_local2world.GetData());
untransformedPoint = maxPoint;
maxPoint.SetMatrixProduct(untransformedPoint, (float*) m_local2world.GetData());
local70 = local168;
local168.SetMatrixProduct(local70, (float*) m_local2world.GetData());
untransformedPoint = centerPoint;
centerPoint.SetMatrixProduct(untransformedPoint, (float*) m_local2world.GetData());
p_v3 = m_local2world[3];
p_intersectionPoint = m_local2world[3];
LegoS32 i;
for (i = 0; i < 6; i++) {
local150[i] = m_local2world[i % 3];
boxFacePlanes[i] = m_local2world[i % 3];
if (i > 2) {
local150[i][3] = -local58.Dot(local58, local150[i]);
boxFacePlanes[i][3] = -boundingBoxMin.Dot(boundingBoxMin, boxFacePlanes[i]);
}
else {
local150[i][3] = -locala8.Dot(locala8, local150[i]);
boxFacePlanes[i][3] = -boundingBoxMax.Dot(boundingBoxMax, boxFacePlanes[i]);
}
if (local150[i][3] + local38.Dot(local38, local150[i]) < 0.0f) {
local150[i] *= -1.0f;
if (boxFacePlanes[i][3] + boundingBoxCenter.Dot(boundingBoxCenter, boxFacePlanes[i]) < 0.0f) {
boxFacePlanes[i] *= -1.0f;
}
}
for (i = 0; i < 6; i++) {
float local50 = p_v2.Dot(p_v2, local150[i]);
float intersectionDistance = p_rayDirection.Dot(p_rayDirection, boxFacePlanes[i]);
if (local50 >= 0.01 || local50 < -0.01) {
local50 = -((local150[i][3] + local4c.Dot(local4c, local150[i])) / local50);
if (intersectionDistance >= 0.01 || intersectionDistance < -0.01) {
intersectionDistance =
-((boxFacePlanes[i][3] + rayOrigin.Dot(rayOrigin, boxFacePlanes[i])) / intersectionDistance);
if (local50 >= 0.0f && local50 <= p_f1) {
Mx3DPointFloat local17c(p_v2);
local17c *= local50;
local17c += local4c;
if (intersectionDistance >= 0.0f && intersectionDistance <= p_rayLength) {
Mx3DPointFloat intersectionPoint(p_rayDirection);
intersectionPoint *= intersectionDistance;
intersectionPoint += rayOrigin;
LegoS32 j;
for (j = 0; j < 6; j++) {
if (i != j && i - j != 3 && j - i != 3) {
if (local150[j][3] + local17c.Dot(local17c, local150[j]) < 0.0f) {
if (boxFacePlanes[j][3] + intersectionPoint.Dot(intersectionPoint, boxFacePlanes[j]) <
0.0f) {
break;
}
}
@ -703,45 +705,46 @@ LegoU32 LegoROI::FUN_100a9410(
}
}
else {
Mx3DPointFloat v1(p_v1);
Mx3DPointFloat v1(p_rayOrigin);
v1 -= GetWorldBoundingSphere().Center();
float local10 = GetWorldBoundingSphere().Radius();
float local8 = p_v2.Dot(p_v2, p_v2);
float localc = p_v2.Dot(p_v2, v1) * 2.0f;
float local14 = v1.Dot(v1, v1) - (local10 * local10);
float radius = GetWorldBoundingSphere().Radius();
// Quadratic equation to solve for ray-sphere intersection: at^2 + bt + c = 0
float a = p_rayDirection.Dot(p_rayDirection, p_rayDirection);
float b = p_rayDirection.Dot(p_rayDirection, v1) * 2.0f;
float c = v1.Dot(v1, v1) - (radius * radius);
if (local8 >= 0.001 || local8 <= -0.001) {
float local1c = -1.0f;
float local18 = (localc * localc) - (local14 * local8 * 4.0f);
if (a >= 0.001 || a <= -0.001) {
float distance = -1.0f;
float discriminant = (b * b) - (c * a * 4.0f);
if (local18 >= -0.001) {
local8 *= 2.0f;
localc = -localc;
if (discriminant >= -0.001) {
a *= 2.0f;
b = -b;
if (local18 > 0.0f) {
local18 = sqrt(local18);
float local184 = (localc + local18) / local8;
float local188 = (localc - local18) / local8;
if (discriminant > 0.0f) {
discriminant = sqrt(discriminant);
float root1 = (b + discriminant) / a;
float root2 = (b - discriminant) / a;
if (local184 > 0.0f && local188 > local184) {
local1c = local184;
if (root1 > 0.0f && root2 > root1) {
distance = root1;
}
else if (local188 > 0.0f) {
local1c = local188;
else if (root2 > 0.0f) {
distance = root2;
}
else {
return 0;
}
}
else {
local1c = localc / local8;
distance = b / a;
}
if (local1c >= 0.0f && p_f1 >= local1c) {
p_v3 = p_v2;
p_v3 *= local1c;
p_v3 += p_v1;
if (distance >= 0.0f && p_rayLength >= distance) {
p_intersectionPoint = p_rayDirection;
p_intersectionPoint *= distance;
p_intersectionPoint += p_rayOrigin;
return 1;
}
}

View File

@ -50,10 +50,17 @@ class LegoROI : public ViewROI {
LegoResult SetLodColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult SetTextureInfo(LegoTextureInfo* p_textureInfo);
LegoResult GetTextureInfo(LegoTextureInfo*& p_textureInfo);
LegoResult FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult SetLodColor(const LegoChar* p_name);
LegoResult FUN_100a93b0(const LegoChar* p_name);
LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox);
LegoResult SetColorByName(const LegoChar* p_name);
LegoU32 Intersect(
Vector3& p_rayOrigin,
Vector3& p_rayDirection,
float p_rayLength,
float p_unused,
Vector3& p_intersectionPoint,
LegoBool p_collideBox
);
void SetName(const LegoChar* p_name);
float IntrinsicImportance() const override; // vtable+0x04
@ -63,7 +70,7 @@ class LegoROI : public ViewROI {
void SetDisplayBB(int p_displayBB);
static LegoResult CreateLocalTransform(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix);
static void FUN_100a81b0(const LegoChar* p_error, ...);
static void ReportError(const LegoChar* p_error, ...);
static void configureLegoROI(int p_roi);
static void SetColorOverride(ColorOverride p_colorOverride);
static LegoBool GetRGBAColor(const LegoChar* p_name, float& p_red, float& p_green, float& p_blue, float& p_alpha);