[Windows] Automated build.
[0ad.git] / source / graphics / ModelDef.h
blobe0e5d35cfbab2a12c348bc4252855739af8e9da2
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/>.
19 * Defines a raw 3d model.
22 #ifndef INCLUDED_MODELDEF
23 #define INCLUDED_MODELDEF
25 #include "maths/BoundingBoxAligned.h"
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"
34 #include <cstring>
35 #include <map>
36 #include <unordered_map>
37 #include <vector>
39 class CBoneState;
40 class CSkeletonAnimDef;
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.
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.
52 * @see CModel::m_BoneMatrices
54 struct SPropPoint
56 /// Name of the prop point
57 CStr m_Name;
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
64 CVector3D m_Position;
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
70 CQuaternion m_Rotation;
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
79 CMatrix3D m_Transform;
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.
85 u8 m_BoneIndex;
88 ///////////////////////////////////////////////////////////////////////////////
89 // SVertexBlend: structure containing the necessary data for blending vertices
90 // with multiple bones
91 struct SVertexBlend
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];
99 bool operator==(const SVertexBlend& o) const
101 return !memcmp(m_Bone, o.m_Bone, sizeof(m_Bone)) && !memcmp(m_Weight, o.m_Weight, sizeof(m_Weight));
105 ///////////////////////////////////////////////////////////////////////////////
106 // SModelVertex: structure containing per-vertex data
107 struct SModelVertex
109 // vertex position
110 CVector3D m_Coords;
111 // vertex normal
112 CVector3D m_Norm;
113 // vertex blend data
114 SVertexBlend m_Blend;
118 ///////////////////////////////////////////////////////////////////////////////
119 // SModelFace: structure containing per-face data
120 struct SModelFace
122 // indices of the 3 vertices on this face
123 u16 m_Verts[3];
127 ////////////////////////////////////////////////////////////////////////////////////////
128 // CModelDefRPrivate
129 class CModelDefRPrivate
131 public:
132 CModelDefRPrivate() { }
133 virtual ~CModelDefRPrivate() { }
137 ////////////////////////////////////////////////////////////////////////////////////////
138 // CModelDef: a raw 3D model; describes the vertices, faces, skinning and skeletal
139 // information of a model
140 class CModelDef
142 NONCOPYABLE(CModelDef);
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 };
151 public:
152 CModelDef();
153 ~CModelDef();
155 // model I/O functions
157 static void Save(const VfsPath& filename,const CModelDef* mdef);
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
166 static CModelDef* Load(const VfsPath& filename, const VfsPath& name);
168 public:
169 // accessor: get vertex data
170 size_t GetNumVertices() const { return m_NumVertices; }
171 SModelVertex* GetVertices() const { return m_pVertices; }
173 // accessor: get number of UV sets
174 size_t GetNumUVsPerVertex() const { return m_NumUVsPerVertex; }
176 const std::vector<CVector2D>& GetUVCoordinates() const { return m_UVCoordinates; }
178 // accessor: get face data
179 size_t GetNumFaces() const { return m_NumFaces; }
180 SModelFace* GetFaces() const { return m_pFaces; }
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; }
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; }
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;
197 * @param anim may be null
199 void GetMaxBounds(CSkeletonAnimDef* anim, bool loop, CBoundingBoxAligned& result);
202 * Transform the given vertex's position from the bind pose into the new pose.
204 * @return new world-space vertex coordinates
206 static CVector3D SkinPoint(const SModelVertex& vtx,
207 const CMatrix3D newPoseMatrices[]);
210 * Transform the given vertex's normal from the bind pose into the new pose.
212 * @return new world-space vertex normal
214 static CVector3D SkinNormal(const SModelVertex& vtx,
215 const CMatrix3D newPoseMatrices[]);
218 * Transform vertices' positions and normals.
219 * (This is equivalent to looping over SkinPoint and SkinNormal,
220 * but slightly more efficient.)
222 static void(*SkinPointsAndNormals)(
223 size_t numVertices,
224 const VertexArrayIterator<CVector3D>& Position,
225 const VertexArrayIterator<CVector3D>& Normal,
226 const SModelVertex* vertices,
227 const size_t* blendIndices,
228 const CMatrix3D newPoseMatrices[]);
231 * Blend bone matrices together to fill bone palette.
233 void BlendBoneMatrices(CMatrix3D boneMatrices[]);
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.
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.
246 * postconditions : data is bound to the lifetime of this CModelDef
247 * object.
249 void SetRenderData(const void* key, CModelDefRPrivate* data);
251 // accessor: render data
252 CModelDefRPrivate* GetRenderData(const void* key) const;
254 // accessor: get model name (for debugging)
255 const VfsPath& GetName() const { return m_Name; }
257 public:
258 // vertex data
259 size_t m_NumVertices;
260 SModelVertex* m_pVertices;
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;
265 SModelFace* m_pFaces;
266 // bone data - default model pose
267 size_t m_NumBones;
268 CBoneState* m_Bones;
269 CMatrix3D* m_InverseBindBoneMatrices;
270 // blend data
271 size_t m_NumBlends;
272 SVertexBlend *m_pBlends;
273 size_t* m_pBlendIndices;
274 // prop point data
275 std::vector<SPropPoint> m_PropPoints;
277 private:
278 VfsPath m_Name; // filename
280 // Maximal bounding box of this mesh for a given animation.
281 std::unordered_map<u32, CBoundingBoxAligned> m_MaxBoundsPerAnimDef;
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;
290 * Detects CPU caps and activates the best possible codepath.
292 extern void ModelDefActivateFastImpl();
294 #endif