mirror of https://github.com/zeldaret/botw.git
ksys/phys: Add SensorContactListener
This commit is contained in:
parent
0e717ed15d
commit
ad6c11f468
|
|
@ -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.
|
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue