diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 7c462630..17e520b9 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -83751,12 +83751,12 @@ Address,Quality,Size,Name 0x0000007100fb295c,O,000220,_ZN4ksys4phys10ContactMgr25makeLayerContactPointInfoEPN4sead4HeapEiiRKNS2_14SafeStringBaseIcEEiii 0x0000007100fb2a38,O,000100,_ZN4ksys4phys10ContactMgr24registerContactPointInfoEPNS0_20ContactPointInfoBaseE 0x0000007100fb2a9c,O,000056,_ZN4ksys4phys10ContactMgr17makeCollisionInfoEPN4sead4HeapERKNS2_14SafeStringBaseIcEE -0x0000007100fb2ad4,U,000156,phys::ContactInfoTable::x_2 +0x0000007100fb2ad4,O,000156,_ZN4ksys4phys10ContactMgr34makeContactLayerCollisionInfoGroupEPN4sead4HeapENS0_12ContactLayerEiRKNS2_14SafeStringBaseIcEE 0x0000007100fb2b70,O,000148,_ZN4ksys4phys10ContactMgr20freeContactPointInfoEPNS0_20ContactPointInfoBaseE 0x0000007100fb2c04,O,000144,_ZN4ksys4phys10ContactMgr17freeCollisionInfoEPNS0_13CollisionInfoE 0x0000007100fb2c94,O,000216,_ZN4ksys4phys10ContactMgr21clearCollisionEntriesEPNS0_13CollisionInfoE -0x0000007100fb2d6c,U,000136,phys::ContactInfoTable::x_7 -0x0000007100fb2df4,U,000312,phys::ContactInfoTable::x_8 +0x0000007100fb2d6c,O,000136,_ZN4ksys4phys10ContactMgr34freeContactLayerCollisionInfoGroupEPNS0_30ContactLayerCollisionInfoGroupE +0x0000007100fb2df4,O,000312,_ZN4ksys4phys10ContactMgr21clearCollisionEntriesEPNS0_30ContactLayerCollisionInfoGroupE 0x0000007100fb2f2c,m,000120,_ZN4ksys4phys10ContactMgr18clearContactPointsEv 0x0000007100fb2fa4,O,000152,_ZN4ksys4phys10ContactMgr27removeContactPointsWithBodyEPNS0_9RigidBodyE 0x0000007100fb303c,O,000380,_ZN4ksys4phys10ContactMgr30removeCollisionEntriesWithBodyEPNS0_9RigidBodyE diff --git a/src/KingSystem/Physics/System/physContactLayerCollisionInfoGroup.h b/src/KingSystem/Physics/System/physContactLayerCollisionInfoGroup.h index 59cff64e..69f0bbec 100644 --- a/src/KingSystem/Physics/System/physContactLayerCollisionInfoGroup.h +++ b/src/KingSystem/Physics/System/physContactLayerCollisionInfoGroup.h @@ -48,6 +48,10 @@ public: CollidingBodiesIterator collidingBodiesEnd() const; CollidingBodiesRange getCollidingBodies() const; + const sead::PtrArray& getCollisionInfo() const { + return mCollisionInfoInstances; + } + static constexpr size_t getListNodeOffset() { return offsetof(ContactLayerCollisionInfoGroup, mListNode); } diff --git a/src/KingSystem/Physics/System/physContactMgr.cpp b/src/KingSystem/Physics/System/physContactMgr.cpp index a467736c..ccc25385 100644 --- a/src/KingSystem/Physics/System/physContactMgr.cpp +++ b/src/KingSystem/Physics/System/physContactMgr.cpp @@ -5,6 +5,7 @@ #include "KingSystem/Physics/RigidBody/physRigidBodyRequestMgr.h" #include "KingSystem/Physics/System/physCollisionInfo.h" #include "KingSystem/Physics/System/physContactLayerCollisionInfo.h" +#include "KingSystem/Physics/System/physContactLayerCollisionInfoGroup.h" #include "KingSystem/Physics/System/physContactPointInfo.h" #include "KingSystem/Physics/System/physEntityGroupFilter.h" #include "KingSystem/Physics/System/physGroupFilter.h" @@ -33,8 +34,7 @@ struct ContactMgr::ImpulseEntry { ContactMgr::ContactMgr() { mContactPointInfoInstances.initOffset(ContactPointInfo::getListNodeOffset()); mCollisionInfoInstances.initOffset(CollisionInfo::getListNodeOffset()); - // FIXME: figure out what this offset is - mList3.initOffset(0x40); + mLayerColInfoGroups.initOffset(ContactLayerCollisionInfoGroup::getListNodeOffset()); mCollidingBodiesFreeList.initOffset(CollidingBodies::getListNodeOffset()); mImpulseEntriesFreeList.initOffset(ImpulseEntry::getListNodeOffset()); mImpulseEntries.initOffset(ImpulseEntry::getListNodeOffset()); @@ -135,6 +135,15 @@ CollisionInfo* ContactMgr::makeCollisionInfo(sead::Heap* heap, const sead::SafeS return new (heap) CollisionInfo(name); } +ContactLayerCollisionInfoGroup* +ContactMgr::makeContactLayerCollisionInfoGroup(sead::Heap* heap, ContactLayer layer, int capacity, + const sead::SafeString& name) { + auto* group = new (heap) ContactLayerCollisionInfoGroup(layer, name); + group->init(heap, capacity); + registerContactLayerCollisionInfoGroup(group); + return group; +} + void ContactMgr::registerContactPointInfo(ContactPointInfoBase* info) { auto lock = sead::makeScopedLock(mContactPointInfoMutex); if (!info->isLinked()) @@ -177,6 +186,27 @@ void ContactMgr::freeCollisionInfo(CollisionInfo* info) { delete info; } +void ContactMgr::registerContactLayerCollisionInfoGroup(ContactLayerCollisionInfoGroup* group) { + auto lock = sead::makeScopedLock(mLayerColInfoGroupMutex); + mLayerColInfoGroups.pushBack(group); +} + +void ContactMgr::unregisterContactLayerCollisionInfoGroup(ContactLayerCollisionInfoGroup* group) { + auto lock = sead::makeScopedLock(mLayerColInfoGroupMutex); + mLayerColInfoGroups.erase(group); +} + +void ContactMgr::freeContactLayerCollisionInfoGroup(ContactLayerCollisionInfoGroup* group) { + if (!group) + return; + + clearCollisionEntries(group); + unregisterContactLayerCollisionInfoGroup(group); + group->finalize(); + + delete group; +} + // NON_MATCHING: two sub instructions reordered void ContactMgr::clearContactPoints() { auto lock = sead::makeScopedLock(mContactPointInfoMutex); @@ -434,6 +464,20 @@ void ContactMgr::clearCollisionEntries(CollisionInfo* info) { } } +void ContactMgr::clearCollisionEntries(ContactLayerCollisionInfoGroup* group) { + auto lock = sead::makeScopedLock(mCollidingBodiesMutex); + + for (int i = 0; i < group->getCollisionInfo().size(); ++i) { + ContactLayerCollisionInfo* info = group->getCollisionInfo()[i]; + auto info_lock = sead::makeScopedLock(*info); + + for (auto& entry : info->getCollidingBodies().robustRange()) { + info->getCollidingBodies().erase(&entry); + freeCollidingBodiesEntry(&entry); + } + } +} + void ContactMgr::addImpulseEntry(RigidBody* body_a, RigidBody* body_b) { auto lock = sead::makeScopedLock(mImpulseEntriesMutex); diff --git a/src/KingSystem/Physics/System/physContactMgr.h b/src/KingSystem/Physics/System/physContactMgr.h index 4a8a8d9b..a5353f9b 100644 --- a/src/KingSystem/Physics/System/physContactMgr.h +++ b/src/KingSystem/Physics/System/physContactMgr.h @@ -28,6 +28,7 @@ enum class IsIndoorStage; struct CollidingBodies; class CollisionInfo; class ContactLayerCollisionInfo; +class ContactLayerCollisionInfoGroup; class ContactPointInfoBase; class QueryContactPointInfo; class RigidBody; @@ -100,6 +101,10 @@ public: CollisionInfo* makeCollisionInfo(sead::Heap* heap, const sead::SafeString& name); + ContactLayerCollisionInfoGroup* + makeContactLayerCollisionInfoGroup(sead::Heap* heap, ContactLayer layer, int capacity, + const sead::SafeString& name); + // endregion void registerContactPointInfo(ContactPointInfoBase* info); @@ -110,6 +115,10 @@ public: void unregisterCollisionInfo(CollisionInfo* info); void freeCollisionInfo(CollisionInfo* info); + void registerContactLayerCollisionInfoGroup(ContactLayerCollisionInfoGroup* group); + void unregisterContactLayerCollisionInfoGroup(ContactLayerCollisionInfoGroup* group); + void freeContactLayerCollisionInfoGroup(ContactLayerCollisionInfoGroup* group); + void clearContactPoints(); /// Remove all contact points with the specified rigid body. /// @note For efficiency reasons, this actually only invalidates the contact points. @@ -138,6 +147,7 @@ public: void unregisterCollisionWithBody(ContactLayerCollisionInfo* info, RigidBody* body); void clearCollisionEntries(CollisionInfo* info); + void clearCollisionEntries(ContactLayerCollisionInfoGroup* group); bool initLayerMasks(ContactPointInfo* info, const sead::SafeString& receiver_name) const; bool initLayerMasks(CollisionInfo* info, const sead::SafeString& receiver_name) const; @@ -180,13 +190,12 @@ private: sead::Atomic mNumContactPoints = 0; sead::OffsetList mContactPointInfoInstances; sead::OffsetList mCollisionInfoInstances; - sead::OffsetList mList3; + sead::OffsetList mLayerColInfoGroups; sead::OffsetList mImpulseEntriesFreeList; sead::OffsetList mImpulseEntries; sead::Mutex mContactPointInfoMutex; sead::Mutex mCollisionInfoMutex; - // TODO: rename mList3 and mMutex3 - sead::Mutex mMutex3; + sead::Mutex mLayerColInfoGroupMutex; sead::Mutex mCollidingBodiesMutex; sead::Mutex mImpulseEntriesMutex; sead::SafeArray mContactInfoTables{};