Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
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
22#include "ps/CStr.h"
23#include "ps/CStrIntern.h"
24
25class CActorDef;
26class CObjectEntry;
27class CObjectManager;
28class CXeromyces;
29class 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.
52public:
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
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
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
81 // allow the prop to ajust the height from minHeight to maxHeight relative to the main model
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;
104 };
105
106 struct Variant
107 {
109
110 CStr m_VariantName; // lowercase name
116
117 std::vector<Anim> m_Anims;
118 std::vector<Prop> m_Props;
119 std::vector<Samp> m_Samplers;
120 };
121
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
167
168 // the material file
170
171 // Quality level - part of the data resource path.
173
174private:
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
199private:
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
222public:
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
236protected:
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
263private:
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
Represents an actor file.
Definition: ObjectBase.h:215
std::vector< std::shared_ptr< CObjectBase > > m_ObjectBases
Definition: ObjectBase.h:267
void LoadErrorPlaceholder(const VfsPath &pathname)
Initialise this object with a default placeholder actor, pretending to be the actor at pathname.
Definition: ObjectBase.cpp:1010
VfsPath GetPathname() const
Definition: ObjectBase.h:228
bool UsesFile(const VfsPath &pathname) const
Returns whether this actor (including any possible props) uses the given file.
Definition: ObjectBase.cpp:1005
NONCOPYABLE(CActorDef)
VfsPath m_Pathname
Definition: ObjectBase.h:261
std::set< CStr > PickSelectionsAtRandom(uint32_t seed) const
Return a list of selections specifying a particular variant in all groups, based on the seed.
Definition: ObjectBase.cpp:784
CActorDef(CObjectManager &objectManager)
Definition: ObjectBase.cpp:780
bool Load(const VfsPath &pathname)
Initialise this object by loading from the given file.
Definition: ObjectBase.cpp:815
std::vector< u8 > QualityLevels() const
Definition: ObjectBase.cpp:792
const std::shared_ptr< CObjectBase > & GetBase(u8 QualityLevel) const
Return the Object base matching the given quality level.
Definition: ObjectBase.cpp:801
CObjectManager & m_ObjectManager
Definition: ObjectBase.h:264
std::unordered_set< VfsPath > m_UsedFiles
Definition: ObjectBase.h:269
Maintains the tree of possible objects from a specific actor definition at a given quality level.
Definition: ObjectBase.h:47
CObjectBase(CObjectManager &objectManager, CActorDef &actorDef, u8 QualityLevel)
Definition: ObjectBase.cpp:59
NONCOPYABLE(CObjectBase)
std::set< CStr > CalculateRandomRemainingSelections(uint32_t seed, const std::vector< std::set< CStr > > &initialSelections) const
Definition: ObjectBase.cpp:510
u8 m_QualityLevel
Definition: ObjectBase.h:172
VfsPath m_Material
Definition: ObjectBase.h:169
bool UsesFile(const VfsPath &pathname) const
Returns whether this object (including any possible props) uses the given file.
Definition: ObjectBase.cpp:774
void GetQualitySplits(std::vector< u8 > &splits) const
Get all quality levels at which this object changes (includes props).
Definition: ObjectBase.cpp:725
boost::mt19937 rng_t
Definition: ObjectBase.h:186
std::unique_ptr< CObjectBase > CopyWithQuality(u8 newQualityLevel) const
Acts as an explicit copy constructor, for a new quality level.
Definition: ObjectBase.cpp:70
friend CActorDef
Definition: ObjectBase.h:48
struct CObjectBase::@7 m_Properties
std::vector< u8 > CalculateVariationKey(const std::vector< const std::set< CStr > * > &selections) const
Definition: ObjectBase.cpp:348
std::vector< std::vector< Variant > > m_VariantGroups
Definition: ObjectBase.h:206
CActorDef & m_ActorDef
Definition: ObjectBase.h:201
const Variation BuildVariation(const std::vector< u8 > &variationKey) const
Definition: ObjectBase.cpp:436
bool LoadVariant(const CXeromyces &XeroFile, const XMBElement &variant, Variant &currentVariant)
Definition: ObjectBase.cpp:160
bool m_CastShadows
Definition: ObjectBase.h:163
const CStr & GetIdentifier() const
Definition: ObjectBase.cpp:769
CStr m_Identifier
Definition: ObjectBase.h:204
bool m_FloatOnWater
Definition: ObjectBase.h:165
std::vector< std::vector< CStr > > GetVariantGroups() const
Definition: ObjectBase.cpp:660
CObjectManager & m_ObjectManager
Definition: ObjectBase.h:207
bool Load(const CXeromyces &XeroFile, const XMBElement &base)
Definition: ObjectBase.cpp:80
Definition: ObjectEntry.h:38
Definition: ObjectManager.h:42
Interned 8-bit strings.
Definition: CStrIntern.h:38
Definition: Xeromyces.h:41
Definition: path.h:80
Definition: XMBData.h:136
Definition: ObjectBase.h:54
int m_Frequency
Definition: ObjectBase.h:61
float m_SoundPos
Definition: ObjectBase.h:70
float m_Speed
Definition: ObjectBase.h:65
float m_ActionPos2
Definition: ObjectBase.h:69
VfsPath m_FileName
Definition: ObjectBase.h:63
CStr m_ID
Definition: ObjectBase.h:60
float m_ActionPos
Definition: ObjectBase.h:68
CStr m_AnimName
Definition: ObjectBase.h:58
Anim()
Definition: ObjectBase.h:56
Definition: ObjectBase.h:96
float m_SizeX
Definition: ObjectBase.h:99
Decal()
Definition: ObjectBase.h:97
float m_Angle
Definition: ObjectBase.h:101
float m_SizeZ
Definition: ObjectBase.h:100
float m_OffsetZ
Definition: ObjectBase.h:103
float m_OffsetX
Definition: ObjectBase.h:102
Definition: ObjectBase.h:74
Prop()
Definition: ObjectBase.h:76
CStrW m_ModelName
Definition: ObjectBase.h:80
CStr m_PropPointName
Definition: ObjectBase.h:78
bool m_selectable
Definition: ObjectBase.h:84
float m_minHeight
Definition: ObjectBase.h:82
float m_maxHeight
Definition: ObjectBase.h:83
Definition: ObjectBase.h:88
CStrIntern m_SamplerName
Definition: ObjectBase.h:90
VfsPath m_SamplerFile
Definition: ObjectBase.h:92
Definition: ObjectBase.h:107
std::vector< Samp > m_Samplers
Definition: ObjectBase.h:119
CStr m_Color
Definition: ObjectBase.h:115
VfsPath m_Particles
Definition: ObjectBase.h:114
VfsPath m_ModelFilename
Definition: ObjectBase.h:112
int m_Frequency
Definition: ObjectBase.h:111
std::vector< Anim > m_Anims
Definition: ObjectBase.h:117
Variant()
Definition: ObjectBase.h:108
Decal m_Decal
Definition: ObjectBase.h:113
std::vector< Prop > m_Props
Definition: ObjectBase.h:118
CStr m_VariantName
Definition: ObjectBase.h:110
Definition: ObjectBase.h:123
std::multimap< CStr, Samp > samplers
Definition: ObjectBase.h:130
std::multimap< CStr, Prop > props
Definition: ObjectBase.h:128
CStr color
Definition: ObjectBase.h:127
std::multimap< CStr, Anim > anims
Definition: ObjectBase.h:129
Decal decal
Definition: ObjectBase.h:125
VfsPath particles
Definition: ObjectBase.h:126
VfsPath model
Definition: ObjectBase.h:124
uint8_t u8
Definition: types.h:37
unsigned int uint32_t
Definition: wposix_types.h:53