MDLLoader.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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. //!
  34. //! @file Definition of MDL importer class
  35. //!
  36. #ifndef AI_MDLLOADER_H_INCLUDED
  37. #define AI_MDLLOADER_H_INCLUDED
  38. #include "BaseImporter.h"
  39. #include "../include/aiTypes.h"
  40. #include "../include/aiTexture.h"
  41. #include "../include/aiMaterial.h"
  42. struct aiNode;
  43. #include "MDLFileData.h"
  44. #include "HalfLifeFileData.h"
  45. namespace Assimp
  46. {
  47. class MaterialHelper;
  48. using namespace MDL;
  49. #if (!defined VALIDATE_FILE_SIZE)
  50. # define VALIDATE_FILE_SIZE(msg) this->SizeCheck(msg,__FILE__,__LINE__)
  51. #endif
  52. // ---------------------------------------------------------------------------
  53. /** Used to load MDL files
  54. */
  55. class MDLImporter : public BaseImporter
  56. {
  57. friend class Importer;
  58. protected:
  59. /** Constructor to be privately used by Importer */
  60. MDLImporter();
  61. /** Destructor, private as well */
  62. ~MDLImporter();
  63. public:
  64. // -------------------------------------------------------------------
  65. /** Returns whether the class can handle the format of the given file.
  66. * See BaseImporter::CanRead() for details. */
  67. bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
  68. protected:
  69. // -------------------------------------------------------------------
  70. /** Called by Importer::GetExtensionList() for each loaded importer.
  71. * See BaseImporter::GetExtensionList() for details
  72. */
  73. void GetExtensionList(std::string& append)
  74. {
  75. append.append("*.mdl");
  76. }
  77. // -------------------------------------------------------------------
  78. /** Imports the given file into the given scene structure.
  79. * See BaseImporter::InternReadFile() for details
  80. */
  81. void InternReadFile( const std::string& pFile, aiScene* pScene,
  82. IOSystem* pIOHandler);
  83. protected:
  84. // -------------------------------------------------------------------
  85. /** Import a quake 1 MDL file (IDPO)
  86. */
  87. void InternReadFile_Quake1( );
  88. // -------------------------------------------------------------------
  89. /** Import a GameStudio A4/A5 file (MDL 3,4,5)
  90. */
  91. void InternReadFile_3DGS_MDL345( );
  92. // -------------------------------------------------------------------
  93. /** Import a GameStudio A7 file (MDL 7)
  94. */
  95. void InternReadFile_3DGS_MDL7( );
  96. // -------------------------------------------------------------------
  97. /** Import a CS:S/HL2 MDL file (not fully implemented)
  98. */
  99. void InternReadFile_HL2( );
  100. // *******************************************************************
  101. // Debugging/validation functions
  102. // -------------------------------------------------------------------
  103. /** Check whether a given position is inside the valid range
  104. * Throw a new ImportErrorException if it is not
  105. * \param szPos Cursor position
  106. * \param szFile Name of the source file from which the function was called
  107. * \param iLine Source code line from which the function was called
  108. */
  109. void SizeCheck(const void* szPos);
  110. void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
  111. // -------------------------------------------------------------------
  112. /** Validate the header data structure of a game studio MDL7 file
  113. * \param pcHeader Input header to be validated
  114. */
  115. void ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader);
  116. // -------------------------------------------------------------------
  117. /** Validate the header data structure of a Quake 1 model
  118. * \param pcHeader Input header to be validated
  119. */
  120. void ValidateHeader_Quake1(const MDL::Header* pcHeader);
  121. // *******************************************************************
  122. // Material import
  123. // -------------------------------------------------------------------
  124. /** Try to load a palette from the current directory (colormap.lmp)
  125. * If it is not found the default palette of Quake1 is returned
  126. */
  127. void SearchPalette(const unsigned char** pszColorMap);
  128. // -------------------------------------------------------------------
  129. /** Free a palette created with a previous call to SearchPalette()
  130. */
  131. void FreePalette(const unsigned char* pszColorMap);
  132. // -------------------------------------------------------------------
  133. /** Load a paletized texture from the file and convert it to 32bpp
  134. */
  135. void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
  136. // -------------------------------------------------------------------
  137. /** Used to load textures from MDL3/4
  138. * \param szData Input data
  139. * \param iType Color data type
  140. * \param piSkip Receive: Size to skip, in bytes
  141. */
  142. void CreateTexture_3DGS_MDL4(const unsigned char* szData,
  143. unsigned int iType,
  144. unsigned int* piSkip);
  145. // -------------------------------------------------------------------
  146. /** Used to load textures from MDL5
  147. * \param szData Input data
  148. * \param iType Color data type
  149. * \param piSkip Receive: Size to skip, in bytes
  150. */
  151. void CreateTexture_3DGS_MDL5(const unsigned char* szData,
  152. unsigned int iType,
  153. unsigned int* piSkip);
  154. // -------------------------------------------------------------------
  155. /** Checks whether a texture can be replaced with a single color
  156. * This is useful for all file formats before MDL7 (all those
  157. * that are not containing material colors separate from textures).
  158. * MED seems to write dummy 8x8 monochrome images instead.
  159. * \param pcTexture Input texture
  160. * \return aiColor.r is set to qnan if the function fails and no
  161. * color can be found.
  162. */
  163. aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
  164. // *******************************************************************
  165. // Quake1, MDL 3,4,5 import
  166. // -------------------------------------------------------------------
  167. /** Converts the absolute texture coordinates in MDL5 files to
  168. * relative in a range between 0 and 1
  169. */
  170. void CalculateUVCoordinates_MDL5();
  171. // -------------------------------------------------------------------
  172. /** Read an UV coordinate from the file. If the file format is not
  173. * MDL5, the function calculates relative texture coordinates
  174. * \param vOut Receives the output UV coord
  175. * \param pcSrc UV coordinate buffer
  176. * \param UV coordinate index
  177. */
  178. void ImportUVCoordinate_3DGS_MDL345( aiVector3D& vOut,
  179. const MDL::TexCoord_MDL3* pcSrc,
  180. unsigned int iIndex);
  181. // -------------------------------------------------------------------
  182. /** Setup the material properties for Quake and MDL<7 models.
  183. * These formats don't support more than one material per mesh,
  184. * therefore the method processes only ONE skin and removes
  185. * all others.
  186. */
  187. void SetupMaterialProperties_3DGS_MDL5_Quake1( );
  188. // *******************************************************************
  189. // MDL7 import
  190. // -------------------------------------------------------------------
  191. /** Parse a skin lump in a MDL7/HMP7 file with all of its features
  192. * variant 1: Current cursor position is the beginning of the skin header
  193. * \param szCurrent Current data pointer
  194. * \param szCurrentOut Output data pointer
  195. * \param pcMats Material list for this group. To be filled ...
  196. */
  197. void ParseSkinLump_3DGS_MDL7(
  198. const unsigned char* szCurrent,
  199. const unsigned char** szCurrentOut,
  200. std::vector<MaterialHelper*>& pcMats);
  201. // -------------------------------------------------------------------
  202. /** Parse a skin lump in a MDL7/HMP7 file with all of its features
  203. * variant 2: Current cursor position is the beginning of the skin data
  204. * \param szCurrent Current data pointer
  205. * \param szCurrentOut Output data pointer
  206. * \param pcMatOut Output material
  207. * \param iType header.typ
  208. * \param iWidth header.width
  209. * \param iHeight header.height
  210. */
  211. void ParseSkinLump_3DGS_MDL7(
  212. const unsigned char* szCurrent,
  213. const unsigned char** szCurrentOut,
  214. MaterialHelper* pcMatOut,
  215. unsigned int iType,
  216. unsigned int iWidth,
  217. unsigned int iHeight);
  218. // -------------------------------------------------------------------
  219. /** Skip a skin lump in a MDL7/HMP7 file
  220. * \param szCurrent Current data pointer
  221. * \param szCurrentOut Output data pointer. Points to the byte just
  222. * behind the last byte of the skin.
  223. * \param iType header.typ
  224. * \param iWidth header.width
  225. * \param iHeight header.height
  226. */
  227. void SkipSkinLump_3DGS_MDL7(const unsigned char* szCurrent,
  228. const unsigned char** szCurrentOut,
  229. unsigned int iType,
  230. unsigned int iWidth,
  231. unsigned int iHeight);
  232. // -------------------------------------------------------------------
  233. /** Parse texture color data for MDL5, MDL6 and MDL7 formats
  234. * \param szData Current data pointer
  235. * \param iType type of the texture data. No DDS or external
  236. * \param piSkip Receive the number of bytes to skip
  237. * \param pcNew Must point to fully initialized data. Width and
  238. * height must be set. If pcNew->pcData is set to 0xffffffff,
  239. * piSkip will receive the size of the texture, in bytes, but no
  240. * color data will be read.
  241. */
  242. void ParseTextureColorData(const unsigned char* szData,
  243. unsigned int iType,
  244. unsigned int* piSkip,
  245. aiTexture* pcNew);
  246. // -------------------------------------------------------------------
  247. /** Join two materials / skins. Setup UV source ... etc
  248. * \param pcMat1 First input material
  249. * \param pcMat2 Second input material
  250. * \param pcMatOut Output material instance to be filled. Must be empty
  251. */
  252. void JoinSkins_3DGS_MDL7(MaterialHelper* pcMat1,
  253. MaterialHelper* pcMat2,
  254. MaterialHelper* pcMatOut);
  255. // -------------------------------------------------------------------
  256. /** Add a bone transformation key to an animation
  257. * \param iTrafo Index of the transformation (always==frame index?)
  258. * No need to validate this index, it is always valid.
  259. * \param pcBoneTransforms Bone transformation for this index
  260. * \param apcOutBones Output bones array
  261. */
  262. void AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
  263. const MDL::BoneTransform_MDL7* pcBoneTransforms,
  264. MDL::IntBone_MDL7** apcBonesOut);
  265. // -------------------------------------------------------------------
  266. /** Load the bone list of a MDL7 file
  267. * \return If the bones could be loaded successfully, a valid
  268. * array containing pointers to a temporary bone
  269. * representation. NULL if the bones could not be loaded.
  270. */
  271. MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();
  272. // -------------------------------------------------------------------
  273. /** Load bone transformation keyframes from a file chunk
  274. * \param groupInfo -> doc of data structure
  275. * \param frame -> doc of data structure
  276. * \param shared -> doc of data structure
  277. */
  278. void ParseBoneTrafoKeys_3DGS_MDL7(
  279. const MDL::IntGroupInfo_MDL7& groupInfo,
  280. IntFrameInfo_MDL7& frame,
  281. MDL::IntSharedData_MDL7& shared);
  282. // -------------------------------------------------------------------
  283. /** Calculate absolute bone animation matrices for each bone
  284. * \param pcBones Pointer to the bone section in the file
  285. * \param apcOutBones Output bones array
  286. */
  287. void CalcAbsBoneMatrices_3DGS_MDL7(const MDL::Bone_MDL7* pcBones,
  288. MDL::IntBone_MDL7** apcOutBones);
  289. // -------------------------------------------------------------------
  290. /** Add all bones to the nodegraph (as children of the root node)
  291. * \param apcBonesOut List of bones
  292. * \param pcParent Parent node. New nodes will be added to this node
  293. * \param iParentIndex Index of the parent bone
  294. */
  295. void AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut,
  296. aiNode* pcParent,uint16_t iParentIndex);
  297. // -------------------------------------------------------------------
  298. /** Build output animations
  299. * \param apcBonesOut List of bones
  300. */
  301. void BuildOutputAnims_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut);
  302. // -------------------------------------------------------------------
  303. /** Handles materials that are just referencing another material
  304. * There is no test file for this feature, but Conitec's doc
  305. * say it is used.
  306. */
  307. void HandleMaterialReferences_3DGS_MDL7();
  308. // -------------------------------------------------------------------
  309. /** Copies only the material that are referenced by at least one
  310. * mesh to the final output material list. All other materials
  311. * will be discarded.
  312. * \param shared -> doc of data structure
  313. */
  314. void CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared);
  315. // -------------------------------------------------------------------
  316. /** Process the frame section at the end of a group
  317. * \param groupInfo -> doc of data structure
  318. * \param shared -> doc of data structure
  319. * \param szCurrent Pointer to the start of the frame section
  320. * \param szCurrentOut Receives a pointer to the first byte of the
  321. * next data section.
  322. * \return false to read no further groups (a small workaround for
  323. * some tiny and unsolved problems ... )
  324. */
  325. bool ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
  326. MDL::IntGroupData_MDL7& groupData,
  327. MDL::IntSharedData_MDL7& shared,
  328. const unsigned char* szCurrent,
  329. const unsigned char** szCurrentOut);
  330. // -------------------------------------------------------------------
  331. /** Sort all faces by their materials. If the mesh is using
  332. * multiple materials per face (that are blended together) the function
  333. * might create new materials.
  334. * \param groupInfo -> doc of data structure
  335. * \param groupData -> doc of data structure
  336. * \param splittedGroupData -> doc of data structure
  337. */
  338. void SortByMaterials_3DGS_MDL7(
  339. const MDL::IntGroupInfo_MDL7& groupInfo,
  340. MDL::IntGroupData_MDL7& groupData,
  341. MDL::IntSplittedGroupData_MDL7& splittedGroupData);
  342. // -------------------------------------------------------------------
  343. /** Read all faces and vertices from a MDL7 group. The function fills
  344. * preallocated memory buffers.
  345. * \param groupInfo -> doc of data structure
  346. * \param groupData -> doc of data structure
  347. */
  348. void ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
  349. MDL::IntGroupData_MDL7& groupData);
  350. // -------------------------------------------------------------------
  351. /** Generate the final output meshes for a7 models
  352. * \param groupData -> doc of data structure
  353. * \param splittedGroupData -> doc of data structure
  354. */
  355. void GenerateOutputMeshes_3DGS_MDL7(
  356. MDL::IntGroupData_MDL7& groupData,
  357. MDL::IntSplittedGroupData_MDL7& splittedGroupData);
  358. protected:
  359. /** Configuration option: frame to be loaded */
  360. unsigned int configFrameID;
  361. /** Buffer to hold the loaded file */
  362. unsigned char* mBuffer;
  363. /** For GameStudio MDL files: The number in the magic word, either 3,4 or 5
  364. * (MDL7 doesn't need this, the format has a separate loader) */
  365. unsigned int iGSFileVersion;
  366. /** Output I/O handler. used to load external lmp files
  367. */
  368. IOSystem* pIOHandler;
  369. /** Output scene to be filled
  370. */
  371. aiScene* pScene;
  372. /** Size of the input file in bytes
  373. */
  374. unsigned int iFileSize;
  375. };
  376. }; // end of namespace Assimp
  377. #endif // AI_3DSIMPORTER_H_INC