mirror of https://github.com/AxioDL/metaforce.git
All animation nodes implemented
This commit is contained in:
parent
bb10423267
commit
36f1473f3e
|
@ -19,33 +19,80 @@ CAnimTreeBlend::CAnimTreeBlend(bool b1,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults CAnimTreeBlend::VAdvanceView(const CCharAnimTime& a)
|
SAdvancementResults CAnimTreeBlend::VAdvanceView(const CCharAnimTime& dt)
|
||||||
{
|
{
|
||||||
return {};
|
IncAdvancementDepth();
|
||||||
|
SAdvancementResults resA = x14_a->VAdvanceView(dt);
|
||||||
|
SAdvancementResults resB = x18_b->VAdvanceView(dt);
|
||||||
|
DecAdvancementDepth();
|
||||||
|
if (ShouldCullTree())
|
||||||
|
{
|
||||||
|
if (GetBlendingWeight() < 0.5f)
|
||||||
|
x20_25_cullSelector = 1;
|
||||||
|
else
|
||||||
|
x20_25_cullSelector = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SAdvancementResults& maxRemTime = (resA.x0_remTime < resB.x0_remTime) ? resB : resA;
|
||||||
|
if (x1c_flags & 0x1)
|
||||||
|
{
|
||||||
|
return {maxRemTime.x0_remTime, SAdvancementDeltas::Blend(resA.x8_deltas, resB.x8_deltas,
|
||||||
|
GetBlendingWeight())};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return resB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCharAnimTime CAnimTreeBlend::VGetTimeRemaining() const
|
CCharAnimTime CAnimTreeBlend::VGetTimeRemaining() const
|
||||||
{
|
{
|
||||||
return {};
|
CCharAnimTime remA = x14_a->VGetTimeRemaining();
|
||||||
|
CCharAnimTime remB = x18_b->VGetTimeRemaining();
|
||||||
|
return (remA < remB) ? remB : remA;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSteadyStateAnimInfo CAnimTreeBlend::VGetSteadyStateAnimInfo() const
|
CSteadyStateAnimInfo CAnimTreeBlend::VGetSteadyStateAnimInfo() const
|
||||||
{
|
{
|
||||||
return {};
|
CSteadyStateAnimInfo ssA = x14_a->VGetSteadyStateAnimInfo();
|
||||||
|
CSteadyStateAnimInfo ssB = x18_b->VGetSteadyStateAnimInfo();
|
||||||
|
zeus::CVector3f resOffset;
|
||||||
|
if (ssA.GetDuration() < ssB.GetDuration())
|
||||||
|
{
|
||||||
|
resOffset = ssA.GetOffset() * (ssB.GetDuration() / ssA.GetDuration()) * x24_blendWeight +
|
||||||
|
ssB.GetOffset() * (1.f - x24_blendWeight);
|
||||||
|
}
|
||||||
|
else if (ssB.GetDuration() < ssA.GetDuration())
|
||||||
|
{
|
||||||
|
resOffset = ssA.GetOffset() * x24_blendWeight +
|
||||||
|
ssB.GetOffset() * (ssA.GetDuration() / ssB.GetDuration()) * (1.f - x24_blendWeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resOffset = ssA.GetOffset() + ssB.GetOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {ssA.IsLooping(),
|
||||||
|
(ssA.GetDuration() < ssB.GetDuration()) ? ssB.GetDuration() : ssA.GetDuration(),
|
||||||
|
resOffset};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IAnimReader> CAnimTreeBlend::VClone() const
|
std::unique_ptr<IAnimReader> CAnimTreeBlend::VClone() const
|
||||||
{
|
{
|
||||||
return {};
|
return std::make_unique<CAnimTreeBlend>(x20_24_b1,
|
||||||
|
CAnimTreeNode::Cast(x14_a->Clone()),
|
||||||
|
CAnimTreeNode::Cast(x18_b->Clone()),
|
||||||
|
x24_blendWeight, x4_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeBlend::SetBlendingWeight(float w)
|
void CAnimTreeBlend::SetBlendingWeight(float w)
|
||||||
{
|
{
|
||||||
|
x24_blendWeight = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CAnimTreeBlend::VGetBlendingWeight() const
|
float CAnimTreeBlend::VGetBlendingWeight() const
|
||||||
{
|
{
|
||||||
return 0.f;
|
return x24_blendWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
const std::shared_ptr<CAnimTreeNode>& b,
|
const std::shared_ptr<CAnimTreeNode>& b,
|
||||||
float blendWeight, std::string_view name);
|
float blendWeight, std::string_view name);
|
||||||
|
|
||||||
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
|
SAdvancementResults VAdvanceView(const CCharAnimTime& dt);
|
||||||
CCharAnimTime VGetTimeRemaining() const;
|
CCharAnimTime VGetTimeRemaining() const;
|
||||||
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
||||||
std::unique_ptr<IAnimReader> VClone() const;
|
std::unique_ptr<IAnimReader> VClone() const;
|
||||||
|
|
|
@ -128,33 +128,55 @@ CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(const ch
|
||||||
return x18_b->VGetParticlePOIState(name);
|
return x18_b->VGetParticlePOIState(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeDoubleChild::VSetPhase(float)
|
void CAnimTreeDoubleChild::VSetPhase(float phase)
|
||||||
{
|
{
|
||||||
|
x14_a->VSetPhase(phase);
|
||||||
|
x18_b->VSetPhase(phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults CAnimTreeDoubleChild::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
|
SAdvancementResults CAnimTreeDoubleChild::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
|
||||||
{
|
{
|
||||||
return {};
|
SAdvancementResults resA = x14_a->VGetAdvancementResults(a, b);
|
||||||
|
SAdvancementResults resB = x18_b->VGetAdvancementResults(a, b);
|
||||||
|
return (resA.x0_remTime > resB.x0_remTime) ? resA : resB;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeDoubleChild::Depth() const
|
u32 CAnimTreeDoubleChild::Depth() const
|
||||||
{
|
{
|
||||||
return 0;
|
return std::max(x14_a->Depth(), x18_b->Depth()) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAnimTreeEffectiveContribution CAnimTreeDoubleChild::VGetContributionOfHighestInfluence() const
|
CAnimTreeEffectiveContribution CAnimTreeDoubleChild::VGetContributionOfHighestInfluence() const
|
||||||
{
|
{
|
||||||
return {0.f, "", CSteadyStateAnimInfo(), CCharAnimTime(), 0};
|
CAnimTreeEffectiveContribution cA = x14_a->GetContributionOfHighestInfluence();
|
||||||
|
CAnimTreeEffectiveContribution cB = x18_b->GetContributionOfHighestInfluence();
|
||||||
|
|
||||||
|
float leftWeight = (1.f - VGetRightChildWeight()) * cA.GetContributionWeight();
|
||||||
|
float rightWeight = VGetRightChildWeight() * cB.GetContributionWeight();
|
||||||
|
|
||||||
|
if (leftWeight > rightWeight)
|
||||||
|
{
|
||||||
|
return {leftWeight, cA.GetPrimitiveName(), cA.GetSteadyStateAnimInfo(),
|
||||||
|
cA.GetTimeRemaining(), cA.GetAnimDatabaseIndex()};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {rightWeight, cB.GetPrimitiveName(), cB.GetSteadyStateAnimInfo(),
|
||||||
|
cB.GetTimeRemaining(), cB.GetAnimDatabaseIndex()};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeDoubleChild::VGetNumChildren() const
|
u32 CAnimTreeDoubleChild::VGetNumChildren() const
|
||||||
{
|
{
|
||||||
return 0;
|
return x14_a->VGetNumChildren() + x18_b->VGetNumChildren() + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IAnimReader> CAnimTreeDoubleChild::VGetBestUnblendedChild() const
|
std::shared_ptr<IAnimReader> CAnimTreeDoubleChild::VGetBestUnblendedChild() const
|
||||||
{
|
{
|
||||||
return {};
|
std::shared_ptr<CAnimTreeNode> bestChild = (VGetRightChildWeight() > 0.5f) ? x18_b : x14_a;
|
||||||
|
if (!bestChild)
|
||||||
|
return {};
|
||||||
|
return bestChild->GetBestUnblendedChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeDoubleChild::VGetWeightedReaders(
|
void CAnimTreeDoubleChild::VGetWeightedReaders(
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include "CAnimTreeLoopIn.hpp"
|
||||||
|
#include "CTreeUtils.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string CAnimTreeLoopIn::CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& c)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
CAnimTreeLoopIn::CAnimTreeLoopIn(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& c,
|
||||||
|
const CAnimSysContext& animCtx,
|
||||||
|
std::string_view name)
|
||||||
|
: CAnimTreeSingleChild(CTreeUtils::GetTransitionTree(a, c, animCtx), name),
|
||||||
|
x18_nextAnim(b.lock()), x20_animCtx(animCtx),
|
||||||
|
x30_fundamentals(CSequenceHelper(x14_child, x18_nextAnim, animCtx).ComputeSequenceFundamentals())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CAnimTreeLoopIn::CAnimTreeLoopIn(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
|
bool didLoopIn,
|
||||||
|
const CAnimSysContext& animCtx,
|
||||||
|
std::string_view name,
|
||||||
|
const CSequenceFundamentals& fundamentals,
|
||||||
|
const CCharAnimTime& time)
|
||||||
|
: CAnimTreeSingleChild(a, name), x18_nextAnim(b.lock()), x1c_didLoopIn(didLoopIn), x20_animCtx(animCtx),
|
||||||
|
x30_fundamentals(fundamentals), x88_curTime(time)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CAnimTreeEffectiveContribution CAnimTreeLoopIn::VGetContributionOfHighestInfluence() const
|
||||||
|
{
|
||||||
|
return x14_child->GetContributionOfHighestInfluence();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeLoopIn::VSimplified()
|
||||||
|
{
|
||||||
|
CCharAnimTime remTime = x14_child->VGetTimeRemaining();
|
||||||
|
if (remTime.GreaterThanZero() && !remTime.EpsilonZero())
|
||||||
|
{
|
||||||
|
auto simp = x14_child->Simplified();
|
||||||
|
if (simp)
|
||||||
|
x14_child = CAnimTreeNode::Cast(std::move(*simp));
|
||||||
|
}
|
||||||
|
else if (x1c_didLoopIn && x14_child->VGetTimeRemaining().EqualsZero())
|
||||||
|
{
|
||||||
|
return x14_child->Clone();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<IAnimReader> CAnimTreeLoopIn::VGetBestUnblendedChild() const
|
||||||
|
{
|
||||||
|
if (std::shared_ptr<IAnimReader> bestChild = x14_child->GetBestUnblendedChild())
|
||||||
|
{
|
||||||
|
return std::make_shared<CAnimTreeLoopIn>(CAnimTreeNode::Cast(bestChild->Clone()),
|
||||||
|
x18_nextAnim, x1c_didLoopIn, x20_animCtx, x4_name,
|
||||||
|
x30_fundamentals, x88_curTime);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IAnimReader> CAnimTreeLoopIn::VClone() const
|
||||||
|
{
|
||||||
|
return std::make_unique<CAnimTreeLoopIn>(CAnimTreeNode::Cast(x14_child->Clone()),
|
||||||
|
x18_nextAnim, x1c_didLoopIn, x20_animCtx, x4_name,
|
||||||
|
x30_fundamentals, x88_curTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CAnimTreeLoopIn::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut,
|
||||||
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
|
{
|
||||||
|
return _getPOIList<CBoolPOINode>(time, listOut, capacity, iterator, unk,
|
||||||
|
x30_fundamentals.GetBoolPointsOfInterest(), x88_curTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CAnimTreeLoopIn::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut,
|
||||||
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
|
{
|
||||||
|
return _getPOIList<CInt32POINode>(time, listOut, capacity, iterator, unk,
|
||||||
|
x30_fundamentals.GetInt32PointsOfInterest(), x88_curTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CAnimTreeLoopIn::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut,
|
||||||
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
|
{
|
||||||
|
return _getPOIList<CParticlePOINode>(time, listOut, capacity, iterator, unk,
|
||||||
|
x30_fundamentals.GetParticlePointsOfInterest(), x88_curTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CAnimTreeLoopIn::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut,
|
||||||
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
|
{
|
||||||
|
return _getPOIList<CSoundPOINode>(time, listOut, capacity, iterator, unk,
|
||||||
|
x30_fundamentals.GetSoundPointsOfInterest(), x88_curTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSteadyStateAnimInfo CAnimTreeLoopIn::VGetSteadyStateAnimInfo() const
|
||||||
|
{
|
||||||
|
return x30_fundamentals.GetSteadyStateAnimInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
CCharAnimTime CAnimTreeLoopIn::VGetTimeRemaining() const
|
||||||
|
{
|
||||||
|
return x30_fundamentals.GetSteadyStateAnimInfo().GetDuration() - x88_curTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
SAdvancementResults CAnimTreeLoopIn::VAdvanceView(const CCharAnimTime& dt)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CAnimTreeNode> origChild = x14_child;
|
||||||
|
SAdvancementResults res = origChild->VAdvanceView(dt);
|
||||||
|
x88_curTime += dt - res.x0_remTime;
|
||||||
|
CCharAnimTime remTime = origChild->VGetTimeRemaining();
|
||||||
|
if ((remTime.EpsilonZero() || (dt - res.x0_remTime).EpsilonZero()) && !x1c_didLoopIn)
|
||||||
|
{
|
||||||
|
x14_child = CTreeUtils::GetTransitionTree(origChild, x18_nextAnim, x20_animCtx);
|
||||||
|
x1c_didLoopIn = true;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,48 @@
|
||||||
#ifndef __URDE_CANIMTREELOOPIN_HPP__
|
#ifndef __URDE_CANIMTREELOOPIN_HPP__
|
||||||
#define __URDE_CANIMTREELOOPIN_HPP__
|
#define __URDE_CANIMTREELOOPIN_HPP__
|
||||||
|
|
||||||
|
#include "CAnimTreeSingleChild.hpp"
|
||||||
|
#include "CAnimSysContext.hpp"
|
||||||
|
#include "CSequenceHelper.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
class CAnimTreeLoopIn
|
class CAnimTreeLoopIn : public CAnimTreeSingleChild
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<CAnimTreeNode> x18_nextAnim;
|
||||||
|
bool x1c_didLoopIn = false;
|
||||||
|
CAnimSysContext x20_animCtx;
|
||||||
|
CSequenceFundamentals x30_fundamentals;
|
||||||
|
CCharAnimTime x88_curTime;
|
||||||
|
public:
|
||||||
|
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& c);
|
||||||
|
CAnimTreeLoopIn(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& c,
|
||||||
|
const CAnimSysContext& animCtx,
|
||||||
|
std::string_view name);
|
||||||
|
CAnimTreeLoopIn(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
|
bool didLoopIn,
|
||||||
|
const CAnimSysContext& animCtx,
|
||||||
|
std::string_view name,
|
||||||
|
const CSequenceFundamentals& fundamentals,
|
||||||
|
const CCharAnimTime& time);
|
||||||
|
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
|
||||||
|
bool VSupportsReverseView() const { return false; }
|
||||||
|
std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
|
||||||
|
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
|
||||||
|
std::unique_ptr<IAnimReader> VClone() const;
|
||||||
|
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
u32 VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
u32 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
||||||
|
CCharAnimTime VGetTimeRemaining() const;
|
||||||
|
SAdvancementResults VAdvanceView(const CCharAnimTime& dt);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CAnimTreeSequence.hpp"
|
#include "CAnimTreeSequence.hpp"
|
||||||
#include "IMetaAnim.hpp"
|
#include "IMetaAnim.hpp"
|
||||||
#include "CAnimSysContext.hpp"
|
#include "CAnimSysContext.hpp"
|
||||||
|
#include "CTreeUtils.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -9,7 +10,8 @@ CAnimTreeSequence::CAnimTreeSequence(const std::vector<std::shared_ptr<IMetaAnim
|
||||||
const CAnimSysContext& animSys,
|
const CAnimSysContext& animSys,
|
||||||
std::string_view name)
|
std::string_view name)
|
||||||
: CAnimTreeSingleChild(seq[0]->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders()), name),
|
: CAnimTreeSingleChild(seq[0]->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders()), name),
|
||||||
x18_(animSys), x3c_fundamentals(CSequenceHelper(seq, animSys).ComputeSequenceFundamentals()), x94_curTime(0.f)
|
x18_animCtx(animSys), x28_sequence(seq),
|
||||||
|
x3c_fundamentals(CSequenceHelper(seq, animSys).ComputeSequenceFundamentals()), x94_curTime(0.f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +21,8 @@ CAnimTreeSequence::CAnimTreeSequence(const std::shared_ptr<CAnimTreeNode>& curNo
|
||||||
std::string_view name,
|
std::string_view name,
|
||||||
const CSequenceFundamentals& fundamentals,
|
const CSequenceFundamentals& fundamentals,
|
||||||
const CCharAnimTime& time)
|
const CCharAnimTime& time)
|
||||||
: CAnimTreeSingleChild(curNode, name), x18_(animSys), x28_(metaAnims), x3c_fundamentals(fundamentals), x94_curTime(time)
|
: CAnimTreeSingleChild(curNode, name), x18_animCtx(animSys), x28_sequence(metaAnims),
|
||||||
|
x3c_fundamentals(fundamentals), x94_curTime(time)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,17 +38,62 @@ std::shared_ptr<IAnimReader> CAnimTreeSequence::VGetBestUnblendedChild() const
|
||||||
return ch;
|
return ch;
|
||||||
return std::make_shared<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(
|
return std::make_shared<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(
|
||||||
std::shared_ptr<IAnimReader>(ch->Clone())),
|
std::shared_ptr<IAnimReader>(ch->Clone())),
|
||||||
x28_, x18_, x4_name, x3c_fundamentals, x94_curTime);
|
x28_sequence, x18_animCtx, x4_name, x3c_fundamentals, x94_curTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults CAnimTreeSequence::VAdvanceView(const CCharAnimTime& a)
|
SAdvancementResults CAnimTreeSequence::VAdvanceView(const CCharAnimTime& dt)
|
||||||
{
|
{
|
||||||
return {};
|
CCharAnimTime totalDelta;
|
||||||
|
zeus::CVector3f posDelta;
|
||||||
|
zeus::CQuaternion rotDelta;
|
||||||
|
|
||||||
|
std::shared_ptr<CAnimTreeNode> curChild = x14_child;
|
||||||
|
if (x38_curIdx >= x28_sequence.size() && curChild->VGetTimeRemaining().EqualsZero())
|
||||||
|
{
|
||||||
|
x3c_fundamentals = CSequenceHelper(x28_sequence, x18_animCtx).ComputeSequenceFundamentals();
|
||||||
|
x38_curIdx = 0;
|
||||||
|
x14_child = CTreeUtils::GetTransitionTree(curChild, x28_sequence[x38_curIdx]->GetAnimationTree(
|
||||||
|
x18_animCtx, CMetaAnimTreeBuildOrders::NoSpecialOrders()), x18_animCtx);
|
||||||
|
curChild = x14_child;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCharAnimTime remTime = dt;
|
||||||
|
while (remTime.GreaterThanZero() && x38_curIdx < x28_sequence.size())
|
||||||
|
{
|
||||||
|
CCharAnimTime chRem = curChild->VGetTimeRemaining();
|
||||||
|
if (chRem.EqualsZero())
|
||||||
|
{
|
||||||
|
++x38_curIdx;
|
||||||
|
if (x38_curIdx < x28_sequence.size())
|
||||||
|
{
|
||||||
|
x14_child = CTreeUtils::GetTransitionTree(curChild, x28_sequence[x38_curIdx]->GetAnimationTree(
|
||||||
|
x18_animCtx, CMetaAnimTreeBuildOrders::NoSpecialOrders()), x18_animCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curChild = x14_child;
|
||||||
|
if (x38_curIdx < x28_sequence.size())
|
||||||
|
{
|
||||||
|
SAdvancementResults res = curChild->VAdvanceView(remTime);
|
||||||
|
if (auto simp = curChild->Simplified())
|
||||||
|
{
|
||||||
|
curChild = CAnimTreeNode::Cast(std::move(*simp));
|
||||||
|
x14_child = curChild;
|
||||||
|
}
|
||||||
|
CCharAnimTime prevRemTime = remTime;
|
||||||
|
remTime = res.x0_remTime;
|
||||||
|
totalDelta += prevRemTime - remTime;
|
||||||
|
posDelta += res.x8_deltas.x0_posDelta;
|
||||||
|
rotDelta = rotDelta * res.x8_deltas.xc_rotDelta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x94_curTime += totalDelta;
|
||||||
|
return {dt - totalDelta, {posDelta, rotDelta}};
|
||||||
}
|
}
|
||||||
|
|
||||||
CCharAnimTime CAnimTreeSequence::VGetTimeRemaining() const
|
CCharAnimTime CAnimTreeSequence::VGetTimeRemaining() const
|
||||||
{
|
{
|
||||||
if (x38_curIdx == x28_.size() - 1)
|
if (x38_curIdx == x28_sequence.size() - 1)
|
||||||
return x14_child->VGetTimeRemaining();
|
return x14_child->VGetTimeRemaining();
|
||||||
return x3c_fundamentals.GetSteadyStateAnimInfo().GetDuration() - x94_curTime.GetSeconds();
|
return x3c_fundamentals.GetSteadyStateAnimInfo().GetDuration() - x94_curTime.GetSeconds();
|
||||||
}
|
}
|
||||||
|
@ -87,7 +135,7 @@ std::unique_ptr<IAnimReader> CAnimTreeSequence::VClone() const
|
||||||
{
|
{
|
||||||
return std::make_unique<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(
|
return std::make_unique<CAnimTreeSequence>(std::static_pointer_cast<CAnimTreeNode>(
|
||||||
std::shared_ptr<IAnimReader>(x14_child->Clone())),
|
std::shared_ptr<IAnimReader>(x14_child->Clone())),
|
||||||
x28_, x18_, x4_name, x3c_fundamentals, x94_curTime);
|
x28_sequence, x18_animCtx, x4_name, x3c_fundamentals, x94_curTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ class CTransitionDatabaseGame;
|
||||||
|
|
||||||
class CAnimTreeSequence : public CAnimTreeSingleChild
|
class CAnimTreeSequence : public CAnimTreeSingleChild
|
||||||
{
|
{
|
||||||
CAnimSysContext x18_;
|
CAnimSysContext x18_animCtx;
|
||||||
std::vector<std::shared_ptr<IMetaAnim>> x28_;
|
std::vector<std::shared_ptr<IMetaAnim>> x28_sequence;
|
||||||
u32 x38_curIdx = 0;
|
u32 x38_curIdx = 0;
|
||||||
CSequenceFundamentals x3c_fundamentals;
|
CSequenceFundamentals x3c_fundamentals;
|
||||||
CCharAnimTime x94_curTime;
|
CCharAnimTime x94_curTime;
|
||||||
|
@ -30,8 +30,9 @@ public:
|
||||||
|
|
||||||
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
|
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
|
||||||
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
|
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
|
||||||
|
bool VSupportsReverseView() const { return false; }
|
||||||
|
|
||||||
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
|
SAdvancementResults VAdvanceView(const CCharAnimTime& dt);
|
||||||
CCharAnimTime VGetTimeRemaining() const;
|
CCharAnimTime VGetTimeRemaining() const;
|
||||||
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
||||||
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
|
|
@ -7,107 +7,109 @@ CAnimTreeSingleChild::CAnimTreeSingleChild(const std::weak_ptr<CAnimTreeNode>& n
|
||||||
: CAnimTreeNode(name)
|
: CAnimTreeNode(name)
|
||||||
, x14_child(node.lock())
|
, x14_child(node.lock())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults CAnimTreeSingleChild::VAdvanceView(const CCharAnimTime& a)
|
SAdvancementResults CAnimTreeSingleChild::VAdvanceView(const CCharAnimTime& dt)
|
||||||
{
|
{
|
||||||
return {};
|
return x14_child->VAdvanceView(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCharAnimTime CAnimTreeSingleChild::VGetTimeRemaining() const
|
CCharAnimTime CAnimTreeSingleChild::VGetTimeRemaining() const
|
||||||
{
|
{
|
||||||
return {};
|
return x14_child->VGetTimeRemaining();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAnimTreeSingleChild::VHasOffset(const CSegId& seg) const
|
bool CAnimTreeSingleChild::VHasOffset(const CSegId& seg) const
|
||||||
{
|
{
|
||||||
return false;
|
return x14_child->VHasOffset(seg);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CVector3f CAnimTreeSingleChild::VGetOffset(const CSegId& seg) const
|
zeus::CVector3f CAnimTreeSingleChild::VGetOffset(const CSegId& seg) const
|
||||||
{
|
{
|
||||||
return {};
|
return x14_child->VGetOffset(seg);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CQuaternion CAnimTreeSingleChild::VGetRotation(const CSegId& seg) const
|
zeus::CQuaternion CAnimTreeSingleChild::VGetRotation(const CSegId& seg) const
|
||||||
{
|
{
|
||||||
return {};
|
return x14_child->VGetRotation(seg);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeSingleChild::VGetBoolPOIList(const CCharAnimTime& time,
|
u32 CAnimTreeSingleChild::VGetBoolPOIList(const CCharAnimTime& time,
|
||||||
CBoolPOINode* listOut,
|
CBoolPOINode* listOut,
|
||||||
u32 capacity, u32 iterator, u32) const
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
{
|
{
|
||||||
return 0;
|
return x14_child->GetBoolPOIList(time, listOut, capacity, iterator, unk);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeSingleChild::VGetInt32POIList(const CCharAnimTime& time,
|
u32 CAnimTreeSingleChild::VGetInt32POIList(const CCharAnimTime& time,
|
||||||
CInt32POINode* listOut,
|
CInt32POINode* listOut,
|
||||||
u32 capacity, u32 iterator, u32) const
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
{
|
{
|
||||||
return 0;
|
return x14_child->GetInt32POIList(time, listOut, capacity, iterator, unk);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeSingleChild::VGetParticlePOIList(const CCharAnimTime& time,
|
u32 CAnimTreeSingleChild::VGetParticlePOIList(const CCharAnimTime& time,
|
||||||
CParticlePOINode* listOut,
|
CParticlePOINode* listOut,
|
||||||
u32 capacity, u32 iterator, u32) const
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
{
|
{
|
||||||
return 0;
|
return x14_child->GetParticlePOIList(time, listOut, capacity, iterator, unk);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeSingleChild::VGetSoundPOIList(const CCharAnimTime& time,
|
u32 CAnimTreeSingleChild::VGetSoundPOIList(const CCharAnimTime& time,
|
||||||
CSoundPOINode* listOut,
|
CSoundPOINode* listOut,
|
||||||
u32 capacity, u32 iterator, u32) const
|
u32 capacity, u32 iterator, u32 unk) const
|
||||||
{
|
{
|
||||||
return 0;
|
return x14_child->GetSoundPOIList(time, listOut, capacity, iterator, unk);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAnimTreeSingleChild::VGetBoolPOIState(const char* name) const
|
bool CAnimTreeSingleChild::VGetBoolPOIState(const char* name) const
|
||||||
{
|
{
|
||||||
return false;
|
return x14_child->VGetBoolPOIState(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 CAnimTreeSingleChild::VGetInt32POIState(const char* name) const
|
s32 CAnimTreeSingleChild::VGetInt32POIState(const char* name) const
|
||||||
{
|
{
|
||||||
return -1;
|
return x14_child->VGetInt32POIState(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
CParticleData::EParentedMode CAnimTreeSingleChild::VGetParticlePOIState(const char* name) const
|
CParticleData::EParentedMode CAnimTreeSingleChild::VGetParticlePOIState(const char* name) const
|
||||||
{
|
{
|
||||||
return CParticleData::EParentedMode::Initial;
|
return x14_child->VGetParticlePOIState(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeSingleChild::VGetSegStatementSet(const CSegIdList& list,
|
void CAnimTreeSingleChild::VGetSegStatementSet(const CSegIdList& list,
|
||||||
CSegStatementSet& setOut) const
|
CSegStatementSet& setOut) const
|
||||||
{
|
{
|
||||||
|
x14_child->VGetSegStatementSet(list, setOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeSingleChild::VGetSegStatementSet(const CSegIdList& list,
|
void CAnimTreeSingleChild::VGetSegStatementSet(const CSegIdList& list,
|
||||||
CSegStatementSet& setOut,
|
CSegStatementSet& setOut,
|
||||||
const CCharAnimTime& time) const
|
const CCharAnimTime& time) const
|
||||||
{
|
{
|
||||||
|
x14_child->VGetSegStatementSet(list, setOut, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeSingleChild::VSetPhase(float)
|
void CAnimTreeSingleChild::VSetPhase(float phase)
|
||||||
{
|
{
|
||||||
|
x14_child->VSetPhase(phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAdvancementResults
|
SAdvancementResults
|
||||||
CAnimTreeSingleChild::VGetAdvancementResults(const CCharAnimTime& a,
|
CAnimTreeSingleChild::VGetAdvancementResults(const CCharAnimTime& a,
|
||||||
const CCharAnimTime& b) const
|
const CCharAnimTime& b) const
|
||||||
{
|
{
|
||||||
return {};
|
return x14_child->VGetAdvancementResults(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeSingleChild::Depth() const
|
u32 CAnimTreeSingleChild::Depth() const
|
||||||
{
|
{
|
||||||
return 1;
|
return x14_child->Depth() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CAnimTreeSingleChild::VGetNumChildren() const
|
u32 CAnimTreeSingleChild::VGetNumChildren() const
|
||||||
{
|
{
|
||||||
return 0;
|
return x14_child->VGetNumChildren() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
CAnimTreeSingleChild(const std::weak_ptr<CAnimTreeNode>& node, std::string_view name);
|
CAnimTreeSingleChild(const std::weak_ptr<CAnimTreeNode>& node, std::string_view name);
|
||||||
|
|
||||||
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
|
SAdvancementResults VAdvanceView(const CCharAnimTime& dt);
|
||||||
CCharAnimTime VGetTimeRemaining() const;
|
CCharAnimTime VGetTimeRemaining() const;
|
||||||
bool VHasOffset(const CSegId& seg) const;
|
bool VHasOffset(const CSegId& seg) const;
|
||||||
zeus::CVector3f VGetOffset(const CSegId& seg) const;
|
zeus::CVector3f VGetOffset(const CSegId& seg) const;
|
||||||
|
|
|
@ -5,11 +5,22 @@ namespace urde
|
||||||
|
|
||||||
CAnimTreeTimeScale::CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>& node, float scale,
|
CAnimTreeTimeScale::CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>& node, float scale,
|
||||||
std::string_view name)
|
std::string_view name)
|
||||||
: CAnimTreeSingleChild(node, name)
|
: CAnimTreeSingleChild(node, name)
|
||||||
, x18_timeScale(new CConstantAnimationTimeScale(scale))
|
, 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,
|
std::string CAnimTreeTimeScale::CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, float,
|
||||||
const CCharAnimTime&, float)
|
const CCharAnimTime&, float)
|
||||||
{
|
{
|
||||||
|
@ -20,26 +31,26 @@ CCharAnimTime CAnimTreeTimeScale::GetRealLifeTime(const CCharAnimTime& time) con
|
||||||
{
|
{
|
||||||
CCharAnimTime timeRem = x14_child->VGetTimeRemaining();
|
CCharAnimTime timeRem = x14_child->VGetTimeRemaining();
|
||||||
|
|
||||||
CCharAnimTime tmp = std::min(timeRem, time);
|
CCharAnimTime ret = std::min(timeRem, time);
|
||||||
if (x28_ > CCharAnimTime())
|
if (x28_targetAccelTime > CCharAnimTime())
|
||||||
{
|
{
|
||||||
if (tmp < CCharAnimTime(x28_ * x20_))
|
if (ret < CCharAnimTime(x28_targetAccelTime - x20_curAccelTime))
|
||||||
return x18_timeScale->VTimeScaleIntegral(x20_.GetSeconds(),
|
return x18_timeScale->VTimeScaleIntegral(x20_curAccelTime.GetSeconds(),
|
||||||
(x20_ + tmp).GetSeconds());
|
(x20_curAccelTime + ret).GetSeconds());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CCharAnimTime integral =
|
CCharAnimTime integral =
|
||||||
x18_timeScale->VTimeScaleIntegral(x20_.GetSeconds(), x28_.GetSeconds());
|
x18_timeScale->VTimeScaleIntegral(x20_curAccelTime.GetSeconds(), x28_targetAccelTime.GetSeconds());
|
||||||
|
|
||||||
if (integral > tmp)
|
if (integral > ret)
|
||||||
return x18_timeScale->VFindUpperLimit(x20_.GetSeconds(), tmp.GetSeconds()) *
|
return x18_timeScale->VFindUpperLimit(x20_curAccelTime.GetSeconds(), ret.GetSeconds()) -
|
||||||
x20_.GetSeconds();
|
x20_curAccelTime.GetSeconds();
|
||||||
else
|
else
|
||||||
return integral + (integral * tmp);
|
return integral + (ret - integral);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimTreeTimeScale::VSetPhase(float phase)
|
void CAnimTreeTimeScale::VSetPhase(float phase)
|
||||||
|
@ -49,7 +60,175 @@ void CAnimTreeTimeScale::VSetPhase(float phase)
|
||||||
|
|
||||||
std::experimental::optional<std::unique_ptr<IAnimReader>> CAnimTreeTimeScale::VSimplified()
|
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 {};
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,36 @@ namespace urde
|
||||||
|
|
||||||
class CAnimTreeTimeScale : public CAnimTreeSingleChild
|
class CAnimTreeTimeScale : public CAnimTreeSingleChild
|
||||||
{
|
{
|
||||||
std::shared_ptr<CConstantAnimationTimeScale> x18_timeScale;
|
std::unique_ptr<IVaryingAnimationTimeScale> x18_timeScale;
|
||||||
CCharAnimTime x20_;
|
CCharAnimTime x20_curAccelTime;
|
||||||
CCharAnimTime x28_;
|
CCharAnimTime x28_targetAccelTime;
|
||||||
|
CCharAnimTime x30_initialTime;
|
||||||
public:
|
public:
|
||||||
CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>&, float, std::string_view);
|
CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>& node, float timeScale, std::string_view name);
|
||||||
|
CAnimTreeTimeScale(const std::weak_ptr<CAnimTreeNode>& node,
|
||||||
|
std::unique_ptr<IVaryingAnimationTimeScale>&& timeScale,
|
||||||
|
const CCharAnimTime& time, std::string_view name);
|
||||||
|
|
||||||
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, float, const CCharAnimTime&, float);
|
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, float, const CCharAnimTime&, float);
|
||||||
|
|
||||||
CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const;
|
CCharAnimTime GetRealLifeTime(const CCharAnimTime&) const;
|
||||||
void VSetPhase(float);
|
void VSetPhase(float);
|
||||||
std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
|
std::experimental::optional<std::unique_ptr<IAnimReader>> VSimplified();
|
||||||
|
|
||||||
|
u32 VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
u32 VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
u32 VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
u32 VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, u32 capacity, u32 iterator, u32) const;
|
||||||
|
bool VGetBoolPOIState(const char* name) const;
|
||||||
|
s32 VGetInt32POIState(const char* name) const;
|
||||||
|
CParticleData::EParentedMode VGetParticlePOIState(const char* name) const;
|
||||||
|
|
||||||
|
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
|
||||||
|
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
|
||||||
|
std::unique_ptr<IAnimReader> VClone() const;
|
||||||
|
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
|
||||||
|
CCharAnimTime VGetTimeRemaining() const;
|
||||||
|
SAdvancementResults VAdvanceView(const CCharAnimTime& dt);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ protected:
|
||||||
bool x36_initialized = false;
|
bool x36_initialized = false;
|
||||||
SAdvancementResults AdvanceViewForTransitionalPeriod(const CCharAnimTime& time);
|
SAdvancementResults AdvanceViewForTransitionalPeriod(const CCharAnimTime& time);
|
||||||
public:
|
public:
|
||||||
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&, const std::weak_ptr<CAnimTreeNode>&,
|
static std::string CreatePrimitiveName(const std::weak_ptr<CAnimTreeNode>&,
|
||||||
|
const std::weak_ptr<CAnimTreeNode>&,
|
||||||
float);
|
float);
|
||||||
|
|
||||||
CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
|
CAnimTreeTransition(bool b1, const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
|
|
|
@ -40,6 +40,8 @@ void CAnimationDatabaseGame::GetAllUniquePrimitives(std::vector<CPrimitive>& pri
|
||||||
|
|
||||||
void CAnimationDatabaseGame::GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>& primsOut,
|
void CAnimationDatabaseGame::GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>& primsOut,
|
||||||
std::string_view name) const
|
std::string_view name) const
|
||||||
{}
|
{
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ CCharAnimTime CCharAnimTime::Infinity()
|
||||||
bool CCharAnimTime::EqualsZero() const
|
bool CCharAnimTime::EqualsZero() const
|
||||||
{
|
{
|
||||||
if (x4_type == EType::ZeroIncreasing || x4_type == EType::ZeroSteady || x4_type == EType::ZeroDecreasing)
|
if (x4_type == EType::ZeroIncreasing || x4_type == EType::ZeroSteady || x4_type == EType::ZeroDecreasing)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
return (x0_time == 0.f);
|
return (x0_time == 0.f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,15 @@ CMetaAnimSequence::VGetAnimationTree(const CAnimSysContext& animSys,
|
||||||
return GetAnimationTree(animSys, modOrders);
|
return GetAnimationTree(animSys, modOrders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
std::vector<std::string> anims;
|
||||||
|
anims.reserve(anims.size());
|
||||||
for (const std::shared_ptr<IMetaAnim>& anim : x4_sequence)
|
for (const std::shared_ptr<IMetaAnim>& anim : x4_sequence)
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<CAnimTreeNode> chNode = anim->GetAnimationTree(animSys, orders);
|
||||||
|
anims.emplace_back(chNode->GetName());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<CAnimTreeNode> ret =
|
std::shared_ptr<CAnimTreeNode> ret =
|
||||||
std::make_shared<CAnimTreeSequence>(x4_sequence, animSys, "");
|
std::make_shared<CAnimTreeSequence>(x4_sequence, animSys, "");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CMetaTransMetaAnim.hpp"
|
#include "CMetaTransMetaAnim.hpp"
|
||||||
#include "CMetaAnimFactory.hpp"
|
#include "CMetaAnimFactory.hpp"
|
||||||
|
#include "CAnimTreeLoopIn.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -12,7 +13,10 @@ CMetaTransMetaAnim::VGetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
const std::weak_ptr<CAnimTreeNode>& b,
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
const CAnimSysContext& animSys) const
|
const CAnimSysContext& animSys) const
|
||||||
{
|
{
|
||||||
return {};
|
std::shared_ptr<CAnimTreeNode> animNode =
|
||||||
|
x4_metaAnim->GetAnimationTree(animSys, CMetaAnimTreeBuildOrders::NoSpecialOrders());
|
||||||
|
return std::make_shared<CAnimTreeLoopIn>(a, b, animNode, animSys,
|
||||||
|
CAnimTreeLoopIn::CreatePrimitiveName(a, b, animNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
#include "CMetaTransPhaseTrans.hpp"
|
#include "CMetaTransPhaseTrans.hpp"
|
||||||
#include "CAnimTreeNode.hpp"
|
#include "CAnimTreeNode.hpp"
|
||||||
|
#include "CTimeScaleFunctions.hpp"
|
||||||
|
#include "CAnimTreeTransition.hpp"
|
||||||
|
#include "CAnimTreeTimeScale.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CMetaTransPhaseTrans::CMetaTransPhaseTrans(CInputStream& in)
|
CMetaTransPhaseTrans::CMetaTransPhaseTrans(CInputStream& in)
|
||||||
{
|
{
|
||||||
x4_ = in.readFloatBig();
|
x4_transDur = CCharAnimTime(in);
|
||||||
x8_ = in.readUint32Big();
|
|
||||||
xc_ = in.readBool();
|
xc_ = in.readBool();
|
||||||
xd_ = in.readBool();
|
xd_runA = in.readBool();
|
||||||
x10_ = in.readUint32Big();
|
x10_flags = in.readUint32Big();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CAnimTreeNode>
|
std::shared_ptr<CAnimTreeNode>
|
||||||
|
@ -18,7 +20,23 @@ CMetaTransPhaseTrans::VGetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
const std::weak_ptr<CAnimTreeNode>& b,
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
const CAnimSysContext& animSys) const
|
const CAnimSysContext& animSys) const
|
||||||
{
|
{
|
||||||
return {};
|
std::shared_ptr<CAnimTreeNode> nA = a.lock();
|
||||||
|
CAnimTreeEffectiveContribution cA = nA->GetContributionOfHighestInfluence();
|
||||||
|
std::shared_ptr<CAnimTreeNode> nB = b.lock();
|
||||||
|
CAnimTreeEffectiveContribution cB = nB->GetContributionOfHighestInfluence();
|
||||||
|
float y2A = cA.GetSteadyStateAnimInfo().GetDuration() / cB.GetSteadyStateAnimInfo().GetDuration();
|
||||||
|
float y1B = cB.GetSteadyStateAnimInfo().GetDuration() / cA.GetSteadyStateAnimInfo().GetDuration();
|
||||||
|
|
||||||
|
nB->VSetPhase(zeus::clamp(0.f, 1.f - cA.GetTimeRemaining() / cA.GetSteadyStateAnimInfo().GetDuration(), 1.f));
|
||||||
|
auto tsA = std::make_shared<CAnimTreeTimeScale>(a,
|
||||||
|
std::make_unique<CLinearAnimationTimeScale>(CCharAnimTime{}, 1.f, x4_transDur, y2A),
|
||||||
|
x4_transDur, CAnimTreeTimeScale::CreatePrimitiveName(a, 1.f, x4_transDur, y2A));
|
||||||
|
auto tsB = std::make_shared<CAnimTreeTimeScale>(b,
|
||||||
|
std::make_unique<CLinearAnimationTimeScale>(CCharAnimTime{}, y1B, x4_transDur, 1.f),
|
||||||
|
x4_transDur, CAnimTreeTimeScale::CreatePrimitiveName(b, y1B, x4_transDur, 1.f));
|
||||||
|
|
||||||
|
return std::make_shared<CAnimTreeTransition>(xc_, tsA, tsB, x4_transDur, xd_runA, x10_flags,
|
||||||
|
CAnimTreeTransition::CreatePrimitiveName(tsA, tsB, x4_transDur.GetSeconds()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
|
|
||||||
#include "IMetaTrans.hpp"
|
#include "IMetaTrans.hpp"
|
||||||
#include "IOStreams.hpp"
|
#include "IOStreams.hpp"
|
||||||
|
#include "CCharAnimTime.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
class CMetaTransPhaseTrans : public IMetaTrans
|
class CMetaTransPhaseTrans : public IMetaTrans
|
||||||
{
|
{
|
||||||
float x4_;
|
CCharAnimTime x4_transDur;
|
||||||
u32 x8_;
|
|
||||||
bool xc_;
|
bool xc_;
|
||||||
bool xd_;
|
bool xd_runA;
|
||||||
u32 x10_;
|
u32 x10_flags;
|
||||||
public:
|
public:
|
||||||
CMetaTransPhaseTrans(CInputStream& in);
|
CMetaTransPhaseTrans(CInputStream& in);
|
||||||
EMetaTransType GetType() const {return EMetaTransType::PhaseTrans;}
|
EMetaTransType GetType() const {return EMetaTransType::PhaseTrans;}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "CParticlePOINode.hpp"
|
#include "CParticlePOINode.hpp"
|
||||||
#include "CSoundPOINode.hpp"
|
#include "CSoundPOINode.hpp"
|
||||||
#include "IMetaAnim.hpp"
|
#include "IMetaAnim.hpp"
|
||||||
|
#include "CTreeUtils.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -22,7 +23,7 @@ CSequenceFundamentals::CSequenceFundamentals(const CSteadyStateAnimInfo& ssInfo,
|
||||||
CSequenceHelper::CSequenceHelper(const std::shared_ptr<CAnimTreeNode>& a,
|
CSequenceHelper::CSequenceHelper(const std::shared_ptr<CAnimTreeNode>& a,
|
||||||
const std::shared_ptr<CAnimTreeNode>& b,
|
const std::shared_ptr<CAnimTreeNode>& b,
|
||||||
const CAnimSysContext& animCtx)
|
const CAnimSysContext& animCtx)
|
||||||
: x0_transDB(animCtx.x0_transDB)
|
: x0_animCtx(animCtx)
|
||||||
{
|
{
|
||||||
x10_treeNodes.reserve(2);
|
x10_treeNodes.reserve(2);
|
||||||
x10_treeNodes.push_back(a);
|
x10_treeNodes.push_back(a);
|
||||||
|
@ -31,7 +32,7 @@ CSequenceHelper::CSequenceHelper(const std::shared_ptr<CAnimTreeNode>& a,
|
||||||
|
|
||||||
CSequenceHelper::CSequenceHelper(const std::vector<std::shared_ptr<IMetaAnim>>& nodes,
|
CSequenceHelper::CSequenceHelper(const std::vector<std::shared_ptr<IMetaAnim>>& nodes,
|
||||||
const CAnimSysContext& animCtx)
|
const CAnimSysContext& animCtx)
|
||||||
: x0_transDB(animCtx.x0_transDB)
|
: x0_animCtx(animCtx)
|
||||||
{
|
{
|
||||||
x10_treeNodes.reserve(nodes.size());
|
x10_treeNodes.reserve(nodes.size());
|
||||||
for (const std::shared_ptr<IMetaAnim>& meta : nodes)
|
for (const std::shared_ptr<IMetaAnim>& meta : nodes)
|
||||||
|
@ -40,7 +41,81 @@ CSequenceHelper::CSequenceHelper(const std::vector<std::shared_ptr<IMetaAnim>>&
|
||||||
|
|
||||||
CSequenceFundamentals CSequenceHelper::ComputeSequenceFundamentals()
|
CSequenceFundamentals CSequenceHelper::ComputeSequenceFundamentals()
|
||||||
{
|
{
|
||||||
return {};
|
CCharAnimTime duration;
|
||||||
|
zeus::CVector3f offset;
|
||||||
|
std::vector<CBoolPOINode> boolNodes;
|
||||||
|
std::vector<CInt32POINode> int32Nodes;
|
||||||
|
std::vector<CParticlePOINode> particleNodes;
|
||||||
|
std::vector<CSoundPOINode> soundNodes;
|
||||||
|
if (x10_treeNodes.size() > 0)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CAnimTreeNode> node = CAnimTreeNode::Cast(x10_treeNodes[0]->Clone());
|
||||||
|
for (int i=0 ; i<x10_treeNodes.size() ; ++i)
|
||||||
|
{
|
||||||
|
CBoolPOINode boolNodeArr[64];
|
||||||
|
u32 numBools = node->GetBoolPOIList(CCharAnimTime::Infinity(), boolNodeArr, 64, 0, 0);
|
||||||
|
boolNodes.reserve(boolNodes.size() + numBools);
|
||||||
|
for (int j=0 ; j<numBools ; ++j)
|
||||||
|
{
|
||||||
|
CBoolPOINode& n = boolNodeArr[j];
|
||||||
|
n.SetTime(n.GetTime() + duration);
|
||||||
|
boolNodes.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
CInt32POINode int32NodeArr[64];
|
||||||
|
u32 numInt32s = node->GetInt32POIList(CCharAnimTime::Infinity(), int32NodeArr, 64, 0, 0);
|
||||||
|
int32Nodes.reserve(int32Nodes.size() + numInt32s);
|
||||||
|
for (int j=0 ; j<numInt32s ; ++j)
|
||||||
|
{
|
||||||
|
CInt32POINode& n = int32NodeArr[j];
|
||||||
|
n.SetTime(n.GetTime() + duration);
|
||||||
|
int32Nodes.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
CParticlePOINode particleNodeArr[64];
|
||||||
|
u32 numParticles = node->GetParticlePOIList(CCharAnimTime::Infinity(), particleNodeArr, 64, 0, 0);
|
||||||
|
particleNodes.reserve(particleNodes.size() + numParticles);
|
||||||
|
for (int j=0 ; j<numParticles ; ++j)
|
||||||
|
{
|
||||||
|
CParticlePOINode& n = particleNodeArr[j];
|
||||||
|
n.SetTime(n.GetTime() + duration);
|
||||||
|
particleNodes.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSoundPOINode soundNodeArr[64];
|
||||||
|
u32 numSounds = node->GetSoundPOIList(CCharAnimTime::Infinity(), soundNodeArr, 64, 0, 0);
|
||||||
|
soundNodes.reserve(soundNodes.size() + numSounds);
|
||||||
|
for (int j=0 ; j<numSounds ; ++j)
|
||||||
|
{
|
||||||
|
CSoundPOINode& n = soundNodeArr[j];
|
||||||
|
n.SetTime(n.GetTime() + duration);
|
||||||
|
soundNodes.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
duration += node->VGetTimeRemaining();
|
||||||
|
|
||||||
|
CCharAnimTime remTime = node->VGetTimeRemaining();
|
||||||
|
while (!remTime.EqualsZero() && !remTime.EpsilonZero())
|
||||||
|
{
|
||||||
|
SAdvancementResults res = node->VAdvanceView(remTime);
|
||||||
|
auto simp = node->Simplified();
|
||||||
|
if (simp)
|
||||||
|
node = CAnimTreeNode::Cast(std::move(*simp));
|
||||||
|
CCharAnimTime prevRemTime = remTime;
|
||||||
|
remTime = res.x0_remTime;
|
||||||
|
/* This was originally accumulating uninitialized register values (stack variable misuse?) */
|
||||||
|
offset += res.x8_deltas.x0_posDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < x10_treeNodes.size()-1)
|
||||||
|
{
|
||||||
|
node = CTreeUtils::GetTransitionTree(node,
|
||||||
|
CAnimTreeNode::Cast(x10_treeNodes[i+1]->Clone()), x0_animCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {{false, duration, offset}, boolNodes, int32Nodes, particleNodes, soundNodes};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
#include "CInt32POINode.hpp"
|
#include "CInt32POINode.hpp"
|
||||||
#include "CParticlePOINode.hpp"
|
#include "CParticlePOINode.hpp"
|
||||||
#include "CSoundPOINode.hpp"
|
#include "CSoundPOINode.hpp"
|
||||||
|
#include "CAnimSysContext.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
struct CAnimSysContext;
|
|
||||||
class IMetaAnim;
|
class IMetaAnim;
|
||||||
class CTransitionDatabaseGame;
|
class CTransitionDatabaseGame;
|
||||||
|
|
||||||
|
@ -21,9 +21,6 @@ class CSequenceFundamentals
|
||||||
std::vector<CParticlePOINode> x38_particleNodes;
|
std::vector<CParticlePOINode> x38_particleNodes;
|
||||||
std::vector<CSoundPOINode> x48_soundNodes;
|
std::vector<CSoundPOINode> x48_soundNodes;
|
||||||
public:
|
public:
|
||||||
/* HACK: Remove this default constructor */
|
|
||||||
CSequenceFundamentals() = default;
|
|
||||||
|
|
||||||
CSequenceFundamentals(const CSteadyStateAnimInfo& ssInfo,
|
CSequenceFundamentals(const CSteadyStateAnimInfo& ssInfo,
|
||||||
const std::vector<CBoolPOINode>& boolNodes,
|
const std::vector<CBoolPOINode>& boolNodes,
|
||||||
const std::vector<CInt32POINode>& int32Nodes,
|
const std::vector<CInt32POINode>& int32Nodes,
|
||||||
|
@ -39,12 +36,10 @@ public:
|
||||||
|
|
||||||
class CSequenceHelper
|
class CSequenceHelper
|
||||||
{
|
{
|
||||||
TLockedToken<CTransitionDatabaseGame> x0_transDB;
|
CAnimSysContext x0_animCtx;
|
||||||
std::vector<std::shared_ptr<CAnimTreeNode>> x10_treeNodes;
|
std::vector<std::shared_ptr<CAnimTreeNode>> x10_treeNodes;
|
||||||
std::vector<bool> x20_;
|
std::vector<bool> x20_;
|
||||||
public:
|
public:
|
||||||
/* HACK: Remove this default constructor */
|
|
||||||
CSequenceHelper() = default;
|
|
||||||
CSequenceHelper(const std::shared_ptr<CAnimTreeNode>& a,
|
CSequenceHelper(const std::shared_ptr<CAnimTreeNode>& a,
|
||||||
const std::shared_ptr<CAnimTreeNode>& b,
|
const std::shared_ptr<CAnimTreeNode>& b,
|
||||||
const CAnimSysContext& animCtx);
|
const CAnimSysContext& animCtx);
|
||||||
|
|
|
@ -1,80 +1,107 @@
|
||||||
#include "CTimeScaleFunctions.hpp"
|
#include "CTimeScaleFunctions.hpp"
|
||||||
#include "CCharAnimTime.hpp"
|
#include "zeus/Math.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> IVaryingAnimationTimeScale::Clone() const
|
std::unique_ptr<IVaryingAnimationTimeScale> IVaryingAnimationTimeScale::Clone() const
|
||||||
{
|
{
|
||||||
return VClone();
|
return VClone();
|
||||||
}
|
}
|
||||||
|
|
||||||
float CConstantAnimationTimeScale::VTimeScaleIntegral(const float& a, const float& b) const { return (b - a) * x4_; }
|
float CConstantAnimationTimeScale::VTimeScaleIntegral(float lowerLimit, float upperLimit) const
|
||||||
float CConstantAnimationTimeScale::VFindUpperLimit(const float& a, const float& b) const { return (b / x4_) + a; }
|
|
||||||
|
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> CConstantAnimationTimeScale::VClone() const
|
|
||||||
{
|
{
|
||||||
CConstantAnimationTimeScale* ret = new CConstantAnimationTimeScale(x4_);
|
return (upperLimit - lowerLimit) * x4_scale;
|
||||||
return std::shared_ptr<IVaryingAnimationTimeScale>(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> CConstantAnimationTimeScale::VGetFunctionMirrored(const float&) const
|
float CConstantAnimationTimeScale::VFindUpperLimit(float lowerLimit, float root) const
|
||||||
|
{
|
||||||
|
return (root / x4_scale) + lowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IVaryingAnimationTimeScale> CConstantAnimationTimeScale::VClone() const
|
||||||
|
{
|
||||||
|
return std::make_unique<CConstantAnimationTimeScale>(x4_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IVaryingAnimationTimeScale> CConstantAnimationTimeScale::VGetFunctionMirrored(float) const
|
||||||
{
|
{
|
||||||
return Clone();
|
return Clone();
|
||||||
}
|
}
|
||||||
float CLinearAnimationTimeScale::VTimeScaleIntegral(const float&, const float&) const
|
|
||||||
|
CLinearAnimationTimeScale::CLinearAnimationTimeScale(const CCharAnimTime& t1, float y1,
|
||||||
|
const CCharAnimTime& t2, float y2)
|
||||||
{
|
{
|
||||||
return 0.f;
|
float y2my1 = y2 - y1;
|
||||||
|
float t2mt1 = (t2 - t1).GetSeconds();
|
||||||
|
x4_desc.x4_slope = y2my1 / t2mt1;
|
||||||
|
x4_desc.x8_yIntercept = y1 - y2my1 / t2mt1 * t1.GetSeconds();
|
||||||
|
x4_desc.xc_t1 = t1.GetSeconds();
|
||||||
|
x4_desc.x10_t2 = t2.GetSeconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<IVaryingAnimationTimeScale>
|
||||||
|
CLinearAnimationTimeScale::CFunctionDescription::FunctionMirroredAround(float value) const
|
||||||
|
{
|
||||||
|
float slope = -x4_slope;
|
||||||
|
float t1 = 2.f * value - x10_t2;
|
||||||
|
float t2 = 2.f * value - xc_t1;
|
||||||
|
float newYInt = x8_yIntercept - x4_slope * 2.f * value;
|
||||||
|
float y1 = slope * t1 + newYInt;
|
||||||
|
float y2 = slope * t2 + newYInt;
|
||||||
|
return std::make_unique<CLinearAnimationTimeScale>(t1, y1, t2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CLinearAnimationTimeScale::VTimeScaleIntegral(float lowerLimit, float upperLimit) const
|
||||||
|
{
|
||||||
|
if (lowerLimit <= upperLimit)
|
||||||
|
return TimeScaleIntegralWithSortedLimits(x4_desc, lowerLimit, upperLimit);
|
||||||
|
else
|
||||||
|
return -TimeScaleIntegralWithSortedLimits(x4_desc, upperLimit, lowerLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CLinearAnimationTimeScale::TimeScaleIntegralWithSortedLimits(const CFunctionDescription& desc,
|
float CLinearAnimationTimeScale::TimeScaleIntegralWithSortedLimits(const CFunctionDescription& desc,
|
||||||
const float&, const float&)
|
float lowerLimit, float upperLimit)
|
||||||
{
|
{
|
||||||
return 0.f;
|
float lowerEval = desc.x4_slope * lowerLimit + desc.x8_yIntercept;
|
||||||
|
float upperEval = desc.x4_slope * upperLimit + desc.x8_yIntercept;
|
||||||
|
return (upperLimit - lowerLimit) * 0.5f * (lowerEval + upperEval);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CLinearAnimationTimeScale::VFindUpperLimit(const float&, const float&) const
|
float CLinearAnimationTimeScale::VFindUpperLimit(float lowerLimit, float root) const
|
||||||
{
|
{
|
||||||
return 0.f;
|
return FindUpperLimitFromRoot(x4_desc, lowerLimit, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CLinearAnimationTimeScale::FindUpperLimitFromRoot(const CFunctionDescription& desc,
|
float CLinearAnimationTimeScale::FindUpperLimitFromRoot(const CFunctionDescription& desc,
|
||||||
const float&, const float&)
|
float lowerLimit, float root)
|
||||||
{
|
{
|
||||||
return 0.f;
|
float M = 0.5f * desc.x4_slope;
|
||||||
|
float upperLimit = lowerLimit;
|
||||||
|
float m = 2.f * M;
|
||||||
|
float lowerIntegration = M * lowerLimit * lowerLimit + desc.x8_yIntercept * lowerLimit;
|
||||||
|
for (int i=0 ; i<16 ; ++i)
|
||||||
|
{
|
||||||
|
float factor = (M * upperLimit * upperLimit + desc.x8_yIntercept * upperLimit - lowerIntegration - root) /
|
||||||
|
(m * upperLimit + desc.x8_yIntercept);
|
||||||
|
upperLimit -= factor;
|
||||||
|
if (zeus::close_enough(factor, 0.f))
|
||||||
|
return upperLimit;
|
||||||
|
}
|
||||||
|
return -1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> CLinearAnimationTimeScale::VClone() const
|
std::unique_ptr<IVaryingAnimationTimeScale> CLinearAnimationTimeScale::VClone() const
|
||||||
{
|
{
|
||||||
CCharAnimTime timeA(x10_);
|
float y1 = x4_desc.x4_slope * x4_desc.xc_t1 + x4_desc.x8_yIntercept;
|
||||||
CCharAnimTime timeB(xc_);
|
float y2 = x4_desc.x4_slope * x4_desc.x10_t2 + x4_desc.x8_yIntercept;
|
||||||
|
return std::make_unique<CLinearAnimationTimeScale>(x4_desc.xc_t1, y1, x4_desc.x10_t2, y2);
|
||||||
CLinearAnimationTimeScale* ret = new CLinearAnimationTimeScale();
|
|
||||||
float f30 = x4_ * xc_ + x8_;
|
|
||||||
ret->x4_ = (x4_ * x10_ + x8_ - f30) / timeB.GetSeconds();
|
|
||||||
ret->x8_ = -((x4_ * x10_ + x8_ - f30) / (timeA - timeB).GetSeconds() * timeB.GetSeconds() - f30);
|
|
||||||
ret->xc_ = timeB.GetSeconds();
|
|
||||||
ret->x10_ = timeA.GetSeconds();
|
|
||||||
|
|
||||||
return std::shared_ptr<IVaryingAnimationTimeScale>(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale>
|
std::unique_ptr<IVaryingAnimationTimeScale>
|
||||||
CLinearAnimationTimeScale::VGetFunctionMirrored(const float& parm) const
|
CLinearAnimationTimeScale::VGetFunctionMirrored(float value) const
|
||||||
{
|
{
|
||||||
float f27 = -(x4_ * parm * 2.f - x8_);
|
return x4_desc.FunctionMirroredAround(value);
|
||||||
float f31 = -x4_ * parm * 2.f - x10_ + f27;
|
|
||||||
CCharAnimTime timeA(2.f * parm - xc_);
|
|
||||||
CCharAnimTime timeB(2.f * parm - x10_);
|
|
||||||
|
|
||||||
CLinearAnimationTimeScale* ret = new CLinearAnimationTimeScale();
|
|
||||||
ret->x4_ = (-x4_ * 2.f * parm - xc_ + f27 - f31) / (timeA - timeB).GetSeconds();
|
|
||||||
ret->x8_ = -(((-x4_ * 2.f * parm - xc_ + f27 - f31) /
|
|
||||||
(timeA - timeB).GetSeconds()) * timeB.GetSeconds() - f31);
|
|
||||||
ret->xc_ = timeB.GetSeconds();
|
|
||||||
ret->x10_ = timeA.GetSeconds();
|
|
||||||
|
|
||||||
return std::shared_ptr<IVaryingAnimationTimeScale>(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __URDE_CTIMESCALEFUNCTIONS_HPP__
|
#define __URDE_CTIMESCALEFUNCTIONS_HPP__
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
|
#include "CCharAnimTime.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -17,45 +18,50 @@ class IVaryingAnimationTimeScale
|
||||||
public:
|
public:
|
||||||
virtual ~IVaryingAnimationTimeScale() = default;
|
virtual ~IVaryingAnimationTimeScale() = default;
|
||||||
virtual EVaryingAnimationTimeScaleType GetType() const=0;
|
virtual EVaryingAnimationTimeScaleType GetType() const=0;
|
||||||
virtual float VTimeScaleIntegral(const float&, const float&) const=0;
|
virtual float VTimeScaleIntegral(float lowerLimit, float upperLimit) const=0;
|
||||||
virtual float VFindUpperLimit(const float&, const float&) const=0;
|
virtual float VFindUpperLimit(float lowerLimit, float root) const=0;
|
||||||
virtual std::shared_ptr<IVaryingAnimationTimeScale> VClone() const=0;
|
virtual std::unique_ptr<IVaryingAnimationTimeScale> VClone() const=0;
|
||||||
virtual std::shared_ptr<IVaryingAnimationTimeScale> VGetFunctionMirrored(const float&) const=0;
|
virtual std::unique_ptr<IVaryingAnimationTimeScale> VGetFunctionMirrored(float value) const=0;
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> Clone() const;
|
std::unique_ptr<IVaryingAnimationTimeScale> Clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CConstantAnimationTimeScale : public IVaryingAnimationTimeScale
|
class CConstantAnimationTimeScale : public IVaryingAnimationTimeScale
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
float x4_;
|
float x4_scale;
|
||||||
public:
|
public:
|
||||||
CConstantAnimationTimeScale(float f) : x4_(f) {}
|
CConstantAnimationTimeScale(float scale) : x4_scale(scale) {}
|
||||||
|
|
||||||
EVaryingAnimationTimeScaleType GetType() const { return EVaryingAnimationTimeScaleType::Constant; }
|
EVaryingAnimationTimeScaleType GetType() const { return EVaryingAnimationTimeScaleType::Constant; }
|
||||||
float VTimeScaleIntegral(const float &, const float &) const;
|
float VTimeScaleIntegral(float lowerLimit, float upperLimit) const;
|
||||||
float VFindUpperLimit(const float &, const float &) const;
|
float VFindUpperLimit(float lowerLimit, float root) const;
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> VClone() const;
|
std::unique_ptr<IVaryingAnimationTimeScale> VClone() const;
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> VGetFunctionMirrored(const float &) const;
|
std::unique_ptr<IVaryingAnimationTimeScale> VGetFunctionMirrored(float value) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CLinearAnimationTimeScale : public IVaryingAnimationTimeScale
|
class CLinearAnimationTimeScale : public IVaryingAnimationTimeScale
|
||||||
{
|
{
|
||||||
float x4_;
|
|
||||||
float x8_;
|
|
||||||
float xc_;
|
|
||||||
float x10_;
|
|
||||||
public:
|
|
||||||
struct CFunctionDescription
|
struct CFunctionDescription
|
||||||
{
|
{
|
||||||
};
|
float x4_slope;
|
||||||
|
float x8_yIntercept;
|
||||||
|
float xc_t1;
|
||||||
|
float x10_t2;
|
||||||
|
std::unique_ptr<IVaryingAnimationTimeScale> FunctionMirroredAround(float value) const;
|
||||||
|
} x4_desc;
|
||||||
|
static float FindUpperLimitFromRoot(const CFunctionDescription& desc,
|
||||||
|
float lowerLimit, float root);
|
||||||
|
static float TimeScaleIntegralWithSortedLimits(const CFunctionDescription& desc,
|
||||||
|
float lowerLimit, float upperLimit);
|
||||||
|
public:
|
||||||
|
CLinearAnimationTimeScale(const CCharAnimTime& t1, float y1,
|
||||||
|
const CCharAnimTime& t2, float y2);
|
||||||
|
|
||||||
EVaryingAnimationTimeScaleType GetType() const {return EVaryingAnimationTimeScaleType::Linear;}
|
EVaryingAnimationTimeScaleType GetType() const {return EVaryingAnimationTimeScaleType::Linear;}
|
||||||
float VTimeScaleIntegral(const float&, const float&) const;
|
float VTimeScaleIntegral(float lowerLimit, float upperLimit) const;
|
||||||
float TimeScaleIntegralWithSortedLimits(const CFunctionDescription& desc, const float&, const float&);
|
float VFindUpperLimit(float lowerLimit, float root) const;
|
||||||
float VFindUpperLimit(const float&, const float&) const;
|
std::unique_ptr<IVaryingAnimationTimeScale> VClone() const;
|
||||||
float FindUpperLimitFromRoot(const CFunctionDescription& desc, const float&, const float&);
|
std::unique_ptr<IVaryingAnimationTimeScale> VGetFunctionMirrored(float value) const;
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> VClone() const;
|
|
||||||
std::shared_ptr<IVaryingAnimationTimeScale> VGetFunctionMirrored(const float&) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
std::shared_ptr<CAnimTreeNode> CTreeUtils::GetTransitionTree(const std::shared_ptr<CAnimTreeNode>& a,
|
std::shared_ptr<CAnimTreeNode> CTreeUtils::GetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
const std::shared_ptr<CAnimTreeNode>& b,
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
const CAnimSysContext& animCtx)
|
const CAnimSysContext& animCtx)
|
||||||
{
|
{
|
||||||
CAnimTreeEffectiveContribution contribA = a->GetContributionOfHighestInfluence();
|
CAnimTreeEffectiveContribution contribA = a.lock()->GetContributionOfHighestInfluence();
|
||||||
CAnimTreeEffectiveContribution contribB = b->GetContributionOfHighestInfluence();
|
CAnimTreeEffectiveContribution contribB = b.lock()->GetContributionOfHighestInfluence();
|
||||||
return animCtx.x0_transDB->GetMetaTrans(contribA.GetAnimDatabaseIndex(),
|
return animCtx.x0_transDB->GetMetaTrans(contribA.GetAnimDatabaseIndex(),
|
||||||
contribB.GetAnimDatabaseIndex())->GetTransitionTree(a, b, animCtx);
|
contribB.GetAnimDatabaseIndex())->GetTransitionTree(a, b, animCtx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ struct CAnimSysContext;
|
||||||
class CTreeUtils
|
class CTreeUtils
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<CAnimTreeNode> GetTransitionTree(const std::shared_ptr<CAnimTreeNode>& a,
|
static std::shared_ptr<CAnimTreeNode> GetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a,
|
||||||
const std::shared_ptr<CAnimTreeNode>& b,
|
const std::weak_ptr<CAnimTreeNode>& b,
|
||||||
const CAnimSysContext& animCtx);
|
const CAnimSysContext& animCtx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,15 @@ SAdvancementDeltas::Interpolate(const SAdvancementDeltas& a, const SAdvancementD
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SAdvancementDeltas
|
||||||
|
SAdvancementDeltas::Blend(const SAdvancementDeltas& a, const SAdvancementDeltas& b, float w)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
b.x0_posDelta * w - a.x0_posDelta * (1.f - w),
|
||||||
|
zeus::CQuaternion::slerpShort(a.xc_rotDelta, b.xc_rotDelta, w)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
SAdvancementResults
|
SAdvancementResults
|
||||||
IAnimReader::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
|
IAnimReader::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct SAdvancementDeltas
|
||||||
|
|
||||||
static SAdvancementDeltas Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b,
|
static SAdvancementDeltas Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b,
|
||||||
float oldWeight, float newWeight);
|
float oldWeight, float newWeight);
|
||||||
|
static SAdvancementDeltas Blend(const SAdvancementDeltas& a, const SAdvancementDeltas& b, float w);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SAdvancementResults
|
struct SAdvancementResults
|
||||||
|
@ -41,8 +42,6 @@ class CSteadyStateAnimInfo
|
||||||
bool x14_looping = false;
|
bool x14_looping = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* HACK: Remove this default constructor */
|
|
||||||
CSteadyStateAnimInfo() = default;
|
|
||||||
CSteadyStateAnimInfo(bool looping, const CCharAnimTime& duration, const zeus::CVector3f& offset)
|
CSteadyStateAnimInfo(bool looping, const CCharAnimTime& duration, const zeus::CVector3f& offset)
|
||||||
: x0_duration(duration), x8_offset(offset), x14_looping(looping) {}
|
: x0_duration(duration), x8_offset(offset), x14_looping(looping) {}
|
||||||
|
|
||||||
|
|
|
@ -1344,7 +1344,8 @@ void CElementGen::RenderParticles()
|
||||||
zeus::CTransform systemViewPointMatrix(CGraphics::g_ViewMatrix);
|
zeus::CTransform systemViewPointMatrix(CGraphics::g_ViewMatrix);
|
||||||
systemViewPointMatrix.origin.zeroOut();
|
systemViewPointMatrix.origin.zeroOut();
|
||||||
zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation;
|
zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation;
|
||||||
systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) * systemViewPointMatrix) * x178_localScaleTransform;
|
systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) *
|
||||||
|
systemViewPointMatrix) * x178_localScaleTransform;
|
||||||
CGraphics::SetModelMatrix(systemViewPointMatrix);
|
CGraphics::SetModelMatrix(systemViewPointMatrix);
|
||||||
|
|
||||||
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
|
||||||
|
@ -1388,7 +1389,8 @@ void CElementGen::RenderParticles()
|
||||||
const CParticle& particle = x30_particles[i];
|
const CParticle& particle = x30_particles[i];
|
||||||
sortItems.emplace_back(i);
|
sortItems.emplace_back(i);
|
||||||
CParticleListItem& sortItem = sortItems.back();
|
CParticleListItem& sortItem = sortItems.back();
|
||||||
sortItem.x4_viewPoint = systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) * x80_timeDeltaScale + particle.x10_prevPos);
|
sortItem.x4_viewPoint = systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) *
|
||||||
|
x80_timeDeltaScale + particle.x10_prevPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(sortItems.begin(), sortItems.end(),
|
std::sort(sortItems.begin(), sortItems.end(),
|
||||||
|
@ -1445,7 +1447,8 @@ void CElementGen::RenderParticles()
|
||||||
if (desc->x44_28_x30_28_SORT)
|
if (desc->x44_28_x30_28_SORT)
|
||||||
viewPoint = sortItems[i].x4_viewPoint;
|
viewPoint = sortItems[i].x4_viewPoint;
|
||||||
else
|
else
|
||||||
viewPoint = systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) * x80_timeDeltaScale + particle.x10_prevPos);
|
viewPoint = systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) *
|
||||||
|
x80_timeDeltaScale + particle.x10_prevPos);
|
||||||
|
|
||||||
if (!constUVs)
|
if (!constUVs)
|
||||||
{
|
{
|
||||||
|
@ -1577,7 +1580,7 @@ void CElementGen::RenderParticles()
|
||||||
float size = 0.5f * particle.x2c_lineLengthOrSize;
|
float size = 0.5f * particle.x2c_lineLengthOrSize;
|
||||||
if (0.f == particle.x30_lineWidthOrRota)
|
if (0.f == particle.x30_lineWidthOrRota)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<mbspVal ; ++i)
|
for (int j=0 ; j<mbspVal ; ++j)
|
||||||
{
|
{
|
||||||
vec += mbspVec;
|
vec += mbspVec;
|
||||||
zeus::CVector3f vec2 = systemCameraMatrix * vec;
|
zeus::CVector3f vec2 = systemCameraMatrix * vec;
|
||||||
|
@ -1620,7 +1623,7 @@ void CElementGen::RenderParticles()
|
||||||
float sinT = std::sin(theta) * size;
|
float sinT = std::sin(theta) * size;
|
||||||
float cosT = std::cos(theta) * size;
|
float cosT = std::cos(theta) * size;
|
||||||
|
|
||||||
for (int i=0 ; i<mbspVal ; ++i)
|
for (int j=0 ; j<mbspVal ; ++j)
|
||||||
{
|
{
|
||||||
vec += mbspVec;
|
vec += mbspVec;
|
||||||
zeus::CVector3f vec2 = systemCameraMatrix * vec;
|
zeus::CVector3f vec2 = systemCameraMatrix * vec;
|
||||||
|
@ -1800,10 +1803,10 @@ void CElementGen::RenderParticlesIndirectTexture()
|
||||||
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f};
|
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f};
|
||||||
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f};
|
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f};
|
||||||
inst.color = particle.x34_color;
|
inst.color = particle.x34_color;
|
||||||
inst.texrTindUVs[0] = zeus::CVector4f{uvs.xMax, uvs.yMax, uvsInd.xMin, uvsInd.yMin};
|
inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMax, uvsInd.xMin, uvsInd.yMin};
|
||||||
inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax};
|
inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax};
|
||||||
inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin};
|
inst.texrTindUVs[0] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin};
|
||||||
inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMax, uvsInd.yMax};
|
inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMax, uvsInd.yMax};
|
||||||
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, clipRect.x24_uvYMax, clipRect.x1c_uvXMax, clipRect.x20_uvYMin};
|
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, clipRect.x24_uvYMax, clipRect.x1c_uvXMax, clipRect.x20_uvYMin};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ void CGunWeapon::Fire(bool underwater, float dt, EChargeState chargeState, const
|
||||||
{
|
{
|
||||||
CDamageInfo dInfo = GetDamageInfo(mgr, chargeState, chargeFactor1);
|
CDamageInfo dInfo = GetDamageInfo(mgr, chargeState, chargeFactor1);
|
||||||
zeus::CVector3f scale(chargeState == EChargeState::Normal ? 1.f : chargeFactor2);
|
zeus::CVector3f scale(chargeState == EChargeState::Normal ? 1.f : chargeFactor2);
|
||||||
bool partialCharge = chargeState == EChargeState::Normal ? false : std::fabs(chargeFactor1 - 1.f) >= 0.00001f;
|
bool partialCharge = chargeState == EChargeState::Normal ? false : !zeus::close_enough(chargeFactor1, 1.f);
|
||||||
CWeapon::EProjectileAttrib attribs = CWeapon::EProjectileAttrib::ArmCannon;
|
CWeapon::EProjectileAttrib attribs = CWeapon::EProjectileAttrib::ArmCannon;
|
||||||
if (partialCharge)
|
if (partialCharge)
|
||||||
attribs |= CWeapon::EProjectileAttrib::PartialCharge;
|
attribs |= CWeapon::EProjectileAttrib::PartialCharge;
|
||||||
|
|
|
@ -415,17 +415,18 @@ void CPlayerGun::StopChargeSound(CStateManager& mgr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerGun::ResetCharge(CStateManager& mgr, bool b1)
|
void CPlayerGun::ResetCharge(CStateManager& mgr, bool resetBeam)
|
||||||
{
|
{
|
||||||
if (x32c_chargePhase != EChargePhase::NotCharging)
|
if (x32c_chargePhase != EChargePhase::NotCharging)
|
||||||
StopChargeSound(mgr);
|
StopChargeSound(mgr);
|
||||||
|
|
||||||
if ((x2f8_stateFlags & 0x8) != 0x8 && (x2f8_stateFlags & 0x10) != 0x10)
|
if ((x2f8_stateFlags & 0x8) != 0x8 && (x2f8_stateFlags & 0x10) != 0x10)
|
||||||
{
|
{
|
||||||
bool r30 = !(mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed && !b1);
|
bool doResetBeam = mgr.GetPlayer().GetMorphballTransitionState() ==
|
||||||
if (x832_27_chargeAnimStarted || r30)
|
CPlayer::EPlayerMorphBallState::Morphed || resetBeam;
|
||||||
|
if (x832_27_chargeAnimStarted || doResetBeam)
|
||||||
PlayAnim(NWeaponTypes::EGunAnimType::BasePosition, false);
|
PlayAnim(NWeaponTypes::EGunAnimType::BasePosition, false);
|
||||||
if (r30)
|
if (doResetBeam)
|
||||||
x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::None);
|
x72c_currentBeam->EnableSecondaryFx(CGunWeapon::ESecondaryFxType::None);
|
||||||
if ((x2f8_stateFlags & 0x2) != 0x2 || x330_chargeState != EChargeState::Normal)
|
if ((x2f8_stateFlags & 0x2) != 0x2 || x330_chargeState != EChargeState::Normal)
|
||||||
{
|
{
|
||||||
|
@ -2559,7 +2560,7 @@ void CPlayerGun::Render(const CStateManager& mgr, const zeus::CVector3f& pos, co
|
||||||
}
|
}
|
||||||
|
|
||||||
oldViewMtx = CGraphics::g_ViewMatrix;
|
oldViewMtx = CGraphics::g_ViewMatrix;
|
||||||
CGraphics::SetModelMatrix(offsetWorldXf.inverse() * oldViewMtx);
|
CGraphics::SetViewPointMatrix(offsetWorldXf.inverse() * oldViewMtx);
|
||||||
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||||
x72c_currentBeam->PostRenderGunFx(mgr, offsetWorldXf);
|
x72c_currentBeam->PostRenderGunFx(mgr, offsetWorldXf);
|
||||||
if (x832_26_comboFiring && x77c_comboXferGen)
|
if (x832_26_comboFiring && x77c_comboXferGen)
|
||||||
|
|
|
@ -393,7 +393,7 @@ public:
|
||||||
void SetAssistAimTransform(const zeus::CTransform& xf) { x478_assistAimXf = xf; }
|
void SetAssistAimTransform(const zeus::CTransform& xf) { x478_assistAimXf = xf; }
|
||||||
CGrappleArm& GetGrappleArm() { return *x740_grappleArm; }
|
CGrappleArm& GetGrappleArm() { return *x740_grappleArm; }
|
||||||
void DamageRumble(const zeus::CVector3f& location, float damage, const CStateManager& mgr);
|
void DamageRumble(const zeus::CVector3f& location, float damage, const CStateManager& mgr);
|
||||||
void ResetCharge(CStateManager& mgr, bool b1);
|
void ResetCharge(CStateManager& mgr, bool resetBeam);
|
||||||
void HandleBeamChange(const CFinalInput& input, CStateManager& mgr);
|
void HandleBeamChange(const CFinalInput& input, CStateManager& mgr);
|
||||||
void HandlePhazonBeamChange(CStateManager& mgr);
|
void HandlePhazonBeamChange(CStateManager& mgr);
|
||||||
void HandleWeaponChange(const CFinalInput& input, CStateManager& mgr);
|
void HandleWeaponChange(const CFinalInput& input, CStateManager& mgr);
|
||||||
|
|
|
@ -94,6 +94,8 @@ void CPowerBeam::EnableSecondaryFx(ESecondaryFxType type)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ESecondaryFxType::None:
|
case ESecondaryFxType::None:
|
||||||
|
case ESecondaryFxType::ToCombo:
|
||||||
|
case ESecondaryFxType::CancelCharge:
|
||||||
if (x1cc_enabledSecondaryEffect != ESecondaryFxType::None && x238_power2ndGen)
|
if (x1cc_enabledSecondaryEffect != ESecondaryFxType::None && x238_power2ndGen)
|
||||||
x238_power2ndGen->SetParticleEmission(false);
|
x238_power2ndGen->SetParticleEmission(false);
|
||||||
x1cc_enabledSecondaryEffect = ESecondaryFxType::None;
|
x1cc_enabledSecondaryEffect = ESecondaryFxType::None;
|
||||||
|
|
Loading…
Reference in New Issue