From a816125247419be2a3b581e136d88b9ecf8a8a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Wed, 22 Dec 2021 16:23:22 +0100 Subject: [PATCH] ksys/phys: Finish SystemData and start implementing GroupFilter --- data/uking_functions.csv | 74 ++++++++--------- src/KingSystem/Physics/CMakeLists.txt | 2 + .../Physics/System/physEntityGroupFilter.cpp | 43 ++++++++++ .../Physics/System/physEntityGroupFilter.h | 63 ++++++++++++++ .../Physics/System/physGroupFilter.cpp | 52 +++++++++++- .../Physics/System/physGroupFilter.h | 83 ++++++++++++++++--- src/KingSystem/Physics/System/physMemSystem.h | 3 + .../Physics/System/physSystemData.cpp | 64 +++++++++++--- .../Physics/System/physSystemData.h | 24 +++--- src/KingSystem/Utils/HeapUtil.h | 6 ++ 10 files changed, 339 insertions(+), 75 deletions(-) create mode 100644 src/KingSystem/Physics/System/physEntityGroupFilter.cpp create mode 100644 src/KingSystem/Physics/System/physEntityGroupFilter.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index c3f4c05b..5d65ff91 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -83765,18 +83765,18 @@ Address,Quality,Size,Name 0x0000007100fb4e04,U,000056, 0x0000007100fb4e3c,U,000036, 0x0000007100fb4e60,U,000016, -0x0000007100fb4e70,U,000144, -0x0000007100fb4f00,U,000004, -0x0000007100fb4f04,U,000008, -0x0000007100fb4f0c,U,000008, -0x0000007100fb4f14,U,000008, -0x0000007100fb4f1c,U,000008, -0x0000007100fb4f24,U,000088, -0x0000007100fb4f7c,U,000096, -0x0000007100fb4fdc,U,000096, -0x0000007100fb503c,U,000096, -0x0000007100fb509c,U,000096, -0x0000007100fb50fc,U,000032,_ZN2nn4ui2d6detail12AnimPaneTree10InitializeEv +0x0000007100fb4e70,O,000144,_ZN4ksys4phys17EntityGroupFilter4makeENS0_12ContactLayer9ValueTypeES3_PN4sead4HeapE +0x0000007100fb4f00,O,000004,_ZN4ksys4phys17EntityGroupFilterD1Ev +0x0000007100fb4f04,O,000008,_ZThn16_N4ksys4phys17EntityGroupFilterD1Ev +0x0000007100fb4f0c,O,000008,_ZThn24_N4ksys4phys17EntityGroupFilterD1Ev +0x0000007100fb4f14,O,000008,_ZThn32_N4ksys4phys17EntityGroupFilterD1Ev +0x0000007100fb4f1c,O,000008,_ZThn40_N4ksys4phys17EntityGroupFilterD1Ev +0x0000007100fb4f24,O,000088,_ZN4ksys4phys17EntityGroupFilterD0Ev +0x0000007100fb4f7c,O,000096,_ZThn16_N4ksys4phys17EntityGroupFilterD0Ev +0x0000007100fb4fdc,O,000096,_ZThn24_N4ksys4phys17EntityGroupFilterD0Ev +0x0000007100fb503c,O,000096,_ZThn32_N4ksys4phys17EntityGroupFilterD0Ev +0x0000007100fb509c,O,000096,_ZThn40_N4ksys4phys17EntityGroupFilterD0Ev +0x0000007100fb50fc,O,000032,_ZN4ksys4phys17EntityGroupFilter7doInit_EPN4sead4HeapE 0x0000007100fb511c,U,001440, 0x0000007100fb56bc,U,000268, 0x0000007100fb57c8,U,000028, @@ -83788,8 +83788,8 @@ Address,Quality,Size,Name 0x0000007100fb5bac,U,000284, 0x0000007100fb5cc8,U,000256, 0x0000007100fb5dc8,U,000028, -0x0000007100fb5de4,U,000192, -0x0000007100fb5ea4,U,000016, +0x0000007100fb5de4,O,000192,_ZN4ksys4phys17EntityGroupFilter30doInitSystemGroupHandlerLists_EPN4sead4HeapE +0x0000007100fb5ea4,O,000016,_ZN4ksys4phys17EntityGroupFilter16getFreeListIndexEPKNS0_18SystemGroupHandlerE 0x0000007100fb5eb4,U,000036, 0x0000007100fb5ed8,O,000060,_ZN4ksys4physL19orGroundHitTypeMaskEjRKN4sead14SafeStringBaseIcEE 0x0000007100fb5f14,U,000032, @@ -83799,14 +83799,14 @@ Address,Quality,Size,Name 0x0000007100fb5ff0,U,000048, 0x0000007100fb6020,U,000040, 0x0000007100fb6048,U,000020, -0x0000007100fb605c,U,000112, -0x0000007100fb60cc,U,000092, -0x0000007100fb6128,U,000004,nullsub_4242 -0x0000007100fb612c,U,000004,j__ZdlPv_1005 +0x0000007100fb605c,O,000112,_ZNK4ksys4phys18SystemGroupHandler27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x0000007100fb60cc,O,000092,_ZNK4ksys4phys18SystemGroupHandler18getRuntimeTypeInfoEv +0x0000007100fb6128,O,000004,_ZN4ksys4phys18SystemGroupHandlerD2Ev +0x0000007100fb612c,O,000004,_ZN4ksys4phys18SystemGroupHandlerD0Ev 0x0000007100fb6130,O,000004,_ZN18hkpCollisionFilter4initEP8hkpWorld 0x0000007100fb6134,O,000008,_ZN14hkpGroupFilter11dummyUnusedEv -0x0000007100fb613c,U,000204, -0x0000007100fb6208,U,000092, +0x0000007100fb613c,O,000204,_ZNK4ksys4phys17EntityGroupFilter27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x0000007100fb6208,O,000092,_ZNK4ksys4phys17EntityGroupFilter18getRuntimeTypeInfoEv 0x0000007100fb6264,U,000044, 0x0000007100fb6290,U,000028, 0x0000007100fb62ac,U,000020, @@ -83814,11 +83814,11 @@ Address,Quality,Size,Name 0x0000007100fb62dc,U,000008, 0x0000007100fb62e4,U,000040, 0x0000007100fb630c,U,000048,GetStringGroundHitMaskModeOrSensorText -0x0000007100fb633c,U,000036, +0x0000007100fb633c,O,000036,_ZN4ksys4phys17EntityGroupFilter18setLayerCustomMaskENS0_12ContactLayerEj 0x0000007100fb6360,U,000008, 0x0000007100fb6368,U,000044, 0x0000007100fb6394,U,000028, -0x0000007100fb63b0,U,000140, +0x0000007100fb63b0,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys11GroupFilterEE9isDerivedEPKNS0_9InterfaceE 0x0000007100fb643c,U,000108, 0x0000007100fb64a8,U,000004, 0x0000007100fb64ac,U,000036, @@ -84137,7 +84137,7 @@ Address,Quality,Size,Name 0x0000007100fc86ac,U,000008, 0x0000007100fc86b4,U,000032, 0x0000007100fc86d4,U,000032, -0x0000007100fc86f4,U,000004,nullsub_4249 +0x0000007100fc86f4,O,000004,_ZN4ksys4phys11GroupFilter18setLayerCustomMaskENS0_12ContactLayerEj 0x0000007100fc86f8,U,000008, 0x0000007100fc8700,U,000008, 0x0000007100fc8708,U,000036, @@ -93366,15 +93366,15 @@ Address,Quality,Size,Name 0x0000007101213a5c,O,000144,_ZThn24_N4ksys4phys11GroupFilterD0Ev 0x0000007101213aec,O,000144,_ZThn32_N4ksys4phys11GroupFilterD0Ev 0x0000007101213b7c,O,000144,_ZThn40_N4ksys4phys11GroupFilterD0Ev -0x0000007101213c0c,U,000092, -0x0000007101213c68,U,000148, -0x0000007101213cfc,U,000160, -0x0000007101213d9c,U,000148, -0x0000007101213e30,U,000008, -0x0000007101213e38,U,000024, +0x0000007101213c0c,O,000092,_ZN4ksys4phys11GroupFilter10initFilterEPN4sead4HeapE +0x0000007101213c68,O,000148,_ZN4ksys4phys11GroupFilter7destroyEv +0x0000007101213cfc,O,000160,_ZN4ksys4phys11GroupFilter21addSystemGroupHandlerEi +0x0000007101213d9c,O,000148,_ZN4ksys4phys11GroupFilter24removeSystemGroupHandlerEPNS0_18SystemGroupHandlerE +0x0000007101213e30,O,000008,_ZN4ksys4phys18SystemGroupHandler2m7Ev +0x0000007101213e38,O,000024,_ZN4ksys4phys18SystemGroupHandler10removeThisEv 0x0000007101213e50,O,000112,_ZNK4ksys4phys11GroupFilter27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE 0x0000007101213ec0,O,000092,_ZNK4ksys4phys11GroupFilter18getRuntimeTypeInfoEv -0x0000007101213f1c,U,000004,nullsub_4710 +0x0000007101213f1c,O,000004,_ZN4ksys4phys11GroupFilter7doInit_EPN4sead4HeapE 0x0000007101213f20,U,000100, 0x0000007101213f84,U,000108, 0x0000007101213ff0,U,000136,PhysicsMemSys::createInstance @@ -95437,20 +95437,20 @@ Address,Quality,Size,Name 0x00000071012b1ef4,U,000092, 0x00000071012b1f50,m,000484,_ZN4ksys4phys10SystemDataC1Ev 0x00000071012b2134,O,000864,_ZN4ksys4phys10SystemDataD1Ev -0x00000071012b2494,O,000404,_ZN4sead9SafeArrayIN4ksys4phys10SystemData6TablesINS2_14LayerTableInfoELi32EEELi2EED2Ev +0x00000071012b2494,O,000404,_ZN4sead9SafeArrayIN4ksys4phys10SystemData6TablesINS2_10LayerTableELi32EEELi2EED2Ev 0x00000071012b2628,O,000036,_ZN4ksys4phys10SystemDataD0Ev -0x00000071012b264c,O,000368,_ZN4ksys4phys10SystemData4loadEPN4sead4HeapEPNS0_10LayerTableES6_PNS0_13MaterialTableEPNS0_16ContactInfoTableE -0x00000071012b27bc,U,000544, +0x00000071012b264c,O,000368,_ZN4ksys4phys10SystemData4loadEPN4sead4HeapEPNS0_11GroupFilterES6_PNS0_13MaterialTableEPNS0_16ContactInfoTableE +0x00000071012b27bc,O,000544,_ZN4ksys4phys10SystemData14loadLayerTableEPN4sead4HeapEPNS0_11GroupFilterENS0_16ContactLayerTypeE 0x00000071012b29dc,O,000316,_ZN4ksys4phys10SystemData22loadCharacterCtrlTableEPN4sead4HeapE 0x00000071012b2b18,O,000292,_ZN4ksys4phys10SystemData22loadRagdollCtrlKeyListEPN4sead4HeapE -0x00000071012b2c3c,O,000284,_ZN4ksys4phys10SystemData17loadLayerTableResERKNS1_6TablesINS0_14LayerTableInfoELi32EEENS0_16ContactLayerTypeE +0x00000071012b2c3c,O,000284,_ZN4ksys4phys10SystemData17loadLayerTableResERKNS1_6TablesINS0_10LayerTableELi32EEENS0_16ContactLayerTypeE 0x00000071012b2d58,O,000260,_ZN4ksys4phys10SystemData20loadMaterialTableResEv 0x00000071012b2e5c,O,000260,_ZN4ksys4phys10SystemData23loadSubMaterialTableResEv 0x00000071012b2f60,O,000304,_ZN4ksys4phys10SystemData23loadContactInfoTableResENS0_16ContactLayerTypeE 0x00000071012b3090,O,000260,_ZN4ksys4phys10SystemData25loadCharacterCtrlTableResEv -0x00000071012b3194,U,000164,_ZN4ksys4phys14LayerTableInfo9postRead_Ev -0x00000071012b3238,O,000160,_ZN4ksys4phys14LayerTableInfoD2Ev -0x00000071012b32d8,O,000004,_ZN4ksys4phys14LayerTableInfoD0Ev +0x00000071012b3194,O,000164,_ZN4ksys4phys10LayerTable9postRead_Ev +0x00000071012b3238,O,000160,_ZN4ksys4phys10LayerTableD2Ev +0x00000071012b32d8,O,000004,_ZN4ksys4phys10LayerTableD0Ev 0x00000071012b32dc,O,000480,_ZN4sead9SafeArrayIN3agl3utl9ParameterIfEELi36EEC2Ev 0x00000071012b34bc,O,000176,_ZN4ksys4phys24CharacterControllerTableD2Ev 0x00000071012b356c,O,000004,_ZN4ksys4phys24CharacterControllerTableD0Ev diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index 4307197e..928e58bd 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -42,6 +42,8 @@ target_sources(uking PRIVATE System/physContactInfoTable.h System/physDefines.cpp System/physDefines.h + System/physEntityGroupFilter.cpp + System/physEntityGroupFilter.h System/physGroupFilter.cpp System/physGroupFilter.h System/physInstanceSet.cpp diff --git a/src/KingSystem/Physics/System/physEntityGroupFilter.cpp b/src/KingSystem/Physics/System/physEntityGroupFilter.cpp new file mode 100644 index 00000000..52618d7a --- /dev/null +++ b/src/KingSystem/Physics/System/physEntityGroupFilter.cpp @@ -0,0 +1,43 @@ +#include "KingSystem/Physics/System/physEntityGroupFilter.h" +#include +#include "KingSystem/Utils/HeapUtil.h" + +namespace ksys::phys { + +constexpr int NumEntityHandlersInList0 = 0x10; +constexpr int NumEntityHandlers = 0x400; + +EntityGroupFilter* EntityGroupFilter::make(ContactLayer::ValueType first, + ContactLayer::ValueType last, sead::Heap* heap) { + auto* filter = util::alloc(heap, first, last); + filter->initFilter(heap); + return filter; +} + +EntityGroupFilter::EntityGroupFilter(ContactLayer::ValueType first, ContactLayer::ValueType last) + : GroupFilter(ContactLayerType::Entity, first, last) {} + +EntityGroupFilter::~EntityGroupFilter() = default; + +void EntityGroupFilter::doInit_(sead::Heap* heap) { + // Enable all collisions by default. + mMasks.fill(0xffffffff); +} + +void EntityGroupFilter::doInitSystemGroupHandlerLists_(sead::Heap* heap) { + for (auto& list : mFreeLists) + list.initOffset(SystemGroupHandler::getFreeListNodeOffset()); + + mUsedList.initOffset(SystemGroupHandler::getUsedListNodeOffset()); + + for (int i = 1; i < NumEntityHandlers; ++i) { + auto& list = mFreeLists[i < NumEntityHandlersInList0]; + list.pushBack(new (heap) EntitySystemGroupHandler(i, 0)); + } +} + +int EntityGroupFilter::getFreeListIndex(const SystemGroupHandler* handler) { + return handler->getIndex() < NumEntityHandlersInList0; +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physEntityGroupFilter.h b/src/KingSystem/Physics/System/physEntityGroupFilter.h new file mode 100644 index 00000000..ca83b49d --- /dev/null +++ b/src/KingSystem/Physics/System/physEntityGroupFilter.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include "KingSystem/Physics/System/physDefines.h" +#include "KingSystem/Physics/System/physGroupFilter.h" + +namespace ksys::phys { + +class EntitySystemGroupHandler : public SystemGroupHandler { +public: + using SystemGroupHandler::SystemGroupHandler; + + u32 m5() override; + u32 m6() override; + bool m8() override; +}; + +class EntityGroupFilter : public GroupFilter { + SEAD_RTTI_OVERRIDE(EntityGroupFilter, GroupFilter) +public: + static EntityGroupFilter* make(ContactLayer::ValueType first, ContactLayer::ValueType last, + sead::Heap* heap); + + EntityGroupFilter(ContactLayer::ValueType first, ContactLayer::ValueType last); + ~EntityGroupFilter() override; + + hkBool isCollisionEnabled(const hkpCollidable& a, const hkpCollidable& b) const override; + hkBool isCollisionEnabled(const hkpCollisionInput& input, const hkpCdBody& a, + const hkpCdBody& b, const hkpShapeContainer& bContainer, + hkpShapeKey bKey) const override; + hkBool isCollisionEnabled(const hkpCollisionInput& input, const hkpCdBody& collectionBodyA, + const hkpCdBody& collectionBodyB, + const hkpShapeContainer& containerShapeA, + const hkpShapeContainer& containerShapeB, hkpShapeKey keyA, + hkpShapeKey keyB) const override; + hkBool isCollisionEnabled(const hkpShapeRayCastInput& aInput, + const hkpShapeContainer& bContainer, hkpShapeKey bKey) const override; + hkBool isCollisionEnabled(const hkpWorldRayCastInput& inputA, + const hkpCollidable& collidableB) const override; + + bool m2() override { return GroupFilter::m2(); } + void m3() override {} + void m4() override {} + void m5() override {} + void m6() override {} + void m7() override {} + void m8() override {} + + void setLayerCustomMask(ContactLayer layer, u32 mask) override { mMasks[layer] = mask; } + + void m10() override {} + +private: + void doInitSystemGroupHandlerLists_(sead::Heap* heap) override; + int getFreeListIndex(const SystemGroupHandler* handler) override; + void doInit_(sead::Heap* heap) override; + virtual void m14(); + virtual void m15(); + + sead::SafeArray mMasks; +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physGroupFilter.cpp b/src/KingSystem/Physics/System/physGroupFilter.cpp index ee698581..c8f0df8d 100644 --- a/src/KingSystem/Physics/System/physGroupFilter.cpp +++ b/src/KingSystem/Physics/System/physGroupFilter.cpp @@ -1,13 +1,61 @@ #include "KingSystem/Physics/System/physGroupFilter.h" +#include +#include "KingSystem/Physics/System/physMemSystem.h" namespace ksys::phys { GroupFilter::GroupFilter(ContactLayerType type, ContactLayer::ValueType layer_first, ContactLayer::ValueType layer_last) - : mIdxLayerFirst(layer_first), mIdxLayerLast(layer_last), mLayerType(type) {} + : mLayerFirst(layer_first), mLayerLast(layer_last), mLayerType(type) {} GroupFilter::~GroupFilter() = default; -void GroupFilter::m13() {} +void GroupFilter::initFilter(sead::Heap* heap) { + for (auto& mask : m_collisionLookupTable) + mask = 0; + + doInit_(heap); + doInitSystemGroupHandlerLists_(heap); + mInhibitCollisions = false; +} + +void GroupFilter::destroy() { + for (auto& list : mFreeLists) { + while (auto* handler = list.popFront()) { + delete handler; + } + } + delete this; +} + +SystemGroupHandler* GroupFilter::addSystemGroupHandler(int free_list_idx) { + mCS.lock(); + + auto* handler = mFreeLists[free_list_idx].popFront(); + if (!handler) { + mCS.unlock(); + return nullptr; + } + + mUsedList.pushBack(handler); + mCS.unlock(); + return handler; +} + +void GroupFilter::removeSystemGroupHandler(SystemGroupHandler* handler) { + auto lock = sead::makeScopedLock(mCS); + + const int free_list_idx = getFreeListIndex(handler); + mFreeLists[free_list_idx].pushBack(handler); + mUsedList.erase(handler); +} + +u32 SystemGroupHandler::m7() { + return 0; +} + +void SystemGroupHandler::removeThis() { + MemSystem::instance()->removeSystemGroupHandler(this); +} } // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physGroupFilter.h b/src/KingSystem/Physics/System/physGroupFilter.h index 08a17ae2..ddf4b327 100644 --- a/src/KingSystem/Physics/System/physGroupFilter.h +++ b/src/KingSystem/Physics/System/physGroupFilter.h @@ -3,12 +3,54 @@ #include #include #include +#include #include #include #include "KingSystem/Physics/System/physDefines.h" namespace ksys::phys { +class SystemGroupHandler { + SEAD_RTTI_BASE(SystemGroupHandler) +public: + explicit SystemGroupHandler(int index, int filter_index) + : mIndex(index), mFilterIndex(filter_index) {} + + virtual ~SystemGroupHandler() = default; + virtual u32 m5() = 0; + virtual u32 m6() = 0; + virtual u32 m7(); + virtual bool m8() = 0; + + int getIndex() const { return mIndex; } + int getFilterIndex() const { return mFilterIndex; } + + const char* getActorName() const { return mActorName; } + void setActorName(const char* name) { mActorName = name; } + + const char* getActorProfile() const { return mActorProfile; } + void setActorProfile(const char* name) { mActorProfile = name; } + + /// Remove this handler from the filter it's attached to. + void removeThis(); + + static constexpr auto getFreeListNodeOffset() { + return offsetof(SystemGroupHandler, mFreeListNode); + } + + static constexpr auto getUsedListNodeOffset() { + return offsetof(SystemGroupHandler, mUsedListNode); + } + +protected: + const char* mActorName = nullptr; + const char* mActorProfile = nullptr; + int mIndex = 0; + int mFilterIndex = 0; + sead::ListNode mFreeListNode; + sead::ListNode mUsedListNode; +}; + class GroupFilter : public hkpGroupFilter { SEAD_RTTI_BASE(GroupFilter) public: @@ -16,7 +58,22 @@ public: ContactLayer::ValueType layer_last); ~GroupFilter() override; -protected: + ContactLayer::ValueType getLayerFirst() const { return mLayerFirst; } + ContactLayer::ValueType getLayerLast() const { return mLayerLast; } + ContactLayerType getLayerType() const { return mLayerType; } + + void initFilter(sead::Heap* heap); + /// Frees all memory associated with this instance and then self-destructs. + /// @warning Do not use this filter after a call to destroy! + void destroy(); + + SystemGroupHandler* addSystemGroupHandler(int free_list_idx); + void removeSystemGroupHandler(SystemGroupHandler* handler); + + void setLayerCollisionEnabledMask(ContactLayer layer, u32 mask) { + m_collisionLookupTable[layer - getLayerFirst()] = mask; + } + virtual bool m2() { return true; } virtual void m3() = 0; virtual void m4() = 0; @@ -24,21 +81,23 @@ protected: virtual void m6() = 0; virtual void m7() = 0; virtual void m8() = 0; - virtual void m9() {} + virtual void setLayerCustomMask(ContactLayer layer, u32 mask) {} virtual void m10() = 0; - virtual void m11() = 0; - virtual void m12() = 0; - virtual void m13(); - u32 mIdxLayerFirst{}; - u32 mIdxLayerLast{}; +protected: + virtual void doInitSystemGroupHandlerLists_(sead::Heap* heap) = 0; + virtual int getFreeListIndex(const SystemGroupHandler* handler) = 0; + + /// Initialises internal state. + virtual void doInit_(sead::Heap* heap) {} + + ContactLayer::ValueType mLayerFirst{}; + ContactLayer::ValueType mLayerLast{}; ContactLayerType mLayerType{}; - u8 _11c{}; - // FIXME: types - sead::OffsetList _120; - sead::OffsetList _138; + bool mInhibitCollisions{}; + sead::SafeArray, 2> mFreeLists; sead::CriticalSection mCS; - sead::OffsetList _190; + sead::OffsetList mUsedList; }; } // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physMemSystem.h b/src/KingSystem/Physics/System/physMemSystem.h index 5866d072..3bd26cab 100644 --- a/src/KingSystem/Physics/System/physMemSystem.h +++ b/src/KingSystem/Physics/System/physMemSystem.h @@ -6,6 +6,7 @@ namespace ksys::phys { class RigidBody; +class SystemGroupHandler; class MemSystem { SEAD_SINGLETON_DISPOSER(MemSystem) @@ -14,6 +15,8 @@ public: void sub_7100FA6C8C(bool, RigidBody*); }; + void removeSystemGroupHandler(SystemGroupHandler* handler); + u8 _20[0x140]; Struct160* _160; }; diff --git a/src/KingSystem/Physics/System/physSystemData.cpp b/src/KingSystem/Physics/System/physSystemData.cpp index 41f3845e..319bb98e 100644 --- a/src/KingSystem/Physics/System/physSystemData.cpp +++ b/src/KingSystem/Physics/System/physSystemData.cpp @@ -1,5 +1,6 @@ #include "KingSystem/Physics/System/physSystemData.h" #include "KingSystem/Physics/System/physContactInfoTable.h" +#include "KingSystem/Physics/System/physGroupFilter.h" #include "KingSystem/Physics/System/physMaterialTable.h" #include "KingSystem/Physics/System/physRagdollControllerKeyList.h" #include "KingSystem/Resource/resHandle.h" @@ -21,10 +22,10 @@ SystemData::~SystemData() { deleteAndNull(mMaterialTableHandle); deleteAndNull(mSubMaterialTableHandle); - deleteAndNull(mLayerTableInfo[0].mResHandle); + deleteAndNull(mLayerMatrices[0].mResHandle); deleteAndNull(mContactInfoTableHandles[0]); - deleteAndNull(mLayerTableInfo[1].mResHandle); + deleteAndNull(mLayerMatrices[1].mResHandle); deleteAndNull(mContactInfoTableHandles[1]); deleteAndNull(mCharacterCtrlTable.mResHandle); @@ -36,11 +37,11 @@ SystemData::~SystemData() { } } -void SystemData::load(sead::Heap* heap, LayerTable* entity_layer_table, - LayerTable* sensor_layer_table, MaterialTable* material_table, +void SystemData::load(sead::Heap* heap, GroupFilter* entity_group_filter, + GroupFilter* sensor_group_filter, MaterialTable* material_table, ContactInfoTable* contact_info_table) { - loadLayerTable(heap, entity_layer_table, ContactLayerType::Entity); - loadLayerTable(heap, sensor_layer_table, ContactLayerType::Sensor); + loadLayerTable(heap, entity_group_filter, ContactLayerType::Entity); + loadLayerTable(heap, sensor_group_filter, ContactLayerType::Sensor); loadMaterialTable(heap, material_table); loadSubMaterialTable(heap, material_table); loadContactInfoTable(heap, contact_info_table, ContactLayerType::Entity); @@ -49,6 +50,34 @@ void SystemData::load(sead::Heap* heap, LayerTable* entity_layer_table, loadRagdollCtrlKeyList(heap); } +void SystemData::loadLayerTable(sead::Heap* heap, GroupFilter* filter, ContactLayerType type) { + auto& matrix = mLayerMatrices[int(type)]; + matrix.addList("LayerTable"); + + const int first = filter->getLayerFirst(); + const int last = filter->getLayerLast(); + const int num_layers = 1 + last - first; + + for (int i = 0; i < num_layers; ++i) { + auto& table = matrix.mTables[i]; + const ContactLayer layer = first + i; + table.num_layers = num_layers; + table.filter = filter; + table.layer = layer; + + matrix.mParamList.addObj(&table, contactLayerToText(layer)); + + for (int j = 0; j < num_layers; ++j) { + const char* other_layer_name = contactLayerToText(first + j); + table.layer_values[j].init(0, other_layer_name, other_layer_name, &table); + } + } + + matrix.mResHandle = new (heap) res::Handle; + const auto res = loadLayerTableRes(matrix, type); + matrix.mParamIO.applyResParameterArchive(res); +} + void SystemData::loadMaterialTable(sead::Heap* heap, MaterialTable* table) { mMaterialTableHandle = new (heap) res::Handle; const auto res = loadMaterialTableRes(); @@ -95,9 +124,8 @@ void SystemData::loadRagdollCtrlKeyList(sead::Heap* heap) { mRagdollCtrlKeyList = sead::DynamicCast(res); } -agl::utl::ResParameterArchive -SystemData::loadLayerTableRes(const SystemData::LayerTableInfoContainer& container, - ContactLayerType type) { +agl::utl::ResParameterArchive SystemData::loadLayerTableRes(const SystemData::LayerMatrix& matrix, + ContactLayerType type) { res::LoadRequest request; request.mRequester = "physSystemData"; const char* path{}; @@ -109,7 +137,7 @@ SystemData::loadLayerTableRes(const SystemData::LayerTableInfoContainer& contain path = "Physics/System/SensorLayerTable.bphyslayer"; break; } - const auto& resource = *container.mResHandle->load(path, &request); + const auto& resource = *matrix.mResHandle->load(path, &request); auto* direct_resource = sead::DynamicCast(&resource); return agl::utl::ResParameterArchive{direct_resource->getRawData()}; } @@ -159,8 +187,20 @@ agl::utl::ResParameterArchive SystemData::loadCharacterCtrlTableRes() { return agl::utl::ResParameterArchive{direct_resource->getRawData()}; } -void LayerTableInfo::postRead_() { - // FIXME +void LayerTable::postRead_() { + u32 collision_mask = 0; + u32 custom_mask = 0; + + for (int i = 0; i < num_layers; ++i) { + const int value = layer_values[i].ref(); + if (value & 1) + collision_mask |= 1 << i; + if (value & 2) + custom_mask |= 1 << i; + } + + filter->setLayerCollisionEnabledMask(layer, collision_mask); + filter->setLayerCustomMask(layer, custom_mask); } } // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physSystemData.h b/src/KingSystem/Physics/System/physSystemData.h index 38d7b7ff..4ee13ef7 100644 --- a/src/KingSystem/Physics/System/physSystemData.h +++ b/src/KingSystem/Physics/System/physSystemData.h @@ -17,22 +17,22 @@ class Handle; namespace ksys::phys { class ContactInfoTable; -class LayerTable; +class GroupFilter; class MaterialTable; class RagdollControllerKeyList; constexpr int NumLayers = 32; -struct LayerTableInfo : agl::utl::IParameterObj { - sead::SafeArray, NumLayers> params; - void* table; // FIXME: type GroupFilter - int idx = 0; // FIXME: ContactLayer - int count; +struct LayerTable : agl::utl::IParameterObj { + sead::SafeArray, NumLayers> layer_values; + GroupFilter* filter; + ContactLayer layer; + int num_layers; protected: void postRead_() override; }; -KSYS_CHECK_SIZE_NX150(LayerTableInfo, 0x440); +KSYS_CHECK_SIZE_NX150(LayerTable, 0x440); struct CharacterControllerTable : agl::utl::IParameterObj { SEAD_ENUM(Type, Default) @@ -63,27 +63,27 @@ public: SystemData(); virtual ~SystemData(); - void load(sead::Heap* heap, LayerTable* entity_layer_table, LayerTable* sensor_layer_table, + void load(sead::Heap* heap, GroupFilter* entity_group_filter, GroupFilter* sensor_group_filter, MaterialTable* material_table, ContactInfoTable* contact_info_table); private: - using LayerTableInfoContainer = Tables; + using LayerMatrix = Tables; - void loadLayerTable(sead::Heap* heap, LayerTable* table, ContactLayerType type); + void loadLayerTable(sead::Heap* heap, GroupFilter* filter, ContactLayerType type); void loadMaterialTable(sead::Heap* heap, MaterialTable* table); void loadSubMaterialTable(sead::Heap* heap, MaterialTable* table); void loadContactInfoTable(sead::Heap* heap, ContactInfoTable* table, ContactLayerType type); void loadCharacterCtrlTable(sead::Heap* heap); void loadRagdollCtrlKeyList(sead::Heap* heap); - agl::utl::ResParameterArchive loadLayerTableRes(const LayerTableInfoContainer& container, + agl::utl::ResParameterArchive loadLayerTableRes(const LayerMatrix& matrix, ContactLayerType type); agl::utl::ResParameterArchive loadMaterialTableRes(); agl::utl::ResParameterArchive loadSubMaterialTableRes(); agl::utl::ResParameterArchive loadContactInfoTableRes(ContactLayerType type); agl::utl::ResParameterArchive loadCharacterCtrlTableRes(); - sead::SafeArray mLayerTableInfo{}; + sead::SafeArray mLayerMatrices{}; res::Handle* mMaterialTableHandle{}; res::Handle* mSubMaterialTableHandle{}; sead::SafeArray mContactInfoTableHandles{}; diff --git a/src/KingSystem/Utils/HeapUtil.h b/src/KingSystem/Utils/HeapUtil.h index b5629aa7..238bfe63 100644 --- a/src/KingSystem/Utils/HeapUtil.h +++ b/src/KingSystem/Utils/HeapUtil.h @@ -124,4 +124,10 @@ KSYS_ALWAYS_INLINE inline sead::Heap* tryCreateDualHeap(sead::Heap* parent) { sead::Heap::cHeapDirection_Forward, false); } +template +inline T* alloc(sead::Heap* heap, Args&&... args) { + void* storage = heap->alloc(sizeof(T), alignof(T)); + return new (storage) T(std::forward(args)...); +} + } // namespace ksys::util