ksys/phys: Implement CylinderShape

This commit is contained in:
Léo Lam 2022-02-03 12:18:20 +01:00
parent a2fa63495c
commit 7c25fd08eb
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
9 changed files with 218 additions and 35 deletions

View File

@ -83624,23 +83624,23 @@ Address,Quality,Size,Name
0x0000007100fad7e4,U,000204,
0x0000007100fad8b0,U,000092,
0x0000007100fad90c,U,000008,
0x0000007100fad914,U,000344,
0x0000007100fada8c,U,000064,
0x0000007100fadacc,U,000072,
0x0000007100fadb14,U,000052,
0x0000007100fadb48,U,000192,
0x0000007100fadc08,U,000192,
0x0000007100fadcc8,U,000008,
0x0000007100fadcd0,U,000052,
0x0000007100fadd04,U,000120,
0x0000007100fadd7c,U,000008,
0x0000007100fadd84,U,000008,
0x0000007100fadd8c,U,000264,
0x0000007100fade94,U,000148,
0x0000007100fadf28,U,000184,
0x0000007100fadfe0,U,000204,
0x0000007100fae0ac,U,000092,
0x0000007100fae108,U,000008,
0x0000007100fad914,O,000344,_ZN4ksys4phys13CylinderShape4makeERKNS0_18CylinderShapeParamEPN4sead4HeapE
0x0000007100fada8c,O,000064,_ZN4ksys4phys13CylinderShapeD1Ev
0x0000007100fadacc,O,000072,_ZN4ksys4phys13CylinderShapeD0Ev
0x0000007100fadb14,O,000052,_ZN4ksys4phys13CylinderShape9setRadiusEf
0x0000007100fadb48,O,000192,_ZN4ksys4phys13CylinderShape11setVerticesERKN4sead7Vector3IfEES6_
0x0000007100fadc08,O,000192,_ZNK4ksys4phys13CylinderShape5cloneEPN4sead4HeapE
0x0000007100fadcc8,O,000008,_ZNK4ksys4phys13CylinderShape9getRadiusEv
0x0000007100fadcd0,O,000052,_ZN4ksys4phys13CylinderShape11getVerticesEPN4sead7Vector3IfEES5_
0x0000007100fadd04,O,000120,_ZNK4ksys4phys13CylinderShape9getVolumeEv
0x0000007100fadd7c,O,000008,_ZN4ksys4phys13CylinderShape13getHavokShapeEv
0x0000007100fadd84,O,000008,_ZNK4ksys4phys13CylinderShape13getHavokShapeEv
0x0000007100fadd8c,O,000264,_ZN4ksys4phys13CylinderShape16updateHavokShapeEv
0x0000007100fade94,O,000148,_ZN4ksys4phys13CylinderShape8setScaleEf
0x0000007100fadf28,O,000184,_ZN4ksys4phys13CylinderShape17transformVerticesEPN4sead7Vector3IfEES5_RK12hkTransformf
0x0000007100fadfe0,O,000204,_ZNK4ksys4phys13CylinderShape27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007100fae0ac,O,000092,_ZNK4ksys4phys13CylinderShape18getRuntimeTypeInfoEv
0x0000007100fae108,O,000008,_ZNK4ksys4phys13CylinderShape7getTypeEv
0x0000007100fae110,U,000288,
0x0000007100fae230,U,000032,
0x0000007100fae250,U,000064,

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

View File

@ -54,6 +54,8 @@ target_sources(uking PRIVATE
RigidBody/Shape/physCapsuleShape.h
RigidBody/Shape/physCharacterPrismShape.cpp
RigidBody/Shape/physCharacterPrismShape.h
RigidBody/Shape/physCylinderRigidBody.cpp
RigidBody/Shape/physCylinderRigidBody.h
RigidBody/Shape/physCylinderShape.cpp
RigidBody/Shape/physCylinderShape.h
RigidBody/Shape/physCylinderWaterShape.cpp

View File

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

View File

@ -0,0 +1,12 @@
#pragma once
#include "KingSystem/Physics/RigidBody/physRigidBodyFromShape.h"
namespace ksys::phys {
// TODO
class CylinderRigidBody : public RigidBodyFromShape {
SEAD_RTTI_OVERRIDE(CylinderRigidBody, RigidBodyFromShape)
};
} // namespace ksys::phys

View File

@ -0,0 +1,125 @@
#include "KingSystem/Physics/RigidBody/Shape/physCylinderShape.h"
#include <Havok/Physics2012/Collide/Shape/Convex/Cylinder/hkpCylinderShape.h>
#include "KingSystem/Physics/physConversions.h"
#include "KingSystem/Utils/HeapUtil.h"
#include "KingSystem/Utils/SafeDelete.h"
namespace ksys::phys {
CylinderShape* CylinderShape::make(const CylinderShapeParam& param, sead::Heap* heap) {
void* storage = util::allocStorage<hkpCylinderShape>(heap);
if (!storage)
return nullptr;
auto* hk_shape = new (storage)
hkpCylinderShape(toHkVec4(param.vertex_a), toHkVec4(param.vertex_b), param.radius);
return new (heap) CylinderShape(param, hk_shape);
}
CylinderShape::CylinderShape(const CylinderShapeParam& param, hkpCylinderShape* hk_shape)
: mVertexA(param.vertex_a), mVertexB(param.vertex_b), mRadius(param.radius),
mMaterialMask(param.common.getMaterialMask()), mHavokShape(hk_shape) {
if (param.common.item_code_disable_stick)
mMaterialMask.getData().setCustomFlag(MaterialMaskData::CustomFlag::_0);
setMaterialMask(mMaterialMask);
}
CylinderShape::~CylinderShape() {
util::deallocateObjectUnsafe(mHavokShape);
}
void CylinderShape::setMaterialMask(const MaterialMask& mask) {
mMaterialMask = mask;
if (mHavokShape)
mHavokShape->setUserData(mask.getRawData());
}
bool CylinderShape::setRadius(float radius) {
if (mRadius == radius)
return false;
mRadius = radius;
mFlags.set(Flag::Dirty);
return true;
}
bool CylinderShape::setVertices(const sead::Vector3f& va, const sead::Vector3f& vb) {
if (mVertexA == va && mVertexB == vb)
return false;
mVertexA = va;
mVertexB = vb;
mFlags.set(Flag::Dirty);
return true;
}
CylinderShape* CylinderShape::clone(sead::Heap* heap) const {
CylinderShapeParam param;
param.radius = mRadius;
param.vertex_a = mVertexA;
param.vertex_b = mVertexB;
auto* cloned = make(param, heap);
cloned->setMaterialMask(mMaterialMask);
return cloned;
}
float CylinderShape::getRadius() const {
return mRadius;
}
void CylinderShape::getVertices(sead::Vector3f* va, sead::Vector3f* vb) {
*va = mVertexA;
*vb = mVertexB;
}
float CylinderShape::getVolume() const {
const auto height = (mVertexA - mVertexB).length();
return height * (sead::Mathf::pi() * mRadius * mRadius);
}
hkpShape* CylinderShape::getHavokShape() {
return mHavokShape;
}
const hkpShape* CylinderShape::getHavokShape() const {
return mHavokShape;
}
const hkpShape* CylinderShape::updateHavokShape() {
if (!mFlags.isOn(Flag::Dirty))
return nullptr;
const auto ref_count = mHavokShape->getReferenceCount();
mHavokShape =
new (mHavokShape) hkpCylinderShape(toHkVec4(mVertexA), toHkVec4(mVertexB), mRadius);
mHavokShape->setReferenceCount(ref_count);
setMaterialMask(mMaterialMask);
mFlags.reset(Flag::Dirty);
return nullptr;
}
void CylinderShape::setScale(float scale) {
setRadius(mRadius * scale);
sead::Vector3f va, vb;
getVertices(&va, &vb);
setVertices(va * scale, vb * scale);
}
void CylinderShape::transformVertices(sead::Vector3f* va, sead::Vector3f* vb,
const hkTransformf& transform) {
hkVector4f vertex;
vertex.setTransformedPos(transform, toHkVec4(mVertexA));
storeToVec3(va, vertex);
vertex.setTransformedPos(transform, toHkVec4(mVertexB));
storeToVec3(vb, vertex);
}
} // namespace ksys::phys

View File

@ -1,27 +1,72 @@
#pragma once
#include <math/seadVector.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#include "KingSystem/Physics/RigidBody/Shape/physShape.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h"
#include "KingSystem/Physics/System/physMaterialMask.h"
class hkTransformf;
class hkpCylinderShape;
namespace ksys::phys {
class CylinderParam;
struct CylinderShapeParam;
struct CylinderShape {
virtual ~CylinderShape();
class CylinderShape : public Shape {
SEAD_RTTI_OVERRIDE(CylinderShape, Shape)
public:
enum class Flag {
Dirty = 1 << 0,
};
RigidBody* createBody(bool flag, const RigidBodyInstanceParam& params, sead::Heap* heap);
static CylinderShape* make(const CylinderShapeParam& param, sead::Heap* heap);
CylinderShape(const CylinderShapeParam& param, hkpCylinderShape* hk_shape);
~CylinderShape() override;
const MaterialMask& getMaterialMask() const { return mMaterialMask; }
void setMaterialMask(const MaterialMask& mask);
float getRadius() const;
bool setRadius(float radius);
void getVertices(sead::Vector3f* va, sead::Vector3f* vb);
bool setVertices(const sead::Vector3f& va, const sead::Vector3f& vb);
CylinderShape* clone(sead::Heap* heap) const;
ShapeType getType() const override { return ShapeType::Cylinder; }
float getVolume() const override;
hkpShape* getHavokShape() override;
const hkpShape* getHavokShape() const override;
const hkpShape* updateHavokShape() override;
void setScale(float scale) override;
void transformVertices(sead::Vector3f* va, sead::Vector3f* vb, const hkTransformf& transform);
private:
sead::Vector3f mVertexA;
sead::TypedBitFlag<Flag, sead::Atomic<u32>> mFlags;
sead::Vector3f mVertexB;
float mRadius;
MaterialMask mMaterialMask;
hkpCylinderShape* mHavokShape;
};
struct CylinderShapeParam {
CylinderShape* createShape(sead::Heap* heap);
sead::Vector3f translate_0;
/// The center of the first circular base.
sead::Vector3f vertex_a;
/// The radius of the circular bases.
float radius;
sead::Vector3f translate_1;
float convex_radius;
/// The center of the second circular base.
sead::Vector3f vertex_b;
/// Additional shell radius around the cylinder.
/// @warning This is ignored by CylinderShape.
float convex_radius = 0.05;
CommonShapeParam common;
};

View File

@ -84,8 +84,8 @@ void ShapeParamObj::getCapsule(CapsuleShapeParam* param) const {
void ShapeParamObj::getCylinder(CylinderShapeParam* param) const {
param->radius = *radius;
param->convex_radius = *convex_radius;
param->translate_0 = *translate_0;
param->translate_1 = *translate_1;
param->vertex_a = *translate_0;
param->vertex_b = *translate_1;
getCommon(&param->common);
}

View File

@ -3,6 +3,7 @@
#include "KingSystem/Physics/RigidBody/Shape/physBoxWaterShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physCapsuleRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physCylinderRigidBody.h"
#include "KingSystem/Physics/RigidBody/Shape/physCylinderShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physCylinderWaterShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physSphereShape.h"
@ -34,13 +35,9 @@ CapsuleRigidBody* RigidBodyFactory::createCapsule(RigidBodyInstanceParam* params
return createRigidBody<CapsuleRigidBody, CapsuleShape, CapsuleParam>(params, heap);
}
RigidBody* RigidBodyFactory::createCylinder(RigidBodyInstanceParam* params, sead::Heap* heap) {
if (params->isDynamicSensor())
params->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<CylinderParam>(params);
auto* shape = v->shape.createShape(heap);
return shape->createBody(true, *params, heap);
CylinderRigidBody* RigidBodyFactory::createCylinder(RigidBodyInstanceParam* params,
sead::Heap* heap) {
return createRigidBody<CylinderRigidBody, CylinderShape, CylinderParam>(params, heap);
}
RigidBody* RigidBodyFactory::createCylinderWater(RigidBodyInstanceParam* params, sead::Heap* heap) {

View File

@ -11,6 +11,7 @@ namespace ksys::phys {
class BoxRigidBody;
class BoxWaterRigidBody;
class CapsuleRigidBody;
class CylinderRigidBody;
class RigidBody;
struct RigidBodyInstanceParam;
@ -18,7 +19,7 @@ class RigidBodyFactory {
public:
static RigidBody* createSphere(RigidBodyInstanceParam* params, sead::Heap* heap);
static CapsuleRigidBody* createCapsule(RigidBodyInstanceParam* params, sead::Heap* heap);
static RigidBody* createCylinder(RigidBodyInstanceParam* params, sead::Heap* heap);
static CylinderRigidBody* createCylinder(RigidBodyInstanceParam* params, sead::Heap* heap);
static RigidBody* createCylinderWater(RigidBodyInstanceParam* params, sead::Heap* heap);
static BoxRigidBody* createBox(RigidBodyInstanceParam* params, sead::Heap* heap);
static BoxWaterRigidBody* createBoxWater(RigidBodyInstanceParam* params, sead::Heap* heap);