From a7677023a11532e35825bd0d61ca5a5f6b85bad7 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Mon, 28 Nov 2022 01:26:24 +0200 Subject: [PATCH] Add CStateManager area_sorter Former-commit-id: 5af3c20f3ccdefa6956ddea697f62df9df0f2fea --- include/Kyoto/Graphics/CGraphics.hpp | 2 + include/Kyoto/Math/CFrustumPlanes.hpp | 18 ++--- include/MetroidPrime/CGameArea.hpp | 28 ++++++++ include/MetroidPrime/CStateManager.hpp | 7 ++ include/MetroidPrime/CWorld.hpp | 4 ++ include/rstl/iterator.hpp | 2 +- src/MetroidPrime/CStateManager.cpp | 65 +++++++++++++++++++ .../ScriptObjects/CScriptSpecialFunction.cpp | 5 +- 8 files changed, 119 insertions(+), 12 deletions(-) diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp index 20f3f3d2..a9960cd2 100644 --- a/include/Kyoto/Graphics/CGraphics.hpp +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -161,6 +161,7 @@ public: static void StreamEnd(); static const CViewport& GetViewport() { return mViewport; } + static const CVector3f& GetViewpoint() { return mViewpoint; } static const CTransform4f& GetViewMatrix() { return mViewMatrix; } static const CTransform4f& GetModelMatrix() { return mModelMatrix; } static void SetViewPointMatrix(const CTransform4f&); @@ -200,6 +201,7 @@ private: static CTransform4f mViewMatrix; static CTransform4f mModelMatrix; static CViewport mViewport; + static CVector3f mViewpoint; static float mBrightness; }; diff --git a/include/Kyoto/Math/CFrustumPlanes.hpp b/include/Kyoto/Math/CFrustumPlanes.hpp index 244376ee..c8e1708e 100644 --- a/include/Kyoto/Math/CFrustumPlanes.hpp +++ b/include/Kyoto/Math/CFrustumPlanes.hpp @@ -11,23 +11,23 @@ class CAABox; class CSphere; -class CPlane { -private: - float x; - float y; - float z; - float d; -}; - class CFrustumPlanes { public: + class SPlane { + private: + float x; + float y; + float z; + float d; + }; + bool BoxInFrustumPlanes(const CAABox& box) const; bool BoxInFrustumPlanes(const rstl::optional_object< CAABox >& box) const; bool SphereInFrustumPlanes(const CSphere& sphere) const; bool PointInFrustumPlanes(const CVector3f& point) const; private: - rstl::reserved_vector< CPlane, 6 > x0_planes; + rstl::reserved_vector< SPlane, 6 > x0_planes; }; #endif // _CFRUSTUMPLANES diff --git a/include/MetroidPrime/CGameArea.hpp b/include/MetroidPrime/CGameArea.hpp index 5fa04425..168a0561 100644 --- a/include/MetroidPrime/CGameArea.hpp +++ b/include/MetroidPrime/CGameArea.hpp @@ -33,6 +33,15 @@ public: virtual rstl::pair< rstl::auto_ptr< uchar >, int > IGetScriptingMemoryAlways() const = 0; }; +enum EChain { + kC_Invalid = -1, + kC_ToDeallocate, + kC_Deallocated, + kC_Loading, + kC_Alive, + kC_AliveJudgement, +}; + class Dock; class CToken; class IDvdRequest; @@ -67,6 +76,22 @@ public: void DisableFog(); }; + class CConstChainIterator { + const CGameArea* m_area; + + public: + CConstChainIterator() : m_area(nullptr) {} + explicit CConstChainIterator(const CGameArea* area) : m_area(area) {} + const CGameArea& operator*() const { return *m_area; } + const CGameArea* operator->() const { return m_area; } + CConstChainIterator& operator++() { + m_area = m_area->GetNext(); + return *this; + } + bool operator!=(const CConstChainIterator& other) const { return m_area != other.m_area; } + bool operator==(const CConstChainIterator& other) const { return m_area == other.m_area; } + }; + ~CGameArea(); const CTransform4f& IGetTM() const override; CAssetId IGetStringTableAssetId() const override; @@ -77,9 +102,12 @@ public: int IGetAreaSaveId() const override; rstl::pair< rstl::auto_ptr< uchar >, int > IGetScriptingMemoryAlways() const override; + TAreaId GetId() const { return x4_selfIdx; } const CTransform4f& GetTM() const { return xc_transform; } bool IsLoaded() const { return xf0_24_postConstructed; } bool IsActive() const { return xf0_25_active; } + const CAABox& GetAABB() const { return x6c_aabb; } + CGameArea* GetNext() const; // { return x130_next; } void SetXRaySpeedAndTarget(float speed, float target); void SetThermalSpeedAndTarget(float speed, float target); diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index d1059814..d422e56a 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -8,6 +8,7 @@ #include "Kyoto/Input/CFinalInput.hpp" #include "Kyoto/Math/CVector2f.hpp" #include "Kyoto/Math/CVector2i.hpp" +#include "Kyoto/Math/CFrustumPlanes.hpp" #include "Kyoto/TOneStatic.hpp" #include "Kyoto/TToken.hpp" @@ -56,6 +57,7 @@ class CWorldLayerState; class CLight; class CDamageInfo; class CTexture; +class CViewport; namespace SL { class CSortedListManager; @@ -157,6 +159,7 @@ public: void SetActorAreaId(CActor& actor, TAreaId); TAreaId GetNextAreaId() const { return x8cc_nextAreaId; } void SetCurrentAreaId(TAreaId); + TAreaId GetVisAreaId() const; bool CanCreateProjectile(TUniqueId, EWeaponType, int) const; @@ -238,6 +241,10 @@ public: void RemoveWeaponId(TUniqueId, EWeaponType); void AddWeaponId(TUniqueId, EWeaponType); + // Draw + CFrustumPlanes SetupViewForDraw(const CViewport&) const; + void DrawWorld() const; + // State transitions void DeferStateTransition(EStateManagerTransition t); void EnterMapScreen() { DeferStateTransition(kSMT_MapScreen); } diff --git a/include/MetroidPrime/CWorld.hpp b/include/MetroidPrime/CWorld.hpp index f61ab47e..bdea8355 100644 --- a/include/MetroidPrime/CWorld.hpp +++ b/include/MetroidPrime/CWorld.hpp @@ -75,6 +75,7 @@ public: int IGetAreaCount() const override; void SetLoadPauseState(bool); + void TouchSky() const; const CGameArea& GetAreaAlways(TAreaId id) const { return *x18_areas[id.Value()]; } CGameArea* Area(TAreaId id) { return x18_areas[id.Value()].get(); } @@ -88,6 +89,9 @@ public: static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area, CWorld* world); + CGameArea::CConstChainIterator GetChainHead(EChain chain) const { return CGameArea::CConstChainIterator(x4c_chainHeads[size_t(chain)]); } + static CGameArea::CConstChainIterator GetAliveAreasEnd(); + private: enum Phase { kP_Loading, diff --git a/include/rstl/iterator.hpp b/include/rstl/iterator.hpp index 1eb252fb..03a16f3a 100644 --- a/include/rstl/iterator.hpp +++ b/include/rstl/iterator.hpp @@ -21,7 +21,7 @@ typename It::difference_type __distance(It first, It last, forward_iterator_tag) } template < typename It > -typename It::difference_type distance(It first, It last) { +inline typename It::difference_type distance(It first, It last) { return __distance(first, last, typename It::iterator_category()); } diff --git a/src/MetroidPrime/CStateManager.cpp b/src/MetroidPrime/CStateManager.cpp index 58f82eb7..6d5e78d6 100644 --- a/src/MetroidPrime/CStateManager.cpp +++ b/src/MetroidPrime/CStateManager.cpp @@ -21,13 +21,44 @@ #include "Kyoto/Basics/RAssertDolphin.hpp" #include "Kyoto/CARAMManager.hpp" #include "Kyoto/CARAMToken.hpp" +#include "Kyoto/CTimeProvider.hpp" #include "Kyoto/Graphics/CLight.hpp" #include "MetaRender/CCubeRenderer.hpp" +#include "rstl/algorithm.hpp" + extern "C" { void sub_8036ccfc(); } +namespace { +class area_sorter { +public: + area_sorter(CVector3f ref, TAreaId aid) : reference(ref), visAreaId(aid) {} + + bool operator()(const CGameArea* a, const CGameArea* b) const; + +private: + CVector3f reference; + TAreaId visAreaId; +}; + +bool area_sorter::operator()(const CGameArea* a, const CGameArea* b) const { + if (a->GetId() == b->GetId()) { + return false; + } + if (visAreaId == a->GetId()) { + return false; + } + if (visAreaId == b->GetId()) { + return true; + } + return CVector3f::Dot(reference, a->GetAABB().GetCenterPoint()) > + CVector3f::Dot(reference, b->GetAABB().GetCenterPoint()); +} + +} // namespace + CStateManager::CStateManager(const rstl::ncrc_ptr< CScriptMailbox >& mailbox, const rstl::ncrc_ptr< CMapWorldInfo >& mwInfo, const rstl::ncrc_ptr< CPlayerState >& playerState, @@ -340,3 +371,37 @@ bool CStateManager::SwapOutAllPossibleMemory() { } void CStateManager::RendererDrawCallback(const void*, const void*, int) {} + +void CStateManager::DrawWorld() const { + + const CTimeProvider timeProvider(xf14_curTimeMod900); + const CViewport backupViewport = CGraphics::GetViewport(); + + /* Area camera is in (not necessarily player) */ + const TAreaId visAreaId = GetVisAreaId(); + + x850_world->TouchSky(); + + const CFrustumPlanes frustum = SetupViewForDraw(CGraphics::GetViewport()); + const CTransform4f backupViewMatrix = CGraphics::GetViewMatrix(); + + int areaCount = 0; + const CGameArea* areaArr[10]; + + CGameArea::CConstChainIterator it = x850_world->GetChainHead(kC_Alive); + CGameArea::CConstChainIterator end = x850_world->GetAliveAreasEnd(); + for (; it != end; ++it) { + if (areaCount == 10) { + break; + } + CGameArea::EOcclusionState occState = CGameArea::kOS_Occluded; + if (it->IsLoaded()) { + occState = it->GetOcclusionState(); + } + if (occState == CGameArea::kOS_Visible) { + areaArr[areaCount++] = &*it; + } + } + + rstl::sort(&areaArr[0], &areaArr[areaCount], area_sorter(CGraphics::GetViewpoint(), visAreaId)); +} diff --git a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp index 0dd44b45..4acef1ef 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp @@ -11,6 +11,7 @@ #include "MetroidPrime/Player/CGameState.hpp" #include "MetroidPrime/Player/CPlayer.hpp" #include "MetroidPrime/Player/CPlayerState.hpp" +#include "MetroidPrime/Player/CWorldLayerState.hpp" #include "MetroidPrime/ScriptObjects/CScriptPlatform.hpp" #include "MetroidPrime/TCastTo.hpp" #include "MetroidPrime/Weapons/CEnergyProjectile.hpp" @@ -28,9 +29,9 @@ #include "Kyoto/Math/CVector2i.hpp" #include "Kyoto/Math/CloseEnough.hpp" -#include "rstl/math.hpp" -#include "rstl/iterator.hpp" #include "rstl/algorithm.hpp" +#include "rstl/iterator.hpp" +#include "rstl/math.hpp" #include "math.h"