ksys/phys: Start adding ContactMgr

Also renames ContactInfoTable to ContactMgr because the contact info
table is a separate data structure that's managed by ContactMgr;
the manager itself handles more than just the table data
This commit is contained in:
Léo Lam 2021-12-26 14:33:41 +01:00
parent c716c3eec8
commit 536a00138e
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
14 changed files with 253 additions and 55 deletions

View File

@ -83719,14 +83719,14 @@ Address,Quality,Size,Name
0x0000007100fb2098,U,000092,
0x0000007100fb20f4,U,000004,nullsub_4241
0x0000007100fb20f8,U,000004,j__ZdlPv_1003
0x0000007100fb20fc,U,000308,
0x0000007100fb20fc,O,000308,_ZN4ksys4phys10ContactMgrC1Ev
0x0000007100fb2230,U,000180,
0x0000007100fb22e4,U,000036,
0x0000007100fb2308,U,000212,
0x0000007100fb23dc,U,000152,
0x0000007100fb2474,U,000116,
0x0000007100fb24e8,U,000316,ContactInfoTable
0x0000007100fb2624,U,000688,
0x0000007100fb24e8,O,000316,_ZN4ksys4phys10ContactMgr20loadContactInfoTableEPN4sead4HeapEN3agl3utl19ResParameterArchiveENS0_16ContactLayerTypeE
0x0000007100fb2624,O,000688,_ZN4ksys4phys10ContactMgr22doLoadContactInfoTableEN3agl3utl19ResParameterArchiveENS0_16ContactLayerTypeEb
0x0000007100fb28d4,U,000136,
0x0000007100fb295c,U,000220,
0x0000007100fb2a38,U,000100,
@ -83752,19 +83752,19 @@ Address,Quality,Size,Name
0x0000007100fb3b50,U,000100,
0x0000007100fb3bb4,U,000652,
0x0000007100fb3e40,U,000644,
0x0000007100fb40c4,U,000356,
0x0000007100fb40c4,O,000356,_ZNK4ksys4phys10ContactMgr18getSensorLayerMaskEPNS0_12ReceiverMaskERKN4sead14SafeStringBaseIcEE
0x0000007100fb4228,U,000204,
0x0000007100fb42f4,U,001092,
0x0000007100fb4738,U,000668,
0x0000007100fb49d4,U,000188,
0x0000007100fb4a90,U,000184,
0x0000007100fb4b48,U,000104,
0x0000007100fb4bb0,U,000160,
0x0000007100fb4c50,U,000004,j__ZdlPv_1004
0x0000007100fb4b48,O,000104,_ZN4ksys4phys16ContactInfoTable8Receiver9postRead_Ev
0x0000007100fb4bb0,O,000160,_ZN4ksys4phys16ContactInfoTable8ReceiverD2Ev
0x0000007100fb4c50,O,000004,_ZN4ksys4phys16ContactInfoTable8ReceiverD0Ev
0x0000007100fb4c54,O,000432,_ZN4sead9SafeArrayIN3agl3utl9ParameterIiEELi32EEC2Ev
0x0000007100fb4e04,U,000056,
0x0000007100fb4e3c,U,000036,
0x0000007100fb4e60,U,000016,
0x0000007100fb4e04,O,000056,_ZN4ksys4phys23receiverMaskEnableLayerEPNS0_12ReceiverMaskENS0_12ContactLayerE
0x0000007100fb4e3c,O,000036,_ZN4ksys4phys37receiverMaskGetSensorLayerMaskForTypeEPNS0_12ReceiverMaskERKN4sead14SafeStringBaseIcEE
0x0000007100fb4e60,O,000016,_ZN4ksys4phys30receiverMaskSetSensorLayerMaskEPNS0_12ReceiverMaskEj
0x0000007100fb4e70,O,000144,_ZN4ksys4phys17EntityGroupFilter4makeENS0_12ContactLayer9ValueTypeES3_PN4sead4HeapE
0x0000007100fb4f00,O,000004,_ZN4ksys4phys17EntityGroupFilterD1Ev
0x0000007100fb4f04,O,000008,_ZThn16_N4ksys4phys17EntityGroupFilterD1Ev
@ -95439,7 +95439,7 @@ Address,Quality,Size,Name
0x00000071012b2134,O,000864,_ZN4ksys4phys10SystemDataD1Ev
0x00000071012b2494,O,000404,_ZN4sead9SafeArrayIN4ksys4phys10SystemData6TablesINS2_10LayerTableELi32EEELi2EED2Ev
0x00000071012b2628,O,000036,_ZN4ksys4phys10SystemDataD0Ev
0x00000071012b264c,O,000368,_ZN4ksys4phys10SystemData4loadEPN4sead4HeapEPNS0_11GroupFilterES6_PNS0_13MaterialTableEPNS0_16ContactInfoTableE
0x00000071012b264c,O,000368,_ZN4ksys4phys10SystemData4loadEPN4sead4HeapEPNS0_11GroupFilterES6_PNS0_13MaterialTableEPNS0_10ContactMgrE
0x00000071012b27bc,O,000544,_ZN4ksys4phys10SystemData14loadLayerTableEPN4sead4HeapEPNS0_11GroupFilterENS0_16ContactLayerTypeE
0x00000071012b29dc,O,000316,_ZN4ksys4phys10SystemData22loadCharacterCtrlTableEPN4sead4HeapE
0x00000071012b2b18,O,000292,_ZN4ksys4phys10SystemData22loadRagdollCtrlKeyListEPN4sead4HeapE

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

View File

@ -38,8 +38,8 @@ target_sources(uking PRIVATE
System/physConstraint.h
System/physContactInfoParam.cpp
System/physContactInfoParam.h
System/physContactInfoTable.cpp
System/physContactInfoTable.h
System/physContactMgr.cpp
System/physContactMgr.h
System/physDefines.cpp
System/physDefines.h
System/physEntityGroupFilter.cpp

View File

@ -33,7 +33,8 @@ void RigidBody::setMotionFlag(MotionFlag flag) {
if (mFlags.isOff(Flag1::_20) && mFlags.isOff(Flag1::_2)) {
mFlags.set(Flag1::_2);
MemSystem::instance()->_160->sub_7100FA6C8C(mFlags.isOn(Flag1::MassScaling), this);
MemSystem::instance()->getRigidBodyRequestMgr()->sub_7100FA6C8C(
mFlags.isOn(Flag1::MassScaling), this);
}
}

View File

@ -1 +0,0 @@
#include "KingSystem/Physics/System/physContactInfoTable.h"

View File

@ -1,23 +0,0 @@
#pragma once
#include <agl/Utils/aglResParameter.h>
#include "KingSystem/Physics/System/physDefines.h"
namespace sead {
class Heap;
}
namespace ksys::phys {
// FIXME
class ContactInfoTable {
public:
ContactInfoTable();
virtual ~ContactInfoTable();
void init(sead::Heap* heap);
void load(sead::Heap* heap, agl::utl::ResParameterArchive archive, ContactLayerType type);
};
} // namespace ksys::phys

View File

@ -0,0 +1,91 @@
#include "KingSystem/Physics/System/physContactMgr.h"
#include "KingSystem/Physics/System/physEntityGroupFilter.h"
#include "KingSystem/Physics/System/physGroupFilter.h"
#include "KingSystem/Physics/System/physMemSystem.h"
namespace ksys::phys {
ContactMgr::ContactMgr() {
// FIXME: figure out what these offsets are
mList1.initOffset(0x38);
mList2.initOffset(0x78);
mList3.initOffset(0x40);
mList0.initOffset(0x10);
mList4.initOffset(0x48);
mList5.initOffset(0x48);
}
void ContactMgr::loadContactInfoTable(sead::Heap* heap, agl::utl::ResParameterArchive archive,
ContactLayerType type) {
auto& table = mContactInfoTables[int(type)];
table.param_io.addList(&table.contact_info_table_plist, "ContactInfoTable");
const auto root = archive.getRootList();
const auto num_receivers = root.getResParameterObj(0).getNum();
if (num_receivers != 0)
table.receivers.allocBufferAssert(num_receivers, heap);
doLoadContactInfoTable(archive, type, false);
}
void ContactMgr::doLoadContactInfoTable(agl::utl::ResParameterArchive archive,
ContactLayerType type, bool skip_params) {
auto& table = mContactInfoTables[int(type)];
table.contact_info_table_plist.clearObj();
const auto root = archive.getRootList();
const auto names = root.getResParameterObj(0);
const auto* filter = MemSystem::instance()->getGroupFilter(type);
const auto layer_base = static_cast<int>(getContactLayerBase(type));
for (int i = 0; i < table.receivers.size(); ++i) {
auto& receiver = table.receivers[i];
auto* receiver_name = names.getParameterData<const char>(i);
receiver.name = receiver_name;
table.contact_info_table_plist.addObj(&receiver, receiver_name);
receiver.num_layers = filter->getNumLayers();
if (!skip_params) {
for (int idx = 0; idx < filter->getNumLayers(); ++idx) {
const char* layer_name = contactLayerToText(layer_base + idx);
receiver.layer_values[idx].init(0, layer_name, layer_name, &receiver);
}
}
}
table.param_io.applyResParameterArchive(archive);
}
bool ContactMgr::getSensorLayerMask(ReceiverMask* mask,
const sead::SafeString& receiver_type) const {
const auto& receivers = mContactInfoTables[int(ContactLayerType::Sensor)].receivers;
for (int i = 0; i < receivers.size(); ++i) {
const auto& receiver = receivers[i];
if (receiver_type == receiver.name) {
receiverMaskSetSensorLayerMask(mask, receiver.layer_mask);
return true;
}
}
return false;
}
void ContactInfoTable::Receiver::postRead_() {
layer_mask = 0;
layer_mask2 = 0;
for (int i = 0; i < num_layers; ++i) {
const auto value = layer_values[i].ref();
if (value & 1)
layer_mask |= 1 << i;
if (value & 2)
layer_mask2 |= 1 << i;
}
}
} // namespace ksys::phys

View File

@ -0,0 +1,75 @@
#pragma once
#include <agl/Utils/aglParameter.h>
#include <agl/Utils/aglParameterIO.h>
#include <agl/Utils/aglParameterList.h>
#include <agl/Utils/aglParameterObj.h>
#include <agl/Utils/aglResParameter.h>
#include <container/seadBuffer.h>
#include <container/seadOffsetList.h>
#include <container/seadSafeArray.h>
#include <hostio/seadHostIONode.h>
#include <prim/seadSafeString.h>
#include <thread/seadAtomic.h>
#include <thread/seadMutex.h>
#include "KingSystem/Physics/System/physDefines.h"
namespace sead {
class Heap;
}
namespace ksys::phys {
struct ContactInfoTable {
struct Receiver : agl::utl::ParameterObj {
const char* name = nullptr;
// TODO: figure out what these masks are
u32 layer_mask = 0;
u32 layer_mask2 = 0;
int num_layers = 0;
sead::SafeArray<agl::utl::Parameter<int>, MaxNumLayersPerType> layer_values;
protected:
void postRead_() override;
};
agl::utl::IParameterIO param_io;
agl::utl::ParameterList contact_info_table_plist;
sead::Buffer<Receiver> receivers;
};
class ContactMgr : public sead::hostio::Node {
public:
ContactMgr();
virtual ~ContactMgr();
void init(sead::Heap* heap);
void loadContactInfoTable(sead::Heap* heap, agl::utl::ResParameterArchive archive,
ContactLayerType type);
bool getSensorLayerMask(ReceiverMask* mask, const sead::SafeString& receiver_type) const;
private:
void doLoadContactInfoTable(agl::utl::ResParameterArchive archive, ContactLayerType type,
bool skip_params);
// FIXME: type, name
sead::Buffer<void*> mBuffer;
sead::OffsetList<void*> mList0;
int mList0Size = 0;
sead::Atomic<int> _34 = 0;
sead::OffsetList<void*> mList1;
sead::OffsetList<void*> mList2;
sead::OffsetList<void*> mList3;
sead::OffsetList<void*> mList4;
sead::OffsetList<void*> mList5;
sead::Mutex mMutex1;
sead::Mutex mMutex2;
sead::Mutex mMutex3;
sead::Mutex mMutex4;
sead::Mutex mMutex5;
sead::SafeArray<ContactInfoTable, 2> mContactInfoTables{};
};
} // namespace ksys::phys

View File

@ -1,7 +1,9 @@
#pragma once
#include <basis/seadTypes.h>
#include <prim/seadEnum.h>
#include <prim/seadSafeString.h>
#include "KingSystem/Utils/BitField.h"
namespace ksys::phys {
@ -69,6 +71,8 @@ SensorReserve20,\
SensorCustomReceiver,\
SensorEnd)
constexpr int MaxNumLayersPerType = 32;
SEAD_ENUM(Material,
Undefined,\
Soil,\
@ -164,6 +168,21 @@ enum class MotionType {
Unknown = 3,
};
union ReceiverMask {
constexpr ReceiverMask() : raw(0) { unk_flag = true; }
constexpr explicit ReceiverMask(u32 raw_) : raw(raw_) {}
constexpr ReceiverMask& operator=(const ReceiverMask& m) {
raw = m.raw;
return *this;
}
u32 raw;
// FIXME: is this a sensor layer mask?
util::BitField<0, 21, u32> layer_mask;
// FIXME: is sensor layer? is layer mask?
util::BitField<31, 1, u32> unk_flag;
};
ContactLayerType getContactLayerType(ContactLayer layer);
u32 makeContactLayerMask(ContactLayer layer);
u32 getContactLayerBase(ContactLayerType type);

View File

@ -7,6 +7,8 @@
#include <Havok/Physics2012/Collide/Shape/hkpShapeContainer.h>
#include <Havok/Physics2012/Dynamics/World/hkpWorldObject.h>
#include <heap/seadHeap.h>
#include "KingSystem/Physics/System/physContactMgr.h"
#include "KingSystem/Physics/System/physMemSystem.h"
#include "KingSystem/Utils/BitField.h"
#include "KingSystem/Utils/HeapUtil.h"
@ -51,6 +53,21 @@ static_assert(sizeof(EntityCollisionFilterInfo) == sizeof(u32));
} // namespace
void receiverMaskEnableLayer(ReceiverMask* mask, ContactLayer layer) {
mask->raw |= 1 << getContactLayerBaseRelativeValue(layer);
}
bool receiverMaskGetSensorLayerMaskForType(ReceiverMask* mask,
const sead::SafeString& receiver_type) {
return MemSystem::instance()->getContactMgr()->getSensorLayerMask(mask, receiver_type);
}
void receiverMaskSetSensorLayerMask(ReceiverMask* mask, u32 layer_mask) {
*mask = {};
mask->layer_mask = layer_mask;
mask->unk_flag = true;
}
EntityGroupFilter* EntityGroupFilter::make(ContactLayer::ValueType first,
ContactLayer::ValueType last, sead::Heap* heap) {
auto* filter = util::alloc<EntityGroupFilter>(heap, first, last);

View File

@ -2,6 +2,7 @@
#include <container/seadSafeArray.h>
#include <prim/seadBitUtil.h>
#include <prim/seadSafeString.h>
#include "KingSystem/Physics/System/physDefines.h"
#include "KingSystem/Physics/System/physGroupFilter.h"
@ -64,6 +65,11 @@ private:
sead::SafeArray<u32, ContactLayer::size()> mMasks;
};
void receiverMaskEnableLayer(ReceiverMask* mask, ContactLayer layer);
bool receiverMaskGetSensorLayerMaskForType(ReceiverMask* mask,
const sead::SafeString& receiver_type);
void receiverMaskSetSensorLayerMask(ReceiverMask* mask, u32 layer_mask);
u32 orEntityGroundHitMask(u32 mask, GroundHit type);
u32 orEntityGroundHitMask(u32 mask, const sead::SafeString& type);

View File

@ -60,6 +60,7 @@ public:
ContactLayer::ValueType getLayerFirst() const { return mLayerFirst; }
ContactLayer::ValueType getLayerLast() const { return mLayerLast; }
int getNumLayers() const { return getLayerLast() - getLayerFirst() + 1; }
ContactLayerType getLayerType() const { return mLayerType; }
void initFilter(sead::Heap* heap);

View File

@ -2,23 +2,38 @@
#include <basis/seadTypes.h>
#include <heap/seadDisposer.h>
#include "KingSystem/Physics/System/physDefines.h"
#include "KingSystem/Utils/Types.h"
namespace ksys::phys {
class ContactMgr;
class GroupFilter;
class RigidBody;
class SystemGroupHandler;
// FIXME: obviously incomplete. Also this should be moved to its own header
struct RigidBodyRequestMgr {
void sub_7100FA6C8C(bool, RigidBody*);
};
class MemSystem {
SEAD_SINGLETON_DISPOSER(MemSystem)
public:
struct Struct160 {
void sub_7100FA6C8C(bool, RigidBody*);
};
GroupFilter* getGroupFilter(ContactLayerType type) const;
ContactMgr* getContactMgr() const { return mContactMgr; }
RigidBodyRequestMgr* getRigidBodyRequestMgr() const { return mRigidBodyRequestMgr; }
void removeSystemGroupHandler(SystemGroupHandler* handler);
u8 _20[0x140];
Struct160* _160;
private:
u8 _20[0x148 - 0x20];
ContactMgr* mContactMgr;
void* _150;
void* _158;
RigidBodyRequestMgr* mRigidBodyRequestMgr;
u8 _168[0x480 - 0x168];
};
KSYS_CHECK_SIZE_NX150(MemSystem, 0x480);
} // namespace ksys::phys

View File

@ -1,5 +1,5 @@
#include "KingSystem/Physics/System/physSystemData.h"
#include "KingSystem/Physics/System/physContactInfoTable.h"
#include "KingSystem/Physics/System/physContactMgr.h"
#include "KingSystem/Physics/System/physGroupFilter.h"
#include "KingSystem/Physics/System/physMaterialTable.h"
#include "KingSystem/Physics/System/physRagdollControllerKeyList.h"
@ -39,7 +39,7 @@ SystemData::~SystemData() {
void SystemData::load(sead::Heap* heap, GroupFilter* entity_group_filter,
GroupFilter* sensor_group_filter, MaterialTable* material_table,
ContactInfoTable* contact_info_table) {
ContactMgr* contact_info_table) {
loadLayerTable(heap, entity_group_filter, ContactLayerType::Entity);
loadLayerTable(heap, sensor_group_filter, ContactLayerType::Sensor);
loadMaterialTable(heap, material_table);
@ -90,11 +90,10 @@ void SystemData::loadSubMaterialTable(sead::Heap* heap, MaterialTable* table) {
table->loadSubMaterialTable(heap, res);
}
void SystemData::loadContactInfoTable(sead::Heap* heap, ContactInfoTable* table,
ContactLayerType type) {
void SystemData::loadContactInfoTable(sead::Heap* heap, ContactMgr* table, ContactLayerType type) {
mContactInfoTableHandles[int(type)] = new (heap) res::Handle;
const auto res = loadContactInfoTableRes(type);
table->load(heap, res, type);
table->loadContactInfoTable(heap, res, type);
}
void SystemData::loadCharacterCtrlTable(sead::Heap* heap) {

View File

@ -16,15 +16,13 @@ class Handle;
namespace ksys::phys {
class ContactInfoTable;
class ContactMgr;
class GroupFilter;
class MaterialTable;
class RagdollControllerKeyList;
constexpr int NumLayers = 32;
struct LayerTable : agl::utl::IParameterObj {
sead::SafeArray<agl::utl::Parameter<int>, NumLayers> layer_values;
sead::SafeArray<agl::utl::Parameter<int>, MaxNumLayersPerType> layer_values;
GroupFilter* filter;
ContactLayer layer;
int num_layers;
@ -64,15 +62,15 @@ public:
virtual ~SystemData();
void load(sead::Heap* heap, GroupFilter* entity_group_filter, GroupFilter* sensor_group_filter,
MaterialTable* material_table, ContactInfoTable* contact_info_table);
MaterialTable* material_table, ContactMgr* contact_info_table);
private:
using LayerMatrix = Tables<LayerTable, NumLayers>;
using LayerMatrix = Tables<LayerTable, MaxNumLayersPerType>;
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 loadContactInfoTable(sead::Heap* heap, ContactMgr* table, ContactLayerType type);
void loadCharacterCtrlTable(sead::Heap* heap);
void loadRagdollCtrlKeyList(sead::Heap* heap);