vrshoot
diff libs/assimp/MDLLoader.h @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/MDLLoader.h Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,456 @@ 1.4 +/* 1.5 +Open Asset Import Library (assimp) 1.6 +---------------------------------------------------------------------- 1.7 + 1.8 +Copyright (c) 2006-2012, assimp team 1.9 +All rights reserved. 1.10 + 1.11 +Redistribution and use of this software in source and binary forms, 1.12 +with or without modification, are permitted provided that the 1.13 +following conditions are met: 1.14 + 1.15 +* Redistributions of source code must retain the above 1.16 + copyright notice, this list of conditions and the 1.17 + following disclaimer. 1.18 + 1.19 +* Redistributions in binary form must reproduce the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer in the documentation and/or other 1.22 + materials provided with the distribution. 1.23 + 1.24 +* Neither the name of the assimp team, nor the names of its 1.25 + contributors may be used to endorse or promote products 1.26 + derived from this software without specific prior 1.27 + written permission of the assimp team. 1.28 + 1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.40 + 1.41 +---------------------------------------------------------------------- 1.42 +*/ 1.43 + 1.44 + 1.45 +/** @file MDLLoader.h 1.46 + * @brief Declaration of the loader for MDL files 1.47 + */ 1.48 + 1.49 +#ifndef AI_MDLLOADER_H_INCLUDED 1.50 +#define AI_MDLLOADER_H_INCLUDED 1.51 + 1.52 +#include "BaseImporter.h" 1.53 + 1.54 +struct aiNode; 1.55 +#include "MDLFileData.h" 1.56 +#include "HalfLifeFileData.h" 1.57 + 1.58 +namespace Assimp { 1.59 + 1.60 + 1.61 +using namespace MDL; 1.62 + 1.63 +// -------------------------------------------------------------------------------------- 1.64 +// Include file/line information in debug builds 1.65 +#ifdef ASSIMP_BUILD_DEBUG 1.66 +# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg,__FILE__,__LINE__) 1.67 +#else 1.68 +# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg) 1.69 +#endif 1.70 + 1.71 +// -------------------------------------------------------------------------------------- 1.72 +/** @brief Class to load MDL files. 1.73 + * 1.74 + * Several subformats exist: 1.75 + * <ul> 1.76 + * <li>Quake I</li> 1.77 + * <li>3D Game Studio MDL3, MDL4</li> 1.78 + * <li>3D Game Studio MDL5</li> 1.79 + * <li>3D Game Studio MDL7</li> 1.80 + * <li>Halflife 2</li> 1.81 + * </ul> 1.82 + * These formats are partially identical and it would be possible to load 1.83 + * them all with a single 1000-line function-beast. However, it has been 1.84 + * split into several code paths to make the code easier to read and maintain. 1.85 +*/ 1.86 +class MDLImporter : public BaseImporter 1.87 +{ 1.88 +public: 1.89 + MDLImporter(); 1.90 + ~MDLImporter(); 1.91 + 1.92 + 1.93 +public: 1.94 + 1.95 + // ------------------------------------------------------------------- 1.96 + /** Returns whether the class can handle the format of the given file. 1.97 + * See BaseImporter::CanRead() for details. */ 1.98 + bool CanRead( const std::string& pFile, IOSystem* pIOHandler, 1.99 + bool checkSig) const; 1.100 + 1.101 + 1.102 + // ------------------------------------------------------------------- 1.103 + /** Called prior to ReadFile(). 1.104 + * The function is a request to the importer to update its configuration 1.105 + * basing on the Importer's configuration property list. 1.106 + */ 1.107 + void SetupProperties(const Importer* pImp); 1.108 + 1.109 +protected: 1.110 + 1.111 + 1.112 + // ------------------------------------------------------------------- 1.113 + /** Return importer meta information. 1.114 + * See #BaseImporter::GetInfo for the details 1.115 + */ 1.116 + const aiImporterDesc* GetInfo () const; 1.117 + 1.118 + // ------------------------------------------------------------------- 1.119 + /** Imports the given file into the given scene structure. 1.120 + * See BaseImporter::InternReadFile() for details 1.121 + */ 1.122 + void InternReadFile( const std::string& pFile, aiScene* pScene, 1.123 + IOSystem* pIOHandler); 1.124 + 1.125 +protected: 1.126 + 1.127 + // ------------------------------------------------------------------- 1.128 + /** Import a quake 1 MDL file (IDPO) 1.129 + */ 1.130 + void InternReadFile_Quake1( ); 1.131 + 1.132 + // ------------------------------------------------------------------- 1.133 + /** Import a GameStudio A4/A5 file (MDL 3,4,5) 1.134 + */ 1.135 + void InternReadFile_3DGS_MDL345( ); 1.136 + 1.137 + // ------------------------------------------------------------------- 1.138 + /** Import a GameStudio A7 file (MDL 7) 1.139 + */ 1.140 + void InternReadFile_3DGS_MDL7( ); 1.141 + 1.142 + // ------------------------------------------------------------------- 1.143 + /** Import a CS:S/HL2 MDL file (not fully implemented) 1.144 + */ 1.145 + void InternReadFile_HL2( ); 1.146 + 1.147 + // ------------------------------------------------------------------- 1.148 + /** Check whether a given position is inside the valid range 1.149 + * Throw a DeadlyImportError if it is not 1.150 + * \param szPos Cursor position 1.151 + * \param szFile Name of the source file from which the function was called 1.152 + * \param iLine Source code line from which the function was called 1.153 + */ 1.154 + void SizeCheck(const void* szPos); 1.155 + void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine); 1.156 + 1.157 + 1.158 + // ------------------------------------------------------------------- 1.159 + /** Validate the header data structure of a game studio MDL7 file 1.160 + * \param pcHeader Input header to be validated 1.161 + */ 1.162 + void ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader); 1.163 + 1.164 + // ------------------------------------------------------------------- 1.165 + /** Validate the header data structure of a Quake 1 model 1.166 + * \param pcHeader Input header to be validated 1.167 + */ 1.168 + void ValidateHeader_Quake1(const MDL::Header* pcHeader); 1.169 + 1.170 + 1.171 + // ------------------------------------------------------------------- 1.172 + /** Try to load a palette from the current directory (colormap.lmp) 1.173 + * If it is not found the default palette of Quake1 is returned 1.174 + */ 1.175 + void SearchPalette(const unsigned char** pszColorMap); 1.176 + 1.177 + // ------------------------------------------------------------------- 1.178 + /** Free a palette created with a previous call to SearchPalette() 1.179 + */ 1.180 + void FreePalette(const unsigned char* pszColorMap); 1.181 + 1.182 + 1.183 + // ------------------------------------------------------------------- 1.184 + /** Load a paletized texture from the file and convert it to 32bpp 1.185 + */ 1.186 + void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData); 1.187 + 1.188 + // ------------------------------------------------------------------- 1.189 + /** Used to load textures from MDL3/4 1.190 + * \param szData Input data 1.191 + * \param iType Color data type 1.192 + * \param piSkip Receive: Size to skip, in bytes 1.193 + */ 1.194 + void CreateTexture_3DGS_MDL4(const unsigned char* szData, 1.195 + unsigned int iType, 1.196 + unsigned int* piSkip); 1.197 + 1.198 + 1.199 + // ------------------------------------------------------------------- 1.200 + /** Used to load textures from MDL5 1.201 + * \param szData Input data 1.202 + * \param iType Color data type 1.203 + * \param piSkip Receive: Size to skip, in bytes 1.204 + */ 1.205 + void CreateTexture_3DGS_MDL5(const unsigned char* szData, 1.206 + unsigned int iType, 1.207 + unsigned int* piSkip); 1.208 + 1.209 + 1.210 + // ------------------------------------------------------------------- 1.211 + /** Checks whether a texture can be replaced with a single color 1.212 + * This is useful for all file formats before MDL7 (all those 1.213 + * that are not containing material colors separate from textures). 1.214 + * MED seems to write dummy 8x8 monochrome images instead. 1.215 + * \param pcTexture Input texture 1.216 + * \return aiColor.r is set to qnan if the function fails and no 1.217 + * color can be found. 1.218 + */ 1.219 + aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture); 1.220 + 1.221 + 1.222 + // ------------------------------------------------------------------- 1.223 + /** Converts the absolute texture coordinates in MDL5 files to 1.224 + * relative in a range between 0 and 1 1.225 + */ 1.226 + void CalculateUVCoordinates_MDL5(); 1.227 + 1.228 + 1.229 + // ------------------------------------------------------------------- 1.230 + /** Read an UV coordinate from the file. If the file format is not 1.231 + * MDL5, the function calculates relative texture coordinates 1.232 + * \param vOut Receives the output UV coord 1.233 + * \param pcSrc UV coordinate buffer 1.234 + * \param UV coordinate index 1.235 + */ 1.236 + void ImportUVCoordinate_3DGS_MDL345( aiVector3D& vOut, 1.237 + const MDL::TexCoord_MDL3* pcSrc, 1.238 + unsigned int iIndex); 1.239 + 1.240 + // ------------------------------------------------------------------- 1.241 + /** Setup the material properties for Quake and MDL<7 models. 1.242 + * These formats don't support more than one material per mesh, 1.243 + * therefore the method processes only ONE skin and removes 1.244 + * all others. 1.245 + */ 1.246 + void SetupMaterialProperties_3DGS_MDL5_Quake1( ); 1.247 + 1.248 + 1.249 + // ------------------------------------------------------------------- 1.250 + /** Parse a skin lump in a MDL7/HMP7 file with all of its features 1.251 + * variant 1: Current cursor position is the beginning of the skin header 1.252 + * \param szCurrent Current data pointer 1.253 + * \param szCurrentOut Output data pointer 1.254 + * \param pcMats Material list for this group. To be filled ... 1.255 + */ 1.256 + void ParseSkinLump_3DGS_MDL7( 1.257 + const unsigned char* szCurrent, 1.258 + const unsigned char** szCurrentOut, 1.259 + std::vector<aiMaterial*>& pcMats); 1.260 + 1.261 + // ------------------------------------------------------------------- 1.262 + /** Parse a skin lump in a MDL7/HMP7 file with all of its features 1.263 + * variant 2: Current cursor position is the beginning of the skin data 1.264 + * \param szCurrent Current data pointer 1.265 + * \param szCurrentOut Output data pointer 1.266 + * \param pcMatOut Output material 1.267 + * \param iType header.typ 1.268 + * \param iWidth header.width 1.269 + * \param iHeight header.height 1.270 + */ 1.271 + void ParseSkinLump_3DGS_MDL7( 1.272 + const unsigned char* szCurrent, 1.273 + const unsigned char** szCurrentOut, 1.274 + aiMaterial* pcMatOut, 1.275 + unsigned int iType, 1.276 + unsigned int iWidth, 1.277 + unsigned int iHeight); 1.278 + 1.279 + // ------------------------------------------------------------------- 1.280 + /** Skip a skin lump in a MDL7/HMP7 file 1.281 + * \param szCurrent Current data pointer 1.282 + * \param szCurrentOut Output data pointer. Points to the byte just 1.283 + * behind the last byte of the skin. 1.284 + * \param iType header.typ 1.285 + * \param iWidth header.width 1.286 + * \param iHeight header.height 1.287 + */ 1.288 + void SkipSkinLump_3DGS_MDL7(const unsigned char* szCurrent, 1.289 + const unsigned char** szCurrentOut, 1.290 + unsigned int iType, 1.291 + unsigned int iWidth, 1.292 + unsigned int iHeight); 1.293 + 1.294 + // ------------------------------------------------------------------- 1.295 + /** Parse texture color data for MDL5, MDL6 and MDL7 formats 1.296 + * \param szData Current data pointer 1.297 + * \param iType type of the texture data. No DDS or external 1.298 + * \param piSkip Receive the number of bytes to skip 1.299 + * \param pcNew Must point to fully initialized data. Width and 1.300 + * height must be set. If pcNew->pcData is set to UINT_MAX, 1.301 + * piSkip will receive the size of the texture, in bytes, but no 1.302 + * color data will be read. 1.303 + */ 1.304 + void ParseTextureColorData(const unsigned char* szData, 1.305 + unsigned int iType, 1.306 + unsigned int* piSkip, 1.307 + aiTexture* pcNew); 1.308 + 1.309 + // ------------------------------------------------------------------- 1.310 + /** Join two materials / skins. Setup UV source ... etc 1.311 + * \param pcMat1 First input material 1.312 + * \param pcMat2 Second input material 1.313 + * \param pcMatOut Output material instance to be filled. Must be empty 1.314 + */ 1.315 + void JoinSkins_3DGS_MDL7(aiMaterial* pcMat1, 1.316 + aiMaterial* pcMat2, 1.317 + aiMaterial* pcMatOut); 1.318 + 1.319 + // ------------------------------------------------------------------- 1.320 + /** Add a bone transformation key to an animation 1.321 + * \param iTrafo Index of the transformation (always==frame index?) 1.322 + * No need to validate this index, it is always valid. 1.323 + * \param pcBoneTransforms Bone transformation for this index 1.324 + * \param apcOutBones Output bones array 1.325 + */ 1.326 + void AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo, 1.327 + const MDL::BoneTransform_MDL7* pcBoneTransforms, 1.328 + MDL::IntBone_MDL7** apcBonesOut); 1.329 + 1.330 + // ------------------------------------------------------------------- 1.331 + /** Load the bone list of a MDL7 file 1.332 + * \return If the bones could be loaded successfully, a valid 1.333 + * array containing pointers to a temporary bone 1.334 + * representation. NULL if the bones could not be loaded. 1.335 + */ 1.336 + MDL::IntBone_MDL7** LoadBones_3DGS_MDL7(); 1.337 + 1.338 + // ------------------------------------------------------------------- 1.339 + /** Load bone transformation keyframes from a file chunk 1.340 + * \param groupInfo -> doc of data structure 1.341 + * \param frame -> doc of data structure 1.342 + * \param shared -> doc of data structure 1.343 + */ 1.344 + void ParseBoneTrafoKeys_3DGS_MDL7( 1.345 + const MDL::IntGroupInfo_MDL7& groupInfo, 1.346 + IntFrameInfo_MDL7& frame, 1.347 + MDL::IntSharedData_MDL7& shared); 1.348 + 1.349 + // ------------------------------------------------------------------- 1.350 + /** Calculate absolute bone animation matrices for each bone 1.351 + * \param apcOutBones Output bones array 1.352 + */ 1.353 + void CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones); 1.354 + 1.355 + // ------------------------------------------------------------------- 1.356 + /** Add all bones to the nodegraph (as children of the root node) 1.357 + * \param apcBonesOut List of bones 1.358 + * \param pcParent Parent node. New nodes will be added to this node 1.359 + * \param iParentIndex Index of the parent bone 1.360 + */ 1.361 + void AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut, 1.362 + aiNode* pcParent,uint16_t iParentIndex); 1.363 + 1.364 + // ------------------------------------------------------------------- 1.365 + /** Build output animations 1.366 + * \param apcBonesOut List of bones 1.367 + */ 1.368 + void BuildOutputAnims_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut); 1.369 + 1.370 + // ------------------------------------------------------------------- 1.371 + /** Handles materials that are just referencing another material 1.372 + * There is no test file for this feature, but Conitec's doc 1.373 + * say it is used. 1.374 + */ 1.375 + void HandleMaterialReferences_3DGS_MDL7(); 1.376 + 1.377 + // ------------------------------------------------------------------- 1.378 + /** Copies only the material that are referenced by at least one 1.379 + * mesh to the final output material list. All other materials 1.380 + * will be discarded. 1.381 + * \param shared -> doc of data structure 1.382 + */ 1.383 + void CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared); 1.384 + 1.385 + // ------------------------------------------------------------------- 1.386 + /** Process the frame section at the end of a group 1.387 + * \param groupInfo -> doc of data structure 1.388 + * \param shared -> doc of data structure 1.389 + * \param szCurrent Pointer to the start of the frame section 1.390 + * \param szCurrentOut Receives a pointer to the first byte of the 1.391 + * next data section. 1.392 + * \return false to read no further groups (a small workaround for 1.393 + * some tiny and unsolved problems ... ) 1.394 + */ 1.395 + bool ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo, 1.396 + MDL::IntGroupData_MDL7& groupData, 1.397 + MDL::IntSharedData_MDL7& shared, 1.398 + const unsigned char* szCurrent, 1.399 + const unsigned char** szCurrentOut); 1.400 + 1.401 + // ------------------------------------------------------------------- 1.402 + /** Sort all faces by their materials. If the mesh is using 1.403 + * multiple materials per face (that are blended together) the function 1.404 + * might create new materials. 1.405 + * \param groupInfo -> doc of data structure 1.406 + * \param groupData -> doc of data structure 1.407 + * \param splitGroupData -> doc of data structure 1.408 + */ 1.409 + void SortByMaterials_3DGS_MDL7( 1.410 + const MDL::IntGroupInfo_MDL7& groupInfo, 1.411 + MDL::IntGroupData_MDL7& groupData, 1.412 + MDL::IntSplitGroupData_MDL7& splitGroupData); 1.413 + 1.414 + // ------------------------------------------------------------------- 1.415 + /** Read all faces and vertices from a MDL7 group. The function fills 1.416 + * preallocated memory buffers. 1.417 + * \param groupInfo -> doc of data structure 1.418 + * \param groupData -> doc of data structure 1.419 + */ 1.420 + void ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo, 1.421 + MDL::IntGroupData_MDL7& groupData); 1.422 + 1.423 + // ------------------------------------------------------------------- 1.424 + /** Generate the final output meshes for a7 models 1.425 + * \param groupData -> doc of data structure 1.426 + * \param splitGroupData -> doc of data structure 1.427 + */ 1.428 + void GenerateOutputMeshes_3DGS_MDL7( 1.429 + MDL::IntGroupData_MDL7& groupData, 1.430 + MDL::IntSplitGroupData_MDL7& splitGroupData); 1.431 + 1.432 +protected: 1.433 + 1.434 + /** Configuration option: frame to be loaded */ 1.435 + unsigned int configFrameID; 1.436 + 1.437 + /** Configuration option: palette to be used to decode palletized images*/ 1.438 + std::string configPalette; 1.439 + 1.440 + /** Buffer to hold the loaded file */ 1.441 + unsigned char* mBuffer; 1.442 + 1.443 + /** For GameStudio MDL files: The number in the magic word, either 3,4 or 5 1.444 + * (MDL7 doesn't need this, the format has a separate loader) */ 1.445 + unsigned int iGSFileVersion; 1.446 + 1.447 + /** Output I/O handler. used to load external lmp files */ 1.448 + IOSystem* pIOHandler; 1.449 + 1.450 + /** Output scene to be filled */ 1.451 + aiScene* pScene; 1.452 + 1.453 + /** Size of the input file in bytes */ 1.454 + unsigned int iFileSize; 1.455 +}; 1.456 + 1.457 +} // end of namespace Assimp 1.458 + 1.459 +#endif // AI_3DSIMPORTER_H_INC