diff options
| author | Léo Lam <leo@leolam.fr> | 2022-03-01 16:55:34 +0100 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2022-03-01 19:11:54 +0100 |
| commit | 18d0c5329327c5d0841e6c446f6453e6c3850ece (patch) | |
| tree | 9440aadf66d06f43a8f552724bd9cd8d49ee03f1 /src | |
| parent | 7f52270cdda40abdab53380bd6e7185a77fc882f (diff) | |
ksys/phys: Add some ContactListener prerequisites
Diffstat (limited to 'src')
| -rw-r--r-- | src/KingSystem/Physics/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/KingSystem/Physics/RigidBody/physRigidBody.h | 7 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physCollisionInfo.h | 43 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physContactListener.cpp | 52 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physContactListener.h | 39 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physContactMgr.h | 11 | ||||
| -rw-r--r-- | src/KingSystem/Physics/System/physInstanceSet.h | 4 |
7 files changed, 142 insertions, 15 deletions
diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index 58d78215..cdeaec75 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -99,6 +99,7 @@ target_sources(uking PRIVATE System/physCharacterControllerParam.cpp System/physCharacterControllerParam.h + System/physCollisionInfo.h System/physConstraint.cpp System/physConstraint.h System/physContactInfoParam.cpp diff --git a/src/KingSystem/Physics/RigidBody/physRigidBody.h b/src/KingSystem/Physics/RigidBody/physRigidBody.h index b98ba414..f3fb87ba 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBody.h +++ b/src/KingSystem/Physics/RigidBody/physRigidBody.h @@ -187,8 +187,11 @@ public: // 0x0000007100f8e3fc void x_11(); + // TODO: rename + void* get90() const { return _90; } // 0x0000007100f8e72c - void x_12(); + void x_12_setField90(void* field_90); + RigidContactPoints* getContactPoints() const { return mContactPoints; } void setContactPoints(RigidContactPoints* points); void freeze(bool should_freeze, bool preserve_velocities, bool preserve_max_impulse); @@ -206,6 +209,8 @@ public: void setContactMask(u32); void setContactAll(); void setContactNone(); + sead::BitFlag32 getContactMask() const { return mContactMask; } + sead::BitFlag32 getIgnoredLayers() const { return ~getContactMask(); } void enableGroundCollision(bool enabled); bool isGroundCollisionEnabled() const; diff --git a/src/KingSystem/Physics/System/physCollisionInfo.h b/src/KingSystem/Physics/System/physCollisionInfo.h new file mode 100644 index 00000000..9a252b01 --- /dev/null +++ b/src/KingSystem/Physics/System/physCollisionInfo.h @@ -0,0 +1,43 @@ +#pragma once + +#include <container/seadSafeArray.h> +#include <prim/seadBitFlag.h> +#include <thread/seadMutex.h> +#include "KingSystem/Physics/physDefines.h" + +namespace ksys::phys { + +class CollisionInfoBase { +public: + CollisionInfoBase() = default; + virtual ~CollisionInfoBase() = default; + + sead::BitFlag32& getLayerMask(ContactLayerType layer_type); + const sead::BitFlag32& getLayerMask(ContactLayerType layer_type) const; + + void lock(); + void unlock(); + +private: + // One layer mask for layer type (entity/sensor). + sead::SafeArray<sead::BitFlag32, 2> mLayerMasks; + sead::Mutex mMutex; +}; + +inline sead::BitFlag32& CollisionInfoBase::getLayerMask(ContactLayerType layer_type) { + return mLayerMasks[int(layer_type)]; +} + +inline const sead::BitFlag32& CollisionInfoBase::getLayerMask(ContactLayerType layer_type) const { + return mLayerMasks[int(layer_type)]; +} + +inline void CollisionInfoBase::lock() { + mMutex.lock(); +} + +inline void CollisionInfoBase::unlock() { + mMutex.unlock(); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physContactListener.cpp b/src/KingSystem/Physics/System/physContactListener.cpp index c3ad636b..4a2a72aa 100644 --- a/src/KingSystem/Physics/System/physContactListener.cpp +++ b/src/KingSystem/Physics/System/physContactListener.cpp @@ -1,9 +1,13 @@ #include "KingSystem/Physics/System/physContactListener.h" +#include <Havok/Common/Base/Types/Physics/ContactPoint/hkContactPoint.h> #include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpCollisionEvent.h> #include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpContactPointEvent.h> +#include <Havok/Physics2012/Utilities/CharacterControl/CharacterRigidBody/hkpCharacterRigidBody.h> #include <math/seadMathCalcCommon.h> #include <prim/seadMemUtil.h> #include "KingSystem/Physics/RigidBody/physRigidBody.h" +#include "KingSystem/Physics/System/physContactMgr.h" +#include "KingSystem/Physics/System/physSystem.h" namespace ksys::phys { @@ -65,4 +69,52 @@ void ContactListener::collisionRemovedCallback(const hkpCollisionEvent& event) { bodyB->onCollisionRemoved(); } +void ContactListener::contactPointCallback(const hkpContactPointEvent& event) { + RigidBody* body_a = getRigidBody(event.getBody(0)); + RigidBody* body_b = getRigidBody(event.getBody(1)); + + if (event.m_contactPoint->getPosition().getInt24W() == hkpCharacterRigidBody::m_magicNumber) { + const auto layer_a = body_a->getContactLayer(); + const auto layer_b = body_b->getContactLayer(); + const u32 ignored_layers_a = ~body_a->getContactMask(); + const u32 ignored_layers_b = ~body_b->getContactMask(); + + static_cast<void>(System::instance()->getGroupFilter(mLayerType)); + + characterControlContactPointCallback(ignored_layers_a, ignored_layers_b, body_a, body_b, + layer_a, layer_b, event); + + } else if (event.m_type == hkpContactPointEvent::TYPE_MANIFOLD) { + manifoldContactPointCallback(event, body_a, body_b); + } else { + regularContactPointCallback(event, body_a, body_b); + } +} + +void ContactListener::handleCollisionRemoved(const hkpCollisionEvent& event, RigidBody* body_a, + RigidBody* body_b) { + unregisterForEndOfStepContactPointCallbacks(event); + + const auto layer_a = body_a->getContactLayer(); + const auto layer_b = body_b->getContactLayer(); + + if (auto* unk = body_a->get90()) + mMgr->x_19(unk, body_a, body_b); + + if (auto* unk = body_b->get90()) + mMgr->x_19(unk, body_b, body_a); + + const auto i = int(layer_a - mLayerBase); + const auto j = int(layer_b - mLayerBase); + ContactUnk1* unk = _30[i][j]; + if (unk->_68) { + const auto layer_a_ = int(layer_a); + const auto layer_unk = unk->_50; + const bool body_a_first = layer_a_ == layer_unk; + auto* body1 = body_a_first ? body_a : body_b; + auto* body2 = body_a_first ? body_b : body_a; + mMgr->x_20(unk, body1, body2); + } +} + } // namespace ksys::phys diff --git a/src/KingSystem/Physics/System/physContactListener.h b/src/KingSystem/Physics/System/physContactListener.h index a01218a3..f04aa91b 100644 --- a/src/KingSystem/Physics/System/physContactListener.h +++ b/src/KingSystem/Physics/System/physContactListener.h @@ -17,7 +17,11 @@ struct ContactUnk1 { ContactUnk1(u32 layer); virtual ~ContactUnk1(); - u8 _8[0x68]; + u8 _8[0x50 - 0x8]; + ContactLayer _50; + u8 _54[0x68 - 0x54]; + u32 _68; + u32 _6c; }; class ContactListener : public hkpContactListener, public sead::hostio::Node { @@ -32,20 +36,31 @@ public: void contactPointCallback(const hkpContactPointEvent& event) override; void collisionAddedCallback(const hkpCollisionEvent& event) override; void collisionRemovedCallback(const hkpCollisionEvent& event) override; - void contactPointAddedCallback(hkpContactPointAddedEvent& event) override; - void contactPointRemovedCallback(hkpContactPointRemovedEvent& event) override; - void contactProcessCallback(hkpContactProcessEvent& event) override; + void contactPointAddedCallback(hkpContactPointAddedEvent& event) override {} + void contactPointRemovedCallback(hkpContactPointRemovedEvent& event) override {} + void contactProcessCallback(hkpContactProcessEvent& event) override {} + +protected: + virtual void characterControlContactPointCallback(u32 ignored_layers_a, u32 ignored_layers_b, + RigidBody* body_a, RigidBody* body_b, + ContactLayer layer_a, ContactLayer layer_b, + const hkpContactPointEvent& event); - virtual void m10(); virtual void m11() {} - virtual void handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* bodyA, - RigidBody* bodyB); - virtual void m13(); - virtual void m14(); - virtual u32 m15() { return 0; } -protected: - void handleCollisionRemoved(const hkpCollisionEvent& event, RigidBody* bodyA, RigidBody* bodyB); + virtual void handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a, + RigidBody* body_b); + + void handleCollisionRemoved(const hkpCollisionEvent& event, RigidBody* body_a, + RigidBody* body_b); + + virtual void manifoldContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a, + RigidBody* body_b); + + virtual void regularContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a, + RigidBody* body_b, void* unk = nullptr); + + virtual u32 m15() { return 0; } private: struct Unk1 { diff --git a/src/KingSystem/Physics/System/physContactMgr.h b/src/KingSystem/Physics/System/physContactMgr.h index 2e989f8a..5a868033 100644 --- a/src/KingSystem/Physics/System/physContactMgr.h +++ b/src/KingSystem/Physics/System/physContactMgr.h @@ -22,8 +22,10 @@ class Heap; namespace ksys::phys { +struct ContactUnk1; enum class IsIndoorStage; class IRigidContactPoints; +class RigidBody; class RigidContactPoints; class RigidContactPointsEx; @@ -86,6 +88,15 @@ public: void registerContactPoints(IRigidContactPoints* points); void freeContactPoints(IRigidContactPoints* points); + // 0x0000007100fb3744 + void x_17(void* unk, RigidBody* body_a, RigidBody* body_b); + // 0x0000007100fb37d4 + void x_18(ContactUnk1* unk, RigidBody* body_a, RigidBody* body_b); + // 0x0000007100fb3854 + void x_19(void* unk, RigidBody* body_a, RigidBody* body_b); + // 0x0000007100fb3938 + void x_20(ContactUnk1* unk, RigidBody* body_a, RigidBody* body_b); + private: void doLoadContactInfoTable(agl::utl::ResParameterArchive archive, ContactLayerType type, bool skip_params); diff --git a/src/KingSystem/Physics/System/physInstanceSet.h b/src/KingSystem/Physics/System/physInstanceSet.h index 5f2f2354..0f65245f 100644 --- a/src/KingSystem/Physics/System/physInstanceSet.h +++ b/src/KingSystem/Physics/System/physInstanceSet.h @@ -38,7 +38,7 @@ public: void enableCollisionMaybe_0(ContactLayer); }; -struct CollisionInfo { +struct CollisionInfoBase { u8 filler[0x50]; sead::SafeString mName; }; @@ -96,7 +96,7 @@ private: f32 mScale; u8 _34[0x40 - 0x34]; sead::PtrArray<RigidBodySet> mRigidBodySets; - sead::PtrArray<CollisionInfo> mCollisionInfos; + sead::PtrArray<CollisionInfoBase> mCollisionInfos; sead::PtrArray<ContactInfo> mContactInfos; u8 _70[0x10]; |
