1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42/** @file Md3Loader.h
43 * @brief Declaration of the .MD3 importer class.
44 */
45#ifndef AI_MD3LOADER_H_INCLUDED
46#define AI_MD3LOADER_H_INCLUDED
47
48#include "BaseImporter.h"
49#include "ByteSwapper.h"
50#include "MD3FileData.h"
51#include "StringComparison.h"
52#include <assimp/types.h>
53
54#include <list>
55
56struct aiMaterial;
57
58namespace Assimp {
59
60
61using namespace MD3;
62namespace Q3Shader {
63
64// ---------------------------------------------------------------------------
65/** @brief Tiny utility data structure to hold the data of a .skin file
66 */
67struct SkinData
68{
69 //! A single entryin texture list
70 struct TextureEntry : public std::pair<std::string,std::string>
71 {
72 // did we resolve this texture entry?
73 bool resolved;
74
75 // for std::find()
76 bool operator == (const std::string& f) const {
77 return f == first;
78 }
79 };
80
81 //! List of textures
82 std::list<TextureEntry> textures;
83
84 // rest is ignored for the moment
85};
86
87// ---------------------------------------------------------------------------
88/** @brief Specifies cull modi for Quake shader files.
89 */
90enum ShaderCullMode
91{
92 CULL_NONE,
93 CULL_CW,
94 CULL_CCW
95};
96
97// ---------------------------------------------------------------------------
98/** @brief Specifies alpha blend modi (src + dest) for Quake shader files
99 */
100enum BlendFunc
101{
102 BLEND_NONE,
103 BLEND_GL_ONE,
104 BLEND_GL_ZERO,
105 BLEND_GL_DST_COLOR,
106 BLEND_GL_ONE_MINUS_DST_COLOR,
107 BLEND_GL_SRC_ALPHA,
108 BLEND_GL_ONE_MINUS_SRC_ALPHA
109};
110
111// ---------------------------------------------------------------------------
112/** @brief Specifies alpha test modi for Quake texture maps
113 */
114enum AlphaTestFunc
115{
116 AT_NONE,
117 AT_GT0,
118 AT_LT128,
119 AT_GE128
120};
121
122// ---------------------------------------------------------------------------
123/** @brief Tiny utility data structure to hold a .shader map data block
124 */
125struct ShaderMapBlock
126{
127 ShaderMapBlock()
128 : blend_src (BLEND_NONE)
129 , blend_dest (BLEND_NONE)
130 , alpha_test (AT_NONE)
131 {}
132
133 //! Name of referenced map
134 std::string name;
135
136 //! Blend and alpha test settings for texture
137 BlendFunc blend_src,blend_dest;
138 AlphaTestFunc alpha_test;
139
140
141 //! For std::find()
142 bool operator== (const std::string& o) const {
143 return !ASSIMP_stricmp(o,name);
144 }
145};
146
147// ---------------------------------------------------------------------------
148/** @brief Tiny utility data structure to hold a .shader data block
149 */
150struct ShaderDataBlock
151{
152 ShaderDataBlock()
153 : cull (CULL_CW)
154 {}
155
156 //! Name of referenced data element
157 std::string name;
158
159 //! Cull mode for the element
160 ShaderCullMode cull;
161
162 //! Maps defined in the shader
163 std::list<ShaderMapBlock> maps;
164
165
166 //! For std::find()
167 bool operator== (const std::string& o) const {
168 return !ASSIMP_stricmp(o,name);
169 }
170};
171
172// ---------------------------------------------------------------------------
173/** @brief Tiny utility data structure to hold the data of a .shader file
174 */
175struct ShaderData
176{
177 //! Shader data blocks
178 std::list<ShaderDataBlock> blocks;
179};
180
181// ---------------------------------------------------------------------------
182/** @brief Load a shader file
183 *
184 * Generally, parsing is error tolerant. There's no failure.
185 * @param fill Receives output data
186 * @param file File to be read.
187 * @param io IOSystem to be used for reading
188 * @return false if file is not accessible
189 */
190bool LoadShader(ShaderData& fill, const std::string& file,IOSystem* io);
191
192
193// ---------------------------------------------------------------------------
194/** @brief Convert a Q3Shader to an aiMaterial
195 *
196 * @param[out] out Material structure to be filled.
197 * @param[in] shader Input shader
198 */
199void ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& shader);
200
201// ---------------------------------------------------------------------------
202/** @brief Load a skin file
203 *
204 * Generally, parsing is error tolerant. There's no failure.
205 * @param fill Receives output data
206 * @param file File to be read.
207 * @param io IOSystem to be used for reading
208 * @return false if file is not accessible
209 */
210bool LoadSkin(SkinData& fill, const std::string& file,IOSystem* io);
211
212} // ! namespace Q3SHader
213
214// ---------------------------------------------------------------------------
215/** @brief Importer class to load MD3 files
216*/
217class MD3Importer : public BaseImporter
218{
219public:
220 MD3Importer();
221 ~MD3Importer();
222
223
224public:
225
226 // -------------------------------------------------------------------
227 /** Returns whether the class can handle the format of the given file.
228 * See BaseImporter::CanRead() for details. */
229 bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
230 bool checkSig) const;
231
232
233 // -------------------------------------------------------------------
234 /** Called prior to ReadFile().
235 * The function is a request to the importer to update its configuration
236 * basing on the Importer's configuration property list.
237 */
238 void SetupProperties(const Importer* pImp);
239
240protected:
241
242 // -------------------------------------------------------------------
243 /** Return importer meta information.
244 * See #BaseImporter::GetInfo for the details
245 */
246 const aiImporterDesc* GetInfo () const;
247
248 // -------------------------------------------------------------------
249 /** Imports the given file into the given scene structure.
250 * See BaseImporter::InternReadFile() for details
251 */
252 void InternReadFile( const std::string& pFile, aiScene* pScene,
253 IOSystem* pIOHandler);
254
255 // -------------------------------------------------------------------
256 /** Validate offsets in the header
257 */
258 void ValidateHeaderOffsets();
259 void ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurfHeader);
260
261 // -------------------------------------------------------------------
262 /** Read a Q3 multipart file
263 * @return true if multi part has been processed
264 */
265 bool ReadMultipartFile();
266
267 // -------------------------------------------------------------------
268 /** Try to read the skin for a MD3 file
269 * @param fill Receives output information
270 */
271 void ReadSkin(Q3Shader::SkinData& fill) const;
272
273 // -------------------------------------------------------------------
274 /** Try to read the shader for a MD3 file
275 * @param fill Receives output information
276 */
277 void ReadShader(Q3Shader::ShaderData& fill) const;
278
279 // -------------------------------------------------------------------
280 /** Convert a texture path in a MD3 file to a proper value
281 * @param[in] texture_name Path to be converted
282 * @param[in] header_path Base path specified in MD3 header
283 * @param[out] out Receives the converted output string
284 */
285 void ConvertPath(const char* texture_name, const char* header_path,
286 std::string& out) const;
287
288protected:
289
290 /** Configuration option: frame to be loaded */
291 unsigned int configFrameID;
292
293 /** Configuration option: process multi-part files */
294 bool configHandleMP;
295
296 /** Configuration option: name of skin file to be read */
297 std::string configSkinFile;
298
299 /** Configuration option: name or path of shader */
300 std::string configShaderFile;
301
302 /** Configuration option: speed flag was set? */
303 bool configSpeedFlag;
304
305 /** Header of the MD3 file */
306 BE_NCONST MD3::Header* pcHeader;
307
308 /** File buffer */
309 BE_NCONST unsigned char* mBuffer;
310
311 /** Size of the file, in bytes */
312 unsigned int fileSize;
313
314 /** Current file name */
315 std::string mFile;
316
317 /** Current base directory */
318 std::string path;
319
320 /** Pure file we're currently reading */
321 std::string filename;
322
323 /** Output scene to be filled */
324 aiScene* mScene;
325
326 /** IO system to be used to access the data*/
327 IOSystem* mIOHandler;
328 };
329
330} // end of namespace Assimp
331
332#endif // AI_3DSIMPORTER_H_INC
333