ksys/phys: Start adding ContactListener

This commit is contained in:
Léo Lam 2022-01-21 12:59:31 +01:00
parent c292675646
commit c36c03c6fb
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
5 changed files with 163 additions and 13 deletions

View File

@ -84291,13 +84291,13 @@ Address,Quality,Size,Name
0x0000007100fcdb38,U,000224,
0x0000007100fcdc18,U,000020,
0x0000007100fcdc2c,U,000204,
0x0000007100fcdcf8,U,000104,
0x0000007100fcdd60,U,000024,
0x0000007100fcdd78,U,000060,
0x0000007100fcddb4,U,000972,
0x0000007100fce180,U,000020,
0x0000007100fce194,U,000136,
0x0000007100fce21c,U,000136,
0x0000007100fcdcf8,O,000104,_ZN4ksys4phys15ContactListenerC1EPNS0_10ContactMgrENS0_16ContactLayerTypeEi
0x0000007100fcdd60,O,000024,_ZN4ksys4phys15ContactListenerD1Ev
0x0000007100fcdd78,O,000060,_ZN4ksys4phys15ContactListenerD0Ev
0x0000007100fcddb4,O,000972,_ZN4ksys4phys15ContactListener4initEPN4sead4HeapE
0x0000007100fce180,O,000020,_ZN4ksys4phys15ContactListener10clearTableEv
0x0000007100fce194,O,000136,_ZN4ksys4phys15ContactListener22collisionAddedCallbackERK17hkpCollisionEvent
0x0000007100fce21c,O,000136,_ZN4ksys4phys15ContactListener24collisionRemovedCallbackERK17hkpCollisionEvent
0x0000007100fce2a4,U,000236,
0x0000007100fce390,U,000416,
0x0000007100fce530,U,000028,
@ -84313,10 +84313,10 @@ Address,Quality,Size,Name
0x0000007100fcf6b4,U,000124,
0x0000007100fcf730,U,000156,
0x0000007100fcf7cc,U,000024,
0x0000007100fcf7e4,U,000112,
0x0000007100fcf854,U,000092,
0x0000007100fcf8b0,U,000004,nullsub_4257
0x0000007100fcf8b4,U,000008,
0x0000007100fcf7e4,O,000112,_ZNK4ksys4phys15ContactListener27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007100fcf854,O,000092,_ZNK4ksys4phys15ContactListener18getRuntimeTypeInfoEv
0x0000007100fcf8b0,O,000004,_ZN4ksys4phys15ContactListener3m11Ev
0x0000007100fcf8b4,O,000008,_ZN4ksys4phys15ContactListener3m15Ev
0x0000007100fcf8bc,O,000072,_ZN4ksys4phys20RigidContactPointsEx4makeEPN4sead4HeapEiiRKNS2_14SafeStringBaseIcEEiii
0x0000007100fcf904,O,000348,_ZN4ksys4phys20RigidContactPointsEx17registerLayerPairENS0_12ContactLayerES2_b
0x0000007100fcfa60,O,000024,_ZN4ksys4phys20RigidContactPointsEx4freeEPS1_

Can't render this file because it is too large.

View File

@ -70,6 +70,8 @@ target_sources(uking PRIVATE
System/physConstraint.h
System/physContactInfoParam.cpp
System/physContactInfoParam.h
System/physContactListener.cpp
System/physContactListener.h
System/physContactMgr.cpp
System/physContactMgr.h
System/physDefines.cpp

View File

@ -365,6 +365,18 @@ public:
virtual void resetPosition();
virtual const char* getName();
// Internal.
void onCollisionAdded() {
if (mCollisionCount.increment() == 0)
clearFlag4000000(false);
}
// Internal.
void onCollisionRemoved() {
if (mCollisionCount.decrement() == 1)
clearFlag4000000(true);
}
private:
void createMotionAccessor(sead::Heap* heap);
void onInvalidParameter(int code = 0);
@ -385,8 +397,7 @@ private:
f32 _b0 = 1.0f;
Type mType{};
MotionAccessor* mMotionAccessor = nullptr;
u16 _c0 = 0;
u16 _c2 = 0;
sead::Atomic<int> mCollisionCount;
void* _c8 = nullptr;
};
KSYS_CHECK_SIZE_NX150(RigidBody, 0xD0);

View File

@ -0,0 +1,68 @@
#include "KingSystem/Physics/System/physContactListener.h"
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpCollisionEvent.h>
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpContactPointEvent.h>
#include <math/seadMathCalcCommon.h>
#include <prim/seadMemUtil.h>
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
namespace ksys::phys {
static RigidBody* getRigidBody(hkpRigidBody* hk_body) {
// This needs to be kept in sync with the RigidBody constructor!
return reinterpret_cast<RigidBody*>(hk_body->getUserData());
}
ContactListener::ContactListener(ContactMgr* mgr, ContactLayerType layer_type, int layer_count)
: mMgr(mgr), mLayerType(layer_type), mLayerBase(getContactLayerBase(layer_type)),
mLayerCount(layer_count) {}
ContactListener::~ContactListener() = default;
void ContactListener::init(sead::Heap* heap) {
// NOLINTBEGIN(cppcoreguidelines-narrowing-conversions)
_20.allocBufferAssert(mLayerCount, nullptr);
for (u32 i = 0; i < mLayerCount; ++i) {
_20[i].allocBufferAssert(mLayerCount, nullptr);
}
_30.allocBufferAssert(mLayerCount, nullptr);
for (u32 i = 0; i < mLayerCount; ++i) {
auto& row = _30[i];
row.allocBufferAssert(mLayerCount, nullptr);
for (u32 j = 0; j < mLayerCount; ++j) {
if (j >= i) {
row[j] = new (heap) ContactUnk1(mLayerBase + i);
} else {
row[j] = _30[j][i];
}
}
}
// NOLINTEND(cppcoreguidelines-narrowing-conversions)
_48 = sead::Mathu::roundUpPow2(mLayerCount * mLayerCount, 0x20);
_40 = ::operator new[](_48, heap, 0x20);
clearTable();
}
void ContactListener::clearTable() {
sead::MemUtil::fillZero(_40, _48);
}
void ContactListener::collisionAddedCallback(const hkpCollisionEvent& event) {
auto* bodyA = getRigidBody(event.getBody(0));
auto* bodyB = getRigidBody(event.getBody(1));
handleCollisionAdded(event, bodyA, bodyB);
bodyA->onCollisionAdded();
bodyB->onCollisionAdded();
}
void ContactListener::collisionRemovedCallback(const hkpCollisionEvent& event) {
auto* bodyA = getRigidBody(event.getBody(0));
auto* bodyB = getRigidBody(event.getBody(1));
handleCollisionRemoved(event, bodyA, bodyB);
bodyA->onCollisionRemoved();
bodyB->onCollisionRemoved();
}
} // namespace ksys::phys

View File

@ -0,0 +1,69 @@
#pragma once
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpContactListener.h>
#include <container/seadBuffer.h>
#include <container/seadObjArray.h>
#include <hostio/seadHostIONode.h>
#include <prim/seadRuntimeTypeInfo.h>
#include <thread/seadCriticalSection.h>
#include "KingSystem/Physics/System/physDefines.h"
namespace ksys::phys {
class ContactMgr;
class RigidBody;
struct ContactUnk1 {
ContactUnk1(u32 layer);
virtual ~ContactUnk1();
u8 _8[0x68];
};
class ContactListener : public hkpContactListener, public sead::hostio::Node {
SEAD_RTTI_BASE(ContactListener)
public:
ContactListener(ContactMgr* mgr, ContactLayerType layer_type, int layer_count);
~ContactListener() override;
void init(sead::Heap* heap);
void clearTable();
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;
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);
private:
struct Unk1 {
void* _0;
void* _8;
};
ContactMgr* mMgr{};
ContactLayerType mLayerType{};
u32 mLayerBase{};
sead::Buffer<sead::Buffer<sead::FixedObjArray<Unk1, 8>>> _20;
sead::Buffer<sead::Buffer<ContactUnk1*>> _30;
void* _40{};
u32 _48{};
u32 mLayerCount{};
sead::CriticalSection mCS;
u16 _90{};
bool _92{};
};
} // namespace ksys::phys