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
|
||||
0x0000007100fb6394,O,000028,_ZN4ksys4phys17EntityGroupFilter34setEntityLayerCollisionEnabledMaskENS0_12ContactLayerEj
|
||||
0x0000007100fb63b0,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys11GroupFilterEE9isDerivedEPKNS0_9InterfaceE
|
||||
0x0000007100fb643c,U,000108,phys::makeEntityContactListener
|
||||
0x0000007100fb64a8,U,000004,j_ksys::phys::ContactListener::dtor
|
||||
0x0000007100fb64ac,U,000036,
|
||||
0x0000007100fb643c,O,000108,_ZN4ksys4phys21EntityContactListener4makeEPNS0_10ContactMgrEPN4sead4HeapE
|
||||
0x0000007100fb64a8,O,000004,_ZN4ksys4phys21EntityContactListenerD1Ev
|
||||
0x0000007100fb64ac,O,000036,_ZN4ksys4phys21EntityContactListenerD0Ev
|
||||
0x0000007100fb64d0,U,000456,
|
||||
0x0000007100fb6698,U,000472,
|
||||
0x0000007100fb6870,U,000320,
|
||||
0x0000007100fb69b0,U,000304,
|
||||
0x0000007100fb6ae0,U,000492,
|
||||
0x0000007100fb6ccc,U,000120,
|
||||
0x0000007100fb6d44,U,000084,
|
||||
0x0000007100fb6d98,U,000128,
|
||||
0x0000007100fb6d44,O,000084,_ZN4ksys4phys21EntityContactListener27isObjectOrGroundOrNPCOrTreeERKNS0_9RigidBodyE
|
||||
0x0000007100fb6d98,O,000128,_ZN4ksys4phys21EntityContactListener27isObjectOrGroundOrNPCOrTreeERK9hkpCdBody
|
||||
0x0000007100fb6e18,U,000460,
|
||||
0x0000007100fb6fe4,U,000284,
|
||||
0x0000007100fb6fe4,O,000284,_ZN4ksys4phys21EntityContactListener3m11ERK20hkpContactPointEventRKNS0_23RigidBodyCollisionMasksES7_PNS0_9RigidBodyES9_
|
||||
0x0000007100fb7100,U,000344,
|
||||
0x0000007100fb7258,U,002036,
|
||||
0x0000007100fb7a4c,U,000204,
|
||||
0x0000007100fb7b18,U,000092,
|
||||
0x0000007100fb7b74,U,000140,
|
||||
0x0000007100fb7a4c,O,000204,_ZNK4ksys4phys21EntityContactListener27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
|
||||
0x0000007100fb7b18,O,000092,_ZNK4ksys4phys21EntityContactListener18getRuntimeTypeInfoEv
|
||||
0x0000007100fb7b74,O,000140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys4phys15ContactListenerEE9isDerivedEPKNS0_9InterfaceE
|
||||
0x0000007100fb7c00,U,000788,ActorPhysics::ctor
|
||||
0x0000007100fb7f14,U,000020,
|
||||
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/physLayerContactPointInfo.cpp
|
||||
System/physLayerContactPointInfo.h
|
||||
System/physEntityContactListener.cpp
|
||||
System/physEntityContactListener.h
|
||||
System/physEntityGroupFilter.cpp
|
||||
System/physEntityGroupFilter.h
|
||||
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 {
|
||||
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 {
|
||||
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 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& getSoundMatchingSubMaterial(Material material, int submat_idx) const;
|
||||
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#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/seadQuat.h>
|
||||
#include <math/seadVector.h>
|
||||
|
||||
namespace ksys::phys {
|
||||
|
||||
class RigidBody;
|
||||
|
||||
inline void toVec3(sead::Vector3f* out, const hkVector4f& vec) {
|
||||
out->x = vec.getX();
|
||||
out->y = vec.getY();
|
||||
|
@ -96,4 +102,20 @@ inline u32 getShapeKeyOrMinus1(const u32* shape_key) {
|
|||
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
|
||||
|
|
|
@ -23,6 +23,11 @@ union MaterialMaskData {
|
|||
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) {
|
||||
if (!b)
|
||||
clearFlag();
|
||||
|
@ -75,8 +80,11 @@ public:
|
|||
MaterialMaskData& getData() { return mData; }
|
||||
const MaterialMaskData& getData() const { return mData; }
|
||||
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* getSubMaterialName() const;
|
||||
|
|
Loading…
Reference in New Issue