ksys/phys: Implement the rest of the easy RagdollController functions

This commit is contained in:
Léo Lam 2022-12-19 00:24:04 +01:00
parent 50464f7435
commit b4e6a4dac9
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
4 changed files with 170 additions and 22 deletions

View File

@ -93626,14 +93626,14 @@ Address,Quality,Size,Name
0x000000710122224c,O,000156,_ZNK4ksys4phys17RagdollController21getChildBoneRigidBodyEPKNS0_9RigidBodyEi
0x00000071012222e8,U,001268,
0x00000071012227dc,U,001844,
0x0000007101222f10,U,000340,
0x0000007101223064,U,000012,
0x0000007101223070,U,000044,
0x000000710122309c,U,000176,
0x000000710122314c,U,000228,
0x0000007101223230,U,000032,
0x0000007101223250,U,000208,
0x0000007101223320,U,000536,
0x0000007101222f10,O,000340,_ZNK4ksys4phys17RagdollController24getConstraintIndexByNameERKN4sead14SafeStringBaseIcEE
0x0000007101223064,O,000012,_ZNK4ksys4phys17RagdollController17getNumConstraintsEv
0x0000007101223070,O,000044,_ZN4ksys4phys17RagdollController16enableConstraintEib
0x000000710122309c,O,000176,_ZN4ksys4phys17RagdollController15setContactLayerENS0_12ContactLayerE
0x000000710122314c,O,000228,_ZN4ksys4phys17RagdollController12setKeyframedEibNS1_14SyncToThisBoneE
0x0000007101223230,m,000032,_ZN4ksys4phys17RagdollController7setUnk1Eh
0x0000007101223250,O,000208,_ZN4ksys4phys17RagdollController21stopForcingKeyframingEv
0x0000007101223320,O,000536,_ZN4ksys4phys17RagdollController6updateEv
0x0000007101223538,O,000440,_ZN4ksys4phys12RagdollParamC1Ev
0x00000071012236f0,O,000044,_ZN4ksys4phys12RagdollParamD1Ev
0x000000710122371c,O,000004,_ZN4ksys4phys12RagdollParamD0Ev

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

View File

@ -26,14 +26,11 @@
namespace ksys::phys {
static u8 sUnk1 = 15;
void RagdollController::setUnk1(u8 value) {
sUnk1 = value;
}
static u8 sRagdollCtrlUnk1 = 15;
static RagdollController::Config sRagdollCtrlConfig;
RagdollController::RagdollController(SystemGroupHandler* handler)
: mGroupHandler(handler), _e8(sUnk1), _e9(sUnk1) {}
: mGroupHandler(handler), _e8(sRagdollCtrlUnk1), _e9(sRagdollCtrlUnk1) {}
RagdollController::~RagdollController() {
finalize();
@ -471,6 +468,128 @@ RagdollRigidBody* RagdollController::getChildBoneRigidBody(const RigidBody* body
return sead::DynamicCast<const RagdollRigidBody>(body)->getChildBodies_()[index];
}
int RagdollController::getConstraintIndexByName(const sead::SafeString& name) const {
for (int i = 0, n = getNumConstraints(); i < n; ++i) {
if (name == mRagdollInstance->m_constraints[i]->getName())
return i;
}
return -1;
}
int RagdollController::getNumConstraints() const {
return mRagdollInstance->m_constraints.size();
}
void RagdollController::enableConstraint(int index, bool enable) {
mDisabledConstraints.changeBit(index, !enable);
}
bool RagdollController::isConstraintEnabled(int index) const {
return mDisabledConstraints.isOffBit(index);
}
void RagdollController::setContactLayer(ContactLayer layer) {
if (mContactLayer.value() == layer)
return;
if (mFlags.isOn(Flag::_10)) {
for (int bone = 0, num_bones = mBoneRigidBodies.size(); bone < num_bones; ++bone) {
if (mKeyframedBones.isOffBit(bone))
mBoneRigidBodies[bone]->setContactLayer(layer);
}
}
mContactLayer = layer;
}
void RagdollController::setKeyframed(int bone_index, bool keyframed,
SyncToThisBone sync_to_this_bone) {
mKeyframedBones.changeBit(bone_index, keyframed);
if (keyframed) {
mBoneRigidBodies[bone_index]->setContactLayer(ContactLayer::EntityNoHit);
mBoneRigidBodies[bone_index]->changeMotionType(MotionType::Keyframed);
} else {
mBoneRigidBodies[bone_index]->setContactLayer(mContactLayer);
mBoneRigidBodies[bone_index]->changeMotionType(MotionType::Dynamic);
}
mKeyframedBonesToSyncTo.changeBit(bone_index, keyframed && bool(sync_to_this_bone));
}
// NON_MATCHING: swapped csel operands
void RagdollController::setUnk1(u8 value) {
value = sead::Mathi::min(value, sRagdollCtrlUnk1);
_e9 = value;
_e8 = value;
}
void RagdollController::setMaximumUnk1(u8 value) {
sRagdollCtrlUnk1 = value;
}
void RagdollController::stopForcingKeyframing() {
if (mFlags.isOn(Flag::_10)) {
for (int i = 0, n = mBoneRigidBodies.size(); i < n; ++i) {
setKeyframed(i, false, {});
}
} else {
mKeyframedBones.makeAllZero();
mKeyframedBonesToSyncTo.makeAllZero();
}
}
void RagdollController::update() {
if (!isAddedToWorld()) {
for (int i = 0, n = getNumConstraints(); i < n; ++i) {
auto* constraint = mRagdollInstance->m_constraints[i];
if (constraint->getOwner() != nullptr) {
System::instance()
->getHavokWorld(ContactLayerType::Entity)
->removeConstraint(constraint);
}
}
return;
}
for (int i = 0, n = getNumConstraints(); i < n; ++i) {
auto* constraint = mRagdollInstance->m_constraints[i];
if (constraint->getOwner() == nullptr) {
System::instance()->getHavokWorld(ContactLayerType::Entity)->addConstraint(constraint);
}
const bool should_enable = mDisabledConstraints.isOffBit(i);
if (should_enable != constraint->isEnabled()) {
if (should_enable) {
constraint->setPriority(getConfig().priority);
constraint->enable();
} else {
constraint->setPriority(hkpConstraintInstance::PRIORITY_PSI);
constraint->disable();
}
}
}
updateGravityFactorOverride();
}
RagdollController::Config& RagdollController::getConfig() {
return sRagdollCtrlConfig;
}
void RagdollController::updateGravityFactorOverride() {
if (mFlags.isOff(Flag::_200))
return;
if (System::instance() == nullptr)
return;
const float factor_divisor = System::instance()->get6c();
for (int i = 0, n = mBoneRigidBodies.size(); i < n; ++i) {
mBoneRigidBodies[i]->setGravityFactor(mGravityFactorOverride / factor_divisor);
}
}
RagdollController::ScopedPhysicsLock::ScopedPhysicsLock(const RagdollController* ctrl)
: mCtrl{ctrl}, mWorldLock{ctrl->isAddedToWorld(), ContactLayerType::Entity} {
for (auto body : util::indexIter(ctrl->mBoneRigidBodies))

View File

@ -1,5 +1,6 @@
#pragma once
#include <Havok/Physics2012/Dynamics/Constraint/hkpConstraintInstance.h>
#include <container/seadBuffer.h>
#include <hostio/seadHostIONode.h>
#include <math/seadMatrix.h>
@ -40,15 +41,24 @@ enum class PreserveVelocities : bool;
// TODO
class RagdollController : public sead::hostio::Node {
public:
enum class SyncToThisBone : bool;
struct Config {
float _0;
float _4;
float _8;
float _c;
float _10;
float _14;
hkpConstraintInstance::ConstraintPriority priority = hkpConstraintInstance::PRIORITY_TOI;
};
explicit RagdollController(SystemGroupHandler* handler);
virtual ~RagdollController();
bool init(const RagdollParam* param, sead::DirectResource* res, gsys::Model* model,
sead::Heap* heap);
// 0x0000007101223320
void update();
bool isAddedToWorld() const;
void removeFromWorldImmediately();
void removeFromWorld();
@ -93,8 +103,22 @@ public:
int getNumChildBones(const RigidBody* body) const;
RagdollRigidBody* getChildBoneRigidBody(const RigidBody* body, int index) const;
static void setUnk1(u8 value);
int getConstraintIndexByName(const sead::SafeString& name) const;
int getNumConstraints() const;
void enableConstraint(int index, bool enable);
bool isConstraintEnabled(int index) const;
void setContactLayer(ContactLayer layer);
/// Sets whether a bone is keyframed.
/// @param sync_to_this_bone Only used if keyframed = true.
void setKeyframed(int bone_index, bool keyframed, SyncToThisBone sync_to_this_bone);
void setUnk1(u8 value);
static void setMaximumUnk1(u8 value);
void stopForcingKeyframing();
void update();
static Config& getConfig();
auto& getRigidBodies_() { return mBoneRigidBodies; }
private:
@ -109,9 +133,11 @@ private:
};
enum class Flag {
_10 = 0x10,
_80 = 0x80,
/// Whether this controller has been registered with the RagdollControllerMgr.
IsRegistered = 0x100,
_200 = 0x200,
};
struct BoneVectors {
@ -130,6 +156,8 @@ private:
void registerSelf();
void unregisterSelf();
void updateGravityFactorOverride();
BoneAccessor* getBoneAccessor() const;
SkeletonMapper* mSkeletonMapper = nullptr;
@ -150,16 +178,16 @@ private:
// TODO: rename
sead::Buffer<float> mBoneStuff2;
float _98 = 0.1;
float _9c = 1.0;
float mGravityFactorOverride = 1.0;
u32 _a0 = 0;
// TODO: type
u8* _a8 = nullptr;
u32 _b0 = 0;
const RagdollParam* mRagdollParam = nullptr;
sead::TypedBitFlag<Flag> mFlags;
u32 _c4 = 0;
u32 _c8 = 0;
u32 _cc = 0;
sead::BitFlag32 mDisabledConstraints;
sead::BitFlag32 mKeyframedBones;
sead::BitFlag32 mKeyframedBonesToSyncTo;
gsys::Model* mModel = nullptr;
RigidBody* mExtraRigidBody = nullptr;
void* _e0 = nullptr;

View File

@ -42,6 +42,7 @@ class System {
public:
float get64() const { return _64; }
float get6c() const { return _6c; }
float getTimeFactor() const { return mTimeFactor; }
ContactMgr* getContactMgr() const { return mContactMgr; }
StaticCompoundMgr* getStaticCompoundMgr() const { return mStaticCompoundMgr; }