1
0
forked from 0ad/0ad
0ad/source/graphics/ObjectManager.h
wraitii 76acc4e146 Implement quality levels for actors & corresponding setting.
An actor file, as referenced by the VisualActor, can now define
different actors for different "quality level" setting.
In this initial version, the quality is handled directly by the object
manager.

Actor format impact:
- '<qualitylevels>' may be used as the root node, containing actor nodes
as children.
  - such actor nodes can refer to a file, or to an inline actor, or
simply be inlined.
  - such actor nodes may have a 'quality' attribute, specifying the
maximum quality level of this actor. By default, 255 (the maximum) is
implied.
- The actor format remains valid, but 'groups', 'variants', 'material',
'castshadow' and 'float' can be given a [minquality, maxquality[ range
via XML attributes. Outside of this range, the XML node is ignored
(making it possible to define, in a single actor file, several quality
levels).

Quality is a 0-255 value, with:
- Range 0-99 intended for lower level-of-detail actors (billboards,
etc.)
- Range 100-200 the 'normal' range for models. 100 is "low", 150
"medium", and 200 "high".
- Range 201-255 used for higher quality actors that might be used for
e.g. cinematics.
The range is wide to make it easier to add intermediate levels in the
future and it seemed easier given that an integer value of some kind was
required anyways.

Engine impacts:
- A new CActorDef class is introduced, wrapping an art/actors XML file
and its different quality levels. ObjectBase remains the definition of a
given 'actor', now at a given quality level.
- CActorDef imposes a maximal # of quality level for a particular actor
definition (5 currently).
- CUnit is made to refer to an Actor Definition explicitly, not a
particular ObjectBase.
- As a minor optimisation, variation keys are calculated on
pointer-to-sets-of-selections, instead of raw sets-of-selections, as
this reduces copying.
- some refactoring, including better const-correctness and hotloading
support via std::shared_ptr.

Differential Revision: https://code.wildfiregames.com/D3787
This was SVN commit r25210.
2021-04-08 07:22:24 +00:00

119 lines
3.7 KiB
C++

/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_OBJECTMANAGER
#define INCLUDED_OBJECTMANAGER
#include "ps/CStr.h"
#include "lib/file/vfs/vfs_path.h"
#include <set>
#include <map>
#include <unordered_map>
#include <vector>
class CActorDef;
class CConfigDBHook;
class CMeshManager;
class CObjectBase;
class CObjectEntry;
class CSkeletonAnimManager;
class CSimulation2;
class CTerrain;
///////////////////////////////////////////////////////////////////////////////////////////
// CObjectManager: manager class for all possible actor types
class CObjectManager
{
NONCOPYABLE(CObjectManager);
public:
// Unique identifier of an actor variation
struct ObjectKey
{
ObjectKey(const CStr& identifier, const std::vector<u8>& var)
: ObjectBaseIdentifier(identifier), ActorVariation(var) {}
bool operator< (const CObjectManager::ObjectKey& a) const;
private:
CStr ObjectBaseIdentifier;
std::vector<u8> ActorVariation;
};
public:
// constructor, destructor
CObjectManager(CMeshManager& meshManager, CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation);
~CObjectManager();
// Provide access to the manager classes for meshes and animations - they're
// needed when objects are being created and so this seems like a convenient
// place to centralise access.
CMeshManager& GetMeshManager() const { return m_MeshManager; }
CSkeletonAnimManager& GetSkeletonAnimManager() const { return m_SkeletonAnimManager; }
void UnloadObjects();
CActorDef* FindActorDef(const CStrW& actorName);
/**
* Get the object entry for a given actor & the given selections list.
* @param selections - a possibly incomplete list of selections.
* @param seed - the randomness seed to use to complete the random selections.
*/
CObjectEntry* FindObjectVariation(const CActorDef* actor, const std::vector<std::set<CStr>>& selections, uint32_t seed);
/**
* @see FindObjectVariation.
* These take a complete selection. These are pointers to sets that are
* guaranteed to exist (pointers are used to avoid copying the sets).
*/
CObjectEntry* FindObjectVariation(const std::shared_ptr<CObjectBase>& base, const std::vector<const std::set<CStr>*>& completeSelections);
CObjectEntry* FindObjectVariation(const CStrW& objname, const std::vector<const std::set<CStr>*>& completeSelections);
/**
* Get the terrain object that actors managed by this manager should be linked
* with (primarily for the purpose of decals)
*/
CTerrain* GetTerrain();
/**
* Reload any scripts that were loaded from the given filename.
* (This is used to implement hotloading.)
*/
Status ReloadChangedFile(const VfsPath& path);
/**
* Reload actors that have a quality setting. Used when changing the actor quality.
*/
void ActorQualityChanged();
CMeshManager& m_MeshManager;
CSkeletonAnimManager& m_SkeletonAnimManager;
CSimulation2& m_Simulation;
u8 m_QualityLevel = 100;
std::unique_ptr<CConfigDBHook> m_QualityHook;
// TODO: define a hash and switch to unordered_map
std::map<ObjectKey, std::unique_ptr<CObjectEntry>> m_Objects;
std::unordered_map<CStrW, std::unique_ptr<CActorDef>> m_ActorDefs;
};
#endif