ksys/phys: Finish RigidBodyFromShape

This commit is contained in:
Léo Lam 2022-02-12 17:31:54 +01:00
parent 3ebf3eda62
commit 0c3ee0dd84
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
7 changed files with 207 additions and 17 deletions

View File

@ -83312,19 +83312,19 @@ Address,Quality,Size,Name
0x0000007100f9ccd0,O,000104,_ZThn32_N4ksys4phys18RigidBodyFromShapeD1Ev
0x0000007100f9cd38,O,000108,_ZN4ksys4phys18RigidBodyFromShapeD0Ev
0x0000007100f9cda4,O,000112,_ZThn32_N4ksys4phys18RigidBodyFromShapeD0Ev
0x0000007100f9ce14,U,000948,
0x0000007100f9ce14,O,000948,_ZNK4ksys4phys18RigidBodyFromShape18tryGetMaterialMaskEv
0x0000007100f9d1c8,O,000036,_ZN4ksys4phys18RigidBodyFromShape17getNewHavokShape_Ev
0x0000007100f9d1ec,O,000244,_ZN4ksys4phys18RigidBodyFromShape12updateScale_Eff
0x0000007100f9d2e0,O,000204,_ZNK4ksys4phys18RigidBodyFromShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007100f9d3ac,O,000092,_ZNK4ksys4phys18RigidBodyFromShape18getRuntimeTypeInfoEv
0x0000007100f9d408,U,000904,
0x0000007100f9d790,U,000904,
0x0000007100f9db18,U,000904,
0x0000007100f9dea0,U,000904,
0x0000007100f9e228,U,000904,
0x0000007100f9e5b0,U,000904,
0x0000007100f9e938,U,000904,
0x0000007100f9ecc0,U,000904,
0x0000007100f9d408,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_15SphereRigidBodyENS0_11SphereShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9d790,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_16CapsuleRigidBodyENS0_12CapsuleShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9db18,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_17CylinderRigidBodyENS0_13CylinderShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9dea0,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_22CylinderWaterRigidBodyENS0_18CylinderWaterShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9e228,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_12BoxRigidBodyENS0_8BoxShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9e5b0,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_17BoxWaterRigidBodyENS0_13BoxWaterShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9e938,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_17PolytopeRigidBodyENS0_13PolytopeShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9ecc0,O,000904,_ZN4ksys4phys18RigidBodyFromShape4makeINS0_18ListShapeRigidBodyENS0_9ListShapeEEEPT_PT0_bRKNS0_22RigidBodyInstanceParamEPN4sead4HeapE
0x0000007100f9f048,U,000204,
0x0000007100f9f114,U,000092,
0x0000007100f9f170,O,000064,_ZN4ksys4phys14RigidBodyParamC1Ev

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

View File

@ -4,10 +4,28 @@
namespace ksys::phys {
class SphereShape;
class SphereRigidBody : public RigidBodyFromShape {
SEAD_RTTI_OVERRIDE(SphereRigidBody, RigidBodyFromShape)
public:
static SphereRigidBody* make(RigidBodyInstanceParam* param, sead::Heap* heap);
SphereRigidBody(hkpRigidBody* hk_body, SphereShape* shape, ContactLayerType layer_type,
const sead::SafeString& name, bool set_flag_10, sead::Heap* heap);
~SphereRigidBody() override;
const MaterialMask& getMaterialMask() const;
float getVolume() override;
protected:
Shape* getShape_() override;
const Shape* getShape_() const override;
u32 getCollisionMasks(RigidBody::CollisionMasks* masks, const u32* unk) override;
private:
SphereShape* mShape{};
};
} // namespace ksys::phys

View File

@ -90,7 +90,7 @@ public:
_2000000 = 1 << 25,
_4000000 = 1 << 26,
_8000000 = 1 << 27,
_10000000 = 1 << 28,
NoCharStandingOn = 1 << 28,
_20000000 = 1 << 29,
_40000000 = 1 << 30,
_80000000 = 1 << 31,
@ -549,6 +549,8 @@ public:
void setFlag400000(bool set) { mFlags.change(Flag::_400000, set); }
// Internal.
void setUpdateRequestedFlag() { mFlags.set(Flag::UpdateRequested); }
// Internal.
void setFlag20() { mFlags.set(Flag::_20); }
// Internal.
void onCollisionAdded() {

View File

@ -21,7 +21,7 @@ static RigidBodyType* createRigidBody(RigidBodyInstanceParam* param, sead::Heap*
auto* v = sead::DynamicCast<ParamType>(param);
auto* shape = ShapeType::make(v->shape, heap);
return RigidBodyFromShape::make<RigidBodyType, ShapeType>(*shape, true, *param, heap);
return RigidBodyFromShape::make<RigidBodyType, ShapeType>(shape, true, *param, heap);
}
SphereRigidBody* RigidBodyFactory::createSphere(RigidBodyInstanceParam* params, sead::Heap* heap) {

View File

@ -1,6 +1,27 @@
#include "KingSystem/Physics/RigidBody/physRigidBodyFromShape.h"
#include <Havok/Physics2012/Dynamics/Entity/hkpRigidBody.h>
#include <Havok/Physics2012/Dynamics/Entity/hkpRigidBodyCinfo.h>
#include <basis/seadRawPrint.h>
#include "KingSystem/Physics/RigidBody/Shape/Box/physBoxRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/Box/physBoxShape.h"
#include "KingSystem/Physics/RigidBody/Shape/BoxWater/physBoxWaterRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/BoxWater/physBoxWaterShape.h"
#include "KingSystem/Physics/RigidBody/Shape/Capsule/physCapsuleRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/Capsule/physCapsuleShape.h"
#include "KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h"
#include "KingSystem/Physics/RigidBody/Shape/List/physListShape.h"
#include "KingSystem/Physics/RigidBody/Shape/List/physListShapeRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/Polytope/physPolytopeRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/Polytope/physPolytopeShape.h"
#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physShape.h"
#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h"
#include "KingSystem/Physics/System/physDefines.h"
#include "KingSystem/Physics/physConversions.h"
#include "KingSystem/Utils/HeapUtil.h"
namespace ksys::phys {
@ -18,6 +39,32 @@ RigidBodyFromShape::~RigidBodyFromShape() {
operator delete(mHkBody);
}
const MaterialMask* RigidBodyFromShape::tryGetMaterialMask() const {
switch (getShape_()->getType()) {
case ShapeType::Sphere:
return &sead::DynamicCast<const SphereRigidBody>(this)->getMaterialMask();
case ShapeType::Capsule:
return &sead::DynamicCast<const CapsuleRigidBody>(this)->getMaterialMask();
case ShapeType::Box:
return &sead::DynamicCast<const BoxRigidBody>(this)->getMaterialMask();
case ShapeType::Cylinder:
return &sead::DynamicCast<const CylinderRigidBody>(this)->getMaterialMask();
case ShapeType::Polytope:
return &sead::DynamicCast<const PolytopeRigidBody>(this)->getMaterialMask();
case ShapeType::List:
return &sead::DynamicCast<const ListShapeRigidBody>(this)->getMaterialMask(0);
case ShapeType::BoxWater:
return &sead::DynamicCast<const BoxWaterRigidBody>(this)->getMaterialMask();
case ShapeType::CylinderWater:
return &sead::DynamicCast<const CylinderWaterRigidBody>(this)->getMaterialMask();
case ShapeType::CharacterPrism:
case ShapeType::Unknown:
SEAD_ASSERT_MSG(false, "unexpected shape type");
break;
}
return &sead::DynamicCast<const SphereRigidBody>(this)->getMaterialMask();
}
const hkpShape* RigidBodyFromShape::getNewHavokShape_() {
return getShape_()->updateHavokShape();
}
@ -45,4 +92,124 @@ float RigidBodyFromShape::updateScale_(float scale, float old_scale) {
return scale;
}
template <typename RigidBodyT, typename ShapeT>
RigidBodyT* RigidBodyFromShape::make(ShapeT* shape, bool set_flag_10,
const RigidBodyInstanceParam& param, sead::Heap* heap) {
const auto layer_type = getContactLayerType(param.contact_layer);
hkMatrix3 inertia_mtx;
const auto inertia = toHkVec4(param.inertia);
inertia_mtx.m_col0.setMul(inertia, hkVector4f::getConstant<HK_QUADREAL_1000>());
inertia_mtx.m_col1.setMul(inertia, hkVector4f::getConstant<HK_QUADREAL_0100>());
inertia_mtx.m_col2.setMul(inertia, hkVector4f::getConstant<HK_QUADREAL_0010>());
// Set up construction info for the Havok rigid body.
hkpRigidBodyCinfo cinfo;
cinfo.m_shape = shape->getHavokShapeConst();
cinfo.m_centerOfMass = toHkVec4(param.center_of_mass);
cinfo.m_mass = param.mass;
cinfo.m_inertiaTensor = inertia_mtx;
cinfo.m_linearDamping = param.linear_damping;
cinfo.m_angularDamping = param.angular_damping;
cinfo.m_gravityFactor = param.gravity_factor;
cinfo.m_timeFactor = param.time_factor;
cinfo.m_maxLinearVelocity = param.max_linear_velocity;
cinfo.m_maxAngularVelocity = param.max_angular_velocity_rad;
cinfo.m_enableDeactivation = param.enable_deactivation;
cinfo.m_numShapeKeysInContactPointProperties = -1;
switch (param.motion_type) {
case MotionType::Dynamic:
cinfo.m_motionType = hkpMotion::MOTION_DYNAMIC;
break;
case MotionType::Fixed:
cinfo.m_motionType = hkpMotion::MOTION_FIXED;
break;
case MotionType::Keyframed:
cinfo.m_motionType = hkpMotion::MOTION_KEYFRAMED;
break;
case MotionType::Unknown:
case MotionType::Invalid:
break;
}
void* hk_body_storage = util::allocStorage<hkpRigidBody>(heap);
if (!hk_body_storage)
return nullptr;
auto* hk_body = new (hk_body_storage) hkpRigidBody(cinfo);
RigidBodyFromShape* body =
new (heap) RigidBodyT(hk_body, shape, layer_type, param.name, set_flag_10, heap);
body->mFlags.set(Flag::UpdateRequested);
if (param.motion_type == MotionType::Keyframed) {
hk_body->setCenterOfMassLocal(cinfo.m_centerOfMass);
hk_body->setMaxLinearVelocity(cinfo.m_maxLinearVelocity);
hk_body->setMaxAngularVelocity(cinfo.m_maxAngularVelocity);
}
if (param._90) {
body->setFlag20();
} else if (!body->initMotionAccessor(param, heap, false)) {
delete body;
return nullptr;
}
if (param.contact_layer == ContactLayer::SensorCustomReceiver) {
body->setSensorCustomReceiver(param.receiver_mask, param.system_group_handler);
} else if (param.groundhit_mask != 0) {
body->setGroundHitMask(param.contact_layer, param.groundhit_mask);
} else {
body->setContactLayerAndGroundHitAndHandler(param.contact_layer, param.groundhit,
param.system_group_handler);
}
body->updateCollidableQualityType(param.toi);
body->updateShape();
body->clearEntityMotionFlag20(!param.ignore_normal_for_impulse);
body->enableGroundCollision(!param.no_hit_ground);
body->enableWaterCollision(!param.no_hit_water);
body->mFlags.change(Flag::NoCharStandingOn, param.no_char_standing_on);
body->setContactMask(param.contact_mask);
body->setEntityMotionFlag1(param.always_character_mass_scaling);
body->processUpdateRequests(nullptr, nullptr);
return static_cast<RigidBodyT*>(body);
}
template SphereRigidBody* RigidBodyFromShape::make(SphereShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template CapsuleRigidBody* RigidBodyFromShape::make(CapsuleShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template CylinderRigidBody* RigidBodyFromShape::make(CylinderShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template CylinderWaterRigidBody* RigidBodyFromShape::make(CylinderWaterShape* shape,
bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template BoxRigidBody* RigidBodyFromShape::make(BoxShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template BoxWaterRigidBody* RigidBodyFromShape::make(BoxWaterShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template PolytopeRigidBody* RigidBodyFromShape::make(PolytopeShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
template ListShapeRigidBody* RigidBodyFromShape::make(ListShape* shape, bool set_flag_10,
const RigidBodyInstanceParam& param,
sead::Heap* heap);
} // namespace ksys::phys

View File

@ -10,10 +10,11 @@ class Shape;
class RigidBodyFromShape : public RigidBody {
SEAD_RTTI_OVERRIDE(RigidBodyFromShape, RigidBody)
public:
// TODO
template <typename RigidBodyType, typename ShapeType>
static RigidBodyType* make(const ShapeType& shape, bool set_flag_10,
const RigidBodyInstanceParam& param, sead::Heap* heap);
/// Create a RigidBodyFromShape with the specified shape and rigid body parameters.
/// @param shape Must not be null.
template <typename RigidBodyT, typename ShapeT>
static RigidBodyT* make(ShapeT* shape, bool set_flag_10, const RigidBodyInstanceParam& param,
sead::Heap* heap);
RigidBodyFromShape(hkpRigidBody* hkp_rigid_body, ContactLayerType layer_type,
const sead::SafeString& name, bool set_flag_10, sead::Heap* heap);

View File

@ -10,6 +10,8 @@
namespace ksys::phys {
class SystemGroupHandler;
// TODO: maybe move this to NavMesh/?
enum class NavMeshType {
NOT_USE,
@ -68,10 +70,10 @@ public:
float water_buoyancy_scale = 1.0f;
float water_flow_effective_rate = 1.0f;
float magne_mass_scaling_factor = 1.0f;
bool gap68 = true;
bool enable_deactivation = true;
bool toi = false;
bool always_character_mass_scaling = false;
void* p = nullptr;
SystemGroupHandler* system_group_handler = nullptr;
ContactLayer contact_layer = ContactLayer::EntityObject;
GroundHit groundhit = GroundHit::HitAll;
u32 groundhit_mask = 0;