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"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
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)
|
||||
CModel::CModel(const CSimulation2& simulation, const CMaterial& material, const CModelDefPtr& modeldef)
|
||||
: m_Simulation{simulation}, m_Material{material}, m_pModelDef{modeldef}
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
const size_t numberOfBones = modeldef->GetNumBones();
|
||||
if (numberOfBones != 0)
|
||||
{
|
||||
size_t numBlends = modeldef->GetNumBlends();
|
||||
const size_t numberOfBlends = modeldef->GetNumBlends();
|
||||
|
||||
// allocate matrices for bone transformations
|
||||
// (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);
|
||||
for (size_t i = 0; i < numBones + 1 + numBlends; ++i)
|
||||
m_BoneMatrices = (CMatrix3D*)rtl_AllocateAligned(sizeof(CMatrix3D) * (numberOfBones + 1 + numberOfBlends), 16);
|
||||
for (size_t i = 0; i < numberOfBones + 1 + numberOfBlends; ++i)
|
||||
{
|
||||
m_BoneMatrices[i].SetIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -497,10 +468,8 @@ CModelAbstract* CModel::FindFirstAmmoProp()
|
||||
// Clone: return a clone of this model
|
||||
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->InitModel(m_pModelDef);
|
||||
clone->SetMaterial(m_Material);
|
||||
clone->SetAnimation(m_Anim);
|
||||
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)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* 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_IGNORE_LOS (1<<4)
|
||||
#define MODELFLAG_FLOATONWATER (1<<5)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CModel: basically, a mesh object - holds the texturing and skinning
|
||||
// information for a model in game
|
||||
|
||||
// Holds world information for a particular instance of a model in the game.
|
||||
class CModel : public CModelAbstract
|
||||
{
|
||||
NONCOPYABLE(CModel);
|
||||
@ -75,34 +74,27 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
// constructor
|
||||
CModel(CSimulation2& simulation);
|
||||
// destructor
|
||||
CModel(const CSimulation2& simulation, const CMaterial& material, const CModelDefPtr& modeldef);
|
||||
~CModel();
|
||||
|
||||
|
||||
/// Dynamic cast
|
||||
virtual CModel* ToCModel()
|
||||
{
|
||||
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
|
||||
void UpdateTo(float time);
|
||||
|
||||
// get the model's geometry data
|
||||
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
|
||||
void SetPlayerID(player_id_t id);
|
||||
// set the models mod color
|
||||
virtual void SetShadingColor(const CColor& color);
|
||||
// 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
|
||||
bool SetAnimation(CSkeletonAnim* anim, bool once = false);
|
||||
@ -118,6 +110,7 @@ public:
|
||||
void SetFlags(int flags) { m_Flags=flags; }
|
||||
// get object flags
|
||||
int GetFlags() const { return m_Flags; }
|
||||
|
||||
// add object flags, recursively through props
|
||||
void AddFlagsRec(int flags);
|
||||
// remove shadow casting and receiving, recursively through props
|
||||
@ -232,26 +225,23 @@ public:
|
||||
virtual void InvalidatePosition();
|
||||
|
||||
private:
|
||||
// delete anything allocated by the model
|
||||
void ReleaseData();
|
||||
|
||||
// Needed for terrain aligned props
|
||||
CSimulation2& m_Simulation;
|
||||
const CSimulation2& m_Simulation;
|
||||
|
||||
// object flags
|
||||
int m_Flags;
|
||||
int m_Flags{0};
|
||||
// model's material
|
||||
CMaterial m_Material;
|
||||
// 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
|
||||
// that can play on a model. Not always up-to-date - currently CalcBounds()
|
||||
// updates it when necessary.
|
||||
CBoundingBoxAligned m_ObjectBounds;
|
||||
// animation currently playing on this model, if any
|
||||
CSkeletonAnim* m_Anim;
|
||||
CSkeletonAnim* m_Anim = nullptr;
|
||||
// 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.
|
||||
@ -261,19 +251,19 @@ private:
|
||||
*
|
||||
* @see SPropPoint
|
||||
*/
|
||||
CMatrix3D* m_BoneMatrices;
|
||||
CMatrix3D* m_BoneMatrices{nullptr};
|
||||
// list of current props on model
|
||||
std::vector<Prop> m_Props;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
size_t m_AmmoLoadedProp;
|
||||
size_t m_AmmoLoadedProp{0};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // INCLUDED_MODEL
|
||||
|
@ -43,16 +43,12 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
CObjectEntry::CObjectEntry(const std::shared_ptr<CObjectBase>& base, CSimulation2& simulation) :
|
||||
m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), m_Model(NULL), m_Simulation(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_Simulation(simulation)
|
||||
{
|
||||
}
|
||||
|
||||
CObjectEntry::~CObjectEntry()
|
||||
{
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
CObjectEntry::~CObjectEntry() = default;
|
||||
|
||||
bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& completeSelections,
|
||||
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_Angle, variation.decal.m_OffsetX, variation.decal.m_OffsetZ,
|
||||
m_Base->m_Properties.m_FloatOnWater);
|
||||
m_Model = new CModelDecal(objectManager.GetTerrain(), decal);
|
||||
m_Model = std::make_unique<CModelDecal>(objectManager.GetTerrain(), decal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (variation.model.empty())
|
||||
{
|
||||
m_Model = new CModelDummy();
|
||||
m_Model = std::make_unique<CModelDummy>();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -134,12 +130,8 @@ bool CObjectEntry::BuildVariation(const std::vector<const std::set<CStr>*>& comp
|
||||
}
|
||||
|
||||
// delete old model, create new
|
||||
CModel* model = new CModel(m_Simulation);
|
||||
delete m_Model;
|
||||
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);
|
||||
CMaterial material = g_Renderer.GetSceneRenderer().GetMaterialManager().LoadMaterial(m_Base->m_Material);
|
||||
material.AddStaticUniform("objectColor", CVector4D(m_Color.r, m_Color.g, m_Color.b, m_Color.a));
|
||||
|
||||
if (m_Samplers.empty())
|
||||
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.
|
||||
// TODO: Should check which renderpath is selected and only preload the necessary textures.
|
||||
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())
|
||||
{
|
||||
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.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -18,29 +18,28 @@
|
||||
#ifndef INCLUDED_OBJECTENTRY
|
||||
#define INCLUDED_OBJECTENTRY
|
||||
|
||||
class CModelAbstract;
|
||||
class CSkeletonAnim;
|
||||
class CObjectBase;
|
||||
class CObjectManager;
|
||||
class CSimulation2;
|
||||
#include "graphics/Color.h"
|
||||
#include "graphics/ObjectBase.h"
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
#include "ps/CStr.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "graphics/Color.h"
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
#include "ps/CStr.h"
|
||||
|
||||
#include "graphics/ObjectBase.h"
|
||||
class CModelAbstract;
|
||||
class CSkeletonAnim;
|
||||
class CObjectBase;
|
||||
class CObjectManager;
|
||||
class CSimulation2;
|
||||
|
||||
class CObjectEntry
|
||||
{
|
||||
NONCOPYABLE(CObjectEntry);
|
||||
|
||||
public:
|
||||
CObjectEntry(const std::shared_ptr<CObjectBase>& base, CSimulation2& simulation);
|
||||
CObjectEntry(const std::shared_ptr<CObjectBase>& base, const CSimulation2& simulation);
|
||||
~CObjectEntry();
|
||||
|
||||
// Construct this actor, using the specified variation selections
|
||||
@ -78,16 +77,14 @@ public:
|
||||
std::vector<CSkeletonAnim*> GetAnimations(const CStr& animationName, const CStr& ID = "") const;
|
||||
|
||||
// corresponding model
|
||||
CModelAbstract* m_Model;
|
||||
std::unique_ptr<CModelAbstract> m_Model;
|
||||
|
||||
private:
|
||||
|
||||
CSimulation2& m_Simulation;
|
||||
const CSimulation2& m_Simulation;
|
||||
|
||||
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?
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif // INCLUDED_OBJECTENTRY
|
||||
|
Loading…
Reference in New Issue
Block a user