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
|
0x000000710122224c,O,000156,_ZNK4ksys4phys17RagdollController21getChildBoneRigidBodyEPKNS0_9RigidBodyEi
|
||||||
0x00000071012222e8,U,001268,
|
0x00000071012222e8,U,001268,
|
||||||
0x00000071012227dc,U,001844,
|
0x00000071012227dc,U,001844,
|
||||||
0x0000007101222f10,U,000340,
|
0x0000007101222f10,O,000340,_ZNK4ksys4phys17RagdollController24getConstraintIndexByNameERKN4sead14SafeStringBaseIcEE
|
||||||
0x0000007101223064,U,000012,
|
0x0000007101223064,O,000012,_ZNK4ksys4phys17RagdollController17getNumConstraintsEv
|
||||||
0x0000007101223070,U,000044,
|
0x0000007101223070,O,000044,_ZN4ksys4phys17RagdollController16enableConstraintEib
|
||||||
0x000000710122309c,U,000176,
|
0x000000710122309c,O,000176,_ZN4ksys4phys17RagdollController15setContactLayerENS0_12ContactLayerE
|
||||||
0x000000710122314c,U,000228,
|
0x000000710122314c,O,000228,_ZN4ksys4phys17RagdollController12setKeyframedEibNS1_14SyncToThisBoneE
|
||||||
0x0000007101223230,U,000032,
|
0x0000007101223230,m,000032,_ZN4ksys4phys17RagdollController7setUnk1Eh
|
||||||
0x0000007101223250,U,000208,
|
0x0000007101223250,O,000208,_ZN4ksys4phys17RagdollController21stopForcingKeyframingEv
|
||||||
0x0000007101223320,U,000536,
|
0x0000007101223320,O,000536,_ZN4ksys4phys17RagdollController6updateEv
|
||||||
0x0000007101223538,O,000440,_ZN4ksys4phys12RagdollParamC1Ev
|
0x0000007101223538,O,000440,_ZN4ksys4phys12RagdollParamC1Ev
|
||||||
0x00000071012236f0,O,000044,_ZN4ksys4phys12RagdollParamD1Ev
|
0x00000071012236f0,O,000044,_ZN4ksys4phys12RagdollParamD1Ev
|
||||||
0x000000710122371c,O,000004,_ZN4ksys4phys12RagdollParamD0Ev
|
0x000000710122371c,O,000004,_ZN4ksys4phys12RagdollParamD0Ev
|
||||||
|
|
Can't render this file because it is too large.
|
|
@ -26,14 +26,11 @@
|
||||||
|
|
||||||
namespace ksys::phys {
|
namespace ksys::phys {
|
||||||
|
|
||||||
static u8 sUnk1 = 15;
|
static u8 sRagdollCtrlUnk1 = 15;
|
||||||
|
static RagdollController::Config sRagdollCtrlConfig;
|
||||||
void RagdollController::setUnk1(u8 value) {
|
|
||||||
sUnk1 = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
RagdollController::RagdollController(SystemGroupHandler* handler)
|
RagdollController::RagdollController(SystemGroupHandler* handler)
|
||||||
: mGroupHandler(handler), _e8(sUnk1), _e9(sUnk1) {}
|
: mGroupHandler(handler), _e8(sRagdollCtrlUnk1), _e9(sRagdollCtrlUnk1) {}
|
||||||
|
|
||||||
RagdollController::~RagdollController() {
|
RagdollController::~RagdollController() {
|
||||||
finalize();
|
finalize();
|
||||||
|
@ -471,6 +468,128 @@ RagdollRigidBody* RagdollController::getChildBoneRigidBody(const RigidBody* body
|
||||||
return sead::DynamicCast<const RagdollRigidBody>(body)->getChildBodies_()[index];
|
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)
|
RagdollController::ScopedPhysicsLock::ScopedPhysicsLock(const RagdollController* ctrl)
|
||||||
: mCtrl{ctrl}, mWorldLock{ctrl->isAddedToWorld(), ContactLayerType::Entity} {
|
: mCtrl{ctrl}, mWorldLock{ctrl->isAddedToWorld(), ContactLayerType::Entity} {
|
||||||
for (auto body : util::indexIter(ctrl->mBoneRigidBodies))
|
for (auto body : util::indexIter(ctrl->mBoneRigidBodies))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Havok/Physics2012/Dynamics/Constraint/hkpConstraintInstance.h>
|
||||||
#include <container/seadBuffer.h>
|
#include <container/seadBuffer.h>
|
||||||
#include <hostio/seadHostIONode.h>
|
#include <hostio/seadHostIONode.h>
|
||||||
#include <math/seadMatrix.h>
|
#include <math/seadMatrix.h>
|
||||||
|
@ -40,15 +41,24 @@ enum class PreserveVelocities : bool;
|
||||||
// TODO
|
// TODO
|
||||||
class RagdollController : public sead::hostio::Node {
|
class RagdollController : public sead::hostio::Node {
|
||||||
public:
|
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);
|
explicit RagdollController(SystemGroupHandler* handler);
|
||||||
virtual ~RagdollController();
|
virtual ~RagdollController();
|
||||||
|
|
||||||
bool init(const RagdollParam* param, sead::DirectResource* res, gsys::Model* model,
|
bool init(const RagdollParam* param, sead::DirectResource* res, gsys::Model* model,
|
||||||
sead::Heap* heap);
|
sead::Heap* heap);
|
||||||
|
|
||||||
// 0x0000007101223320
|
|
||||||
void update();
|
|
||||||
|
|
||||||
bool isAddedToWorld() const;
|
bool isAddedToWorld() const;
|
||||||
void removeFromWorldImmediately();
|
void removeFromWorldImmediately();
|
||||||
void removeFromWorld();
|
void removeFromWorld();
|
||||||
|
@ -93,8 +103,22 @@ public:
|
||||||
int getNumChildBones(const RigidBody* body) const;
|
int getNumChildBones(const RigidBody* body) const;
|
||||||
RagdollRigidBody* getChildBoneRigidBody(const RigidBody* body, int index) 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; }
|
auto& getRigidBodies_() { return mBoneRigidBodies; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -109,9 +133,11 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Flag {
|
enum class Flag {
|
||||||
|
_10 = 0x10,
|
||||||
_80 = 0x80,
|
_80 = 0x80,
|
||||||
/// Whether this controller has been registered with the RagdollControllerMgr.
|
/// Whether this controller has been registered with the RagdollControllerMgr.
|
||||||
IsRegistered = 0x100,
|
IsRegistered = 0x100,
|
||||||
|
_200 = 0x200,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoneVectors {
|
struct BoneVectors {
|
||||||
|
@ -130,6 +156,8 @@ private:
|
||||||
void registerSelf();
|
void registerSelf();
|
||||||
void unregisterSelf();
|
void unregisterSelf();
|
||||||
|
|
||||||
|
void updateGravityFactorOverride();
|
||||||
|
|
||||||
BoneAccessor* getBoneAccessor() const;
|
BoneAccessor* getBoneAccessor() const;
|
||||||
|
|
||||||
SkeletonMapper* mSkeletonMapper = nullptr;
|
SkeletonMapper* mSkeletonMapper = nullptr;
|
||||||
|
@ -150,16 +178,16 @@ private:
|
||||||
// TODO: rename
|
// TODO: rename
|
||||||
sead::Buffer<float> mBoneStuff2;
|
sead::Buffer<float> mBoneStuff2;
|
||||||
float _98 = 0.1;
|
float _98 = 0.1;
|
||||||
float _9c = 1.0;
|
float mGravityFactorOverride = 1.0;
|
||||||
u32 _a0 = 0;
|
u32 _a0 = 0;
|
||||||
// TODO: type
|
// TODO: type
|
||||||
u8* _a8 = nullptr;
|
u8* _a8 = nullptr;
|
||||||
u32 _b0 = 0;
|
u32 _b0 = 0;
|
||||||
const RagdollParam* mRagdollParam = nullptr;
|
const RagdollParam* mRagdollParam = nullptr;
|
||||||
sead::TypedBitFlag<Flag> mFlags;
|
sead::TypedBitFlag<Flag> mFlags;
|
||||||
u32 _c4 = 0;
|
sead::BitFlag32 mDisabledConstraints;
|
||||||
u32 _c8 = 0;
|
sead::BitFlag32 mKeyframedBones;
|
||||||
u32 _cc = 0;
|
sead::BitFlag32 mKeyframedBonesToSyncTo;
|
||||||
gsys::Model* mModel = nullptr;
|
gsys::Model* mModel = nullptr;
|
||||||
RigidBody* mExtraRigidBody = nullptr;
|
RigidBody* mExtraRigidBody = nullptr;
|
||||||
void* _e0 = nullptr;
|
void* _e0 = nullptr;
|
||||||
|
|
|
@ -42,6 +42,7 @@ class System {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float get64() const { return _64; }
|
float get64() const { return _64; }
|
||||||
|
float get6c() const { return _6c; }
|
||||||
float getTimeFactor() const { return mTimeFactor; }
|
float getTimeFactor() const { return mTimeFactor; }
|
||||||
ContactMgr* getContactMgr() const { return mContactMgr; }
|
ContactMgr* getContactMgr() const { return mContactMgr; }
|
||||||
StaticCompoundMgr* getStaticCompoundMgr() const { return mStaticCompoundMgr; }
|
StaticCompoundMgr* getStaticCompoundMgr() const { return mStaticCompoundMgr; }
|
||||||
|
|
Loading…
Reference in New Issue