Removes unused forward declarations of class and struct.
[0ad.git] / source / graphics / ObjectBase.h
blobfecda0cfd09f94ff61b4ea38a27efe1c8798917e
1 /* Copyright (C) 2021 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_OBJECTBASE
19 #define INCLUDED_OBJECTBASE
21 #include "lib/file/vfs/vfs_path.h"
22 #include "ps/CStr.h"
23 #include "ps/CStrIntern.h"
25 class CActorDef;
26 class CObjectEntry;
27 class CObjectManager;
28 class CXeromyces;
29 class XMBElement;
31 #include <boost/random/mersenne_twister.hpp>
32 #include <map>
33 #include <memory>
34 #include <set>
35 #include <unordered_set>
36 #include <vector>
38 /**
39 * Maintains the tree of possible objects from a specific actor definition at a given quality level.
40 * An Object Base is made of:
41 * - a material
42 * - a few properties (float on water / casts shadow / ...)
43 * - a number of variant groups.
44 * Any actual object in game will pick a variant from each group (see ObjectEntry).
46 class CObjectBase
48 friend CActorDef;
50 // See CopyWithQuality() below.
51 NONCOPYABLE(CObjectBase);
52 public:
53 struct Anim
55 // constructor
56 Anim() : m_Frequency(0), m_Speed(1.f), m_ActionPos(-1.f), m_ActionPos2(-1.f), m_SoundPos(-1.f) {}
57 // name of the animation - "Idle", "Run", etc
58 CStr m_AnimName;
59 // ID of the animation: if not empty, something specific to sync with props.
60 CStr m_ID = "";
61 int m_Frequency;
62 // filename of the animation - manidle.psa, manrun.psa, etc
63 VfsPath m_FileName;
64 // animation speed, as specified in XML actor file
65 float m_Speed;
66 // fraction [0.0, 1.0] of the way through the animation that the interesting bit(s)
67 // happens, or -1.0 if unspecified
68 float m_ActionPos;
69 float m_ActionPos2;
70 float m_SoundPos;
73 struct Prop
75 // constructor
76 Prop() : m_minHeight(0.f), m_maxHeight(0.f), m_selectable(true) {}
77 // name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc ..
78 CStr m_PropPointName;
79 // name of the model file - art/actors/props/sword.xml or whatever
80 CStrW m_ModelName;
81 // allow the prop to ajust the height from minHeight to maxHeight relative to the main model
82 float m_minHeight;
83 float m_maxHeight;
84 bool m_selectable;
87 struct Samp
89 // identifier name of sampler in GLSL shaders
90 CStrIntern m_SamplerName;
91 // path to load from
92 VfsPath m_SamplerFile;
95 struct Decal
97 Decal() : m_SizeX(0.f), m_SizeZ(0.f), m_Angle(0.f), m_OffsetX(0.f), m_OffsetZ(0.f) {}
99 float m_SizeX;
100 float m_SizeZ;
101 float m_Angle;
102 float m_OffsetX;
103 float m_OffsetZ;
106 struct Variant
108 Variant() : m_Frequency(0) {}
110 CStr m_VariantName; // lowercase name
111 int m_Frequency;
112 VfsPath m_ModelFilename;
113 Decal m_Decal;
114 VfsPath m_Particles;
115 CStr m_Color;
117 std::vector<Anim> m_Anims;
118 std::vector<Prop> m_Props;
119 std::vector<Samp> m_Samplers;
122 struct Variation
124 VfsPath model;
125 Decal decal;
126 VfsPath particles;
127 CStr color;
128 std::multimap<CStr, Prop> props;
129 std::multimap<CStr, Anim> anims;
130 std::multimap<CStr, Samp> samplers;
133 CObjectBase(CObjectManager& objectManager, CActorDef& actorDef, u8 QualityLevel);
135 // Returns a set of selection such that, added to initialSelections, CalculateVariationKey can proceed.
136 std::set<CStr> CalculateRandomRemainingSelections(uint32_t seed, const std::vector<std::set<CStr>>& initialSelections) const;
138 // Get the variation key (indices of chosen variants from each group)
139 // based on the selection strings.
140 // Should not have to make a random choice: the selections should be complete.
141 std::vector<u8> CalculateVariationKey(const std::vector<const std::set<CStr>*>& selections) const;
143 // Get the final actor data, combining all selected variants
144 const Variation BuildVariation(const std::vector<u8>& variationKey) const;
146 // Get a list of variant groups for this object, plus for all possible
147 // props. Duplicated groups are removed, if several props share the same
148 // variant names.
149 std::vector<std::vector<CStr> > GetVariantGroups() const;
151 // Return a string identifying this actor uniquely (includes quality level information);
152 const CStr& GetIdentifier() const;
155 * Returns whether this object (including any possible props)
156 * uses the given file. (This is used for hotloading.)
158 bool UsesFile(const VfsPath& pathname) const;
161 struct {
162 // cast shadows from this object
163 bool m_CastShadows;
164 // float on top of water
165 bool m_FloatOnWater;
166 } m_Properties;
168 // the material file
169 VfsPath m_Material;
171 // Quality level - part of the data resource path.
172 u8 m_QualityLevel;
174 private:
175 // Private interface for CActorDef/ObjectEntry
178 * Acts as an explicit copy constructor, for a new quality level.
179 * Note that this does not reload the actor, so this setting will only change props.
181 std::unique_ptr<CObjectBase> CopyWithQuality(u8 newQualityLevel) const;
183 // A low-quality RNG like rand48 causes visible non-random patterns (particularly
184 // in large grids of the same actor with consecutive seeds, e.g. forests),
185 // so use a better one that appears to avoid those patterns
186 using rng_t = boost::mt19937;
187 std::set<CStr> CalculateRandomRemainingSelections(rng_t& rng, const std::vector<std::set<CStr>>& initialSelections) const;
190 * Get all quality levels at which this object changes (includes props).
191 * Intended to be called by CActorFef.
192 * @param splits - a sorted vector of unique quality splits.
194 void GetQualitySplits(std::vector<u8>& splits) const;
196 [[nodiscard]] bool Load(const CXeromyces& XeroFile, const XMBElement& base);
197 [[nodiscard]] bool LoadVariant(const CXeromyces& XeroFile, const XMBElement& variant, Variant& currentVariant);
199 private:
200 // Backref to the owning actor.
201 CActorDef& m_ActorDef;
203 // Used to identify this actor uniquely in the ObjectManager (and for debug).
204 CStr m_Identifier;
206 std::vector< std::vector<Variant> > m_VariantGroups;
207 CObjectManager& m_ObjectManager;
211 * Represents an actor file. Actors can contain various quality levels.
212 * An ActorDef maintains a CObjectBase for each specified quality level, and provides access to it.
214 class CActorDef
216 // Friend these three so they can use GetBase.
217 friend class CObjectManager;
218 friend class CObjectBase;
219 friend class CObjectEntry;
221 NONCOPYABLE(CActorDef);
222 public:
224 CActorDef(CObjectManager& objectManager);
226 std::vector<u8> QualityLevels() const;
228 VfsPath GetPathname() const { return m_Pathname; }
231 * Return a list of selections specifying a particular variant in all groups, based on the seed.
233 std::set<CStr> PickSelectionsAtRandom(uint32_t seed) const;
235 // Interface accessible from CObjectManager / CObjectBase
236 protected:
238 * Return the Object base matching the given quality level.
240 const std::shared_ptr<CObjectBase>& GetBase(u8 QualityLevel) const;
243 * Initialise this object by loading from the given file.
244 * Returns false on error.
246 bool Load(const VfsPath& pathname);
249 * Initialise this object with a default placeholder actor,
250 * pretending to be the actor at pathname.
252 void LoadErrorPlaceholder(const VfsPath& pathname);
255 * Returns whether this actor (including any possible props)
256 * uses the given file. (This is used for hotloading.)
258 bool UsesFile(const VfsPath& pathname) const;
260 // filename that this was loaded from
261 VfsPath m_Pathname;
263 private:
264 CObjectManager& m_ObjectManager;
266 // std::shared_ptr to avoid issues during hotloading.
267 std::vector<std::shared_ptr<CObjectBase>> m_ObjectBases;
269 std::unordered_set<VfsPath> m_UsedFiles;
272 #endif