ksys/phys: Add even more RigidBody functions

This commit is contained in:
Léo Lam
2022-01-18 19:22:27 +01:00
parent c343c3d9e3
commit 52e2111ff3
6 changed files with 126 additions and 15 deletions
@@ -176,6 +176,32 @@ sead::SafeString RigidBody::getHkBodyName() const {
return name;
}
// NON_MATCHING: ldr w8, [x20, #0x68] should be ldr w8, [x22] (equivalent)
void RigidBody::x_0() {
// debug code that survived because mFlags is atomic
static_cast<void>(isFlag8Set());
auto lock = makeScopedLock(false);
if (mMotionAccessor) {
const bool use_system_time_factor = hasFlag(Flag::_100);
setTimeFactor(use_system_time_factor ? MemSystem::instance()->getTimeFactor() : 1.0f);
if (isSensor()) {
auto* accessor = sead::DynamicCast<RigidBodyMotionSensor>(mMotionAccessor);
if (accessor->hasFlag(RigidBodyMotionSensor::Flag::_400000))
return;
}
}
if (isMotionFlag2Set()) {
mMotionFlags.reset(MotionFlag::_2);
mMotionFlags.set(MotionFlag::_1);
} else if (!isMotionFlag1Set()) {
setMotionFlag(MotionFlag::_1);
}
}
void RigidBody::setMotionFlag(MotionFlag flag) {
auto lock = sead::makeScopedLock(mCS);
@@ -288,11 +314,91 @@ void RigidBody::setContactPoints(RigidContactPoints* points) {
MemSystem::instance()->registerContactPoints(points);
}
void RigidBody::freeze(bool should_freeze, bool preserve_velocities, bool preserve_max_impulse) {
if (hasFlag(Flag::_80000) == should_freeze) {
if (should_freeze) {
setLinearVelocity(sead::Vector3f::zero);
setAngularVelocity(sead::Vector3f::zero);
}
return;
}
if (!mMotionAccessor) {
mFlags.change(Flag::_80000, should_freeze);
return;
}
if (should_freeze) {
mMotionAccessor->freeze(true, preserve_velocities, preserve_max_impulse);
mFlags.set(Flag::_80000);
} else {
mFlags.reset(Flag::_80000);
mMotionAccessor->freeze(false, preserve_velocities, preserve_max_impulse);
}
}
void RigidBody::setFixedAndPreserveImpulse(bool fixed, bool mark_linear_vel_as_dirty) {
if (hasFlag(Flag::_20000) != fixed) {
mFlags.change(Flag::_20000, fixed);
if (!fixed && mark_linear_vel_as_dirty) {
setMotionFlag(MotionFlag::DirtyLinearVelocity);
}
}
freeze(hasFlag(Flag::_20000) || hasFlag(Flag::_40000), true, true);
}
void RigidBody::setFixed(bool fixed, bool preserve_velocities) {
if (hasFlag(Flag::_40000) != fixed) {
mFlags.change(Flag::_40000, fixed);
if (!fixed) {
setMotionFlag(MotionFlag::DirtyLinearVelocity);
setMotionFlag(MotionFlag::_40000);
}
}
freeze(hasFlag(Flag::_20000) || hasFlag(Flag::_40000), preserve_velocities, false);
}
void RigidBody::resetFrozenState() {
if (mMotionAccessor)
mMotionAccessor->resetFrozenState();
}
void RigidBody::updateCollidableQualityType(bool high_quality) {
auto lock = makeScopedLock(isFlag8Set());
if (isCharacterControllerType()) {
setCollidableQualityType(HK_COLLIDABLE_QUALITY_CHARACTER);
mFlags.set(Flag::IsCharacterController);
return;
}
switch (getMotionType()) {
case MotionType::Dynamic:
setCollidableQualityType(high_quality ? HK_COLLIDABLE_QUALITY_BULLET :
HK_COLLIDABLE_QUALITY_DEBRIS_SIMPLE_TOI);
break;
case MotionType::Fixed:
setCollidableQualityType(HK_COLLIDABLE_QUALITY_FIXED);
break;
case MotionType::Keyframed:
setCollidableQualityType(isEntity() && high_quality ?
HK_COLLIDABLE_QUALITY_MOVING :
HK_COLLIDABLE_QUALITY_KEYFRAMED_REPORTING);
break;
case MotionType::Unknown:
case MotionType::Invalid:
break;
}
mFlags.change(Flag::IsCharacterController, high_quality);
}
void RigidBody::setCollidableQualityType(hkpCollidableQualityType quality) {
getHkBody()->getCollidableRw()->setQualityType(quality);
}
void RigidBody::setContactMask(u32 value) {
mContactMask.setDirect(value);
}
@@ -12,6 +12,7 @@
#include "KingSystem/Physics/System/physDefines.h"
#include "KingSystem/Utils/Types.h"
enum hkpCollidableQualityType : int;
class hkQuaternionf;
class hkVector4f;
class hkpRigidBody;
@@ -129,7 +130,6 @@ public:
sead::SafeString getHkBodyName() const;
// 0x0000007100f8cfa0
void x_0();
bool isActive() const;
@@ -175,15 +175,13 @@ public:
// 0x0000007100f8e7b4
void setContactPoints(RigidContactPoints* points);
// 0x0000007100f8e7e8
void x_13(bool a, bool b);
// 0x0000007100f8e8f0
void x_14(bool a, bool b, bool c);
// 0x0000007100f8eabc
void x_15(bool a, bool b);
// 0x0000007100f8ee38
void freeze(bool should_freeze, bool preserve_velocities, bool preserve_max_impulse);
void setFixedAndPreserveImpulse(bool fixed, bool mark_linear_vel_as_dirty);
void setFixed(bool fixed, bool preserve_velocities);
void resetFrozenState();
void updateCollidableQualityType(bool high_quality);
u32 addContactLayer(ContactLayer);
u32 removeContactLayer(ContactLayer);
void setContactMask(u32);
@@ -371,6 +369,7 @@ private:
void onInvalidParameter(int code = 0);
void notifyUserTag(int code);
void updateDeactivation();
void setCollidableQualityType(hkpCollidableQualityType quality);
sead::CriticalSection mCS;
sead::TypedBitFlag<Flag, sead::Atomic<u32>> mFlags{};
@@ -15,6 +15,7 @@ public:
HasExtraTranslateForLinkedRigidBody = 1 << 19,
HasExtraRotateForLinkedRigidBody = 1 << 20,
HasLinkedRigidBodyWithoutFlag10 = 1 << 21,
_400000 = 1 << 22,
};
explicit RigidBodyMotionSensor(RigidBody* body);
@@ -61,6 +62,8 @@ public:
mFrozenAngularVelocity.set(0, 0, 0);
}
bool hasFlag(Flag flag) const { return mFlags.isOn(flag); }
private:
void setTransformImpl(const sead::Matrix34f& mtx);
@@ -30,6 +30,7 @@ class MemSystem {
virtual ~MemSystem();
public:
float getTimeFactor() const { return mTimeFactor; }
GroupFilter* getGroupFilter(ContactLayerType type) const;
ContactMgr* getContactMgr() const { return mContactMgr; }
RigidBodyRequestMgr* getRigidBodyRequestMgr() const { return mRigidBodyRequestMgr; }
@@ -57,7 +58,9 @@ public:
void unlockWorld(ContactLayerType type, void* a = nullptr, int b = 0, bool c = false);
private:
u8 _28[0xa8 - 0x28];
u8 _28[0x74 - 0x28];
float mTimeFactor{};
u8 _78[0xa8 - 0x78];
sead::CriticalSection mCS;
void* _e8{};
void* _f0{};