summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2022-03-01 16:55:34 +0100
committerLéo Lam <leo@leolam.fr>2022-03-01 19:11:54 +0100
commit18d0c5329327c5d0841e6c446f6453e6c3850ece (patch)
tree9440aadf66d06f43a8f552724bd9cd8d49ee03f1 /src
parent7f52270cdda40abdab53380bd6e7185a77fc882f (diff)
ksys/phys: Add some ContactListener prerequisites
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/Physics/CMakeLists.txt1
-rw-r--r--src/KingSystem/Physics/RigidBody/physRigidBody.h7
-rw-r--r--src/KingSystem/Physics/System/physCollisionInfo.h43
-rw-r--r--src/KingSystem/Physics/System/physContactListener.cpp52
-rw-r--r--src/KingSystem/Physics/System/physContactListener.h39
-rw-r--r--src/KingSystem/Physics/System/physContactMgr.h11
-rw-r--r--src/KingSystem/Physics/System/physInstanceSet.h4
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];