rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 ---------------------------------------------------------------------------
|
nuclear@0
|
3 Open Asset Import Library (assimp)
|
nuclear@0
|
4 ---------------------------------------------------------------------------
|
nuclear@0
|
5
|
nuclear@0
|
6 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
7
|
nuclear@0
|
8 All rights reserved.
|
nuclear@0
|
9
|
nuclear@0
|
10 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
11 with or without modification, are permitted provided that the following
|
nuclear@0
|
12 conditions are met:
|
nuclear@0
|
13
|
nuclear@0
|
14 * Redistributions of source code must retain the above
|
nuclear@0
|
15 copyright notice, this list of conditions and the
|
nuclear@0
|
16 following disclaimer.
|
nuclear@0
|
17
|
nuclear@0
|
18 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
19 copyright notice, this list of conditions and the
|
nuclear@0
|
20 following disclaimer in the documentation and/or other
|
nuclear@0
|
21 materials provided with the distribution.
|
nuclear@0
|
22
|
nuclear@0
|
23 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
24 contributors may be used to endorse or promote products
|
nuclear@0
|
25 derived from this software without specific prior
|
nuclear@0
|
26 written permission of the assimp team.
|
nuclear@0
|
27
|
nuclear@0
|
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
39 ---------------------------------------------------------------------------
|
nuclear@0
|
40 */
|
nuclear@0
|
41
|
nuclear@0
|
42 /** @file Implementation of the material part of the MDL importer class */
|
nuclear@0
|
43
|
nuclear@0
|
44 #include "AssimpPCH.h"
|
nuclear@0
|
45 #ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
|
nuclear@0
|
46
|
nuclear@0
|
47 // internal headers
|
nuclear@0
|
48 #include "MDLLoader.h"
|
nuclear@0
|
49 #include "MDLDefaultColorMap.h"
|
nuclear@0
|
50
|
nuclear@0
|
51 using namespace Assimp;
|
nuclear@0
|
52 static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);
|
nuclear@0
|
53
|
nuclear@0
|
54 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
55 // Find a suitable pallette file or take teh default one
|
nuclear@0
|
56 void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
|
nuclear@0
|
57 {
|
nuclear@0
|
58 // now try to find the color map in the current directory
|
nuclear@0
|
59 IOStream* pcStream = pIOHandler->Open(configPalette,"rb");
|
nuclear@0
|
60
|
nuclear@0
|
61 const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
|
nuclear@0
|
62 if(pcStream)
|
nuclear@0
|
63 {
|
nuclear@0
|
64 if (pcStream->FileSize() >= 768)
|
nuclear@0
|
65 {
|
nuclear@0
|
66 unsigned char* colorMap = new unsigned char[256*3];
|
nuclear@0
|
67 szColorMap = colorMap;
|
nuclear@0
|
68 pcStream->Read(colorMap,256*3,1);
|
nuclear@0
|
69 DefaultLogger::get()->info("Found valid colormap.lmp in directory. "
|
nuclear@0
|
70 "It will be used to decode embedded textures in palletized formats.");
|
nuclear@0
|
71 }
|
nuclear@0
|
72 delete pcStream;
|
nuclear@0
|
73 pcStream = NULL;
|
nuclear@0
|
74 }
|
nuclear@0
|
75 *pszColorMap = szColorMap;
|
nuclear@0
|
76 }
|
nuclear@0
|
77
|
nuclear@0
|
78 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
79 // Free the palette again
|
nuclear@0
|
80 void MDLImporter::FreePalette(const unsigned char* szColorMap)
|
nuclear@0
|
81 {
|
nuclear@0
|
82 if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
|
nuclear@0
|
83 delete[] szColorMap;
|
nuclear@0
|
84 }
|
nuclear@0
|
85
|
nuclear@0
|
86 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
87 // Check whether we can replace a texture with a single color
|
nuclear@0
|
88 aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
|
nuclear@0
|
89 {
|
nuclear@0
|
90 ai_assert(NULL != pcTexture);
|
nuclear@0
|
91
|
nuclear@0
|
92 aiColor4D clrOut;
|
nuclear@0
|
93 clrOut.r = get_qnan();
|
nuclear@0
|
94 if (!pcTexture->mHeight || !pcTexture->mWidth)
|
nuclear@0
|
95 return clrOut;
|
nuclear@0
|
96
|
nuclear@0
|
97 const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth;
|
nuclear@0
|
98 const aiTexel* pcTexel = pcTexture->pcData+1;
|
nuclear@0
|
99 const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels];
|
nuclear@0
|
100
|
nuclear@0
|
101 while (pcTexel != pcTexelEnd)
|
nuclear@0
|
102 {
|
nuclear@0
|
103 if (*pcTexel != *(pcTexel-1))
|
nuclear@0
|
104 {
|
nuclear@0
|
105 pcTexel = NULL;
|
nuclear@0
|
106 break;
|
nuclear@0
|
107 }
|
nuclear@0
|
108 ++pcTexel;
|
nuclear@0
|
109 }
|
nuclear@0
|
110 if (pcTexel)
|
nuclear@0
|
111 {
|
nuclear@0
|
112 clrOut.r = pcTexture->pcData->r / 255.0f;
|
nuclear@0
|
113 clrOut.g = pcTexture->pcData->g / 255.0f;
|
nuclear@0
|
114 clrOut.b = pcTexture->pcData->b / 255.0f;
|
nuclear@0
|
115 clrOut.a = pcTexture->pcData->a / 255.0f;
|
nuclear@0
|
116 }
|
nuclear@0
|
117 return clrOut;
|
nuclear@0
|
118 }
|
nuclear@0
|
119
|
nuclear@0
|
120 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
121 // Read a texture from a MDL3 file
|
nuclear@0
|
122 void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
|
nuclear@0
|
123 {
|
nuclear@0
|
124 const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
|
nuclear@0
|
125
|
nuclear@0
|
126 VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
|
nuclear@0
|
127 pcHeader->skinheight);
|
nuclear@0
|
128
|
nuclear@0
|
129 // allocate a new texture object
|
nuclear@0
|
130 aiTexture* pcNew = new aiTexture();
|
nuclear@0
|
131 pcNew->mWidth = pcHeader->skinwidth;
|
nuclear@0
|
132 pcNew->mHeight = pcHeader->skinheight;
|
nuclear@0
|
133
|
nuclear@0
|
134 pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
|
nuclear@0
|
135
|
nuclear@0
|
136 const unsigned char* szColorMap;
|
nuclear@0
|
137 this->SearchPalette(&szColorMap);
|
nuclear@0
|
138
|
nuclear@0
|
139 // copy texture data
|
nuclear@0
|
140 for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
nuclear@0
|
141 {
|
nuclear@0
|
142 const unsigned char val = szData[i];
|
nuclear@0
|
143 const unsigned char* sz = &szColorMap[val*3];
|
nuclear@0
|
144
|
nuclear@0
|
145 pcNew->pcData[i].a = 0xFF;
|
nuclear@0
|
146 pcNew->pcData[i].r = *sz++;
|
nuclear@0
|
147 pcNew->pcData[i].g = *sz++;
|
nuclear@0
|
148 pcNew->pcData[i].b = *sz;
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 FreePalette(szColorMap);
|
nuclear@0
|
152
|
nuclear@0
|
153 // store the texture
|
nuclear@0
|
154 aiTexture** pc = this->pScene->mTextures;
|
nuclear@0
|
155 this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
|
nuclear@0
|
156 for (unsigned int i = 0; i <pScene->mNumTextures;++i)
|
nuclear@0
|
157 pScene->mTextures[i] = pc[i];
|
nuclear@0
|
158
|
nuclear@0
|
159 pScene->mTextures[this->pScene->mNumTextures] = pcNew;
|
nuclear@0
|
160 pScene->mNumTextures++;
|
nuclear@0
|
161 delete[] pc;
|
nuclear@0
|
162 return;
|
nuclear@0
|
163 }
|
nuclear@0
|
164
|
nuclear@0
|
165 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
166 // Read a texture from a MDL4 file
|
nuclear@0
|
167 void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
|
nuclear@0
|
168 unsigned int iType,
|
nuclear@0
|
169 unsigned int* piSkip)
|
nuclear@0
|
170 {
|
nuclear@0
|
171 ai_assert(NULL != piSkip);
|
nuclear@0
|
172
|
nuclear@0
|
173 const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function
|
nuclear@0
|
174
|
nuclear@0
|
175 if (iType == 1 || iType > 3)
|
nuclear@0
|
176 {
|
nuclear@0
|
177 DefaultLogger::get()->error("Unsupported texture file format");
|
nuclear@0
|
178 return;
|
nuclear@0
|
179 }
|
nuclear@0
|
180
|
nuclear@0
|
181 const bool bNoRead = *piSkip == UINT_MAX;
|
nuclear@0
|
182
|
nuclear@0
|
183 // allocate a new texture object
|
nuclear@0
|
184 aiTexture* pcNew = new aiTexture();
|
nuclear@0
|
185 pcNew->mWidth = pcHeader->skinwidth;
|
nuclear@0
|
186 pcNew->mHeight = pcHeader->skinheight;
|
nuclear@0
|
187
|
nuclear@0
|
188 if (bNoRead)pcNew->pcData = bad_texel;
|
nuclear@0
|
189 ParseTextureColorData(szData,iType,piSkip,pcNew);
|
nuclear@0
|
190
|
nuclear@0
|
191 // store the texture
|
nuclear@0
|
192 if (!bNoRead)
|
nuclear@0
|
193 {
|
nuclear@0
|
194 if (!this->pScene->mNumTextures)
|
nuclear@0
|
195 {
|
nuclear@0
|
196 pScene->mNumTextures = 1;
|
nuclear@0
|
197 pScene->mTextures = new aiTexture*[1];
|
nuclear@0
|
198 pScene->mTextures[0] = pcNew;
|
nuclear@0
|
199 }
|
nuclear@0
|
200 else
|
nuclear@0
|
201 {
|
nuclear@0
|
202 aiTexture** pc = pScene->mTextures;
|
nuclear@0
|
203 pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
|
nuclear@0
|
204 for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
|
nuclear@0
|
205 pScene->mTextures[i] = pc[i];
|
nuclear@0
|
206 pScene->mTextures[pScene->mNumTextures] = pcNew;
|
nuclear@0
|
207 pScene->mNumTextures++;
|
nuclear@0
|
208 delete[] pc;
|
nuclear@0
|
209 }
|
nuclear@0
|
210 }
|
nuclear@0
|
211 else {
|
nuclear@0
|
212 pcNew->pcData = NULL;
|
nuclear@0
|
213 delete pcNew;
|
nuclear@0
|
214 }
|
nuclear@0
|
215 return;
|
nuclear@0
|
216 }
|
nuclear@0
|
217
|
nuclear@0
|
218 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
219 // Load color data of a texture and convert it to our output format
|
nuclear@0
|
220 void MDLImporter::ParseTextureColorData(const unsigned char* szData,
|
nuclear@0
|
221 unsigned int iType,
|
nuclear@0
|
222 unsigned int* piSkip,
|
nuclear@0
|
223 aiTexture* pcNew)
|
nuclear@0
|
224 {
|
nuclear@0
|
225 const bool do_read = bad_texel != pcNew->pcData;
|
nuclear@0
|
226
|
nuclear@0
|
227 // allocate storage for the texture image
|
nuclear@0
|
228 if (do_read) {
|
nuclear@0
|
229 pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
|
nuclear@0
|
230 }
|
nuclear@0
|
231
|
nuclear@0
|
232 // R5G6B5 format (with or without MIPs)
|
nuclear@0
|
233 // ****************************************************************
|
nuclear@0
|
234 if (2 == iType || 10 == iType)
|
nuclear@0
|
235 {
|
nuclear@0
|
236 VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2);
|
nuclear@0
|
237
|
nuclear@0
|
238 // copy texture data
|
nuclear@0
|
239 unsigned int i;
|
nuclear@0
|
240 if (do_read)
|
nuclear@0
|
241 {
|
nuclear@0
|
242 for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
nuclear@0
|
243 {
|
nuclear@0
|
244 MDL::RGB565 val = ((MDL::RGB565*)szData)[i];
|
nuclear@0
|
245 AI_SWAP2(val);
|
nuclear@0
|
246
|
nuclear@0
|
247 pcNew->pcData[i].a = 0xFF;
|
nuclear@0
|
248 pcNew->pcData[i].r = (unsigned char)val.b << 3;
|
nuclear@0
|
249 pcNew->pcData[i].g = (unsigned char)val.g << 2;
|
nuclear@0
|
250 pcNew->pcData[i].b = (unsigned char)val.r << 3;
|
nuclear@0
|
251 }
|
nuclear@0
|
252 }
|
nuclear@0
|
253 else i = pcNew->mWidth*pcNew->mHeight;
|
nuclear@0
|
254 *piSkip = i * 2;
|
nuclear@0
|
255
|
nuclear@0
|
256 // apply MIP maps
|
nuclear@0
|
257 if (10 == iType)
|
nuclear@0
|
258 {
|
nuclear@0
|
259 *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
|
nuclear@0
|
260 VALIDATE_FILE_SIZE(szData + *piSkip);
|
nuclear@0
|
261 }
|
nuclear@0
|
262 }
|
nuclear@0
|
263 // ARGB4 format (with or without MIPs)
|
nuclear@0
|
264 // ****************************************************************
|
nuclear@0
|
265 else if (3 == iType || 11 == iType)
|
nuclear@0
|
266 {
|
nuclear@0
|
267 VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
|
nuclear@0
|
268
|
nuclear@0
|
269 // copy texture data
|
nuclear@0
|
270 unsigned int i;
|
nuclear@0
|
271 if (do_read)
|
nuclear@0
|
272 {
|
nuclear@0
|
273 for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
nuclear@0
|
274 {
|
nuclear@0
|
275 MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i];
|
nuclear@0
|
276 AI_SWAP2(val);
|
nuclear@0
|
277
|
nuclear@0
|
278 pcNew->pcData[i].a = (unsigned char)val.a << 4;
|
nuclear@0
|
279 pcNew->pcData[i].r = (unsigned char)val.r << 4;
|
nuclear@0
|
280 pcNew->pcData[i].g = (unsigned char)val.g << 4;
|
nuclear@0
|
281 pcNew->pcData[i].b = (unsigned char)val.b << 4;
|
nuclear@0
|
282 }
|
nuclear@0
|
283 }
|
nuclear@0
|
284 else i = pcNew->mWidth*pcNew->mHeight;
|
nuclear@0
|
285 *piSkip = i * 2;
|
nuclear@0
|
286
|
nuclear@0
|
287 // apply MIP maps
|
nuclear@0
|
288 if (11 == iType)
|
nuclear@0
|
289 {
|
nuclear@0
|
290 *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
|
nuclear@0
|
291 VALIDATE_FILE_SIZE(szData + *piSkip);
|
nuclear@0
|
292 }
|
nuclear@0
|
293 }
|
nuclear@0
|
294 // RGB8 format (with or without MIPs)
|
nuclear@0
|
295 // ****************************************************************
|
nuclear@0
|
296 else if (4 == iType || 12 == iType)
|
nuclear@0
|
297 {
|
nuclear@0
|
298 VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3);
|
nuclear@0
|
299
|
nuclear@0
|
300 // copy texture data
|
nuclear@0
|
301 unsigned int i;
|
nuclear@0
|
302 if (do_read)
|
nuclear@0
|
303 {
|
nuclear@0
|
304 for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
nuclear@0
|
305 {
|
nuclear@0
|
306 const unsigned char* _szData = &szData[i*3];
|
nuclear@0
|
307
|
nuclear@0
|
308 pcNew->pcData[i].a = 0xFF;
|
nuclear@0
|
309 pcNew->pcData[i].b = *_szData++;
|
nuclear@0
|
310 pcNew->pcData[i].g = *_szData++;
|
nuclear@0
|
311 pcNew->pcData[i].r = *_szData;
|
nuclear@0
|
312 }
|
nuclear@0
|
313 }
|
nuclear@0
|
314 else i = pcNew->mWidth*pcNew->mHeight;
|
nuclear@0
|
315
|
nuclear@0
|
316
|
nuclear@0
|
317 // apply MIP maps
|
nuclear@0
|
318 *piSkip = i * 3;
|
nuclear@0
|
319 if (12 == iType)
|
nuclear@0
|
320 {
|
nuclear@0
|
321 *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3;
|
nuclear@0
|
322 VALIDATE_FILE_SIZE(szData + *piSkip);
|
nuclear@0
|
323 }
|
nuclear@0
|
324 }
|
nuclear@0
|
325 // ARGB8 format (with ir without MIPs)
|
nuclear@0
|
326 // ****************************************************************
|
nuclear@0
|
327 else if (5 == iType || 13 == iType)
|
nuclear@0
|
328 {
|
nuclear@0
|
329 VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
|
nuclear@0
|
330
|
nuclear@0
|
331 // copy texture data
|
nuclear@0
|
332 unsigned int i;
|
nuclear@0
|
333 if (do_read)
|
nuclear@0
|
334 {
|
nuclear@0
|
335 for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
nuclear@0
|
336 {
|
nuclear@0
|
337 const unsigned char* _szData = &szData[i*4];
|
nuclear@0
|
338
|
nuclear@0
|
339 pcNew->pcData[i].b = *_szData++;
|
nuclear@0
|
340 pcNew->pcData[i].g = *_szData++;
|
nuclear@0
|
341 pcNew->pcData[i].r = *_szData++;
|
nuclear@0
|
342 pcNew->pcData[i].a = *_szData;
|
nuclear@0
|
343 }
|
nuclear@0
|
344 }
|
nuclear@0
|
345 else i = pcNew->mWidth*pcNew->mHeight;
|
nuclear@0
|
346
|
nuclear@0
|
347 // apply MIP maps
|
nuclear@0
|
348 *piSkip = i << 2;
|
nuclear@0
|
349 if (13 == iType)
|
nuclear@0
|
350 {
|
nuclear@0
|
351 *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
|
nuclear@0
|
352 }
|
nuclear@0
|
353 }
|
nuclear@0
|
354 // palletized 8 bit texture. As for Quake 1
|
nuclear@0
|
355 // ****************************************************************
|
nuclear@0
|
356 else if (0 == iType)
|
nuclear@0
|
357 {
|
nuclear@0
|
358 VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight);
|
nuclear@0
|
359
|
nuclear@0
|
360 // copy texture data
|
nuclear@0
|
361 unsigned int i;
|
nuclear@0
|
362 if (do_read)
|
nuclear@0
|
363 {
|
nuclear@0
|
364
|
nuclear@0
|
365 const unsigned char* szColorMap;
|
nuclear@0
|
366 SearchPalette(&szColorMap);
|
nuclear@0
|
367
|
nuclear@0
|
368 for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
|
nuclear@0
|
369 {
|
nuclear@0
|
370 const unsigned char val = szData[i];
|
nuclear@0
|
371 const unsigned char* sz = &szColorMap[val*3];
|
nuclear@0
|
372
|
nuclear@0
|
373 pcNew->pcData[i].a = 0xFF;
|
nuclear@0
|
374 pcNew->pcData[i].r = *sz++;
|
nuclear@0
|
375 pcNew->pcData[i].g = *sz++;
|
nuclear@0
|
376 pcNew->pcData[i].b = *sz;
|
nuclear@0
|
377 }
|
nuclear@0
|
378 this->FreePalette(szColorMap);
|
nuclear@0
|
379
|
nuclear@0
|
380 }
|
nuclear@0
|
381 else i = pcNew->mWidth*pcNew->mHeight;
|
nuclear@0
|
382 *piSkip = i;
|
nuclear@0
|
383
|
nuclear@0
|
384 // FIXME: Also support for MIP maps?
|
nuclear@0
|
385 }
|
nuclear@0
|
386 }
|
nuclear@0
|
387
|
nuclear@0
|
388 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
389 // Get a texture from a MDL5 file
|
nuclear@0
|
390 void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
|
nuclear@0
|
391 unsigned int iType,
|
nuclear@0
|
392 unsigned int* piSkip)
|
nuclear@0
|
393 {
|
nuclear@0
|
394 ai_assert(NULL != piSkip);
|
nuclear@0
|
395 bool bNoRead = *piSkip == UINT_MAX;
|
nuclear@0
|
396
|
nuclear@0
|
397 // allocate a new texture object
|
nuclear@0
|
398 aiTexture* pcNew = new aiTexture();
|
nuclear@0
|
399
|
nuclear@0
|
400 VALIDATE_FILE_SIZE(szData+8);
|
nuclear@0
|
401
|
nuclear@0
|
402 // first read the size of the texture
|
nuclear@0
|
403 pcNew->mWidth = *((uint32_t*)szData);
|
nuclear@0
|
404 AI_SWAP4(pcNew->mWidth);
|
nuclear@0
|
405 szData += sizeof(uint32_t);
|
nuclear@0
|
406
|
nuclear@0
|
407 pcNew->mHeight = *((uint32_t*)szData);
|
nuclear@0
|
408 AI_SWAP4(pcNew->mHeight);
|
nuclear@0
|
409 szData += sizeof(uint32_t);
|
nuclear@0
|
410
|
nuclear@0
|
411 if (bNoRead) {
|
nuclear@0
|
412 pcNew->pcData = bad_texel;
|
nuclear@0
|
413 }
|
nuclear@0
|
414
|
nuclear@0
|
415 // this should not occur - at least the docs say it shouldn't.
|
nuclear@0
|
416 // however, one can easily try out what MED does if you have
|
nuclear@0
|
417 // a model with a DDS texture and export it to MDL5 ...
|
nuclear@0
|
418 // yeah, it embedds the DDS file.
|
nuclear@0
|
419 if (6 == iType)
|
nuclear@0
|
420 {
|
nuclear@0
|
421 // this is a compressed texture in DDS format
|
nuclear@0
|
422 *piSkip = pcNew->mWidth;
|
nuclear@0
|
423 VALIDATE_FILE_SIZE(szData + *piSkip);
|
nuclear@0
|
424
|
nuclear@0
|
425 if (!bNoRead)
|
nuclear@0
|
426 {
|
nuclear@0
|
427 // place a hint and let the application know that this is a DDS file
|
nuclear@0
|
428 pcNew->mHeight = 0;
|
nuclear@0
|
429 pcNew->achFormatHint[0] = 'd';
|
nuclear@0
|
430 pcNew->achFormatHint[1] = 'd';
|
nuclear@0
|
431 pcNew->achFormatHint[2] = 's';
|
nuclear@0
|
432 pcNew->achFormatHint[3] = '\0';
|
nuclear@0
|
433
|
nuclear@0
|
434 pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
|
nuclear@0
|
435 ::memcpy(pcNew->pcData,szData,pcNew->mWidth);
|
nuclear@0
|
436 }
|
nuclear@0
|
437 }
|
nuclear@0
|
438 else
|
nuclear@0
|
439 {
|
nuclear@0
|
440 // parse the color data of the texture
|
nuclear@0
|
441 ParseTextureColorData(szData,iType,piSkip,pcNew);
|
nuclear@0
|
442 }
|
nuclear@0
|
443 *piSkip += sizeof(uint32_t) * 2;
|
nuclear@0
|
444
|
nuclear@0
|
445 if (!bNoRead)
|
nuclear@0
|
446 {
|
nuclear@0
|
447 // store the texture
|
nuclear@0
|
448 if (!this->pScene->mNumTextures)
|
nuclear@0
|
449 {
|
nuclear@0
|
450 pScene->mNumTextures = 1;
|
nuclear@0
|
451 pScene->mTextures = new aiTexture*[1];
|
nuclear@0
|
452 pScene->mTextures[0] = pcNew;
|
nuclear@0
|
453 }
|
nuclear@0
|
454 else
|
nuclear@0
|
455 {
|
nuclear@0
|
456 aiTexture** pc = pScene->mTextures;
|
nuclear@0
|
457 pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
|
nuclear@0
|
458 for (unsigned int i = 0; i < pScene->mNumTextures;++i)
|
nuclear@0
|
459 this->pScene->mTextures[i] = pc[i];
|
nuclear@0
|
460
|
nuclear@0
|
461 pScene->mTextures[pScene->mNumTextures] = pcNew;
|
nuclear@0
|
462 pScene->mNumTextures++;
|
nuclear@0
|
463 delete[] pc;
|
nuclear@0
|
464 }
|
nuclear@0
|
465 }
|
nuclear@0
|
466 else {
|
nuclear@0
|
467 pcNew->pcData = NULL;
|
nuclear@0
|
468 delete pcNew;
|
nuclear@0
|
469 }
|
nuclear@0
|
470 return;
|
nuclear@0
|
471 }
|
nuclear@0
|
472
|
nuclear@0
|
473 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
474 // Get a skin from a MDL7 file - more complex than all other subformats
|
nuclear@0
|
475 void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
nuclear@0
|
476 const unsigned char* szCurrent,
|
nuclear@0
|
477 const unsigned char** szCurrentOut,
|
nuclear@0
|
478 aiMaterial* pcMatOut,
|
nuclear@0
|
479 unsigned int iType,
|
nuclear@0
|
480 unsigned int iWidth,
|
nuclear@0
|
481 unsigned int iHeight)
|
nuclear@0
|
482 {
|
nuclear@0
|
483 aiTexture* pcNew = NULL;
|
nuclear@0
|
484
|
nuclear@0
|
485 // get the type of the skin
|
nuclear@0
|
486 unsigned int iMasked = (unsigned int)(iType & 0xF);
|
nuclear@0
|
487
|
nuclear@0
|
488 if (0x1 == iMasked)
|
nuclear@0
|
489 {
|
nuclear@0
|
490 // ***** REFERENCE TO ANOTHER SKIN INDEX *****
|
nuclear@0
|
491 int referrer = (int)iWidth;
|
nuclear@0
|
492 pcMatOut->AddProperty<int>(&referrer,1,AI_MDL7_REFERRER_MATERIAL);
|
nuclear@0
|
493 }
|
nuclear@0
|
494 else if (0x6 == iMasked)
|
nuclear@0
|
495 {
|
nuclear@0
|
496 // ***** EMBEDDED DDS FILE *****
|
nuclear@0
|
497 if (1 != iHeight)
|
nuclear@0
|
498 {
|
nuclear@0
|
499 DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
|
nuclear@0
|
500 "but texture height is not equal to 1, which is not supported by MED");
|
nuclear@0
|
501 }
|
nuclear@0
|
502
|
nuclear@0
|
503 pcNew = new aiTexture();
|
nuclear@0
|
504 pcNew->mHeight = 0;
|
nuclear@0
|
505 pcNew->mWidth = iWidth;
|
nuclear@0
|
506
|
nuclear@0
|
507 // place a proper format hint
|
nuclear@0
|
508 pcNew->achFormatHint[0] = 'd';
|
nuclear@0
|
509 pcNew->achFormatHint[1] = 'd';
|
nuclear@0
|
510 pcNew->achFormatHint[2] = 's';
|
nuclear@0
|
511 pcNew->achFormatHint[3] = '\0';
|
nuclear@0
|
512
|
nuclear@0
|
513 pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
|
nuclear@0
|
514 memcpy(pcNew->pcData,szCurrent,pcNew->mWidth);
|
nuclear@0
|
515 szCurrent += iWidth;
|
nuclear@0
|
516 }
|
nuclear@0
|
517 if (0x7 == iMasked)
|
nuclear@0
|
518 {
|
nuclear@0
|
519 // ***** REFERENCE TO EXTERNAL FILE *****
|
nuclear@0
|
520 if (1 != iHeight)
|
nuclear@0
|
521 {
|
nuclear@0
|
522 DefaultLogger::get()->warn("Found a reference to an external texture, "
|
nuclear@0
|
523 "but texture height is not equal to 1, which is not supported by MED");
|
nuclear@0
|
524 }
|
nuclear@0
|
525
|
nuclear@0
|
526 aiString szFile;
|
nuclear@0
|
527 const size_t iLen = strlen((const char*)szCurrent);
|
nuclear@0
|
528 size_t iLen2 = iLen+1;
|
nuclear@0
|
529 iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
|
nuclear@0
|
530 memcpy(szFile.data,(const char*)szCurrent,iLen2);
|
nuclear@0
|
531 szFile.length = iLen;
|
nuclear@0
|
532
|
nuclear@0
|
533 szCurrent += iLen2;
|
nuclear@0
|
534
|
nuclear@0
|
535 // place this as diffuse texture
|
nuclear@0
|
536 pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
nuclear@0
|
537 }
|
nuclear@0
|
538 else if (iMasked || !iType || (iType && iWidth && iHeight))
|
nuclear@0
|
539 {
|
nuclear@0
|
540 // ***** STANDARD COLOR TEXTURE *****
|
nuclear@0
|
541 pcNew = new aiTexture();
|
nuclear@0
|
542 if (!iHeight || !iWidth)
|
nuclear@0
|
543 {
|
nuclear@0
|
544 DefaultLogger::get()->warn("Found embedded texture, but its width "
|
nuclear@0
|
545 "an height are both 0. Is this a joke?");
|
nuclear@0
|
546
|
nuclear@0
|
547 // generate an empty chess pattern
|
nuclear@0
|
548 pcNew->mWidth = pcNew->mHeight = 8;
|
nuclear@0
|
549 pcNew->pcData = new aiTexel[64];
|
nuclear@0
|
550 for (unsigned int x = 0; x < 8;++x)
|
nuclear@0
|
551 {
|
nuclear@0
|
552 for (unsigned int y = 0; y < 8;++y)
|
nuclear@0
|
553 {
|
nuclear@0
|
554 const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
|
nuclear@0
|
555 (0 != x % 2 && 0 == y % 2));
|
nuclear@0
|
556
|
nuclear@0
|
557 aiTexel* pc = &pcNew->pcData[y * 8 + x];
|
nuclear@0
|
558 pc->r = pc->b = pc->g = (bSet?0xFF:0);
|
nuclear@0
|
559 pc->a = 0xFF;
|
nuclear@0
|
560 }
|
nuclear@0
|
561 }
|
nuclear@0
|
562 }
|
nuclear@0
|
563 else
|
nuclear@0
|
564 {
|
nuclear@0
|
565 // it is a standard color texture. Fill in width and height
|
nuclear@0
|
566 // and call the same function we used for loading MDL5 files
|
nuclear@0
|
567
|
nuclear@0
|
568 pcNew->mWidth = iWidth;
|
nuclear@0
|
569 pcNew->mHeight = iHeight;
|
nuclear@0
|
570
|
nuclear@0
|
571 unsigned int iSkip = 0;
|
nuclear@0
|
572 ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
|
nuclear@0
|
573
|
nuclear@0
|
574 // skip length of texture data
|
nuclear@0
|
575 szCurrent += iSkip;
|
nuclear@0
|
576 }
|
nuclear@0
|
577 }
|
nuclear@0
|
578
|
nuclear@0
|
579 // sometimes there are MDL7 files which have a monochrome
|
nuclear@0
|
580 // texture instead of material colors ... posssible they have
|
nuclear@0
|
581 // been converted to MDL7 from other formats, such as MDL5
|
nuclear@0
|
582 aiColor4D clrTexture;
|
nuclear@0
|
583 if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew);
|
nuclear@0
|
584 else clrTexture.r = get_qnan();
|
nuclear@0
|
585
|
nuclear@0
|
586 // check whether a material definition is contained in the skin
|
nuclear@0
|
587 if (iType & AI_MDL7_SKINTYPE_MATERIAL)
|
nuclear@0
|
588 {
|
nuclear@0
|
589 BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
|
nuclear@0
|
590 szCurrent = (unsigned char*)(pcMatIn+1);
|
nuclear@0
|
591 VALIDATE_FILE_SIZE(szCurrent);
|
nuclear@0
|
592
|
nuclear@0
|
593 aiColor3D clrTemp;
|
nuclear@0
|
594
|
nuclear@0
|
595 #define COLOR_MULTIPLY_RGB() \
|
nuclear@0
|
596 if (is_not_qnan(clrTexture.r)) \
|
nuclear@0
|
597 { \
|
nuclear@0
|
598 clrTemp.r *= clrTexture.r; \
|
nuclear@0
|
599 clrTemp.g *= clrTexture.g; \
|
nuclear@0
|
600 clrTemp.b *= clrTexture.b; \
|
nuclear@0
|
601 }
|
nuclear@0
|
602
|
nuclear@0
|
603 // read diffuse color
|
nuclear@0
|
604 clrTemp.r = pcMatIn->Diffuse.r;
|
nuclear@0
|
605 AI_SWAP4(clrTemp.r);
|
nuclear@0
|
606 clrTemp.g = pcMatIn->Diffuse.g;
|
nuclear@0
|
607 AI_SWAP4(clrTemp.g);
|
nuclear@0
|
608 clrTemp.b = pcMatIn->Diffuse.b;
|
nuclear@0
|
609 AI_SWAP4(clrTemp.b);
|
nuclear@0
|
610 COLOR_MULTIPLY_RGB();
|
nuclear@0
|
611 pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE);
|
nuclear@0
|
612
|
nuclear@0
|
613 // read specular color
|
nuclear@0
|
614 clrTemp.r = pcMatIn->Specular.r;
|
nuclear@0
|
615 AI_SWAP4(clrTemp.r);
|
nuclear@0
|
616 clrTemp.g = pcMatIn->Specular.g;
|
nuclear@0
|
617 AI_SWAP4(clrTemp.g);
|
nuclear@0
|
618 clrTemp.b = pcMatIn->Specular.b;
|
nuclear@0
|
619 AI_SWAP4(clrTemp.b);
|
nuclear@0
|
620 COLOR_MULTIPLY_RGB();
|
nuclear@0
|
621 pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR);
|
nuclear@0
|
622
|
nuclear@0
|
623 // read ambient color
|
nuclear@0
|
624 clrTemp.r = pcMatIn->Ambient.r;
|
nuclear@0
|
625 AI_SWAP4(clrTemp.r);
|
nuclear@0
|
626 clrTemp.g = pcMatIn->Ambient.g;
|
nuclear@0
|
627 AI_SWAP4(clrTemp.g);
|
nuclear@0
|
628 clrTemp.b = pcMatIn->Ambient.b;
|
nuclear@0
|
629 AI_SWAP4(clrTemp.b);
|
nuclear@0
|
630 COLOR_MULTIPLY_RGB();
|
nuclear@0
|
631 pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT);
|
nuclear@0
|
632
|
nuclear@0
|
633 // read emissive color
|
nuclear@0
|
634 clrTemp.r = pcMatIn->Emissive.r;
|
nuclear@0
|
635 AI_SWAP4(clrTemp.r);
|
nuclear@0
|
636 clrTemp.g = pcMatIn->Emissive.g;
|
nuclear@0
|
637 AI_SWAP4(clrTemp.g);
|
nuclear@0
|
638 clrTemp.b = pcMatIn->Emissive.b;
|
nuclear@0
|
639 AI_SWAP4(clrTemp.b);
|
nuclear@0
|
640 pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE);
|
nuclear@0
|
641
|
nuclear@0
|
642 #undef COLOR_MULITPLY_RGB
|
nuclear@0
|
643
|
nuclear@0
|
644 // FIX: Take the opacity from the ambient color.
|
nuclear@0
|
645 // The doc say something else, but it is fact that MED exports the
|
nuclear@0
|
646 // opacity like this .... oh well.
|
nuclear@0
|
647 clrTemp.r = pcMatIn->Ambient.a;
|
nuclear@0
|
648 AI_SWAP4(clrTemp.r);
|
nuclear@0
|
649 if (is_not_qnan(clrTexture.r)) {
|
nuclear@0
|
650 clrTemp.r *= clrTexture.a;
|
nuclear@0
|
651 }
|
nuclear@0
|
652 pcMatOut->AddProperty<float>(&clrTemp.r,1,AI_MATKEY_OPACITY);
|
nuclear@0
|
653
|
nuclear@0
|
654 // read phong power
|
nuclear@0
|
655 int iShadingMode = (int)aiShadingMode_Gouraud;
|
nuclear@0
|
656 AI_SWAP4(pcMatIn->Power);
|
nuclear@0
|
657 if (0.0f != pcMatIn->Power)
|
nuclear@0
|
658 {
|
nuclear@0
|
659 iShadingMode = (int)aiShadingMode_Phong;
|
nuclear@0
|
660 pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
|
nuclear@0
|
661 }
|
nuclear@0
|
662 pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
|
nuclear@0
|
663 }
|
nuclear@0
|
664 else if (is_not_qnan(clrTexture.r))
|
nuclear@0
|
665 {
|
nuclear@0
|
666 pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE);
|
nuclear@0
|
667 pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR);
|
nuclear@0
|
668 }
|
nuclear@0
|
669 // if the texture could be replaced by a single material color
|
nuclear@0
|
670 // we don't need the texture anymore
|
nuclear@0
|
671 if (is_not_qnan(clrTexture.r))
|
nuclear@0
|
672 {
|
nuclear@0
|
673 delete pcNew;
|
nuclear@0
|
674 pcNew = NULL;
|
nuclear@0
|
675 }
|
nuclear@0
|
676
|
nuclear@0
|
677 // If an ASCII effect description (HLSL?) is contained in the file,
|
nuclear@0
|
678 // we can simply ignore it ...
|
nuclear@0
|
679 if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
|
nuclear@0
|
680 {
|
nuclear@0
|
681 VALIDATE_FILE_SIZE(szCurrent);
|
nuclear@0
|
682 int32_t iMe = *((int32_t*)szCurrent);
|
nuclear@0
|
683 AI_SWAP4(iMe);
|
nuclear@0
|
684 szCurrent += sizeof(char) * iMe + sizeof(int32_t);
|
nuclear@0
|
685 VALIDATE_FILE_SIZE(szCurrent);
|
nuclear@0
|
686 }
|
nuclear@0
|
687
|
nuclear@0
|
688 // If an embedded texture has been loaded setup the corresponding
|
nuclear@0
|
689 // data structures in the aiScene instance
|
nuclear@0
|
690 if (pcNew && pScene->mNumTextures <= 999)
|
nuclear@0
|
691 {
|
nuclear@0
|
692
|
nuclear@0
|
693 // place this as diffuse texture
|
nuclear@0
|
694 char szCurrent[5];
|
nuclear@0
|
695 ::sprintf(szCurrent,"*%i",this->pScene->mNumTextures);
|
nuclear@0
|
696
|
nuclear@0
|
697 aiString szFile;
|
nuclear@0
|
698 const size_t iLen = strlen((const char*)szCurrent);
|
nuclear@0
|
699 ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
|
nuclear@0
|
700 szFile.length = iLen;
|
nuclear@0
|
701
|
nuclear@0
|
702 pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
nuclear@0
|
703
|
nuclear@0
|
704 // store the texture
|
nuclear@0
|
705 if (!pScene->mNumTextures)
|
nuclear@0
|
706 {
|
nuclear@0
|
707 pScene->mNumTextures = 1;
|
nuclear@0
|
708 pScene->mTextures = new aiTexture*[1];
|
nuclear@0
|
709 pScene->mTextures[0] = pcNew;
|
nuclear@0
|
710 }
|
nuclear@0
|
711 else
|
nuclear@0
|
712 {
|
nuclear@0
|
713 aiTexture** pc = pScene->mTextures;
|
nuclear@0
|
714 pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
|
nuclear@0
|
715 for (unsigned int i = 0; i < pScene->mNumTextures;++i) {
|
nuclear@0
|
716 pScene->mTextures[i] = pc[i];
|
nuclear@0
|
717 }
|
nuclear@0
|
718
|
nuclear@0
|
719 pScene->mTextures[pScene->mNumTextures] = pcNew;
|
nuclear@0
|
720 pScene->mNumTextures++;
|
nuclear@0
|
721 delete[] pc;
|
nuclear@0
|
722 }
|
nuclear@0
|
723 }
|
nuclear@0
|
724 VALIDATE_FILE_SIZE(szCurrent);
|
nuclear@0
|
725 *szCurrentOut = szCurrent;
|
nuclear@0
|
726 }
|
nuclear@0
|
727
|
nuclear@0
|
728 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
729 // Skip a skin lump
|
nuclear@0
|
730 void MDLImporter::SkipSkinLump_3DGS_MDL7(
|
nuclear@0
|
731 const unsigned char* szCurrent,
|
nuclear@0
|
732 const unsigned char** szCurrentOut,
|
nuclear@0
|
733 unsigned int iType,
|
nuclear@0
|
734 unsigned int iWidth,
|
nuclear@0
|
735 unsigned int iHeight)
|
nuclear@0
|
736 {
|
nuclear@0
|
737 // get the type of the skin
|
nuclear@0
|
738 const unsigned int iMasked = (unsigned int)(iType & 0xF);
|
nuclear@0
|
739
|
nuclear@0
|
740 if (0x6 == iMasked)
|
nuclear@0
|
741 {
|
nuclear@0
|
742 szCurrent += iWidth;
|
nuclear@0
|
743 }
|
nuclear@0
|
744 if (0x7 == iMasked)
|
nuclear@0
|
745 {
|
nuclear@0
|
746 const size_t iLen = ::strlen((const char*)szCurrent);
|
nuclear@0
|
747 szCurrent += iLen+1;
|
nuclear@0
|
748 }
|
nuclear@0
|
749 else if (iMasked || !iType)
|
nuclear@0
|
750 {
|
nuclear@0
|
751 if (iMasked || !iType || (iType && iWidth && iHeight))
|
nuclear@0
|
752 {
|
nuclear@0
|
753 // ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply
|
nuclear@0
|
754 // return the size of the color data in bytes in iSkip
|
nuclear@0
|
755 unsigned int iSkip = 0;
|
nuclear@0
|
756
|
nuclear@0
|
757 aiTexture tex;
|
nuclear@0
|
758 tex.pcData = bad_texel;
|
nuclear@0
|
759 tex.mHeight = iHeight;
|
nuclear@0
|
760 tex.mWidth = iWidth;
|
nuclear@0
|
761 ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex);
|
nuclear@0
|
762
|
nuclear@0
|
763 // FIX: Important, otherwise the destructor will crash
|
nuclear@0
|
764 tex.pcData = NULL;
|
nuclear@0
|
765
|
nuclear@0
|
766 // skip length of texture data
|
nuclear@0
|
767 szCurrent += iSkip;
|
nuclear@0
|
768 }
|
nuclear@0
|
769 }
|
nuclear@0
|
770
|
nuclear@0
|
771 // check whether a material definition is contained in the skin
|
nuclear@0
|
772 if (iType & AI_MDL7_SKINTYPE_MATERIAL)
|
nuclear@0
|
773 {
|
nuclear@0
|
774 BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
|
nuclear@0
|
775 szCurrent = (unsigned char*)(pcMatIn+1);
|
nuclear@0
|
776 }
|
nuclear@0
|
777
|
nuclear@0
|
778 // if an ASCII effect description (HLSL?) is contained in the file,
|
nuclear@0
|
779 // we can simply ignore it ...
|
nuclear@0
|
780 if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
|
nuclear@0
|
781 {
|
nuclear@0
|
782 int32_t iMe = *((int32_t*)szCurrent);
|
nuclear@0
|
783 AI_SWAP4(iMe);
|
nuclear@0
|
784 szCurrent += sizeof(char) * iMe + sizeof(int32_t);
|
nuclear@0
|
785 }
|
nuclear@0
|
786 *szCurrentOut = szCurrent;
|
nuclear@0
|
787 }
|
nuclear@0
|
788
|
nuclear@0
|
789 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
790 void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
nuclear@0
|
791 const unsigned char* szCurrent,
|
nuclear@0
|
792 const unsigned char** szCurrentOut,
|
nuclear@0
|
793 std::vector<aiMaterial*>& pcMats)
|
nuclear@0
|
794 {
|
nuclear@0
|
795 ai_assert(NULL != szCurrent);
|
nuclear@0
|
796 ai_assert(NULL != szCurrentOut);
|
nuclear@0
|
797
|
nuclear@0
|
798 *szCurrentOut = szCurrent;
|
nuclear@0
|
799 BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent;
|
nuclear@0
|
800 AI_SWAP4(pcSkin->width);
|
nuclear@0
|
801 AI_SWAP4(pcSkin->height);
|
nuclear@0
|
802 szCurrent += 12;
|
nuclear@0
|
803
|
nuclear@0
|
804 // allocate an output material
|
nuclear@0
|
805 aiMaterial* pcMatOut = new aiMaterial();
|
nuclear@0
|
806 pcMats.push_back(pcMatOut);
|
nuclear@0
|
807
|
nuclear@0
|
808 // skip length of file name
|
nuclear@0
|
809 szCurrent += AI_MDL7_MAX_TEXNAMESIZE;
|
nuclear@0
|
810
|
nuclear@0
|
811 ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut,
|
nuclear@0
|
812 pcSkin->typ,pcSkin->width,pcSkin->height);
|
nuclear@0
|
813
|
nuclear@0
|
814 // place the name of the skin in the material
|
nuclear@0
|
815 if (pcSkin->texture_name[0])
|
nuclear@0
|
816 {
|
nuclear@0
|
817 // the 0 termination could be there or not - we can't know
|
nuclear@0
|
818 aiString szFile;
|
nuclear@0
|
819 ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
|
nuclear@0
|
820 szFile.data[sizeof(pcSkin->texture_name)] = '\0';
|
nuclear@0
|
821 szFile.length = ::strlen(szFile.data);
|
nuclear@0
|
822
|
nuclear@0
|
823 pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
|
nuclear@0
|
824 }
|
nuclear@0
|
825 }
|
nuclear@0
|
826
|
nuclear@0
|
827 #endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
|