mirror of https://github.com/AxioDL/metaforce.git
144 lines
5.2 KiB
C++
144 lines
5.2 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include "Runtime/RetroTypes.hpp"
|
|
#include "Runtime/Character/CSegId.hpp"
|
|
|
|
#include <zeus/CAABox.hpp>
|
|
#include <zeus/CQuaternion.hpp>
|
|
#include <zeus/CVector3f.hpp>
|
|
|
|
namespace urde {
|
|
class CCharLayoutInfo;
|
|
class CHierarchyPoseBuilder;
|
|
class CModelData;
|
|
class CStateManager;
|
|
|
|
class CRagDoll {
|
|
protected:
|
|
class CRagDollParticle {
|
|
friend class CRagDoll;
|
|
CSegId x0_id;
|
|
zeus::CVector3f x4_curPos;
|
|
float x10_radius;
|
|
zeus::CVector3f x14_prevPos;
|
|
zeus::CVector3f x20_velocity;
|
|
zeus::CVector3f x2c_impactResponseDelta;
|
|
float x38_impactFrameVel = 0.f;
|
|
bool x3c_24_impactPending : 1;
|
|
bool x3c_25_ : 1;
|
|
|
|
public:
|
|
CRagDollParticle(CSegId id, const zeus::CVector3f& curPos, float radius, const zeus::CVector3f& prevPos)
|
|
: x0_id(id), x4_curPos(curPos), x10_radius(radius), x14_prevPos(prevPos) {
|
|
x3c_24_impactPending = false;
|
|
x3c_25_ = false;
|
|
}
|
|
CSegId GetBone() const { return x0_id; }
|
|
const zeus::CVector3f& GetPosition() const { return x4_curPos; }
|
|
zeus::CVector3f& Position() { return x4_curPos; }
|
|
const zeus::CVector3f& GetVelocity() const { return x20_velocity; }
|
|
zeus::CVector3f& Velocity() { return x20_velocity; }
|
|
float GetRadius() const { return x10_radius; }
|
|
};
|
|
class CRagDollLengthConstraint {
|
|
friend class CRagDoll;
|
|
CRagDollParticle* x0_p1;
|
|
CRagDollParticle* x4_p2;
|
|
float x8_length;
|
|
int xc_ineqType;
|
|
|
|
public:
|
|
CRagDollLengthConstraint(CRagDollParticle* p1, CRagDollParticle* p2, float f1, int i1)
|
|
: x0_p1(p1), x4_p2(p2), x8_length(f1), xc_ineqType(i1) {}
|
|
void Update();
|
|
float GetLength() const { return x8_length; }
|
|
};
|
|
class CRagDollJointConstraint {
|
|
friend class CRagDoll;
|
|
CRagDollParticle* x0_p1; // Shoulder plane 0
|
|
CRagDollParticle* x4_p2; // Shoulder plane 1
|
|
CRagDollParticle* x8_p3; // Shoulder plane 2
|
|
CRagDollParticle* xc_p4; // Shoulder
|
|
CRagDollParticle* x10_p5; // Elbow
|
|
CRagDollParticle* x14_p6; // Wrist
|
|
public:
|
|
CRagDollJointConstraint(CRagDollParticle* p1, CRagDollParticle* p2, CRagDollParticle* p3, CRagDollParticle* p4,
|
|
CRagDollParticle* p5, CRagDollParticle* p6)
|
|
: x0_p1(p1), x4_p2(p2), x8_p3(p3), xc_p4(p4), x10_p5(p5), x14_p6(p6) {}
|
|
void Update();
|
|
};
|
|
class CRagDollPlaneConstraint {
|
|
friend class CRagDoll;
|
|
CRagDollParticle* x0_p1;
|
|
CRagDollParticle* x4_p2;
|
|
CRagDollParticle* x8_p3;
|
|
CRagDollParticle* xc_p4;
|
|
CRagDollParticle* x10_p5;
|
|
|
|
public:
|
|
CRagDollPlaneConstraint(CRagDollParticle* p1, CRagDollParticle* p2, CRagDollParticle* p3, CRagDollParticle* p4,
|
|
CRagDollParticle* p5)
|
|
: x0_p1(p1), x4_p2(p2), x8_p3(p3), xc_p4(p4), x10_p5(p5) {}
|
|
void Update();
|
|
};
|
|
std::vector<CRagDollParticle> x4_particles;
|
|
std::vector<CRagDollLengthConstraint> x14_lengthConstraints;
|
|
std::vector<CRagDollJointConstraint> x24_jointConstraints;
|
|
std::vector<CRagDollPlaneConstraint> x34_planeConstraints;
|
|
float x44_normalGravity;
|
|
float x48_floatingGravity;
|
|
u32 x4c_impactCount = 0;
|
|
float x50_overTimer;
|
|
float x54_impactVel = 0.f;
|
|
zeus::CVector3f x58_averageVel;
|
|
float x64_angTimer = 0.f;
|
|
union {
|
|
struct {
|
|
bool x68_24_prevMovingSlowly : 1;
|
|
bool x68_25_over : 1;
|
|
bool x68_26_primed : 1;
|
|
bool x68_27_continueSmallMovements : 1;
|
|
bool x68_28_noOverTimer : 1;
|
|
bool x68_29_noAiCollision : 1;
|
|
};
|
|
u32 _dummy = 0;
|
|
};
|
|
void AccumulateForces(float dt, float waterTop);
|
|
void SetNumParticles(int num) { x4_particles.reserve(num); }
|
|
void AddParticle(CSegId id, const zeus::CVector3f& prevPos, const zeus::CVector3f& curPos, float radius);
|
|
void SetNumLengthConstraints(int num) { x14_lengthConstraints.reserve(num); }
|
|
void AddLengthConstraint(int i1, int i2);
|
|
void AddMaxLengthConstraint(int i1, int i2, float length);
|
|
void AddMinLengthConstraint(int i1, int i2, float length);
|
|
void SetNumJointConstraints(int num) { x24_jointConstraints.reserve(num); }
|
|
void AddJointConstraint(int i1, int i2, int i3, int i4, int i5, int i6);
|
|
zeus::CQuaternion BoneAlign(CHierarchyPoseBuilder& pb, const CCharLayoutInfo& charInfo, int i1, int i2,
|
|
const zeus::CQuaternion& q);
|
|
void CheckStatic(float dt);
|
|
void ClearForces();
|
|
void SatisfyConstraints(CStateManager& mgr);
|
|
bool SatisfyWorldConstraints(CStateManager& mgr, int pass);
|
|
void SatisfyWorldConstraintsOnConstruction(CStateManager& mgr);
|
|
void Verlet(float dt);
|
|
|
|
public:
|
|
virtual ~CRagDoll() = default;
|
|
CRagDoll(float normalGravity, float floatingGravity, float overTime, u32 flags);
|
|
|
|
virtual void PreRender(const zeus::CVector3f& v, CModelData& mData);
|
|
virtual void Update(CStateManager& mgr, float dt, float waterTop);
|
|
virtual void Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& mData);
|
|
|
|
zeus::CAABox CalculateRenderBounds() const;
|
|
bool IsPrimed() const { return x68_26_primed; }
|
|
bool WillContinueSmallMovements() const { return x68_27_continueSmallMovements; }
|
|
bool IsOver() const { return x68_25_over; }
|
|
void SetNoOverTimer(bool b) { x68_28_noOverTimer = b; }
|
|
void SetContinueSmallMovements(bool b) { x68_27_continueSmallMovements = b; }
|
|
u32 GetImpactCount() const { return x4c_impactCount; }
|
|
};
|
|
|
|
} // namespace urde
|