diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 4479c7e1..e893922b 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -83083,7 +83083,7 @@ Address,Quality,Size,Name 0x0000007100f93e18,O,000016,_ZNK4ksys4phys9RigidBody13getTimeFactorEv 0x0000007100f93e28,O,000176,_ZN4ksys4phys9RigidBody18setLinkedRigidBodyEPS1_ 0x0000007100f93ed8,O,000156,_ZNK4ksys4phys9RigidBody26isSensorMotionFlag40000SetEv -0x0000007100f93f74,O,000008,_ZN4ksys4phys9RigidBody3m12Eff +0x0000007100f93f74,O,000008,_ZN4ksys4phys9RigidBody12updateScale_Eff 0x0000007100f93f7c,O,000008,_ZN4ksys4phys9RigidBody2m4Ev 0x0000007100f93f84,O,000152,_ZN4ksys4phys9RigidBody21setWaterBuoyancyScaleEf 0x0000007100f9401c,O,000148,_ZNK4ksys4phys9RigidBody21getWaterBuoyancyScaleEv @@ -83126,7 +83126,7 @@ Address,Quality,Size,Name 0x0000007100f963a4,O,000156,_ZNK4ksys4phys9RigidBody22isEntityMotionFlag80OnEv 0x0000007100f96440,O,000156,_ZN4ksys4phys9RigidBody25setMagneMassScalingFactorEf 0x0000007100f964dc,O,000148,_ZNK4ksys4phys9RigidBody25getMagneMassScalingFactorEv -0x0000007100f96570,O,000008,_ZN4ksys4phys9RigidBody11getNewShapeEv +0x0000007100f96570,O,000008,_ZN4ksys4phys9RigidBody17getNewHavokShape_Ev 0x0000007100f96578,O,000008,_ZN4ksys4phys9RigidBody3m11Ev 0x0000007100f96580,O,000240,_ZN4ksys4phys9RigidBody21onMaxPositionExceededEv 0x0000007100f96670,O,000144,_ZN4ksys4phys9RigidBody7getNameEv @@ -83307,16 +83307,16 @@ Address,Quality,Size,Name 0x0000007100f9c474,U,000696, 0x0000007100f9c72c,U,000656, 0x0000007100f9c9bc,U,000608, -0x0000007100f9cc1c,U,000080,RigidBodyDerivedType0::ctor -0x0000007100f9cc6c,U,000100, -0x0000007100f9ccd0,U,000104, -0x0000007100f9cd38,U,000108, -0x0000007100f9cda4,U,000112, +0x0000007100f9cc1c,O,000080,_ZN4ksys4phys18RigidBodyFromShapeC2EP12hkpRigidBodyNS0_16ContactLayerTypeERKN4sead14SafeStringBaseIcEEbPNS5_4HeapE +0x0000007100f9cc6c,O,000100,_ZN4ksys4phys18RigidBodyFromShapeD1Ev +0x0000007100f9ccd0,O,000104,_ZThn32_N4ksys4phys18RigidBodyFromShapeD1Ev +0x0000007100f9cd38,O,000108,_ZN4ksys4phys18RigidBodyFromShapeD0Ev +0x0000007100f9cda4,O,000112,_ZThn32_N4ksys4phys18RigidBodyFromShapeD0Ev 0x0000007100f9ce14,U,000948, 0x0000007100f9d1c8,U,000036, 0x0000007100f9d1ec,U,000244, -0x0000007100f9d2e0,U,000204, -0x0000007100f9d3ac,U,000092, +0x0000007100f9d2e0,O,000204,_ZNK4ksys4phys18RigidBodyFromShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x0000007100f9d3ac,O,000092,_ZNK4ksys4phys18RigidBodyFromShape18getRuntimeTypeInfoEv 0x0000007100f9d408,U,000904, 0x0000007100f9d790,U,000904, 0x0000007100f9db18,U,000904, @@ -83595,8 +83595,8 @@ Address,Quality,Size,Name 0x0000007100fabb4c,O,000060,_ZN4ksys4phys12CapsuleShape9setRadiusEf 0x0000007100fabb88,O,000192,_ZN4ksys4phys12CapsuleShape11setVerticesERKN4sead7Vector3IfEES6_ 0x0000007100fabc48,O,000140,_ZNK4ksys4phys12CapsuleShape9getVolumeEv -0x0000007100fabcd4,O,000008,_ZN4ksys4phys12CapsuleShape8getShapeEv -0x0000007100fabcdc,O,000008,_ZNK4ksys4phys12CapsuleShape8getShapeEv +0x0000007100fabcd4,O,000008,_ZN4ksys4phys12CapsuleShape13getHavokShapeEv +0x0000007100fabcdc,O,000008,_ZNK4ksys4phys12CapsuleShape13getHavokShapeEv 0x0000007100fabce4,U,000252, 0x0000007100fabde0,U,000160, 0x0000007100fabe80,O,000192,_ZN4ksys4phys12CapsuleShape14sub_7100FABE80EPN4sead7Vector3IfEES5_RK12hkTransformf diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index d334a10b..29597c74 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -23,6 +23,8 @@ target_sources(uking PRIVATE RigidBody/physRigidBodyAccessor.h RigidBody/physRigidBodyFactory.cpp RigidBody/physRigidBodyFactory.h + RigidBody/physRigidBodyFromShape.cpp + RigidBody/physRigidBodyFromShape.h RigidBody/physRigidBodyMotionEntity.cpp RigidBody/physRigidBodyMotionEntity.h RigidBody/physRigidBodyMotionSensor.cpp @@ -43,6 +45,7 @@ target_sources(uking PRIVATE RigidBody/Shape/physCapsuleShape.h RigidBody/Shape/physCylinderShape.cpp RigidBody/Shape/physCylinderShape.h + RigidBody/Shape/physShape.h RigidBody/Shape/physSphereShape.cpp RigidBody/Shape/physSphereShape.h RigidBody/Shape/physWaterCylinderShape.cpp diff --git a/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.cpp b/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.cpp index 9b5ae788..60963fd0 100644 --- a/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.cpp +++ b/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.cpp @@ -87,11 +87,11 @@ f32 CapsuleShape::getVolume() const { return sead::Mathf::pi() * radius * radius * (dist + radius * 4.0f / 3.0f); } -hkpShape* CapsuleShape::getShape() { +hkpShape* CapsuleShape::getHavokShape() { return shape; } -const hkpShape* CapsuleShape::getShape() const { +const hkpShape* CapsuleShape::getHavokShape() const { return shape; } diff --git a/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h b/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h index 936b8793..5609f224 100644 --- a/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h +++ b/src/KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h @@ -4,6 +4,7 @@ #include #include #include +#include "KingSystem/Physics/RigidBody/Shape/physShape.h" #include "KingSystem/Physics/RigidBody/physRigidBody.h" #include "KingSystem/Physics/RigidBody/physRigidBodyParam.h" #include "KingSystem/Physics/System/physDefines.h" @@ -30,18 +31,20 @@ struct CapsuleShapeParam { bool _38 = false; }; -struct CapsuleShape { +struct CapsuleShape : Shape { + SEAD_RTTI_OVERRIDE(CapsuleShape, Shape) +public: enum class Flag { Modified = 1 << 0, }; CapsuleShape(const CapsuleShapeParam& shape_, hkpShape* hkp_shape_); - virtual ~CapsuleShape(); + ~CapsuleShape() override; - virtual hkpShape* getShape(); - virtual const hkpShape* getShape() const; - virtual void updateChanges(); - virtual void scaleVerts(f32 scale); + hkpShape* getHavokShape() override; + const hkpShape* getHavokShape() const override; + void updateHavokShape() override; + void setScale(float scale) override; RigidBody* createBody(bool flag, const RigidBodyInstanceParam& params, sead::Heap* heap); CapsuleShape* clone(sead::Heap* heap); diff --git a/src/KingSystem/Physics/RigidBody/Shape/physShape.h b/src/KingSystem/Physics/RigidBody/Shape/physShape.h new file mode 100644 index 00000000..521d3443 --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/Shape/physShape.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +class hkpShape; + +namespace ksys::phys { + +class Shape { + SEAD_RTTI_BASE(Shape) + +public: + Shape() = default; + virtual ~Shape() = default; + + virtual hkpShape* getHavokShape() = 0; + virtual const hkpShape* getHavokShape() const = 0; + virtual void updateHavokShape() = 0; + virtual void setScale(float scale) = 0; +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/physRigidBody.cpp b/src/KingSystem/Physics/RigidBody/physRigidBody.cpp index 58eaac47..c84473d1 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBody.cpp +++ b/src/KingSystem/Physics/RigidBody/physRigidBody.cpp @@ -44,7 +44,7 @@ static bool isMatrixInvalid(const sead::Matrix34f& matrix) { } RigidBody::RigidBody(Type type, ContactLayerType layer_type, hkpRigidBody* hk_body, - const sead::SafeString& name, sead::Heap* heap, bool a7) + const sead::SafeString& name, sead::Heap* heap, bool set_flag_10) : mCS(heap), mHkBody(hk_body), mRigidBodyAccessor(hk_body), mType(type) { if (!name.isEmpty()) { mHkBody->setName(name.cstr()); @@ -60,12 +60,12 @@ RigidBody::RigidBody(Type type, ContactLayerType layer_type, hkpRigidBody* hk_bo mFlags.change(Flag::HighQualityCollidable, isCharacterControllerType()); mFlags.change(Flag::IsSensor, layer_type == ContactLayerType::Sensor); - mFlags.change(Flag::_10, a7); + mFlags.change(Flag::_10, set_flag_10); mFlags.set(Flag::UseSystemTimeFactor); } RigidBody::~RigidBody() { - if (mType != Type::_0 && mType != Type::TerrainHeightField && + if (mType != Type::FromShape && mType != Type::TerrainHeightField && mType != Type::CharacterController) { mHkBody->setName(nullptr); mHkBody->deallocateInternalArrays(); @@ -911,7 +911,7 @@ void RigidBody::updateShape() { return; } - auto* shape = getNewShape(); + auto* shape = getNewHavokShape_(); if (shape) { mHkBody->setShape(shape); if (isEntity() && mMotionAccessor) @@ -936,7 +936,7 @@ void RigidBody::setScale(float scale) { if (sead::Mathf::equalsEpsilon(mScale, scale)) return; - mScale = m12(scale, mScale); + mScale = updateScale_(scale, mScale); updateShape(); } @@ -1482,8 +1482,8 @@ sead::Vector3f RigidBody::getInertiaLocal() const { return inertia; } -float RigidBody::m12(float x, float y) { - return y; +float RigidBody::updateScale_(float scale, float old_scale) { + return old_scale; } float RigidBody::m4() { @@ -1738,7 +1738,7 @@ void RigidBody::clearFlag8000000(bool clear) { updateDeactivation(); } -const hkpShape* RigidBody::getNewShape() { +const hkpShape* RigidBody::getNewHavokShape_() { return nullptr; } diff --git a/src/KingSystem/Physics/RigidBody/physRigidBody.h b/src/KingSystem/Physics/RigidBody/physRigidBody.h index 14894e9a..4e852722 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBody.h +++ b/src/KingSystem/Physics/RigidBody/physRigidBody.h @@ -41,7 +41,7 @@ class RigidBody : public sead::IDisposer, public RigidBase { SEAD_RTTI_BASE(RigidBody) public: enum class Type { - _0 = 0, + FromShape = 0, _1 = 1, _2 = 2, TerrainHeightField = 3, @@ -125,7 +125,7 @@ public: }; RigidBody(Type type, ContactLayerType layer_type, hkpRigidBody* hk_body, - const sead::SafeString& name, sead::Heap* heap, bool a7); + const sead::SafeString& name, sead::Heap* heap, bool set_flag_10); ~RigidBody() override; virtual float m4(); @@ -508,11 +508,19 @@ public: void setEntityMotionFlag200(bool set); bool isEntityMotionFlag200On() const; +protected: virtual void m9() = 0; - virtual const hkpShape* getNewShape(); - virtual void* m11(); - virtual float m12(float x, float y); + /// Called whenever a shape update is requested. + /// @return the new shape to use for the Havok rigid body or null to keep the current hkpShape + virtual const hkpShape* getNewHavokShape_(); + + virtual void* m11(); + + /// @return the new scale + virtual float updateScale_(float scale, float old_scale); + +public: /// Called when the rigid body goes beyond the broadphase border. /// /// Note: this is not guaranteed to be called if we have a user tag. @@ -543,7 +551,7 @@ public: clearFlag4000000(true); } -private: +protected: void createMotionAccessor(sead::Heap* heap); void assertLayerType(ContactLayer layer) const; void onInvalidParameter(int code = 0); diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodyFromShape.cpp b/src/KingSystem/Physics/RigidBody/physRigidBodyFromShape.cpp new file mode 100644 index 00000000..85507c87 --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/physRigidBodyFromShape.cpp @@ -0,0 +1,20 @@ +#include "KingSystem/Physics/RigidBody/physRigidBodyFromShape.h" +#include + +namespace ksys::phys { + +RigidBodyFromShape::RigidBodyFromShape(hkpRigidBody* hkp_rigid_body, ContactLayerType layer_type, + const sead::SafeString& name, bool set_flag_10, + sead::Heap* heap) + : RigidBody(RigidBody::Type::FromShape, layer_type, hkp_rigid_body, name, heap, set_flag_10) {} + +RigidBodyFromShape::~RigidBodyFromShape() { + mHkBody->setName(nullptr); + mHkBody->deallocateInternalArrays(); + /// @bug This should be `delete mhkBody;` -- hkpRigidBody is not trivially destructible and + /// calling operator delete directly does not call the destructor. + if (mHkBody) + operator delete(mHkBody); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodyFromShape.h b/src/KingSystem/Physics/RigidBody/physRigidBodyFromShape.h new file mode 100644 index 00000000..eca6e12d --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/physRigidBodyFromShape.h @@ -0,0 +1,22 @@ +#pragma once + +#include "KingSystem/Physics/RigidBody/physRigidBody.h" + +namespace ksys::phys { + +class RigidBodyFromShape : public RigidBody { + SEAD_RTTI_OVERRIDE(RigidBodyFromShape, RigidBody) +public: + RigidBodyFromShape(hkpRigidBody* hkp_rigid_body, ContactLayerType layer_type, + const sead::SafeString& name, bool set_flag_10, sead::Heap* heap); + ~RigidBodyFromShape() override; + +protected: + const hkpShape* getNewHavokShape_() override; + float updateScale_(float scale, float old_scale) override; + + virtual void m15() = 0; + virtual void m16() = 0; +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.cpp b/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.cpp index a7ca5edb..2193a895 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.cpp +++ b/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.cpp @@ -21,7 +21,7 @@ bool RigidBodySetParam::parse(agl::utl::ResParameterList res_list, sead::Heap* h if (*type == "from_shape_type") type_val = Type::FromShapeType; else - type_val = Type::Other; + type_val = Type::FromResource; const int num_bodies = *num; if (num_bodies == 0 || res_list.getResParameterListNum() != num_bodies) diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.h b/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.h index 536f3c4c..b328eb28 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.h +++ b/src/KingSystem/Physics/RigidBody/physRigidBodySetParam.h @@ -13,7 +13,7 @@ struct RigidBodySetParam : agl::utl::ParameterList { enum class Type { Invalid = 0, FromShapeType = 1, - Other = 2, + FromResource = 2, }; RigidBodySetParam();