Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
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"
31#include "ps/CStr.h"
33
34#include <cstring>
35#include <map>
36#include <unordered_map>
37#include <vector>
38
39class CBoneState;
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 */
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
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
124};
125
126
127////////////////////////////////////////////////////////////////////////////////////////
128// CModelDefRPrivate
130{
131public:
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
144public:
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
151public:
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
168public:
169 // accessor: get vertex data
170 size_t GetNumVertices() const { return m_NumVertices; }
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; }
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
257public:
258 // vertex data
261 std::vector<CVector2D> m_UVCoordinates;
262 size_t m_NumUVsPerVertex; // number of UV pairs per vertex
263 // face data
266 // bone data - default model pose
270 // blend data
274 // prop point data
275 std::vector<SPropPoint> m_PropPoints;
276
277private:
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;
287};
288
289/**
290 * Detects CPU caps and activates the best possible codepath.
291 */
292extern void ModelDefActivateFastImpl();
293
294#endif
295
void ModelDefActivateFastImpl()
Detects CPU caps and activates the best possible codepath.
Definition: ModelDef.cpp:525
Definition: SkeletonAnimDef.h:35
Definition: BoundingBoxAligned.h:34
Definition: Matrix3D.h:34
Definition: ModelDef.h:130
CModelDefRPrivate()
Definition: ModelDef.h:132
virtual ~CModelDefRPrivate()
Definition: ModelDef.h:133
Definition: ModelDef.h:141
const VfsPath & GetName() const
Definition: ModelDef.h:255
CMatrix3D * m_InverseBindBoneMatrices
Definition: ModelDef.h:269
SModelVertex * m_pVertices
Definition: ModelDef.h:260
const std::vector< CVector2D > & GetUVCoordinates() const
Definition: ModelDef.h:176
void BlendBoneMatrices(CMatrix3D boneMatrices[])
Blend bone matrices together to fill bone palette.
Definition: ModelDef.cpp:256
std::map< const void *, CModelDefRPrivate * > RenderDataMap
Definition: ModelDef.h:285
size_t m_NumBlends
Definition: ModelDef.h:271
void SetRenderData(const void *key, CModelDefRPrivate *data)
Register renderer private data.
Definition: ModelDef.cpp:506
size_t m_NumUVsPerVertex
Definition: ModelDef.h:262
static void(* SkinPointsAndNormals)(size_t numVertices, const VertexArrayIterator< CVector3D > &Position, const VertexArrayIterator< CVector3D > &Normal, const SModelVertex *vertices, const size_t *blendIndices, const CMatrix3D newPoseMatrices[])
Transform vertices' positions and normals.
Definition: ModelDef.h:222
CMatrix3D * GetInverseBindBoneMatrices()
Definition: ModelDef.h:185
const SPropPoint * FindPropPoint(const char *name) const
Definition: ModelDef.cpp:301
SModelFace * GetFaces() const
Definition: ModelDef.h:180
VfsPath m_Name
Definition: ModelDef.h:278
CBoneState * GetBones() const
Definition: ModelDef.h:184
size_t m_NumBones
Definition: ModelDef.h:267
SVertexBlend * m_pBlends
Definition: ModelDef.h:272
RenderDataMap m_RenderData
Definition: ModelDef.h:286
@ FILE_VERSION
Definition: ModelDef.h:146
static void Save(const VfsPath &filename, const CModelDef *mdef)
Definition: ModelDef.cpp:473
size_t GetNumVertices() const
Definition: ModelDef.h:170
~CModelDef()
Definition: ModelDef.cpp:287
CModelDef()
Definition: ModelDef.cpp:278
std::vector< CVector2D > m_UVCoordinates
Definition: ModelDef.h:261
size_t GetNumFaces() const
Definition: ModelDef.h:179
static CVector3D SkinNormal(const SModelVertex &vtx, const CMatrix3D newPoseMatrices[])
Transform the given vertex's normal from the bind pose into the new pose.
Definition: ModelDef.cpp:86
NONCOPYABLE(CModelDef)
size_t m_NumVertices
Definition: ModelDef.h:259
SModelFace * m_pFaces
Definition: ModelDef.h:265
size_t GetNumBlends() const
Definition: ModelDef.h:188
size_t * m_pBlendIndices
Definition: ModelDef.h:273
std::vector< SPropPoint > m_PropPoints
Definition: ModelDef.h:275
size_t GetNumBones() const
Definition: ModelDef.h:183
size_t GetNumUVsPerVertex() const
Definition: ModelDef.h:174
void GetMaxBounds(CSkeletonAnimDef *anim, bool loop, CBoundingBoxAligned &result)
Definition: ModelDef.cpp:31
static CModelDef * Load(const VfsPath &filename, const VfsPath &name)
Loads a PMD file.
Definition: ModelDef.cpp:311
static CVector3D SkinPoint(const SModelVertex &vtx, const CMatrix3D newPoseMatrices[])
Transform the given vertex's position from the bind pose into the new pose.
Definition: ModelDef.cpp:73
size_t * GetBlendIndices() const
Definition: ModelDef.h:190
SModelVertex * GetVertices() const
Definition: ModelDef.h:171
SVertexBlend * GetBlends() const
Definition: ModelDef.h:189
CBoneState * m_Bones
Definition: ModelDef.h:268
std::unordered_map< u32, CBoundingBoxAligned > m_MaxBoundsPerAnimDef
Definition: ModelDef.h:281
@ FILE_READ_VERSION
Definition: ModelDef.h:148
CModelDefRPrivate * GetRenderData(const void *key) const
Definition: ModelDef.cpp:515
size_t m_NumFaces
Definition: ModelDef.h:264
Definition: Quaternion.h:26
Definition: SkeletonAnimDef.h:48
Definition: Vector3D.h:31
Definition: path.h:80
Definition: VertexArray.h:31
@ Normal
Definition: CCmpRangeManager.cpp:211
Definition: ModelDef.h:121
u16 m_Verts[3]
Definition: ModelDef.h:123
Definition: ModelDef.h:108
CVector3D m_Norm
Definition: ModelDef.h:112
CVector3D m_Coords
Definition: ModelDef.h:110
SVertexBlend m_Blend
Definition: ModelDef.h:114
Describes the position of a prop point within its parent model.
Definition: ModelDef.h:55
u8 m_BoneIndex
Index of parent bone to which this prop point is relative, if any.
Definition: ModelDef.h:85
CStr m_Name
Name of the prop point.
Definition: ModelDef.h:57
CVector3D m_Position
Position of the point within the parent model, relative to either the parent model's origin or one of...
Definition: ModelDef.h:64
CQuaternion m_Rotation
Rotation of the prop model that will be attached at this point.
Definition: ModelDef.h:70
CMatrix3D m_Transform
Object to parent space transformation.
Definition: ModelDef.h:79
Definition: ModelDef.h:92
bool operator==(const SVertexBlend &o) const
Definition: ModelDef.h:99
u8 m_Bone[SIZE]
Definition: ModelDef.h:95
float m_Weight[SIZE]
Definition: ModelDef.h:97
@ SIZE
Definition: ModelDef.h:93
uint8_t u8
Definition: types.h:37
uint16_t u16
Definition: types.h:38
pthread_key_t key
Definition: wpthread.cpp:140