From aab6a17d2f76b3db7b89c46199b4a190186873e4 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 18 May 2024 11:48:07 -0400 Subject: [PATCH] Implement/match LegoAnimationManager::FUN_10064120 (#932) * Implement/match LegoAnimationManager::FUN_10064120 * Fix naming * Fix parentheses --- .../legoomni/include/legoanimationmanager.h | 4 +- .../src/common/legoanimationmanager.cpp | 102 +++++++++++++++++- LEGO1/lego/sources/geom/legounkown100db7f4.h | 20 +++- LEGO1/lego/sources/geom/legowegedge.h | 4 + 4 files changed, 125 insertions(+), 5 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 30d4670b..439b9346 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -15,6 +15,7 @@ class LegoExtraActor; class LegoFile; class LegoPathBoundary; class LegoROIList; +struct LegoUnknown100db7f4; class LegoWorld; struct ModelInfo; class MxDSAction; @@ -151,7 +152,8 @@ class LegoAnimationManager : public MxCore { MxBool FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_actor, MxU8 p_unk0x14, MxU32 p_characterId); void FUN_10063d10(); MxBool FUN_10063fb0(LegoLocation::Boundary* p_boundary, LegoWorld* p_world); - MxBool FUN_10064120(LegoLocation::Boundary* p_boundary, MxBool, MxBool); + MxBool FUN_10064010(LegoPathBoundary*, LegoUnknown100db7f4*, float); + MxBool FUN_10064120(LegoLocation::Boundary* p_boundary, MxBool p_bool1, MxBool p_bool2); MxResult FUN_10064380( const char* p_name, const char* p_boundaryName, diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 54e81dcb..b4db53fd 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -2085,14 +2085,110 @@ MxBool LegoAnimationManager::FUN_10063fb0(LegoLocation::Boundary* p_boundary, Le return TRUE; } -// STUB: LEGO1 0x10064120 -// FUNCTION: BETA10 0x100454f5 -MxBool LegoAnimationManager::FUN_10064120(LegoLocation::Boundary* p_boundary, MxBool, MxBool) +// STUB: LEGO1 0x10064010 +// FUNCTION: BETA10 0x100453a5 +MxBool LegoAnimationManager::FUN_10064010(LegoPathBoundary*, LegoUnknown100db7f4*, float) { // TODO return TRUE; } +// FUNCTION: LEGO1 0x10064120 +// FUNCTION: BETA10 0x100454f5 +MxBool LegoAnimationManager::FUN_10064120(LegoLocation::Boundary* p_boundary, MxBool p_bool1, MxBool p_bool2) +{ + MxU32 local2c = 12; + float destScale = ((rand() * 0.5) / 32767.0) + 0.25; + IslePathActor* actor = CurrentActor(); + + if (actor == NULL) { + return FALSE; + } + + LegoPathBoundary* boundary = actor->GetBoundary(); + + if (boundary == NULL) { + return FALSE; + } + + Mx3DPointFloat direction = actor->GetWorldDirection(); + float local4c = 0.0f; + LegoUnknown100db7f4* local50 = NULL; + LegoS32 numEdges = boundary->GetNumEdges(); + Mx3DPointFloat vec; + LegoUnknown100db7f4* e; + MxS32 i; + + for (i = 0; i < numEdges; i++) { + e = (LegoUnknown100db7f4*) boundary->GetEdges()[i]; + e->FUN_1002ddc0(*boundary, vec); + float dot = vec.Dot(&direction, &vec); + + if (dot > local4c) { + local50 = e; + local4c = dot; + } + } + + e = local50; + do { + e = (LegoUnknown100db7f4*) e->GetCounterclockwiseEdge(boundary); + if (e->GetMask0x03()) { + break; + } + } while (e != local50); + + if (e == local50) { + return FALSE; + } + + LegoUnknown100db7f4* local34 = e; + LegoUnknown100db7f4* local8 = local50; + + while (local2c--) { + if (local34 != NULL) { + if (local34->Unknown(*boundary, LegoWEGEdge::c_bit1) && FUN_10064010(boundary, local34, destScale) && + (!p_bool2 || FUN_10064010(boundary, local8, destScale))) { + p_boundary->m_srcScale = p_boundary->m_destScale = destScale; + p_boundary->m_name = boundary->GetName(); + numEdges = boundary->GetNumEdges(); + + for (i = 0; i < numEdges; i++) { + LegoUnknown100db7f4* e = (LegoUnknown100db7f4*) boundary->GetEdges()[i]; + + if (local34 == e) { + p_boundary->m_src = i; + } + else if (local8 == e) { + p_boundary->m_dest = i; + } + } + + return TRUE; + } + + local8 = local34; + boundary = (LegoPathBoundary*) local34->OtherFace(boundary); + local50 = local34; + + do { + if (p_bool1) { + local34 = (LegoUnknown100db7f4*) local34->GetCounterclockwiseEdge(boundary); + } + else { + local34 = (LegoUnknown100db7f4*) local34->GetClockwiseEdge(boundary); + } + } while (!local34->GetMask0x03() && local34 != local50); + + if (local34 == local50) { + return FALSE; + } + } + } + + return FALSE; +} + // FUNCTION: LEGO1 0x10064380 // FUNCTION: BETA10 0x1004583a MxResult LegoAnimationManager::FUN_10064380( diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index 0a609d51..9bbffc03 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -2,7 +2,7 @@ #define __LEGOUNKNOWN100DB7F4_H #include "legoedge.h" -#include "legoweedge.h" +#include "legowegedge.h" #include "mxgeometry/mxgeometry3d.h" // VTABLE: LEGO1 0x100db7f4 @@ -34,6 +34,24 @@ struct LegoUnknown100db7f4 : public LegoEdge { return SUCCESS; } + // FUNCTION: BETA10 0x1004a830 + LegoU32 Unknown(LegoWEGEdge& p_face, LegoU8 p_mask) + { + return (p_face.IsEqual(*m_faceB) && (m_flags & c_bit1) && (p_face.GetMask0x03() & p_mask) == p_mask) || + (p_face.IsEqual(*m_faceA) && (m_flags & c_bit2) && (p_face.GetMask0x03() & p_mask) == p_mask); + } + + // FUNCTION: BETA10 0x1001cbe0 + LegoWEEdge* OtherFace(LegoWEEdge* p_other) + { + if (m_faceA == p_other) { + return m_faceB; + } + else { + return m_faceA; + } + } + LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } // SYNTHETIC: LEGO1 0x1009a6c0 diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index e8a0c396..d0599d84 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -13,6 +13,8 @@ struct LegoPathStruct; class LegoWEGEdge : public LegoWEEdge { public: enum { + c_bit1 = 0x01, + c_bit2 = 0x02, c_bit3 = 0x04, c_bit5 = 0x10 }; @@ -53,6 +55,8 @@ class LegoWEGEdge : public LegoWEEdge { } } + inline LegoU8 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } + // SYNTHETIC: LEGO1 0x1009a7e0 // LegoWEGEdge::`scalar deleting destructor'