mirror of https://github.com/zeldaret/botw.git
ksys/phys: Finish ContactListener
This commit is contained in:
parent
1518cc4960
commit
d839816081
|
@ -84307,18 +84307,18 @@ Address,Quality,Size,Name
|
||||||
0x0000007100fce54c,O,000048,_ZN4ksys4phys15ContactListener28getContactLayerCollisionInfoEjj
|
0x0000007100fce54c,O,000048,_ZN4ksys4phys15ContactListener28getContactLayerCollisionInfoEjj
|
||||||
0x0000007100fce57c,O,000308,_ZN4ksys4phys15ContactListener20contactPointCallbackERK20hkpContactPointEvent
|
0x0000007100fce57c,O,000308,_ZN4ksys4phys15ContactListener20contactPointCallbackERK20hkpContactPointEvent
|
||||||
0x0000007100fce6b0,O,000580,_ZN4ksys4phys15ContactListener28manifoldContactPointCallbackERK20hkpContactPointEventPNS0_9RigidBodyES6_
|
0x0000007100fce6b0,O,000580,_ZN4ksys4phys15ContactListener28manifoldContactPointCallbackERK20hkpContactPointEventPNS0_9RigidBodyES6_
|
||||||
0x0000007100fce8f4,U,000764,ksys::phys::ContactListener::m14
|
0x0000007100fce8f4,O,000764,_ZN4ksys4phys15ContactListener27regularContactPointCallbackERK20hkpContactPointEventPNS0_9RigidBodyES6_PN4sead9SafeArrayINS0_16MaterialMaskDataELi2EEE
|
||||||
0x0000007100fcebf0,U,001052,ksys::phys::ContactListener::x_2
|
0x0000007100fcebf0,O,001052,_ZN4ksys4phys15ContactListener22notifyContactPointInfoEPNS0_9RigidBodyES3_NS0_12ContactLayerES4_RKNS0_23RigidBodyCollisionMasksES7_RK20hkpContactPointEventb
|
||||||
0x0000007100fcf00c,U,000660,ksys::phys::ContactListener::x_3
|
0x0000007100fcf00c,M,000660,_ZN4ksys4phys15ContactListener27notifyLayerContactPointInfoERKNS1_24TrackedContactPointLayerEiPNS0_9RigidBodyES6_NS0_12ContactLayerES7_jjRK20hkpContactPointEvent
|
||||||
0x0000007100fcf2a0,O,000356,_ZN4ksys4phys15ContactListener31addLayerPairForContactPointInfoEPNS0_21LayerContactPointInfoENS0_12ContactLayerES4_b
|
0x0000007100fcf2a0,O,000356,_ZN4ksys4phys15ContactListener31addLayerPairForContactPointInfoEPNS0_21LayerContactPointInfoENS0_12ContactLayerES4_b
|
||||||
0x0000007100fcf404,O,000112,_ZN4ksys4phys15ContactListener35removeLayerPairsForContactPointInfoEPNS0_21LayerContactPointInfoE
|
0x0000007100fcf404,O,000112,_ZN4ksys4phys15ContactListener35removeLayerPairsForContactPointInfoEPNS0_21LayerContactPointInfoE
|
||||||
0x0000007100fcf474,m,000576,_ZN4ksys4phys15ContactListener34removeLayerPairForContactPointInfoEPNS0_21LayerContactPointInfoENS0_12ContactLayerES4_
|
0x0000007100fcf474,m,000576,_ZN4ksys4phys15ContactListener34removeLayerPairForContactPointInfoEPNS0_21LayerContactPointInfoENS0_12ContactLayerES4_
|
||||||
0x0000007100fcf6b4,O,000124,_ZN4ksys4phys15ContactListener14trackLayerPairENS0_12ContactLayerES2_
|
0x0000007100fcf6b4,O,000124,_ZN4ksys4phys15ContactListener14trackLayerPairENS0_12ContactLayerES2_
|
||||||
0x0000007100fcf730,O,000156,_ZN4ksys4phys15ContactListener17registerRigidBodyEPNS0_9RigidBodyE
|
0x0000007100fcf730,O,000156,_ZN4ksys4phys15ContactListener17registerRigidBodyEPNS0_9RigidBodyE
|
||||||
0x0000007100fcf7cc,O,000024,_ZN4ksys4phys15ContactListener36characterControlContactPointCallbackEjjPNS0_9RigidBodyES3_NS0_12ContactLayerES4_RK20hkpContactPointEvent
|
0x0000007100fcf7cc,O,000024,_ZN4ksys4phys15ContactListener24contactPointCallbackImplEjjPNS0_9RigidBodyES3_NS0_12ContactLayerES4_RK20hkpContactPointEvent
|
||||||
0x0000007100fcf7e4,O,000112,_ZNK4ksys4phys15ContactListener27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
0x0000007100fcf7e4,O,000112,_ZNK4ksys4phys15ContactListener27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||||
0x0000007100fcf854,O,000092,_ZNK4ksys4phys15ContactListener18getRuntimeTypeInfoEv
|
0x0000007100fcf854,O,000092,_ZNK4ksys4phys15ContactListener18getRuntimeTypeInfoEv
|
||||||
0x0000007100fcf8b0,O,000004,_ZN4ksys4phys15ContactListener3m11Ev
|
0x0000007100fcf8b0,O,000004,_ZN4ksys4phys15ContactListener3m11ERK20hkpContactPointEventRKNS0_23RigidBodyCollisionMasksES7_PNS0_9RigidBodyES9_
|
||||||
0x0000007100fcf8b4,O,000008,_ZN4ksys4phys15ContactListener3m15Ev
|
0x0000007100fcf8b4,O,000008,_ZN4ksys4phys15ContactListener3m15Ev
|
||||||
0x0000007100fcf8bc,O,000072,_ZN4ksys4phys21LayerContactPointInfo4makeEPN4sead4HeapEiiRKNS2_14SafeStringBaseIcEEiii
|
0x0000007100fcf8bc,O,000072,_ZN4ksys4phys21LayerContactPointInfo4makeEPN4sead4HeapEiiRKNS2_14SafeStringBaseIcEEiii
|
||||||
0x0000007100fcf904,O,000348,_ZN4ksys4phys21LayerContactPointInfo17registerLayerPairENS0_12ContactLayerES2_b
|
0x0000007100fcf904,O,000348,_ZN4ksys4phys21LayerContactPointInfo17registerLayerPairENS0_12ContactLayerES2_b
|
||||||
|
|
Can't render this file because it is too large.
|
|
@ -21,6 +21,7 @@ public:
|
||||||
inline void setSeparatingNormal(const hkVector4& separatingNormal);
|
inline void setSeparatingNormal(const hkVector4& separatingNormal);
|
||||||
inline void setNormalOnly(const hkVector4& normal);
|
inline void setNormalOnly(const hkVector4& normal);
|
||||||
|
|
||||||
|
/// If negative, the two bodies are penetrating.
|
||||||
inline hkReal getDistance() const;
|
inline hkReal getDistance() const;
|
||||||
inline hkSimdReal getDistanceSimdReal() const;
|
inline hkSimdReal getDistanceSimdReal() const;
|
||||||
inline void setDistance(hkReal d);
|
inline void setDistance(hkReal d);
|
||||||
|
|
|
@ -21,6 +21,7 @@ target_sources(uking PRIVATE
|
||||||
RigidBody/physRigidBody.h
|
RigidBody/physRigidBody.h
|
||||||
RigidBody/physRigidBodyAccessor.cpp
|
RigidBody/physRigidBodyAccessor.cpp
|
||||||
RigidBody/physRigidBodyAccessor.h
|
RigidBody/physRigidBodyAccessor.h
|
||||||
|
RigidBody/physRigidBodyContactEvent.h
|
||||||
RigidBody/physRigidBodyFromResource.cpp
|
RigidBody/physRigidBodyFromResource.cpp
|
||||||
RigidBody/physRigidBodyFromResource.h
|
RigidBody/physRigidBodyFromResource.h
|
||||||
RigidBody/physRigidBodyFromShape.cpp
|
RigidBody/physRigidBodyFromShape.cpp
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <thread/seadAtomic.h>
|
#include <thread/seadAtomic.h>
|
||||||
#include <thread/seadCriticalSection.h>
|
#include <thread/seadCriticalSection.h>
|
||||||
#include "KingSystem/Physics/RigidBody/physRigidBodyAccessor.h"
|
#include "KingSystem/Physics/RigidBody/physRigidBodyAccessor.h"
|
||||||
|
#include "KingSystem/Physics/RigidBody/physRigidBodyContactEvent.h"
|
||||||
#include "KingSystem/Physics/physDefines.h"
|
#include "KingSystem/Physics/physDefines.h"
|
||||||
#include "KingSystem/Utils/Types.h"
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
|
@ -551,6 +552,9 @@ public:
|
||||||
/// Get the name of this rigid body or its user.
|
/// Get the name of this rigid body or its user.
|
||||||
virtual const char* getName();
|
virtual const char* getName();
|
||||||
|
|
||||||
|
RigidBodyContactCallback* getContactCallback() const { return mContactCallback; }
|
||||||
|
void setContactCallback(RigidBodyContactCallback* cb) { mContactCallback = cb; }
|
||||||
|
|
||||||
// Internal.
|
// Internal.
|
||||||
void setUseSystemTimeFactor(bool use) { mFlags.change(Flag::UseSystemTimeFactor, use); }
|
void setUseSystemTimeFactor(bool use) { mFlags.change(Flag::UseSystemTimeFactor, use); }
|
||||||
// Internal.
|
// Internal.
|
||||||
|
@ -594,7 +598,7 @@ protected:
|
||||||
Type mType{};
|
Type mType{};
|
||||||
MotionAccessor* mMotionAccessor = nullptr;
|
MotionAccessor* mMotionAccessor = nullptr;
|
||||||
sead::Atomic<int> mCollisionCount;
|
sead::Atomic<int> mCollisionCount;
|
||||||
void* _c8 = nullptr;
|
RigidBodyContactCallback* mContactCallback = nullptr;
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(RigidBody, 0xD0);
|
KSYS_CHECK_SIZE_NX150(RigidBody, 0xD0);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <prim/seadDelegate.h>
|
||||||
|
|
||||||
|
class hkpContactPointEvent;
|
||||||
|
|
||||||
|
namespace ksys::phys {
|
||||||
|
|
||||||
|
class RigidBody;
|
||||||
|
struct RigidBodyCollisionMasks;
|
||||||
|
|
||||||
|
struct RigidBodyContactEvent {
|
||||||
|
RigidBody* body;
|
||||||
|
const RigidBodyCollisionMasks* collision_masks;
|
||||||
|
const u32* shape_keys;
|
||||||
|
const hkpContactPointEvent* event;
|
||||||
|
};
|
||||||
|
|
||||||
|
using RigidBodyContactCallback = sead::IDelegate1R<const RigidBodyContactEvent&, bool>;
|
||||||
|
|
||||||
|
} // namespace ksys::phys
|
|
@ -84,15 +84,18 @@ private:
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(Unk6, 0x48);
|
KSYS_CHECK_SIZE_NX150(Unk6, 0x48);
|
||||||
|
|
||||||
struct PointCallback : LayerContactPointInfo::Callback {
|
struct PointCallback : LayerContactPointInfo::ContactCallback {
|
||||||
explicit PointCallback(RigidBodyRequestMgr* mgr_) : mgr(mgr_) {}
|
explicit PointCallback(RigidBodyRequestMgr* mgr_) : mgr(mgr_) {}
|
||||||
void invoke(void* arg) override { mgr->someFunction2(arg); }
|
|
||||||
|
bool invoke(const LayerContactPointInfo::ContactEvent& event) override {
|
||||||
|
return mgr->someFunction2(event);
|
||||||
|
}
|
||||||
|
|
||||||
RigidBodyRequestMgr* mgr;
|
RigidBodyRequestMgr* mgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: rename, implement
|
// FIXME: rename, implement
|
||||||
void someFunction2(void* arg);
|
bool someFunction2(const LayerContactPointInfo::ContactEvent& event);
|
||||||
static void someFunction(void* arg);
|
static void someFunction(void* arg);
|
||||||
|
|
||||||
static constexpr int NumRigidBodyBuffers = 2;
|
static constexpr int NumRigidBodyBuffers = 2;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "KingSystem/Physics/System/physContactListener.h"
|
#include "KingSystem/Physics/System/physContactListener.h"
|
||||||
#include <Havok/Common/Base/Types/Physics/ContactPoint/hkContactPoint.h>
|
#include <Havok/Common/Base/Types/Physics/ContactPoint/hkContactPoint.h>
|
||||||
#include <Havok/Physics2012/Collide/Agent/ContactMgr/hkpContactMgr.h>
|
|
||||||
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpCollisionEvent.h>
|
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpCollisionEvent.h>
|
||||||
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpContactPointEvent.h>
|
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpContactPointEvent.h>
|
||||||
|
#include <Havok/Physics2012/Dynamics/Collide/hkpSimpleConstraintContactMgr.h>
|
||||||
#include <Havok/Physics2012/Dynamics/Constraint/Contact/hkpContactPointProperties.h>
|
#include <Havok/Physics2012/Dynamics/Constraint/Contact/hkpContactPointProperties.h>
|
||||||
#include <Havok/Physics2012/Utilities/CharacterControl/CharacterRigidBody/hkpCharacterRigidBody.h>
|
#include <Havok/Physics2012/Utilities/CharacterControl/CharacterRigidBody/hkpCharacterRigidBody.h>
|
||||||
#include <math/seadMathCalcCommon.h>
|
#include <math/seadMathCalcCommon.h>
|
||||||
|
@ -23,6 +23,18 @@ static RigidBody* getRigidBody(hkpRigidBody* hk_body) {
|
||||||
return reinterpret_cast<RigidBody*>(hk_body->getUserData());
|
return reinterpret_cast<RigidBody*>(hk_body->getUserData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clearCallbackDelay(const hkpContactPointEvent& event) {
|
||||||
|
event.m_contactMgr->m_contactPointCallbackDelay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disableContact(const hkpContactPointEvent& event) {
|
||||||
|
event.m_contactPointProperties->m_flags |= hkpContactPointProperties::CONTACT_IS_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isContactDisabled(const hkpContactPointEvent& event) {
|
||||||
|
return event.m_contactPointProperties->m_flags & hkpContactPointProperties::CONTACT_IS_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
ContactListener::ContactListener(ContactMgr* mgr, ContactLayerType layer_type, int layer_count)
|
ContactListener::ContactListener(ContactMgr* mgr, ContactLayerType layer_type, int layer_count)
|
||||||
: mMgr(mgr), mLayerType(layer_type), mLayerBase(getContactLayerBase(layer_type)),
|
: mMgr(mgr), mLayerType(layer_type), mLayerBase(getContactLayerBase(layer_type)),
|
||||||
mLayerCount(layer_count) {}
|
mLayerCount(layer_count) {}
|
||||||
|
@ -88,8 +100,8 @@ void ContactListener::contactPointCallback(const hkpContactPointEvent& event) {
|
||||||
|
|
||||||
static_cast<void>(System::instance()->getGroupFilter(mLayerType));
|
static_cast<void>(System::instance()->getGroupFilter(mLayerType));
|
||||||
|
|
||||||
characterControlContactPointCallback(ignored_layers_a, ignored_layers_b, body_a, body_b,
|
contactPointCallbackImpl(ignored_layers_a, ignored_layers_b, body_a, body_b, layer_a,
|
||||||
layer_a, layer_b, event);
|
layer_b, event);
|
||||||
|
|
||||||
} else if (event.m_type == hkpContactPointEvent::TYPE_MANIFOLD) {
|
} else if (event.m_type == hkpContactPointEvent::TYPE_MANIFOLD) {
|
||||||
manifoldContactPointCallback(event, body_a, body_b);
|
manifoldContactPointCallback(event, body_a, body_b);
|
||||||
|
@ -114,11 +126,13 @@ bool ContactListener::manifoldContactPointCallback(const hkpContactPointEvent& e
|
||||||
const auto layer_a = filter->getCollisionFilterInfoLayer(masks_a.collision_filter_info);
|
const auto layer_a = filter->getCollisionFilterInfoLayer(masks_a.collision_filter_info);
|
||||||
const auto layer_b = filter->getCollisionFilterInfoLayer(masks_b.collision_filter_info);
|
const auto layer_b = filter->getCollisionFilterInfoLayer(masks_b.collision_filter_info);
|
||||||
|
|
||||||
if (!characterControlContactPointCallback(masks_a.ignored_layers, masks_b.ignored_layers,
|
if (!contactPointCallbackImpl(masks_a.ignored_layers, masks_b.ignored_layers, body_a, body_b,
|
||||||
body_a, body_b, layer_a, layer_b, event)) {
|
layer_a, layer_b, event)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fire ContactPointInfo callbacks.
|
||||||
|
|
||||||
if (auto* info = body_a->getContactPointInfo(); info && info->getContactCallback()) {
|
if (auto* info = body_a->getContactPointInfo(); info && info->getContactCallback()) {
|
||||||
storeToVec3(&position, event.m_contactPoint->getPosition());
|
storeToVec3(&position, event.m_contactPoint->getPosition());
|
||||||
storeToVec3(&normal, event.m_contactPoint->getSeparatingNormal());
|
storeToVec3(&normal, event.m_contactPoint->getSeparatingNormal());
|
||||||
|
@ -133,8 +147,7 @@ bool ContactListener::manifoldContactPointCallback(const hkpContactPointEvent& e
|
||||||
info->getContactCallback()->invoke(&disable, my_event);
|
info->getContactCallback()->invoke(&disable, my_event);
|
||||||
|
|
||||||
if (disable == ContactPointInfo::ShouldDisableContact::Yes) {
|
if (disable == ContactPointInfo::ShouldDisableContact::Yes) {
|
||||||
event.m_contactPointProperties->m_flags |=
|
disableContact(event);
|
||||||
hkpContactPointProperties::CONTACT_IS_DISABLED;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,8 +165,7 @@ bool ContactListener::manifoldContactPointCallback(const hkpContactPointEvent& e
|
||||||
info->getContactCallback()->invoke(&disable, my_event);
|
info->getContactCallback()->invoke(&disable, my_event);
|
||||||
|
|
||||||
if (disable == ContactPointInfo::ShouldDisableContact::Yes) {
|
if (disable == ContactPointInfo::ShouldDisableContact::Yes) {
|
||||||
event.m_contactPointProperties->m_flags |=
|
disableContact(event);
|
||||||
hkpContactPointProperties::CONTACT_IS_DISABLED;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,6 +173,199 @@ bool ContactListener::manifoldContactPointCallback(const hkpContactPointEvent& e
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ContactListener::regularContactPointCallback(
|
||||||
|
const hkpContactPointEvent& event, RigidBody* body_a, RigidBody* body_b,
|
||||||
|
sead::SafeArray<MaterialMaskData, 2>* out_material_masks) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (out_material_masks) {
|
||||||
|
(*out_material_masks)[0] = MaterialMaskData(masks_a.material_mask);
|
||||||
|
(*out_material_masks)[1] = MaterialMaskData(masks_b.material_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto layer_a = filter->getCollisionFilterInfoLayer(masks_a.collision_filter_info);
|
||||||
|
const auto layer_b = filter->getCollisionFilterInfoLayer(masks_b.collision_filter_info);
|
||||||
|
const auto i = layer_a - int(mLayerBase);
|
||||||
|
const auto j = layer_b - int(mLayerBase);
|
||||||
|
|
||||||
|
const bool result = contactPointCallbackImpl(masks_a.ignored_layers, masks_b.ignored_layers,
|
||||||
|
body_a, body_b, layer_a, layer_b, event);
|
||||||
|
if (result)
|
||||||
|
m11(event, masks_a, masks_b, body_a, body_b);
|
||||||
|
|
||||||
|
const auto& entries = mTrackedContactPointLayers[i][j];
|
||||||
|
|
||||||
|
if (layer_a == ContactLayer::EntityRagdoll || layer_b == ContactLayer::EntityRagdoll)
|
||||||
|
clearCallbackDelay(event);
|
||||||
|
|
||||||
|
// Fire rigid body callbacks.
|
||||||
|
bool callbacks_ok = true;
|
||||||
|
if (auto* callback = body_a->getContactCallback()) {
|
||||||
|
RigidBodyContactEvent my_event{body_b, &masks_b, event.getShapeKeys(1), &event};
|
||||||
|
callbacks_ok &= callback->invoke(my_event);
|
||||||
|
}
|
||||||
|
if (auto* callback = body_b->getContactCallback()) {
|
||||||
|
RigidBodyContactEvent my_event{body_a, &masks_a, event.getShapeKeys(0), &event};
|
||||||
|
callbacks_ok &= callback->invoke(my_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto notify_result = notifyContactPointInfo(body_a, body_b, layer_a, layer_b, masks_a, masks_b,
|
||||||
|
event, callbacks_ok);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ContactListener::notifyContactPointInfo(RigidBody* body_a, RigidBody* body_b,
|
||||||
|
ContactLayer layer_a, ContactLayer layer_b,
|
||||||
|
const RigidBodyCollisionMasks& masks_a,
|
||||||
|
const RigidBodyCollisionMasks& masks_b,
|
||||||
|
const hkpContactPointEvent& event, bool callbacks_ok) {
|
||||||
|
const hkReal distance = event.m_contactPoint->getDistance();
|
||||||
|
const bool should_notify = callbacks_ok && !mDisableContactPointInfoNotifications;
|
||||||
|
auto* info_a = body_a->getContactPointInfo();
|
||||||
|
auto* info_b = body_b->getContactPointInfo();
|
||||||
|
const bool contact_disabled = isContactDisabled(event);
|
||||||
|
|
||||||
|
ContactPoint point;
|
||||||
|
point.separating_distance = distance;
|
||||||
|
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
if (info_b && info_b->isLayerSubscribed(layer_a) && (info_b->get30() == 0 || distance <= 0.0) &&
|
||||||
|
(info_b->get34() == 0 || !contact_disabled)) {
|
||||||
|
if (should_notify) {
|
||||||
|
point.body_a = body_b;
|
||||||
|
point.body_b = body_a;
|
||||||
|
point.material_mask_a = MaterialMaskData(masks_b.material_mask);
|
||||||
|
point.material_mask_b = MaterialMaskData(masks_a.material_mask);
|
||||||
|
point.shape_key_a = getShapeKeyOrMinus1(event.getShapeKeys(1));
|
||||||
|
point.shape_key_b = getShapeKeyOrMinus1(event.getShapeKeys(0));
|
||||||
|
storeToVec3(&point.position, event.m_contactPoint->getPosition());
|
||||||
|
storeToVec3(&point.separating_normal, event.m_contactPoint->getSeparatingNormal());
|
||||||
|
|
||||||
|
if (mMgr->x_13(body_b->getContactPointInfo(), point, masks_a, distance < 0)) {
|
||||||
|
disableContact(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info_b->isLayerInMask2(layer_a))
|
||||||
|
clearCallbackDelay(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info_a && info_a->isLayerSubscribed(layer_b) && (info_a->get30() == 0 || distance <= 0.0) &&
|
||||||
|
(info_a->get34() == 0 || !contact_disabled)) {
|
||||||
|
if (should_notify) {
|
||||||
|
point.body_a = body_a;
|
||||||
|
point.body_b = body_b;
|
||||||
|
if (result == 1) {
|
||||||
|
storeToVec3(&point.position, event.m_contactPoint->getPosition());
|
||||||
|
storeToVec3(&point.separating_normal, event.m_contactPoint->getSeparatingNormal());
|
||||||
|
}
|
||||||
|
point.material_mask_a = MaterialMaskData(masks_a.material_mask);
|
||||||
|
point.material_mask_b = MaterialMaskData(masks_b.material_mask);
|
||||||
|
point.shape_key_a = getShapeKeyOrMinus1(event.getShapeKeys(0));
|
||||||
|
point.shape_key_b = getShapeKeyOrMinus1(event.getShapeKeys(1));
|
||||||
|
point.separating_normal *= -1;
|
||||||
|
|
||||||
|
if (mMgr->x_13(body_a->getContactPointInfo(), point, masks_b, !(distance < 0))) {
|
||||||
|
disableContact(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info_a->isLayerInMask2(layer_b))
|
||||||
|
clearCallbackDelay(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NON_MATCHING: branching (shape_key_b store), layer_a not being saved on the stack
|
||||||
|
void ContactListener::notifyLayerContactPointInfo(const TrackedContactPointLayer& tracked_layer,
|
||||||
|
int, RigidBody* body_a, RigidBody* body_b,
|
||||||
|
ContactLayer layer_a, ContactLayer layer_b,
|
||||||
|
u32 material_a, u32 material_b,
|
||||||
|
const hkpContactPointEvent& event) {
|
||||||
|
if (tracked_layer.do_not_delay_callback)
|
||||||
|
clearCallbackDelay(event);
|
||||||
|
|
||||||
|
if (mDisableContactPointInfoNotifications)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const hkReal distance = event.m_contactPoint->getDistance();
|
||||||
|
if (!(tracked_layer.info->get30() == 0 || distance <= 0.0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tracked_layer.info->get34() != 0 && isContactDisabled(event))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ContactPoint point;
|
||||||
|
storeToVec3(&point.position, event.m_contactPoint->getPosition());
|
||||||
|
storeToVec3(&point.separating_normal, event.m_contactPoint->getSeparatingNormal());
|
||||||
|
|
||||||
|
if (auto* callback = tracked_layer.info->getCallback()) {
|
||||||
|
if (tracked_layer.layer == layer_a) {
|
||||||
|
LayerContactPointInfo::ContactEvent my_event;
|
||||||
|
my_event.body_a = body_a;
|
||||||
|
my_event.body_b = body_b;
|
||||||
|
my_event.point_position = &point.position;
|
||||||
|
my_event.layer_a = layer_a;
|
||||||
|
my_event.layer_b = layer_b;
|
||||||
|
my_event.material_a = MaterialMaskData(material_a);
|
||||||
|
my_event.material_b = MaterialMaskData(material_b);
|
||||||
|
if (!callback->invoke(my_event))
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
LayerContactPointInfo::ContactEvent my_event;
|
||||||
|
my_event.body_a = body_b;
|
||||||
|
my_event.body_b = body_a;
|
||||||
|
my_event.point_position = &point.position;
|
||||||
|
my_event.layer_a = layer_b;
|
||||||
|
my_event.layer_b = layer_a;
|
||||||
|
my_event.material_a = MaterialMaskData(material_b);
|
||||||
|
my_event.material_b = MaterialMaskData(material_a);
|
||||||
|
if (!callback->invoke(my_event))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tracked_layer.layer == layer_a) {
|
||||||
|
point.body_a = body_a;
|
||||||
|
point.body_b = body_b;
|
||||||
|
point.material_mask_a = MaterialMaskData(material_a);
|
||||||
|
point.material_mask_b = MaterialMaskData(material_b);
|
||||||
|
point.shape_key_a = getShapeKeyOrMinus1(event.getShapeKeys(0));
|
||||||
|
point.shape_key_b = getShapeKeyOrMinus1(event.getShapeKeys(1));
|
||||||
|
point.separating_normal *= -1;
|
||||||
|
point.separating_distance = distance < 0 ? distance : 0;
|
||||||
|
mMgr->x_15(tracked_layer.info, point, !(distance < 0));
|
||||||
|
} else {
|
||||||
|
point.body_a = body_b;
|
||||||
|
point.body_b = body_a;
|
||||||
|
point.material_mask_a = MaterialMaskData(material_b);
|
||||||
|
point.material_mask_b = MaterialMaskData(material_a);
|
||||||
|
point.shape_key_a = getShapeKeyOrMinus1(event.getShapeKeys(1));
|
||||||
|
point.shape_key_b = getShapeKeyOrMinus1(event.getShapeKeys(0));
|
||||||
|
point.separating_distance = distance < 0 ? distance : 0;
|
||||||
|
mMgr->x_15(tracked_layer.info, point, distance < 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ContactListener::handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a,
|
void ContactListener::handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a,
|
||||||
RigidBody* body_b) {
|
RigidBody* body_b) {
|
||||||
registerForEndOfStepContactPointCallbacks(event);
|
registerForEndOfStepContactPointCallbacks(event);
|
||||||
|
@ -243,7 +448,7 @@ void ContactListener::addLayerPairForContactPointInfo(LayerContactPointInfo* inf
|
||||||
return;
|
return;
|
||||||
entry->info = info;
|
entry->info = info;
|
||||||
entry->layer = layer1;
|
entry->layer = layer1;
|
||||||
entry->enabled = enabled;
|
entry->do_not_delay_callback = enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto& row_i = mTrackedContactPointLayers[i];
|
auto& row_i = mTrackedContactPointLayers[i];
|
||||||
|
@ -293,12 +498,11 @@ void ContactListener::registerRigidBody(RigidBody* body) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContactListener::characterControlContactPointCallback(u32 ignored_layers_a,
|
bool ContactListener::contactPointCallbackImpl(u32 ignored_layers_a, u32 ignored_layers_b,
|
||||||
u32 ignored_layers_b, RigidBody* body_a,
|
RigidBody* body_a, RigidBody* body_b,
|
||||||
RigidBody* body_b, ContactLayer layer_a,
|
ContactLayer layer_a, ContactLayer layer_b,
|
||||||
ContactLayer layer_b,
|
const hkpContactPointEvent& event) {
|
||||||
const hkpContactPointEvent& event) {
|
disableContact(event);
|
||||||
event.m_contactPointProperties->m_flags |= hkpContactPointProperties::CONTACT_IS_DISABLED;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ class ContactLayerCollisionInfo;
|
||||||
class ContactMgr;
|
class ContactMgr;
|
||||||
class LayerContactPointInfo;
|
class LayerContactPointInfo;
|
||||||
class RigidBody;
|
class RigidBody;
|
||||||
|
struct RigidBodyCollisionMasks;
|
||||||
|
|
||||||
class ContactListener : public hkpContactListener, public sead::hostio::Node {
|
class ContactListener : public hkpContactListener, public sead::hostio::Node {
|
||||||
SEAD_RTTI_BASE(ContactListener)
|
SEAD_RTTI_BASE(ContactListener)
|
||||||
|
@ -46,12 +47,20 @@ public:
|
||||||
void contactProcessCallback(hkpContactProcessEvent& event) override {}
|
void contactProcessCallback(hkpContactProcessEvent& event) override {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool characterControlContactPointCallback(u32 ignored_layers_a, u32 ignored_layers_b,
|
struct TrackedContactPointLayer {
|
||||||
RigidBody* body_a, RigidBody* body_b,
|
LayerContactPointInfo* info;
|
||||||
ContactLayer layer_a, ContactLayer layer_b,
|
ContactLayer layer;
|
||||||
const hkpContactPointEvent& event);
|
bool do_not_delay_callback;
|
||||||
|
};
|
||||||
|
|
||||||
virtual void m11() {}
|
virtual bool contactPointCallbackImpl(u32 ignored_layers_a, u32 ignored_layers_b,
|
||||||
|
RigidBody* body_a, RigidBody* body_b,
|
||||||
|
ContactLayer layer_a, ContactLayer layer_b,
|
||||||
|
const hkpContactPointEvent& event);
|
||||||
|
|
||||||
|
virtual void m11(const hkpContactPointEvent& event, const RigidBodyCollisionMasks& masks_a,
|
||||||
|
const RigidBodyCollisionMasks& masks_b, RigidBody* body_a, RigidBody* body_b) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual void handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a,
|
virtual void handleCollisionAdded(const hkpCollisionEvent& event, RigidBody* body_a,
|
||||||
RigidBody* body_b);
|
RigidBody* body_b);
|
||||||
|
@ -63,23 +72,30 @@ protected:
|
||||||
RigidBody* body_b);
|
RigidBody* body_b);
|
||||||
|
|
||||||
/// @param out_material_masks [Optional] Pass this to get the materials of the rigid bodies.
|
/// @param out_material_masks [Optional] Pass this to get the materials of the rigid bodies.
|
||||||
virtual bool regularContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a,
|
virtual bool
|
||||||
RigidBody* body_b,
|
regularContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a,
|
||||||
sead::SafeArray<MaterialMask, 2>* out_material_masks);
|
RigidBody* body_b,
|
||||||
|
sead::SafeArray<MaterialMaskData, 2>* out_material_masks);
|
||||||
|
|
||||||
virtual u32 m15() { return 0; }
|
virtual u32 m15() { return 0; }
|
||||||
|
|
||||||
|
/// Record a contact point in the ContactPointInfo instances of the bodies (if applicable).
|
||||||
|
int notifyContactPointInfo(RigidBody* body_a, RigidBody* body_b, ContactLayer layer_a,
|
||||||
|
ContactLayer layer_b, const RigidBodyCollisionMasks& masks_a,
|
||||||
|
const RigidBodyCollisionMasks& masks_b,
|
||||||
|
const hkpContactPointEvent& event, bool callbacks_ok);
|
||||||
|
|
||||||
|
/// Record a contact point in the specified LayerContactPointInfo (if applicable).
|
||||||
|
void notifyLayerContactPointInfo(const TrackedContactPointLayer& tracked_layer, int,
|
||||||
|
RigidBody* body_a, RigidBody* body_b, ContactLayer layer_a,
|
||||||
|
ContactLayer layer_b, u32 material_a, u32 material_b,
|
||||||
|
const hkpContactPointEvent& event);
|
||||||
|
|
||||||
std::pair<int, int> convertToRelativeLayer(ContactLayer layer1, ContactLayer layer2) const {
|
std::pair<int, int> convertToRelativeLayer(ContactLayer layer1, ContactLayer layer2) const {
|
||||||
return {layer1 - int(mLayerBase), layer2 - int(mLayerBase)};
|
return {layer1 - int(mLayerBase), layer2 - int(mLayerBase)};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TrackedContactPointLayer {
|
|
||||||
LayerContactPointInfo* info;
|
|
||||||
ContactLayer layer;
|
|
||||||
bool enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
ContactMgr* mMgr{};
|
ContactMgr* mMgr{};
|
||||||
ContactLayerType mLayerType{};
|
ContactLayerType mLayerType{};
|
||||||
u32 mLayerBase{};
|
u32 mLayerBase{};
|
||||||
|
@ -91,7 +107,7 @@ private:
|
||||||
u32 mLayerCount{};
|
u32 mLayerCount{};
|
||||||
sead::CriticalSection mCS;
|
sead::CriticalSection mCS;
|
||||||
u16 _90{};
|
u16 _90{};
|
||||||
bool _92{};
|
bool mDisableContactPointInfoNotifications = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ksys::phys
|
} // namespace ksys::phys
|
||||||
|
|
|
@ -28,6 +28,7 @@ class CollisionInfo;
|
||||||
class ContactLayerCollisionInfo;
|
class ContactLayerCollisionInfo;
|
||||||
class ContactPointInfoBase;
|
class ContactPointInfoBase;
|
||||||
class RigidBody;
|
class RigidBody;
|
||||||
|
struct RigidBodyCollisionMasks;
|
||||||
class ContactPointInfo;
|
class ContactPointInfo;
|
||||||
class LayerContactPointInfo;
|
class LayerContactPointInfo;
|
||||||
|
|
||||||
|
@ -49,21 +50,21 @@ struct ContactInfoTable {
|
||||||
sead::Buffer<Receiver> receivers;
|
sead::Buffer<Receiver> receivers;
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXX: what exactly is this? Is this really a contact point?
|
|
||||||
struct ContactPoint {
|
struct ContactPoint {
|
||||||
enum class Flag {
|
enum class Flag {
|
||||||
_1 = 1 << 0,
|
_1 = 1 << 0,
|
||||||
_2 = 1 << 1,
|
_2 = 1 << 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void* _0;
|
RigidBody* body_a;
|
||||||
void* _8;
|
RigidBody* body_b;
|
||||||
sead::Vector3f _10;
|
sead::Vector3f position;
|
||||||
sead::Vector3f _1c;
|
sead::Vector3f separating_normal;
|
||||||
float scale;
|
float separating_distance;
|
||||||
MaterialMask material_mask1;
|
MaterialMask material_mask_a;
|
||||||
MaterialMask material_mask2;
|
MaterialMask material_mask_b;
|
||||||
void* _60;
|
u32 shape_key_a;
|
||||||
|
u32 shape_key_b;
|
||||||
sead::TypedBitFlag<Flag, u8> flags;
|
sead::TypedBitFlag<Flag, u8> flags;
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(ContactPoint, 0x70);
|
KSYS_CHECK_SIZE_NX150(ContactPoint, 0x70);
|
||||||
|
@ -90,6 +91,15 @@ public:
|
||||||
void registerContactPointInfo(ContactPointInfoBase* info);
|
void registerContactPointInfo(ContactPointInfoBase* info);
|
||||||
void freeContactPointInfo(ContactPointInfoBase* info);
|
void freeContactPointInfo(ContactPointInfoBase* info);
|
||||||
|
|
||||||
|
// 0x0000007100fb3284
|
||||||
|
/// @param colliding_body_masks The collision masks of the colliding rigid bodies.
|
||||||
|
/// @returns whether contact should be disabled.
|
||||||
|
bool x_13(ContactPointInfo* info, const ContactPoint& point,
|
||||||
|
const RigidBodyCollisionMasks& colliding_body_masks, bool penetrating);
|
||||||
|
|
||||||
|
// 0x0000007100fb3478
|
||||||
|
void x_15(LayerContactPointInfo* info, const ContactPoint& point, bool penetrating);
|
||||||
|
|
||||||
// 0x0000007100fb3744
|
// 0x0000007100fb3744
|
||||||
void x_17(CollisionInfo* info, RigidBody* body_a, RigidBody* body_b);
|
void x_17(CollisionInfo* info, RigidBody* body_a, RigidBody* body_b);
|
||||||
// 0x0000007100fb37d4
|
// 0x0000007100fb37d4
|
||||||
|
|
|
@ -24,8 +24,23 @@ public:
|
||||||
virtual ~ContactPointInfoBase() = default;
|
virtual ~ContactPointInfoBase() = default;
|
||||||
virtual void freePoints() = 0;
|
virtual void freePoints() = 0;
|
||||||
|
|
||||||
|
u32 get30() const { return _30; }
|
||||||
void set30(u32 value) { _30 = value; }
|
void set30(u32 value) { _30 = value; }
|
||||||
|
|
||||||
|
u32 get34() const { return _34; }
|
||||||
|
void set34(u32 value) { _34 = value; }
|
||||||
|
|
||||||
|
bool isLayerSubscribed(ContactLayer layer) const {
|
||||||
|
const auto type = getContactLayerType(layer);
|
||||||
|
return mSubscribedLayers[int(type)].isOnBit(int(getContactLayerBaseRelativeValue(layer)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: rename
|
||||||
|
bool isLayerInMask2(ContactLayer layer) const {
|
||||||
|
const auto type = getContactLayerType(layer);
|
||||||
|
return mLayerMask2[int(type)].isOnBit(int(getContactLayerBaseRelativeValue(layer)));
|
||||||
|
}
|
||||||
|
|
||||||
bool isLinked() const { return mListNode.isLinked(); }
|
bool isLinked() const { return mListNode.isLinked(); }
|
||||||
static constexpr size_t getListNodeOffset() {
|
static constexpr size_t getListNodeOffset() {
|
||||||
return offsetof(ContactPointInfoBase, mListNode);
|
return offsetof(ContactPointInfoBase, mListNode);
|
||||||
|
@ -33,7 +48,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
sead::Atomic<int> _18;
|
sead::Atomic<int> _18;
|
||||||
sead::SafeArray<sead::BitFlag32, 2> mLayerMask;
|
sead::SafeArray<sead::BitFlag32, 2> mSubscribedLayers;
|
||||||
|
// TODO: rename
|
||||||
sead::SafeArray<sead::BitFlag32, 2> mLayerMask2;
|
sead::SafeArray<sead::BitFlag32, 2> mLayerMask2;
|
||||||
u32 _2c{};
|
u32 _2c{};
|
||||||
u32 _30{};
|
u32 _30{};
|
||||||
|
|
|
@ -62,27 +62,27 @@ void LayerContactPointInfo::freePoints() {
|
||||||
|
|
||||||
void LayerContactPointInfo::Iterator::getData(sead::Vector3f* out,
|
void LayerContactPointInfo::Iterator::getData(sead::Vector3f* out,
|
||||||
LayerContactPointInfo::Iterator::Mode mode) const {
|
LayerContactPointInfo::Iterator::Mode mode) const {
|
||||||
const float scale = getPoint()->scale;
|
const float separating_distance = getPoint()->separating_distance;
|
||||||
out->e = getPoint()->_10.e;
|
out->e = getPoint()->position.e;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case Mode::_0: {
|
case Mode::_0: {
|
||||||
if (getPoint()->flags.isOn(ContactPoint::Flag::_2))
|
if (getPoint()->flags.isOn(ContactPoint::Flag::_2))
|
||||||
return;
|
return;
|
||||||
*out += getPoint()->_1c * -scale;
|
*out += getPoint()->separating_normal * -separating_distance;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Mode::_1: {
|
case Mode::_1: {
|
||||||
if (!getPoint()->flags.isOn(ContactPoint::Flag::_2))
|
if (!getPoint()->flags.isOn(ContactPoint::Flag::_2))
|
||||||
return;
|
return;
|
||||||
*out += getPoint()->_1c * scale;
|
*out += getPoint()->separating_normal * separating_distance;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Mode::_2:
|
case Mode::_2:
|
||||||
default: {
|
default: {
|
||||||
*out += getPoint()->_1c * scale * 0.5f;
|
*out += getPoint()->separating_normal * separating_distance * 0.5f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
#include <prim/seadTypedBitFlag.h>
|
#include <prim/seadTypedBitFlag.h>
|
||||||
#include "KingSystem/Physics/System/physContactPointInfo.h"
|
#include "KingSystem/Physics/System/physContactPointInfo.h"
|
||||||
#include "KingSystem/Physics/physDefines.h"
|
#include "KingSystem/Physics/physDefines.h"
|
||||||
|
#include "KingSystem/Physics/physMaterialMask.h"
|
||||||
#include "KingSystem/Utils/Types.h"
|
#include "KingSystem/Utils/Types.h"
|
||||||
|
|
||||||
namespace ksys::phys {
|
namespace ksys::phys {
|
||||||
|
|
||||||
struct ContactPoint;
|
struct ContactPoint;
|
||||||
|
class RigidBody;
|
||||||
|
|
||||||
class LayerContactPointInfo : public ContactPointInfoBase {
|
class LayerContactPointInfo : public ContactPointInfoBase {
|
||||||
public:
|
public:
|
||||||
|
@ -86,8 +88,17 @@ public:
|
||||||
const ContactPoint* const* mPointsStart = nullptr;
|
const ContactPoint* const* mPointsStart = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: figure out the types
|
struct ContactEvent {
|
||||||
using Callback = sead::IDelegate1<void*>;
|
RigidBody* body_a;
|
||||||
|
RigidBody* body_b;
|
||||||
|
const sead::Vector3f* point_position;
|
||||||
|
ContactLayer layer_a;
|
||||||
|
ContactLayer layer_b;
|
||||||
|
MaterialMaskData material_a;
|
||||||
|
MaterialMaskData material_b;
|
||||||
|
};
|
||||||
|
|
||||||
|
using ContactCallback = sead::IDelegate1R<const ContactEvent&, bool>;
|
||||||
|
|
||||||
static LayerContactPointInfo* make(sead::Heap* heap, int num, int num2,
|
static LayerContactPointInfo* make(sead::Heap* heap, int num, int num2,
|
||||||
const sead::SafeString& name, int a, int b, int c);
|
const sead::SafeString& name, int a, int b, int c);
|
||||||
|
@ -101,7 +112,8 @@ public:
|
||||||
bool registerLayerPair(ContactLayer layer1, ContactLayer layer2, bool enabled = true);
|
bool registerLayerPair(ContactLayer layer1, ContactLayer layer2, bool enabled = true);
|
||||||
bool isPairUnknown(ContactLayer layer1, ContactLayer layer2) const;
|
bool isPairUnknown(ContactLayer layer1, ContactLayer layer2) const;
|
||||||
|
|
||||||
void setCallback(Callback* callback) { mCallback = callback; }
|
ContactCallback* getCallback() const { return mCallback; }
|
||||||
|
void setCallback(ContactCallback* callback) { mCallback = callback; }
|
||||||
|
|
||||||
auto begin() const { return Iterator(mPoints, _18); }
|
auto begin() const { return Iterator(mPoints, _18); }
|
||||||
auto end() const { return IteratorEnd(mPoints, _18); }
|
auto end() const { return IteratorEnd(mPoints, _18); }
|
||||||
|
@ -113,7 +125,7 @@ private:
|
||||||
Points mPoints{};
|
Points mPoints{};
|
||||||
sead::ObjArray<LayerEntry> mLayerEntries;
|
sead::ObjArray<LayerEntry> mLayerEntries;
|
||||||
ContactLayerType mLayerType = ContactLayerType::Invalid;
|
ContactLayerType mLayerType = ContactLayerType::Invalid;
|
||||||
Callback* mCallback = nullptr;
|
ContactCallback* mCallback = nullptr;
|
||||||
};
|
};
|
||||||
KSYS_CHECK_SIZE_NX150(LayerContactPointInfo, 0x88);
|
KSYS_CHECK_SIZE_NX150(LayerContactPointInfo, 0x88);
|
||||||
|
|
||||||
|
|
|
@ -92,4 +92,8 @@ inline void setMtxTranslation(sead::Matrix34f* mtx, const hkVector4f& translatio
|
||||||
mtx->setTranslation(toVec3(translation));
|
mtx->setTranslation(toVec3(translation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline u32 getShapeKeyOrMinus1(const u32* shape_key) {
|
||||||
|
return shape_key ? *shape_key : u32(-1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ksys::phys
|
} // namespace ksys::phys
|
||||||
|
|
|
@ -50,7 +50,7 @@ static_assert(sizeof(MaterialMaskData) == sizeof(u32));
|
||||||
class MaterialMask {
|
class MaterialMask {
|
||||||
public:
|
public:
|
||||||
MaterialMask();
|
MaterialMask();
|
||||||
explicit MaterialMask(MaterialMaskData data);
|
MaterialMask(MaterialMaskData data); // NOLINT(google-explicit-constructor)
|
||||||
MaterialMask(Material mat, FloorCode floor, WallCode wall, bool flag = false);
|
MaterialMask(Material mat, FloorCode floor, WallCode wall, bool flag = false);
|
||||||
MaterialMask(Material mat, const char* submat_name, FloorCode floor, WallCode wall,
|
MaterialMask(Material mat, const char* submat_name, FloorCode floor, WallCode wall,
|
||||||
bool flag = false);
|
bool flag = false);
|
||||||
|
@ -66,6 +66,12 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialMask& operator=(MaterialMaskData data) {
|
||||||
|
mData = data;
|
||||||
|
mSubMaterialNameCache = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
MaterialMaskData& getData() { return mData; }
|
MaterialMaskData& getData() { return mData; }
|
||||||
const MaterialMaskData& getData() const { return mData; }
|
const MaterialMaskData& getData() const { return mData; }
|
||||||
u32 getRawData() const { return mData.raw; }
|
u32 getRawData() const { return mData.raw; }
|
||||||
|
|
Loading…
Reference in New Issue