Implement/match LegoCarRaceActor::VTable0x1c (#1078)

* Implement/match `LegoCarRaceActor::VTable0x1c`

* Fix formatting

* Fix LegoEdge::CWVertex()

* Fix more CI issues

* Trz to fix lvalue compile issue

* Fix formatting

---------

Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
jonschz 2024-08-04 21:13:12 +02:00 committed by GitHub
parent fe1b66938d
commit e09acfcddb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 328 additions and 161 deletions

View file

@ -350,7 +350,6 @@ add_library(lego1 SHARED
LEGO1/lego/legoomni/src/entity/legoactor.cpp
LEGO1/lego/legoomni/src/entity/legoactorpresenter.cpp
LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp
LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp
LEGO1/lego/legoomni/src/entity/legoentity.cpp
LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp
LEGO1/lego/legoomni/src/entity/legojetski.cpp
@ -375,8 +374,9 @@ add_library(lego1 SHARED
LEGO1/lego/legoomni/src/race/jetskirace.cpp
LEGO1/lego/legoomni/src/race/legorace.cpp
LEGO1/lego/legoomni/src/race/legoraceactor.cpp
LEGO1/lego/legoomni/src/race/legoracers.cpp
LEGO1/lego/legoomni/src/race/legoracemap.cpp
LEGO1/lego/legoomni/src/race/legoracers.cpp
LEGO1/lego/legoomni/src/race/legoracespecial.cpp
LEGO1/lego/legoomni/src/race/raceskel.cpp
LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp
LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp

View file

@ -1,7 +1,7 @@
#ifndef LEGOJETSKIRACEACTOR_H
#define LEGOJETSKIRACEACTOR_H
#include "legocarraceactor.h"
#include "legoracespecial.h"
// VTABLE: LEGO1 0x100da208 LegoCarRaceActor
// VTABLE: LEGO1 0x100da228 LegoRaceActor
@ -34,7 +34,7 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor {
Vector3& p_v3
) override; // vtable+0x6c
void VTable0x70(float p_float) override; // vtable+0x70
void VTable0x1c() override; // vtable+0x1c
MxS32 VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) override; // vtable+0x1c
// SYNTHETIC: LEGO1 0x10081d50
// LegoJetskiRaceActor::`scalar deleting destructor'

View file

@ -13,6 +13,7 @@ class Vector3;
// LegoMouseController
// VTABLE: LEGO1 0x100d85b8
// VTABLE: BETA10 0x101bcc80
// SIZE 0x70
class LegoNavController : public MxCore {
public:
@ -22,6 +23,7 @@ class LegoNavController : public MxCore {
MxLong Notify(MxParam& p_param) override; // vtable+0x04
// FUNCTION: LEGO1 0x10054b80
// FUNCTION: BETA10 0x1009e5f0
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f66d8
@ -77,7 +79,9 @@ class LegoNavController : public MxCore {
static MxS32 GetNumLocations();
static LegoLocation* GetLocation(MxU32 p_location);
// FUNCTION: BETA10 0x100b0f40
void SetLinearVel(MxFloat p_linearVel) { m_linearVel = p_linearVel; }
MxFloat GetLinearVel() { return m_linearVel; }
MxFloat GetRotationalVel() { return m_rotationalVel; }
MxFloat GetMaxLinearVel() { return m_maxLinearVel; }

View file

@ -59,7 +59,7 @@ class LegoPathActor : public LegoActor {
virtual MxBool GetUserNavFlag() { return m_userNavFlag; } // vtable+0x7c
virtual MxResult VTable0x80(
Vector3& p_point1,
const Vector3& p_point1,
Vector3& p_point2,
Vector3& p_point3,
Vector3& p_point4
@ -165,7 +165,7 @@ class LegoPathActor : public LegoActor {
LegoUnknown100db7f4* m_destEdge; // 0xe0
MxFloat m_unk0xe4; // 0xe4
MxBool m_collideBox; // 0xe8
undefined m_unk0xe9; // 0xe9
MxBool m_unk0xe9; // 0xe9
MxBool m_userNavFlag; // 0xea
MxMatrix m_unk0xec; // 0xec
LegoPathEdgeContainer* m_grec; // 0x134

View file

@ -60,7 +60,7 @@ class LegoPathController : public MxCore {
}
LegoPathController* m_controller; // 0x00
LegoEdge* m_edge; // 0x04
LegoUnknown100db7f4* m_edge; // 0x04
};
LegoPathController();
@ -121,6 +121,16 @@ class LegoPathController : public MxCore {
static MxResult Init();
static MxResult Reset();
// FUNCTION: BETA10 0x100cf580
static LegoUnknown100db7f4* GetControlEdgeA(MxS32 p_index) { return g_ctrlEdgesA[p_index].m_edge; }
// FUNCTION: BETA10 0x100cf5b0
static LegoPathBoundary* GetControlBoundaryA(MxS32 p_index) { return g_ctrlBoundariesA[p_index].m_boundary; }
// These two are an educated guess because BETA10 does not have the g_ctrl.*B globals
static LegoUnknown100db7f4* GetControlEdgeB(MxS32 p_index) { return g_ctrlEdgesB[p_index].m_edge; }
static LegoPathBoundary* GetControlBoundaryB(MxS32 p_index) { return g_ctrlBoundariesB[p_index].m_boundary; }
private:
void FUN_10046970();
MxResult Read(LegoStorage* p_storage);
@ -140,6 +150,15 @@ class LegoPathController : public MxCore {
MxU16 m_numT; // 0x1e
LegoPathCtrlEdgeSet m_pfsE; // 0x20
LegoPathActorSet m_actors; // 0x30
// Names verified by BETA10
static CtrlBoundary* g_ctrlBoundariesA;
static CtrlEdge* g_ctrlEdgesA;
static const char* g_unk0x100f42f0[];
static const char* g_unk0x100f4330[];
static CtrlBoundary* g_ctrlBoundariesB;
static CtrlEdge* g_ctrlEdgesB;
};
// clang-format off

View file

@ -1,8 +1,8 @@
#ifndef LEGORACERS_H
#define LEGORACERS_H
#include "legocarraceactor.h"
#include "legoracemap.h"
#include "legoracespecial.h"
#define LEGORACECAR_UNKNOWN_0 0
#define LEGORACECAR_UNKNOWN_1 1

View file

@ -64,7 +64,7 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
// FUNCTION: LEGO1 0x10012c00
virtual float FUN_10012c00() { return m_unk0x18; }
virtual void VTable0x1c(); // vtable+0x1c
virtual MxS32 VTable0x1c(undefined4 p_param1, LegoEdge* p_edge); // vtable+0x1c
// SYNTHETIC: LEGO1 0x10012c30
// LegoCarRaceActor::`vbase destructor'
@ -86,6 +86,8 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
// Could be the current timestamp for time-based movement
MxFloat m_unk0x1c; // 0x1c
static MxFloat g_unk0x100f7aec;
};
// GLOBAL: LEGO1 0x100da0b0

View file

@ -40,7 +40,6 @@
#include "legoanimpresenter.h"
#include "legocarbuild.h"
#include "legocarbuildpresenter.h"
#include "legocarraceactor.h"
#include "legoentity.h"
#include "legoentitypresenter.h"
#include "legoflctexturepresenter.h"
@ -58,6 +57,7 @@
#include "legopathpresenter.h"
#include "legophonemepresenter.h"
#include "legoracers.h"
#include "legoracespecial.h"
#include "legotexturepresenter.h"
#include "legoworld.h"
#include "legoworldpresenter.h"

View file

@ -61,8 +61,10 @@ LegoAnimationManager* AnimationManager()
}
// FUNCTION: LEGO1 0x10015780
// FUNCTION: BETA10 0x100e49b8
LegoNavController* NavController()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetNavController();
}

View file

@ -1,124 +0,0 @@
#include "legocarraceactor.h"
#include "geom/legounkown100db7f4.h"
#include "legopathboundary.h"
#include "misc.h"
#include "mxmisc.h"
#include "mxvariabletable.h"
DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0)
// GLOBAL: LEGO1 0x100f7af0
// STRING: LEGO1 0x100f7ae4
const char* g_fuel = "FUEL";
// FUNCTION: LEGO1 0x10080350
// FUNCTION: BETA10 0x100cd6b0
LegoCarRaceActor::LegoCarRaceActor()
{
m_unk0x08 = 1.0f;
m_unk0x70 = 0.0f;
m_unk0x0c = 0;
m_maxLinearVel = 0.0f;
m_frequencyFactor = 1.0f;
m_unk0x1c = 0;
m_unk0x10 = 0.65f;
m_unk0x14 = 0.03f;
m_unk0x18 = 0.6f;
m_unk0x140 = 0.1f;
m_unk0x150 = -5.0f;
m_unk0x148 = 1;
VariableTable()->SetVariable(g_fuel, "0.8");
}
// FUNCTION: LEGO1 0x10080590
// FUNCTION: BETA10 0x100cd8cf
void LegoCarRaceActor::FUN_10080590(float p_float)
{
MxFloat maxSpeed = m_maxLinearVel;
Mx3DPointFloat destEdgeUnknownVector;
Mx3DPointFloat worldDirection = Mx3DPointFloat(m_roi->GetWorldDirection());
m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector);
if (abs(destEdgeUnknownVector.Dot(destEdgeUnknownVector.GetData(), worldDirection.GetData())) > 0.5) {
maxSpeed *= m_unk0x10;
}
MxS32 deltaUnk0x70;
LegoPathActor* userActor = UserActor();
if (userActor) {
// All known implementations of LegoPathActor->VTable0x5c() return LegoPathActor::m_unk0x70
deltaUnk0x70 = m_unk0x70 - userActor->VTable0x5c();
}
else {
deltaUnk0x70 = 0;
}
if (deltaUnk0x70 > 1) {
if (deltaUnk0x70 > 3) {
deltaUnk0x70 = 3;
}
maxSpeed *= (m_unk0x18 * (--deltaUnk0x70) * -0.25f + 1.0f);
}
else if (deltaUnk0x70 < -1) {
maxSpeed *= 1.3;
}
MxFloat deltaSpeed = maxSpeed - m_worldSpeed;
MxFloat changeInSpeed = (p_float - m_unk0x1c) * m_unk0x14;
m_unk0x1c = p_float;
if (deltaSpeed < 0.0f) {
changeInSpeed = -changeInSpeed;
}
MxFloat newWorldSpeed = changeInSpeed + m_worldSpeed;
if (newWorldSpeed > maxSpeed) {
newWorldSpeed = maxSpeed;
}
SetWorldSpeed(newWorldSpeed);
}
// STUB: LEGO1 0x10080740
void LegoCarRaceActor::VTable0x1c()
{
}
// FUNCTION: LEGO1 0x10080b40
// FUNCTION: BETA10 0x100cdb3c
void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4)
{
LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4);
}
// STUB: LEGO1 0x10080b70
void LegoCarRaceActor::VTable0x70(float p_float)
{
// TODO
}
// STUB: LEGO1 0x10080be0
MxResult LegoCarRaceActor::VTable0x9c()
{
// TODO
return SUCCESS;
}
// STUB: LEGO1 0x10081840
MxU32 LegoCarRaceActor::VTable0x6c(
LegoPathBoundary* p_boundary,
Vector3& p_v1,
Vector3& p_v2,
float p_f1,
float p_f2,
Vector3& p_v3
)
{
// TODO
return 0;
}

View file

@ -12,9 +12,10 @@ LegoJetskiRaceActor::LegoJetskiRaceActor()
}
// STUB: LEGO1 0x10081120
void LegoJetskiRaceActor::VTable0x1c()
MxS32 LegoJetskiRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge)
{
// TODO
return 0;
}
// STUB: LEGO1 0x10081550

View file

@ -64,7 +64,7 @@ LegoPathActor::~LegoPathActor()
}
// FUNCTION: LEGO1 0x1002d8d0
MxResult LegoPathActor::VTable0x80(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4)
MxResult LegoPathActor::VTable0x80(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4)
{
Mx3DPointFloat p1, p2, p3;

View file

@ -19,13 +19,15 @@ MxU32 g_unk0x100d7cc8[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0};
MxU32 g_unk0x100d7d08[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// GLOBAL: LEGO1 0x100f42e8
LegoPathController::CtrlBoundary* g_ctrlBoundariesA = NULL;
// GLOBAL: BETA10 0x101f25f0
LegoPathController::CtrlBoundary* LegoPathController::g_ctrlBoundariesA = NULL;
// GLOBAL: LEGO1 0x100f42ec
LegoPathController::CtrlEdge* g_ctrlEdgesA = NULL;
// GLOBAL: BETA10 0x101f25f4
LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesA = NULL;
// GLOBAL: LEGO1 0x100f42f0
const char* g_unk0x100f42f0[] = {
const char* LegoPathController::g_unk0x100f42f0[] = {
"edg03_21",
"edg03_23",
"edg03_30",
@ -45,7 +47,7 @@ const char* g_unk0x100f42f0[] = {
};
// GLOBAL: LEGO1 0x100f4330
const char* g_unk0x100f4330[] = {
const char* LegoPathController::g_unk0x100f4330[] = {
"edg03_06",
"edg03_21",
"edg03_30",
@ -59,10 +61,10 @@ const char* g_unk0x100f4330[] = {
};
// GLOBAL: LEGO1 0x100f4358
LegoPathController::CtrlBoundary* g_ctrlBoundariesB = NULL;
LegoPathController::CtrlBoundary* LegoPathController::g_ctrlBoundariesB = NULL;
// GLOBAL: LEGO1 0x100f435c
LegoPathController::CtrlEdge* g_ctrlEdgesB = NULL;
LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesB = NULL;
// FUNCTION: LEGO1 0x10044f40
// FUNCTION: BETA10 0x100b6860
@ -620,7 +622,7 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage)
boundary.m_edgeNormals = new Mx4DPointFloat[numE];
LegoEdge** edges = new LegoEdge*[numE];
LegoUnknown100db7f4** edges = new LegoUnknown100db7f4*[numE];
boundary.SetEdges(edges, numE);
for (j = 0; j < numE; j++) {

View file

@ -266,13 +266,13 @@ void LegoRaceCar::FUN_10012ff0(float p_param)
if (a->GetDuration() <= deltaTime || deltaTime < 0.0) {
if (m_userState == LEGORACECAR_KICK1) {
LegoEdge** edges = m_kick1B->GetEdges();
m_destEdge = (LegoUnknown100db7f4*) (edges[2]);
LegoUnknown100db7f4** edges = m_kick1B->GetEdges();
m_destEdge = edges[2];
m_boundary = m_kick1B;
}
else {
LegoEdge** edges = m_kick1B->GetEdges();
m_destEdge = (LegoUnknown100db7f4*) (edges[1]);
LegoUnknown100db7f4** edges = m_kick1B->GetEdges();
m_destEdge = edges[1];
m_boundary = m_kick2B;
}

View file

@ -0,0 +1,228 @@
#include "legoracespecial.h"
#include "geom/legounkown100db7f4.h"
#include "legonavcontroller.h"
#include "legopathboundary.h"
#include "legopathcontroller.h"
#include "misc.h"
#include "mxmisc.h"
#include "mxvariabletable.h"
// File name verified by BETA10 0x100cedf7
DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0)
// GLOBAL: LEGO1 0x100f7af0
// STRING: LEGO1 0x100f7ae4
const char* g_fuel = "FUEL";
// GLOBAL: LEGO1 0x100f7aec
MxFloat LegoCarRaceActor::g_unk0x100f7aec = 8.0f;
// FUNCTION: LEGO1 0x10080350
// FUNCTION: BETA10 0x100cd6b0
LegoCarRaceActor::LegoCarRaceActor()
{
m_unk0x08 = 1.0f;
m_unk0x70 = 0.0f;
m_unk0x0c = 0;
m_maxLinearVel = 0.0f;
m_frequencyFactor = 1.0f;
m_unk0x1c = 0;
m_unk0x10 = 0.65f;
m_unk0x14 = 0.03f;
m_unk0x18 = 0.6f;
m_unk0x140 = 0.1f;
m_unk0x150 = -5.0f;
m_unk0x148 = 1;
VariableTable()->SetVariable(g_fuel, "0.8");
}
// FUNCTION: LEGO1 0x10080590
// FUNCTION: BETA10 0x100cd8cf
void LegoCarRaceActor::FUN_10080590(float p_float)
{
MxFloat maxSpeed = m_maxLinearVel;
Mx3DPointFloat destEdgeUnknownVector;
Mx3DPointFloat worldDirection = Mx3DPointFloat(m_roi->GetWorldDirection());
m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector);
if (abs(destEdgeUnknownVector.Dot(destEdgeUnknownVector.GetData(), worldDirection.GetData())) > 0.5) {
maxSpeed *= m_unk0x10;
}
MxS32 deltaUnk0x70;
LegoPathActor* userActor = UserActor();
if (userActor) {
// All known implementations of LegoPathActor->VTable0x5c() return LegoPathActor::m_unk0x70
deltaUnk0x70 = m_unk0x70 - userActor->VTable0x5c();
}
else {
deltaUnk0x70 = 0;
}
if (deltaUnk0x70 > 1) {
if (deltaUnk0x70 > 3) {
deltaUnk0x70 = 3;
}
maxSpeed *= (m_unk0x18 * (--deltaUnk0x70) * -0.25f + 1.0f);
}
else if (deltaUnk0x70 < -1) {
maxSpeed *= 1.3;
}
MxFloat deltaSpeed = maxSpeed - m_worldSpeed;
MxFloat changeInSpeed = (p_float - m_unk0x1c) * m_unk0x14;
m_unk0x1c = p_float;
if (deltaSpeed < 0.0f) {
changeInSpeed = -changeInSpeed;
}
MxFloat newWorldSpeed = changeInSpeed + m_worldSpeed;
if (newWorldSpeed > maxSpeed) {
newWorldSpeed = maxSpeed;
}
SetWorldSpeed(newWorldSpeed);
}
// FUNCTION: LEGO1 0x10080740
// FUNCTION: BETA10 0x100cece0
MxS32 LegoCarRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge)
{
Mx3DPointFloat pointUnknown;
Mx3DPointFloat destEdgeUnknownVector;
Mx3DPointFloat crossProduct;
if (m_state == 1) {
m_boundary = NULL;
// Not sure where the upper bound of 11 comes from, the underlying array has a size of 16
for (MxS32 i = 0; i < 11; i += 2) {
if (LegoPathController::GetControlEdgeA(i + 1) == m_destEdge) {
m_boundary = LegoPathController::GetControlBoundaryA(i + 1);
break;
}
}
assert(m_boundary);
m_state = 0;
m_unk0x7c = 0;
if (m_userNavFlag) {
NavController()->SetLinearVel(m_worldSpeed);
return 0;
}
else {
return 1;
}
}
else {
for (MxS32 i = 0; i < 11; i += 2) {
if (LegoPathController::GetControlEdgeA(i) == p_edge) {
m_state = 1;
if (m_worldSpeed < g_unk0x100f7aec) {
m_worldSpeed = g_unk0x100f7aec;
}
m_destEdge = LegoPathController::GetControlEdgeA(i + 1);
m_boundary = LegoPathController::GetControlBoundaryA(i + 1);
break;
}
}
if (m_state == 1) {
if (m_userNavFlag) {
m_unk0xe4 = 0.5f;
}
// variable names verified by BETA10
Vector3* v1 = m_destEdge->CCWVertex(*m_boundary);
Vector3* v2 = m_destEdge->CWVertex(*m_boundary);
assert(v1 && v2);
pointUnknown[0] = (*v1)[0] + ((*v2)[0] - (*v1)[0]) * m_unk0xe4;
pointUnknown[1] = (*v1)[1] + ((*v2)[1] - (*v1)[1]) * m_unk0xe4;
pointUnknown[2] = (*v1)[2] + ((*v2)[2] - (*v1)[2]) * m_unk0xe4;
m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector);
crossProduct.EqualsCross(m_boundary->GetUnknown0x14(), &destEdgeUnknownVector);
crossProduct.Unitize();
Mx3DPointFloat worldDirection(Vector3(m_roi->GetWorldDirection()));
if (!m_userNavFlag) {
((Vector3*) &worldDirection)->Mul(-1.0f);
}
((Vector3*) &worldDirection)->Mul(5.0f);
((Vector3*) &crossProduct)->Mul(5.0f);
MxResult callResult =
VTable0x80(Vector3(m_roi->GetWorldPosition()), worldDirection, pointUnknown, crossProduct);
if (callResult) {
m_unk0x7c = 0;
return 0;
}
else {
m_unk0x7c = 0;
assert(0);
return 0; // BETA10 returns -1 here
}
}
else {
// This `for` loop does not exist in BETA10
for (MxS32 i = 0; i < 10; i++) {
if (LegoPathController::GetControlEdgeB(i) == p_edge &&
LegoPathController::GetControlBoundaryB(i) == m_boundary) {
return 0;
}
}
return 1;
}
}
}
// FUNCTION: LEGO1 0x10080b40
// FUNCTION: BETA10 0x100cdb3c
void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4)
{
LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4);
}
// STUB: LEGO1 0x10080b70
void LegoCarRaceActor::VTable0x70(float p_float)
{
// TODO
}
// STUB: LEGO1 0x10080be0
MxResult LegoCarRaceActor::VTable0x9c()
{
// TODO
return SUCCESS;
}
// STUB: LEGO1 0x10081840
MxU32 LegoCarRaceActor::VTable0x6c(
LegoPathBoundary* p_boundary,
Vector3& p_v1,
Vector3& p_v2,
float p_f1,
float p_f2,
Vector3& p_v3
)
{
// TODO
return 0;
}

View file

@ -1,5 +1,6 @@
#include "legoedge.h"
#include "assert.h"
#include "decomp.h"
DECOMP_SIZE_ASSERT(LegoEdge, 0x24)
@ -51,13 +52,27 @@ LegoEdge* LegoEdge::GetCounterclockwiseEdge(LegoWEEdge& p_face)
}
// FUNCTION: LEGO1 0x1009a510
// FUNCTION: BETA10 0x10182433
Vector3* LegoEdge::CWVertex(LegoWEEdge& p_face)
{
return &p_face == m_faceA ? m_pointB : m_pointA;
if (m_faceA == &p_face) {
return m_pointB;
}
else {
assert(m_faceB == &p_face);
return m_pointA;
}
}
// FUNCTION: LEGO1 0x1009a530
// FUNCTION: BETA10 0x10182498
Vector3* LegoEdge::CCWVertex(LegoWEEdge& p_face)
{
return &p_face == m_faceB ? m_pointB : m_pointA;
if (m_faceB == &p_face) {
return m_pointB;
}
else {
assert(m_faceA == &p_face);
return m_pointA;
}
}

View file

@ -1,5 +1,7 @@
#include "legoweedge.h"
#include "legounkown100db7f4.h"
DECOMP_SIZE_ASSERT(LegoWEEdge, 0x0c)
// FUNCTION: LEGO1 0x1009a550
@ -21,8 +23,8 @@ LegoWEEdge::~LegoWEEdge()
LegoResult LegoWEEdge::VTable0x04()
{
for (LegoS32 i = 0; i < m_numEdges; i++) {
LegoEdge* e1 = m_edges[i];
LegoEdge* e2 = (m_numEdges - i) == 1 ? m_edges[0] : m_edges[i + 1];
LegoUnknown100db7f4* e1 = m_edges[i];
LegoUnknown100db7f4* e2 = (m_numEdges - i) == 1 ? m_edges[0] : m_edges[i + 1];
if (e2->m_pointA == e1->m_pointA) {
e1->m_faceA = this;

View file

@ -2,9 +2,10 @@
#define __LEGOWEEDGE_H
#include "decomp.h"
#include "legoedge.h"
#include "misc/legotypes.h"
struct LegoUnknown100db7f4;
// might be a struct with public members
// VTABLE: LEGO1 0x100db7c0
// SIZE 0x0c
@ -18,13 +19,13 @@ class LegoWEEdge {
LegoU8 GetNumEdges() { return m_numEdges; }
// FUNCTION: BETA10 0x1001cc30
LegoEdge** GetEdges() { return m_edges; }
LegoUnknown100db7f4** GetEdges() { return m_edges; }
// TODO: The assertion at BETA10 0x10037352 suggests that this function might take a pointer instead of a reference
// FUNCTION: BETA10 0x100373f0
LegoU32 IsEqual(LegoWEEdge& p_other) { return this == &p_other; }
void SetEdges(LegoEdge** p_edges, LegoU8 p_numEdges)
void SetEdges(LegoUnknown100db7f4** p_edges, LegoU8 p_numEdges)
{
m_edges = p_edges;
m_numEdges = p_numEdges;
@ -35,7 +36,7 @@ class LegoWEEdge {
protected:
LegoU8 m_numEdges; // 0x04
LegoEdge** m_edges; // 0x08
LegoUnknown100db7f4** m_edges; // 0x08
};
#endif // __LEGOWEEDGE_H

View file

@ -41,7 +41,10 @@ class LegoWEGEdge : public LegoWEEdge {
LegoResult VTable0x04() override; // vtable+0x04
LegoU32 GetFlag0x10() { return m_flags & c_bit5 ? FALSE : TRUE; }
// FUNCTION: BETA10 0x1001ff80
Mx4DPointFloat* GetUnknown0x14() { return &m_unk0x14; }
Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; }
// FUNCTION: BETA10 0x1001c9b0

View file

@ -16,7 +16,7 @@ LegoUnknown::~LegoUnknown()
}
// FUNCTION: LEGO1 0x1009a140
void LegoUnknown::FUN_1009a140(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4)
void LegoUnknown::FUN_1009a140(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4)
{
m_unk0x00[0] = p_point1;
m_unk0x00[1] = p_point2;

View file

@ -12,7 +12,7 @@ class LegoUnknown {
LegoUnknown();
~LegoUnknown();
void FUN_1009a140(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4);
void FUN_1009a140(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4);
LegoResult FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und);
private:

View file

@ -18,6 +18,7 @@ class Mx3DPointFloat : public Vector3 {
}
// FUNCTION: LEGO1 0x100343a0
// FUNCTION: BETA10 0x10011600
Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }
Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }

View file

@ -10,10 +10,12 @@
// The class needs to undergo a very careful refactoring to fix that (no matches should break).
// VTABLE: LEGO1 0x100d4288
// VTABLE: BETA10 0x101b8440
// SIZE 0x08
class Vector2 {
public:
// FUNCTION: LEGO1 0x1000c0f0
// FUNCTION: BETA10 0x100116a0
Vector2(float* p_data) { SetData(p_data); }
// Note: virtual function overloads appear in the virtual table
@ -68,6 +70,7 @@ class Vector2 {
virtual float DotImpl(float* p_a, float* p_b) const { return p_b[0] * p_a[0] + p_b[1] * p_a[1]; } // vtable+0x18
// FUNCTION: LEGO1 0x10002060
// FUNCTION: BETA10 0x10010c90
virtual void SetData(float* p_data) { m_data = p_data; } // vtable+0x1c
// FUNCTION: LEGO1 0x10002070
@ -86,6 +89,7 @@ class Vector2 {
virtual float Dot(float* p_a, float* p_b) const { return DotImpl(p_a, p_b); } // vtable+0x3c
// FUNCTION: LEGO1 0x100020f0
// FUNCTION: BETA10 0x100028f6
virtual float Dot(Vector2* p_a, Vector2* p_b) const { return DotImpl(p_a->m_data, p_b->m_data); } // vtable+0x38
// FUNCTION: LEGO1 0x10002110
@ -98,6 +102,7 @@ class Vector2 {
virtual float LenSquared() const { return m_data[0] * m_data[0] + m_data[1] * m_data[1]; } // vtable+0x40
// FUNCTION: LEGO1 0x10002160
// FUNCTION: BETA10 0x10010900
virtual int Unitize()
{
float sq = LenSquared();
@ -154,7 +159,11 @@ class Vector2 {
Vector2::SetVector(&p_other);
return *this;
}
// FUNCTION: BETA10 0x10013460
float& operator[](int idx) { return m_data[idx]; }
// FUNCTION: BETA10 0x1001d140
const float& operator[](int idx) const { return m_data[idx]; }
protected:
@ -188,6 +197,7 @@ class Vector3 : public Vector2 {
} // vtable+0x74
// FUNCTION: LEGO1 0x100022c0
// FUNCTION: BETA10 0x10011430
virtual void EqualsCross(Vector3* p_a, Vector3* p_b) { EqualsCrossImpl(p_a->m_data, p_b->m_data); } // vtable+0x80
// FUNCTION: LEGO1 0x100022e0
@ -261,10 +271,11 @@ class Vector3 : public Vector2 {
} // vtable+0x18
// FUNCTION: LEGO1 0x10003ba0
// FUNCTION: BETA10 0x100113f0
void EqualsImpl(float* p_data) override { memcpy(m_data, p_data, sizeof(float) * 3); } // vtable+0x20
// FUNCTION: LEGO1 0x10003bc0
// FUNCTION: BETA10 0x101b84fc
// FUNCTION: BETA10 0x1000132a
void Clear() override { memset(m_data, 0, sizeof(float) * 3); } // vtable+0x2c
// FUNCTION: LEGO1 0x10003bd0