Pyrogenesis  trunk
ModelDef.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 /*
19  * Defines a raw 3d model.
20  */
21 
22 #ifndef INCLUDED_MODELDEF
23 #define INCLUDED_MODELDEF
24 
26 #include "maths/Matrix3D.h"
27 #include "maths/Quaternion.h"
28 #include "maths/Vector2D.h"
29 #include "maths/Vector3D.h"
30 #include "lib/file/vfs/vfs_path.h"
31 #include "ps/CStr.h"
32 #include "renderer/VertexArray.h"
33 
34 #include <cstring>
35 #include <map>
36 #include <unordered_map>
37 #include <vector>
38 
39 class CBoneState;
40 class CSkeletonAnimDef;
41 
42 /**
43  * Describes the position of a prop point within its parent model. A prop point is the location within a parent model
44  * where the prop's origin will be attached.
45  *
46  * A prop point is specified by its transformation matrix (or separately by its position and rotation), which
47  * can be relative to either the parent model's origin, or one of the parent's bones. If the parent model is boned,
48  * then the @ref m_BoneIndex field may specify a bone to which the transformation matrix is relative (see
49  * @ref CModel::m_BoneMatrices). Otherwise, the transformation matrix is assumed to be relative to the parent model's
50  * origin.
51  *
52  * @see CModel::m_BoneMatrices
53  */
54 struct SPropPoint
55 {
56  /// Name of the prop point
57  CStr m_Name;
58 
59  /**
60  * Position of the point within the parent model, relative to either the parent model's origin or one of the parent
61  * model's bones if applicable. Also specified as part of @ref m_Transform.
62  * @see m_Transform
63  */
65 
66  /**
67  * Rotation of the prop model that will be attached at this point. Also specified as part of @ref m_Transform.
68  * @see m_Transform
69  */
71 
72  /**
73  * Object to parent space transformation. Combines both @ref m_Position and @ref m_Rotation in a single
74  * transformation matrix. This transformation is relative to either the parent model's origin, or one of its
75  * bones, depending on whether it is skeletal. If relative to a bone, then the bone in the parent model to
76  * which this transformation is relative may be found by m_BoneIndex.
77  * @see m_Position, m_Rotation
78  */
80 
81  /**
82  * Index of parent bone to which this prop point is relative, if any. The value 0xFF specifies that either the parent
83  * model is unboned, or that this prop point is relative to the parent model's origin rather than one if its bones.
84  */
86 };
87 
88 ///////////////////////////////////////////////////////////////////////////////
89 // SVertexBlend: structure containing the necessary data for blending vertices
90 // with multiple bones
92 {
93  enum { SIZE = 4 };
94  // index of the influencing bone, or 0xff if none
95  u8 m_Bone[SIZE];
96  // weight of the influence; all weights sum to 1
97  float m_Weight[SIZE];
98 
99  bool operator==(const SVertexBlend& o) const
100  {
101  return !memcmp(m_Bone, o.m_Bone, sizeof(m_Bone)) && !memcmp(m_Weight, o.m_Weight, sizeof(m_Weight));
102  }
103 };
104 
105 ///////////////////////////////////////////////////////////////////////////////
106 // SModelVertex: structure containing per-vertex data
108 {
109  // vertex position
111  // vertex normal
113  // vertex blend data
115 };
116 
117 
118 ///////////////////////////////////////////////////////////////////////////////
119 // SModelFace: structure containing per-face data
121 {
122  // indices of the 3 vertices on this face
123  u16 m_Verts[3];
124 };
125 
126 
127 ////////////////////////////////////////////////////////////////////////////////////////
128 // CModelDefRPrivate
130 {
131 public:
133  virtual ~CModelDefRPrivate() { }
134 };
135 
136 
137 ////////////////////////////////////////////////////////////////////////////////////////
138 // CModelDef: a raw 3D model; describes the vertices, faces, skinning and skeletal
139 // information of a model
141 {
143 
144 public:
145  // current file version given to saved animations
146  enum { FILE_VERSION = 3 };
147  // supported file read version - files with a version less than this will be rejected
148  enum { FILE_READ_VERSION = 1 };
149 
150 
151 public:
152  CModelDef();
153  ~CModelDef();
154 
155  // model I/O functions
156 
157  static void Save(const VfsPath& filename,const CModelDef* mdef);
158 
159  /**
160  * Loads a PMD file.
161  * @param filename VFS path of .pmd file to load
162  * @param name arbitrary name to give the model for debugging purposes (usually pathname)
163  * @return the model - always non-NULL
164  * @throw PSERROR_File if it can't load the model
165  */
166  static CModelDef* Load(const VfsPath& filename, const VfsPath& name);
167 
168 public:
169  // accessor: get vertex data
170  size_t GetNumVertices() const { return m_NumVertices; }
171  SModelVertex* GetVertices() const { return m_pVertices; }
172 
173  // accessor: get number of UV sets
174  size_t GetNumUVsPerVertex() const { return m_NumUVsPerVertex; }
175 
176  const std::vector<CVector2D>& GetUVCoordinates() const { return m_UVCoordinates; }
177 
178  // accessor: get face data
179  size_t GetNumFaces() const { return m_NumFaces; }
180  SModelFace* GetFaces() const { return m_pFaces; }
181 
182  // accessor: get bone data
183  size_t GetNumBones() const { return m_NumBones; }
184  CBoneState* GetBones() const { return m_Bones; }
185  CMatrix3D* GetInverseBindBoneMatrices() { return m_InverseBindBoneMatrices; }
186 
187  // accessor: get blend data
188  size_t GetNumBlends() const { return m_NumBlends; }
189  SVertexBlend* GetBlends() const { return m_pBlends; }
190  size_t* GetBlendIndices() const { return m_pBlendIndices; }
191 
192  // find and return pointer to prop point matching given name; return
193  // null if no match (case insensitive search)
194  const SPropPoint* FindPropPoint(const char* name) const;
195 
196  /**
197  * @param anim may be null
198  */
199  void GetMaxBounds(CSkeletonAnimDef* anim, bool loop, CBoundingBoxAligned& result);
200 
201  /**
202  * Transform the given vertex's position from the bind pose into the new pose.
203  *
204  * @return new world-space vertex coordinates
205  */
206  static CVector3D SkinPoint(const SModelVertex& vtx,
207  const CMatrix3D newPoseMatrices[]);
208 
209  /**
210  * Transform the given vertex's normal from the bind pose into the new pose.
211  *
212  * @return new world-space vertex normal
213  */
214  static CVector3D SkinNormal(const SModelVertex& vtx,
215  const CMatrix3D newPoseMatrices[]);
216 
217  /**
218  * Transform vertices' positions and normals.
219  * (This is equivalent to looping over SkinPoint and SkinNormal,
220  * but slightly more efficient.)
221  */
222  static void(*SkinPointsAndNormals)(
223  size_t numVertices,
224  const VertexArrayIterator<CVector3D>& Position,
226  const SModelVertex* vertices,
227  const size_t* blendIndices,
228  const CMatrix3D newPoseMatrices[]);
229 
230  /**
231  * Blend bone matrices together to fill bone palette.
232  */
233  void BlendBoneMatrices(CMatrix3D boneMatrices[]);
234 
235  /**
236  * Register renderer private data. Use the key to
237  * distinguish between private data used by different render paths.
238  * The private data will be managed by this CModelDef object:
239  * It will be deleted when CModelDef is destructed or when private
240  * data is registered using the same key.
241  *
242  * @param key The opaque key that is used to identify the caller.
243  * The given private data can be retrieved by passing key to GetRenderData.
244  * @param data The private data.
245  *
246  * postconditions : data is bound to the lifetime of this CModelDef
247  * object.
248  */
249  void SetRenderData(const void* key, CModelDefRPrivate* data);
250 
251  // accessor: render data
252  CModelDefRPrivate* GetRenderData(const void* key) const;
253 
254  // accessor: get model name (for debugging)
255  const VfsPath& GetName() const { return m_Name; }
256 
257 public:
258  // vertex data
261  std::vector<CVector2D> m_UVCoordinates;
262  size_t m_NumUVsPerVertex; // number of UV pairs per vertex
263  // face data
264  size_t m_NumFaces;
266  // bone data - default model pose
267  size_t m_NumBones;
270  // blend data
271  size_t m_NumBlends;
274  // prop point data
275  std::vector<SPropPoint> m_PropPoints;
276 
277 private:
278  VfsPath m_Name; // filename
279 
280  // Maximal bounding box of this mesh for a given animation.
281  std::unordered_map<u32, CBoundingBoxAligned> m_MaxBoundsPerAnimDef;
282 
283  // renderdata shared by models of the same modeldef,
284  // by render path
285  typedef std::map<const void*, CModelDefRPrivate*> RenderDataMap;
286  RenderDataMap m_RenderData;
287 };
288 
289 /**
290  * Detects CPU caps and activates the best possible codepath.
291  */
292 extern void ModelDefActivateFastImpl();
293 
294 #endif
295 
#define NONCOPYABLE(className)
Indicates that a class is noncopyable (usually due to const or reference members, or because the clas...
Definition: code_annotation.h:227
u8 m_BoneIndex
Index of parent bone to which this prop point is relative, if any.
Definition: ModelDef.h:85
CQuaternion m_Rotation
Rotation of the prop model that will be attached at this point.
Definition: ModelDef.h:70
const std::vector< CVector2D > & GetUVCoordinates() const
Definition: ModelDef.h:176
size_t GetNumFaces() const
Definition: ModelDef.h:179
SModelFace * m_pFaces
Definition: ModelDef.h:265
std::unordered_map< u32, CBoundingBoxAligned > m_MaxBoundsPerAnimDef
Definition: ModelDef.h:281
Describes the position of a prop point within its parent model.
Definition: ModelDef.h:54
RenderDataMap m_RenderData
Definition: ModelDef.h:286
void ModelDefActivateFastImpl()
Detects CPU caps and activates the best possible codepath.
Definition: ModelDef.cpp:525
bool operator==(const SVertexBlend &o) const
Definition: ModelDef.h:99
CVector3D m_Norm
Definition: ModelDef.h:112
SModelVertex * m_pVertices
Definition: ModelDef.h:260
uint16_t u16
Definition: types.h:38
float m_Weight[SIZE]
Definition: ModelDef.h:97
SVertexBlend * GetBlends() const
Definition: ModelDef.h:189
Definition: SkeletonAnimDef.h:34
Definition: Vector3D.h:30
Definition: ModelDef.h:129
virtual ~CModelDefRPrivate()
Definition: ModelDef.h:133
std::vector< SPropPoint > m_PropPoints
Definition: ModelDef.h:275
SModelFace * GetFaces() const
Definition: ModelDef.h:180
Definition: ModelDef.h:140
size_t m_NumBones
Definition: ModelDef.h:267
uint8_t u8
Definition: types.h:37
size_t m_NumFaces
Definition: ModelDef.h:264
SVertexBlend * m_pBlends
Definition: ModelDef.h:272
const VfsPath & GetName() const
Definition: ModelDef.h:255
size_t GetNumVertices() const
Definition: ModelDef.h:170
Definition: ModelDef.h:107
Definition: Matrix3D.h:33
u8 m_Bone[SIZE]
Definition: ModelDef.h:95
CMatrix3D * GetInverseBindBoneMatrices()
Definition: ModelDef.h:185
Definition: SkeletonAnimDef.h:47
Definition: CCmpRangeManager.cpp:211
VfsPath m_Name
Definition: ModelDef.h:278
Definition: path.h:79
size_t m_NumBlends
Definition: ModelDef.h:271
size_t * m_pBlendIndices
Definition: ModelDef.h:273
pthread_key_t key
Definition: wpthread.cpp:140
size_t m_NumVertices
Definition: ModelDef.h:259
CStr m_Name
Name of the prop point.
Definition: ModelDef.h:57
static Status Load(const OsPath &pathname, void *buf, size_t size, const Parameters &p=Parameters(), const CompletedHook &completedHook=CompletedHook(), const IssueHook &issueHook=IssueHook())
Definition: io.h:347
CMatrix3D * m_InverseBindBoneMatrices
Definition: ModelDef.h:269
Definition: ModelDef.h:91
Definition: ModelDef.h:120
CMatrix3D m_Transform
Object to parent space transformation.
Definition: ModelDef.h:79
CModelDefRPrivate()
Definition: ModelDef.h:132
Status Save(const CStrW &name, const CStrW &description, CSimulation2 &simulation, const Script::StructuredClone &guiMetadataClone)
Create new saved game archive with given name and simulation data.
Definition: SavedGame.cpp:56
std::map< const void *, CModelDefRPrivate * > RenderDataMap
Definition: ModelDef.h:285
CBoneState * GetBones() const
Definition: ModelDef.h:184
size_t * GetBlendIndices() const
Definition: ModelDef.h:190
Definition: Quaternion.h:25
Definition: BoundingBoxAligned.h:33
CVector3D m_Coords
Definition: ModelDef.h:110
SVertexBlend m_Blend
Definition: ModelDef.h:114
SModelVertex * GetVertices() const
Definition: ModelDef.h:171
size_t GetNumBlends() const
Definition: ModelDef.h:188
CVector3D m_Position
Position of the point within the parent model, relative to either the parent model&#39;s origin or one of...
Definition: ModelDef.h:64
Definition: VertexArray.h:30
std::vector< CVector2D > m_UVCoordinates
Definition: ModelDef.h:261
size_t m_NumUVsPerVertex
Definition: ModelDef.h:262
size_t GetNumUVsPerVertex() const
Definition: ModelDef.h:174
CBoneState * m_Bones
Definition: ModelDef.h:268
size_t GetNumBones() const
Definition: ModelDef.h:183