2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 02:27:43 +00:00

CPASDatabase imps

This commit is contained in:
2016-08-20 22:47:47 -07:00
parent 6cb956cced
commit 4244f39bd5
11 changed files with 320 additions and 34 deletions

View File

@@ -1,5 +1,10 @@
#include "CPASAnimState.hpp"
#include "CPASAnimParmData.hpp"
#include "CRandom16.hpp"
#include "zeus/Math.hpp"
#include <math.h>
#include <float.h>
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<parmCount ; ++i)
x4_parms.emplace_back(in);
@@ -23,7 +28,7 @@ CPASAnimState::CPASAnimState(CInputStream& in)
for (const CPASParmInfo& parm : x4_parms)
{
CPASAnimParm::UParmValue val = {};
switch (parm.GetType())
switch (parm.GetParameterType())
{
case CPASAnimParm::EParmType::Int32:
val.m_int = in.readInt32Big();
@@ -51,14 +56,194 @@ CPASAnimState::CPASAnimState(CInputStream& in)
}
}
const CPASAnimParmData& CPASAnimState::GetAnimParmData(s32, u32) const
CPASAnimParm CPASAnimState::GetAnimParmData(s32 idx, u32 id) const
{
static const CPASAnimParmData badData;
return badData;
auto search = std::lower_bound(x14_anims.begin(), x14_anims.end(), id,
[](const CPASAnimInfo& item, const u32& testId) ->
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<float, s32> CPASAnimState::FindBestAnimation(const rstl::reserved_vector<CPASAnimParm, 8>&, 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<float, s32> CPASAnimState::FindBestAnimation(const rstl::reserved_vector<CPASAnimParm, 8>& parms,
CRandom16& rand, s32 anim) const
{
const_cast<std::vector<s32>*>(&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<x4_parms.size() ; ++i)
{
CPASAnimParm::UParmValue val = info.GetAnimParmValue(i);
const CPASParmInfo& parmInfo = x4_parms[i];
float parmWeight = parmInfo.GetParameterWeight();
float computedWeight;
if (parmInfo.GetWeightFunction() == CPASParmInfo::EWeightFunction::AngularPercent)
computedWeight = ComputeAngularPercentErrorWeight(i, parms[i], val);
else if (parmInfo.GetWeightFunction() == CPASParmInfo::EWeightFunction::ExactMatch)
computedWeight = ComputeExactMatchWeight(i, parms[i], val);
else if (parmInfo.GetWeightFunction() == CPASParmInfo::EWeightFunction::PercentError)
computedWeight = ComputePercentErrorWeight(i, parms[i], val);
else if (parmInfo.GetWeightFunction() == CPASParmInfo::EWeightFunction::Three)
r23++;
calcWeight = parmWeight * calcWeight + computedWeight;
}
if (r23 == x4_parms.size())
calcWeight = 1.0f;
if (calcWeight < weight)
continue;
auto search = std::find(x24_selectionCache.cbegin(), x24_selectionCache.cend(),
info.GetAnimId());
if (search == x24_selectionCache.cend())
const_cast<std::vector<s32>*>(&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);
}
}