From 1a15981324c299184d930d4ac3b648caa9fb3ae3 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sun, 6 Oct 2024 01:20:45 +0200 Subject: [PATCH] Implement `LegoCarBuildAnimPresenter::StreamingTickle()` (#1109) * Implement LegoCarBuildAnimPresenter::StreamingTickle and dependents * Fix naming issue * Address review comment --------- Co-authored-by: jonschz --- .../legoomni/include/legocarbuildpresenter.h | 8 +- LEGO1/lego/legoomni/include/legoutils.h | 1 + .../lego/legoomni/include/legovideomanager.h | 2 + .../src/build/legocarbuildpresenter.cpp | 140 +++++++++++++++++- LEGO1/lego/legoomni/src/common/legoutils.cpp | 2 + LEGO1/lego/legoomni/src/entity/legoentity.cpp | 1 + LEGO1/lego/legoomni/src/entity/legoworld.cpp | 1 + .../lego/sources/3dmanager/lego3dmanager.cpp | 1 + LEGO1/lego/sources/3dmanager/lego3dview.cpp | 1 + LEGO1/lego/sources/anim/legoanim.h | 4 + LEGO1/lego/sources/misc/legotree.h | 7 + LEGO1/lego/sources/roi/legoroi.cpp | 20 +++ LEGO1/lego/sources/roi/legoroi.h | 2 + LEGO1/library_msvc.h | 7 + LEGO1/mxgeometry/mxgeometry3d.h | 10 +- LEGO1/omni/include/mxdsobject.h | 2 + LEGO1/realtime/matrix.h | 2 + LEGO1/realtime/orientableroi.h | 2 + LEGO1/realtime/realtime.cpp | 1 + LEGO1/realtime/vector.h | 17 ++- 20 files changed, 216 insertions(+), 15 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h index 8084da7c..b7b02d52 100644 --- a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h +++ b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h @@ -45,7 +45,11 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { void EndAction() override; // vtable+0x40 void PutFrame() override; // vtable+0x6c + void FUN_10079050(MxS16 p_index); + void FUN_10079090(LegoChar* p_param1, LegoChar* p_param2); void FUN_10079160(); + void FUN_100795d0(LegoChar* p_param); + void FUN_10079680(LegoChar* p_param); void RotateAroundYAxis(MxFloat p_angle); MxBool FUN_10079c30(const LegoChar* p_name); MxBool FUN_10079ca0(const LegoChar* p_name); @@ -77,7 +81,9 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { LegoEntity* m_unk0x140; // 0x140 MxS32 m_unk0x144; // 0x144 MxS32 m_unk0x148; // 0x148 - undefined* m_unk0x14c; // 0x14c + + // name verified by BETA10 0x10070d63 + LegoChar* m_mainSourceId; // 0x14c }; #endif // LEGOCARBUILDPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index 9e8c91fc..b6143c36 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -43,6 +43,7 @@ void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2); MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3]); MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]); MxS16 CountTotalTreeNodes(LegoTreeNode* p_node); +LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index); void FUN_1003e050(LegoAnimPresenter* p_presenter); Extra::ActionType MatchActionString(const char*); void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender); diff --git a/LEGO1/lego/legoomni/include/legovideomanager.h b/LEGO1/lego/legoomni/include/legovideomanager.h index edfd345e..605d0626 100644 --- a/LEGO1/lego/legoomni/include/legovideomanager.h +++ b/LEGO1/lego/legoomni/include/legovideomanager.h @@ -53,7 +53,9 @@ class LegoVideoManager : public MxVideoManager { // FUNCTION: BETA10 0x100117e0 Lego3DManager* Get3DManager() { return m_3dManager; } + // FUNCTION: BETA10 0x1003a380 LegoROI* GetViewROI() { return m_viewROI; } + MxDirect3D* GetDirect3D() { return m_direct3d; } MxBool GetRender3D() { return m_render3d; } double GetElapsedSeconds() { return m_elapsedSeconds; } diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp index 29b35d21..5bd69f58 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp @@ -1,7 +1,13 @@ #include "legocarbuildpresenter.h" +#include "3dmanager/lego3dmanager.h" #include "legoentity.h" +#include "legogamestate.h" +#include "legoutils.h" +#include "legovideomanager.h" +#include "misc.h" #include "mxautolock.h" +#include "realtime/realtime.h" DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter::UnknownListEntry, 0x0c) DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter, 0x150) @@ -23,7 +29,7 @@ LegoCarBuildAnimPresenter::LegoCarBuildAnimPresenter() m_unk0x140 = NULL; m_unk0x144 = -1; m_unk0x148 = -1; - m_unk0x14c = NULL; + m_mainSourceId = NULL; } // FUNCTION: LEGO1 0x10078500 @@ -47,8 +53,8 @@ LegoCarBuildAnimPresenter::~LegoCarBuildAnimPresenter() m_unk0xc8.GetRoot()->SetNumChildren(0); *m_unk0xc8.GetRoot()->GetChildren() = NULL; - if (m_unk0x14c) { - delete m_unk0x14c; + if (m_mainSourceId) { + delete[] m_mainSourceId; } } @@ -65,11 +71,103 @@ void LegoCarBuildAnimPresenter::ReadyTickle() // TODO } -// STUB: LEGO1 0x100789e0 -// STUB: BETA10 0x10070cdd +// FUNCTION: LEGO1 0x100789e0 +// FUNCTION: BETA10 0x10070cdd void LegoCarBuildAnimPresenter::StreamingTickle() { - // TODO + if (!m_unk0x140->GetROI()) { + return; + } + + m_mainSourceId = new LegoChar[strlen(m_action->GetAtomId().GetInternal()) + 1]; + assert(m_mainSourceId); + + strcpy(m_mainSourceId, m_action->GetAtomId().GetInternal()); + m_mainSourceId[strlen(m_mainSourceId) - 1] = 'M'; + + FUN_10079160(); + + if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { + m_unk0xc0 = 10; + } + + MxS16 i; + + for (i = 0; i < m_unk0xbe; i++) { + if (m_unk0xc0 == i) { + FUN_10079680(m_unk0x128[i].m_unk0x04); + } + else { + FUN_100795d0(m_unk0x128[i].m_unk0x04); + } + + if (i < m_unk0xc0) { + FUN_10079050(i); + FUN_10079680(m_unk0x128[i].m_unk0x00); + } + + LegoChar* name = m_unk0x128[i].m_unk0x04; + + if (name) { + for (MxS32 j = 0; j <= m_roiMapSize; j++) { + LegoROI* roi = m_roiMap[j]; + + if (roi && roi->GetName() && (strcmpi(name, roi->GetName()) == 0)) { + roi->FUN_100a9dd0(); + roi->FUN_100a9350("lego red"); + } + } + } + } + + LegoVideoManager* videoManager = VideoManager(); + assert(videoManager); // verifies variable name 'videoManager' + + Lego3DView* lego3dview = videoManager->Get3DManager()->GetLego3DView(); + LegoROI* videoManagerROI = videoManager->GetViewROI(); + LegoROI* local60 = m_unk0x140->GetROI(); + LegoROI* camera = NULL; + MxFloat fov; + + MxS16 totalNodes = CountTotalTreeNodes(m_anim->GetRoot()); + + for (i = 0; i < totalNodes; i++) { + LegoAnimNodeData* animNodeData = (LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData(); + + if (strnicmp(animNodeData->GetName(), "CAM", strlen("CAM")) == 0) { + camera = local60->FindChildROI(animNodeData->GetName(), local60); + fov = atof(&animNodeData->GetName()[strlen(animNodeData->GetName()) - 2]); + break; + } + } + + assert(camera); // verifies variable name 'camera' + + LegoROI* targetROI = local60->FindChildROI("TARGET", local60); + + Mx3DPointFloat dirVec; + + Vector3 cameraPosition(camera->GetWorldPosition()); + Vector3 upVec(camera->GetWorldUp()); + Vector3 targetPosition(targetROI->GetWorldPosition()); + + MxMatrix localTransform; + + dirVec[0] = targetPosition[0] - cameraPosition[0]; + dirVec[1] = targetPosition[1] - cameraPosition[1]; + dirVec[2] = targetPosition[2] - cameraPosition[2]; + dirVec.Unitize(); + + CalcLocalTransform(cameraPosition, dirVec, upVec, localTransform); + + videoManagerROI->WrappedSetLocalTransform(localTransform); + lego3dview->Moved(*videoManagerROI); + videoManager->Get3DManager()->SetFrustrum(fov, 0.1, 250.0); + + m_unk0xe0 = local60->FindChildROI("VIEW", local60)->GetLocal2World(); + + m_previousTickleStates |= 1 << m_currentTickleState; + m_currentTickleState = e_repeating; } // FUNCTION: LEGO1 0x10078db0 @@ -83,13 +181,43 @@ void LegoCarBuildAnimPresenter::EndAction() } } +// FUNCTION: LEGO1 0x10079050 +// FUNCTION: BETA10 0x1007151e +void LegoCarBuildAnimPresenter::FUN_10079050(MxS16 p_index) +{ + FUN_10079090(m_unk0x128[p_index].m_unk0x04, m_unk0x128[p_index].m_unk0x00); + FUN_100795d0(m_unk0x128[p_index].m_unk0x04); +} + +// STUB: LEGO1 0x10079090 +// STUB: BETA10 0x10071584 +void LegoCarBuildAnimPresenter::FUN_10079090(LegoChar* p_param1, LegoChar* p_param2) +{ + // TODO +} + // STUB: LEGO1 0x10079160 +// STUB: BETA10 0x1007165d void LegoCarBuildAnimPresenter::FUN_10079160() { // called from LegoCarBuildAnimPresenter::StreamingTickle() // TODO } +// STUB: LEGO1 0x100795d0 +// STUB: BETA10 0x10071d96 +void LegoCarBuildAnimPresenter::FUN_100795d0(LegoChar* p_param) +{ + // TODO +} + +// STUB: LEGO1 0x10079680 +// STUB: BETA10 0x10071ec5 +void LegoCarBuildAnimPresenter::FUN_10079680(LegoChar* p_param) +{ + // TODO +} + // FUNCTION: LEGO1 0x10079920 // FUNCTION: BETA10 0x1007225d void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle) diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 266ac1b1..d90e655e 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -106,6 +106,7 @@ MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]) } // FUNCTION: LEGO1 0x1003df90 +// FUNCTION: BETA10 0x100d39a3 MxS16 CountTotalTreeNodes(LegoTreeNode* p_node) { MxS16 result = 1; @@ -118,6 +119,7 @@ MxS16 CountTotalTreeNodes(LegoTreeNode* p_node) } // FUNCTION: LEGO1 0x1003dfd0 +// FUNCTION: BETA10 0x100d3a09 LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index) { LegoTreeNode* result = NULL; diff --git a/LEGO1/lego/legoomni/src/entity/legoentity.cpp b/LEGO1/lego/legoomni/src/entity/legoentity.cpp index f59c83a9..81cb3fe3 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentity.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentity.cpp @@ -213,6 +213,7 @@ Mx3DPointFloat LegoEntity::GetWorldUp() } // FUNCTION: LEGO1 0x10010d80 +// FUNCTION: BETA10 0x1007ebbe Mx3DPointFloat LegoEntity::GetWorldPosition() { if (m_roi != NULL) { diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index eafc5e1e..822121e6 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -380,6 +380,7 @@ void LegoWorld::AddPath(LegoPathController* p_controller) } // FUNCTION: LEGO1 0x10020020 +// FUNCTION: BETA10 0x100da77c LegoPathBoundary* LegoWorld::FindPathBoundary(const char* p_name) { LegoPathControllerListCursor cursor(&m_list0x68); diff --git a/LEGO1/lego/sources/3dmanager/lego3dmanager.cpp b/LEGO1/lego/sources/3dmanager/lego3dmanager.cpp index 1781870a..750f54c6 100644 --- a/LEGO1/lego/sources/3dmanager/lego3dmanager.cpp +++ b/LEGO1/lego/sources/3dmanager/lego3dmanager.cpp @@ -97,6 +97,7 @@ double Lego3DManager::Render(double p_und) } // FUNCTION: LEGO1 0x100ab4d0 +// FUNCTION: BETA10 0x1017baeb int Lego3DManager::SetFrustrum(float p_fov, float p_front, float p_back) { m_pLego3DView->GetView()->SetFrustrum(p_front, p_back, p_fov); diff --git a/LEGO1/lego/sources/3dmanager/lego3dview.cpp b/LEGO1/lego/sources/3dmanager/lego3dview.cpp index e895e378..4f69fa40 100644 --- a/LEGO1/lego/sources/3dmanager/lego3dview.cpp +++ b/LEGO1/lego/sources/3dmanager/lego3dview.cpp @@ -119,6 +119,7 @@ BOOL Lego3DView::SetPointOfView(ViewROI& rROI) } // FUNCTION: LEGO1 0x100ab210 +// FUNCTION: BETA10 0x1017d230 BOOL Lego3DView::Moved(ViewROI& rROI) { assert(m_pViewManager); diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 0badeae9..62816ba9 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -148,7 +148,9 @@ class LegoAnimNodeData : public LegoTreeNodeData { LegoResult CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix); LegoBool FUN_100a0990(LegoFloat p_time); + // FUNCTION: BETA10 0x100595d0 const LegoChar* GetName() { return m_name; } + LegoU32 GetTranslationIndex() { return m_translationIndex; } LegoU32 GetRotationIndex() { return m_rotationIndex; } LegoU32 GetScaleIndex() { return m_scaleIndex; } @@ -164,6 +166,8 @@ class LegoAnimNodeData : public LegoTreeNodeData { void SetScaleIndex(LegoU32 p_scaleIndex) { m_scaleIndex = p_scaleIndex; } void SetMorphIndex(LegoU32 p_morphIndex) { m_morphIndex = p_morphIndex; } void SetUnknown0x20(LegoU16 p_unk0x20) { m_unk0x20 = p_unk0x20; } + + // FUNCTION: BETA10 0x1005f2e0 void SetUnknown0x22(LegoU16 p_unk0x22) { m_unk0x22 = p_unk0x22; } LegoResult CreateLocalTransform(LegoTime p_time, Matrix4& p_matrix) diff --git a/LEGO1/lego/sources/misc/legotree.h b/LEGO1/lego/sources/misc/legotree.h index fb97a612..fea8d5ec 100644 --- a/LEGO1/lego/sources/misc/legotree.h +++ b/LEGO1/lego/sources/misc/legotree.h @@ -32,14 +32,21 @@ class LegoTreeNode { public: LegoTreeNode(); virtual ~LegoTreeNode(); + + // FUNCTION: BETA10 0x100595a0 LegoTreeNodeData* GetData() { return m_data; } + void SetData(LegoTreeNodeData* p_data) { m_data = p_data; } + + // FUNCTION: BETA10 0x10012150 LegoU32 GetNumChildren() { return m_numChildren; } // FUNCTION: BETA10 0x10073370 void SetNumChildren(LegoU32 p_numChildren) { m_numChildren = p_numChildren; } + // FUNCTION: BETA10 0x10012180 LegoTreeNode* GetChild(LegoU32 p_i) { return m_children[p_i]; } + void SetChild(LegoU32 p_i, LegoTreeNode* p_child) { m_children[p_i] = p_child; } // FUNCTION: BETA10 0x100733a0 diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index a11436f3..94fed7c6 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -341,6 +341,7 @@ LegoResult LegoROI::FUN_100a8cb0(LegoAnimNodeData* p_data, LegoTime p_time, Matr } // FUNCTION: LEGO1 0x100a8ce0 +// FUNCTION: BETA10 0x1018a815 LegoROI* LegoROI::FindChildROI(const LegoChar* p_name, LegoROI* p_roi) { CompoundObject::iterator it; @@ -551,6 +552,18 @@ LegoResult LegoROI::GetTexture(LegoTextureInfo*& p_textureInfo) return FAILURE; } +// FUNCTION: LEGO1 0x100a9350 +// FUNCTION: BETA10 0x1018b25c +LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color) +{ + MxFloat red, green, blue, alpha; + if (ColorAliasLookup(p_color, red, green, blue, alpha)) { + return FUN_100a9170(red, green, blue, alpha); + } + + return SUCCESS; +} + // FUNCTION: LEGO1 0x100a9410 // FUNCTION: BETA10 0x1018b324 LegoU32 LegoROI::FUN_100a9410( @@ -778,6 +791,13 @@ void LegoROI::SetName(const LegoChar* p_name) } } +// STUB: LEGO1 0x100a9dd0 +// STUB: BETA10 0x1018bfdb +void LegoROI::FUN_100a9dd0() +{ + // TODO +} + // FUNCTION: LEGO1 0x100a9e10 void LegoROI::SetDisplayBB(int p_displayBB) { diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index fb96b2a5..babb566a 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -38,12 +38,14 @@ class LegoROI : public ViewROI { LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo); LegoResult GetTexture(LegoTextureInfo*& p_textureInfo); + LegoResult FUN_100a9350(const LegoChar* p_color); LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox); void SetName(const LegoChar* p_name); float IntrinsicImportance() const override; // vtable+0x04 void UpdateWorldBoundingVolumes() override; // vtable+0x18 + void FUN_100a9dd0(); void SetDisplayBB(int p_displayBB); static LegoResult FUN_100a8cb0(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix); diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 5df6786c..b9a1359c 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -482,6 +482,7 @@ // __setmode_lk // LIBRARY: LEGO1 0x100d1ed0 +// LIBRARY: BETA10 0x1018ec70 // _strnicmp // LIBRARY: LEGO1 0x100d1fd0 @@ -682,6 +683,9 @@ // LIBRARY: BETA10 0x100f9780 // strlen +// LIBRARY: BETA10 0x100fa200 +// strcpy + // LIBRARY: BETA10 0x100f8a88 // operator new @@ -703,6 +707,9 @@ // LIBRARY: BETA10 0x100fe5a0 // abort +// LIBRARY: BETA10 0x100fa0e0 +// atof + // LIBRARY: BETA10 0x100ff82b // __ctrandisp1 diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index f73d5d8a..f09ea244 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -6,10 +6,15 @@ #include "realtime/vector.h" // VTABLE: LEGO1 0x100d4488 +// VTABLE: BETA10 0x101b84d0 // SIZE 0x14 class Mx3DPointFloat : public Vector3 { public: + // FUNCTION: LEGO1 0x1001d170 + // FUNCTION: BETA10 0x10011990 Mx3DPointFloat() : Vector3(m_elements) {} + + // FUNCTION: BETA10 0x10011870 Mx3DPointFloat(float p_x, float p_y, float p_z) : Vector3(m_elements) { m_elements[0] = p_x; @@ -24,9 +29,6 @@ class Mx3DPointFloat : public Vector3 { // FUNCTION: BETA10 0x100151e0 Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } - // SYNTHETIC: LEGO1 0x1001d170 - // Mx3DPointFloat::Mx3DPointFloat - // FUNCTION: LEGO1 0x10003c10 virtual void operator=(const Vector3& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x88 @@ -34,7 +36,9 @@ class Mx3DPointFloat : public Vector3 { float GetY() { return m_data[1]; } float GetZ() { return m_data[2]; } + // FUNCTION: BETA10 0x10013460 float& operator[](int idx) { return m_data[idx]; } + const float& operator[](int idx) const { return m_data[idx]; } // SYNTHETIC: LEGO1 0x10010c00 diff --git a/LEGO1/omni/include/mxdsobject.h b/LEGO1/omni/include/mxdsobject.h index 3bb0a3ff..eb80044b 100644 --- a/LEGO1/omni/include/mxdsobject.h +++ b/LEGO1/omni/include/mxdsobject.h @@ -69,7 +69,9 @@ class MxDSObject : public MxCore { // FUNCTION: BETA10 0x10017910 MxU32 GetObjectId() { return m_objectId; } + // FUNCTION: BETA10 0x10017940 const MxAtomId& GetAtomId() { return m_atomId; } + MxS16 GetUnknown24() { return m_unk0x24; } MxPresenter* GetUnknown28() { return m_unk0x28; } diff --git a/LEGO1/realtime/matrix.h b/LEGO1/realtime/matrix.h index 181acedf..8f9f63fe 100644 --- a/LEGO1/realtime/matrix.h +++ b/LEGO1/realtime/matrix.h @@ -183,6 +183,7 @@ class Matrix4 { }; // FUNCTION: LEGO1 0x10002550 +// FUNCTION: BETA10 0x100101c0 inline void Matrix4::ToQuaternion(Vector4& p_outQuat) { float trace = m_data[0][0] + m_data[1][1] + m_data[2][2]; @@ -223,6 +224,7 @@ inline void Matrix4::ToQuaternion(Vector4& p_outQuat) } // FUNCTION: LEGO1 0x10002710 +// FUNCTION: BETA10 0x10010550 inline int Matrix4::FromQuaternion(const Vector4& p_vec) { float len = p_vec.LenSquared(); diff --git a/LEGO1/realtime/orientableroi.h b/LEGO1/realtime/orientableroi.h index 61b61645..5e70aa5e 100644 --- a/LEGO1/realtime/orientableroi.h +++ b/LEGO1/realtime/orientableroi.h @@ -48,7 +48,9 @@ class OrientableROI : public ROI { // FUNCTION: BETA10 0x10011780 const float* GetWorldDirection() const { return m_local2world[2]; } + // FUNCTION: BETA10 0x1004aa70 const float* GetWorldUp() const { return m_local2world[1]; } + OrientableROI* GetParentROI() const { return m_parentROI; } void SetParentROI(OrientableROI* p_parentROI) { m_parentROI = p_parentROI; } diff --git a/LEGO1/realtime/realtime.cpp b/LEGO1/realtime/realtime.cpp index 829b2271..944b093c 100644 --- a/LEGO1/realtime/realtime.cpp +++ b/LEGO1/realtime/realtime.cpp @@ -3,6 +3,7 @@ #include // FUNCTION: LEGO1 0x100a5b40 +// FUNCTION: BETA10 0x10168127 void CalcLocalTransform(const Vector3& p_posVec, const Vector3& p_dirVec, const Vector3& p_upVec, Matrix4& p_outMatrix) { float x_axis[3], y_axis[3], z_axis[3]; diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 3faa559e..6d0803b9 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -163,13 +163,18 @@ class Vector2 { return *this; } - // SYNTHETIC: BETA10 0x10013460 - // Vector3::operator[] - - // FUNCTION: BETA10 0x10010890 - float& operator[](int idx) { return m_data[idx]; } + // There is another candidate for `Vector2::operator[]` at BETA10 0x10010890, which is called from only three + // functions in BETA10: + // - `Matrix4::FromQuaternion()` + // - `Matrix4::ToQuaternion()` + // - `UnknownMx4DPointFloat::FUN_100040a0()` + // Maybe there is another subclass of `Vector4` involved that has the same VTABLE but a different `operator[]`. + // It is also interesting that `Matrix4::operator[]` is located right above at BETA10 0x10010860. // FUNCTION: BETA10 0x1001d140 + float& operator[](int idx) { return m_data[idx]; } + + // FUNCTION: BETA10 0x1001d170 const float& operator[](int idx) const { return m_data[idx]; } protected: @@ -189,6 +194,8 @@ class Vector3 : public Vector2 { // Example: LegoCameraController::GetWorldUp // Vector3 however is a class that can mutate its underlying source, making // initialization with a const source fundamentally incompatible. + + // FUNCTION: BETA10 0x100109a0 Vector3(const float* p_data) : Vector2((float*) p_data) {} // Note: virtual function overloads appear in the virtual table