From ced69f3e7df4fecde0690508808b57ce3f1eeb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 3 Feb 2022 14:39:56 +0100 Subject: [PATCH] ksys/phys: Implement CylinderWaterShape --- data/uking_functions.csv | 34 ++--- src/KingSystem/Physics/CMakeLists.txt | 2 + .../Shape/Cylinder/physCylinderShape.h | 4 + .../physCylinderWaterRigidBody.cpp | 1 + .../physCylinderWaterRigidBody.h | 12 ++ .../CylinderWater/physCylinderWaterShape.cpp | 127 ++++++++++++++++++ .../CylinderWater/physCylinderWaterShape.h | 52 ++++--- .../Physics/RigidBody/Shape/physShape.h | 1 + .../RigidBody/physRigidBodyFactory.cpp | 11 +- .../Physics/RigidBody/physRigidBodyFactory.h | 4 +- 10 files changed, 207 insertions(+), 41 deletions(-) create mode 100644 src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.cpp create mode 100644 src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 12cf2e4c..153e6b6d 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -83642,23 +83642,23 @@ Address,Quality,Size,Name 0x0000007100fadfe0,O,000204,_ZNK4ksys4phys13CylinderShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE 0x0000007100fae0ac,O,000092,_ZNK4ksys4phys13CylinderShape18getRuntimeTypeInfoEv 0x0000007100fae108,O,000008,_ZNK4ksys4phys13CylinderShape7getTypeEv -0x0000007100fae110,U,000288, -0x0000007100fae230,U,000032, -0x0000007100fae250,U,000064, -0x0000007100fae290,U,000072, -0x0000007100fae2d8,U,000068, -0x0000007100fae31c,U,000056, -0x0000007100fae354,U,000192, -0x0000007100fae414,U,000012, -0x0000007100fae420,U,000012, -0x0000007100fae42c,U,000032, -0x0000007100fae44c,U,000008, -0x0000007100fae454,U,000008, -0x0000007100fae45c,U,000032, -0x0000007100fae47c,U,000096, -0x0000007100fae4dc,U,000204, -0x0000007100fae5a8,U,000092, -0x0000007100fae604,U,000008, +0x0000007100fae110,O,000288,_ZN4ksys4phys18CylinderWaterShape4makeERKNS0_18CylinderShapeParamEPN4sead4HeapE +0x0000007100fae230,O,000032,_ZN4ksys4phys18CylinderWaterShape15setMaterialMaskERKNS0_12MaterialMaskE +0x0000007100fae250,O,000064,_ZN4ksys4phys18CylinderWaterShapeD1Ev +0x0000007100fae290,O,000072,_ZN4ksys4phys18CylinderWaterShapeD0Ev +0x0000007100fae2d8,O,000068,_ZN4ksys4phys18CylinderWaterShape9setRadiusEf +0x0000007100fae31c,O,000056,_ZN4ksys4phys18CylinderWaterShape9setHeightEf +0x0000007100fae354,m,000192,_ZNK4ksys4phys18CylinderWaterShape5cloneEPN4sead4HeapE +0x0000007100fae414,O,000012,_ZNK4ksys4phys18CylinderWaterShape9getRadiusEv +0x0000007100fae420,O,000012,_ZNK4ksys4phys18CylinderWaterShape9getHeightEv +0x0000007100fae42c,O,000032,_ZNK4ksys4phys18CylinderWaterShape9getVolumeEv +0x0000007100fae44c,O,000008,_ZN4ksys4phys18CylinderWaterShape13getHavokShapeEv +0x0000007100fae454,O,000008,_ZNK4ksys4phys18CylinderWaterShape13getHavokShapeEv +0x0000007100fae45c,O,000032,_ZN4ksys4phys18CylinderWaterShape16updateHavokShapeEv +0x0000007100fae47c,O,000096,_ZN4ksys4phys18CylinderWaterShape8setScaleEf +0x0000007100fae4dc,O,000204,_ZNK4ksys4phys18CylinderWaterShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x0000007100fae5a8,O,000092,_ZNK4ksys4phys18CylinderWaterShape18getRuntimeTypeInfoEv +0x0000007100fae604,O,000008,_ZNK4ksys4phys18CylinderWaterShape7getTypeEv 0x0000007100fae60c,U,000084, 0x0000007100fae660,U,000140, 0x0000007100fae6ec,U,001508, diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt index 47377a3d..ed4321a6 100644 --- a/src/KingSystem/Physics/CMakeLists.txt +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -58,6 +58,8 @@ target_sources(uking PRIVATE RigidBody/Shape/Cylinder/physCylinderRigidBody.h RigidBody/Shape/Cylinder/physCylinderShape.cpp RigidBody/Shape/Cylinder/physCylinderShape.h + RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.cpp + RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h RigidBody/Shape/CylinderWater/physCylinderWaterShape.cpp RigidBody/Shape/CylinderWater/physCylinderWaterShape.h RigidBody/Shape/Polytope/physPolytopeShape.cpp diff --git a/src/KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h b/src/KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h index 35c08290..9eed38b1 100644 --- a/src/KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h +++ b/src/KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h @@ -58,6 +58,10 @@ private: }; struct CylinderShapeParam { + CylinderShapeParam() = default; + CylinderShapeParam(const sead::Vector3f& va, const sead::Vector3f& vb) + : vertex_a(va), vertex_b(vb) {} + /// The center of the first circular base. sead::Vector3f vertex_a; /// The radius of the circular bases. diff --git a/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.cpp b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.cpp new file mode 100644 index 00000000..48f26c95 --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.cpp @@ -0,0 +1 @@ +#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h" diff --git a/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h new file mode 100644 index 00000000..fc638816 --- /dev/null +++ b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h @@ -0,0 +1,12 @@ +#pragma once + +#include "KingSystem/Physics/RigidBody/physRigidBodyFromShape.h" + +namespace ksys::phys { + +// TODO +class CylinderWaterRigidBody : public RigidBodyFromShape { + SEAD_RTTI_OVERRIDE(CylinderWaterRigidBody, RigidBodyFromShape) +}; + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.cpp b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.cpp index e69de29b..d4d452da 100644 --- a/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.cpp +++ b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.cpp @@ -0,0 +1,127 @@ +#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h" +#include +#include "KingSystem/Utils/HeapUtil.h" +#include "KingSystem/Utils/SafeDelete.h" + +namespace ksys::phys { + +class alignas(16) HavokCylinderWaterShape : public hkpHeightFieldShape { +public: + HK_DECLARE_CLASS_ALLOCATOR(HavokCylinderWaterShape) + + HavokCylinderWaterShape() : hkpHeightFieldShape(hkcdShapeType::HEIGHT_FIELD) {} + + void setRadius(float radius) { m_radius = radius; } + + void getAabb(const hkTransform& localToWorld, hkReal tolerance, hkAabb& aabbOut) const override; + + hkBool castRay(const hkpShapeRayCastInput& input, hkpShapeRayCastOutput& output) const override; + + void castRayWithCollector(const hkpShapeRayCastInput& input, const hkpCdBody& cdBody, + hkpRayHitCollector& collector) const override; + + void collideSpheres(const CollideSpheresInput& input, + SphereCollisionOutput* outputArray) const override; + + void castSphere(const hkpSphereCastInput& input, const hkpCdBody& cdBody, + hkpRayHitCollector& collector) const override {} + + float m_height = 1.0; + float m_radius = 1.0; +}; + +CylinderWaterShape* CylinderWaterShape::make(const CylinderShapeParam& param, sead::Heap* heap) { + void* storage = util::allocStorage(heap); + if (!storage) + return nullptr; + + auto* hk_shape = new (storage) HavokCylinderWaterShape; + return new (heap) CylinderWaterShape(param, hk_shape); +} + +CylinderWaterShape::CylinderWaterShape(const CylinderShapeParam& param, + HavokCylinderWaterShape* shape) + : mMaterialMask(param.common.getMaterialMask()), mHavokShape(shape) { + if (param.common.item_code_disable_stick) + mMaterialMask.getData().setCustomFlag(MaterialMaskData::CustomFlag::_0); + + setMaterialMask(mMaterialMask); + mHavokShape->setRadius(param.radius); + mHavokShape->m_height = param.vertex_a.x; +} + +CylinderWaterShape::~CylinderWaterShape() { + util::deallocateObjectUnsafe(mHavokShape); +} + +void CylinderWaterShape::setMaterialMask(const MaterialMask& mask) { + mMaterialMask = mask; + if (mHavokShape) + mHavokShape->setUserData(mask.getRawData()); +} + +bool CylinderWaterShape::setRadius(float radius) { + if (!mHavokShape) + return false; + + if (mHavokShape->m_radius == radius) + return false; + + mHavokShape->m_radius = radius; + mFlags.set(Flag::Dirty); + return true; +} + +bool CylinderWaterShape::setHeight(float height) { + if (mHavokShape->m_height == height) + return false; + + mHavokShape->m_height = height; + mFlags.set(Flag::Dirty); + return true; +} + +// NON_MATCHING: useless store to param.vertex_a.x +CylinderWaterShape* CylinderWaterShape::clone(sead::Heap* heap) const { + CylinderShapeParam param(-sead::Vector3f::ey, sead::Vector3f::ey); + param.radius = getRadius(); + param.vertex_a.x = getHeight(); + auto* cloned = make(param, heap); + cloned->setMaterialMask(mMaterialMask); + return cloned; +} + +float CylinderWaterShape::getRadius() const { + return mHavokShape->m_radius; +} + +float CylinderWaterShape::getHeight() const { + return mHavokShape->m_height; +} + +float CylinderWaterShape::getVolume() const { + return getHeight() * (sead::Mathf::piHalf() * getRadius() * getRadius()); +} + +hkpShape* CylinderWaterShape::getHavokShape() { + return mHavokShape; +} + +const hkpShape* CylinderWaterShape::getHavokShape() const { + return mHavokShape; +} + +const hkpShape* CylinderWaterShape::updateHavokShape() { + if (mFlags.isOn(Flag::Dirty)) { + // Nothing to do. + mFlags.reset(Flag::Dirty); + } + return nullptr; +} + +void CylinderWaterShape::setScale(float scale) { + setRadius(getRadius() * scale); + setHeight(getHeight() * scale); +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h index e9d26b13..93b06b1a 100644 --- a/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h +++ b/src/KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h @@ -1,28 +1,48 @@ #pragma once +#include +#include +#include "KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h" #include "KingSystem/Physics/RigidBody/physRigidBody.h" #include "KingSystem/Physics/RigidBody/physRigidBodyParam.h" +#include "KingSystem/Physics/System/physMaterialMask.h" namespace ksys::phys { -class CylinderWaterParam; +class HavokCylinderWaterShape; -struct CylinderWaterShape { - virtual ~CylinderWaterShape(); - - RigidBody* createBody(bool flag, const RigidBodyInstanceParam& params, sead::Heap* heap); -}; - -struct WaterCylinderShapeParam { - CylinderWaterShape* createShape(sead::Heap* heap); -}; - -class CylinderWaterParam : public RigidBodyInstanceParam { - SEAD_RTTI_OVERRIDE(CylinderWaterParam, RigidBodyInstanceParam) +class CylinderWaterShape : public Shape { + SEAD_RTTI_OVERRIDE(CylinderWaterShape, Shape) public: - u8 _90; - float _94; - WaterCylinderShapeParam shape; + enum class Flag { + Dirty = 1 << 0, + }; + + static CylinderWaterShape* make(const CylinderShapeParam& param, sead::Heap* heap); + + CylinderWaterShape(const CylinderShapeParam& param, HavokCylinderWaterShape* shape); + ~CylinderWaterShape() override; + + void setMaterialMask(const MaterialMask& mask); + bool setRadius(float radius); + bool setHeight(float height); + + CylinderWaterShape* clone(sead::Heap* heap) const; + + float getRadius() const; + float getHeight() const; + + float getVolume() const override; + hkpShape* getHavokShape() override; + const hkpShape* getHavokShape() const override; + const hkpShape* updateHavokShape() override; + void setScale(float scale) override; + ShapeType getType() const override { return ShapeType::CylinderWater; } + +private: + MaterialMask mMaterialMask; + sead::TypedBitFlag> mFlags; + HavokCylinderWaterShape* mHavokShape; }; } // namespace ksys::phys diff --git a/src/KingSystem/Physics/RigidBody/Shape/physShape.h b/src/KingSystem/Physics/RigidBody/Shape/physShape.h index 0cd660f5..9f0f91e6 100644 --- a/src/KingSystem/Physics/RigidBody/Shape/physShape.h +++ b/src/KingSystem/Physics/RigidBody/Shape/physShape.h @@ -17,6 +17,7 @@ enum class ShapeType { Polytope = 4, CharacterPrism = 6, BoxWater = 7, + CylinderWater = 8, Unknown = -1, }; diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.cpp b/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.cpp index e7c75c75..8bd1d621 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.cpp +++ b/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.cpp @@ -5,6 +5,7 @@ #include "KingSystem/Physics/RigidBody/Shape/Capsule/physCapsuleShape.h" #include "KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderRigidBody.h" #include "KingSystem/Physics/RigidBody/Shape/Cylinder/physCylinderShape.h" +#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h" #include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h" #include "KingSystem/Physics/RigidBody/Shape/Sphere/physSphereShape.h" #include "KingSystem/Physics/RigidBody/physRigidBodyFromShape.h" @@ -40,13 +41,9 @@ CylinderRigidBody* RigidBodyFactory::createCylinder(RigidBodyInstanceParam* para return createRigidBody(params, heap); } -RigidBody* RigidBodyFactory::createCylinderWater(RigidBodyInstanceParam* params, sead::Heap* heap) { - if (params->isDynamicSensor()) - params->motion_type = MotionType::Keyframed; - - auto* v = sead::DynamicCast(params); - auto* shape = v->shape.createShape(heap); - return shape->createBody(true, *params, heap); +CylinderWaterRigidBody* RigidBodyFactory::createCylinderWater(RigidBodyInstanceParam* params, + sead::Heap* heap) { + return createRigidBody(params, heap); } BoxRigidBody* RigidBodyFactory::createBox(RigidBodyInstanceParam* params, sead::Heap* heap) { diff --git a/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.h b/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.h index e3da1c1e..2e3b2927 100644 --- a/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.h +++ b/src/KingSystem/Physics/RigidBody/physRigidBodyFactory.h @@ -12,6 +12,7 @@ class BoxRigidBody; class BoxWaterRigidBody; class CapsuleRigidBody; class CylinderRigidBody; +class CylinderWaterRigidBody; class RigidBody; struct RigidBodyInstanceParam; @@ -20,7 +21,8 @@ public: static RigidBody* createSphere(RigidBodyInstanceParam* params, sead::Heap* heap); static CapsuleRigidBody* createCapsule(RigidBodyInstanceParam* params, sead::Heap* heap); static CylinderRigidBody* createCylinder(RigidBodyInstanceParam* params, sead::Heap* heap); - static RigidBody* createCylinderWater(RigidBodyInstanceParam* params, sead::Heap* heap); + static CylinderWaterRigidBody* createCylinderWater(RigidBodyInstanceParam* params, + sead::Heap* heap); static BoxRigidBody* createBox(RigidBodyInstanceParam* params, sead::Heap* heap); static BoxWaterRigidBody* createBoxWater(RigidBodyInstanceParam* params, sead::Heap* heap); static RigidBody* createPolytope(RigidBodyInstanceParam* params, sead::Heap* heap);