forked from 0ad/0ad
Refactors models and materials, part 1, reduces amount of mutable properties.
Comments By: phosit Differential Revision: https://code.wildfiregames.com/D5108 This was SVN commit r27841.
This commit is contained in:
parent
af13be489e
commit
b8cd3a0268
@ -37,62 +37,33 @@
|
|||||||
#include "simulation2/Simulation2.h"
|
#include "simulation2/Simulation2.h"
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
CModel::CModel(const CSimulation2& simulation, const CMaterial& material, const CModelDefPtr& modeldef)
|
||||||
// Constructor
|
: m_Simulation{simulation}, m_Material{material}, m_pModelDef{modeldef}
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
}
|
const size_t numberOfBones = modeldef->GetNumBones();
|
||||||
|
if (numberOfBones != 0)
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Destructor
|
|
||||||
CModel::~CModel()
|
|
||||||
{
|
|
||||||
ReleaseData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ReleaseData: delete anything allocated by the model
|
|
||||||
void CModel::ReleaseData()
|
|
||||||
{
|
|
||||||
rtl_FreeAligned(m_BoneMatrices);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_Props.size(); ++i)
|
|
||||||
delete m_Props[i].m_Model;
|
|
||||||
m_Props.clear();
|
|
||||||
|
|
||||||
m_pModelDef = CModelDefPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// InitModel: setup model from given geometry
|
|
||||||
bool CModel::InitModel(const CModelDefPtr& modeldef)
|
|
||||||
{
|
|
||||||
// clean up any existing data first
|
|
||||||
ReleaseData();
|
|
||||||
|
|
||||||
m_pModelDef = modeldef;
|
|
||||||
|
|
||||||
size_t numBones = modeldef->GetNumBones();
|
|
||||||
if (numBones != 0)
|
|
||||||
{
|
{
|
||||||
size_t numBlends = modeldef->GetNumBlends();
|
const size_t numberOfBlends = modeldef->GetNumBlends();
|
||||||
|
|
||||||
// allocate matrices for bone transformations
|
// allocate matrices for bone transformations
|
||||||
// (one extra matrix is used for the special case of bind-shape relative weighting)
|
// (one extra matrix is used for the special case of bind-shape relative weighting)
|
||||||
m_BoneMatrices = (CMatrix3D*)rtl_AllocateAligned(sizeof(CMatrix3D) * (numBones + 1 + numBlends), 16);
|
m_BoneMatrices = (CMatrix3D*)rtl_AllocateAligned(sizeof(CMatrix3D) * (numberOfBones + 1 + numberOfBlends), 16);
|
||||||
for (size_t i = 0; i < numBones + 1 + numBlends; ++i)
|
for (size_t i = 0; i < numberOfBones + 1 + numberOfBlends; ++i)
|
||||||
{
|
{
|
||||||
m_BoneMatrices[i].SetIdentity();
|
m_BoneMatrices[i].SetIdentity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PositionValid = true;
|
m_PositionValid = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CModel::~CModel()
|
||||||
|
{
|
||||||
|
rtl_FreeAligned(m_BoneMatrices);
|
||||||
|
|
||||||
|
for (Prop& prop : m_Props)
|
||||||
|
delete prop.m_Model;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// CalcBound: calculate the world space bounds of this model
|
// CalcBound: calculate the world space bounds of this model
|
||||||
@ -497,10 +468,8 @@ CModelAbstract* CModel::FindFirstAmmoProp()
|
|||||||
// Clone: return a clone of this model
|
// Clone: return a clone of this model
|
||||||
CModelAbstract* CModel::Clone() const
|
CModelAbstract* CModel::Clone() const
|
||||||
{
|
{
|
||||||
CModel* clone = new CModel(m_Simulation);
|
CModel* clone = new CModel(m_Simulation, m_Material, m_pModelDef);
|
||||||
clone->m_ObjectBounds = m_ObjectBounds;
|
clone->m_ObjectBounds = m_ObjectBounds;
|
||||||
clone->InitModel(m_pModelDef);
|
|
||||||
clone->SetMaterial(m_Material);
|
|
||||||
clone->SetAnimation(m_Anim);
|
clone->SetAnimation(m_Anim);
|
||||||
clone->SetFlags(m_Flags);
|
clone->SetFlags(m_Flags);
|
||||||
|
|
||||||
@ -555,11 +524,6 @@ void CModel::RemoveShadowsRec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel::SetMaterial(const CMaterial &material)
|
|
||||||
{
|
|
||||||
m_Material = material;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModel::SetPlayerID(player_id_t id)
|
void CModel::SetPlayerID(player_id_t id)
|
||||||
{
|
{
|
||||||
CModelAbstract::SetPlayerID(id);
|
CModelAbstract::SetPlayerID(id);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2022 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -40,9 +40,8 @@ class CSimulation2;
|
|||||||
#define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3)
|
#define MODELFLAG_SILHOUETTE_OCCLUDER (1<<3)
|
||||||
#define MODELFLAG_IGNORE_LOS (1<<4)
|
#define MODELFLAG_IGNORE_LOS (1<<4)
|
||||||
#define MODELFLAG_FLOATONWATER (1<<5)
|
#define MODELFLAG_FLOATONWATER (1<<5)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CModel: basically, a mesh object - holds the texturing and skinning
|
// Holds world information for a particular instance of a model in the game.
|
||||||
// information for a model in game
|
|
||||||
class CModel : public CModelAbstract
|
class CModel : public CModelAbstract
|
||||||
{
|
{
|
||||||
NONCOPYABLE(CModel);
|
NONCOPYABLE(CModel);
|
||||||
@ -75,34 +74,27 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
CModel(const CSimulation2& simulation, const CMaterial& material, const CModelDefPtr& modeldef);
|
||||||
CModel(CSimulation2& simulation);
|
|
||||||
// destructor
|
|
||||||
~CModel();
|
~CModel();
|
||||||
|
|
||||||
|
|
||||||
/// Dynamic cast
|
/// Dynamic cast
|
||||||
virtual CModel* ToCModel()
|
virtual CModel* ToCModel()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup model from given geometry
|
|
||||||
bool InitModel(const CModelDefPtr& modeldef);
|
|
||||||
// update this model's state; 'time' is the absolute time since the start of the animation, in MS
|
// update this model's state; 'time' is the absolute time since the start of the animation, in MS
|
||||||
void UpdateTo(float time);
|
void UpdateTo(float time);
|
||||||
|
|
||||||
// get the model's geometry data
|
// get the model's geometry data
|
||||||
const CModelDefPtr& GetModelDef() { return m_pModelDef; }
|
const CModelDefPtr& GetModelDef() { return m_pModelDef; }
|
||||||
|
|
||||||
// set the model's material
|
|
||||||
void SetMaterial(const CMaterial &material);
|
|
||||||
// set the model's player ID, recursively through props
|
// set the model's player ID, recursively through props
|
||||||
void SetPlayerID(player_id_t id);
|
void SetPlayerID(player_id_t id);
|
||||||
// set the models mod color
|
// set the models mod color
|
||||||
virtual void SetShadingColor(const CColor& color);
|
virtual void SetShadingColor(const CColor& color);
|
||||||
// get the model's material
|
// get the model's material
|
||||||
CMaterial& GetMaterial() { return m_Material; }
|
const CMaterial& GetMaterial() { return m_Material; }
|
||||||
|
|
||||||
// set the given animation as the current animation on this model
|
// set the given animation as the current animation on this model
|
||||||
bool SetAnimation(CSkeletonAnim* anim, bool once = false);
|
bool SetAnimation(CSkeletonAnim* anim, bool once = false);
|
||||||
@ -118,6 +110,7 @@ public:
|
|||||||
void SetFlags(int flags) { m_Flags=flags; }
|
void SetFlags(int flags) { m_Flags=flags; }
|
||||||
// get object flags
|
// get object flags
|
||||||
int GetFlags() const { return m_Flags; }
|
int GetFlags() const { return m_Flags; }
|
||||||
|
|
||||||
// add object flags, recursively through props
|
// add object flags, recursively through props
|
||||||
void AddFlagsRec(int flags);
|
void AddFlagsRec(int flags);
|
||||||
// remove shadow casting and receiving, recursively through props
|
// remove shadow casting and receiving, recursively through props
|
||||||
@ -232,26 +225,23 @@ public:
|
|||||||
virtual void InvalidatePosition();
|
virtual void InvalidatePosition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// delete anything allocated by the model
|
|
||||||
void ReleaseData();
|
|
||||||
|
|
||||||
// Needed for terrain aligned props
|
// Needed for terrain aligned props
|
||||||
CSimulation2& m_Simulation;
|
const CSimulation2& m_Simulation;
|
||||||
|
|
||||||
// object flags
|
// object flags
|
||||||
int m_Flags;
|
int m_Flags{0};
|
||||||
// model's material
|
// model's material
|
||||||
CMaterial m_Material;
|
CMaterial m_Material;
|
||||||
// pointer to the model's raw 3d data
|
// pointer to the model's raw 3d data
|
||||||
CModelDefPtr m_pModelDef;
|
const CModelDefPtr m_pModelDef;
|
||||||
// object space bounds of model - accounts for bounds of all possible animations
|
// object space bounds of model - accounts for bounds of all possible animations
|
||||||
// that can play on a model. Not always up-to-date - currently CalcBounds()
|
// that can play on a model. Not always up-to-date - currently CalcBounds()
|
||||||
// updates it when necessary.
|
// updates it when necessary.
|
||||||
CBoundingBoxAligned m_ObjectBounds;
|
CBoundingBoxAligned m_ObjectBounds;
|
||||||
// animation currently playing on this model, if any
|
// animation currently playing on this model, if any
|
||||||
CSkeletonAnim* m_Anim;
|
CSkeletonAnim* m_Anim = nullptr;
|
||||||
// time (in MS) into the current animation
|
// time (in MS) into the current animation
|
||||||
float m_AnimTime;
|
float m_AnimTime{0.0f};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current state of all bones on this model; null if associated modeldef isn't skeletal.
|
* Current state of all bones on this model; null if associated modeldef isn't skeletal.
|
||||||
@ -261,19 +251,19 @@ private:
|
|||||||
*
|
*
|
||||||
* @see SPropPoint
|
* @see SPropPoint
|
||||||
*/
|
*/
|
||||||
CMatrix3D* m_BoneMatrices;
|
CMatrix3D* m_BoneMatrices{nullptr};
|
||||||
// list of current props on model
|
// list of current props on model
|
||||||
std::vector<Prop> m_Props;
|
std::vector<Prop> m_Props;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The prop point to which the ammo prop is attached, or NULL if none
|
* The prop point to which the ammo prop is attached, or NULL if none
|
||||||
*/
|
*/
|
||||||
const SPropPoint* m_AmmoPropPoint;
|
const SPropPoint* m_AmmoPropPoint{nullptr};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop
|
* If m_AmmoPropPoint is not NULL, then the index in m_Props of the ammo prop
|
||||||
*/
|
*/
|
||||||
size_t m_AmmoLoadedProp;
|
size_t m_AmmoLoadedProp{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // INCLUDED_MODEL
|
||||||
|
@ -43,16 +43,12 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
CObjectEntry::CObjectEntry(const std::shared_ptr<CObjectBase>& base, CSimulation2& simulation) :
|
CObjectEntry::CObjectEntry(const std::shared_ptr<CObjectBase>& base, const CSimulation2& simulation) :
|
||||||
m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), m_Model(NULL), m_Simulation(simulation)
|
m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), m_Simulation(simulation)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CObjectEntry::~CObjectEntry()
|
CObjectEntry::~CObjectEntry() = default;
|
||||||
{
|
|
||||||
delete m_Model;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& completeSelections,
|
bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& completeSelections,
|
||||||
const std::vector<u8>& variationKey,
|
const std::vector<u8>& variationKey,
|
||||||
@ -101,20 +97,20 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
|||||||
variation.decal.m_SizeX, variation.decal.m_SizeZ,
|
variation.decal.m_SizeX, variation.decal.m_SizeZ,
|
||||||
variation.decal.m_Angle, variation.decal.m_OffsetX, variation.decal.m_OffsetZ,
|
variation.decal.m_Angle, variation.decal.m_OffsetX, variation.decal.m_OffsetZ,
|
||||||
m_Base->m_Properties.m_FloatOnWater);
|
m_Base->m_Properties.m_FloatOnWater);
|
||||||
m_Model = new CModelDecal(objectManager.GetTerrain(), decal);
|
m_Model = std::make_unique<CModelDecal>(objectManager.GetTerrain(), decal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!variation.particles.empty())
|
if (!variation.particles.empty())
|
||||||
{
|
{
|
||||||
m_Model = new CModelParticleEmitter(g_Renderer.GetSceneRenderer().GetParticleManager().LoadEmitterType(variation.particles));
|
m_Model = std::make_unique<CModelParticleEmitter>(g_Renderer.GetSceneRenderer().GetParticleManager().LoadEmitterType(variation.particles));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variation.model.empty())
|
if (variation.model.empty())
|
||||||
{
|
{
|
||||||
m_Model = new CModelDummy();
|
m_Model = std::make_unique<CModelDummy>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,12 +130,8 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete old model, create new
|
// delete old model, create new
|
||||||
CModel* model = new CModel(m_Simulation);
|
CMaterial material = g_Renderer.GetSceneRenderer().GetMaterialManager().LoadMaterial(m_Base->m_Material);
|
||||||
delete m_Model;
|
material.AddStaticUniform("objectColor", CVector4D(m_Color.r, m_Color.g, m_Color.b, m_Color.a));
|
||||||
m_Model = model;
|
|
||||||
model->SetMaterial(g_Renderer.GetSceneRenderer().GetMaterialManager().LoadMaterial(m_Base->m_Material));
|
|
||||||
model->GetMaterial().AddStaticUniform("objectColor", CVector4D(m_Color.r, m_Color.g, m_Color.b, m_Color.a));
|
|
||||||
model->InitModel(modeldef);
|
|
||||||
|
|
||||||
if (m_Samplers.empty())
|
if (m_Samplers.empty())
|
||||||
LOGERROR("Actor '%s' has no textures.", m_Base->GetIdentifier());
|
LOGERROR("Actor '%s' has no textures.", m_Base->GetIdentifier());
|
||||||
@ -153,9 +145,13 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
|||||||
// All textures are prefetched even in the fixed pipeline, including the normal maps etc.
|
// All textures are prefetched even in the fixed pipeline, including the normal maps etc.
|
||||||
// TODO: Should check which renderpath is selected and only preload the necessary textures.
|
// TODO: Should check which renderpath is selected and only preload the necessary textures.
|
||||||
texture->Prefetch();
|
texture->Prefetch();
|
||||||
model->GetMaterial().AddSampler(CMaterial::TextureSampler(samp.m_SamplerName, texture));
|
material.AddSampler(CMaterial::TextureSampler(samp.m_SamplerName, texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CModel> newModel = std::make_unique<CModel>(m_Simulation, material, modeldef);
|
||||||
|
CModel* model = newModel.get();
|
||||||
|
m_Model = std::move(newModel);
|
||||||
|
|
||||||
for (const CStrIntern& requSampName : model->GetMaterial().GetRequiredSampler())
|
for (const CStrIntern& requSampName : model->GetMaterial().GetRequiredSampler())
|
||||||
{
|
{
|
||||||
if (std::find_if(m_Samplers.begin(), m_Samplers.end(),
|
if (std::find_if(m_Samplers.begin(), m_Samplers.end(),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2022 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -18,29 +18,28 @@
|
|||||||
#ifndef INCLUDED_OBJECTENTRY
|
#ifndef INCLUDED_OBJECTENTRY
|
||||||
#define INCLUDED_OBJECTENTRY
|
#define INCLUDED_OBJECTENTRY
|
||||||
|
|
||||||
class CModelAbstract;
|
#include "graphics/Color.h"
|
||||||
class CSkeletonAnim;
|
#include "graphics/ObjectBase.h"
|
||||||
class CObjectBase;
|
#include "lib/file/vfs/vfs_path.h"
|
||||||
class CObjectManager;
|
#include "ps/CStr.h"
|
||||||
class CSimulation2;
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "graphics/Color.h"
|
class CModelAbstract;
|
||||||
#include "lib/file/vfs/vfs_path.h"
|
class CSkeletonAnim;
|
||||||
#include "ps/CStr.h"
|
class CObjectBase;
|
||||||
|
class CObjectManager;
|
||||||
#include "graphics/ObjectBase.h"
|
class CSimulation2;
|
||||||
|
|
||||||
class CObjectEntry
|
class CObjectEntry
|
||||||
{
|
{
|
||||||
NONCOPYABLE(CObjectEntry);
|
NONCOPYABLE(CObjectEntry);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CObjectEntry(const std::shared_ptr<CObjectBase>& base, CSimulation2& simulation);
|
CObjectEntry(const std::shared_ptr<CObjectBase>& base, const CSimulation2& simulation);
|
||||||
~CObjectEntry();
|
~CObjectEntry();
|
||||||
|
|
||||||
// Construct this actor, using the specified variation selections
|
// Construct this actor, using the specified variation selections
|
||||||
@ -78,16 +77,14 @@ public:
|
|||||||
std::vector<CSkeletonAnim*> GetAnimations(const CStr& animationName, const CStr& ID = "") const;
|
std::vector<CSkeletonAnim*> GetAnimations(const CStr& animationName, const CStr& ID = "") const;
|
||||||
|
|
||||||
// corresponding model
|
// corresponding model
|
||||||
CModelAbstract* m_Model;
|
std::unique_ptr<CModelAbstract> m_Model;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const CSimulation2& m_Simulation;
|
||||||
CSimulation2& m_Simulation;
|
|
||||||
|
|
||||||
using SkeletonAnimMap = std::multimap<CStr, std::unique_ptr<CSkeletonAnim>>;
|
using SkeletonAnimMap = std::multimap<CStr, std::unique_ptr<CSkeletonAnim>>;
|
||||||
SkeletonAnimMap m_Animations;
|
SkeletonAnimMap m_Animations;
|
||||||
// TODO: something more memory-efficient than storing loads of similar strings for each unit?
|
// TODO: something more memory-efficient than storing loads of similar strings for each unit?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // INCLUDED_OBJECTENTRY
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user