ksys/phys: Implement CylinderWaterShape

This commit is contained in:
Léo Lam 2022-02-03 14:39:56 +01:00
parent 872d02a037
commit ced69f3e7d
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
10 changed files with 207 additions and 41 deletions

View File

@ -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,

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

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1 @@
#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterRigidBody.h"

View File

@ -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

View File

@ -0,0 +1,127 @@
#include "KingSystem/Physics/RigidBody/Shape/CylinderWater/physCylinderWaterShape.h"
#include <Havok/Physics2012/Collide/Shape/HeightField/hkpHeightFieldShape.h>
#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<HavokCylinderWaterShape>(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

View File

@ -1,28 +1,48 @@
#pragma once
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#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<Flag, sead::Atomic<u32>> mFlags;
HavokCylinderWaterShape* mHavokShape;
};
} // namespace ksys::phys

View File

@ -17,6 +17,7 @@ enum class ShapeType {
Polytope = 4,
CharacterPrism = 6,
BoxWater = 7,
CylinderWater = 8,
Unknown = -1,
};

View File

@ -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<CylinderRigidBody, CylinderShape, CylinderParam>(params, heap);
}
RigidBody* RigidBodyFactory::createCylinderWater(RigidBodyInstanceParam* params, sead::Heap* heap) {
if (params->isDynamicSensor())
params->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<CylinderWaterParam>(params);
auto* shape = v->shape.createShape(heap);
return shape->createBody(true, *params, heap);
CylinderWaterRigidBody* RigidBodyFactory::createCylinderWater(RigidBodyInstanceParam* params,
sead::Heap* heap) {
return createRigidBody<CylinderWaterRigidBody, CylinderWaterShape, CylinderParam>(params, heap);
}
BoxRigidBody* RigidBodyFactory::createBox(RigidBodyInstanceParam* params, sead::Heap* heap) {

View File

@ -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);