Move BuildAnimation to CSkeletalAnimMgr / CObjectEntry
There is no need to have BuildAnimation in CModel when everything is done in CObjectEntry anyways. This removes a pointer in every CModel object, which is nice. Accepted By: vladislavbelov Differential Revision: https://code.wildfiregames.com/D4454 This was SVN commit r26254.
This commit is contained in:
parent
fe816ecb1a
commit
83d251406c
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -25,7 +25,6 @@
|
||||
#include "graphics/ObjectEntry.h"
|
||||
#include "graphics/SkeletonAnim.h"
|
||||
#include "graphics/SkeletonAnimDef.h"
|
||||
#include "graphics/SkeletonAnimManager.h"
|
||||
#include "maths/BoundingBoxAligned.h"
|
||||
#include "maths/Quaternion.h"
|
||||
#include "lib/sysdep/rtl.h"
|
||||
@ -40,10 +39,9 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
CModel::CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation)
|
||||
CModel::CModel(CSimulation2& simulation)
|
||||
: m_Flags(0), m_Anim(NULL), m_AnimTime(0), m_Simulation(simulation),
|
||||
m_BoneMatrices(NULL), m_AmmoPropPoint(NULL), m_AmmoLoadedProp(0),
|
||||
m_SkeletonAnimManager(skeletonAnimManager)
|
||||
m_BoneMatrices(NULL), m_AmmoPropPoint(NULL), m_AmmoLoadedProp(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -198,43 +196,6 @@ const CBoundingBoxAligned CModel::GetObjectSelectionBoundsRec()
|
||||
return objBounds;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// BuildAnimation: load raw animation frame animation from given file, and build a
|
||||
// animation specific to this model
|
||||
CSkeletonAnim* CModel::BuildAnimation(const VfsPath& pathname, const CStr& name, const CStr& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos)
|
||||
{
|
||||
CSkeletonAnimDef* def = m_SkeletonAnimManager.GetAnimation(pathname);
|
||||
if (!def)
|
||||
return NULL;
|
||||
|
||||
CSkeletonAnim* anim = new CSkeletonAnim();
|
||||
anim->m_Name = name;
|
||||
anim->m_ID = ID;
|
||||
anim->m_Frequency = frequency;
|
||||
anim->m_AnimDef = def;
|
||||
anim->m_Speed = speed;
|
||||
|
||||
if (actionpos == -1.f)
|
||||
anim->m_ActionPos = -1.f;
|
||||
else
|
||||
anim->m_ActionPos = actionpos * anim->m_AnimDef->GetDuration();
|
||||
|
||||
if (actionpos2 == -1.f)
|
||||
anim->m_ActionPos2 = -1.f;
|
||||
else
|
||||
anim->m_ActionPos2 = actionpos2 * anim->m_AnimDef->GetDuration();
|
||||
|
||||
if (soundpos == -1.f)
|
||||
anim->m_SoundPos = -1.f;
|
||||
else
|
||||
anim->m_SoundPos = soundpos * anim->m_AnimDef->GetDuration();
|
||||
|
||||
anim->m_ObjectBounds.SetEmpty();
|
||||
InvalidateBounds();
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Update: update this model to the given time, in msec
|
||||
void CModel::UpdateTo(float time)
|
||||
@ -533,7 +494,7 @@ CModelAbstract* CModel::FindFirstAmmoProp()
|
||||
// Clone: return a clone of this model
|
||||
CModelAbstract* CModel::Clone() const
|
||||
{
|
||||
CModel* clone = new CModel(m_SkeletonAnimManager, m_Simulation);
|
||||
CModel* clone = new CModel(m_Simulation);
|
||||
clone->m_ObjectBounds = m_ObjectBounds;
|
||||
clone->InitModel(m_pModelDef);
|
||||
clone->SetMaterial(m_Material);
|
||||
|
@ -32,7 +32,6 @@ struct SPropPoint;
|
||||
class CObjectEntry;
|
||||
class CSkeletonAnim;
|
||||
class CSkeletonAnimDef;
|
||||
class CSkeletonAnimManager;
|
||||
class CSimulation2;
|
||||
|
||||
#define MODELFLAG_CASTSHADOWS (1<<0)
|
||||
@ -77,7 +76,7 @@ public:
|
||||
|
||||
public:
|
||||
// constructor
|
||||
CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation);
|
||||
CModel(CSimulation2& simulation);
|
||||
// destructor
|
||||
~CModel();
|
||||
|
||||
@ -187,21 +186,6 @@ public:
|
||||
return m_BoneMatrices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load raw animation frame animation from given file, and build an
|
||||
* animation specific to this model.
|
||||
* @param pathname animation file to load
|
||||
* @param name animation name (e.g. "idle")
|
||||
* @param ID specific ID of the animation, to sync with props
|
||||
* @param frequency influences the random choices
|
||||
* @param speed animation speed as a factor of the default animation speed
|
||||
* @param actionpos offset of 'action' event, in range [0, 1]
|
||||
* @param actionpos2 offset of 'action2' event, in range [0, 1]
|
||||
* @param sound offset of 'sound' event, in range [0, 1]
|
||||
* @return new animation, or NULL on error
|
||||
*/
|
||||
CSkeletonAnim* BuildAnimation(const VfsPath& pathname, const CStr& name, const CStr& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos);
|
||||
|
||||
/**
|
||||
* Add a prop to the model on the given point.
|
||||
*/
|
||||
@ -290,9 +274,6 @@ private:
|
||||
* If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop
|
||||
*/
|
||||
size_t m_AmmoLoadedProp;
|
||||
|
||||
// manager object which can load animations for us
|
||||
CSkeletonAnimManager& m_SkeletonAnimManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "graphics/ObjectManager.h"
|
||||
#include "graphics/ParticleManager.h"
|
||||
#include "graphics/SkeletonAnim.h"
|
||||
#include "graphics/SkeletonAnimManager.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "lib/rand.h"
|
||||
#include "ps/CLogger.h"
|
||||
@ -48,9 +49,6 @@ CObjectEntry::CObjectEntry(const std::shared_ptr<CObjectBase>& base, CSimulation
|
||||
|
||||
CObjectEntry::~CObjectEntry()
|
||||
{
|
||||
for (const std::pair<const CStr, CSkeletonAnim*>& anim : m_Animations)
|
||||
delete anim.second;
|
||||
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
@ -130,7 +128,7 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
||||
}
|
||||
|
||||
// delete old model, create new
|
||||
CModel* model = new CModel(objectManager.GetSkeletonAnimManager(), m_Simulation);
|
||||
CModel* model = new CModel(m_Simulation);
|
||||
delete m_Model;
|
||||
m_Model = model;
|
||||
model->SetMaterial(g_Renderer.GetSceneRenderer().GetMaterialManager().LoadMaterial(m_Base->m_Material));
|
||||
@ -169,7 +167,7 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
||||
|
||||
if (it->second.m_FileName.empty())
|
||||
continue;
|
||||
CSkeletonAnim* anim = model->BuildAnimation(
|
||||
std::unique_ptr<CSkeletonAnim> anim = objectManager.GetSkeletonAnimManager().BuildAnimation(
|
||||
it->second.m_FileName,
|
||||
name,
|
||||
it->second.m_ID,
|
||||
@ -179,13 +177,13 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
||||
it->second.m_ActionPos2,
|
||||
it->second.m_SoundPos);
|
||||
if (anim)
|
||||
m_Animations.insert(std::make_pair(name, anim));
|
||||
m_Animations.emplace(name, std::move(anim));
|
||||
}
|
||||
|
||||
// ensure there's always an idle animation
|
||||
if (m_Animations.find("idle") == m_Animations.end())
|
||||
{
|
||||
CSkeletonAnim* anim = new CSkeletonAnim();
|
||||
std::unique_ptr<CSkeletonAnim> anim = std::make_unique<CSkeletonAnim>();
|
||||
anim->m_Name = "idle";
|
||||
anim->m_ID = "";
|
||||
anim->m_AnimDef = NULL;
|
||||
@ -194,10 +192,10 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
||||
anim->m_ActionPos = 0.f;
|
||||
anim->m_ActionPos2 = 0.f;
|
||||
anim->m_SoundPos = 0.f;
|
||||
m_Animations.insert(std::make_pair("idle", anim));
|
||||
SkeletonAnimMap::const_iterator it = m_Animations.emplace("idle", std::move(anim));
|
||||
|
||||
// Ignore errors, since they're probably saying this is a non-animated model
|
||||
model->SetAnimation(anim);
|
||||
model->SetAnimation(it->second.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -302,7 +300,7 @@ std::vector<CSkeletonAnim*> CObjectEntry::GetAnimations(const CStr& animationNam
|
||||
for (SkeletonAnimMap::const_iterator it = lower; it != upper; ++it)
|
||||
{
|
||||
if (ID.empty() || it->second->m_ID == ID)
|
||||
anims.push_back(it->second);
|
||||
anims.push_back(it->second.get());
|
||||
}
|
||||
|
||||
if (anims.empty())
|
||||
@ -310,7 +308,7 @@ std::vector<CSkeletonAnim*> CObjectEntry::GetAnimations(const CStr& animationNam
|
||||
lower = m_Animations.lower_bound("idle");
|
||||
upper = m_Animations.upper_bound("idle");
|
||||
for (SkeletonAnimMap::const_iterator it = lower; it != upper; ++it)
|
||||
anims.push_back(it->second);
|
||||
anims.push_back(it->second.get());
|
||||
}
|
||||
|
||||
ENSURE(!anims.empty());
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -25,6 +25,7 @@ class CObjectManager;
|
||||
class CSimulation2;
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
@ -83,7 +84,7 @@ private:
|
||||
|
||||
CSimulation2& m_Simulation;
|
||||
|
||||
typedef std::multimap<CStr, CSkeletonAnim*> SkeletonAnimMap;
|
||||
using SkeletonAnimMap = std::multimap<CStr, std::unique_ptr<CSkeletonAnim>>;
|
||||
SkeletonAnimMap m_Animations;
|
||||
// TODO: something more memory-efficient than storing loads of similar strings for each unit?
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -25,8 +25,10 @@
|
||||
|
||||
#include "graphics/ColladaManager.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "graphics/SkeletonAnim.h"
|
||||
#include "graphics/SkeletonAnimDef.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/FileIo.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -79,3 +81,40 @@ CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname)
|
||||
// Add to map, NULL if failed to load - we won't try loading it again
|
||||
return m_Animations.insert_or_assign(name, std::move(def)).first->second.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* BuildAnimation: load raw animation frame animation from given file, and build a
|
||||
* animation specific to this model
|
||||
*/
|
||||
std::unique_ptr<CSkeletonAnim> CSkeletonAnimManager::BuildAnimation(const VfsPath& pathname, const CStr8& name, const CStr8& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos)
|
||||
{
|
||||
CSkeletonAnimDef* def = GetAnimation(pathname);
|
||||
if (!def)
|
||||
return nullptr;
|
||||
|
||||
std::unique_ptr<CSkeletonAnim> anim = std::make_unique<CSkeletonAnim>();
|
||||
anim->m_Name = name;
|
||||
anim->m_ID = ID;
|
||||
anim->m_Frequency = frequency;
|
||||
anim->m_AnimDef = def;
|
||||
anim->m_Speed = speed;
|
||||
|
||||
if (actionpos == -1.f)
|
||||
anim->m_ActionPos = -1.f;
|
||||
else
|
||||
anim->m_ActionPos = actionpos * anim->m_AnimDef->GetDuration();
|
||||
|
||||
if (actionpos2 == -1.f)
|
||||
anim->m_ActionPos2 = -1.f;
|
||||
else
|
||||
anim->m_ActionPos2 = actionpos2 * anim->m_AnimDef->GetDuration();
|
||||
|
||||
if (soundpos == -1.f)
|
||||
anim->m_SoundPos = -1.f;
|
||||
else
|
||||
anim->m_SoundPos = soundpos * anim->m_AnimDef->GetDuration();
|
||||
|
||||
anim->m_ObjectBounds.SetEmpty();
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -29,6 +29,8 @@
|
||||
|
||||
class CColladaManager;
|
||||
class CSkeletonAnimDef;
|
||||
class CSkeletonAnim;
|
||||
class CStr8;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CSkeletonAnimManager : owner class of all skeleton anims - manages creation,
|
||||
@ -45,6 +47,21 @@ public:
|
||||
// refer to valid animation file
|
||||
CSkeletonAnimDef* GetAnimation(const VfsPath& pathname);
|
||||
|
||||
/**
|
||||
* Load raw animation frame animation from given file, and build an
|
||||
* animation specific to this model.
|
||||
* @param pathname animation file to load
|
||||
* @param name animation name (e.g. "idle")
|
||||
* @param ID specific ID of the animation, to sync with props
|
||||
* @param frequency influences the random choices
|
||||
* @param speed animation speed as a factor of the default animation speed
|
||||
* @param actionpos offset of 'action' event, in range [0, 1]
|
||||
* @param actionpos2 offset of 'action2' event, in range [0, 1]
|
||||
* @param sound offset of 'sound' event, in range [0, 1]
|
||||
* @return new animation, or NULL on error
|
||||
*/
|
||||
std::unique_ptr<CSkeletonAnim> BuildAnimation(const VfsPath& pathname, const CStr8& name, const CStr8& ID, int frequency, float speed, float actionpos, float actionpos2, float soundpos);
|
||||
|
||||
private:
|
||||
// map of all known animations. Value is NULL if it failed to load.
|
||||
std::unordered_map<VfsPath, std::unique_ptr<CSkeletonAnimDef>> m_Animations;
|
||||
|
Loading…
Reference in New Issue
Block a user