ksys/phys: Start implementing SensorGroupFilter

This commit is contained in:
Léo Lam 2022-02-28 19:14:39 +01:00
parent c32557b793
commit e219eccf0d
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
7 changed files with 257 additions and 38 deletions

View File

@ -84117,18 +84117,18 @@ Address,Quality,Size,Name
0x0000007100fc77c8,U,000044,phys::SomeClass::ctor_0
0x0000007100fc77f4,U,000260,phys::SomeClass::someCalc
0x0000007100fc78f8,U,000056,phys::SomeClass::x
0x0000007100fc7930,U,000140,makeSensorLayerTable
0x0000007100fc79bc,U,000004,phys::SensorGroupFilter::dtor
0x0000007100fc79c0,U,000008,
0x0000007100fc79c8,U,000008,
0x0000007100fc79d0,U,000008,
0x0000007100fc79d8,U,000008,
0x0000007100fc79e0,U,000088,phys::SensorGroupFilter::dtorDelete
0x0000007100fc7a38,U,000096,
0x0000007100fc7a98,U,000096,
0x0000007100fc7af8,U,000096,
0x0000007100fc7b58,U,000096,
0x0000007100fc7bb8,U,000004,phys::SensorGroupFilter::m13_n
0x0000007100fc7930,O,000140,_ZN4ksys4phys17SensorGroupFilter4makeENS0_12ContactLayer9ValueTypeEPN4sead4HeapE
0x0000007100fc79bc,O,000004,_ZN4ksys4phys17SensorGroupFilterD1Ev
0x0000007100fc79c0,O,000008,_ZThn16_N4ksys4phys17SensorGroupFilterD1Ev
0x0000007100fc79c8,O,000008,_ZThn24_N4ksys4phys17SensorGroupFilterD1Ev
0x0000007100fc79d0,O,000008,_ZThn32_N4ksys4phys17SensorGroupFilterD1Ev
0x0000007100fc79d8,O,000008,_ZThn40_N4ksys4phys17SensorGroupFilterD1Ev
0x0000007100fc79e0,O,000088,_ZN4ksys4phys17SensorGroupFilterD0Ev
0x0000007100fc7a38,O,000096,_ZThn16_N4ksys4phys17SensorGroupFilterD0Ev
0x0000007100fc7a98,O,000096,_ZThn24_N4ksys4phys17SensorGroupFilterD0Ev
0x0000007100fc7af8,O,000096,_ZThn32_N4ksys4phys17SensorGroupFilterD0Ev
0x0000007100fc7b58,O,000096,_ZThn40_N4ksys4phys17SensorGroupFilterD0Ev
0x0000007100fc7bb8,O,000004,_ZN4ksys4phys17SensorGroupFilter7doInit_EPN4sead4HeapE
0x0000007100fc7bbc,U,000432,phys::SensorGroupFilter::x
0x0000007100fc7d6c,U,000032,phys::SensorGroupFilter::isCollisionEnabled
0x0000007100fc7d8c,U,000036,
@ -84140,27 +84140,27 @@ Address,Quality,Size,Name
0x0000007100fc812c,U,000208,
0x0000007100fc81fc,U,000188,phys::SensorGroupFilter::isCollisionEnabled4
0x0000007100fc82b8,U,000188,
0x0000007100fc8374,U,000192,phys::SensorGroupFilter::m11
0x0000007100fc8434,U,000016,phys::SensorGroupFilter::m12
0x0000007100fc8374,O,000192,_ZN4ksys4phys17SensorGroupFilter30doInitSystemGroupHandlerLists_EPN4sead4HeapE
0x0000007100fc8434,O,000016,_ZN4ksys4phys17SensorGroupFilter16getFreeListIndexEPKNS0_18SystemGroupHandlerE
0x0000007100fc8444,O,000072,_ZN4ksys4phys26sensorReceiverMaskSetLayerENS0_12ContactLayerEj
0x0000007100fc848c,O,000060,_ZN4ksys4phys27sensorReceiverMaskSetLayer2EbNS0_12ContactLayerEj
0x0000007100fc84c8,U,000056,SensorGroupFilter::Handler::m5
0x0000007100fc8500,U,000020,SensorGroupFilter::Handler::m6
0x0000007100fc8514,U,000020,SensorGroupFilter::Handler::m8
0x0000007100fc8528,U,000004,j__ZdlPv_1010
0x0000007100fc852c,U,000204,phys::SensorGroupFilter::rtti1
0x0000007100fc85f8,U,000092,phys::SensorGroupFilter::rtti2
0x0000007100fc8654,U,000008,phys::GroupFilter::m2
0x0000007100fc865c,U,000048,phys::SensorGroupFilter::m3
0x0000007100fc868c,U,000024,phys::SensorGroupFilter::m4
0x0000007100fc86a4,U,000008,phys::SensorGroupFilter::m5
0x0000007100fc86ac,U,000008,phys::SensorGroupFilter::m6
0x0000007100fc86b4,U,000032,phys::SensorGroupFilter::m7
0x0000007100fc86d4,U,000032,phys::SensorGroupFilter::m8
0x0000007100fc84c8,O,000056,_ZN4ksys4phys24SensorSystemGroupHandler23makeCollisionFilterInfoEjNS0_12ContactLayerENS0_9GroundHitE
0x0000007100fc8500,O,000020,_ZN4ksys4phys24SensorSystemGroupHandler22makeQueryCollisionMaskEjNS0_9GroundHitEb
0x0000007100fc8514,O,000020,_ZN4ksys4phys24SensorSystemGroupHandler2m8Ev
0x0000007100fc8528,O,000004,_ZN4ksys4phys24SensorSystemGroupHandlerD0Ev
0x0000007100fc852c,O,000204,_ZNK4ksys4phys17SensorGroupFilter27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007100fc85f8,O,000092,_ZNK4ksys4phys17SensorGroupFilter18getRuntimeTypeInfoEv
0x0000007100fc8654,O,000008,_ZN4ksys4phys11GroupFilter2m2ENS0_12ContactLayerES2_
0x0000007100fc865c,O,000048,_ZN4ksys4phys17SensorGroupFilter23makeCollisionFilterInfoENS0_12ContactLayerENS0_9GroundHitE
0x0000007100fc868c,O,000024,_ZN4ksys4phys17SensorGroupFilter27getCollisionFilterInfoLayerEj
0x0000007100fc86a4,O,000008,_ZN4ksys4phys17SensorGroupFilter22makeQueryCollisionMaskEjNS0_9GroundHitEb
0x0000007100fc86ac,O,000008,_ZN4ksys4phys17SensorGroupFilter30getQueryCollisionMaskGroundHitEj
0x0000007100fc86b4,O,000032,_ZN4ksys4phys17SensorGroupFilter39getCollisionFilterInfoLayerAndGroundHitEjPNS0_12ContactLayerEPNS0_9GroundHitE
0x0000007100fc86d4,O,000032,_ZN4ksys4phys17SensorGroupFilter31getCollisionFilterInfoLayerTextEj
0x0000007100fc86f4,O,000004,_ZN4ksys4phys11GroupFilter18setLayerCustomMaskENS0_12ContactLayerEj
0x0000007100fc86f8,U,000008,phys::SensorGroupFilter::m10
0x0000007100fc8700,U,000008,phys::SensorGroupFilter::m14
0x0000007100fc8708,U,000036,phys::SensorGroupFilter::m15
0x0000007100fc86f8,O,000008,_ZN4ksys4phys17SensorGroupFilter37getCollisionFilterInfoGroupHandlerIdxEj
0x0000007100fc8700,O,000008,_ZN4ksys4phys17SensorGroupFilter23makeCollisionFilterInfoENS0_12ContactLayerENS0_9GroundHitEjj
0x0000007100fc8708,O,000036,_ZN4ksys4phys17SensorGroupFilter34setSensorLayerCollisionEnabledMaskENS0_12ContactLayerEj
0x0000007100fc872c,U,000172,
0x0000007100fc87d8,U,000004,nullsub_4250
0x0000007100fc87dc,U,000004,j__ZdlPv_1011

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

View File

@ -794,7 +794,7 @@ void RigidBody::setSensorCustomReceiver(const ReceiverMask& mask,
info.raw = sensorReceiverMaskSetLayer(ContactLayer::SensorCustomReceiver, info.raw);
if (handler) {
info.custom_receiver_data.group_handler_index.SetUnsafe(handler->getIndex());
info.group_handler_index.SetUnsafe(handler->getIndex());
}
setCollisionFilterInfo(info.raw);
}

View File

@ -351,7 +351,7 @@ RigidBodyT* RigidBodyFromShape::make(const Shape& shape, RigidBodyInstanceParam*
const u32 idx = group_handler ? group_handler->getIndex() : 0;
collision_filter_info = [&] {
ReceiverMask info{collision_filter_info};
info.custom_receiver_data.group_handler_index.SetUnsafe(idx);
info.group_handler_index.SetUnsafe(idx);
return info.raw;
}();
}

View File

@ -82,7 +82,7 @@ public:
GroundHit groundhit = GroundHit::HitAll;
u32 groundhit_mask = 0;
u32 contact_mask = 0;
ReceiverMask receiver_mask;
ReceiverMask receiver_mask{ReceiverMask::CustomReceiverTag{}};
bool ignore_normal_for_impulse = false;
bool no_hit_ground = false;
bool no_hit_water = false;

View File

@ -1,8 +1,78 @@
#include "KingSystem/Physics/System/physSensorGroupFilter.h"
#include <basis/seadRawPrint.h>
#include "KingSystem/Utils/HeapUtil.h"
namespace ksys::phys {
constexpr int NumSensorHandlersInList0 = 0x10;
constexpr int NumSensorHandlers = 0x400;
SensorGroupFilter* SensorGroupFilter::make(ContactLayer::ValueType last, sead::Heap* heap) {
auto* filter = util::alloc<SensorGroupFilter>(heap, FirstSensor, last);
filter->initFilter(heap);
return filter;
}
SensorGroupFilter::SensorGroupFilter(ContactLayer::ValueType first, ContactLayer::ValueType last)
: GroupFilter(ContactLayerType::Sensor, first, last) {}
SensorGroupFilter::~SensorGroupFilter() = default;
void SensorGroupFilter::doInit_(sead::Heap* heap) {}
// TODO
hkBool SensorGroupFilter::isCollisionEnabled(const hkpCollidable& a, const hkpCollidable& b) const {
return hkpGroupFilter::isCollisionEnabled(a, b);
}
// TODO
hkBool SensorGroupFilter::isCollisionEnabled(const hkpCollisionInput& input,
const hkpCdBody& collectionBodyA,
const hkpCdBody& collectionBodyB,
const hkpShapeContainer& containerShapeA,
const hkpShapeContainer& containerShapeB,
hkpShapeKey keyA, hkpShapeKey keyB) const {
return hkpGroupFilter::isCollisionEnabled(input, collectionBodyA, collectionBodyB,
containerShapeA, containerShapeB, keyA, keyB);
}
// TODO
hkBool SensorGroupFilter::isCollisionEnabled(const hkpCollisionInput& input, const hkpCdBody& a,
const hkpCdBody& b,
const hkpShapeContainer& bContainer,
hkpShapeKey bKey) const {
return hkpGroupFilter::isCollisionEnabled(input, a, b, bContainer, bKey);
}
// TODO
hkBool SensorGroupFilter::isCollisionEnabled(const hkpShapeRayCastInput& aInput,
const hkpShapeContainer& bContainer,
hkpShapeKey bKey) const {
return hkpGroupFilter::isCollisionEnabled(aInput, bContainer, bKey);
}
// TODO
hkBool SensorGroupFilter::isCollisionEnabled(const hkpWorldRayCastInput& inputA,
const hkpCollidable& collidableB) const {
return hkpGroupFilter::isCollisionEnabled(inputA, collidableB);
}
void SensorGroupFilter::doInitSystemGroupHandlerLists_(sead::Heap* heap) {
for (auto& list : mFreeLists)
list.initOffset(SystemGroupHandler::getFreeListNodeOffset());
mUsedList.initOffset(SystemGroupHandler::getUsedListNodeOffset());
for (int i = 1; i < NumSensorHandlers; ++i) {
auto& list = mFreeLists[i < NumSensorHandlersInList0];
list.pushBack(new (heap) SensorSystemGroupHandler(i));
}
}
int SensorGroupFilter::getFreeListIndex(const SystemGroupHandler* handler) {
return handler->getIndex() < NumSensorHandlersInList0;
}
u32 sensorReceiverMaskSetLayer(ContactLayer layer, u32 mask) {
SEAD_ASSERT(getContactLayerType(layer) == ContactLayerType::Sensor);

View File

@ -5,11 +5,57 @@
namespace ksys::phys {
// FIXME
class SensorSystemGroupHandler : public SystemGroupHandler {
public:
explicit SensorSystemGroupHandler(int i) : SystemGroupHandler(i, ContactLayerType::Sensor) {}
u32 makeCollisionFilterInfo(u32 info, ContactLayer layer, GroundHit ground_hit) override;
u32 makeQueryCollisionMask(u32 layer_mask, GroundHit ground_hit, bool unk) override;
bool m8() override;
};
class SensorGroupFilter : public GroupFilter {
SEAD_RTTI_OVERRIDE(SensorGroupFilter, GroupFilter)
public:
static SensorGroupFilter* make(ContactLayer::ValueType last, sead::Heap* heap);
SensorGroupFilter(ContactLayer::ValueType first, ContactLayer::ValueType last);
~SensorGroupFilter() 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;
u32 makeCollisionFilterInfo(ContactLayer layer, GroundHit ground_hit) override;
ContactLayer getCollisionFilterInfoLayer(u32 info) override;
u32 makeQueryCollisionMask(u32 layer_mask, GroundHit ground_hit, bool unk) override;
GroundHit getQueryCollisionMaskGroundHit(u32 info) override;
void getCollisionFilterInfoLayerAndGroundHit(u32 info, ContactLayer* layer,
GroundHit* ground_hit) override;
const char* getCollisionFilterInfoLayerText(u32 info) override;
u32 getCollisionFilterInfoGroupHandlerIdx(u32 info) override;
virtual u32 makeCollisionFilterInfo(ContactLayer layer, GroundHit ground_hit, u32 unk5,
u32 unk10);
virtual void setSensorLayerCollisionEnabledMask(ContactLayer layer, u32 mask);
protected:
/// Checks whether two sensors are colliding.
hkBool testCollisionForSensors(u32 infoA, u32 infoB) const;
void doInitSystemGroupHandlerLists_(sead::Heap* heap) override;
int getFreeListIndex(const SystemGroupHandler* handler) override;
void doInit_(sead::Heap* heap) override;
};
/// Set the contact layer in a sensor receiver mask.
@ -25,4 +71,77 @@ u32 sensorReceiverMaskSetLayer(ContactLayer layer, u32 mask);
// TODO: rename once we figure out what this layer is used for
u32 sensorReceiverMaskSetLayer2(bool set, ContactLayer layer, u32 mask);
inline u32 SensorSystemGroupHandler::makeCollisionFilterInfo(u32 info, ContactLayer layer,
GroundHit ground_hit) {
const ReceiverMask current_info{info};
ReceiverMask result;
if (layer == ContactLayer::SensorCustomReceiver) {
result.is_custom_receiver = true;
result.group_handler_index.Init(getIndex());
result.custom_receiver_data.layer.Init(current_info.custom_receiver_data.layer);
} else {
result.is_custom_receiver = false;
result.group_handler_index.Init(getIndex());
result.data.layer.Init(layer - FirstSensor);
}
return result.raw;
}
inline u32 SensorSystemGroupHandler::makeQueryCollisionMask(u32 layer_mask, GroundHit ground_hit,
bool unk) {
SensorQueryCollisionMask mask;
mask.layer_mask = layer_mask;
mask.group_handler_index.Init(getIndex());
return mask.raw;
}
inline bool SensorSystemGroupHandler::m8() {
return getIndex() > 0 && getIndex() < 0x400;
}
inline u32 SensorGroupFilter::makeCollisionFilterInfo(ContactLayer layer, GroundHit ground_hit) {
return ReceiverMask::make(layer).raw;
}
inline ContactLayer SensorGroupFilter::getCollisionFilterInfoLayer(u32 info) {
return ReceiverMask(info).getLayer();
}
inline u32 SensorGroupFilter::makeQueryCollisionMask(u32 layer_mask, GroundHit ground_hit,
bool unk) {
SensorQueryCollisionMask mask;
mask.layer_mask = layer_mask;
return mask.raw;
}
inline GroundHit SensorGroupFilter::getQueryCollisionMaskGroundHit(u32 info) {
return GroundHit::HitAll;
}
inline void SensorGroupFilter::getCollisionFilterInfoLayerAndGroundHit(u32 info,
ContactLayer* layer,
GroundHit* ground_hit) {
ReceiverMask mask{info};
*layer = mask.getLayer();
*ground_hit = {};
}
inline const char* SensorGroupFilter::getCollisionFilterInfoLayerText(u32 info) {
return contactLayerToText(getCollisionFilterInfoLayer(info));
}
inline u32 SensorGroupFilter::getCollisionFilterInfoGroupHandlerIdx(u32 info) {
return ReceiverMask(info).group_handler_index;
}
inline u32 SensorGroupFilter::makeCollisionFilterInfo(ContactLayer layer, GroundHit ground_hit,
u32 unk5, u32 unk10) {
return 0;
}
inline void SensorGroupFilter::setSensorLayerCollisionEnabledMask(ContactLayer layer, u32 mask) {
m_collisionLookupTable[layer - mLayerFirst] = mask;
}
} // namespace ksys::phys

View File

@ -201,8 +201,14 @@ enum class WaterCollisionMode {
IgnoreWater = 1,
};
// TODO: rename to SensorCollisionFilterInfo.
union ReceiverMask {
struct CustomReceiverTag {};
union Data {
ContactLayer getLayer() const { return int(layer) + FirstSensor; }
/// ContactLayer minus FirstSensor.
util::BitField<0, 5, u32> layer;
// TODO: rename once we figure out what this layer is used for
util::BitField<5, 1, bool, u32> has_layer2;
@ -211,10 +217,10 @@ union ReceiverMask {
union CustomReceiverData {
util::BitField<0, 21, u32> layer;
util::BitField<21, 10, u32> group_handler_index;
};
constexpr ReceiverMask() : raw(0) { is_custom_receiver = true; }
constexpr ReceiverMask() : raw(0) {}
constexpr explicit ReceiverMask(CustomReceiverTag) : raw(0) { is_custom_receiver = true; }
constexpr explicit ReceiverMask(u32 raw_) : raw(raw_) {}
constexpr ReceiverMask(const ReceiverMask&) = default;
constexpr ReceiverMask& operator=(const ReceiverMask& m) {
@ -234,11 +240,17 @@ union ReceiverMask {
return mask;
}
ContactLayer getLayer() const {
return is_custom_receiver ? ContactLayer::SensorCustomReceiver : data.getLayer();
}
u32 raw;
Data data;
CustomReceiverData custom_receiver_data;
// FIXME: is this a sensor layer mask?
/// Sensor layer mask.
// TODO: add a constant for 21.
util::BitField<0, 21, u32> layer_mask;
util::BitField<21, 10, u32> group_handler_index;
util::BitField<31, 1, bool, u32> is_custom_receiver;
};
@ -319,7 +331,8 @@ union EntityCollisionFilterInfo {
};
static_assert(sizeof(EntityCollisionFilterInfo) == sizeof(u32));
/// Collision mask that is used for raycast-based queries.
/// Collision mask that is used for raycast-based queries against entities.
// TODO: rename to make it clear this is used for entities, not sensors
union RayCastCollisionMask {
constexpr explicit RayCastCollisionMask(u32 raw_ = 0) : raw(raw_) {}
constexpr RayCastCollisionMask(const RayCastCollisionMask&) = default;
@ -337,6 +350,23 @@ union RayCastCollisionMask {
u32 raw;
};
/// Collision mask that is used for raycast-based queries against sensors.
union SensorQueryCollisionMask {
constexpr explicit SensorQueryCollisionMask(u32 raw_ = 0) : raw(raw_) {}
constexpr SensorQueryCollisionMask(const SensorQueryCollisionMask&) = default;
constexpr SensorQueryCollisionMask& operator=(const SensorQueryCollisionMask& m) {
raw = m.raw;
return *this;
}
constexpr bool operator==(SensorQueryCollisionMask rhs) const { return raw == rhs.raw; }
constexpr bool operator!=(SensorQueryCollisionMask rhs) const { return raw != rhs.raw; }
// TODO: add a constant for 21.
util::BitField<0, 21, u32> layer_mask;
util::BitField<22, 10, u32> group_handler_index;
u32 raw;
};
ContactLayerType getContactLayerType(ContactLayer layer);
u32 makeContactLayerMask(ContactLayer layer);
u32 getContactLayerBase(ContactLayerType type);