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 LWO importer class for the older LWOB
|
nuclear@0
|
43 file formats, including materials */
|
nuclear@0
|
44
|
nuclear@0
|
45 #include "AssimpPCH.h"
|
nuclear@0
|
46 #ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
|
nuclear@0
|
47
|
nuclear@0
|
48 // Internal headers
|
nuclear@0
|
49 #include "LWOLoader.h"
|
nuclear@0
|
50 using namespace Assimp;
|
nuclear@0
|
51
|
nuclear@0
|
52
|
nuclear@0
|
53 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
54 void LWOImporter::LoadLWOBFile()
|
nuclear@0
|
55 {
|
nuclear@0
|
56 LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
|
nuclear@0
|
57 bool running = true;
|
nuclear@0
|
58 while (running)
|
nuclear@0
|
59 {
|
nuclear@0
|
60 if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
|
nuclear@0
|
61 LE_NCONST IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
|
nuclear@0
|
62
|
nuclear@0
|
63 if (mFileBuffer + head->length > end)
|
nuclear@0
|
64 {
|
nuclear@0
|
65 throw DeadlyImportError("LWOB: Invalid chunk length");
|
nuclear@0
|
66 break;
|
nuclear@0
|
67 }
|
nuclear@0
|
68 uint8_t* const next = mFileBuffer+head->length;
|
nuclear@0
|
69 switch (head->type)
|
nuclear@0
|
70 {
|
nuclear@0
|
71 // vertex list
|
nuclear@0
|
72 case AI_LWO_PNTS:
|
nuclear@0
|
73 {
|
nuclear@0
|
74 if (!mCurLayer->mTempPoints.empty())
|
nuclear@0
|
75 DefaultLogger::get()->warn("LWO: PNTS chunk encountered twice");
|
nuclear@0
|
76 else LoadLWOPoints(head->length);
|
nuclear@0
|
77 break;
|
nuclear@0
|
78 }
|
nuclear@0
|
79 // face list
|
nuclear@0
|
80 case AI_LWO_POLS:
|
nuclear@0
|
81 {
|
nuclear@0
|
82 if (!mCurLayer->mFaces.empty())
|
nuclear@0
|
83 DefaultLogger::get()->warn("LWO: POLS chunk encountered twice");
|
nuclear@0
|
84 else LoadLWOBPolygons(head->length);
|
nuclear@0
|
85 break;
|
nuclear@0
|
86 }
|
nuclear@0
|
87 // list of tags
|
nuclear@0
|
88 case AI_LWO_SRFS:
|
nuclear@0
|
89 {
|
nuclear@0
|
90 if (!mTags->empty())
|
nuclear@0
|
91 DefaultLogger::get()->warn("LWO: SRFS chunk encountered twice");
|
nuclear@0
|
92 else LoadLWOTags(head->length);
|
nuclear@0
|
93 break;
|
nuclear@0
|
94 }
|
nuclear@0
|
95
|
nuclear@0
|
96 // surface chunk
|
nuclear@0
|
97 case AI_LWO_SURF:
|
nuclear@0
|
98 {
|
nuclear@0
|
99 LoadLWOBSurface(head->length);
|
nuclear@0
|
100 break;
|
nuclear@0
|
101 }
|
nuclear@0
|
102 }
|
nuclear@0
|
103 mFileBuffer = next;
|
nuclear@0
|
104 }
|
nuclear@0
|
105 }
|
nuclear@0
|
106
|
nuclear@0
|
107 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
108 void LWOImporter::LoadLWOBPolygons(unsigned int length)
|
nuclear@0
|
109 {
|
nuclear@0
|
110 // first find out how many faces and vertices we'll finally need
|
nuclear@0
|
111 LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
|
nuclear@0
|
112 LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
nuclear@0
|
113
|
nuclear@0
|
114 // perform endianess conversions
|
nuclear@0
|
115 #ifndef AI_BUILD_BIG_ENDIAN
|
nuclear@0
|
116 while (cursor < end)ByteSwap::Swap2(cursor++);
|
nuclear@0
|
117 cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
nuclear@0
|
118 #endif
|
nuclear@0
|
119
|
nuclear@0
|
120 unsigned int iNumFaces = 0,iNumVertices = 0;
|
nuclear@0
|
121 CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
|
nuclear@0
|
122
|
nuclear@0
|
123 // allocate the output array and copy face indices
|
nuclear@0
|
124 if (iNumFaces)
|
nuclear@0
|
125 {
|
nuclear@0
|
126 cursor = (LE_NCONST uint16_t*)mFileBuffer;
|
nuclear@0
|
127
|
nuclear@0
|
128 mCurLayer->mFaces.resize(iNumFaces);
|
nuclear@0
|
129 FaceList::iterator it = mCurLayer->mFaces.begin();
|
nuclear@0
|
130 CopyFaceIndicesLWOB(it,cursor,end);
|
nuclear@0
|
131 }
|
nuclear@0
|
132 }
|
nuclear@0
|
133
|
nuclear@0
|
134 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
135 void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
|
nuclear@0
|
136 LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
|
nuclear@0
|
137 {
|
nuclear@0
|
138 while (cursor < end && max--)
|
nuclear@0
|
139 {
|
nuclear@0
|
140 uint16_t numIndices = *cursor++;
|
nuclear@0
|
141 verts += numIndices;faces++;
|
nuclear@0
|
142 cursor += numIndices;
|
nuclear@0
|
143 int16_t surface = *cursor++;
|
nuclear@0
|
144 if (surface < 0)
|
nuclear@0
|
145 {
|
nuclear@0
|
146 // there are detail polygons
|
nuclear@0
|
147 numIndices = *cursor++;
|
nuclear@0
|
148 CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
|
nuclear@0
|
149 }
|
nuclear@0
|
150 }
|
nuclear@0
|
151 }
|
nuclear@0
|
152
|
nuclear@0
|
153 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
154 void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
nuclear@0
|
155 LE_NCONST uint16_t*& cursor,
|
nuclear@0
|
156 const uint16_t* const end,
|
nuclear@0
|
157 unsigned int max)
|
nuclear@0
|
158 {
|
nuclear@0
|
159 while (cursor < end && max--)
|
nuclear@0
|
160 {
|
nuclear@0
|
161 LWO::Face& face = *it;++it;
|
nuclear@0
|
162 if((face.mNumIndices = *cursor++))
|
nuclear@0
|
163 {
|
nuclear@0
|
164 if (cursor + face.mNumIndices >= end)break;
|
nuclear@0
|
165 face.mIndices = new unsigned int[face.mNumIndices];
|
nuclear@0
|
166 for (unsigned int i = 0; i < face.mNumIndices;++i)
|
nuclear@0
|
167 {
|
nuclear@0
|
168 unsigned int & mi = face.mIndices[i] = *cursor++;
|
nuclear@0
|
169 if (mi > mCurLayer->mTempPoints.size())
|
nuclear@0
|
170 {
|
nuclear@0
|
171 DefaultLogger::get()->warn("LWOB: face index is out of range");
|
nuclear@0
|
172 mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
|
nuclear@0
|
173 }
|
nuclear@0
|
174 }
|
nuclear@0
|
175 }
|
nuclear@0
|
176 else DefaultLogger::get()->warn("LWOB: Face has 0 indices");
|
nuclear@0
|
177 int16_t surface = *cursor++;
|
nuclear@0
|
178 if (surface < 0)
|
nuclear@0
|
179 {
|
nuclear@0
|
180 surface = -surface;
|
nuclear@0
|
181
|
nuclear@0
|
182 // there are detail polygons.
|
nuclear@0
|
183 const uint16_t numPolygons = *cursor++;
|
nuclear@0
|
184 if (cursor < end)CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
|
nuclear@0
|
185 }
|
nuclear@0
|
186 face.surfaceIndex = surface-1;
|
nuclear@0
|
187 }
|
nuclear@0
|
188 }
|
nuclear@0
|
189
|
nuclear@0
|
190 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
191 LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
|
nuclear@0
|
192 {
|
nuclear@0
|
193 list.push_back(LWO::Texture());
|
nuclear@0
|
194 LWO::Texture* tex = &list.back();
|
nuclear@0
|
195
|
nuclear@0
|
196 std::string type;
|
nuclear@0
|
197 GetS0(type,size);
|
nuclear@0
|
198 const char* s = type.c_str();
|
nuclear@0
|
199
|
nuclear@0
|
200 if(strstr(s, "Image Map"))
|
nuclear@0
|
201 {
|
nuclear@0
|
202 // Determine mapping type
|
nuclear@0
|
203 if(strstr(s, "Planar"))
|
nuclear@0
|
204 tex->mapMode = LWO::Texture::Planar;
|
nuclear@0
|
205 else if(strstr(s, "Cylindrical"))
|
nuclear@0
|
206 tex->mapMode = LWO::Texture::Cylindrical;
|
nuclear@0
|
207 else if(strstr(s, "Spherical"))
|
nuclear@0
|
208 tex->mapMode = LWO::Texture::Spherical;
|
nuclear@0
|
209 else if(strstr(s, "Cubic"))
|
nuclear@0
|
210 tex->mapMode = LWO::Texture::Cubic;
|
nuclear@0
|
211 else if(strstr(s, "Front"))
|
nuclear@0
|
212 tex->mapMode = LWO::Texture::FrontProjection;
|
nuclear@0
|
213 }
|
nuclear@0
|
214 else
|
nuclear@0
|
215 {
|
nuclear@0
|
216 // procedural or gradient, not supported
|
nuclear@0
|
217 DefaultLogger::get()->error("LWOB: Unsupported legacy texture: " + type);
|
nuclear@0
|
218 }
|
nuclear@0
|
219
|
nuclear@0
|
220 return tex;
|
nuclear@0
|
221 }
|
nuclear@0
|
222
|
nuclear@0
|
223 // ------------------------------------------------------------------------------------------------
|
nuclear@0
|
224 void LWOImporter::LoadLWOBSurface(unsigned int size)
|
nuclear@0
|
225 {
|
nuclear@0
|
226 LE_NCONST uint8_t* const end = mFileBuffer + size;
|
nuclear@0
|
227
|
nuclear@0
|
228 mSurfaces->push_back( LWO::Surface () );
|
nuclear@0
|
229 LWO::Surface& surf = mSurfaces->back();
|
nuclear@0
|
230 LWO::Texture* pTex = NULL;
|
nuclear@0
|
231
|
nuclear@0
|
232 GetS0(surf.mName,size);
|
nuclear@0
|
233 bool runnning = true;
|
nuclear@0
|
234 while (runnning) {
|
nuclear@0
|
235 if (mFileBuffer + 6 >= end)
|
nuclear@0
|
236 break;
|
nuclear@0
|
237
|
nuclear@0
|
238 IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
nuclear@0
|
239
|
nuclear@0
|
240 /* A single test file (sonycam.lwo) seems to have invalid surface chunks.
|
nuclear@0
|
241 * I'm assuming it's the fault of a single, unknown exporter so there are
|
nuclear@0
|
242 * probably THOUSANDS of them. Here's a dirty workaround:
|
nuclear@0
|
243 *
|
nuclear@0
|
244 * We don't break if the chunk limit is exceeded. Instead, we're computing
|
nuclear@0
|
245 * how much storage is actually left and work with this value from now on.
|
nuclear@0
|
246 */
|
nuclear@0
|
247 if (mFileBuffer + head->length > end) {
|
nuclear@0
|
248 DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue.");
|
nuclear@0
|
249 head->length = (uint16_t) (end - mFileBuffer);
|
nuclear@0
|
250 }
|
nuclear@0
|
251
|
nuclear@0
|
252 uint8_t* const next = mFileBuffer+head->length;
|
nuclear@0
|
253 switch (head->type)
|
nuclear@0
|
254 {
|
nuclear@0
|
255 // diffuse color
|
nuclear@0
|
256 case AI_LWO_COLR:
|
nuclear@0
|
257 {
|
nuclear@0
|
258 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,3);
|
nuclear@0
|
259 surf.mColor.r = GetU1() / 255.0f;
|
nuclear@0
|
260 surf.mColor.g = GetU1() / 255.0f;
|
nuclear@0
|
261 surf.mColor.b = GetU1() / 255.0f;
|
nuclear@0
|
262 break;
|
nuclear@0
|
263 }
|
nuclear@0
|
264 // diffuse strength ...
|
nuclear@0
|
265 case AI_LWO_DIFF:
|
nuclear@0
|
266 {
|
nuclear@0
|
267 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,2);
|
nuclear@0
|
268 surf.mDiffuseValue = GetU2() / 255.0f;
|
nuclear@0
|
269 break;
|
nuclear@0
|
270 }
|
nuclear@0
|
271 // specular strength ...
|
nuclear@0
|
272 case AI_LWO_SPEC:
|
nuclear@0
|
273 {
|
nuclear@0
|
274 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,2);
|
nuclear@0
|
275 surf.mSpecularValue = GetU2() / 255.0f;
|
nuclear@0
|
276 break;
|
nuclear@0
|
277 }
|
nuclear@0
|
278 // luminosity ...
|
nuclear@0
|
279 case AI_LWO_LUMI:
|
nuclear@0
|
280 {
|
nuclear@0
|
281 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LUMI,2);
|
nuclear@0
|
282 surf.mLuminosity = GetU2() / 255.0f;
|
nuclear@0
|
283 break;
|
nuclear@0
|
284 }
|
nuclear@0
|
285 // transparency
|
nuclear@0
|
286 case AI_LWO_TRAN:
|
nuclear@0
|
287 {
|
nuclear@0
|
288 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,2);
|
nuclear@0
|
289 surf.mTransparency = GetU2() / 255.0f;
|
nuclear@0
|
290 break;
|
nuclear@0
|
291 }
|
nuclear@0
|
292 // surface flags
|
nuclear@0
|
293 case AI_LWO_FLAG:
|
nuclear@0
|
294 {
|
nuclear@0
|
295 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,FLAG,2);
|
nuclear@0
|
296 uint16_t flag = GetU2();
|
nuclear@0
|
297 if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
|
nuclear@0
|
298 if (flag & 0x8 ) surf.mColorHighlights = 1.f;
|
nuclear@0
|
299 if (flag & 0x100) surf.bDoubleSided = true;
|
nuclear@0
|
300 break;
|
nuclear@0
|
301 }
|
nuclear@0
|
302 // maximum smoothing angle
|
nuclear@0
|
303 case AI_LWO_SMAN:
|
nuclear@0
|
304 {
|
nuclear@0
|
305 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
|
nuclear@0
|
306 surf.mMaximumSmoothAngle = fabs( GetF4() );
|
nuclear@0
|
307 break;
|
nuclear@0
|
308 }
|
nuclear@0
|
309 // glossiness
|
nuclear@0
|
310 case AI_LWO_GLOS:
|
nuclear@0
|
311 {
|
nuclear@0
|
312 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,2);
|
nuclear@0
|
313 surf.mGlossiness = (float)GetU2();
|
nuclear@0
|
314 break;
|
nuclear@0
|
315 }
|
nuclear@0
|
316 // color texture
|
nuclear@0
|
317 case AI_LWO_CTEX:
|
nuclear@0
|
318 {
|
nuclear@0
|
319 pTex = SetupNewTextureLWOB(surf.mColorTextures,
|
nuclear@0
|
320 head->length);
|
nuclear@0
|
321 break;
|
nuclear@0
|
322 }
|
nuclear@0
|
323 // diffuse texture
|
nuclear@0
|
324 case AI_LWO_DTEX:
|
nuclear@0
|
325 {
|
nuclear@0
|
326 pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
|
nuclear@0
|
327 head->length);
|
nuclear@0
|
328 break;
|
nuclear@0
|
329 }
|
nuclear@0
|
330 // specular texture
|
nuclear@0
|
331 case AI_LWO_STEX:
|
nuclear@0
|
332 {
|
nuclear@0
|
333 pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
|
nuclear@0
|
334 head->length);
|
nuclear@0
|
335 break;
|
nuclear@0
|
336 }
|
nuclear@0
|
337 // bump texture
|
nuclear@0
|
338 case AI_LWO_BTEX:
|
nuclear@0
|
339 {
|
nuclear@0
|
340 pTex = SetupNewTextureLWOB(surf.mBumpTextures,
|
nuclear@0
|
341 head->length);
|
nuclear@0
|
342 break;
|
nuclear@0
|
343 }
|
nuclear@0
|
344 // transparency texture
|
nuclear@0
|
345 case AI_LWO_TTEX:
|
nuclear@0
|
346 {
|
nuclear@0
|
347 pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
|
nuclear@0
|
348 head->length);
|
nuclear@0
|
349 break;
|
nuclear@0
|
350 }
|
nuclear@0
|
351 // texture path
|
nuclear@0
|
352 case AI_LWO_TIMG:
|
nuclear@0
|
353 {
|
nuclear@0
|
354 if (pTex) {
|
nuclear@0
|
355 GetS0(pTex->mFileName,head->length);
|
nuclear@0
|
356 }
|
nuclear@0
|
357 else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
|
nuclear@0
|
358 break;
|
nuclear@0
|
359 }
|
nuclear@0
|
360 // texture strength
|
nuclear@0
|
361 case AI_LWO_TVAL:
|
nuclear@0
|
362 {
|
nuclear@0
|
363 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TVAL,1);
|
nuclear@0
|
364 if (pTex) {
|
nuclear@0
|
365 pTex->mStrength = (float)GetU1()/ 255.f;
|
nuclear@0
|
366 }
|
nuclear@0
|
367 else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
|
nuclear@0
|
368 break;
|
nuclear@0
|
369 }
|
nuclear@0
|
370 // texture flags
|
nuclear@0
|
371 case AI_LWO_TFLG:
|
nuclear@0
|
372 {
|
nuclear@0
|
373 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TFLG,2);
|
nuclear@0
|
374
|
nuclear@0
|
375 if (pTex)
|
nuclear@0
|
376 {
|
nuclear@0
|
377 const uint16_t s = GetU2();
|
nuclear@0
|
378 if (s & 1)
|
nuclear@0
|
379 pTex->majorAxis = LWO::Texture::AXIS_X;
|
nuclear@0
|
380 else if (s & 2)
|
nuclear@0
|
381 pTex->majorAxis = LWO::Texture::AXIS_Y;
|
nuclear@0
|
382 else if (s & 4)
|
nuclear@0
|
383 pTex->majorAxis = LWO::Texture::AXIS_Z;
|
nuclear@0
|
384
|
nuclear@0
|
385 if (s & 16)
|
nuclear@0
|
386 DefaultLogger::get()->warn("LWOB: Ignoring \'negate\' flag on texture");
|
nuclear@0
|
387 }
|
nuclear@0
|
388 else DefaultLogger::get()->warn("LWOB: Unexpected TFLG chunk");
|
nuclear@0
|
389 break;
|
nuclear@0
|
390 }
|
nuclear@0
|
391 }
|
nuclear@0
|
392 mFileBuffer = next;
|
nuclear@0
|
393 }
|
nuclear@0
|
394 }
|
nuclear@0
|
395
|
nuclear@0
|
396 #endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
|