mirror of https://github.com/zeldaret/botw.git
ksys/phys: Start adding EntityContactListener
This commit is contained in:
parent
c11a33c5ab
commit
a9ee6f839e
|
@ -83839,24 +83839,24 @@ Address,Quality,Size,Name
|
||||||
0x0000007100fb6368,O,000044,_ZN4ksys4phys17EntityGroupFilter23makeCollisionFilterInfoENS0_12ContactLayerENS0_9GroundHitEjj
|
0x0000007100fb6368,O,000044,_ZN4ksys4phys17EntityGroupFilter23makeCollisionFilterInfoENS0_12ContactLayerENS0_9GroundHitEjj
|
||||||
0x0000007100fb6394,O,000028,_ZN4ksys4phys17EntityGroupFilter34setEntityLayerCollisionEnabledMaskENS0_12ContactLayerEj
|
0x0000007100fb6394,O,000028,_ZN4ksys4phys17EntityGroupFilter34setEntityLayerCollisionEnabledMaskENS0_12ContactLayerEj
|
||||||
0x0000007100fb63b0,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys11GroupFilterEE9isDerivedEPKNS0_9InterfaceE
|
0x0000007100fb63b0,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys11GroupFilterEE9isDerivedEPKNS0_9InterfaceE
|
||||||
0x0000007100fb643c,U,000108,phys::makeEntityContactListener
|
0x0000007100fb643c,O,000108,_ZN4ksys4phys21EntityContactListener4makeEPNS0_10ContactMgrEPN4sead4HeapE
|
||||||
0x0000007100fb64a8,U,000004,j_ksys::phys::ContactListener::dtor
|
0x0000007100fb64a8,O,000004,_ZN4ksys4phys21EntityContactListenerD1Ev
|
||||||
0x0000007100fb64ac,U,000036,
|
0x0000007100fb64ac,O,000036,_ZN4ksys4phys21EntityContactListenerD0Ev
|
||||||
0x0000007100fb64d0,U,000456,
|
0x0000007100fb64d0,U,000456,
|
||||||
0x0000007100fb6698,U,000472,
|
0x0000007100fb6698,U,000472,
|
||||||
0x0000007100fb6870,U,000320,
|
0x0000007100fb6870,U,000320,
|
||||||
0x0000007100fb69b0,U,000304,
|
0x0000007100fb69b0,U,000304,
|
||||||
0x0000007100fb6ae0,U,000492,
|
0x0000007100fb6ae0,U,000492,
|
||||||
0x0000007100fb6ccc,U,000120,
|
0x0000007100fb6ccc,U,000120,
|
||||||
0x0000007100fb6d44,U,000084,
|
0x0000007100fb6d44,O,000084,_ZN4ksys4phys21EntityContactListener27isObjectOrGroundOrNPCOrTreeERKNS0_9RigidBodyE
|
||||||
0x0000007100fb6d98,U,000128,
|
0x0000007100fb6d98,O,000128,_ZN4ksys4phys21EntityContactListener27isObjectOrGroundOrNPCOrTreeERK9hkpCdBody
|
||||||
0x0000007100fb6e18,U,000460,
|
0x0000007100fb6e18,U,000460,
|
||||||
0x0000007100fb6fe4,U,000284,
|
0x0000007100fb6fe4,O,000284,_ZN4ksys4phys21EntityContactListener3m11ERK20hkpContactPointEventRKNS0_23RigidBodyCollisionMasksES7_PNS0_9RigidBodyES9_
|
||||||
0x0000007100fb7100,U,000344,
|
0x0000007100fb7100,U,000344,
|
||||||
0x0000007100fb7258,U,002036,
|
0x0000007100fb7258,U,002036,
|
||||||
0x0000007100fb7a4c,U,000204,
|
0x0000007100fb7a4c,O,000204,_ZNK4ksys4phys21EntityContactListener27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||||
0x0000007100fb7b18,U,000092,
|
0x0000007100fb7b18,O,000092,_ZNK4ksys4phys21EntityContactListener18getRuntimeTypeInfoEv
|
||||||
0x0000007100fb7b74,U,000140,
|
0x0000007100fb7b74,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys15ContactListenerEE9isDerivedEPKNS0_9InterfaceE
|
||||||
0x0000007100fb7c00,U,000788,ActorPhysics::ctor
|
0x0000007100fb7c00,U,000788,ActorPhysics::ctor
|
||||||
0x0000007100fb7f14,U,000020,
|
0x0000007100fb7f14,U,000020,
|
||||||
0x0000007100fb7f28,U,000004,j__ZdlPv_1006
|
0x0000007100fb7f28,U,000004,j__ZdlPv_1006
|
||||||
|
|
Can't render this file because it is too large.
|
|
@ -121,6 +121,8 @@ target_sources(uking PRIVATE
|
||||||
System/physContactPointInfo.h
|
System/physContactPointInfo.h
|
||||||
System/physLayerContactPointInfo.cpp
|
System/physLayerContactPointInfo.cpp
|
||||||
System/physLayerContactPointInfo.h
|
System/physLayerContactPointInfo.h
|
||||||
|
System/physEntityContactListener.cpp
|
||||||
|
System/physEntityContactListener.h
|
||||||
System/physEntityGroupFilter.cpp
|
System/physEntityGroupFilter.cpp
|
||||||
System/physEntityGroupFilter.h
|
System/physEntityGroupFilter.h
|
||||||
System/physGroupFilter.cpp
|
System/physGroupFilter.cpp
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "KingSystem/Physics/System/physEntityContactListener.h"
|
||||||
|
#include <Havok/Physics2012/Collide/Agent/Collidable/hkpCdBody.h>
|
||||||
|
#include <Havok/Physics2012/Dynamics/Collide/ContactListener/hkpContactPointEvent.h>
|
||||||
|
#include <Havok/Physics2012/Dynamics/Constraint/Contact/hkpContactPointProperties.h>
|
||||||
|
#include <math/seadMathCalcCommon.h>
|
||||||
|
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
|
||||||
|
#include "KingSystem/Physics/System/physMaterialTable.h"
|
||||||
|
#include "KingSystem/Physics/System/physSystem.h"
|
||||||
|
#include "KingSystem/Physics/physConversions.h"
|
||||||
|
#include "KingSystem/Physics/physMaterialMask.h"
|
||||||
|
|
||||||
|
namespace ksys::phys {
|
||||||
|
|
||||||
|
EntityContactListener* EntityContactListener::make(ContactMgr* mgr, sead::Heap* heap) {
|
||||||
|
auto* listener = new (heap) EntityContactListener(mgr, heap);
|
||||||
|
listener->init(heap);
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityContactListener::EntityContactListener(ContactMgr* mgr, sead::Heap* heap)
|
||||||
|
: ContactListener(mgr, ContactLayerType::Entity, MaxNumLayersPerType) {}
|
||||||
|
|
||||||
|
EntityContactListener::~EntityContactListener() = default;
|
||||||
|
|
||||||
|
bool EntityContactListener::isObjectOrGroundOrNPCOrTree(const RigidBody& body) {
|
||||||
|
switch (body.getContactLayer().value()) {
|
||||||
|
case ContactLayer::EntityObject:
|
||||||
|
case ContactLayer::EntityGroundObject:
|
||||||
|
case ContactLayer::EntityNPC:
|
||||||
|
case ContactLayer::EntityTree:
|
||||||
|
if (body.hasFlag(RigidBody::Flag::_400000))
|
||||||
|
break;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityContactListener::isObjectOrGroundOrNPCOrTree(const hkpCdBody& cd_body) {
|
||||||
|
auto* body = getRigidBody(*cd_body.getRootCollidable());
|
||||||
|
if (!body)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return isObjectOrGroundOrNPCOrTree(*body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityContactListener::m11(const hkpContactPointEvent& event,
|
||||||
|
const RigidBodyCollisionMasks& masks_a,
|
||||||
|
const RigidBodyCollisionMasks& masks_b, RigidBody* body_a,
|
||||||
|
RigidBody* body_b) {
|
||||||
|
auto* hk_point_properties = event.m_contactPointProperties;
|
||||||
|
|
||||||
|
const MaterialMask mat_mask_a = MaterialMaskData(masks_a.material_mask);
|
||||||
|
const MaterialMask mat_mask_b = MaterialMaskData(masks_b.material_mask);
|
||||||
|
const auto* material_table = System::instance()->getMaterialTable();
|
||||||
|
|
||||||
|
const auto mat_a = mat_mask_a.getMaterial();
|
||||||
|
const auto mat_b = mat_mask_b.getMaterial();
|
||||||
|
const auto properties = material_table->getPairProperties(mat_a, mat_b);
|
||||||
|
|
||||||
|
const float friction = properties.friction *
|
||||||
|
sead::Mathf::min(body_a->getFrictionScale(), body_b->getFrictionScale());
|
||||||
|
|
||||||
|
const float restitution =
|
||||||
|
properties.restitution * sead::Mathf::min(body_a->getEffectiveRestitutionScale(),
|
||||||
|
body_b->getEffectiveRestitutionScale());
|
||||||
|
|
||||||
|
hk_point_properties->setFriction(friction);
|
||||||
|
hk_point_properties->setRestitution(restitution);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ksys::phys
|
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "KingSystem/Physics/System/physContactListener.h"
|
||||||
|
|
||||||
|
class hkpCdBody;
|
||||||
|
|
||||||
|
namespace ksys::phys {
|
||||||
|
|
||||||
|
class EntityContactListener : public ContactListener {
|
||||||
|
SEAD_RTTI_OVERRIDE(EntityContactListener, ContactListener)
|
||||||
|
public:
|
||||||
|
static EntityContactListener* make(ContactMgr* mgr, sead::Heap* heap);
|
||||||
|
|
||||||
|
~EntityContactListener() override;
|
||||||
|
void collisionAddedCallback(const hkpCollisionEvent& event) override;
|
||||||
|
void collisionRemovedCallback(const hkpCollisionEvent& event) override;
|
||||||
|
|
||||||
|
static bool isObjectOrGroundOrNPCOrTree(const RigidBody& body);
|
||||||
|
static bool isObjectOrGroundOrNPCOrTree(const hkpCdBody& cd_body);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EntityContactListener(ContactMgr* mgr, sead::Heap* heap);
|
||||||
|
|
||||||
|
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) override;
|
||||||
|
|
||||||
|
void m11(const hkpContactPointEvent& event, const RigidBodyCollisionMasks& masks_a,
|
||||||
|
const RigidBodyCollisionMasks& masks_b, RigidBody* body_a, RigidBody* body_b) override;
|
||||||
|
|
||||||
|
bool
|
||||||
|
regularContactPointCallback(const hkpContactPointEvent& event, RigidBody* body_a,
|
||||||
|
RigidBody* body_b,
|
||||||
|
sead::SafeArray<MaterialMaskData, 2>* out_material_masks) override;
|
||||||
|
|
||||||
|
u32 m15() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ksys::phys
|
|
@ -13,6 +13,13 @@ namespace ksys::phys {
|
||||||
|
|
||||||
class MaterialTable {
|
class MaterialTable {
|
||||||
public:
|
public:
|
||||||
|
/// Properties for interactions between two materials.
|
||||||
|
struct MaterialPairProperties {
|
||||||
|
float friction;
|
||||||
|
float restitution;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Parameter object that stores an entire row of InteractionProperties.
|
||||||
struct Values : agl::utl::IParameterObj {
|
struct Values : agl::utl::IParameterObj {
|
||||||
sead::SafeArray<agl::utl::Parameter<sead::Vector2f>, Material::size()> values;
|
sead::SafeArray<agl::utl::Parameter<sead::Vector2f>, Material::size()> values;
|
||||||
};
|
};
|
||||||
|
@ -30,6 +37,11 @@ public:
|
||||||
void loadMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive);
|
void loadMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive);
|
||||||
void loadSubMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive);
|
void loadSubMaterialTable(sead::Heap* heap, agl::utl::ResParameterArchive archive);
|
||||||
|
|
||||||
|
MaterialPairProperties getPairProperties(Material mat_a, Material mat_b) const {
|
||||||
|
auto& vec = mMaterialTable[mat_a].values[mat_b];
|
||||||
|
return {vec->x, vec->y};
|
||||||
|
}
|
||||||
|
|
||||||
const sead::SafeString& getSubMaterial(Material material, int submat_idx) const;
|
const sead::SafeString& getSubMaterial(Material material, int submat_idx) const;
|
||||||
const sead::SafeString& getSoundMatchingSubMaterial(Material material, int submat_idx) const;
|
const sead::SafeString& getSoundMatchingSubMaterial(Material material, int submat_idx) const;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Havok/Common/Base/hkBase.h>
|
#include <Havok/Common/Base/hkBase.h>
|
||||||
|
#include <Havok/Physics2012/Collide/Agent/Collidable/hkpCdBody.h>
|
||||||
|
#include <Havok/Physics2012/Collide/Agent/Collidable/hkpCollidable.h>
|
||||||
|
#include <Havok/Physics2012/Dynamics/Entity/hkpEntity.h>
|
||||||
|
#include <Havok/Physics2012/Dynamics/World/hkpWorldObject.h>
|
||||||
#include <math/seadMatrix.h>
|
#include <math/seadMatrix.h>
|
||||||
#include <math/seadQuat.h>
|
#include <math/seadQuat.h>
|
||||||
#include <math/seadVector.h>
|
#include <math/seadVector.h>
|
||||||
|
|
||||||
namespace ksys::phys {
|
namespace ksys::phys {
|
||||||
|
|
||||||
|
class RigidBody;
|
||||||
|
|
||||||
inline void toVec3(sead::Vector3f* out, const hkVector4f& vec) {
|
inline void toVec3(sead::Vector3f* out, const hkVector4f& vec) {
|
||||||
out->x = vec.getX();
|
out->x = vec.getX();
|
||||||
out->y = vec.getY();
|
out->y = vec.getY();
|
||||||
|
@ -96,4 +102,20 @@ inline u32 getShapeKeyOrMinus1(const u32* shape_key) {
|
||||||
return shape_key ? *shape_key : u32(-1);
|
return shape_key ? *shape_key : u32(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline RigidBody* getRigidBody(const hkpEntity* entity) {
|
||||||
|
// This needs to be kept in sync with the RigidBody constructor!
|
||||||
|
return reinterpret_cast<RigidBody*>(entity->getUserData());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline RigidBody* getRigidBody(const hkpCollidable& collidable) {
|
||||||
|
if (collidable.getType() != hkpWorldObject::BroadPhaseType::BROAD_PHASE_ENTITY)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto* entity = static_cast<const hkpEntity*>(collidable.getOwner());
|
||||||
|
if (!entity)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return getRigidBody(entity);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ksys::phys
|
} // namespace ksys::phys
|
||||||
|
|
|
@ -23,6 +23,11 @@ union MaterialMaskData {
|
||||||
return u32(idx) < (1 << decltype(sub_material)::NumBits());
|
return u32(idx) < (1 << decltype(sub_material)::NumBits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Material getMaterial() const { return int(material.Value()); }
|
||||||
|
int getSubMaterialIndex() const { return int(sub_material.Value()); }
|
||||||
|
FloorCode getFloorCode() const { return int(floor.Value()); }
|
||||||
|
WallCode getWallCode() const { return int(wall.Value()); }
|
||||||
|
|
||||||
void setFlag(bool b) {
|
void setFlag(bool b) {
|
||||||
if (!b)
|
if (!b)
|
||||||
clearFlag();
|
clearFlag();
|
||||||
|
@ -75,8 +80,11 @@ public:
|
||||||
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; }
|
||||||
Material getMaterial() const { return Material::ValueType(mData.material.Value()); }
|
|
||||||
int getSubMaterialIdx() const { return mData.sub_material; }
|
Material getMaterial() const { return mData.getMaterial(); }
|
||||||
|
int getSubMaterialIdx() const { return mData.getSubMaterialIndex(); }
|
||||||
|
FloorCode getFloorCode() const { return mData.getFloorCode(); }
|
||||||
|
WallCode getWallCode() const { return mData.getWallCode(); }
|
||||||
|
|
||||||
const char* getMaterialName() const;
|
const char* getMaterialName() const;
|
||||||
const char* getSubMaterialName() const;
|
const char* getSubMaterialName() const;
|
||||||
|
|
Loading…
Reference in New Issue