mirror of https://github.com/zeldaret/botw.git
ksys/phys: Implement the rest of the easy RagdollController functions
This commit is contained in:
parent
50464f7435
commit
b4e6a4dac9
|
@ -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.
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue