1 | /* |
2 | --------------------------------------------------------------------------- |
3 | Open Asset Import Library (assimp) |
4 | --------------------------------------------------------------------------- |
5 | |
6 | Copyright (c) 2006-2017, assimp team |
7 | |
8 | |
9 | All rights reserved. |
10 | |
11 | Redistribution and use of this software in source and binary forms, |
12 | with or without modification, are permitted provided that the following |
13 | conditions are met: |
14 | |
15 | * Redistributions of source code must retain the above |
16 | copyright notice, this list of conditions and the |
17 | following disclaimer. |
18 | |
19 | * Redistributions in binary form must reproduce the above |
20 | copyright notice, this list of conditions and the |
21 | following disclaimer in the documentation and/or other |
22 | materials provided with the distribution. |
23 | |
24 | * Neither the name of the assimp team, nor the names of its |
25 | contributors may be used to endorse or promote products |
26 | derived from this software without specific prior |
27 | written permission of the assimp team. |
28 | |
29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
33 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
34 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
35 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
36 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
37 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
38 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
39 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
40 | --------------------------------------------------------------------------- |
41 | */ |
42 | |
43 | |
44 | #ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER |
45 | |
46 | #include <stdlib.h> |
47 | #include "ObjFileMtlImporter.h" |
48 | #include "ObjTools.h" |
49 | #include "ObjFileData.h" |
50 | #include "fast_atof.h" |
51 | #include "ParsingUtils.h" |
52 | #include <assimp/material.h> |
53 | #include <assimp/DefaultLogger.hpp> |
54 | |
55 | |
56 | namespace Assimp { |
57 | |
58 | // Material specific token (case insensitive compare) |
59 | static const std::string DiffuseTexture = "map_Kd" ; |
60 | static const std::string AmbientTexture = "map_Ka" ; |
61 | static const std::string SpecularTexture = "map_Ks" ; |
62 | static const std::string OpacityTexture = "map_d" ; |
63 | static const std::string EmissiveTexture1 = "map_emissive" ; |
64 | static const std::string EmissiveTexture2 = "map_Ke" ; |
65 | static const std::string BumpTexture1 = "map_bump" ; |
66 | static const std::string BumpTexture2 = "bump" ; |
67 | static const std::string NormalTexture = "map_Kn" ; |
68 | static const std::string ReflectionTexture = "refl" ; |
69 | static const std::string DisplacementTexture1 = "map_disp" ; |
70 | static const std::string DisplacementTexture2 = "disp" ; |
71 | static const std::string SpecularityTexture = "map_ns" ; |
72 | |
73 | // texture option specific token |
74 | static const std::string BlendUOption = "-blendu" ; |
75 | static const std::string BlendVOption = "-blendv" ; |
76 | static const std::string BoostOption = "-boost" ; |
77 | static const std::string ModifyMapOption = "-mm" ; |
78 | static const std::string OffsetOption = "-o" ; |
79 | static const std::string ScaleOption = "-s" ; |
80 | static const std::string TurbulenceOption = "-t" ; |
81 | static const std::string ResolutionOption = "-texres" ; |
82 | static const std::string ClampOption = "-clamp" ; |
83 | static const std::string BumpOption = "-bm" ; |
84 | static const std::string ChannelOption = "-imfchan" ; |
85 | static const std::string TypeOption = "-type" ; |
86 | |
87 | |
88 | |
89 | // ------------------------------------------------------------------- |
90 | // Constructor |
91 | ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer, |
92 | const std::string &, |
93 | ObjFile::Model *pModel ) : |
94 | m_DataIt( buffer.begin() ), |
95 | m_DataItEnd( buffer.end() ), |
96 | m_pModel( pModel ), |
97 | m_uiLine( 0 ) |
98 | { |
99 | ai_assert( NULL != m_pModel ); |
100 | if ( NULL == m_pModel->m_pDefaultMaterial ) |
101 | { |
102 | m_pModel->m_pDefaultMaterial = new ObjFile::Material; |
103 | m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" ); |
104 | } |
105 | load(); |
106 | } |
107 | |
108 | // ------------------------------------------------------------------- |
109 | // Destructor |
110 | ObjFileMtlImporter::~ObjFileMtlImporter() |
111 | { |
112 | // empty |
113 | } |
114 | |
115 | // ------------------------------------------------------------------- |
116 | // Private copy constructor |
117 | ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & ) |
118 | { |
119 | // empty |
120 | } |
121 | |
122 | // ------------------------------------------------------------------- |
123 | // Private copy constructor |
124 | ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & ) |
125 | { |
126 | return *this; |
127 | } |
128 | |
129 | // ------------------------------------------------------------------- |
130 | // Loads the material description |
131 | void ObjFileMtlImporter::load() |
132 | { |
133 | if ( m_DataIt == m_DataItEnd ) |
134 | return; |
135 | |
136 | while ( m_DataIt != m_DataItEnd ) |
137 | { |
138 | switch (*m_DataIt) |
139 | { |
140 | case 'k': |
141 | case 'K': |
142 | { |
143 | ++m_DataIt; |
144 | if (*m_DataIt == 'a') // Ambient color |
145 | { |
146 | ++m_DataIt; |
147 | getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient ); |
148 | } |
149 | else if (*m_DataIt == 'd') // Diffuse color |
150 | { |
151 | ++m_DataIt; |
152 | getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse ); |
153 | } |
154 | else if (*m_DataIt == 's') |
155 | { |
156 | ++m_DataIt; |
157 | getColorRGBA( &m_pModel->m_pCurrentMaterial->specular ); |
158 | } |
159 | else if (*m_DataIt == 'e') |
160 | { |
161 | ++m_DataIt; |
162 | getColorRGBA( &m_pModel->m_pCurrentMaterial->emissive ); |
163 | } |
164 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
165 | } |
166 | break; |
167 | case 'T': |
168 | { |
169 | ++m_DataIt; |
170 | if (*m_DataIt == 'f') // Material transmission |
171 | { |
172 | ++m_DataIt; |
173 | getColorRGBA( &m_pModel->m_pCurrentMaterial->transparent); |
174 | } |
175 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
176 | } |
177 | break; |
178 | case 'd': |
179 | { |
180 | if( *(m_DataIt+1) == 'i' && *( m_DataIt + 2 ) == 's' && *( m_DataIt + 3 ) == 'p' ) { |
181 | // A displacement map |
182 | getTexture(); |
183 | } else { |
184 | // Alpha value |
185 | ++m_DataIt; |
186 | getFloatValue( m_pModel->m_pCurrentMaterial->alpha ); |
187 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
188 | } |
189 | } |
190 | break; |
191 | |
192 | case 'N': |
193 | case 'n': |
194 | { |
195 | ++m_DataIt; |
196 | switch(*m_DataIt) |
197 | { |
198 | case 's': // Specular exponent |
199 | ++m_DataIt; |
200 | getFloatValue(m_pModel->m_pCurrentMaterial->shineness); |
201 | break; |
202 | case 'i': // Index Of refraction |
203 | ++m_DataIt; |
204 | getFloatValue(m_pModel->m_pCurrentMaterial->ior); |
205 | break; |
206 | case 'e': // New material |
207 | createMaterial(); |
208 | break; |
209 | } |
210 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
211 | } |
212 | break; |
213 | |
214 | case 'm': // Texture |
215 | case 'b': // quick'n'dirty - for 'bump' sections |
216 | case 'r': // quick'n'dirty - for 'refl' sections |
217 | { |
218 | getTexture(); |
219 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
220 | } |
221 | break; |
222 | |
223 | case 'i': // Illumination model |
224 | { |
225 | m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); |
226 | getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model ); |
227 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
228 | } |
229 | break; |
230 | |
231 | default: |
232 | { |
233 | m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); |
234 | } |
235 | break; |
236 | } |
237 | } |
238 | } |
239 | |
240 | // ------------------------------------------------------------------- |
241 | // Loads a color definition |
242 | void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor ) |
243 | { |
244 | ai_assert( NULL != pColor ); |
245 | |
246 | ai_real r( 0.0 ), g( 0.0 ), b( 0.0 ); |
247 | m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r ); |
248 | pColor->r = r; |
249 | |
250 | // we have to check if color is default 0 with only one token |
251 | if( !IsLineEnd( *m_DataIt ) ) { |
252 | m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g ); |
253 | m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b ); |
254 | } |
255 | pColor->g = g; |
256 | pColor->b = b; |
257 | } |
258 | |
259 | // ------------------------------------------------------------------- |
260 | // Loads the kind of illumination model. |
261 | void ObjFileMtlImporter::getIlluminationModel( int &illum_model ) |
262 | { |
263 | m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); |
264 | illum_model = atoi(m_buffer); |
265 | } |
266 | |
267 | // ------------------------------------------------------------------- |
268 | // Loads a single float value. |
269 | void ObjFileMtlImporter::getFloatValue( ai_real &value ) |
270 | { |
271 | m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); |
272 | value = (ai_real) fast_atof(m_buffer); |
273 | } |
274 | |
275 | // ------------------------------------------------------------------- |
276 | // Creates a material from loaded data. |
277 | void ObjFileMtlImporter::createMaterial() |
278 | { |
279 | std::string line( "" ); |
280 | while( !IsLineEnd( *m_DataIt ) ) { |
281 | line += *m_DataIt; |
282 | ++m_DataIt; |
283 | } |
284 | |
285 | std::vector<std::string> token; |
286 | const unsigned int numToken = tokenize<std::string>( line, token, " \t" ); |
287 | std::string name( "" ); |
288 | if ( numToken == 1 ) { |
289 | name = AI_DEFAULT_MATERIAL_NAME; |
290 | } else { |
291 | // skip newmtl and all following white spaces |
292 | std::size_t first_ws_pos = line.find_first_of(" \t" ); |
293 | std::size_t first_non_ws_pos = line.find_first_not_of(" \t" , first_ws_pos); |
294 | if (first_non_ws_pos != std::string::npos) { |
295 | name = line.substr(first_non_ws_pos); |
296 | } |
297 | } |
298 | |
299 | name = trim_whitespaces(name); |
300 | |
301 | std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( name ); |
302 | if ( m_pModel->m_MaterialMap.end() == it) { |
303 | // New Material created |
304 | m_pModel->m_pCurrentMaterial = new ObjFile::Material(); |
305 | m_pModel->m_pCurrentMaterial->MaterialName.Set( name ); |
306 | if (m_pModel->m_pCurrentMesh) { |
307 | m_pModel->m_pCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->m_MaterialLib.size() - 1); |
308 | } |
309 | m_pModel->m_MaterialLib.push_back( name ); |
310 | m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial; |
311 | } else { |
312 | // Use older material |
313 | m_pModel->m_pCurrentMaterial = (*it).second; |
314 | } |
315 | } |
316 | |
317 | // ------------------------------------------------------------------- |
318 | // Gets a texture name from data. |
319 | void ObjFileMtlImporter::getTexture() { |
320 | aiString *out( NULL ); |
321 | int clampIndex = -1; |
322 | |
323 | const char *pPtr( &(*m_DataIt) ); |
324 | if ( !ASSIMP_strincmp( pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()) ) ) { |
325 | // Diffuse texture |
326 | out = & m_pModel->m_pCurrentMaterial->texture; |
327 | clampIndex = ObjFile::Material::TextureDiffuseType; |
328 | } else if ( !ASSIMP_strincmp( pPtr,AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()) ) ) { |
329 | // Ambient texture |
330 | out = & m_pModel->m_pCurrentMaterial->textureAmbient; |
331 | clampIndex = ObjFile::Material::TextureAmbientType; |
332 | } else if ( !ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()) ) ) { |
333 | // Specular texture |
334 | out = & m_pModel->m_pCurrentMaterial->textureSpecular; |
335 | clampIndex = ObjFile::Material::TextureSpecularType; |
336 | } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) { |
337 | // Opacity texture |
338 | out = & m_pModel->m_pCurrentMaterial->textureOpacity; |
339 | clampIndex = ObjFile::Material::TextureOpacityType; |
340 | } else if ( !ASSIMP_strincmp( pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size()) ) || |
341 | !ASSIMP_strincmp( pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()) ) ) { |
342 | // Emissive texture |
343 | out = & m_pModel->m_pCurrentMaterial->textureEmissive; |
344 | clampIndex = ObjFile::Material::TextureEmissiveType; |
345 | } else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size()) ) || |
346 | !ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()) ) ) { |
347 | // Bump texture |
348 | out = & m_pModel->m_pCurrentMaterial->textureBump; |
349 | clampIndex = ObjFile::Material::TextureBumpType; |
350 | } else if ( !ASSIMP_strincmp( pPtr,NormalTexture.c_str(), static_cast<unsigned int>(NormalTexture.size()) ) ) { |
351 | // Normal map |
352 | out = & m_pModel->m_pCurrentMaterial->textureNormal; |
353 | clampIndex = ObjFile::Material::TextureNormalType; |
354 | } else if( !ASSIMP_strincmp( pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()) ) ) { |
355 | // Reflection texture(s) |
356 | //Do nothing here |
357 | return; |
358 | } else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) || |
359 | !ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) { |
360 | // Displacement texture |
361 | out = &m_pModel->m_pCurrentMaterial->textureDisp; |
362 | clampIndex = ObjFile::Material::TextureDispType; |
363 | } else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) { |
364 | // Specularity scaling (glossiness) |
365 | out = & m_pModel->m_pCurrentMaterial->textureSpecularity; |
366 | clampIndex = ObjFile::Material::TextureSpecularityType; |
367 | } else { |
368 | DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type" ); |
369 | return; |
370 | } |
371 | |
372 | bool clamp = false; |
373 | getTextureOption(clamp, clampIndex, out); |
374 | m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp; |
375 | |
376 | std::string texture; |
377 | m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, texture ); |
378 | if ( NULL!=out ) { |
379 | out->Set( texture ); |
380 | } |
381 | } |
382 | |
383 | /* ///////////////////////////////////////////////////////////////////////////// |
384 | * Texture Option |
385 | * ///////////////////////////////////////////////////////////////////////////// |
386 | * According to http://en.wikipedia.org/wiki/Wavefront_.obj_file#Texture_options |
387 | * Texture map statement can contains various texture option, for example: |
388 | * |
389 | * map_Ka -o 1 1 1 some.png |
390 | * map_Kd -clamp on some.png |
391 | * |
392 | * So we need to parse and skip these options, and leave the last part which is |
393 | * the url of image, otherwise we will get a wrong url like "-clamp on some.png". |
394 | * |
395 | * Because aiMaterial supports clamp option, so we also want to return it |
396 | * ///////////////////////////////////////////////////////////////////////////// |
397 | */ |
398 | void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString *&out) { |
399 | m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); |
400 | |
401 | // If there is any more texture option |
402 | while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-') |
403 | { |
404 | const char *pPtr( &(*m_DataIt) ); |
405 | //skip option key and value |
406 | int skipToken = 1; |
407 | |
408 | if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), static_cast<unsigned int>(ClampOption.size()))) |
409 | { |
410 | DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); |
411 | char value[3]; |
412 | CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value)); |
413 | if (!ASSIMP_strincmp(value, "on" , 2)) |
414 | { |
415 | clamp = true; |
416 | } |
417 | |
418 | skipToken = 2; |
419 | } |
420 | else if( !ASSIMP_strincmp( pPtr, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()) ) ) |
421 | { |
422 | DataArrayIt it = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd ); |
423 | char value[ 12 ]; |
424 | CopyNextWord( it, m_DataItEnd, value, sizeof( value ) / sizeof( *value ) ); |
425 | if( !ASSIMP_strincmp( value, "cube_top" , 8 ) ) |
426 | { |
427 | clampIndex = ObjFile::Material::TextureReflectionCubeTopType; |
428 | out = &m_pModel->m_pCurrentMaterial->textureReflection[0]; |
429 | } |
430 | else if( !ASSIMP_strincmp( value, "cube_bottom" , 11 ) ) |
431 | { |
432 | clampIndex = ObjFile::Material::TextureReflectionCubeBottomType; |
433 | out = &m_pModel->m_pCurrentMaterial->textureReflection[1]; |
434 | } |
435 | else if( !ASSIMP_strincmp( value, "cube_front" , 10 ) ) |
436 | { |
437 | clampIndex = ObjFile::Material::TextureReflectionCubeFrontType; |
438 | out = &m_pModel->m_pCurrentMaterial->textureReflection[2]; |
439 | } |
440 | else if( !ASSIMP_strincmp( value, "cube_back" , 9 ) ) |
441 | { |
442 | clampIndex = ObjFile::Material::TextureReflectionCubeBackType; |
443 | out = &m_pModel->m_pCurrentMaterial->textureReflection[3]; |
444 | } |
445 | else if( !ASSIMP_strincmp( value, "cube_left" , 9 ) ) |
446 | { |
447 | clampIndex = ObjFile::Material::TextureReflectionCubeLeftType; |
448 | out = &m_pModel->m_pCurrentMaterial->textureReflection[4]; |
449 | } |
450 | else if( !ASSIMP_strincmp( value, "cube_right" , 10 ) ) |
451 | { |
452 | clampIndex = ObjFile::Material::TextureReflectionCubeRightType; |
453 | out = &m_pModel->m_pCurrentMaterial->textureReflection[5]; |
454 | } |
455 | else if( !ASSIMP_strincmp( value, "sphere" , 6 ) ) |
456 | { |
457 | clampIndex = ObjFile::Material::TextureReflectionSphereType; |
458 | out = &m_pModel->m_pCurrentMaterial->textureReflection[0]; |
459 | } |
460 | |
461 | skipToken = 2; |
462 | } |
463 | else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) |
464 | || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) |
465 | || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) |
466 | || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) |
467 | || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size())) |
468 | || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) |
469 | { |
470 | skipToken = 2; |
471 | } |
472 | else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size()))) |
473 | { |
474 | skipToken = 3; |
475 | } |
476 | else if ( !ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size())) |
477 | || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size())) |
478 | || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size())) |
479 | ) |
480 | { |
481 | skipToken = 4; |
482 | } |
483 | |
484 | for (int i = 0; i < skipToken; ++i) |
485 | { |
486 | m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); |
487 | } |
488 | } |
489 | } |
490 | |
491 | // ------------------------------------------------------------------- |
492 | |
493 | } // Namespace Assimp |
494 | |
495 | #endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER |
496 | |