havok stubs and ksys::phys work

This commit is contained in:
theo3
2021-11-29 00:00:56 -08:00
parent e09eb09f66
commit 87e8bafae2
43 changed files with 1440 additions and 170 deletions
+20
View File
@@ -1,4 +1,6 @@
target_sources(uking PRIVATE
physInstanceSet.cpp
physInstanceSet.h
Cloth/physClothParam.cpp
Cloth/physClothParam.h
Ragdoll/physRagdollConfig.cpp
@@ -7,10 +9,26 @@ target_sources(uking PRIVATE
Ragdoll/physRagdollParam.h
RigidBody/physEdgeRigidBodyParam.cpp
RigidBody/physEdgeRigidBodyParam.h
RigidBody/physMotionAccessor.cpp
RigidBody/physMotionAccessor.h
RigidBody/physRigidBody.cpp
RigidBody/physRigidBody.h
RigidBody/physRigidBodyFactory.cpp
RigidBody/physRigidBodyFactory.h
RigidBody/physRigidBodyParam.cpp
RigidBody/physRigidBodyParam.h
RigidBody/physRigidBodySetParam.cpp
RigidBody/physRigidBodySetParam.h
RigidBody/Shape/physBoxShape.cpp
RigidBody/Shape/physBoxShape.h
RigidBody/Shape/physCapsuleShape.cpp
RigidBody/Shape/physCapsuleShape.h
RigidBody/Shape/physCylinderShape.cpp
RigidBody/Shape/physCylinderShape.h
RigidBody/Shape/physSphereShape.cpp
RigidBody/Shape/physSphereShape.h
RigidBody/Shape/physWaterCylinderShape.cpp
RigidBody/Shape/physWaterCylinderShape.h
SupportBone/physSupportBoneParam.cpp
SupportBone/physSupportBoneParam.h
SupportBone/physSupportBoneResource.cpp
@@ -28,6 +46,8 @@ target_sources(uking PRIVATE
System/physDefines.h
System/physMaterialTable.cpp
System/physMaterialTable.h
System/physMemSystem.cpp
System/physMemSystem.h
System/physParamSet.cpp
System/physParamSet.h
System/physRagdollControllerKeyList.h
@@ -0,0 +1,27 @@
#pragma once
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
namespace ksys::phys {
class BoxView;
struct BoxBody {
virtual ~BoxBody();
RigidBody* init(u32 flag, RigidBodyParamView* view, sead::Heap* heap);
};
struct BoxShape {
BoxBody* init(sead::Heap* heap);
};
class BoxView : public RigidBodyParamView {
SEAD_RTTI_OVERRIDE(BoxView, RigidBodyParamView)
public:
u8 _90;
float _94;
BoxShape shape;
};
} // namespace ksys::phys
@@ -0,0 +1,118 @@
#include "KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h"
#include <Havok/Physics/Collide/Shape/Convex/Capsule/hkpCapsuleShape.h>
#include <heap/seadHeap.h>
#include <math/seadMathCalcCommon.h>
namespace ksys::phys {
CapsuleBody* CapsuleShape::init(sead::Heap* heap) {
void* ptr = heap->tryAlloc(sizeof(hkpCapsuleShape), 0x10);
if (ptr == nullptr)
return nullptr;
auto* hk_shape =
new (ptr) hkpCapsuleShape(hkVector4(vertex_a.x, vertex_a.y, vertex_a.z),
hkVector4(vertex_b.x, vertex_b.y, vertex_b.z), radius);
auto* body = new (heap) CapsuleBody(vertex_a, vertex_b, radius, _20, _28, _30, _34, hk_shape);
if (_38) {
body->unk.shape_type = 1 << 23;
}
body->unk._10 = nullptr;
hk_shape->m_type = body->unk.shape_type;
return body;
}
CapsuleBody* CapsuleBody::clone(sead::Heap* heap) {
CapsuleShape shape;
shape._20 = 0;
shape._28 = sead::SafeString::cEmptyString.cstr();
shape._30 = 0;
shape._34 = 0;
shape._38 = false;
shape.radius = radius;
shape.vertex_a = vertex_a;
shape.vertex_b = vertex_b;
CapsuleBody* body = shape.init(heap);
body->unk.shape_type = unk.shape_type;
body->unk._10 = nullptr;
if (body->shape != nullptr)
body->shape->m_type = unk.shape_type;
return body;
}
f32 CapsuleBody::getRadius() const {
return radius;
}
void CapsuleBody::getVertices(sead::Vector3f* va, sead::Vector3f* vb) const {
if (va != nullptr)
*va = vertex_a;
if (vb != nullptr)
*vb = vertex_b;
}
CapsuleBody::~CapsuleBody() {
if (shape != nullptr) {
::operator delete(shape);
shape = nullptr;
}
}
bool CapsuleBody::setRadius(f32 r) {
if (r <= 0.0f || r == radius) {
return false;
}
radius = r;
flags.set(Flag::Modified);
return true;
}
bool CapsuleBody::setVertices(const sead::Vector3f& va, const sead::Vector3f& vb) {
if (vertex_a == va && vertex_b == vb) {
return false;
}
vertex_a = va;
vertex_b = vb;
flags.set(Flag::Modified);
return true;
}
f32 CapsuleBody::getVolume() const {
f32 dy = vertex_a.y - vertex_b.y;
f32 dx = vertex_a.x - vertex_b.x;
f32 dz = vertex_a.z - vertex_b.z;
f32 dist = sqrtf(dx * dx + dy * dy + dz * dz);
f32 pi_r_sq = radius * radius * sead::Mathf::pi();
f32 c = (radius * 4.0f) / 3.0f;
return pi_r_sq * (dist + c);
}
hkpShape* CapsuleBody::getShape() {
return shape;
}
const hkpShape* CapsuleBody::getShape() const {
return shape;
}
void CapsuleBody::sub_7100FABE80(sead::Vector3f* veca, sead::Vector3f* vecb,
const hkVector4& rb_vec) {
if (veca != nullptr) {
hkVector4 tmp;
tmp.sub_7100FABE80(rb_vec, hkVector4(vertex_a.x, vertex_a.y, vertex_a.z));
veca->x = tmp.v[0];
veca->y = tmp.v[1];
veca->z = tmp.v[2];
}
if (vecb != nullptr) {
hkVector4 tmp;
tmp.sub_7100FABE80(rb_vec, hkVector4(vertex_b.x, vertex_b.y, vertex_b.z));
vecb->x = tmp.v[0];
vecb->y = tmp.v[1];
vecb->z = tmp.v[2];
}
}
} // namespace ksys::phys
@@ -0,0 +1,78 @@
#pragma once
#include <math/seadVector.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
class hkpShape;
class hkVector4;
namespace ksys::phys {
class CapsuleView;
struct CapsuleShape;
struct CapsuleBody {
enum class Flag {
Modified = 1 << 0,
};
struct Unk {
Unk(u32 a1, const char* a2, u32 a3, u32 a4, u32 a5);
virtual ~Unk();
u32 shape_type = 0;
const char* _10;
};
CapsuleBody(const sead::Vector3f& va, const sead::Vector3f& vb, f32 r, u32 a4, const char* a5,
u32 a6, u32 a7, hkpShape* a8)
: vertex_a(va), vertex_b(vb), radius(r), unk(a4, a5, a6, a7, 0), shape(a8) {}
virtual ~CapsuleBody();
virtual hkpShape* getShape();
virtual const hkpShape* getShape() const;
virtual void updateChanges();
virtual void scaleVerts(f32 scale);
RigidBody* init(u32 flag, RigidBodyParamView* view, sead::Heap* heap);
CapsuleBody* clone(sead::Heap* heap);
f32 getRadius() const;
void getVertices(sead::Vector3f* va, sead::Vector3f* vb) const;
bool setRadius(f32 r);
bool setVertices(const sead::Vector3f& va, const sead::Vector3f& vb);
f32 getVolume() const;
void sub_7100FABE80(sead::Vector3f* veca, sead::Vector3f* vecb, const hkVector4& rb_vec);
sead::Vector3f vertex_a;
sead::TypedBitFlag<Flag, sead::Atomic<u32>> flags{};
sead::Vector3f vertex_b;
f32 radius;
Unk unk;
hkpShape* shape;
};
struct CapsuleShape {
CapsuleBody* init(sead::Heap* heap);
sead::Vector3f vertex_a;
sead::Vector3f vertex_b;
f32 radius;
u32 _1c;
u32 _20;
const char* _28;
u32 _30;
u32 _34;
bool _38;
};
class CapsuleView : public RigidBodyParamView {
SEAD_RTTI_OVERRIDE(CapsuleView, RigidBodyParamView)
public:
u8 _90;
float _94;
CapsuleShape shape;
};
} // namespace ksys::phys
@@ -0,0 +1,27 @@
#pragma once
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
namespace ksys::phys {
class CylinderView;
struct CylinderBody {
virtual ~CylinderBody();
RigidBody* init(u32 flag, RigidBodyParamView* view, sead::Heap* heap);
};
struct CylinderShape {
CylinderBody* init(sead::Heap* heap);
};
class CylinderView : public RigidBodyParamView {
SEAD_RTTI_OVERRIDE(CylinderView, RigidBodyParamView)
public:
u8 _90;
float _94;
CylinderShape shape;
};
} // namespace ksys::phys
@@ -0,0 +1,27 @@
#pragma once
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
namespace ksys::phys {
class SphereView;
struct SphereBody {
virtual ~SphereBody();
RigidBody* init(u32 flag, RigidBodyParamView* view, sead::Heap* heap);
};
struct SphereShape {
SphereBody* init(sead::Heap* heap);
};
class SphereView : public RigidBodyParamView {
SEAD_RTTI_OVERRIDE(SphereView, RigidBodyParamView)
public:
u8 _90;
float _94;
SphereShape shape;
};
} // namespace ksys::phys
@@ -0,0 +1,27 @@
#pragma once
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
namespace ksys::phys {
class WaterCylinderView;
struct WaterCylinderBody {
virtual ~WaterCylinderBody();
RigidBody* init(u32 flag, RigidBodyParamView* view, sead::Heap* heap);
};
struct WaterCylinderShape {
WaterCylinderBody* init(sead::Heap* heap);
};
class WaterCylinderView : public RigidBodyParamView {
SEAD_RTTI_OVERRIDE(WaterCylinderView, RigidBodyParamView)
public:
u8 _90;
float _94;
WaterCylinderShape shape;
};
} // namespace ksys::phys
@@ -0,0 +1,34 @@
#include "KingSystem/Physics/RigidBody/physMotionAccessor.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
namespace ksys::phys {
MotionAccessor::MotionAccessor(RigidBody* body) : mBody(body) {}
MotionAccessor::~MotionAccessor() = default;
MotionType MotionAccessor::getMotionInfo() const {
return mBody->getMotionInfo();
}
hkpMotion* MotionAccessor::getMotion() const {
return mBody->getMotion();
}
void MotionAccessor::setMotionFlag(RigidBody::MotionFlag flag) {
mBody->setMotionFlag(flag);
}
bool MotionAccessor::hasMotionSet(RigidBody::MotionFlag flag) const {
return mBody->getMotionFlags().isOn(flag);
}
bool MotionAccessor::hasMotionDisabled(RigidBody::MotionFlag flag) const {
return mBody->getMotionFlags().isOff(flag);
}
void MotionAccessor::disableMotionFlag(RigidBody::MotionFlag flag) {
mBody->resetMotionFlagDirect(flag);
}
} // namespace ksys::phys
@@ -0,0 +1,28 @@
#pragma once
#include <basis/seadTypes.h>
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
class hkpMotion;
namespace ksys::phys {
class MotionAccessor {
SEAD_RTTI_BASE(MotionAccessor)
public:
explicit MotionAccessor(RigidBody* body);
virtual ~MotionAccessor();
MotionType getMotionInfo() const;
hkpMotion* getMotion() const;
void setMotionFlag(RigidBody::MotionFlag flag);
bool hasMotionSet(RigidBody::MotionFlag flag) const;
bool hasMotionDisabled(RigidBody::MotionFlag flag) const;
void disableMotionFlag(RigidBody::MotionFlag flag);
private:
RigidBody* mBody;
void* _10 = nullptr;
};
} // namespace ksys::phys
@@ -0,0 +1,86 @@
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
#include <Havok/Physics/Dynamics/Entity/hkpRigidBody.h>
#include "KingSystem/Physics/System/physMemSystem.h"
namespace ksys::phys {
// NON_MATCHING
RigidBody::RigidBody(u32 a, u32 mass_scaling, hkpRigidBody* hk_body, const sead::SafeString& name,
sead::Heap* heap, bool a7)
: mHkBody(hk_body), mHkBodyMgr(hk_body), _b4(a) {
if (!name.isEmpty()) {
hk_body->setName(name.cstr());
}
hk_body->setUserData(this);
hk_body->m_motion._128 = nullptr;
hk_body->m_motion.m_motionState__m_timeFactor.setOne();
hk_body->enableDeactivation(true);
hk_body->_88 = 0.1f;
if (mFlags.isOn(Flag1::MassScaling)) {
hk_body->_132 |= 1;
}
mFlags.change(Flag1::_80, _b4 == 5);
mFlags.change(Flag1::MassScaling, mass_scaling);
mFlags.change(Flag1::_10, a7);
mFlags.set(Flag1::_100);
}
void RigidBody::setMotionFlag(MotionFlag flag) {
auto lock = sead::makeScopedLock(mCS);
mMotionFlags.set(flag);
if (mFlags.isOff(Flag1::_20) && mFlags.isOff(Flag1::_2)) {
mFlags.set(Flag1::_2);
MemSystem::instance()->_160->sub_7100FA6C8C(mFlags.isOn(Flag1::MassScaling), this);
}
}
bool RigidBody::sub_7100F8D1F8() const {
return mFlags.isOn(Flag1::_8);
}
bool RigidBody::sub_7100F8D204() const {
return mMotionFlags.isOn(MotionFlag::_1);
}
bool RigidBody::sub_7100F8D210() const {
return mMotionFlags.isOn(MotionFlag::_2);
}
// NON_MATCHING: mFlags is loaded differently
void RigidBody::sub_7100F8D21C() {
auto lock = sead::makeScopedLock(mCS);
if (mMotionFlags.isOn(MotionFlag::_1)) {
mMotionFlags.reset(MotionFlag::_1);
mMotionFlags.set(MotionFlag::_2);
} else if (mFlags.isOn(Flag1::_8)) {
setMotionFlag(MotionFlag::_2);
}
}
MotionType RigidBody::getMotionInfo() const {
if (mMotionFlags.isOn(MotionFlag::Dynamic))
return MotionType::Dynamic;
if (mMotionFlags.isOn(MotionFlag::Keyframed))
return MotionType::Keyframed;
if (mMotionFlags.isOn(MotionFlag::Fixed))
return MotionType::Fixed;
return mHkBodyMgr.getMotionInfo();
}
void RigidBody::setContactMask(u32 value) {
mContactMask.setDirect(value);
}
void RigidBody::setContactAll() {
mContactMask.makeAllOne();
}
void RigidBody::setContactNone() {
mContactMask.makeAllZero();
}
} // namespace ksys::phys
@@ -0,0 +1,106 @@
#pragma once
#include <container/seadPtrArray.h>
#include <heap/seadDisposer.h>
#include <prim/seadRuntimeTypeInfo.h>
#include <prim/seadTypedBitFlag.h>
#include <thread/seadAtomic.h>
#include <thread/seadCriticalSection.h>
#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h"
#include "KingSystem/Physics/System/physDefines.h"
#include "KingSystem/Utils/Types.h"
class hkpRigidBody;
class hkpMotion;
namespace ksys::phys {
class MotionAccessor;
class RigidBase {
public:
virtual ~RigidBase();
};
class RigidBody : public sead::IDisposer, public RigidBase {
SEAD_RTTI_BASE(RigidBody)
public:
struct HkBodyMgr {
explicit HkBodyMgr(hkpRigidBody* body);
virtual ~HkBodyMgr();
MotionType getMotionInfo() const;
void* p;
};
enum class Flag1 {
MassScaling = 1 << 0,
_2 = 1 << 1,
_4 = 1 << 2,
_8 = 1 << 3,
_10 = 1 << 4,
_20 = 1 << 5,
_40 = 1 << 6,
_80 = 1 << 7,
_100 = 1 << 8,
};
enum class MotionFlag {
_1 = 1 << 0,
_2 = 1 << 1,
Dynamic = 1 << 2,
Keyframed = 1 << 3,
Fixed = 1 << 4,
_20 = 1 << 5,
};
RigidBody(u32 a, u32 mass_scaling, hkpRigidBody* hk_body, const sead::SafeString& name,
sead::Heap* heap, bool a7);
virtual ~RigidBody();
void sub_7100F8CFA0();
void setMotionFlag(MotionFlag);
bool sub_7100F8D1F8() const;
bool sub_7100F8D204() const;
bool sub_7100F8D210() const;
void sub_7100F8D21C();
void sub_7100F8D680();
MotionType getMotionInfo() const;
u32 addContactLayer(ContactLayer);
u32 removeContactLayer(ContactLayer);
void setContactMask(u32);
void setContactAll();
void setContactNone();
void setCollideGround(bool);
void setCollideWater(bool);
void sub_7100F8F51C();
void sub_7100F8F8CC(ContactLayer, GroundHit, void*);
void sub_7100F8F9E8(u32*, void*);
void sub_7100F8FA44(ContactLayer, u32);
hkpMotion* getMotion() const;
bool isMassScaling() const { return mFlags.isOn(Flag1::MassScaling); }
const auto& getMotionFlags() const { return mMotionFlags; }
void resetMotionFlagDirect(const MotionFlag flag) { mMotionFlags.reset(flag); }
private:
sead::CriticalSection mCS;
sead::TypedBitFlag<Flag1, sead::Atomic<u32>> mFlags{};
sead::TypedBitFlag<MotionFlag, sead::Atomic<u32>> mMotionFlags{};
sead::BitFlag32 mContactMask{};
hkpRigidBody* mHkBody;
void* mActor = nullptr;
void* _88 = nullptr;
void* _90 = nullptr;
u16 _98 = 0;
HkBodyMgr mHkBodyMgr;
f32 _b0 = 0.0f;
u32 _b4;
MotionAccessor* mMotionAccessor = nullptr;
u16 _c0 = 0;
void* _c8 = nullptr;
void* _d0;
};
KSYS_CHECK_SIZE_NX150(RigidBody, 0xD8);
} // namespace ksys::phys
@@ -0,0 +1,56 @@
#include "KingSystem/Physics/RigidBody/physRigidBodyFactory.h"
#include "KingSystem/Physics/RigidBody/Shape/physBoxShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physCapsuleShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physCylinderShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physSphereShape.h"
#include "KingSystem/Physics/RigidBody/Shape/physWaterCylinderShape.h"
namespace ksys::phys {
RigidBody* RigidBodyFactory::createSphere(RigidBodyParamView* view, sead::Heap* heap) {
if (view->isDynamicSensor())
view->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<SphereView>(view);
SphereBody* body = v->shape.init(heap);
return body->init(1, view, heap);
}
RigidBody* RigidBodyFactory::createCapsule(RigidBodyParamView* view, sead::Heap* heap) {
if (view->isDynamicSensor())
view->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<CapsuleView>(view);
CapsuleBody* body = v->shape.init(heap);
return body->init(1, view, heap);
}
RigidBody* RigidBodyFactory::createCylinder(RigidBodyParamView* view, sead::Heap* heap) {
if (view->isDynamicSensor())
view->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<CylinderView>(view);
CylinderBody* body = v->shape.init(heap);
return body->init(1, view, heap);
}
RigidBody* RigidBodyFactory::createWaterCylinder(RigidBodyParamView* view, sead::Heap* heap) {
if (view->isDynamicSensor())
view->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<WaterCylinderView>(view);
WaterCylinderBody* body = v->shape.init(heap);
return body->init(1, view, heap);
}
RigidBody* RigidBodyFactory::createBox(RigidBodyParamView* view, sead::Heap* heap) {
if (view->isDynamicSensor())
view->motion_type = MotionType::Keyframed;
auto* v = sead::DynamicCast<BoxView>(view);
BoxBody* body = v->shape.init(heap);
return body->init(1, view, heap);
}
} // namespace ksys::phys
@@ -0,0 +1,26 @@
#pragma once
#include <basis/seadTypes.h>
namespace sead {
class Heap;
} // namespace sead
namespace ksys::phys {
class RigidBody;
struct RigidBodyParamView;
class RigidBodyFactory {
public:
static RigidBody* createSphere(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createCapsule(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createCylinder(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createWaterCylinder(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createBox(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createWaterBox(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createPolytope(RigidBodyParamView* view, sead::Heap* heap);
static RigidBody* createCollection(RigidBodyParamView* view, sead::Heap* heap);
};
} // namespace ksys::phys
@@ -49,37 +49,42 @@ struct ShapeParam;
struct RigidBodyParamView {
SEAD_RTTI_BASE(RigidBodyParamView)
public:
const char* name;
u32 _10;
MotionType motion_type;
float mass;
sead::Vector3f inertia;
sead::Vector3f center_of_mass;
float linear_damping;
float angular_damping;
u8 _3c[8];
float max_linear_velocity;
float max_angular_velocity_rad;
float max_impulse;
float col_impulse_scale;
float friction_scale;
float restitution_scale;
float water_buoyancy_scale;
float water_flow_effective_rate;
float magne_mass_scaling_factor;
bool gap68;
bool toi;
bool always_character_mass_scaling;
bool gap6B[13];
ContactLayer contact_layer;
GroundHit groundhit;
u32 info_5e0;
u32 contact_mask;
u32 flags;
bool ignore_normal_for_impulse;
bool no_hit_ground;
bool no_hit_water;
bool no_char_standing_on;
const char* name = "no name";
u32 _10 = -1;
MotionType motion_type = MotionType::Dynamic;
float mass = 1.0f;
sead::Vector3f inertia = sead::Vector3f::ones;
sead::Vector3f center_of_mass = sead::Vector3f::zero;
float linear_damping = 0.0f;
float angular_damping = 0.05f;
f32 _3c = 1.0f;
f32 _40 = 1.0f;
float max_linear_velocity = 200.0f;
float max_angular_velocity_rad = 200.0f;
float max_impulse = -1.0f;
float col_impulse_scale = 1.0f;
float friction_scale = 1.0f;
float restitution_scale = 1.0f;
float water_buoyancy_scale = 1.0f;
float water_flow_effective_rate = 1.0f;
float magne_mass_scaling_factor = 1.0f;
bool gap68 = true;
bool toi = false;
bool always_character_mass_scaling = false;
void* p = nullptr;
ContactLayer contact_layer = ContactLayer::EntityObject;
GroundHit groundhit = GroundHit::HitAll;
u32 info_5e0 = 0;
u32 contact_mask = 0;
u32 flags = 0x80000000;
bool ignore_normal_for_impulse = false;
bool no_hit_ground = false;
bool no_hit_water = false;
bool no_char_standing_on = false;
bool isDynamicSensor() const {
return isSensorLayer(contact_layer) == 1 && motion_type == MotionType::Dynamic;
}
};
KSYS_CHECK_SIZE_NX150(RigidBodyParamView, 0x90);
@@ -2,7 +2,7 @@
namespace ksys::phys {
bool isSensorLayer(ContactLayer layer) {
u32 isSensorLayer(ContactLayer layer) {
return layer > ContactLayer::EntityEnd;
}
+1 -1
View File
@@ -164,7 +164,7 @@ enum class MotionType {
Unknown = 3,
};
bool isSensorLayer(ContactLayer layer);
u32 isSensorLayer(ContactLayer layer);
u32 makeContactLayerMask(ContactLayer layer);
u32 getContactLayerBase(ContactLayerType type);
u32 getContactLayerBaseRelativeValue(ContactLayer layer);
@@ -0,0 +1,21 @@
#pragma once
#include <basis/seadTypes.h>
#include <heap/seadDisposer.h>
namespace ksys::phys {
class RigidBody;
class MemSystem {
SEAD_SINGLETON_DISPOSER(MemSystem)
public:
struct Struct160 {
void sub_7100FA6C8C(bool, RigidBody*);
};
u8 _20[0x140];
Struct160* _160;
};
} // namespace ksys::phys
+211
View File
@@ -0,0 +1,211 @@
#include "KingSystem/Physics/physInstanceSet.h"
namespace ksys::phys {
void InstanceSet::setFlag2() {
mFlags.set(Flag::_2);
if (_d8 != nullptr) {
mFlags.set(Flag::_2);
mFlags.set(Flag::DisableDraw);
}
}
void InstanceSet::clothVisibleStuff() {
if (_d8 != nullptr) {
mFlags.set(Flag::DisableDraw);
}
}
void InstanceSet::setInDemo() {
mFlags.set(Flag::InDemo);
}
void InstanceSet::resetInDemo() {
mFlags.reset(Flag::InDemo);
}
void InstanceSet::clothVisibleStuff_0(s32 setting) {
if (mFlags.isOn(Flag::InDemo))
return;
switch (setting) {
case -2:
mFlags.reset(Flag::Cloth2);
mFlags.set(Flag::Cloth1);
break;
case -1:
mFlags.reset(Flag::Cloth3);
mFlags.reset(Flag::Cloth2);
mFlags.reset(Flag::Cloth1);
mFlags.set(Flag::Cloth2);
mFlags.set(Flag::Cloth3);
break;
case 0:
mFlags.reset(Flag::Cloth1);
mFlags.reset(Flag::Cloth2);
mFlags.set(Flag::Cloth3);
break;
case 1:
mFlags.reset(Flag::Cloth1);
mFlags.reset(Flag::Cloth2);
mFlags.reset(Flag::Cloth3);
break;
}
}
void InstanceSet::sub_7100FB9BAC(InstanceSet* other) {
if (other == nullptr)
return;
u32 idx = other->sub_7100FB9C2C();
clothVisibleStuff_0(idx);
}
u32 InstanceSet::sub_7100FB9C2C() const {
u32 idx;
if (mFlags.isOn(Flag::Cloth1)) {
idx = -2;
} else if (mFlags.isOn(Flag::Cloth2)) {
idx = -1;
} else if (mFlags.isOn(Flag::Cloth3)) {
idx = 0;
} else {
idx = 1;
}
return idx;
}
void InstanceSet::sub_7100FBA9BC() {
for (auto& rb : mRigidBodySets) {
rb.sub_7100FA97FC();
}
for (auto& body : mList) {
body->sub_7100F8CFA0();
}
if (mCollisionController != nullptr)
mCollisionController->sub_7100F5EC30();
}
void InstanceSet::sub_7100FBACE0(phys::ContactLayer layer) {
bool sensor = phys::isSensorLayer(layer);
for (auto& rb : mRigidBodySets) {
rb.disableCollisionMaybe(layer);
}
if (sensor)
return;
if (mRagdollController != nullptr)
mRagdollController->sub_7101221728(layer);
if (mCollisionController != nullptr)
mCollisionController->enableCollisionMaybe_0(layer);
}
void InstanceSet::sub_7100FBAD74() {
for (auto& rb : mRigidBodySets) {
rb.disableAllContact();
}
if (mRagdollController != nullptr) {
mRagdollController->sub_71012217A8();
}
if (mCollisionController != nullptr) {
mCollisionController->sub_7100F60604();
}
}
void* InstanceSet::sub_7100FBAEDC(s32 idx1, s32 idx2) const {
if (mRigidBodySets.size() <= idx1)
return nullptr;
return mRigidBodySets[idx1]->getRigidBody(idx2);
}
// NON_MATCHING
void InstanceSet::sub_7100FBB00C(phys::RigidBody* body, phys::RigidBodyParam* param) {
if (body == nullptr)
return;
phys::RigidBodyParamView view;
param->getParams(&view);
if (view.contact_layer == phys::ContactLayer::SensorCustomReceiver) {
body->sub_7100F8F9E8(&view.flags, _188[body->isMassScaling()]);
} else if (view.info_5e0) {
body->sub_7100F8FA44(view.contact_layer, view.info_5e0);
} else {
body->sub_7100F8F8CC(view.contact_layer, view.groundhit, _188[body->isMassScaling()]);
}
body->setCollideGround(view.no_hit_ground == 0);
body->setCollideWater(view.no_hit_water == 0);
body->sub_7100F8F51C();
}
void* InstanceSet::sub_7100FBBC28(const sead::SafeString& name) const {
for (auto& rb : mRigidBodySets) {
void* p = rb.findXByName(name);
if (p != nullptr)
return p;
}
return nullptr;
}
s32 InstanceSet::sub_7100FBBC78(const sead::SafeString& name) const {
s32 idx = 0;
for (auto& info : mContactInfos) {
if (name == info.mName)
return idx;
idx++;
}
return -1;
}
s32 InstanceSet::sub_7100FBBD9C(const sead::SafeString& name) const {
s32 idx = 0;
for (auto& info : mCollisionInfos) {
if (name == info.mName)
return idx;
idx++;
}
return -1;
}
void InstanceSet::sub_7100FBD284(const sead::Matrix34f& mtx) {
if (mFlags.isOff(Flag::_1))
return;
if (mFlags.isOn(Flag::_80000000)) {
sub_7100FBC890(mtx, true, false);
} else {
mFlags.reset(Flag::_8);
if (mFlags.isOn(Flag::_2))
setMtxAndScale(mtx, false, false, mScale);
}
mFlags.reset(Flag::_80000000);
if (mRagdollController == nullptr)
return;
if (mRagdollController->sub_7101221CC4() == 0)
sub_7100FBC890(mtx, false, false);
}
s32 InstanceSet::sub_7100FBDA2C(const sead::SafeString& name) const {
if (mRagdollBlendWt == nullptr)
return -1;
s32 idx = mRagdollBlendWt->findStateIdx(name);
if (idx >= 0)
return idx + 2;
if (name == "full_dynamic") {
return 1;
}
if (name == "full_key_framed") {
return 0;
}
return -1;
}
} // namespace ksys::phys
+124
View File
@@ -0,0 +1,124 @@
#pragma once
#include <container/seadListImpl.h>
#include <container/seadPtrArray.h>
#include <hostio/seadHostIONode.h>
#include "KingSystem/ActorSystem/actActor.h"
#include "KingSystem/Physics/RigidBody/physRigidBody.h"
#include "KingSystem/Physics/RigidBody/physRigidBodyParam.h"
namespace ksys::res {
class RagdollBlendWeight {
public:
s32 findStateIdx(const sead::SafeString& name) const;
};
} // namespace ksys::res
namespace ksys::phys {
class Ragdoll {};
class RagdollController {
public:
u32 sub_7101221CC4();
void sub_7101221728(ContactLayer);
void sub_71012217A8();
};
class CollisionController {
public:
void sub_7100F5EC30();
void sub_7100F60604();
void enableCollisionMaybe_0(ContactLayer);
};
struct CollisionInfo {
u8 filler[0x50];
sead::SafeString mName;
};
struct ContactInfo {
u8 filler[0x8];
sead::SafeString mName;
};
class RigidBodySet {
public:
void disableAllContact();
void sub_7100FA97FC();
void disableCollisionMaybe(ContactLayer);
void* findXByName(const sead::SafeString& name) const;
RigidBody* getRigidBody() const { return mBodies[0]; }
RigidBody* getRigidBody(s32 idx) const { return mBodies[idx]; }
private:
u8 _0[0x18];
sead::PtrArray<RigidBody> mBodies;
};
class InstanceSet : public sead::hostio::Node {
public:
enum class Flag : u32 {
_1 = 1 << 0,
_2 = 1 << 1,
_8 = 1 << 3,
DisableDraw = 1 << 2,
_200000 = 1 << 21,
Cloth1 = 1 << 22,
Cloth2 = 1 << 23,
Cloth3 = 1 << 24,
InDemo = 1 << 25,
_80000000 = 1u << 31,
};
void setFlag2();
void clothVisibleStuff();
void setInDemo();
void resetInDemo();
void clothVisibleStuff_0(s32 setting);
void sub_7100FB9BAC(InstanceSet* other);
u32 sub_7100FB9C2C() const;
void sub_7100FBA9BC();
void sub_7100FBACE0(ContactLayer layer);
void sub_7100FBAD74();
void* sub_7100FBAEDC(s32 rigidbody_idx, s32 ragdoll_idx) const;
void sub_7100FBB00C(RigidBody* body, RigidBodyParam* param);
void setMtxAndScale(const sead::Matrix34f& mtx, bool a2, bool a3, f32 scale);
void sub_7100FBB4B4();
void* findX(const sead::SafeString& a1, const sead::SafeString& a2) const;
void* sub_7100FBBC28(const sead::SafeString& name) const;
s32 sub_7100FBBC78(const sead::SafeString& name) const;
s32 sub_7100FBBD9C(const sead::SafeString& name) const;
void sub_7100FBD284(const sead::Matrix34f& mtx);
void sub_7100FBC890(const sead::Matrix34f& mtx, bool a2, bool a3);
s32 sub_7100FBDA2C(const sead::SafeString& name) const;
private:
u8 _8[0x18];
sead::TypedBitFlag<Flag> mFlags;
void* _28;
f32 mScale;
u8 _34[0x40 - 0x34];
sead::PtrArray<RigidBodySet> mRigidBodySets;
sead::PtrArray<CollisionInfo> mCollisionInfos;
sead::PtrArray<ContactInfo> mContactInfos;
u8 _70[0x10];
CollisionController* mCollisionController;
u8 _88[8];
RagdollController* mRagdollController;
u8 _98[0xb8 - 0x98];
res::RagdollBlendWeight* mRagdollBlendWt;
u8 _c0[0xd8 - 0xc0];
void* _d8;
u8 _e0[0x148 - 0xe0];
sead::TList<RigidBody*> mList;
u8 _160[0x188 - 0x160];
void* _188[2];
};
KSYS_CHECK_SIZE_NX150(InstanceSet, 0x198);
} // namespace ksys::phys