ksys/phys: Add SensorContactListener

This commit is contained in:
Léo Lam 2022-03-10 21:23:35 +01:00
parent 0e717ed15d
commit ad6c11f468
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
4 changed files with 135 additions and 8 deletions

View File

@ -95450,14 +95450,14 @@ Address,Quality,Size,Name
0x00000071012b1940,U,000004,
0x00000071012b1944,U,000004,
0x00000071012b1948,U,000008,
0x00000071012b1950,U,000108,phys::makeSensorContactListener
0x00000071012b19bc,U,000004,j_ksys::phys::ContactListener::dtor_0
0x00000071012b19c0,U,000036,
0x00000071012b19e4,U,000424,
0x00000071012b1b8c,U,000136,
0x00000071012b1c14,U,000532,
0x00000071012b1e28,U,000204,
0x00000071012b1ef4,U,000092,
0x00000071012b1950,O,000108,_ZN4ksys4phys21SensorContactListener4makeEPNS0_10ContactMgrEPN4sead4HeapE
0x00000071012b19bc,O,000004,_ZN4ksys4phys21SensorContactListenerD1Ev
0x00000071012b19c0,O,000036,_ZN4ksys4phys21SensorContactListenerD0Ev
0x00000071012b19e4,O,000424,_ZN4ksys4phys21SensorContactListener20handleCollisionAddedERK17hkpCollisionEventPNS0_9RigidBodyES6_
0x00000071012b1b8c,O,000136,_ZN4ksys4phys21SensorContactListener28manifoldContactPointCallbackERK20hkpContactPointEventPNS0_9RigidBodyES6_
0x00000071012b1c14,O,000532,_ZN4ksys4phys21SensorContactListener27regularContactPointCallbackERK20hkpContactPointEventPNS0_9RigidBodyES6_PN4sead9SafeArrayIjLi2EEE
0x00000071012b1e28,O,000204,_ZNK4ksys4phys21SensorContactListener27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x00000071012b1ef4,O,000092,_ZNK4ksys4phys21SensorContactListener18getRuntimeTypeInfoEv
0x00000071012b1f50,m,000484,_ZN4ksys4phys10SystemDataC1Ev
0x00000071012b2134,O,000864,_ZN4ksys4phys10SystemDataD1Ev
0x00000071012b2494,O,000404,_ZN4sead9SafeArrayIN4ksys4phys10SystemData6TablesINS2_10LayerTableELi32EEELi2EED2Ev

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

View File

@ -137,6 +137,8 @@ target_sources(uking PRIVATE
System/physParamSet.h
System/physQueryContactPointInfo.cpp
System/physQueryContactPointInfo.h
System/physSensorContactListener.cpp
System/physSensorContactListener.h
System/physSensorGroupFilter.cpp
System/physSensorGroupFilter.h
System/physSystem.cpp

View File

@ -0,0 +1,99 @@
#include "KingSystem/Physics/System/physSensorContactListener.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
#include "KingSystem/Physics/System/physCollisionInfo.h"
#include "KingSystem/Physics/System/physContactLayerCollisionInfo.h"
#include "KingSystem/Physics/System/physContactMgr.h"
#include "KingSystem/Physics/System/physSystem.h"
#include "KingSystem/Physics/physConversions.h"
namespace ksys::phys {
SensorContactListener* SensorContactListener::make(ContactMgr* mgr, sead::Heap* heap) {
auto* listener = new (heap) SensorContactListener(mgr);
listener->init(heap);
return listener;
}
SensorContactListener::SensorContactListener(ContactMgr* mgr)
: ContactListener(mgr, ContactLayerType::Sensor, LastSensor - FirstSensor + 1) {}
SensorContactListener::~SensorContactListener() = default;
void SensorContactListener::handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a,
RigidBody* body_b) {
registerForEndOfStepContactPointCallbacks(event);
const auto layer_a = body_a->getContactLayer();
const auto layer_b = body_b->getContactLayer();
const auto rlayer_a = int(layer_a - mLayerBase);
const auto rlayer_b = int(layer_b - mLayerBase);
if (body_a->getContactMask().isOnBit(rlayer_b) || body_b->getContactMask().isOnBit(rlayer_a))
return;
if (body_a->getCollisionInfo() && body_a->getCollisionInfo()->isLayerEnabled(layer_b))
mMgr->registerCollision(body_a->getCollisionInfo(), body_a, body_b);
if (body_b->getCollisionInfo() && body_b->getCollisionInfo()->isLayerEnabled(layer_a))
mMgr->registerCollision(body_b->getCollisionInfo(), body_b, body_a);
if (areContactsTrackedForLayerPair(rlayer_a, rlayer_b)) {
auto* layer_col_info = getContactLayerCollisionInfo(rlayer_a, rlayer_b);
if (body_a->isFlag8Set() && body_b->isFlag8Set()) {
const auto layer_a_ = int(layer_a);
const auto tracked_layer = layer_col_info->getLayer();
const bool body_a_first = layer_a_ == tracked_layer;
auto* body1 = body_a_first ? body_a : body_b;
auto* body2 = body_a_first ? body_b : body_a;
mMgr->registerCollision(layer_col_info, body1, body2);
}
}
}
bool SensorContactListener::manifoldContactPointCallback(const hkpContactPointEvent& event,
RigidBody* body_a, RigidBody* body_b) {
[[maybe_unused]] auto* filter = System::instance()->getGroupFilter(mLayerType);
const auto layer_a = body_a->getContactLayer();
const auto layer_b = body_b->getContactLayer();
return contactPointCallbackImpl(0, 0, body_a, body_b, layer_a, layer_b, event);
}
bool SensorContactListener::regularContactPointCallback(
const hkpContactPointEvent& event, RigidBody* body_a, RigidBody* body_b,
sead::SafeArray<u32, 2>* out_material_masks) {
[[maybe_unused]] auto* filter = System::instance()->getGroupFilter(mLayerType);
RigidBody::CollisionMasks masks_a, masks_b;
sead::Vector3f contact_point_pos;
storeToVec3(&contact_point_pos, event.m_contactPoint->getPosition());
body_a->getCollisionMasks(&masks_a, event.getShapeKeys(0), contact_point_pos);
body_b->getCollisionMasks(&masks_b, event.getShapeKeys(1), contact_point_pos);
const auto layer_a = body_a->getContactLayer();
const auto layer_b = body_b->getContactLayer();
const auto rlayer_a = layer_a - int(mLayerBase);
const auto rlayer_b = layer_b - int(mLayerBase);
const auto& entries = mTrackedContactPointLayers[rlayer_a][rlayer_b];
const bool result = contactPointCallbackImpl(0, 0, body_a, body_b, layer_a, layer_b, event);
if (body_a->getIgnoredLayers().isOnBit(rlayer_b) &&
body_b->getIgnoredLayers().isOnBit(rlayer_a)) {
const auto notify_result =
notifyContactPointInfo(body_a, body_b, layer_a, layer_b, masks_a, masks_b, event, true);
for (int idx = 0; idx < entries.size(); ++idx) {
notifyLayerContactPointInfo(*entries[idx], notify_result, body_a, body_b, layer_a,
layer_b, masks_a.material_mask, masks_b.material_mask,
event);
}
}
return result;
}
} // namespace ksys::phys

View File

@ -0,0 +1,26 @@
#pragma once
#include "KingSystem/Physics/System/physContactListener.h"
namespace ksys::phys {
class SensorContactListener : public ContactListener {
SEAD_RTTI_OVERRIDE(SensorContactListener, ContactListener)
public:
static SensorContactListener* make(ContactMgr* mgr, sead::Heap* heap);
~SensorContactListener() override;
protected:
explicit SensorContactListener(ContactMgr* mgr);
void handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a,
RigidBody* body_b) override;
bool manifoldContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a,
RigidBody* body_b) override;
bool regularContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a,
RigidBody* body_b,
sead::SafeArray<u32, 2>* out_material_masks) override;
};
} // namespace ksys::phys