mirror of https://github.com/AxioDL/metaforce.git
235 lines
9.1 KiB
C++
235 lines
9.1 KiB
C++
#include "CAnimTreeTimeScale.hpp"
|
|
|
|
namespace urde
|
|
{
|
|
|
|
CAnimTreeTimeScale::CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>& node, float scale,
|
|
std::string_view name)
|
|
: CAnimTreeSingleChild(node, name)
|
|
, x18_timeScale(new CConstantAnimationTimeScale(scale))
|
|
, x28_targetAccelTime(CCharAnimTime::Infinity())
|
|
{
|
|
}
|
|
|
|
CAnimTreeTimeScale::CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>& node,
|
|
std::unique_ptr<IVaryingAnimationTimeScale>&& timeScale,
|
|
const CCharAnimTime& time, std::string_view name)
|
|
: CAnimTreeSingleChild(node, name)
|
|
, x18_timeScale(std::move(timeScale))
|
|
, x28_targetAccelTime(time)
|
|
{
|
|
x30_initialTime = x14_child->VGetSteadyStateAnimInfo().GetDuration() - x14_child->VGetTimeRemaining();
|
|
}
|
|
|
|
std::string CAnimTreeTimeScale::CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, float,
|
|
const CCharAnimTime&, float)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
CCharAnimTime CAnimTreeTimeScale::GetRealLifeTime(const CCharAnimTime& time) const
|
|
{
|
|
CCharAnimTime timeRem = x14_child->VGetTimeRemaining();
|
|
|
|
CCharAnimTime ret = std::min(timeRem, time);
|
|
if (x28_targetAccelTime > CCharAnimTime())
|
|
{
|
|
if (ret < CCharAnimTime(x28_targetAccelTime - x20_curAccelTime))
|
|
return x18_timeScale->VTimeScaleIntegral(x20_curAccelTime.GetSeconds(),
|
|
(x20_curAccelTime + ret).GetSeconds());
|
|
else
|
|
{
|
|
CCharAnimTime integral =
|
|
x18_timeScale->VTimeScaleIntegral(x20_curAccelTime.GetSeconds(), x28_targetAccelTime.GetSeconds());
|
|
|
|
if (integral > ret)
|
|
return x18_timeScale->VFindUpperLimit(x20_curAccelTime.GetSeconds(), ret.GetSeconds()) -
|
|
x20_curAccelTime.GetSeconds();
|
|
else
|
|
return integral + (ret - integral);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void CAnimTreeTimeScale::VSetPhase(float phase)
|
|
{
|
|
x14_child->VSetPhase(phase);
|
|
}
|
|
|
|
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTimeScale::VSimplified()
|
|
{
|
|
if (auto simp = x14_child->Simplified())
|
|
{
|
|
CAnimTreeTimeScale* newNode = new CAnimTreeTimeScale(CAnimTreeNode::Cast(std::move(*simp)),
|
|
x18_timeScale->Clone(), x28_targetAccelTime, x4_name);
|
|
newNode->x20_curAccelTime = x20_curAccelTime;
|
|
newNode->x30_initialTime = x30_initialTime;
|
|
return {std::unique_ptr<IAnimReader>(newNode)};
|
|
}
|
|
else if (x20_curAccelTime == x28_targetAccelTime)
|
|
{
|
|
return {x14_child->Clone()};
|
|
}
|
|
return {};
|
|
}
|
|
|
|
u32 CAnimTreeTimeScale::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut,
|
|
u32 capacity, u32 iterator, u32 unk) const
|
|
{
|
|
CCharAnimTime useTime = (time == CCharAnimTime::Infinity()) ?
|
|
x14_child->VGetTimeRemaining() : GetRealLifeTime(time);
|
|
u32 ret = x14_child->GetBoolPOIList(useTime, listOut, capacity, iterator, unk);
|
|
if (x28_targetAccelTime > CCharAnimTime())
|
|
for (int i=0 ; i<ret ; ++i)
|
|
listOut[iterator + i].SetTime(GetRealLifeTime(listOut[i].GetTime()));
|
|
return ret;
|
|
}
|
|
|
|
u32 CAnimTreeTimeScale::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut,
|
|
u32 capacity, u32 iterator, u32 unk) const
|
|
{
|
|
CCharAnimTime useTime = (time == CCharAnimTime::Infinity()) ?
|
|
x14_child->VGetTimeRemaining() : GetRealLifeTime(time);
|
|
u32 ret = x14_child->GetInt32POIList(useTime, listOut, capacity, iterator, unk);
|
|
if (x28_targetAccelTime > CCharAnimTime())
|
|
for (int i=0 ; i<ret ; ++i)
|
|
listOut[iterator + i].SetTime(GetRealLifeTime(listOut[i].GetTime()));
|
|
return ret;
|
|
}
|
|
|
|
u32 CAnimTreeTimeScale::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut,
|
|
u32 capacity, u32 iterator, u32 unk) const
|
|
{
|
|
CCharAnimTime useTime = (time == CCharAnimTime::Infinity()) ?
|
|
x14_child->VGetTimeRemaining() : GetRealLifeTime(time);
|
|
u32 ret = x14_child->GetParticlePOIList(useTime, listOut, capacity, iterator, unk);
|
|
if (x28_targetAccelTime > CCharAnimTime())
|
|
for (int i=0 ; i<ret ; ++i)
|
|
listOut[iterator + i].SetTime(GetRealLifeTime(listOut[i].GetTime()));
|
|
return ret;
|
|
}
|
|
|
|
u32 CAnimTreeTimeScale::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut,
|
|
u32 capacity, u32 iterator, u32 unk) const
|
|
{
|
|
CCharAnimTime useTime = (time == CCharAnimTime::Infinity()) ?
|
|
x14_child->VGetTimeRemaining() : GetRealLifeTime(time);
|
|
u32 ret = x14_child->GetSoundPOIList(useTime, listOut, capacity, iterator, unk);
|
|
if (x28_targetAccelTime > CCharAnimTime())
|
|
for (int i=0 ; i<ret ; ++i)
|
|
listOut[iterator + i].SetTime(GetRealLifeTime(listOut[i].GetTime()));
|
|
return ret;
|
|
}
|
|
|
|
bool CAnimTreeTimeScale::VGetBoolPOIState(const char* name) const
|
|
{
|
|
return x14_child->VGetBoolPOIState(name);
|
|
}
|
|
|
|
s32 CAnimTreeTimeScale::VGetInt32POIState(const char* name) const
|
|
{
|
|
return x14_child->VGetInt32POIState(name);
|
|
}
|
|
|
|
CParticleData::EParentedMode CAnimTreeTimeScale::VGetParticlePOIState(const char* name) const
|
|
{
|
|
return x14_child->VGetParticlePOIState(name);
|
|
}
|
|
|
|
CAnimTreeEffectiveContribution CAnimTreeTimeScale::VGetContributionOfHighestInfluence() const
|
|
{
|
|
CAnimTreeEffectiveContribution c = x14_child->VGetContributionOfHighestInfluence();
|
|
return {c.GetContributionWeight(), c.GetPrimitiveName(), VGetSteadyStateAnimInfo(),
|
|
VGetTimeRemaining(), c.GetAnimDatabaseIndex()};
|
|
}
|
|
|
|
std::shared_ptr<IAnimReader> CAnimTreeTimeScale::VGetBestUnblendedChild() const
|
|
{
|
|
if (std::shared_ptr<IAnimReader> bestChild = x14_child->VGetBestUnblendedChild())
|
|
{
|
|
CAnimTreeTimeScale* newNode = new CAnimTreeTimeScale(CAnimTreeNode::Cast(bestChild->Clone()),
|
|
x18_timeScale->Clone(), x28_targetAccelTime, x4_name);
|
|
newNode->x20_curAccelTime = x20_curAccelTime;
|
|
newNode->x30_initialTime = x30_initialTime;
|
|
return {std::shared_ptr<IAnimReader>(newNode)};
|
|
}
|
|
return {};
|
|
}
|
|
|
|
std::unique_ptr<IAnimReader> CAnimTreeTimeScale::VClone() const
|
|
{
|
|
CAnimTreeTimeScale* newNode = new CAnimTreeTimeScale(CAnimTreeNode::Cast(x14_child->Clone()),
|
|
x18_timeScale->Clone(), x28_targetAccelTime, x4_name);
|
|
newNode->x20_curAccelTime = x20_curAccelTime;
|
|
newNode->x30_initialTime = x30_initialTime;
|
|
return {std::unique_ptr<IAnimReader>(newNode)};
|
|
}
|
|
|
|
CSteadyStateAnimInfo CAnimTreeTimeScale::VGetSteadyStateAnimInfo() const
|
|
{
|
|
CSteadyStateAnimInfo ssInfo = x14_child->VGetSteadyStateAnimInfo();
|
|
if (x28_targetAccelTime == CCharAnimTime::Infinity())
|
|
{
|
|
return {ssInfo.IsLooping(),
|
|
x18_timeScale->VFindUpperLimit(0.f, ssInfo.GetDuration().GetSeconds()), ssInfo.GetOffset()};
|
|
}
|
|
else
|
|
{
|
|
CCharAnimTime time;
|
|
if (x20_curAccelTime.GreaterThanZero())
|
|
time = x18_timeScale->VTimeScaleIntegral(0.f, x20_curAccelTime.GetSeconds());
|
|
return {ssInfo.IsLooping(), x30_initialTime + time + VGetTimeRemaining(), ssInfo.GetOffset()};
|
|
}
|
|
}
|
|
|
|
CCharAnimTime CAnimTreeTimeScale::VGetTimeRemaining() const
|
|
{
|
|
CCharAnimTime timeRem = x14_child->VGetTimeRemaining();
|
|
if (x28_targetAccelTime == CCharAnimTime::Infinity())
|
|
return CCharAnimTime(x18_timeScale->VFindUpperLimit(x20_curAccelTime.GetSeconds(),
|
|
timeRem.GetSeconds())) - x20_curAccelTime;
|
|
else
|
|
return GetRealLifeTime(timeRem);
|
|
}
|
|
|
|
SAdvancementResults CAnimTreeTimeScale::VAdvanceView(const CCharAnimTime& dt)
|
|
{
|
|
if (dt.EqualsZero() && dt > CCharAnimTime())
|
|
return x14_child->VAdvanceView(dt);
|
|
|
|
CCharAnimTime origAccelTime = x20_curAccelTime;
|
|
CCharAnimTime newTime = x20_curAccelTime + dt;
|
|
if (newTime < x28_targetAccelTime)
|
|
{
|
|
SAdvancementResults res = x14_child->VAdvanceView(
|
|
x18_timeScale->VTimeScaleIntegral(origAccelTime.GetSeconds(), newTime.GetSeconds()));
|
|
if (res.x0_remTime.EqualsZero())
|
|
{
|
|
x20_curAccelTime = newTime;
|
|
res.x0_remTime = CCharAnimTime();
|
|
return res;
|
|
}
|
|
else
|
|
{
|
|
x20_curAccelTime = x18_timeScale->VFindUpperLimit(origAccelTime.GetSeconds(),
|
|
(newTime - res.x0_remTime).GetSeconds());
|
|
res.x0_remTime = dt - (x20_curAccelTime - origAccelTime);
|
|
return res;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CCharAnimTime newDt(x18_timeScale->VTimeScaleIntegral(origAccelTime.GetSeconds(),
|
|
x28_targetAccelTime.GetSeconds()));
|
|
SAdvancementResults res2;
|
|
if (newDt.GreaterThanZero())
|
|
res2 = x14_child->VAdvanceView(newDt);
|
|
res2.x0_remTime = res2.x0_remTime + (newTime - x28_targetAccelTime);
|
|
return res2;
|
|
}
|
|
}
|
|
|
|
}
|