MD5Parser.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. Open Asset Import Library (ASSIMP)
  3. ----------------------------------------------------------------------
  4. Copyright (c) 2006-2008, ASSIMP Development Team
  5. All rights reserved.
  6. Redistribution and use of this software in source and binary forms,
  7. with or without modification, are permitted provided that the
  8. following conditions are met:
  9. * Redistributions of source code must retain the above
  10. copyright notice, this list of conditions and the
  11. following disclaimer.
  12. * Redistributions in binary form must reproduce the above
  13. copyright notice, this list of conditions and the
  14. following disclaimer in the documentation and/or other
  15. materials provided with the distribution.
  16. * Neither the name of the ASSIMP team, nor the names of its
  17. contributors may be used to endorse or promote products
  18. derived from this software without specific prior
  19. written permission of the ASSIMP Development Team.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. ----------------------------------------------------------------------
  32. */
  33. /** @file Definition of the .MD5 parser class.
  34. http://www.modwiki.net/wiki/MD5_(file_format)
  35. */
  36. #ifndef AI_MD5PARSER_H_INCLUDED
  37. #define AI_MD5PARSER_H_INCLUDED
  38. #include "../include/aiTypes.h"
  39. #include "ParsingUtils.h"
  40. #include <vector>
  41. struct aiFace;
  42. namespace Assimp {
  43. namespace MD5 {
  44. // ---------------------------------------------------------------------------
  45. /** Represents a single element in a MD5 file
  46. *
  47. * Elements are always contained in sections.
  48. */
  49. struct Element
  50. {
  51. //! Points to the starting point of the element
  52. //! Whitespace at the beginning and at the end have been removed,
  53. //! Elements are terminated with \0
  54. char* szStart;
  55. //! Original line number (can be used in error messages
  56. //! if a parsing error occurs)
  57. unsigned int iLineNumber;
  58. };
  59. typedef std::vector< Element > ElementList;
  60. // ---------------------------------------------------------------------------
  61. /** Represents a section of a MD5 file (such as the mesh or the joints section)
  62. *
  63. * A section is always enclosed in { and } brackets.
  64. */
  65. struct Section
  66. {
  67. //! Original line number (can be used in error messages
  68. //! if a parsing error occurs)
  69. unsigned int iLineNumber;
  70. //! List of all elements which have been parsed in this section.
  71. ElementList mElements;
  72. //! Name of the section
  73. std::string mName;
  74. //! For global elements: the value of the element as string
  75. //! Iif !length() the section is not a global element
  76. std::string mGlobalValue;
  77. };
  78. typedef std::vector< Section> SectionList;
  79. // ---------------------------------------------------------------------------
  80. /** Represents a bone (joint) descriptor in a MD5Mesh file
  81. */
  82. struct BoneDesc
  83. {
  84. //! Name of the bone
  85. aiString mName;
  86. //! Parent index of the bone
  87. int mParentIndex;
  88. //! Relative position of the bone
  89. aiVector3D mPositionXYZ;
  90. //! Relative rotation of the bone
  91. aiVector3D mRotationQuat;
  92. //! Absolute transformation of the bone
  93. //! (temporary)
  94. aiMatrix4x4 mTransform;
  95. //! Inverse transformation of the bone
  96. //! (temporary)
  97. aiMatrix4x4 mInvTransform;
  98. //! Internal
  99. unsigned int mMap;
  100. };
  101. typedef std::vector< BoneDesc > BoneList;
  102. // ---------------------------------------------------------------------------
  103. /** Represents a bone (joint) descriptor in a MD5Anim file
  104. */
  105. struct AnimBoneDesc
  106. {
  107. //! Name of the bone
  108. aiString mName;
  109. //! Parent index of the bone
  110. int mParentIndex;
  111. //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
  112. unsigned int iFlags;
  113. //! Index of the first key that corresponds to this anim bone
  114. unsigned int iFirstKeyIndex;
  115. };
  116. typedef std::vector< AnimBoneDesc > AnimBoneList;
  117. // ---------------------------------------------------------------------------
  118. /** Represents a base frame descriptor in a MD5Anim file
  119. */
  120. struct BaseFrameDesc
  121. {
  122. aiVector3D vPositionXYZ;
  123. aiVector3D vRotationQuat;
  124. };
  125. typedef std::vector< BaseFrameDesc > BaseFrameList;
  126. // ---------------------------------------------------------------------------
  127. /** Represents a frame descriptor in a MD5Anim file
  128. */
  129. struct FrameDesc
  130. {
  131. //! Index of the frame
  132. unsigned int iIndex;
  133. //! Animation keyframes - a large blob of data at first
  134. std::vector< float > mValues;
  135. };
  136. typedef std::vector< FrameDesc > FrameList;
  137. // ---------------------------------------------------------------------------
  138. /** Represents a vertex descriptor in a MD5 file
  139. */
  140. struct VertexDesc
  141. {
  142. VertexDesc()
  143. : mFirstWeight (0)
  144. , mNumWeights (0)
  145. {}
  146. //! UV cordinate of the vertex
  147. aiVector2D mUV;
  148. //! Index of the first weight of the vertex in
  149. //! the vertex weight list
  150. unsigned int mFirstWeight;
  151. //! Number of weights assigned to this vertex
  152. unsigned int mNumWeights;
  153. };
  154. typedef std::vector< VertexDesc > VertexList;
  155. // ---------------------------------------------------------------------------
  156. /** Represents a vertex weight descriptor in a MD5 file
  157. */
  158. struct WeightDesc
  159. {
  160. //! Index of the bone to which this weight refers
  161. unsigned int mBone;
  162. //! The weight value
  163. float mWeight;
  164. //! The offset position of this weight
  165. // ! (in the coordinate system defined by the parent bone)
  166. aiVector3D vOffsetPosition;
  167. };
  168. typedef std::vector< WeightDesc > WeightList;
  169. typedef std::vector< aiFace > FaceList;
  170. // ---------------------------------------------------------------------------
  171. /** Represents a mesh in a MD5 file
  172. */
  173. struct MeshDesc
  174. {
  175. //! Weights of the mesh
  176. WeightList mWeights;
  177. //! Vertices of the mesh
  178. VertexList mVertices;
  179. //! Faces of the mesh
  180. FaceList mFaces;
  181. //! Name of the shader (=texture) to be assigned to the mesh
  182. aiString mShader;
  183. };
  184. typedef std::vector< MeshDesc > MeshList;
  185. // ---------------------------------------------------------------------------
  186. /** Parses the data sections of a MD5 mesh file
  187. */
  188. class MD5MeshParser
  189. {
  190. public:
  191. // -------------------------------------------------------------------
  192. /** Constructs a new MD5MeshParser instance from an existing
  193. * preparsed list of file sections.
  194. *
  195. * @param mSections List of file sections (output of MD5Parser)
  196. */
  197. MD5MeshParser(SectionList& mSections);
  198. //! List of all meshes
  199. MeshList mMeshes;
  200. //! List of all joints
  201. BoneList mJoints;
  202. };
  203. #define AI_MD5_ANIMATION_FLAG_TRANSLATE_X 0x1
  204. #define AI_MD5_ANIMATION_FLAG_TRANSLATE_Y 0x2
  205. #define AI_MD5_ANIMATION_FLAG_TRANSLATE_Z 0x4
  206. #define AI_MD5_ANIMATION_FLAG_ROTQUAT_X 0x8
  207. #define AI_MD5_ANIMATION_FLAG_ROTQUAT_Y 0x10
  208. #define AI_MD5_ANIMATION_FLAG_ROTQUAT_Z 0x12
  209. // remove this flag if you need to the bounding box data
  210. #define AI_MD5_PARSE_NO_BOUNDS
  211. // ---------------------------------------------------------------------------
  212. /** Parses the data sections of a MD5 animation file
  213. */
  214. class MD5AnimParser
  215. {
  216. public:
  217. // -------------------------------------------------------------------
  218. /** Constructs a new MD5AnimParser instance from an existing
  219. * preparsed list of file sections.
  220. *
  221. * @param mSections List of file sections (output of MD5Parser)
  222. */
  223. MD5AnimParser(SectionList& mSections);
  224. //! Output frame rate
  225. float fFrameRate;
  226. //! List of animation bones
  227. AnimBoneList mAnimatedBones;
  228. //! List of base frames
  229. BaseFrameList mBaseFrames;
  230. //! List of animation frames
  231. FrameList mFrames;
  232. //! Number of animated components
  233. unsigned int mNumAnimatedComponents;
  234. };
  235. // ---------------------------------------------------------------------------
  236. /** Parses the block structure of MD5MESH and MD5ANIM files (but does no
  237. * further processing)
  238. */
  239. class MD5Parser
  240. {
  241. public:
  242. // -------------------------------------------------------------------
  243. /** Constructs a new MD5Parser instance from an existing buffer.
  244. *
  245. * @param buffer File buffer
  246. * @param fileSize Length of the file in bytes (excluding a terminal 0)
  247. */
  248. MD5Parser(char* buffer, unsigned int fileSize);
  249. // -------------------------------------------------------------------
  250. /** Report a specific error message and throw an exception
  251. * @param error Error message to be reported
  252. * @param line Index of the line where the error occured
  253. */
  254. static void ReportError (const char* error, unsigned int line);
  255. // -------------------------------------------------------------------
  256. /** Report a specific warning
  257. * @param warn Warn message to be reported
  258. * @param line Index of the line where the error occured
  259. */
  260. static void ReportWarning (const char* warn, unsigned int line);
  261. inline void ReportError (const char* error)
  262. {return ReportError(error, this->lineNumber);}
  263. inline void ReportWarning (const char* warn)
  264. {return ReportWarning(warn, this->lineNumber);}
  265. public:
  266. //! List of all sections which have been read
  267. SectionList mSections;
  268. private:
  269. // -------------------------------------------------------------------
  270. /** Parses a file section. The current file pointer must be outside
  271. * of a section.
  272. * @param out Receives the section data
  273. * @return true if the end of the file has been reached
  274. * @throws ImportErrorException if an error occurs
  275. */
  276. bool ParseSection(Section& out);
  277. // -------------------------------------------------------------------
  278. /** Parses the file header
  279. * @throws ImportErrorException if an error occurs
  280. */
  281. void ParseHeader();
  282. // override these functions to make sure the line counter gets incremented
  283. // -------------------------------------------------------------------
  284. inline bool SkipLine( const char* in, const char** out)
  285. {
  286. ++lineNumber;
  287. return ::SkipLine(in,out);
  288. }
  289. // -------------------------------------------------------------------
  290. inline bool SkipLine( )
  291. {
  292. return SkipLine(buffer,(const char**)&buffer);
  293. }
  294. // -------------------------------------------------------------------
  295. inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
  296. {
  297. bool bHad = false;
  298. while (true)
  299. {
  300. if( *in == '\r' || *in == '\n')
  301. {
  302. if (!bHad) // we open files in binary mode, so there could be \r\n sequences ...
  303. {
  304. bHad = true;
  305. ++lineNumber;
  306. }
  307. }
  308. else if (*in == '\t' || *in == ' ')bHad = false;
  309. else break;
  310. in++;
  311. }
  312. *out = in;
  313. return *in != '\0';
  314. }
  315. // -------------------------------------------------------------------
  316. inline bool SkipSpacesAndLineEnd( )
  317. {
  318. return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
  319. }
  320. // -------------------------------------------------------------------
  321. inline bool SkipSpaces( )
  322. {
  323. return ::SkipSpaces((const char**)&buffer);
  324. }
  325. char* buffer;
  326. unsigned int fileSize;
  327. unsigned int lineNumber;
  328. };
  329. }}
  330. #endif // AI_MD5PARSER_H_INCLUDED