Several CAnimData integrations

This commit is contained in:
Jack Andersen 2016-09-03 16:27:35 -10:00
parent c29013ba89
commit a349076740
37 changed files with 721 additions and 174 deletions

View File

@ -7,10 +7,10 @@ namespace urde
{
CAdditiveAnimPlayback::CAdditiveAnimPlayback(const std::weak_ptr<CAnimTreeNode>& anim,
float weight, bool a, const CAdditiveAnimationInfo& info, bool b)
: x0_info(info), x8_anim(anim.lock()), xc_targetWeight(weight), x14_a(a)
float weight, bool active, const CAdditiveAnimationInfo& info, bool b)
: x0_info(info), x8_anim(anim.lock()), xc_targetWeight(weight), x14_active(active)
{
if (!a && b)
if (!active && b)
x20_ = true;
}

View File

@ -43,12 +43,12 @@ private:
std::shared_ptr<CAnimTreeNode> x8_anim;
float xc_targetWeight;
float x10_curWeight = 0.f;
bool x14_a;
bool x14_active;
float x18_weightTimer = 0.f;
EAdditivePlaybackPhase x1c_phase = EAdditivePlaybackPhase::FadingIn;
bool x20_ = false;
public:
CAdditiveAnimPlayback(const std::weak_ptr<CAnimTreeNode>& anim, float weight, bool a,
CAdditiveAnimPlayback(const std::weak_ptr<CAnimTreeNode>& anim, float weight, bool active,
const CAdditiveAnimationInfo& info, bool b);
void AddToSegStatementSet(const CSegIdList& list, const CCharLayoutInfo&, CSegStatementSet&) const;
@ -56,7 +56,7 @@ public:
void FadeOut();
void SetWeight(float w);
float GetTargetWeight() const {return xc_targetWeight;}
bool GetA() const {return x14_a;}
bool IsActive() const {return x14_active;}
const std::shared_ptr<CAnimTreeNode>& GetAnim() const {return x8_anim;}
};

View File

@ -34,7 +34,9 @@ class CAnimFormatUnion
public:
CAnimFormatUnion(CInputStream& in, IObjectStore& store);
~CAnimFormatUnion();
operator CAnimSource&() {return *reinterpret_cast<CAnimSource*>(x4_storage);}
EAnimFormat GetFormat() const { return x0_format; }
const CAnimSource& GetAsCAnimSource() const { return *reinterpret_cast<const CAnimSource*>(x4_storage); }
const CFBStreamedCompression& GetAsCFBStreamedCompression() const { return *reinterpret_cast<const CFBStreamedCompression*>(x4_storage); }
};
class CAllFormatsAnimSource : public CAnimFormatUnion

View File

@ -16,6 +16,11 @@
#include "CAnimPerSegmentData.hpp"
#include "CSegStatementSet.hpp"
#include "CStateManager.hpp"
#include "CAnimPlaybackParms.hpp"
#include "CAnimTreeBlend.hpp"
#include "CPrimitive.hpp"
#include "CAllFormatsAnimSource.hpp"
#include "GameGlobalObjects.hpp"
namespace urde
{
@ -75,7 +80,7 @@ ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId id) const
void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet)
{
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x1048_additiveAnims)
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims)
if (additive.second.GetTargetWeight() > 0.00001f)
additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet);
}
@ -88,9 +93,9 @@ SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt)
{
CCharAnimTime time(dt);
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x1048_additiveAnims)
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims)
{
if (additive.second.GetA())
if (additive.second.IsActive())
{
while (time.GreaterThanZero() && std::fabs(time) >= 0.00001f)
{
@ -112,19 +117,37 @@ SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt)
return AdvanceAdditiveAnims(dt);
}
bool CAnimData::IsAdditiveAnimation(u32) const
bool CAnimData::IsAdditiveAnimation(u32 idx) const
{
return false;
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
return pair.first == idx;
});
if (search == x434_additiveAnims.cend())
return false;
return true;
}
std::shared_ptr<CAnimTreeNode> CAnimData::GetAdditiveAnimationTree(u32) const
std::shared_ptr<CAnimTreeNode> CAnimData::GetAdditiveAnimationTree(u32 idx) const
{
return {};
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
return pair.first == idx;
});
if (search == x434_additiveAnims.cend())
return {};
return search->second.GetAnim();
}
bool CAnimData::IsAdditiveAnimationActive(u32) const
bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
{
return false;
auto search = std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool {
return pair.first == idx;
});
if (search == x434_additiveAnims.cend())
return {};
return search->second.IsActive();
}
void CAnimData::DelAdditiveAnimation(u32)
@ -137,21 +160,23 @@ void CAnimData::AddAdditiveAnimation(u32, float, bool, bool)
std::shared_ptr<CAnimationManager> CAnimData::GetAnimationManager()
{
return {};
return x100_animMgr;
}
void CAnimData::SetPhase(float)
void CAnimData::SetPhase(float ph)
{
x1f8_animRoot->VSetPhase(ph);
}
void CAnimData::Touch(const CSkinnedModel& model, int) const
void CAnimData::Touch(const CSkinnedModel& model, int shadIdx) const
{
const_cast<CBooModel&>(*model.GetModelInst()).Touch(shadIdx);
}
SAdvancementDeltas CAnimData::GetAdvancementDeltas(const CCharAnimTime& a,
const CCharAnimTime& b) const
{
return {};
return x1f8_animRoot->VGetAdvancementResults(a, b).x8_deltas;
}
CCharAnimTime CAnimData::GetTimeOfUserEvent(EUserEventType, const CCharAnimTime& time) const
@ -159,12 +184,14 @@ CCharAnimTime CAnimData::GetTimeOfUserEvent(EUserEventType, const CCharAnimTime&
return {};
}
void CAnimData::MultiplyPlaybackRate(float)
void CAnimData::MultiplyPlaybackRate(float mul)
{
x200_speedScale += mul;
}
void CAnimData::SetPlaybackRate(float)
void CAnimData::SetPlaybackRate(float set)
{
x200_speedScale = set;
}
void CAnimData::SetRandomPlaybackRate(CRandom16&)
@ -172,7 +199,7 @@ void CAnimData::SetRandomPlaybackRate(CRandom16&)
}
void CAnimData::CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms,
const std::weak_ptr<CAnimTreeNode>& node)
const std::shared_ptr<CAnimTreeNode>& node)
{
}
@ -202,29 +229,69 @@ zeus::CTransform CAnimData::GetLocatorTransform(const std::string& name, const C
return GetLocatorTransform(xcc_layoutData->GetSegIdFromString(name), time);
}
bool CAnimData::IsAnimTimeRemaining(float, const std::string& name) const
bool CAnimData::IsAnimTimeRemaining(float rem, const std::string& name) const
{
return false;
if (!x1f8_animRoot)
return false;
return float(x1f8_animRoot->VGetTimeRemaining()) <= rem;
}
float CAnimData::GetAnimTimeRemaining(const std::string& name) const
{
return 0.f;
float rem = x1f8_animRoot->VGetTimeRemaining();
if (x200_speedScale)
return rem / x200_speedScale;
return rem;
}
float CAnimData::GetAnimationDuration(int) const
float CAnimData::GetAnimationDuration(int animIn) const
{
return 0.f;
std::shared_ptr<IMetaAnim> anim = x100_animMgr->GetMetaAnimation(xc_charInfo.GetAnimationIndex(animIn));
std::set<CPrimitive> prims;
anim->GetUniquePrimitives(prims);
SObjectTag tag{FOURCC('ANIM'), 0};
float durAccum = 0.f;
for (const CPrimitive& prim : prims)
{
tag.id = prim.GetAnimResId();
TLockedToken<CAllFormatsAnimSource> animRes = xfc_animCtx->xc_store.GetObj(tag);
CCharAnimTime dur;
switch (animRes->GetFormat())
{
case EAnimFormat::Uncompressed:
default:
{
const CAnimSource& src = animRes->GetAsCAnimSource();
dur = src.GetDuration();
break;
}
case EAnimFormat::BitstreamCompressed:
case EAnimFormat::BitstreamCompressed24:
{
const CFBStreamedCompression& src = animRes->GetAsCFBStreamedCompression();
dur = src.GetAnimationDuration();
break;
}
}
durAccum += dur;
}
if (anim->GetType() == EMetaAnimType::Random)
return durAccum / float(prims.size());
return durAccum;
}
std::shared_ptr<CAnimSysContext> CAnimData::GetAnimSysContext() const
{
return {};
return xfc_animCtx;
}
std::shared_ptr<CAnimationManager> CAnimData::GetAnimationManager() const
{
return {};
return x100_animMgr;
}
void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time)
@ -249,8 +316,9 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time)
}
}
void CAnimData::RenderAuxiliary(const CFrustumPlanes& frustum) const
void CAnimData::RenderAuxiliary(const zeus::CFrustum& frustum) const
{
const_cast<CParticleDatabase&>(x120_particleDB).AddToRendererClipped(frustum);
}
void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags,
@ -291,18 +359,99 @@ void CAnimData::PreRender()
void CAnimData::BuildPose()
{
if (!x220_31_poseCached)
{
RecalcPoseBuilder(nullptr);
x220_31_poseCached = true;
x220_30_poseBuilt = false;
}
if (!x220_30_poseBuilt)
{
x2fc_poseBuilder.BuildNoScale(x224_pose);
x220_30_poseBuilt = true;
}
}
void CAnimData::PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet, std::vector<CToken>& tokensOut)
void CAnimData::PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet,
std::vector<CToken>& tokensOut, bool preLock)
{
tokensOut.reserve(primSet.size());
SObjectTag tag{FOURCC('ANIM'), 0};
for (const CPrimitive& prim : primSet)
{
tag.id = prim.GetAnimResId();
tokensOut.push_back(g_SimplePool->GetObj(tag));
if (preLock)
tokensOut.back().Lock();
}
}
void CAnimData::GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set<CPrimitive>& primsOut) const
{
std::shared_ptr<IMetaAnim> animA =
GetAnimationManager()->GetMetaAnimation(xc_charInfo.GetAnimationIndex(parms.x0_animA));
animA->GetUniquePrimitives(primsOut);
if (parms.x4_animB != -1)
{
std::shared_ptr<IMetaAnim> animB =
GetAnimationManager()->GetMetaAnimation(xc_charInfo.GetAnimationIndex(parms.x4_animB));
animB->GetUniquePrimitives(primsOut);
}
}
void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool)
void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool noTrans)
{
if (parms.x0_animA == x40c_playbackParms.x0_animA ||
(parms.x4_animB != x40c_playbackParms.x4_animB &&
parms.x8_blendWeight == x40c_playbackParms.x8_blendWeight &&
parms.x8_blendWeight != 1.f) ||
parms.x4_animB == -1)
{
if (x220_29_)
return;
}
x40c_playbackParms.x0_animA = parms.x0_animA;
x40c_playbackParms.x4_animB = parms.x4_animB;
x40c_playbackParms.x8_blendWeight = parms.x8_blendWeight;
x200_speedScale = 1.f;
x208_defaultAnim = parms.x0_animA;
u32 animIdxA = xc_charInfo.GetAnimationIndex(parms.x0_animA);
ResetPOILists();
std::shared_ptr<CAnimTreeNode> blendNode;
if (parms.x4_animB != -1)
{
u32 animIdxB = xc_charInfo.GetAnimationIndex(parms.x4_animB);
std::shared_ptr<CAnimTreeNode> treeA =
GetAnimationManager()->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders());
std::shared_ptr<CAnimTreeNode> treeB =
GetAnimationManager()->GetAnimationTree(animIdxB, CMetaAnimTreeBuildOrders::NoSpecialOrders());
blendNode = std::make_shared<CAnimTreeBlend>(false, treeA, treeB, parms.x8_blendWeight,
CAnimTreeBlend::CreatePrimitiveName(treeA, treeB,
parms.x8_blendWeight));
}
else
{
blendNode = GetAnimationManager()->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders());
}
if (!noTrans)
x1f8_animRoot = x1fc_transMgr->GetTransitionTree(x1f8_animRoot, blendNode);
else
x1f8_animRoot = blendNode;
x220_24_animating = parms.xc_animating;
CalcPlaybackAlignmentParms(parms, blendNode);
ResetPOILists();
x220_29_ = true;
}
SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& b1, CRandom16& random, bool advTree)
@ -417,7 +566,7 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::
if (simplified->IsCAnimTreeNode())
{
if (x1f8_animRoot != simplified)
x1f8_animRoot = std::move(simplified);
x1f8_animRoot = std::static_pointer_cast<CAnimTreeNode>(std::move(simplified));
}
else
x1f8_animRoot.reset();
@ -467,10 +616,12 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::
void CAnimData::SetXRayModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules)
{
xf4_xrayModel = std::make_shared<CSkinnedModel>(model, skinRules, xd8_modelData->GetLayoutInfo(), 0);
}
void CAnimData::SetInfraModel(const TLockedToken<CModel>& model, const TLockedToken<CSkinRules>& skinRules)
{
xf8_infraModel = std::make_shared<CSkinnedModel>(model, skinRules, xd8_modelData->GetLayoutInfo(), 0);
}
void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose,
@ -481,32 +632,90 @@ void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms&
model.Calculate(pose, drawFlags, morphEffect, morphMagnitudes);
}
void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float,
const zeus::CVector3f&, CStateManager& stateMgr)
void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float dt,
const zeus::CVector3f& vec, CStateManager& stateMgr)
{
x120_particleDB.Update(dt, x224_pose, *xcc_layoutData, xf, vec, stateMgr);
}
void CAnimData::GetAverageVelocity(int) const
float CAnimData::GetAverageVelocity(int animIn) const
{
std::shared_ptr<IMetaAnim> anim = x100_animMgr->GetMetaAnimation(xc_charInfo.GetAnimationIndex(animIn));
std::set<CPrimitive> prims;
anim->GetUniquePrimitives(prims);
SObjectTag tag{FOURCC('ANIM'), 0};
float velAccum = 0.f;
float durAccum = 0.f;
for (const CPrimitive& prim : prims)
{
tag.id = prim.GetAnimResId();
TLockedToken<CAllFormatsAnimSource> animRes = xfc_animCtx->xc_store.GetObj(tag);
CCharAnimTime dur;
float avgVel;
switch (animRes->GetFormat())
{
case EAnimFormat::Uncompressed:
default:
{
const CAnimSource& src = animRes->GetAsCAnimSource();
dur = src.GetDuration();
avgVel = src.GetAverageVelocity();
break;
}
case EAnimFormat::BitstreamCompressed:
case EAnimFormat::BitstreamCompressed24:
{
const CFBStreamedCompression& src = animRes->GetAsCFBStreamedCompression();
dur = src.GetAnimationDuration();
avgVel = src.GetAverageVelocity();
break;
}
}
velAccum += dur * avgVel;
durAccum += dur;
}
if (durAccum > 0.f)
return velAccum / durAccum;
return 0.f;
}
void CAnimData::ResetPOILists()
{
x20c_passedBoolCount = 0;
x210_passedIntCount = 0;
x214_passedParticleCount = 0;
x218_passedSoundCount = 0;
}
CSegId CAnimData::GetLocatorSegId(const std::string& name) const
{
return {};
return xcc_layoutData->GetSegIdFromString(name);
}
zeus::CAABox CAnimData::GetBoundingBox(const zeus::CTransform& xf) const
{
return {};
return GetBoundingBox().getTransformedAABox(xf);
}
zeus::CAABox CAnimData::GetBoundingBox() const
{
return {};
auto aabbList = xc_charInfo.GetAnimBBoxList();
if (aabbList.empty())
return x108_aabb;
CAnimTreeEffectiveContribution contrib = x1f8_animRoot->GetContributionOfHighestInfluence();
auto search = std::find_if(aabbList.cbegin(), aabbList.cend(),
[&](const std::pair<std::string, zeus::CAABox>& other) -> bool {
return contrib.x4_name == other.first;
});
if (search == aabbList.cend())
return x108_aabb;
return search->second;
}
}

View File

@ -9,6 +9,7 @@
#include "CHierarchyPoseBuilder.hpp"
#include "CAdditiveAnimPlayback.hpp"
#include "CCharLayoutInfo.hpp"
#include "CAnimPlaybackParms.hpp"
#include <set>
enum class EUserEventType
@ -62,9 +63,7 @@ class CCharacterFactory;
class IMetaAnim;
struct CModelFlags;
class CVertexMorphEffect;
class CFrustumPlanes;
class CPrimitive;
class CAnimPlaybackParms;
class CRandom16;
class CStateManager;
class CCharAnimTime;
@ -98,7 +97,7 @@ class CAnimData
ResId x1d8_selfId;
zeus::CVector3f x1dc_;
zeus::CQuaternion x1e8_;
std::shared_ptr<IAnimReader> x1f8_animRoot;
std::shared_ptr<CAnimTreeNode> x1f8_animRoot;
std::shared_ptr<CTransitionManager> x1fc_transMgr;
float x200_speedScale = 1.f;
@ -129,17 +128,8 @@ class CAnimData
CPoseAsTransforms x224_pose;
CHierarchyPoseBuilder x2fc_poseBuilder;
u32 x1020_ = -1;
u32 x10204_ = -1;
float x1028_ = 1.f;
bool x102c_ = true;
u32 x1030_ = 0;
u32 x1034_ = 0;
bool x1038_ = false;
u32 x103c_ = 0;
u32 x1040_ = 0;
u32 x1044_ = 0;
rstl::reserved_vector<std::pair<u32, CAdditiveAnimPlayback>, 8> x1048_additiveAnims;
CAnimPlaybackParms x40c_playbackParms;
rstl::reserved_vector<std::pair<u32, CAdditiveAnimPlayback>, 8> x434_additiveAnims;
static rstl::reserved_vector<CBoolPOINode, 8> g_BoolPOINodes;
static rstl::reserved_vector<CInt32POINode, 16> g_Int32POINodes;
@ -177,7 +167,7 @@ public:
void SetPlaybackRate(float);
void SetRandomPlaybackRate(CRandom16&);
void CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms,
const std::weak_ptr<CAnimTreeNode>& node);
const std::shared_ptr<CAnimTreeNode>& node);
zeus::CTransform GetLocatorTransform(CSegId id, const CCharAnimTime* time) const;
zeus::CTransform GetLocatorTransform(const std::string& name, const CCharAnimTime* time) const;
bool IsAnimTimeRemaining(float, const std::string& name) const;
@ -189,7 +179,7 @@ public:
std::shared_ptr<CAnimSysContext> GetAnimSysContext() const;
std::shared_ptr<CAnimationManager> GetAnimationManager() const;
void RecalcPoseBuilder(const CCharAnimTime*);
void RenderAuxiliary(const CFrustumPlanes& frustum) const;
void RenderAuxiliary(const zeus::CFrustum& frustum) const;
void Render(CSkinnedModel& model, const CModelFlags& drawFlags,
const std::experimental::optional<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes);
@ -200,7 +190,8 @@ public:
static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags);
void PreRender();
void BuildPose();
void PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet, std::vector<CToken>& tokensOut);
static void PrimitiveSetToTokenVector(const std::set<CPrimitive>& primSet,
std::vector<CToken>& tokensOut, bool preLock);
void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set<CPrimitive>& primsOut) const;
void SetAnimation(const CAnimPlaybackParms& parms, bool);
SAdvancementDeltas DoAdvance(float, bool&, CRandom16&, bool advTree);
@ -216,7 +207,7 @@ public:
const float* morphMagnitudes);
void AdvanceParticles(const zeus::CTransform& xf, float dt,
const zeus::CVector3f&, CStateManager& stateMgr);
void GetAverageVelocity(int) const;
float GetAverageVelocity(int animIn) const;
void ResetPOILists();
CSegId GetLocatorSegId(const std::string& name) const;
zeus::CAABox GetBoundingBox(const zeus::CTransform& xf) const;

View File

@ -7,10 +7,11 @@ namespace urde
{
class CAnimPlaybackParms
{
s32 x0_defaultAnim;
s32 x4_;
float x8_scale;
bool xc_loop;
friend class CAnimData;
s32 x0_animA = -1;
s32 x4_animB = -1;
float x8_blendWeight = 1.f;
bool xc_animating = true;
s32 x10_ = 0;
s32 x14_ = 0;
bool x18_ = false;
@ -18,8 +19,9 @@ class CAnimPlaybackParms
s32 x20_ = 0;
s32 x24_ = 0;
public:
CAnimPlaybackParms(s32 defaultAnim, s32 b, float scale, bool loop)
: x0_defaultAnim(defaultAnim), x4_(b), x8_scale(scale), xc_loop(loop)
CAnimPlaybackParms() = default;
CAnimPlaybackParms(s32 animA, s32 animB, float blendWeight, bool animating)
: x0_animA(animA), x4_animB(animB), x8_blendWeight(blendWeight), xc_animating(animating)
{}
};
}

View File

@ -75,6 +75,7 @@ public:
const std::vector<CInt32POINode>& GetInt32POIStream() const;
const std::vector<CBoolPOINode>& GetBoolPOIStream() const;
const TCachedToken<CAnimPOIData>& GetPOIData() const {return x58_evntData;}
float GetAverageVelocity() const { return x60_averageVelocity; }
zeus::CQuaternion GetRotation(const CSegId& seg, const CCharAnimTime& time) const;
zeus::CVector3f GetOffset(const CSegId& seg, const CCharAnimTime& time) const;
bool HasOffset(const CSegId& seg) const;

View File

@ -0,0 +1,46 @@
#include "CAnimTreeBlend.hpp"
namespace urde
{
std::string CAnimTreeBlend::CreatePrimitiveName(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
float scale)
{
return "";
}
CAnimTreeBlend::CAnimTreeBlend(bool b1,
const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
float blendWeight, const std::string& name)
: CAnimTreeTweenBase(b1, a, b, 1 | 2, name), x24_blendWeight(blendWeight)
{
}
SAdvancementResults CAnimTreeBlend::VAdvanceView(const CCharAnimTime& a)
{
}
CCharAnimTime CAnimTreeBlend::VGetTimeRemaining() const
{
}
CSteadyStateAnimInfo CAnimTreeBlend::VGetSteadyStateAnimInfo() const
{
}
std::shared_ptr<IAnimReader> CAnimTreeBlend::VClone() const
{
}
void CAnimTreeBlend::SetBlendingWeight(float w)
{
}
float CAnimTreeBlend::VGetBlendingWeight() const
{
}
}

View File

@ -1,11 +1,30 @@
#ifndef __URDE_CANIMTREEBLEND_HPP__
#define __URDE_CANIMTREEBLEND_HPP__
#include "CAnimTreeTweenBase.hpp"
namespace urde
{
class CAnimTreeBlend
class CAnimTreeBlend : public CAnimTreeTweenBase
{
float x24_blendWeight;
public:
static std::string CreatePrimitiveName(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
float scale);
CAnimTreeBlend(bool,
const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
float blendWeight, const std::string& name);
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
CCharAnimTime VGetTimeRemaining() const;
CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const;
std::shared_ptr<IAnimReader> VClone() const;
void SetBlendingWeight(float w);
float VGetBlendingWeight() const;
};
}

View File

@ -0,0 +1,77 @@
#include "CAnimTreeDoubleChild.hpp"
namespace urde
{
CAnimTreeDoubleChild::CAnimTreeDoubleChild(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
const std::string& name)
: CAnimTreeNode(name), x14_a(a), x18_b(b)
{
}
SAdvancementResults CAnimTreeDoubleChild::VAdvanceView(const CCharAnimTime& a)
{
}
u32 CAnimTreeDoubleChild::VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut,
u32 capacity, u32 iterator, u32) const
{
}
u32 CAnimTreeDoubleChild::VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut,
u32 capacity, u32 iterator, u32) const
{
}
u32 CAnimTreeDoubleChild::VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut,
u32 capacity, u32 iterator, u32) const
{
}
u32 CAnimTreeDoubleChild::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut,
u32 capacity, u32 iterator, u32) const
{
}
bool CAnimTreeDoubleChild::VGetBoolPOIState(const char* name) const
{
}
s32 CAnimTreeDoubleChild::VGetInt32POIState(const char* name) const
{
}
CParticleData::EParentedMode CAnimTreeDoubleChild::VGetParticlePOIState(const char* name) const
{
}
void CAnimTreeDoubleChild::VSetPhase(float)
{
}
SAdvancementResults CAnimTreeDoubleChild::VGetAdvancementResults(const CCharAnimTime& a, const CCharAnimTime& b) const
{
}
u32 CAnimTreeDoubleChild::Depth() const
{
}
CAnimTreeEffectiveContribution CAnimTreeDoubleChild::VGetContributionOfHighestInfluence() const
{
}
u32 CAnimTreeDoubleChild::VGetNumChildren() const
{
}
std::shared_ptr<IAnimReader> CAnimTreeDoubleChild::VGetBestUnblendedChild() const
{
}
void CAnimTreeDoubleChild::VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const
{
}
}

View File

@ -8,7 +8,12 @@ namespace urde
class CAnimTreeDoubleChild : public CAnimTreeNode
{
std::shared_ptr<CAnimTreeNode> x14_a;
std::shared_ptr<CAnimTreeNode> x18_b;
public:
CAnimTreeDoubleChild(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
const std::string& name);
SAdvancementResults VAdvanceView(const CCharAnimTime& a);
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;
@ -23,6 +28,15 @@ public:
CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const;
u32 VGetNumChildren() const;
std::shared_ptr<IAnimReader> VGetBestUnblendedChild() const;
void VGetWeightedReaders(std::vector<std::pair<float, std::weak_ptr<IAnimReader>>>& out, float w) const;
virtual float VGetLeftChildWeight() const=0;
float GetLeftChildWeight() const { return VGetLeftChildWeight(); }
virtual float VGetRightChildWeight() const=0;
float GetRightChildWeight() const { return VGetRightChildWeight(); }
const std::shared_ptr<CAnimTreeNode>& GetLeftChild() const { return x14_a; }
const std::shared_ptr<CAnimTreeNode>& GetRightChild() const { return x18_b; }
};
}

View File

@ -0,0 +1,39 @@
#include "CAnimTreeTweenBase.hpp"
namespace urde
{
CAnimTreeTweenBase::CAnimTreeTweenBase(bool b1,
const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
int flags, const std::string& name)
: CAnimTreeDoubleChild(a, b, name), x1c_flags(flags), x20_31_b1(b1)
{
}
void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const
{
}
void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut,
const CCharAnimTime& time) const
{
}
bool CAnimTreeTweenBase::VHasOffset(const CSegId& seg) const
{
}
zeus::CVector3f CAnimTreeTweenBase::VGetOffset(const CSegId& seg) const
{
}
zeus::CQuaternion CAnimTreeTweenBase::VGetRotation(const CSegId& seg) const
{
}
std::shared_ptr<IAnimReader> CAnimTreeTweenBase::VSimplified()
{
}
}

View File

@ -8,6 +8,31 @@ namespace urde
class CAnimTreeTweenBase : public CAnimTreeDoubleChild
{
int x1c_flags;
bool x20_31_b1;
bool x20_30_b2 = false;
public:
CAnimTreeTweenBase(bool,
const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
int, const std::string& name);
virtual void SetBlendingWeight(float w)=0;
virtual float VGetBlendingWeight() const=0;
float GetBlendingWeight() const { return VGetBlendingWeight(); }
float VGetLeftChildWeight() const { return 1.f - GetBlendingWeight(); }
float VGetRightChildWeight() const { return GetBlendingWeight(); }
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const;
void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, const CCharAnimTime& time) const;
bool VHasOffset(const CSegId& seg) const;
zeus::CVector3f VGetOffset(const CSegId& seg) const;
zeus::CQuaternion VGetRotation(const CSegId& seg) const;
std::shared_ptr<IAnimReader> VSimplified();
bool ShouldCullTree() const { return false; }
};
}

View File

@ -1,6 +1,7 @@
#include "CAnimationManager.hpp"
#include "CAnimationDatabaseGame.hpp"
#include "CTransitionDatabaseGame.hpp"
#include "IMetaAnim.hpp"
namespace urde
{
@ -10,4 +11,16 @@ const CAnimationDatabaseGame* CAnimationManager::GetAnimationDatabase() const
return x0_animDB.GetObj();
}
std::shared_ptr<CAnimTreeNode>
CAnimationManager::GetAnimationTree(u32 animIdx, const CMetaAnimTreeBuildOrders& orders) const
{
const std::shared_ptr<IMetaAnim>& anim = x0_animDB->GetMetaAnim(animIdx);
return anim->GetAnimationTree(x8_sysCtx, orders);
}
const std::shared_ptr<IMetaAnim>& CAnimationManager::GetMetaAnimation(u32 idx) const
{
return x0_animDB->GetMetaAnim(idx);
}
}

View File

@ -9,6 +9,9 @@ namespace urde
class CAnimationDatabaseGame;
class CTransitionDatabaseGame;
class CSimplePool;
class CAnimTreeNode;
class CMetaAnimTreeBuildOrders;
class IMetaAnim;
class CAnimationManager
{
@ -20,6 +23,8 @@ public:
: x0_animDB(animDB), x8_sysCtx(sysCtx) {}
const CAnimationDatabaseGame* GetAnimationDatabase() const;
std::shared_ptr<CAnimTreeNode> GetAnimationTree(u32, const CMetaAnimTreeBuildOrders& orders) const;
const std::shared_ptr<IMetaAnim>& GetMetaAnimation(u32) const;
};
}

View File

@ -37,9 +37,10 @@ void CCharLayoutNode::Bone::read(CInputStream& in)
}
CCharLayoutNode::CCharLayoutNode(CInputStream& in)
: x0_boneMap(in.readUint32Big())
{
u32 count = in.readUint32Big();
for (u32 i=0 ; i<count ; ++i)
u32 cap = x0_boneMap.GetCapacity();
for (u32 i=0 ; i<cap ; ++i)
{
u32 thisId = in.readUint32Big();
Bone& bone = x0_boneMap[thisId];

View File

@ -46,10 +46,13 @@ public:
ResId GetSkinRulesId() const {return x18_cskr;}
ResId GetCharLayoutInfoId() const {return x1c_cinf;}
const std::vector<std::pair<std::string, zeus::CAABox>>& GetAnimBBoxList() const { return x88_aabbs; }
ResId GetIceModelId() const {return xa8_cmdlOverlay;}
ResId GetIceSkinRulesId() const {return xac_cskrOverlay;}
const CParticleResData& GetParticleResData() const {return x44_partRes;}
u32 GetAnimationIndex(u32 idx) const { return xb0_animIdxs[idx]; }
};
}

View File

@ -1,4 +1,5 @@
#include "CFBStreamedCompression.hpp"
#include "CFBStreamedAnimReader.hpp"
namespace urde
{
@ -13,6 +14,8 @@ CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& o
if (x4_evnt)
x8_evntToken = objStore.GetObj(SObjectTag{FOURCC('EVNT'), x4_evnt});
x10_averageVelocity = CalculateAverageVelocity(GetPerChannelHeaders());
}
const u32* CFBStreamedCompression::GetTimes() const
@ -217,4 +220,65 @@ u32 CFBStreamedCompression::ComputeBitstreamWords(const u8* chans)
return (totalBits * keyCount + 31) / 32;
}
float CFBStreamedCompression::CalculateAverageVelocity(const u8* chans)
{
u32 boneChanCount = *reinterpret_cast<const u32*>(chans);
chans += 4;
u32 keyCount;
u32 rootIdx = 0;
if (m_pc)
{
keyCount = *reinterpret_cast<const u32*>(chans + 0x4);
for (u32 c=0 ; c<boneChanCount ; ++c)
{
u32 boneId = *reinterpret_cast<const u32*>(chans);
if (boneId == 3)
break;
++rootIdx;
chans += 0x8;
u32 tKeyCount = *reinterpret_cast<const u32*>(chans + 0xc);
chans += 0x10;
if (tKeyCount)
chans += 0xc;
}
}
else
{
keyCount = *reinterpret_cast<const u16*>(chans + 0x4);
for (u32 c=0 ; c<boneChanCount ; ++c)
{
u32 boneId = *reinterpret_cast<const u32*>(chans);
if (boneId == 3)
break;
++rootIdx;
chans += 0x6;
u16 tKeyCount = *reinterpret_cast<const u16*>(chans + 0x9);
chans += 0xb;
if (tKeyCount)
chans += 0x9;
}
}
CBitLevelLoader loader(GetBitstreamPointer());
CFBStreamedAnimReaderTotals tempTotals(*this);
tempTotals.CalculateDown();
const float* floats = tempTotals.GetFloats(rootIdx);
zeus::CVector3f transCompA(floats[4], floats[5], floats[6]);
float accumMag = 0.f;
for (u32 i=0 ; i<keyCount ; ++i)
{
tempTotals.IncrementInto(loader, *this, tempTotals);
tempTotals.CalculateDown();
zeus::CVector3f transCompB(floats[4], floats[5], floats[6]);
accumMag += (transCompB - transCompA).magnitude();
transCompA = transCompB;
}
return accumMag / GetAnimationDuration();
}
}

View File

@ -58,11 +58,13 @@ private:
ResId x4_evnt;
TLockedToken<CAnimPOIData> x8_evntToken;
std::unique_ptr<u32[]> xc_rotsAndOffs;
float x10_averageVelocity;
zeus::CVector3f x14_rootOffset;
u8* ReadBoneChannelDescriptors(u8* out, CInputStream& in);
u32 ComputeBitstreamWords(const u8* chans);
std::unique_ptr<u32[]> GetRotationsAndOffsets(u32 words, CInputStream& in);
float CalculateAverageVelocity(const u8* chans);
public:
CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc);
@ -72,6 +74,7 @@ public:
const u8* GetBitstreamPointer() const;
bool IsLooping() const { return MainHeader().looping; }
CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; }
float GetAverageVelocity() const { return x10_averageVelocity; }
const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; }
bool HasPOIData() const { return x8_evntToken; }
const std::vector<CBoolPOINode>& GetBoolPOIStream() const { return x8_evntToken->GetBoolPOIStream(); }

View File

@ -8,7 +8,7 @@ namespace urde
void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
const CSegId& boneId, const CSegId& nullId)
{
if (!x0_treeMap.HasElement(boneId))
if (!x38_treeMap.HasElement(boneId))
{
const CCharLayoutNode::Bone& bone = layout.GetRootNode()->GetBoneMap()[boneId];
if (bone.x0_parentId == nullId)
@ -16,17 +16,17 @@ void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
xcec_rootId = boneId;
xcf0_hasRoot = true;
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
x0_treeMap[boneId] = CTreeNode(origin);
x38_treeMap[boneId] = CTreeNode(origin);
}
else
{
BuildIntoHierarchy(layout, bone.x0_parentId, nullId);
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
CTreeNode& pNode = x0_treeMap[bone.x0_parentId];
CTreeNode& pNode = x38_treeMap[bone.x0_parentId];
CTreeNode node(origin);
node.x1_sibling = pNode.x0_child;
pNode.x0_child = boneId;
x0_treeMap[boneId] = node;
x38_treeMap[boneId] = node;
}
}
}
@ -43,7 +43,7 @@ void CHierarchyPoseBuilder::RecursivelyBuildNoScale(const CSegId& boneId, const
CSegId curBone = node.x0_child;
while (curBone != 0)
{
const CTreeNode& node = x0_treeMap[curBone];
const CTreeNode& node = x38_treeMap[curBone];
RecursivelyBuild(curBone, node, pose, quat, xf, xfOffset);
curBone = node.x1_sibling;
}
@ -56,8 +56,8 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo
zeus::CQuaternion quat = parentRot * node.x4_rotation;
float scale;
if (xcf4_layoutDesc.GetScaledLayoutDescription())
scale = xcf4_layoutDesc.GetScaledLayoutDescription()->GetScale();
if (x0_layoutDesc.GetScaledLayoutDescription())
scale = x0_layoutDesc.GetScaledLayoutDescription()->GetScale();
else
scale = 1.f;
@ -73,7 +73,7 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo
CSegId curBone = node.x0_child;
while (curBone != 0)
{
const CTreeNode& node = x0_treeMap[curBone];
const CTreeNode& node = x38_treeMap[curBone];
RecursivelyBuild(curBone, node, pose, quat, quat, xfOffset);
curBone = node.x1_sibling;
}
@ -83,14 +83,14 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
{
TLockedToken<CCharLayoutInfo> layoutInfoTok;
float scale;
if (xcf4_layoutDesc.GetScaledLayoutDescription())
if (x0_layoutDesc.GetScaledLayoutDescription())
{
layoutInfoTok = xcf4_layoutDesc.GetScaledLayoutDescription()->GetCharLayoutInfo();
scale = xcf4_layoutDesc.GetScaledLayoutDescription()->GetScale();
layoutInfoTok = x0_layoutDesc.GetScaledLayoutDescription()->GetCharLayoutInfo();
scale = x0_layoutDesc.GetScaledLayoutDescription()->GetScale();
}
else
{
layoutInfoTok = xcf4_layoutDesc.GetCharLayoutInfo();
layoutInfoTok = x0_layoutDesc.GetCharLayoutInfo();
scale = 1.f;
}
const CCharLayoutInfo& layoutInfo = *layoutInfoTok.GetObj();
@ -112,7 +112,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
for (CSegId* id=&buildIDs[idCount] ; id != buildIDs ; --id)
{
CSegId& thisId = id[-1];
const CTreeNode& node = x0_treeMap[thisId];
const CTreeNode& node = x38_treeMap[thisId];
accumRot *= node.x4_rotation;
accumPos += accumXF * node.x14_offset;
if (scale == 1.f)
@ -128,7 +128,7 @@ void CHierarchyPoseBuilder::BuildTransform(const CSegId& boneId, zeus::CTransfor
void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose)
{
pose.Clear();
const CTreeNode& node = x0_treeMap[xcec_rootId];
const CTreeNode& node = x38_treeMap[xcec_rootId];
zeus::CQuaternion quat;
zeus::CMatrix3f mtx;
zeus::CVector3f vec;
@ -137,16 +137,16 @@ void CHierarchyPoseBuilder::BuildNoScale(CPoseAsTransforms& pose)
void CHierarchyPoseBuilder::Insert(const CSegId& boneId, const zeus::CQuaternion& quat)
{
x0_treeMap[boneId] = CTreeNode(quat);
x38_treeMap[boneId] = CTreeNode(quat);
}
void CHierarchyPoseBuilder::Insert(const CSegId& boneId, const zeus::CQuaternion& quat, const zeus::CVector3f& offset)
{
x0_treeMap[boneId] = CTreeNode(quat, offset);
x38_treeMap[boneId] = CTreeNode(quat, offset);
}
CHierarchyPoseBuilder::CHierarchyPoseBuilder(const CLayoutDescription& layout)
: xcf4_layoutDesc(layout)
: x0_layoutDesc(layout), x38_treeMap(layout.GetCharLayoutInfo()->GetSegIdList().GetList().size())
{
TLockedToken<CCharLayoutInfo> layoutInfoTok;
if (layout.GetScaledLayoutDescription())

View File

@ -14,6 +14,10 @@ class CPoseAsTransforms;
class CHierarchyPoseBuilder
{
CLayoutDescription x0_layoutDesc;
bool x34_ = 0;
struct CTreeNode
{
CSegId x0_child = 0;
@ -26,11 +30,10 @@ class CHierarchyPoseBuilder
CTreeNode(const zeus::CQuaternion& quat, const zeus::CVector3f& offset)
: x4_rotation(quat), x14_offset(offset) {}
};
TSegIdMap<CTreeNode> x0_treeMap;
TSegIdMap<CTreeNode> x38_treeMap;
CSegId xcec_rootId;
bool xcf0_hasRoot = false;
CLayoutDescription xcf4_layoutDesc;
void BuildIntoHierarchy(const CCharLayoutInfo& layout,
const CSegId& boneId, const CSegId& nullId);

View File

@ -50,6 +50,7 @@ set(CHARACTER_SOURCES
CAnimTreeSequence.hpp CAnimTreeSequence.cpp
CSequenceHelper.hpp CSequenceHelper.cpp
CAnimTreeAnimReaderContainer.hpp CAnimTreeAnimReaderContainer.cpp
CTreeUtils.hpp CTreeUtils.cpp
CAnimTreeBlend.hpp CAnimTreeBlend.cpp
CAnimTreeNode.hpp CAnimTreeNode.cpp
CAnimTreeScale.hpp CAnimTreeScale.cpp

View File

@ -3,7 +3,6 @@
#include "IAnimReader.hpp"
#include "Graphics/CGraphics.hpp"
#include "Graphics/CSkinnedModel.hpp"
#include "Graphics/CFrustumPlanes.hpp"
#include "Graphics/CVertexMorphEffect.hpp"
#include "Editor/ProjectManager.hpp"
#include "CActorLights.hpp"
@ -266,14 +265,14 @@ bool CModelData::IsAnimating() const
}
bool CModelData::IsInFrustum(const zeus::CTransform& xf,
const CFrustumPlanes& frustum) const
const zeus::CFrustum& frustum) const
{
if (!x10_animData && !x1c_normalModel)
return true;
return frustum.BoxInFrustumPlanes(GetBounds(xf));
return frustum.aabbFrustumTest(GetBounds(xf));
}
void CModelData::RenderParticles(const CFrustumPlanes& frustum) const
void CModelData::RenderParticles(const zeus::CFrustum& frustum) const
{
if (x10_animData)
x10_animData->RenderAuxiliary(frustum);

View File

@ -16,7 +16,6 @@ class CStateManager;
class CActorLights;
struct CModelFlags;
class CRandom16;
class CFrustumPlanes;
class CAnimData;
class CModel;
class CSkinnedModel;
@ -128,8 +127,8 @@ public:
SAdvancementDeltas AdvanceAnimationIgnoreParticles(float dt, CRandom16&, bool advTree);
SAdvancementDeltas AdvanceAnimation(float dt, CStateManager& stateMgr, TAreaId aid, bool advTree);
bool IsAnimating() const;
bool IsInFrustum(const zeus::CTransform& xf, const CFrustumPlanes& frustum) const;
void RenderParticles(const CFrustumPlanes& frustum) const;
bool IsInFrustum(const zeus::CTransform& xf, const zeus::CFrustum& frustum) const;
void RenderParticles(const zeus::CFrustum& frustum) const;
void Touch(EWhichModel, int shaderIdx);
void Touch(const CStateManager& stateMgr, int shaderIdx);
void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& a, const zeus::CColor& b);

View File

@ -20,4 +20,13 @@ void CParticleDatabase::StartEffect(const std::string& name, u32 flags, const CP
{
}
void CParticleDatabase::Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo,
const zeus::CTransform& xf, const zeus::CVector3f& vec, CStateManager& stateMgr)
{
}
void CParticleDatabase::AddToRendererClipped(const zeus::CFrustum& frustum)
{
}
}

View File

@ -3,10 +3,13 @@
#include "CCharacterInfo.hpp"
#include "CParticleGenInfo.hpp"
#include "zeus/CFrustum.hpp"
#include <map>
namespace urde
{
class CPoseAsTransforms;
class CCharLayoutInfo;
class CParticleDatabase
{
@ -17,6 +20,9 @@ public:
void SuspendAllActiveEffects(CStateManager& stateMgr);
void StartEffect(const std::string& name, u32 flags, const CParticleData& data,
const zeus::CVector3f& scale, CStateManager& stateMgr, TAreaId aid, u32 unk1);
void Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo,
const zeus::CTransform& xf, const zeus::CVector3f& vec, CStateManager& stateMgr);
void AddToRendererClipped(const zeus::CFrustum& frustum);
};
}

View File

@ -0,0 +1,14 @@
#include "CTransitionManager.hpp"
#include "CTreeUtils.hpp"
namespace urde
{
std::shared_ptr<CAnimTreeNode>
CTransitionManager::GetTransitionTree(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b) const
{
return CTreeUtils::GetTransitionTree(a, b, x0_animCtx);
}
}

View File

@ -9,12 +9,15 @@ namespace urde
class CTransitionDatabaseGame;
class CRandom16;
class CSimplePool;
class CAnimTreeNode;
class CTransitionManager
{
CAnimSysContext x0_animCtx;
public:
CTransitionManager(const CAnimSysContext& sysCtx) : x0_animCtx(sysCtx) {}
std::shared_ptr<CAnimTreeNode> GetTransitionTree(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b) const;
};
}

View File

@ -0,0 +1,20 @@
#include "CTreeUtils.hpp"
#include "CAnimTreeNode.hpp"
#include "CAnimSysContext.hpp"
#include "CTransitionDatabaseGame.hpp"
#include "IMetaTrans.hpp"
namespace urde
{
std::shared_ptr<CAnimTreeNode> CTreeUtils::GetTransitionTree(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
const CAnimSysContext& animCtx)
{
CAnimTreeEffectiveContribution contribA = a->GetContributionOfHighestInfluence();
CAnimTreeEffectiveContribution contribB = b->GetContributionOfHighestInfluence();
return animCtx.x0_transDB->GetMetaTrans(contribA.GetAnimDatabaseIndex(),
contribB.GetAnimDatabaseIndex())->GetTransitionTree(a, b, animCtx);
}
}

View File

@ -0,0 +1,21 @@
#ifndef __URDE_CTREEUTILS_HPP__
#define __URDE_CTREEUTILS_HPP__
#include "RetroTypes.hpp"
namespace urde
{
class CAnimTreeNode;
class CAnimSysContext;
class CTreeUtils
{
public:
static std::shared_ptr<CAnimTreeNode> GetTransitionTree(const std::shared_ptr<CAnimTreeNode>& a,
const std::shared_ptr<CAnimTreeNode>& b,
const CAnimSysContext& animCtx);
};
}
#endif // __URDE_CTREEUTILS_HPP__

View File

@ -24,6 +24,13 @@ public:
const std::weak_ptr<CAnimTreeNode>& b,
const CAnimSysContext& animSys) const=0;
virtual EMetaTransType GetType() const=0;
std::shared_ptr<CAnimTreeNode> GetTransitionTree(const std::weak_ptr<CAnimTreeNode>& a,
const std::weak_ptr<CAnimTreeNode>& b,
const CAnimSysContext& animSys)
{
return VGetTransitionTree(a, b, animSys);
}
};
}

View File

@ -11,45 +11,52 @@ template <class T>
class TSegIdMap
{
CSegId x0_boneCount = 0;
CSegId x1_curPrevBone = 0;
u32 x4_capacity = 100;
CSegId x8_prevBones[100];
T x6c_bones[100];
CSegId x1_capacity = 0;
u32 x4_maxCapacity = 100;
std::pair<CSegId, CSegId> x8_indirectionMap[100];
std::unique_ptr<T[]> xd0_bones;
CSegId xd4_curPrevBone = 0;
public:
TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {}
T& operator[](const CSegId& id) {return SetElement(id);}
const T& operator[](const CSegId& id) const {return x6c_bones[id];}
const T& operator[](const CSegId& id) const {return xd0_bones[id];}
T& SetElement(const CSegId& id, T&& obj)
{
x6c_bones[id] = std::move(obj);
if (x8_prevBones[id] == 0xff)
xd0_bones[id] = std::move(obj);
if (x8_indirectionMap[id].first == 0xff)
{
x8_prevBones[id] = x1_curPrevBone;
x1_curPrevBone = id;
x8_indirectionMap[id].first = xd4_curPrevBone;
x8_indirectionMap[id].second = x0_boneCount;
xd4_curPrevBone = id;
++x0_boneCount;
}
return x6c_bones[id];
return xd0_bones[id];
}
T& SetElement(const CSegId& id)
{
if (x8_prevBones[id] == 0xff)
if (x8_indirectionMap[id].first == 0xff)
{
x8_prevBones[id] = x1_curPrevBone;
x1_curPrevBone = id;
x8_indirectionMap[id].first = xd4_curPrevBone;
x8_indirectionMap[id].second = x0_boneCount;
xd4_curPrevBone = id;
++x0_boneCount;
}
return x6c_bones[id];
return xd0_bones[id];
}
void DelElement(const CSegId& id)
{
if (x8_prevBones[id] != 0xff)
if (x8_indirectionMap[id].first != 0xff)
{
if (id == x1_curPrevBone)
x1_curPrevBone = x8_prevBones[id];
x8_prevBones[id] = 0xff;
if (id == xd4_curPrevBone)
xd4_curPrevBone = x8_indirectionMap[id].first;
x8_indirectionMap[id].first = 0xff;
x8_indirectionMap[id].second = 0xff;
--x0_boneCount;
}
}
bool HasElement(const CSegId& id) const {return x8_prevBones[id] != 0xff;}
bool HasElement(const CSegId& id) const {return x8_indirectionMap[id].first != 0xff;}
u32 GetCapacity() const { return x1_capacity; }
};
}

View File

@ -1,30 +0,0 @@
#include "CFrustumPlanes.hpp"
namespace urde
{
CFrustumPlanes::CFrustumPlanes(const zeus::CTransform& cameraXf, float, float, float, bool, float)
{
}
bool CFrustumPlanes::PointInFrustumPlanes(const zeus::CVector3f& point) const
{
return false;
}
bool CFrustumPlanes::SphereInFrustumPlanes(const zeus::CSphere& sphere) const
{
return false;
}
bool CFrustumPlanes::BoxInFrustumPlanes(const zeus::CAABox& box) const
{
return false;
}
bool CFrustumPlanes::BoxInFrustumPlanes(const rstl::optional_object<zeus::CAABox>& box) const
{
return false;
}
}

View File

@ -1,24 +0,0 @@
#ifndef __URDE_CFRUSTUMPLANES_HPP__
#define __URDE_CFRUSTUMPLANES_HPP__
#include "zeus/CTransform.hpp"
#include "zeus/CAABox.hpp"
#include "rstl.hpp"
namespace urde
{
class CFrustumPlanes
{
public:
CFrustumPlanes(const zeus::CTransform& cameraXf, float, float, float, bool, float);
bool PointInFrustumPlanes(const zeus::CVector3f& point) const;
bool SphereInFrustumPlanes(const zeus::CSphere& sphere) const;
bool BoxInFrustumPlanes(const zeus::CAABox& box) const;
bool BoxInFrustumPlanes(const rstl::optional_object<zeus::CAABox>& box) const;
};
}
#endif // __URDE_CFRUSTUMPLANES_HPP__

View File

@ -36,7 +36,6 @@ set(GRAPHICS_SOURCES
CSkinnedModel.hpp CSkinnedModel.cpp
CVertexMorphEffect.hpp CVertexMorphEffect.cpp
CMoviePlayer.hpp CMoviePlayer.cpp
CFrustumPlanes.hpp CFrustumPlanes.cpp
CGraphicsPalette.hpp CGraphicsPalette.cpp
CPVSVisSet.hpp CPVSVisSet.cpp
CPVSVisOctree.hpp CPVSVisOctree.cpp

View File

@ -34,10 +34,10 @@ public:
CSkinnedModel(IObjectStore& store, ResId model, ResId skinRules,
ResId layoutInfo, int shaderIdx);
TLockedToken<CModel>& GetModel() {return x4_model;}
std::unique_ptr<CBooModel>& GetModelInst() {return m_modelInst;}
TLockedToken<CSkinRules>& GetSkinRules() {return x10_skinRules;}
TLockedToken<CCharLayoutInfo>& GetLayoutInfo() {return x1c_layoutInfo;}
const TLockedToken<CModel>& GetModel() const {return x4_model;}
const std::unique_ptr<CBooModel>& GetModelInst() const {return m_modelInst;}
const TLockedToken<CSkinRules>& GetSkinRules() const {return x10_skinRules;}
const TLockedToken<CCharLayoutInfo>& GetLayoutInfo() const {return x1c_layoutInfo;}
void Calculate(const CPoseAsTransforms& pose,
const CModelFlags& drawFlags,

View File

@ -13,7 +13,6 @@ class CActorLights;
class CPlayer;
class CDamageInfo;
class CFinalInput;
class CFrustumPlanes;
class CScriptWater;
class CStateManager;
@ -91,7 +90,7 @@ public:
zeus::CTransform GetPrimitiveTransform() const { return {}; }
void DrawCollisionPrimitive() const {}
void GetMinimumAlignmentSpeed() const {}
void PreRender(CStateManager&, const CFrustumPlanes&);
void PreRender(CStateManager&, const zeus::CFrustum&);
void Render(const CStateManager&, const CActorLights*) const {}
void ResetMorphBallTransitionFlash() {}
void UpdateMorphBallTransitionFlash(float) {}
@ -108,7 +107,7 @@ public:
void DisableHalfPipeStatus() {}
void BallCloseToCollision(const CStateManager&, float) const {}
void CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&) {}
void IsInFrustum(const CFrustumPlanes&) const {}
void IsInFrustum(const zeus::CFrustum&) const {}
void ComputeLiftForces(const zeus::CVector3f&, const zeus::CVector3f&, const CStateManager&) {}
void CalculateSurfaceFriction() const {}
void ApplyGravity(CStateManager&) {}