From 3a7b4df04c8999868444fedd215f2551e30d472d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Wed, 14 Apr 2021 16:27:20 +0200 Subject: [PATCH] ksys/phys: Add RagdollConfig --- data/uking_functions.csv | 34 +++--- src/KingSystem/CMakeLists.txt | 1 + src/KingSystem/Physics/CMakeLists.txt | 4 + .../Physics/Ragdoll/physRagdollConfig.cpp | 92 +++++++++++++++ .../Physics/Ragdoll/physRagdollConfig.h | 110 ++++++++++++++++++ 5 files changed, 224 insertions(+), 17 deletions(-) create mode 100644 src/KingSystem/Physics/CMakeLists.txt create mode 100644 src/KingSystem/Physics/Ragdoll/physRagdollConfig.cpp create mode 100644 src/KingSystem/Physics/Ragdoll/physRagdollConfig.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index c64d1bd3..6d7b1280 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -79515,23 +79515,23 @@ 0x0000007100e9f8e8,sub_7100E9F8E8,116, 0x0000007100e9f95c,sub_7100E9F95C,48, 0x0000007100e9f98c,sub_7100E9F98C,92, -0x0000007100e9f9e8,sub_7100E9F9E8,608, -0x0000007100e9fc48,sub_7100E9FC48,620, -0x0000007100e9feb4,sub_7100E9FEB4,556, -0x0000007100ea00e0,sub_7100EA00E0,568, -0x0000007100ea0318,sub_7100EA0318,784, -0x0000007100ea0628,sub_7100EA0628,432, -0x0000007100ea07d8,sub_7100EA07D8,316, -0x0000007100ea0914,sub_7100EA0914,36, -0x0000007100ea0938,sub_7100EA0938,24, -0x0000007100ea0950,sub_7100EA0950,108, -0x0000007100ea09bc,sub_7100EA09BC,48, -0x0000007100ea09ec,j__ZdlPv_944,4, -0x0000007100ea09f0,sub_7100EA09F0,52, -0x0000007100ea0a24,j__ZdlPv_945,4, -0x0000007100ea0a28,sub_7100EA0A28,248, -0x0000007100ea0b20,j__ZdlPv_946,4, -0x0000007100ea0b24,sub_7100EA0B24,308, +0x0000007100e9f9e8,sub_7100E9F9E8,608,_ZN4ksys4phys13RagdollConfig15PartImpulseInfo10ReceiveObjC1Ev +0x0000007100e9fc48,sub_7100E9FC48,620,_ZN4ksys4phys13RagdollConfig15PartImpulseInfo10ImpulseObjC1Ev +0x0000007100e9feb4,sub_7100E9FEB4,556,_ZN4ksys4phys13RagdollConfig15PartImpulseInfoC1Ev? +0x0000007100ea00e0,sub_7100EA00E0,568,_ZN4ksys4phys13RagdollConfig17ImpactImpulseInfoC1Ev +0x0000007100ea0318,sub_7100EA0318,784,_ZN4ksys4phys13RagdollConfigC1Ev +0x0000007100ea0628,sub_7100EA0628,432,_ZN4ksys4phys13RagdollConfigD1Ev +0x0000007100ea07d8,sub_7100EA07D8,316,_ZN4ksys4phys13RagdollConfig17ImpactImpulseInfoD2Ev +0x0000007100ea0914,sub_7100EA0914,36,_ZN4ksys4phys13RagdollConfigD0Ev +0x0000007100ea0938,sub_7100EA0938,24,_ZNK4ksys4phys13RagdollConfig14getImpulseInfoEji +0x0000007100ea0950,sub_7100EA0950,108,_ZNK4ksys4phys13RagdollConfig15getImpulsePowerEib +0x0000007100ea09bc,sub_7100EA09BC,48,_ZN4ksys4phys13RagdollConfig15PartImpulseInfo10ReceiveObjD2Ev +0x0000007100ea09ec,j__ZdlPv_944,4,_ZN4ksys4phys13RagdollConfig15PartImpulseInfo10ReceiveObjD0Ev +0x0000007100ea09f0,sub_7100EA09F0,52,_ZN4ksys4phys13RagdollConfig15PartImpulseInfo10ImpulseObjD2Ev +0x0000007100ea0a24,j__ZdlPv_945,4,_ZN4ksys4phys13RagdollConfig15PartImpulseInfo10ImpulseObjD0Ev +0x0000007100ea0a28,sub_7100EA0A28,248,_ZN4ksys4phys13RagdollConfig15PartImpulseInfoD2Ev +0x0000007100ea0b20,j__ZdlPv_946,4,_ZN4ksys4phys13RagdollConfig15PartImpulseInfoD0Ev +0x0000007100ea0b24,sub_7100EA0B24,308,_ZN4ksys4phys13RagdollConfig17ImpactImpulseInfoD0Ev 0x0000007100ea0c58,AI_Action_PlayerActionClimb::ctor,388, 0x0000007100ea0ddc,_ZN5uking6action17PlayerActionClimb5init_EPN4sead4HeapE,8,_ZN5uking6action17PlayerActionClimb5init_EPN4sead4HeapE 0x0000007100ea0de4,_ZN5uking6action17PlayerActionClimb6enter_EPN4ksys3act2ai15InlineParamPackE,1952, diff --git a/src/KingSystem/CMakeLists.txt b/src/KingSystem/CMakeLists.txt index 97733bd4..f3f89a44 100644 --- a/src/KingSystem/CMakeLists.txt +++ b/src/KingSystem/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(Event) add_subdirectory(Framework) add_subdirectory(Map) add_subdirectory(Mii) +add_subdirectory(Physics) add_subdirectory(Sound) add_subdirectory(System) add_subdirectory(Terrain) diff --git a/src/KingSystem/Physics/CMakeLists.txt b/src/KingSystem/Physics/CMakeLists.txt new file mode 100644 index 00000000..0b27d301 --- /dev/null +++ b/src/KingSystem/Physics/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(uking PRIVATE + Ragdoll/physRagdollConfig.cpp + Ragdoll/physRagdollConfig.h +) diff --git a/src/KingSystem/Physics/Ragdoll/physRagdollConfig.cpp b/src/KingSystem/Physics/Ragdoll/physRagdollConfig.cpp new file mode 100644 index 00000000..1403a775 --- /dev/null +++ b/src/KingSystem/Physics/Ragdoll/physRagdollConfig.cpp @@ -0,0 +1,92 @@ +#include "KingSystem/Physics/Ragdoll/physRagdollConfig.h" + +namespace ksys::phys { + +RagdollConfig::PartImpulseInfo::ReceiveObj::ReceiveObj() + : mTypeName({"null"}, "TypeName", "適用するラグドール剛体名", this), + mDivideFlag(false, "DivideFlag", "インパルスを親子に分散させるか", this), + mImpulseRate(1.0, "ImpulseRate", "インパルスの適用比率", this), + mDivideRate(0.5, "DivideRate", "親子へのインパルス分配比率", this) {} + +RagdollConfig::PartImpulseInfo::ImpulseObj::ImpulseObj() + : mTypeName({""}, "TypeName", "適用するラグドール剛体名", this), + mUseFlag(false, "UseFlag", "このスロットのインパルス情報を使うかどうか", this), + mAttackVector({0, 0, 0}, "AttackVector", "インパルスの方向", this), + mAttackPoint({0, 0, 0}, "AttackPoint", "インパルスを与える点", this), + mImpulsePower(0.1, "ImpulsePower", "インパルスの強さ", this) {} + +// NON_MATCHING: loop unrolling +RagdollConfig::PartImpulseInfo::PartImpulseInfo() + : mIsUseReceiveImpulse(true, "IsUseReceiveImpulse", "攻撃インパルスを反映させるかどうか", + &mObj), + mIsUseFixedImpulse(true, "IsUseFixedImpulse", "固定インパルスを反映させるかどうか", &mObj) { + for (int i = 0; i < mReceiveObjs.size(); ++i) { + sead::FormatFixedSafeString<128> name("ReceiveObj%02d", i + 1); + addObj(&mReceiveObjs[i], name); + } + + for (int i = 0; i < mImpulseObjs.size(); ++i) { + sead::FormatFixedSafeString<128> name("ImpulseObj%02d", i + 1); + addObj(&mImpulseObjs[i], name); + } + + addObj(&mObj, "PartImpulseData"); +} + +RagdollConfig::ImpactImpulseInfo::ImpactImpulseInfo() { + for (int i = 0; i < NumParts; ++i) { + sead::FormatFixedSafeString<128> name("PartImpulseInfo%02d", i + 1); + addList(&mPartImpulseInfo[i], name); + + sead::FormatFixedSafeString<32> use_flag_name("UseFlag%02d", i + 1); + mUseFlags[i].init(true, use_flag_name, "攻撃インパルスを反映させるかどうか", &mObj); + } + + addObj(&mObj, "ImpactImpulseData"); +} + +RagdollConfig::RagdollConfig() + : agl::utl::IParameterIO("rgconfig", 0), + mImpulseUseRate(0.5, "ImpulseUseRate", "攻撃インパルスの混合率", &mObj), + mImpulsePower(0.1, "ImpulsePower", "インパルスの強さ", &mObj), + mLargeAttackRate(1.5, "LargeAttackRate", "大攻撃のインパルス倍率", &mObj), + mBlastOffAttackRateSmall(2.0, "BlastOffAttackRateSmall", "小攻撃のふっ飛ばしインパルス倍率", + &mObj), + mBlastOffAttackRateLarge(3.0, "BlastOffAttackRateLarge", "大攻撃のふっ飛ばしインパルス倍率", + &mObj), + mSpecialAttackRate(10.0, "SpecialAttackRate", "特殊攻撃のふっ飛ばしインパルス倍率", &mObj) { + for (int i = 0; i < mImpactImpulseInfo.size(); ++i) { + sead::FormatFixedSafeString<128> name("ImpactImpulseInfo%02d", i + 1); + addList(&mImpactImpulseInfo[i], name); + } + + addObj(&mObj, "AttackTypeImpulseData"); +} + +RagdollConfig::~RagdollConfig() = default; + +const RagdollConfig::PartImpulseInfo& RagdollConfig::getImpulseInfo(u32 impact_idx, + int part_idx) const { + return mImpactImpulseInfo.getBufferPtr()[impact_idx].getPartImpulseInfo()(part_idx); +} + +float RagdollConfig::getImpulsePower(int attack_rate_type, bool is_blast_off) const { + switch (attack_rate_type) { + case 0: + if (!is_blast_off) + return *mImpulsePower; + return *mImpulsePower * *mBlastOffAttackRateSmall; + case 1: + if (!is_blast_off) + return *mImpulsePower * *mLargeAttackRate; + return *mImpulsePower * *mBlastOffAttackRateLarge; + case 2: + return *mImpulsePower * *mBlastOffAttackRateLarge; + case 3: + return *mImpulsePower * *mSpecialAttackRate; + default: + return 0.0; + } +} + +} // namespace ksys::phys diff --git a/src/KingSystem/Physics/Ragdoll/physRagdollConfig.h b/src/KingSystem/Physics/Ragdoll/physRagdollConfig.h new file mode 100644 index 00000000..5f65b895 --- /dev/null +++ b/src/KingSystem/Physics/Ragdoll/physRagdollConfig.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace ksys::phys { + +class RagdollConfig : public agl::utl::IParameterIO, public sead::hostio::Node { +public: + class PartImpulseInfo : public agl::utl::ParameterList, public sead::hostio::Node { + public: + class ReceiveObj : public agl::utl::ParameterObj { + public: + ReceiveObj(); + + const auto& getTypeName() const { return *mTypeName; } + const auto& getDivideFlag() const { return *mDivideFlag; } + const auto& getImpulseRate() const { return *mImpulseRate; } + const auto& getDivideRate() const { return *mDivideRate; } + bool is100() const { return _100; } + + private: + agl::utl::Parameter> mTypeName; + agl::utl::Parameter mDivideFlag; + agl::utl::Parameter mImpulseRate; + agl::utl::Parameter mDivideRate; + bool _100 = true; + }; + + class ImpulseObj : public agl::utl::ParameterObj { + public: + ImpulseObj(); + + const auto& getTypeName() const { return *mTypeName; } + const auto& getUseFlag() const { return *mUseFlag; } + const auto& getAttackVector() const { return *mAttackVector; } + const auto& getAttackPoint() const { return *mAttackPoint; } + const auto& getImpulsePower() const { return *mImpulsePower; } + bool is130() const { return _130; } + + private: + agl::utl::Parameter> mTypeName; + agl::utl::Parameter mUseFlag; + agl::utl::Parameter mAttackVector; + agl::utl::Parameter mAttackPoint; + agl::utl::Parameter mImpulsePower; + bool _130 = false; + }; + + PartImpulseInfo(); + + const auto& getReceiveObjs() const { return mReceiveObjs; } + const auto& getImpulseObjs() const { return mImpulseObjs; } + const bool& isUseReceiveImpulse() const { return *mIsUseReceiveImpulse; } + const bool& isUseFixedImpulse() const { return *mIsUseFixedImpulse; } + + private: + sead::SafeArray mReceiveObjs; + sead::SafeArray mImpulseObjs; + agl::utl::IParameterObj mObj; + agl::utl::Parameter mIsUseReceiveImpulse; + agl::utl::Parameter mIsUseFixedImpulse; + }; + + class ImpactImpulseInfo : public agl::utl::ParameterList, public sead::hostio::Node { + public: + ImpactImpulseInfo(); + + const auto& getPartImpulseInfo() const { return mPartImpulseInfo; } + bool isUsed(int idx) const { return *mUseFlags[idx]; } + + private: + static constexpr int NumParts = 3; + + sead::SafeArray mPartImpulseInfo; + agl::utl::IParameterObj mObj; + sead::SafeArray, NumParts> mUseFlags; + }; + + RagdollConfig(); + ~RagdollConfig() override; + + const auto& getImpactImpulseInfo() const { return mImpactImpulseInfo; } + const float& getImpulseUseRate() const { return *mImpulseUseRate; } + const float& getImpulsePower() const { return *mImpulsePower; } + const float& getLargeAttackRate() const { return *mLargeAttackRate; } + const float& getBlastOffAttackRateSmall() const { return *mBlastOffAttackRateSmall; } + const float& getBlastOffAttackRateLarge() const { return *mBlastOffAttackRateLarge; } + const float& getSpecialAttackRate() const { return *mSpecialAttackRate; } + + const PartImpulseInfo& getImpulseInfo(u32 impact_idx, int part_idx) const; + float getImpulsePower(int attack_rate_type, bool is_blast_off) const; + +private: + sead::SafeArray mImpactImpulseInfo; + agl::utl::IParameterObj mObj; + agl::utl::Parameter mImpulseUseRate; + agl::utl::Parameter mImpulsePower; + agl::utl::Parameter mLargeAttackRate; + agl::utl::Parameter mBlastOffAttackRateSmall; + agl::utl::Parameter mBlastOffAttackRateLarge; + agl::utl::Parameter mSpecialAttackRate; +}; + +} // namespace ksys::phys