diff --git a/data/uking_functions.csv b/data/uking_functions.csv index f292644b..2eff34dd 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -84202,25 +84202,25 @@ Address,Quality,Size,Name 0x0000007100fc9ba4,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys9ShapeCastEE9isDerivedEPKNS0_9InterfaceE 0x0000007100fc9c30,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys17ShapeCastWithInfoEE9isDerivedEPKNS0_9InterfaceE 0x0000007100fc9cbc,O,000208,_ZN4ksys4phys14StaticCompoundC1Ev -0x0000007100fc9d8c,U,000352,ResourceHksc::dtor -0x0000007100fc9eec,U,000008, -0x0000007100fc9ef4,U,000036,ResourceHksc::dtorDelete -0x0000007100fc9f18,U,000040, +0x0000007100fc9d8c,O,000352,_ZN4ksys4phys14StaticCompoundD1Ev +0x0000007100fc9eec,O,000008,_ZThn32_N4ksys4phys14StaticCompoundD1Ev +0x0000007100fc9ef4,O,000036,_ZN4ksys4phys14StaticCompoundD0Ev +0x0000007100fc9f18,O,000040,_ZThn32_N4ksys4phys14StaticCompoundD0Ev 0x0000007100fc9f40,O,001356,_ZN4ksys4phys14StaticCompound9doCreate_EPhjPN4sead4HeapE -0x0000007100fca48c,U,000268,ResourceHksc::afterParse -0x0000007100fca598,U,000416,ResourceHksc::m7 -0x0000007100fca738,U,000156,ResourceHksc::calledFromMapDtor -0x0000007100fca7d4,U,000192,ResourceHksc::x_3 -0x0000007100fca894,U,000136,ResourceHksc::x_2 -0x0000007100fca91c,U,000212,ResourceHksc::x_4 -0x0000007100fca9f0,U,000112, -0x0000007100fcaa60,U,000136,ResourceHksc::cleanUp +0x0000007100fca48c,O,000268,_ZN4ksys4phys14StaticCompound14finishParsing_Ev +0x0000007100fca598,O,000416,_ZN4ksys4phys14StaticCompound3m7_Ev +0x0000007100fca738,O,000156,_ZNK4ksys4phys14StaticCompound26isAnyRigidBodyAddedToWorldEv +0x0000007100fca7d4,O,000192,_ZNK4ksys4phys14StaticCompound38isAnyRigidBodyAddedOrBeingAddedToWorldEv +0x0000007100fca894,O,000136,_ZN4ksys4phys14StaticCompound15removeFromWorldEv +0x0000007100fca91c,O,000212,_ZN4ksys4phys14StaticCompound10addToWorldEv +0x0000007100fca9f0,O,000112,_ZN4ksys4phys14StaticCompound28resetExtraTransformsAndApplyEv +0x0000007100fcaa60,O,000136,_ZN4ksys4phys14StaticCompound26removeFromWorldImmediatelyEv 0x0000007100fcaae8,O,000076,_ZN4ksys4phys14StaticCompound12setMapObjectEjjPNS_3map6ObjectE 0x0000007100fcab34,O,000072,_ZNK4ksys4phys14StaticCompound12getMapObjectEi 0x0000007100fcab7c,O,000176,_ZN4ksys4phys14StaticCompound16disableCollisionEib -0x0000007100fcac2c,U,000112, -0x0000007100fcac9c,U,000112, -0x0000007100fcad0c,U,000328, +0x0000007100fcac2c,O,000112,_ZN4ksys4phys14StaticCompound14processUpdatesEv +0x0000007100fcac9c,O,000112,_ZN4ksys4phys14StaticCompound24recomputeTransformMatrixEv +0x0000007100fcad0c,O,000328,_ZN4ksys4phys14StaticCompound20applyExtraTransformsERKN4sead8Matrix34IfEE 0x0000007100fcae54,O,000028,_ZN4ksys4phys14StaticCompound17getFieldBodyGroupEi 0x0000007100fcae70,O,000084,_ZNK4ksys4phys14StaticCompound17hasFieldBodyGroupEPNS0_28StaticCompoundRigidBodyGroupE 0x0000007100fcaec4,O,000008,_ZNK4ksys4phys14StaticCompound27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE @@ -84265,7 +84265,7 @@ Address,Quality,Size,Name 0x0000007100fcca20,O,000112,_ZN4ksys4phys28StaticCompoundRigidBodyGroup26removeFromWorldImmediatelyEv 0x0000007100fcca90,O,000108,_ZN4ksys4phys28StaticCompoundRigidBodyGroup18setInstanceEnabledENS0_13BodyLayerTypeEib 0x0000007100fccafc,O,000116,_ZN4ksys4phys28StaticCompoundRigidBodyGroup30enableAllInstancesAndShapeKeysEv -0x0000007100fccb70,O,000268,_ZN4ksys4phys28StaticCompoundRigidBodyGroup31resetMatricesAndUpdateTransformEv +0x0000007100fccb70,O,000268,_ZN4ksys4phys28StaticCompoundRigidBodyGroup28resetExtraTransformsAndApplyEv 0x0000007100fccc7c,O,000312,_ZN4ksys4phys28StaticCompoundRigidBodyGroup20applyExtraTransformsEv 0x0000007100fccdb4,O,000944,_ZN4ksys4phys28StaticCompoundRigidBodyGroup14processUpdatesEv 0x0000007100fcd164,O,000244,_ZN4ksys4phys28StaticCompoundRigidBodyGroup24recomputeTransformMatrixEv diff --git a/src/KingSystem/Map/mapPlacementMap.cpp b/src/KingSystem/Map/mapPlacementMap.cpp index 26dfbd0f..44defe6c 100644 --- a/src/KingSystem/Map/mapPlacementMap.cpp +++ b/src/KingSystem/Map/mapPlacementMap.cpp @@ -1,9 +1,10 @@ - #include "KingSystem/Map/mapPlacementMap.h" #include #include #include "Game/DLC/aocManager.h" #include "KingSystem/Map/mapObject.h" +#include "KingSystem/Physics/StaticCompound/physStaticCompound.h" +#include "KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h" #include "KingSystem/Resource/resLoadRequest.h" namespace ksys::map { @@ -36,15 +37,15 @@ PlacementMap::PlacementMap() { PlacementMap::~PlacementMap() { mRoutes.freeBuffer(); - for (auto& r : mRes) { - r.cleanup(); + for (auto& resource : mRes) { + resource.cleanup(); } } bool PlacementMap::clearStaticCompoundActorId(int idx) { const auto lock = sead::makeScopedLock(mCs); const auto& resource = mRes[idx].mRes.getResource(); if (auto* sc = sead::DynamicCast(resource)) { - if (sc->calledFromMapDtor()) { + if (sc->isAnyRigidBodyAddedToWorld()) { return false; } mRes[idx].mRes.requestUnload(); @@ -220,7 +221,7 @@ PlacementMap::MapObjStatus PlacementMap::x_2(int hksc_idx) { auto* resource = handle->getResource(); auto* sc = sead::DynamicCast(resource); - sc->sub_7100FCAD0C(mMat); + sc->applyExtraTransforms(mMat); for (int i = mParsedNumStaticObjs; i <= mNumStaticObjs; i++) { updateObjectCollisionAndId(hksc_idx, mPa->getStaticObj_0(i)); } @@ -262,8 +263,8 @@ void PlacementMap::doDisableObjStaticCompound(Object* obj, bool disable) { int PlacementMap::doSomethingStaticCompound(int hksc_idx) { auto* resource = mRes[hksc_idx].mRes.getResource(); if (auto* sc = sead::DynamicCast(resource)) { - if (!sc->calledFromMapDtor() && !sc->x_3()) { - sc->x_4(); + if (!sc->isAnyRigidBodyAddedToWorld() && !sc->isAnyRigidBodyAddedOrBeingAddedToWorld()) { + sc->addToWorld(); } } return 1; @@ -302,7 +303,7 @@ void PlacementMap::cleanupPhysics() { for (int i = 0; i < 4; i++) { auto resource = mRes[i].mRes.getResource(); if (auto* sc = sead::DynamicCast(resource)) { - sc->cleanUp(); + sc->removeFromWorldImmediately(); } mRes[i].mRes.requestUnload2(); mRes[i].mStatus = HkscRes::Status::_0; @@ -383,4 +384,13 @@ void PlacementMap::unloadHksc(int hksc_idx) { mRes[hksc_idx].mRes.requestUnload(); } +void PlacementMap::HkscRes::cleanup() { + auto* r = mRes.getResource(); + if (auto sc = sead::DynamicCast(r)) { + if (sc->isAnyRigidBodyAddedToWorld()) { + sc->removeFromWorldImmediately(); + } + } +} + } // namespace ksys::map diff --git a/src/KingSystem/Map/mapPlacementMap.h b/src/KingSystem/Map/mapPlacementMap.h index 219a82b1..b5b7357a 100644 --- a/src/KingSystem/Map/mapPlacementMap.h +++ b/src/KingSystem/Map/mapPlacementMap.h @@ -9,14 +9,19 @@ #include #include "KingSystem/Map/mapPlacementActors.h" #include "KingSystem/Map/mapPlacementMapMgr.h" -#include "KingSystem/Physics/StaticCompound/physStaticCompound.h" #include "KingSystem/Resource/resHandle.h" #include "KingSystem/Resource/resResource.h" #include "KingSystem/System/Patrol.h" #include "KingSystem/Utils/Types.h" +namespace ksys::phys { +class StaticCompound; +class StaticCompoundRigidBodyGroup; +} // namespace ksys::phys + namespace ksys::map { +class Object; class PlacementMapMgr; class PlacementActors; @@ -35,14 +40,7 @@ class PlacementMap { HkscRes() = default; ~HkscRes() = default; - void cleanup() { - auto* r = mRes.getResource(); - if (auto sc = sead::DynamicCast(r)) { - if (sc->calledFromMapDtor()) { - sc->cleanUp(); - } - } - } + void cleanup(); res::Handle mRes; Status mStatus; diff --git a/src/KingSystem/Physics/StaticCompound/physStaticCompound.cpp b/src/KingSystem/Physics/StaticCompound/physStaticCompound.cpp index 59abc724..97fc491e 100644 --- a/src/KingSystem/Physics/StaticCompound/physStaticCompound.cpp +++ b/src/KingSystem/Physics/StaticCompound/physStaticCompound.cpp @@ -2,10 +2,15 @@ #include #include #include +#include +#include #include "KingSystem/Physics/StaticCompound/physStaticCompoundInfo.h" +#include "KingSystem/Physics/StaticCompound/physStaticCompoundMgr.h" #include "KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h" +#include "KingSystem/Physics/System/physSystem.h" #include "KingSystem/Utils/Debug.h" #include "KingSystem/Utils/HeapUtil.h" +#include "KingSystem/Utils/SafeDelete.h" namespace ksys::phys { @@ -15,7 +20,29 @@ constexpr int NumBodyGroups = 16 + 1; StaticCompound::StaticCompound() = default; StaticCompound::~StaticCompound() { - // FIXME + System::instance()->getStaticCompoundMgr()->removeStaticCompound(this); + mFlags.reset(Flag::Initialised); + + { + sead::ScopedCurrentHeapSetter heap_setter{mHeap}; + mFieldBodyGroups.freeBuffer(); + mMapObjects.freeBuffer(); + } + + if (mContainerBuffer) { + hkNativePackfileUtils::unloadInPlace(mContainerBuffer, mContainerBufferSize); + mContainerBuffer = nullptr; + mContainerBufferSize = 0; + } + + if (mBuffer) { + hkNativePackfileUtils::unloadInPlace(mBuffer, mBufferSize); + mBuffer = nullptr; + mBufferSize = 0; + mStaticCompoundInfo = nullptr; + } + + util::safeDeleteHeap(mHeap); } void StaticCompound::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* parent_heap) { @@ -62,6 +89,75 @@ void StaticCompound::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* parent_h mHeap->adjust(); } +bool StaticCompound::finishParsing_() { + mFlags.set(Flag::Initialised); + mMapObjects.fill(nullptr); + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].enableAllInstancesAndShapeKeys(); + + System::instance()->getStaticCompoundMgr()->addStaticCompound(this); + return true; +} + +bool StaticCompound::m7_() { + if (isAnyRigidBodyAddedToWorld() || isAnyRigidBodyAddedOrBeingAddedToWorld()) { + removeFromWorld(); + // We cannot unload this resource immediately. + return false; + } + + System::instance()->getStaticCompoundMgr()->removeStaticCompound(this); + mFlags.reset(Flag::Initialised); + return true; +} + +bool StaticCompound::isAnyRigidBodyAddedToWorld() const { + auto lock = sead::makeScopedLock(mCS); + + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) { + if (mFieldBodyGroups[i].isAnyRigidBodyAddedToWorld()) + return true; + } + + return false; +} + +bool StaticCompound::isAnyRigidBodyAddedOrBeingAddedToWorld() const { + auto lock = sead::makeScopedLock(mCS); + + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) { + if (mFieldBodyGroups[i].isAnyRigidBodyBeingAddedToWorld() || + mFieldBodyGroups[i].isAnyRigidBodyAddedToWorld()) { + return true; + } + } + + return false; +} + +void StaticCompound::removeFromWorld() { + auto lock = sead::makeScopedLock(mCS); + + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].removeFromWorld(); +} + +void StaticCompound::addToWorld() { + auto lock = sead::makeScopedLock(mCS); + + resetExtraTransformsAndApply(); + + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].addToWorld(); +} + +void StaticCompound::removeFromWorldImmediately() { + auto lock = sead::makeScopedLock(mCS); + + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].removeFromWorldImmediately(); +} + int StaticCompound::setMapObject(u32 hash_id, u32 srt_hash, map::Object* object) { int idx = mStaticCompoundInfo->getActorIdx(hash_id, srt_hash); if (idx >= 0 && idx < mMapObjects.size()) @@ -98,6 +194,30 @@ bool StaticCompound::disableCollision(int actor_idx, bool x) { return true; } +void StaticCompound::processUpdates() { + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].processUpdates(); +} + +void StaticCompound::recomputeTransformMatrix() { + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].recomputeTransformMatrix(); +} + +void StaticCompound::applyExtraTransforms(const sead::Matrix34f& mtx) { + if (mtx == mMtx) + return; + + mMtx = mtx; + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].applyExtraTransforms(); +} + +void StaticCompound::resetExtraTransformsAndApply() { + for (int i = 0, n = mFieldBodyGroups.size(); i < n; ++i) + mFieldBodyGroups[i].resetExtraTransformsAndApply(); +} + StaticCompoundRigidBodyGroup* StaticCompound::getFieldBodyGroup(int idx) { return &mFieldBodyGroups[idx]; } diff --git a/src/KingSystem/Physics/StaticCompound/physStaticCompound.h b/src/KingSystem/Physics/StaticCompound/physStaticCompound.h index fc06f8fa..9864894f 100644 --- a/src/KingSystem/Physics/StaticCompound/physStaticCompound.h +++ b/src/KingSystem/Physics/StaticCompound/physStaticCompound.h @@ -27,11 +27,23 @@ public: StaticCompound(); ~StaticCompound() override; + bool isAnyRigidBodyAddedToWorld() const; + bool isAnyRigidBodyAddedOrBeingAddedToWorld() const; + void removeFromWorld(); + void addToWorld(); + void removeFromWorldImmediately(); + int setMapObject(u32 hash_id, u32 srt_hash, map::Object* object); map::Object* getMapObject(int shape_idx) const; bool disableCollision(int actor_idx, bool x); + void processUpdates(); + void recomputeTransformMatrix(); + void applyExtraTransforms(const sead::Matrix34f& mtx); + void resetExtraTransformsAndApply(); + + int getNumFieldBodyGroups() const { return mFieldBodyGroups.size(); } StaticCompoundRigidBodyGroup* getFieldBodyGroup(int idx); bool hasFieldBodyGroup(StaticCompoundRigidBodyGroup* group) const; @@ -41,13 +53,6 @@ public: bool finishParsing_() override; bool m7_() override; - void cleanUp(); - bool calledFromMapDtor(); - int getNumFieldBodyGroups() const { return mFieldBodyGroups.size(); } - bool x_3(); - void x_4(); - StaticCompound* sub_7100FCAD0C(sead::Matrix34f& mtx); - private: enum class Flag { Initialised = 1 << 0, @@ -64,7 +69,7 @@ private: sead::FixedSafeString<32> mName; sead::Matrix34f mMtx = sead::Matrix34f::ident; sead::Buffer mMapObjects{}; - sead::CriticalSection mCS; + mutable sead::CriticalSection mCS; }; KSYS_CHECK_SIZE_NX150(StaticCompound, 0x140); diff --git a/src/KingSystem/Physics/StaticCompound/physStaticCompoundMgr.h b/src/KingSystem/Physics/StaticCompound/physStaticCompoundMgr.h index 7cab39f5..5b15b9e5 100644 --- a/src/KingSystem/Physics/StaticCompound/physStaticCompoundMgr.h +++ b/src/KingSystem/Physics/StaticCompound/physStaticCompoundMgr.h @@ -17,6 +17,11 @@ public: bool init(); + // 0x0000007100fcb554 + void addStaticCompound(StaticCompound* sc); + // 0x0000007100fcb5e0 + void removeStaticCompound(StaticCompound* sc); + SystemGroupHandler* getGroupHandler() const { return mGroupHandler; } // TODO: more functions diff --git a/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.cpp b/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.cpp index 940663e6..86929a4a 100644 --- a/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.cpp +++ b/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.cpp @@ -180,7 +180,7 @@ void StaticCompoundRigidBodyGroup::resetExtraTransforms() { } } -void StaticCompoundRigidBodyGroup::resetMatricesAndUpdateTransform() { +void StaticCompoundRigidBodyGroup::resetExtraTransformsAndApply() { resetExtraTransforms(); mPendingTransformChanges = 0; diff --git a/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h b/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h index 8bc40f64..7800c1b6 100644 --- a/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h +++ b/src/KingSystem/Physics/StaticCompound/physStaticCompoundRigidBodyGroup.h @@ -58,7 +58,7 @@ public: void enableAllInstancesAndShapeKeys(); void resetExtraTransforms(); - void resetMatricesAndUpdateTransform(); + void resetExtraTransformsAndApply(); void applyExtraTransforms(); void recomputeTransformMatrix();