From 4244f39bd5c873d8d7c3195db06a476b7ba44505 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 20 Aug 2016 22:47:47 -0700 Subject: [PATCH] CPASDatabase imps --- Runtime/Character/CCharacterInfo.hpp | 1 + Runtime/Character/CPASAnimParm.hpp | 1 + Runtime/Character/CPASAnimParmData.cpp | 2 +- Runtime/Character/CPASAnimParmData.hpp | 6 +- Runtime/Character/CPASAnimState.cpp | 199 ++++++++++++++++++++++++- Runtime/Character/CPASAnimState.hpp | 5 +- Runtime/Character/CPASDatabase.cpp | 19 +++ Runtime/Character/CPASDatabase.hpp | 4 +- Runtime/Character/CPASParmInfo.cpp | 28 ++-- Runtime/Character/CPASParmInfo.hpp | 23 ++- Runtime/Character/CharacterCommon.hpp | 66 ++++++++ 11 files changed, 320 insertions(+), 34 deletions(-) diff --git a/Runtime/Character/CCharacterInfo.hpp b/Runtime/Character/CCharacterInfo.hpp index 7a9295b86..2866806c4 100644 --- a/Runtime/Character/CCharacterInfo.hpp +++ b/Runtime/Character/CCharacterInfo.hpp @@ -41,6 +41,7 @@ private: public: CCharacterInfo(CInputStream& in); + const std::string& GetCharacterName() const { return x4_name; } ResId GetModelId() const {return x14_cmdl;} ResId GetSkinRulesId() const {return x18_cskr;} ResId GetCharLayoutInfoId() const {return x1c_cinf;} diff --git a/Runtime/Character/CPASAnimParm.hpp b/Runtime/Character/CPASAnimParm.hpp index fd5e8c4cb..a3f46dd33 100644 --- a/Runtime/Character/CPASAnimParm.hpp +++ b/Runtime/Character/CPASAnimParm.hpp @@ -32,6 +32,7 @@ private: public: CPASAnimParm(UParmValue val, EParmType tp) : x4_type(tp), x0_value(val) {} + EParmType GetParameterType() const { return x4_type; } s32 GetEnumValue() const {return x0_value.m_int;} bool GetBoolValue() const {return x0_value.m_bool;} float GetReal32Value() const {return x0_value.m_float;} diff --git a/Runtime/Character/CPASAnimParmData.cpp b/Runtime/Character/CPASAnimParmData.cpp index fc35eeb75..2a1edfea0 100644 --- a/Runtime/Character/CPASAnimParmData.cpp +++ b/Runtime/Character/CPASAnimParmData.cpp @@ -23,7 +23,7 @@ s32 CPASAnimParmData::GetStateId() return x0_stateId; } -const std::vector& CPASAnimParmData::GetAnimParmData() const +const rstl::reserved_vector& CPASAnimParmData::GetAnimParmData() const { return x4_parms; } diff --git a/Runtime/Character/CPASAnimParmData.hpp b/Runtime/Character/CPASAnimParmData.hpp index d83f0b42a..331df14f6 100644 --- a/Runtime/Character/CPASAnimParmData.hpp +++ b/Runtime/Character/CPASAnimParmData.hpp @@ -14,11 +14,11 @@ public: {}; CPASAnimParmData(s32 stateId, const CPASAnimParm& parm1, const CPASAnimParm& parm2, const CPASAnimParm& parm3, - const CPASAnimParm& parm4, const CPASAnimParm& parm5, const CPASAnimParm& parm6, const CPASAnimParm& parm7, - const CPASAnimParm& parm8); + const CPASAnimParm& parm4, const CPASAnimParm& parm5, const CPASAnimParm& parm6, + const CPASAnimParm& parm7, const CPASAnimParm& parm8); s32 GetStateId(); - const std::vector& GetAnimParmData() const; + const rstl::reserved_vector& GetAnimParmData() const; }; } diff --git a/Runtime/Character/CPASAnimState.cpp b/Runtime/Character/CPASAnimState.cpp index 3553973a7..0ff5ce976 100644 --- a/Runtime/Character/CPASAnimState.cpp +++ b/Runtime/Character/CPASAnimState.cpp @@ -1,5 +1,10 @@ #include "CPASAnimState.hpp" #include "CPASAnimParmData.hpp" +#include "CRandom16.hpp" +#include "zeus/Math.hpp" +#include +#include + namespace urde { @@ -11,7 +16,7 @@ CPASAnimState::CPASAnimState(CInputStream& in) x4_parms.reserve(parmCount); x14_anims.reserve(animCount); - x24_.reserve(animCount); + x24_selectionCache.reserve(animCount); for (u32 i=0 ; i + bool {return item.GetAnimId() < testId;}); + if (search == x14_anims.end()) + return CPASAnimParm::NoParameter(); + + CPASParmInfo parm = x4_parms.at(idx); + return (*search).GetAnimParmData(idx, parm.GetParameterType()); } -std::pair CPASAnimState::FindBestAnimation(const rstl::reserved_vector&, CRandom16&, s32) const +s32 CPASAnimState::PickRandomAnimation(CRandom16& rand) const { - return {}; + if (x24_selectionCache.size() == 1) + return x24_selectionCache[0]; + + if (x24_selectionCache.size() > 1) + { + u32 idx = u32(floor(rand.Float())); + if (idx == x24_selectionCache.size()) + idx--; + + return x24_selectionCache[idx]; + } + + return -1; +} + +std::pair CPASAnimState::FindBestAnimation(const rstl::reserved_vector& parms, + CRandom16& rand, s32 anim) const +{ + const_cast*>(&x24_selectionCache)->clear(); + float weight = -1.f; + + if (x14_anims.size() != 0) + { + for (const CPASAnimInfo& info : x14_anims) + { + float calcWeight = 1.f; + if (x4_parms.size() > 0) + calcWeight = 0.f; + + u32 r23 = 0 ; + u32 i = 0; + + for (; i*>(&x24_selectionCache)->push_back(info.GetAnimId()); + } + } + return {weight, PickRandomAnimation(rand)}; +} + +float CPASAnimState::ComputeExactMatchWeight(u32, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const +{ + if (parm.GetParameterType() == CPASAnimParm::EParmType::Int32) + { + return (parm.GetInt32Value() == parmVal.m_int ? 1.f : 0.f); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::UInt32) + { + return (parm.GetUint32Value() == parmVal.m_uint ? 1.f : 0.f); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Float) + { + return ((parmVal.m_float - parm.GetReal32Value()) < FLT_EPSILON ? 1.f : 0.f); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Bool) + { + return (parm.GetBoolValue() == parmVal.m_bool ? 1.f : 0.f); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Enum) + { + return (parm.GetEnumValue() == parmVal.m_int ? 1.f : 0.f); + } + + return 0.f; +} + +float CPASAnimState::ComputePercentErrorWeight(u32 idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const +{ + float range = 0.f; + float val = 0.f; + + if (parm.GetParameterType() == CPASAnimParm::EParmType::Int32) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_int - info.GetWeightMaxValue().m_int); + val = float(fabs(parmVal.m_int - parm.GetInt32Value())); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::UInt32) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_uint - info.GetWeightMaxValue().m_uint); + val = float(fabs(parmVal.m_uint - parm.GetUint32Value())); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Float) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_float - info.GetWeightMaxValue().m_float); + val = float(fabs(parmVal.m_float - parm.GetReal32Value())); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Bool) + { + val = parm.GetBoolValue() ? 1.f : 0.f; + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Enum) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_float - info.GetWeightMaxValue().m_float); + val = float(fabs(parmVal.m_float - parm.GetReal32Value())); + } + + if (range > FLT_EPSILON) + return (val / range) - 1.0f; + + return (val < FLT_EPSILON ? 1.f : 0.f); +} + +float CPASAnimState::ComputeAngularPercentErrorWeight(u32 idx, const CPASAnimParm& parm, CPASAnimParm::UParmValue parmVal) const +{ + float range = 0.f; + float val = 0.f; + + if (parm.GetParameterType() == CPASAnimParm::EParmType::Int32) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_int - info.GetWeightMaxValue().m_int); + val = float(fabs(parmVal.m_int - parm.GetInt32Value())); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::UInt32) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_uint - info.GetWeightMaxValue().m_uint); + val = float(fabs(parmVal.m_uint - parm.GetUint32Value())); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Float) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_float - info.GetWeightMaxValue().m_float); + val = float(fabs(parmVal.m_float - parm.GetReal32Value())); + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Bool) + { + val = parm.GetBoolValue() ? 1.f : 0.f; + } + else if (parm.GetParameterType() == CPASAnimParm::EParmType::Enum) + { + const CPASParmInfo& info = x4_parms[idx]; + range = float(info.GetWeightMinValue().m_float - info.GetWeightMaxValue().m_float); + val = float(fabs(parmVal.m_float - parm.GetReal32Value())); + } + + if (range > FLT_EPSILON) + { + float mid = 0.5f * range; + float offset = 1.f - ((val > mid ? range - val : val) / mid); + return zeus::clamp(0.f, offset, 1.f); + } + + return (val >= FLT_EPSILON ? 0.f : 1.f); } } diff --git a/Runtime/Character/CPASAnimState.hpp b/Runtime/Character/CPASAnimState.hpp index bf8313827..9bce44218 100644 --- a/Runtime/Character/CPASAnimState.hpp +++ b/Runtime/Character/CPASAnimState.hpp @@ -14,12 +14,13 @@ class CPASAnimState s32 x0_id; std::vector x4_parms; std::vector x14_anims; - std::vector x24_; + std::vector x24_selectionCache; public: CPASAnimState(CInputStream& in); s32 GetStateId() const {return x0_id;} s32 GetNumAnims() const { return x14_anims.size(); } - const CPASAnimParmData& GetAnimParmData(s32, u32) const; + CPASAnimParm GetAnimParmData(s32, u32) const; + s32 PickRandomAnimation(CRandom16 &rand) const; std::pair FindBestAnimation(const rstl::reserved_vector&, CRandom16&, s32) const; float ComputeExactMatchWeight(u32, const CPASAnimParm&, CPASAnimParm::UParmValue) const; float ComputePercentErrorWeight(u32, const CPASAnimParm&, CPASAnimParm::UParmValue) const; diff --git a/Runtime/Character/CPASDatabase.cpp b/Runtime/Character/CPASDatabase.cpp index 40c901a9a..270a7b323 100644 --- a/Runtime/Character/CPASDatabase.cpp +++ b/Runtime/Character/CPASDatabase.cpp @@ -1,4 +1,6 @@ #include "CPASDatabase.hpp" +#include "CPASAnimParmData.hpp" +#include "CRandom16.hpp" namespace urde { @@ -27,4 +29,21 @@ CPASDatabase::CPASDatabase(CInputStream& in) SetDefaultState(defaultState); } +std::pair CPASDatabase::FindBestAnimation(const CPASAnimParmData& data, s32 id) const +{ + CRandom16 rnd(4660); + return FindBestAnimation(data, rnd, id); +} + +std::pair CPASDatabase::FindBestAnimation(const CPASAnimParmData& data, CRandom16& rand, s32 id) const +{ + auto it = std::lower_bound(x0_states.cbegin(), x0_states.cend(), id, + [](const CPASAnimState& item, const int& test) -> bool {return item.GetStateId() < test;}); + + if (it == x0_states.cend()) + return {0.f, -1}; + + return (*it).FindBestAnimation(data.GetAnimParmData(), rand, id); +} + } diff --git a/Runtime/Character/CPASDatabase.hpp b/Runtime/Character/CPASDatabase.hpp index 92078421b..1f8d1241b 100644 --- a/Runtime/Character/CPASDatabase.hpp +++ b/Runtime/Character/CPASDatabase.hpp @@ -18,8 +18,8 @@ class CPASDatabase public: CPASDatabase(CInputStream& in); - void FindBestAnimation(const CPASAnimParmData&, int) const; - void FindBestAnimation(const CPASAnimParmData&, CRandom16&, int) const; + std::pair FindBestAnimation(const CPASAnimParmData&, s32) const; + std::pair FindBestAnimation(const CPASAnimParmData&, CRandom16&, s32) const; s32 GetDefaultState() const { return x10_defaultState; } s32 GetNumAnimStates() const { return x0_states.size(); } const CPASAnimState* GetAnimState(s32 id) const diff --git a/Runtime/Character/CPASParmInfo.cpp b/Runtime/Character/CPASParmInfo.cpp index 20bb19723..14fc4f5df 100644 --- a/Runtime/Character/CPASParmInfo.cpp +++ b/Runtime/Character/CPASParmInfo.cpp @@ -5,33 +5,33 @@ namespace urde CPASParmInfo::CPASParmInfo(CInputStream& in) { - xc_val1.m_int = 0; - x10_val2.m_int = 0; + xc_min.m_int = 0; + x10_max.m_int = 0; x0_type = CPASAnimParm::EParmType(in.readUint32Big()); - x4_unk1 = in.readUint32Big(); - x8_unk2 = in.readFloatBig(); + x4_weightFunction = EWeightFunction(in.readUint32Big()); + x8_weight = in.readFloatBig(); switch (x0_type) { case CPASAnimParm::EParmType::Int32: - xc_val1.m_int = in.readInt32Big(); - x10_val2.m_int = in.readInt32Big(); + xc_min.m_int = in.readInt32Big(); + x10_max.m_int = in.readInt32Big(); break; case CPASAnimParm::EParmType::UInt32: - xc_val1.m_uint = in.readUint32Big(); - x10_val2.m_uint = in.readUint32Big(); + xc_min.m_uint = in.readUint32Big(); + x10_max.m_uint = in.readUint32Big(); break; case CPASAnimParm::EParmType::Float: - xc_val1.m_float = in.readFloatBig(); - x10_val2.m_float = in.readFloatBig(); + xc_min.m_float = in.readFloatBig(); + x10_max.m_float = in.readFloatBig(); break; case CPASAnimParm::EParmType::Bool: - xc_val1.m_bool = in.readBool(); - x10_val2.m_bool = in.readBool(); + xc_min.m_bool = in.readBool(); + x10_max.m_bool = in.readBool(); break; case CPASAnimParm::EParmType::Enum: - xc_val1.m_int = in.readInt32Big(); - x10_val2.m_int = in.readInt32Big(); + xc_min.m_int = in.readInt32Big(); + x10_max.m_int = in.readInt32Big(); break; default: break; } diff --git a/Runtime/Character/CPASParmInfo.hpp b/Runtime/Character/CPASParmInfo.hpp index 2aa835ffa..2de76c6be 100644 --- a/Runtime/Character/CPASParmInfo.hpp +++ b/Runtime/Character/CPASParmInfo.hpp @@ -9,14 +9,27 @@ namespace urde class CPASParmInfo { +public: + enum class EWeightFunction + { + ExactMatch, + PercentError, + AngularPercent, + Three + }; + CPASAnimParm::EParmType x0_type; - u32 x4_unk1; - float x8_unk2; - CPASAnimParm::UParmValue xc_val1; - CPASAnimParm::UParmValue x10_val2; + EWeightFunction x4_weightFunction; + float x8_weight; + CPASAnimParm::UParmValue xc_min; + CPASAnimParm::UParmValue x10_max; public: CPASParmInfo(CInputStream& in); - CPASAnimParm::EParmType GetType() const {return x0_type;} + CPASAnimParm::EParmType GetParameterType() const {return x0_type;} + EWeightFunction GetWeightFunction() const { return x4_weightFunction; } + float GetParameterWeight() const { return x8_weight; } + CPASAnimParm::UParmValue GetWeightMinValue() const { return xc_min; } + CPASAnimParm::UParmValue GetWeightMaxValue() const { return x10_max; } }; } diff --git a/Runtime/Character/CharacterCommon.hpp b/Runtime/Character/CharacterCommon.hpp index dfad77abe..eea0cc8b9 100644 --- a/Runtime/Character/CharacterCommon.hpp +++ b/Runtime/Character/CharacterCommon.hpp @@ -17,8 +17,73 @@ enum class EAnimationState { }; +enum class EHurledType +{ + +}; + enum class EFallState { +}; + +enum class EReactionType +{ + +}; + +enum class EAdditiveReactionType +{ + +}; + +enum class EJumpType +{ + +}; + +enum class EStepDirection +{ + +}; + +enum class EStepType +{ + +}; + +enum class ESeverity +{ + +}; + +enum class EGetupType +{ + +}; + +enum class ELoopAttackType +{ + +}; + +enum class EGenerateType +{ + +}; + +enum class ESlideType +{ + +}; + +enum class ETauntType +{ + +}; + +enum class ECoverDirection +{ + }; } @@ -32,6 +97,7 @@ enum class EBodyStateCmd { }; + } #endif // __URDE_PASTYPES_HPP__