Pyrogenesis  trunk
ObjectBase.h
Go to the documentation of this file.
1 /* Copyright (C) 2021 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 
18 #ifndef INCLUDED_OBJECTBASE
19 #define INCLUDED_OBJECTBASE
20 
21 #include "lib/file/vfs/vfs_path.h"
22 #include "ps/CStr.h"
23 #include "ps/CStrIntern.h"
24 
25 class CActorDef;
26 class CObjectEntry;
27 class CObjectManager;
28 class CXeromyces;
29 class XMBElement;
30 
31 #include <boost/random/mersenne_twister.hpp>
32 #include <map>
33 #include <memory>
34 #include <set>
35 #include <unordered_set>
36 #include <vector>
37 
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).
45  */
47 {
48  friend CActorDef;
49 
50  // See CopyWithQuality() below.
52 public:
53  struct Anim
54  {
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 = "";
62  // filename of the animation - manidle.psa, manrun.psa, etc
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;
71  };
72 
73  struct Prop
74  {
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 ..
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;
85  };
86 
87  struct Samp
88  {
89  // identifier name of sampler in GLSL shaders
91  // path to load from
93  };
94 
95  struct Decal
96  {
97  Decal() : m_SizeX(0.f), m_SizeZ(0.f), m_Angle(0.f), m_OffsetX(0.f), m_OffsetZ(0.f) {}
98 
99  float m_SizeX;
100  float m_SizeZ;
101  float m_Angle;
102  float m_OffsetX;
103  float m_OffsetZ;
104  };
105 
106  struct Variant
107  {
109 
110  CStr m_VariantName; // lowercase name
115  CStr m_Color;
116 
117  std::vector<Anim> m_Anims;
118  std::vector<Prop> m_Props;
119  std::vector<Samp> m_Samplers;
120  };
121 
122  struct Variation
123  {
127  CStr color;
128  std::multimap<CStr, Prop> props;
129  std::multimap<CStr, Anim> anims;
130  std::multimap<CStr, Samp> samplers;
131  };
132 
133  CObjectBase(CObjectManager& objectManager, CActorDef& actorDef, u8 QualityLevel);
134 
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;
137 
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;
142 
143  // Get the final actor data, combining all selected variants
144  const Variation BuildVariation(const std::vector<u8>& variationKey) const;
145 
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;
150 
151  // Return a string identifying this actor uniquely (includes quality level information);
152  const CStr& GetIdentifier() const;
153 
154  /**
155  * Returns whether this object (including any possible props)
156  * uses the given file. (This is used for hotloading.)
157  */
158  bool UsesFile(const VfsPath& pathname) const;
159 
160 
161  struct {
162  // cast shadows from this object
164  // float on top of water
166  } m_Properties;
167 
168  // the material file
170 
171  // Quality level - part of the data resource path.
173 
174 private:
175  // Private interface for CActorDef/ObjectEntry
176 
177  /**
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.
180  */
181  std::unique_ptr<CObjectBase> CopyWithQuality(u8 newQualityLevel) const;
182 
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;
188 
189  /**
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.
193  */
194  void GetQualitySplits(std::vector<u8>& splits) const;
195 
196  [[nodiscard]] bool Load(const CXeromyces& XeroFile, const XMBElement& base);
197  [[nodiscard]] bool LoadVariant(const CXeromyces& XeroFile, const XMBElement& variant, Variant& currentVariant);
198 
199 private:
200  // Backref to the owning actor.
202 
203  // Used to identify this actor uniquely in the ObjectManager (and for debug).
205 
206  std::vector< std::vector<Variant> > m_VariantGroups;
208 };
209 
210 /**
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.
213  */
215 {
216  // Friend these three so they can use GetBase.
217  friend class CObjectManager;
218  friend class CObjectBase;
219  friend class CObjectEntry;
220 
222 public:
223 
224  CActorDef(CObjectManager& objectManager);
225 
226  std::vector<u8> QualityLevels() const;
227 
228  VfsPath GetPathname() const { return m_Pathname; }
229 
230  /**
231  * Return a list of selections specifying a particular variant in all groups, based on the seed.
232  */
233  std::set<CStr> PickSelectionsAtRandom(uint32_t seed) const;
234 
235 // Interface accessible from CObjectManager / CObjectBase
236 protected:
237  /**
238  * Return the Object base matching the given quality level.
239  */
240  const std::shared_ptr<CObjectBase>& GetBase(u8 QualityLevel) const;
241 
242  /**
243  * Initialise this object by loading from the given file.
244  * Returns false on error.
245  */
246  bool Load(const VfsPath& pathname);
247 
248  /**
249  * Initialise this object with a default placeholder actor,
250  * pretending to be the actor at pathname.
251  */
252  void LoadErrorPlaceholder(const VfsPath& pathname);
253 
254  /**
255  * Returns whether this actor (including any possible props)
256  * uses the given file. (This is used for hotloading.)
257  */
258  bool UsesFile(const VfsPath& pathname) const;
259 
260  // filename that this was loaded from
262 
263 private:
265 
266  // std::shared_ptr to avoid issues during hotloading.
267  std::vector<std::shared_ptr<CObjectBase>> m_ObjectBases;
268 
269  std::unordered_set<VfsPath> m_UsedFiles;
270 };
271 
272 #endif
bool m_selectable
Definition: ObjectBase.h:84
CStrW m_ModelName
Definition: ObjectBase.h:80
std::vector< u8 > CalculateVariationKey(const std::vector< const std::set< CStr > *> &selections) const
Definition: ObjectBase.cpp:348
float m_SoundPos
Definition: ObjectBase.h:70
void GetQualitySplits(std::vector< u8 > &splits) const
Get all quality levels at which this object changes (includes props).
Definition: ObjectBase.cpp:725
CActorDef & m_ActorDef
Definition: ObjectBase.h:201
std::vector< std::shared_ptr< CObjectBase > > m_ObjectBases
Definition: ObjectBase.h:267
VfsPath m_ModelFilename
Definition: ObjectBase.h:112
VfsPath m_Material
Definition: ObjectBase.h:169
CStr m_AnimName
Definition: ObjectBase.h:58
CObjectManager & m_ObjectManager
Definition: ObjectBase.h:264
float m_Angle
Definition: ObjectBase.h:101
float m_maxHeight
Definition: ObjectBase.h:83
NONCOPYABLE(CObjectBase)
Definition: ObjectManager.h:41
Decal decal
Definition: ObjectBase.h:125
Decal()
Definition: ObjectBase.h:97
float m_Speed
Definition: ObjectBase.h:65
Definition: XMBData.h:135
std::vector< Prop > m_Props
Definition: ObjectBase.h:118
Represents an actor file.
Definition: ObjectBase.h:214
Definition: ObjectBase.h:95
float m_SizeX
Definition: ObjectBase.h:99
bool Load(const CXeromyces &XeroFile, const XMBElement &base)
Definition: ObjectBase.cpp:80
CStr m_VariantName
Definition: ObjectBase.h:110
VfsPath m_FileName
Definition: ObjectBase.h:63
std::set< CStr > CalculateRandomRemainingSelections(uint32_t seed, const std::vector< std::set< CStr >> &initialSelections) const
Definition: ObjectBase.cpp:510
std::vector< std::vector< CStr > > GetVariantGroups() const
Definition: ObjectBase.cpp:660
uint8_t u8
Definition: types.h:37
VfsPath particles
Definition: ObjectBase.h:126
CStr color
Definition: ObjectBase.h:127
CStrIntern m_SamplerName
Definition: ObjectBase.h:90
VfsPath m_Particles
Definition: ObjectBase.h:114
std::vector< std::vector< Variant > > m_VariantGroups
Definition: ObjectBase.h:206
Variant()
Definition: ObjectBase.h:108
Definition: ObjectBase.h:87
const Variation BuildVariation(const std::vector< u8 > &variationKey) const
Definition: ObjectBase.cpp:436
CStr m_ID
Definition: ObjectBase.h:60
Interned 8-bit strings.
Definition: CStrIntern.h:37
std::multimap< CStr, Samp > samplers
Definition: ObjectBase.h:130
Definition: path.h:79
VfsPath m_Pathname
Definition: ObjectBase.h:261
std::vector< Anim > m_Anims
Definition: ObjectBase.h:117
boost::mt19937 rng_t
Definition: ObjectBase.h:186
float m_ActionPos2
Definition: ObjectBase.h:69
std::vector< Samp > m_Samplers
Definition: ObjectBase.h:119
struct CObjectBase::@7 m_Properties
CStr m_Identifier
Definition: ObjectBase.h:204
std::multimap< CStr, Prop > props
Definition: ObjectBase.h:128
u8 m_QualityLevel
Definition: ObjectBase.h:172
Anim()
Definition: ObjectBase.h:56
CObjectManager & m_ObjectManager
Definition: ObjectBase.h:207
Prop()
Definition: ObjectBase.h:76
float m_OffsetX
Definition: ObjectBase.h:102
CObjectBase(CObjectManager &objectManager, CActorDef &actorDef, u8 QualityLevel)
Definition: ObjectBase.cpp:59
VfsPath GetPathname() const
Definition: ObjectBase.h:228
Definition: ObjectBase.h:73
friend CActorDef
Definition: ObjectBase.h:48
CStr m_PropPointName
Definition: ObjectBase.h:78
int m_Frequency
Definition: ObjectBase.h:61
CStr m_Color
Definition: ObjectBase.h:115
Definition: Xeromyces.h:40
std::unique_ptr< CObjectBase > CopyWithQuality(u8 newQualityLevel) const
Acts as an explicit copy constructor, for a new quality level.
Definition: ObjectBase.cpp:70
std::multimap< CStr, Anim > anims
Definition: ObjectBase.h:129
VfsPath model
Definition: ObjectBase.h:124
unsigned int uint32_t
Definition: wposix_types.h:53
Maintains the tree of possible objects from a specific actor definition at a given quality level...
Definition: ObjectBase.h:46
const CStr & GetIdentifier() const
Definition: ObjectBase.cpp:769
bool UsesFile(const VfsPath &pathname) const
Returns whether this object (including any possible props) uses the given file.
Definition: ObjectBase.cpp:774
bool m_CastShadows
Definition: ObjectBase.h:163
std::unordered_set< VfsPath > m_UsedFiles
Definition: ObjectBase.h:269
bool m_FloatOnWater
Definition: ObjectBase.h:165
float m_SizeZ
Definition: ObjectBase.h:100
Decal m_Decal
Definition: ObjectBase.h:113
float m_OffsetZ
Definition: ObjectBase.h:103
Definition: ObjectBase.h:122
Definition: ObjectBase.h:106
VfsPath m_SamplerFile
Definition: ObjectBase.h:92
bool LoadVariant(const CXeromyces &XeroFile, const XMBElement &variant, Variant &currentVariant)
Definition: ObjectBase.cpp:160
float m_ActionPos
Definition: ObjectBase.h:68
Definition: ObjectBase.h:53
Definition: ObjectEntry.h:38
float m_minHeight
Definition: ObjectBase.h:82
int m_Frequency
Definition: ObjectBase.h:111