vrshoot

annotate libs/assimp/LWOMaterial.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
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 oart of the LWO importer class */
nuclear@0 43
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 #include "ByteSwap.h"
nuclear@0 51
nuclear@0 52 using namespace Assimp;
nuclear@0 53
nuclear@0 54 // ------------------------------------------------------------------------------------------------
nuclear@0 55 template <class T>
nuclear@0 56 T lerp(const T& one, const T& two, float val)
nuclear@0 57 {
nuclear@0 58 return one + (two-one)*val;
nuclear@0 59 }
nuclear@0 60
nuclear@0 61 // ------------------------------------------------------------------------------------------------
nuclear@0 62 // Convert a lightwave mapping mode to our's
nuclear@0 63 inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
nuclear@0 64 {
nuclear@0 65 switch (in)
nuclear@0 66 {
nuclear@0 67 case LWO::Texture::REPEAT:
nuclear@0 68 return aiTextureMapMode_Wrap;
nuclear@0 69
nuclear@0 70 case LWO::Texture::MIRROR:
nuclear@0 71 return aiTextureMapMode_Mirror;
nuclear@0 72
nuclear@0 73 case LWO::Texture::RESET:
nuclear@0 74 DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET");
nuclear@0 75
nuclear@0 76 // fall though here
nuclear@0 77 case LWO::Texture::EDGE:
nuclear@0 78 return aiTextureMapMode_Clamp;
nuclear@0 79 }
nuclear@0 80 return (aiTextureMapMode)0;
nuclear@0 81 }
nuclear@0 82
nuclear@0 83 // ------------------------------------------------------------------------------------------------
nuclear@0 84 bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type)
nuclear@0 85 {
nuclear@0 86 ai_assert(NULL != pcMat);
nuclear@0 87
nuclear@0 88 unsigned int cur = 0, temp = 0;
nuclear@0 89 aiString s;
nuclear@0 90 bool ret = false;
nuclear@0 91
nuclear@0 92 for (TextureList::const_iterator it = in.begin(), end = in.end();it != end;++it) {
nuclear@0 93 if (!(*it).enabled || !(*it).bCanUse)
nuclear@0 94 continue;
nuclear@0 95 ret = true;
nuclear@0 96
nuclear@0 97 // Convert lightwave's mapping modes to ours. We let them
nuclear@0 98 // as they are, the GenUVcoords step will compute UV
nuclear@0 99 // channels if they're not there.
nuclear@0 100
nuclear@0 101 aiTextureMapping mapping;
nuclear@0 102 switch ((*it).mapMode)
nuclear@0 103 {
nuclear@0 104 case LWO::Texture::Planar:
nuclear@0 105 mapping = aiTextureMapping_PLANE;
nuclear@0 106 break;
nuclear@0 107 case LWO::Texture::Cylindrical:
nuclear@0 108 mapping = aiTextureMapping_CYLINDER;
nuclear@0 109 break;
nuclear@0 110 case LWO::Texture::Spherical:
nuclear@0 111 mapping = aiTextureMapping_SPHERE;
nuclear@0 112 break;
nuclear@0 113 case LWO::Texture::Cubic:
nuclear@0 114 mapping = aiTextureMapping_BOX;
nuclear@0 115 break;
nuclear@0 116 case LWO::Texture::FrontProjection:
nuclear@0 117 DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection");
nuclear@0 118 mapping = aiTextureMapping_OTHER;
nuclear@0 119 break;
nuclear@0 120 case LWO::Texture::UV:
nuclear@0 121 {
nuclear@0 122 if( UINT_MAX == (*it).mRealUVIndex ) {
nuclear@0 123 // We have no UV index for this texture, so we can't display it
nuclear@0 124 continue;
nuclear@0 125 }
nuclear@0 126
nuclear@0 127 // add the UV source index
nuclear@0 128 temp = (*it).mRealUVIndex;
nuclear@0 129 pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur));
nuclear@0 130
nuclear@0 131 mapping = aiTextureMapping_UV;
nuclear@0 132 }
nuclear@0 133 break;
nuclear@0 134 default:
nuclear@0 135 ai_assert(false);
nuclear@0 136 };
nuclear@0 137
nuclear@0 138 if (mapping != aiTextureMapping_UV) {
nuclear@0 139 // Setup the main axis
nuclear@0 140 aiVector3D v;
nuclear@0 141 switch ((*it).majorAxis) {
nuclear@0 142 case Texture::AXIS_X:
nuclear@0 143 v = aiVector3D(1.f,0.f,0.f);
nuclear@0 144 break;
nuclear@0 145 case Texture::AXIS_Y:
nuclear@0 146 v = aiVector3D(0.f,1.f,0.f);
nuclear@0 147 break;
nuclear@0 148 default: // case Texture::AXIS_Z:
nuclear@0 149 v = aiVector3D(0.f,0.f,1.f);
nuclear@0 150 break;
nuclear@0 151 }
nuclear@0 152
nuclear@0 153 pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur));
nuclear@0 154
nuclear@0 155 // Setup UV scalings for cylindric and spherical projections
nuclear@0 156 if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) {
nuclear@0 157 aiUVTransform trafo;
nuclear@0 158 trafo.mScaling.x = (*it).wrapAmountW;
nuclear@0 159 trafo.mScaling.y = (*it).wrapAmountH;
nuclear@0 160
nuclear@0 161 BOOST_STATIC_ASSERT(sizeof(aiUVTransform)/sizeof(float) == 5);
nuclear@0 162 pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur));
nuclear@0 163 }
nuclear@0 164 DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping");
nuclear@0 165 }
nuclear@0 166
nuclear@0 167 // The older LWOB format does not use indirect references to clips.
nuclear@0 168 // The file name of a texture is directly specified in the tex chunk.
nuclear@0 169 if (mIsLWO2) {
nuclear@0 170 // find the corresponding clip
nuclear@0 171 ClipList::iterator clip = mClips.begin();
nuclear@0 172 temp = (*it).mClipIdx;
nuclear@0 173 for (ClipList::iterator end = mClips.end(); clip != end; ++clip) {
nuclear@0 174 if ((*clip).idx == temp)
nuclear@0 175 break;
nuclear@0 176
nuclear@0 177 }
nuclear@0 178 if (mClips.end() == clip) {
nuclear@0 179 DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
nuclear@0 180 temp = 0;
nuclear@0 181
nuclear@0 182 // fixme: appearently some LWO files shipping with Doom3 don't
nuclear@0 183 // have clips at all ... check whether that's true or whether
nuclear@0 184 // it's a bug in the loader.
nuclear@0 185
nuclear@0 186 s.Set("$texture.png");
nuclear@0 187
nuclear@0 188 //continue;
nuclear@0 189 }
nuclear@0 190 else {
nuclear@0 191 if (Clip::UNSUPPORTED == (*clip).type) {
nuclear@0 192 DefaultLogger::get()->error("LWO2: Clip type is not supported");
nuclear@0 193 continue;
nuclear@0 194 }
nuclear@0 195 AdjustTexturePath((*clip).path);
nuclear@0 196 s.Set((*clip).path);
nuclear@0 197
nuclear@0 198 // Additional image settings
nuclear@0 199 int flags = 0;
nuclear@0 200 if ((*clip).negate) {
nuclear@0 201 flags |= aiTextureFlags_Invert;
nuclear@0 202 }
nuclear@0 203 pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
nuclear@0 204 }
nuclear@0 205 }
nuclear@0 206 else
nuclear@0 207 {
nuclear@0 208 std::string ss = (*it).mFileName;
nuclear@0 209 if (!ss.length()) {
nuclear@0 210 DefaultLogger::get()->error("LWOB: Empty file name");
nuclear@0 211 continue;
nuclear@0 212 }
nuclear@0 213 AdjustTexturePath(ss);
nuclear@0 214 s.Set(ss);
nuclear@0 215 }
nuclear@0 216 pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur));
nuclear@0 217
nuclear@0 218 // add the blend factor
nuclear@0 219 pcMat->AddProperty<float>(&(*it).mStrength,1,AI_MATKEY_TEXBLEND(type,cur));
nuclear@0 220
nuclear@0 221 // add the blend operation
nuclear@0 222 switch ((*it).blendType)
nuclear@0 223 {
nuclear@0 224 case LWO::Texture::Normal:
nuclear@0 225 case LWO::Texture::Multiply:
nuclear@0 226 temp = (unsigned int)aiTextureOp_Multiply;
nuclear@0 227 break;
nuclear@0 228
nuclear@0 229 case LWO::Texture::Subtractive:
nuclear@0 230 case LWO::Texture::Difference:
nuclear@0 231 temp = (unsigned int)aiTextureOp_Subtract;
nuclear@0 232 break;
nuclear@0 233
nuclear@0 234 case LWO::Texture::Divide:
nuclear@0 235 temp = (unsigned int)aiTextureOp_Divide;
nuclear@0 236 break;
nuclear@0 237
nuclear@0 238 case LWO::Texture::Additive:
nuclear@0 239 temp = (unsigned int)aiTextureOp_Add;
nuclear@0 240 break;
nuclear@0 241
nuclear@0 242 default:
nuclear@0 243 temp = (unsigned int)aiTextureOp_Multiply;
nuclear@0 244 DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement");
nuclear@0 245
nuclear@0 246 }
nuclear@0 247 // Setup texture operation
nuclear@0 248 pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
nuclear@0 249
nuclear@0 250 // setup the mapping mode
nuclear@0 251 pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
nuclear@0 252
nuclear@0 253 // add the u-wrapping
nuclear@0 254 temp = (unsigned int)GetMapMode((*it).wrapModeWidth);
nuclear@0 255 pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur));
nuclear@0 256
nuclear@0 257 // add the v-wrapping
nuclear@0 258 temp = (unsigned int)GetMapMode((*it).wrapModeHeight);
nuclear@0 259 pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur));
nuclear@0 260
nuclear@0 261 ++cur;
nuclear@0 262 }
nuclear@0 263 return ret;
nuclear@0 264 }
nuclear@0 265
nuclear@0 266 // ------------------------------------------------------------------------------------------------
nuclear@0 267 void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
nuclear@0 268 {
nuclear@0 269 // copy the name of the surface
nuclear@0 270 aiString st;
nuclear@0 271 st.Set(surf.mName);
nuclear@0 272 pcMat->AddProperty(&st,AI_MATKEY_NAME);
nuclear@0 273
nuclear@0 274 const int i = surf.bDoubleSided ? 1 : 0;
nuclear@0 275 pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
nuclear@0 276
nuclear@0 277 // add the refraction index and the bump intensity
nuclear@0 278 pcMat->AddProperty(&surf.mIOR,1,AI_MATKEY_REFRACTI);
nuclear@0 279 pcMat->AddProperty(&surf.mBumpIntensity,1,AI_MATKEY_BUMPSCALING);
nuclear@0 280
nuclear@0 281 aiShadingMode m;
nuclear@0 282 if (surf.mSpecularValue && surf.mGlossiness)
nuclear@0 283 {
nuclear@0 284 float fGloss;
nuclear@0 285 if (mIsLWO2) {
nuclear@0 286 fGloss = pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
nuclear@0 287 }
nuclear@0 288 else
nuclear@0 289 {
nuclear@0 290 if (16.0f >= surf.mGlossiness)
nuclear@0 291 fGloss = 6.0f;
nuclear@0 292 else if (64.0f >= surf.mGlossiness)
nuclear@0 293 fGloss = 20.0f;
nuclear@0 294 else if (256.0f >= surf.mGlossiness)
nuclear@0 295 fGloss = 50.0f;
nuclear@0 296 else fGloss = 80.0f;
nuclear@0 297 }
nuclear@0 298
nuclear@0 299 pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
nuclear@0 300 pcMat->AddProperty(&fGloss,1,AI_MATKEY_SHININESS);
nuclear@0 301 m = aiShadingMode_Phong;
nuclear@0 302 }
nuclear@0 303 else m = aiShadingMode_Gouraud;
nuclear@0 304
nuclear@0 305 // specular color
nuclear@0 306 aiColor3D clr = lerp( aiColor3D(1.f,1.f,1.f), surf.mColor, surf.mColorHighlights );
nuclear@0 307 pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_SPECULAR);
nuclear@0 308 pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
nuclear@0 309
nuclear@0 310 // emissive color
nuclear@0 311 // luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
nuclear@0 312 clr.g = clr.b = clr.r = surf.mLuminosity*0.8f;
nuclear@0 313 pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
nuclear@0 314
nuclear@0 315 // opacity ... either additive or default-blended, please
nuclear@0 316 if (0.f != surf.mAdditiveTransparency) {
nuclear@0 317
nuclear@0 318 const int add = aiBlendMode_Additive;
nuclear@0 319 pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
nuclear@0 320 pcMat->AddProperty(&add,1,AI_MATKEY_BLEND_FUNC);
nuclear@0 321 }
nuclear@0 322
nuclear@0 323 else if (10e10f != surf.mTransparency) {
nuclear@0 324 const int def = aiBlendMode_Default;
nuclear@0 325 const float f = 1.0f-surf.mTransparency;
nuclear@0 326 pcMat->AddProperty(&f,1,AI_MATKEY_OPACITY);
nuclear@0 327 pcMat->AddProperty(&def,1,AI_MATKEY_BLEND_FUNC);
nuclear@0 328 }
nuclear@0 329
nuclear@0 330
nuclear@0 331 // ADD TEXTURES to the material
nuclear@0 332 // TODO: find out how we can handle COLOR textures correctly...
nuclear@0 333 bool b = HandleTextures(pcMat,surf.mColorTextures,aiTextureType_DIFFUSE);
nuclear@0 334 b = (b || HandleTextures(pcMat,surf.mDiffuseTextures,aiTextureType_DIFFUSE));
nuclear@0 335 HandleTextures(pcMat,surf.mSpecularTextures,aiTextureType_SPECULAR);
nuclear@0 336 HandleTextures(pcMat,surf.mGlossinessTextures,aiTextureType_SHININESS);
nuclear@0 337 HandleTextures(pcMat,surf.mBumpTextures,aiTextureType_HEIGHT);
nuclear@0 338 HandleTextures(pcMat,surf.mOpacityTextures,aiTextureType_OPACITY);
nuclear@0 339 HandleTextures(pcMat,surf.mReflectionTextures,aiTextureType_REFLECTION);
nuclear@0 340
nuclear@0 341 // Now we need to know which shader to use .. iterate through the shader list of
nuclear@0 342 // the surface and search for a name which we know ...
nuclear@0 343 for (ShaderList::const_iterator it = surf.mShaders.begin(), end = surf.mShaders.end();it != end;++it) {
nuclear@0 344 //if (!(*it).enabled)continue;
nuclear@0 345
nuclear@0 346 if ((*it).functionName == "LW_SuperCelShader" || (*it).functionName == "AH_CelShader") {
nuclear@0 347 DefaultLogger::get()->info("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon");
nuclear@0 348
nuclear@0 349 m = aiShadingMode_Toon;
nuclear@0 350 break;
nuclear@0 351 }
nuclear@0 352 else if ((*it).functionName == "LW_RealFresnel" || (*it).functionName == "LW_FastFresnel") {
nuclear@0 353 DefaultLogger::get()->info("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
nuclear@0 354
nuclear@0 355 m = aiShadingMode_Fresnel;
nuclear@0 356 break;
nuclear@0 357 }
nuclear@0 358 else
nuclear@0 359 {
nuclear@0 360 DefaultLogger::get()->warn("LWO2: Unknown surface shader: " + (*it).functionName);
nuclear@0 361 }
nuclear@0 362 }
nuclear@0 363 if (surf.mMaximumSmoothAngle <= 0.0f)
nuclear@0 364 m = aiShadingMode_Flat;
nuclear@0 365 pcMat->AddProperty((int*)&m,1,AI_MATKEY_SHADING_MODEL);
nuclear@0 366
nuclear@0 367 // (the diffuse value is just a scaling factor)
nuclear@0 368 // If a diffuse texture is set, we set this value to 1.0
nuclear@0 369 clr = (b && false ? aiColor3D(1.f,1.f,1.f) : surf.mColor);
nuclear@0 370 clr.r *= surf.mDiffuseValue;
nuclear@0 371 clr.g *= surf.mDiffuseValue;
nuclear@0 372 clr.b *= surf.mDiffuseValue;
nuclear@0 373 pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
nuclear@0 374 }
nuclear@0 375
nuclear@0 376 // ------------------------------------------------------------------------------------------------
nuclear@0 377 char LWOImporter::FindUVChannels(LWO::TextureList& list,
nuclear@0 378 LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next)
nuclear@0 379 {
nuclear@0 380 char ret = 0;
nuclear@0 381 for (TextureList::iterator it = list.begin(), end = list.end();it != end;++it) {
nuclear@0 382
nuclear@0 383 // Ignore textures with non-UV mappings for the moment.
nuclear@0 384 if (!(*it).enabled || !(*it).bCanUse || (*it).mapMode != LWO::Texture::UV) {
nuclear@0 385 continue;
nuclear@0 386 }
nuclear@0 387
nuclear@0 388 if ((*it).mUVChannelIndex == uv.name) {
nuclear@0 389 ret = 1;
nuclear@0 390
nuclear@0 391 // got it.
nuclear@0 392 if ((*it).mRealUVIndex == UINT_MAX || (*it).mRealUVIndex == next)
nuclear@0 393 {
nuclear@0 394 (*it).mRealUVIndex = next;
nuclear@0 395 }
nuclear@0 396 else {
nuclear@0 397 // channel mismatch. need to duplicate the material.
nuclear@0 398 DefaultLogger::get()->warn("LWO: Channel mismatch, would need to duplicate surface [design bug]");
nuclear@0 399
nuclear@0 400 // TODO
nuclear@0 401 }
nuclear@0 402 }
nuclear@0 403 }
nuclear@0 404 return ret;
nuclear@0 405 }
nuclear@0 406
nuclear@0 407 // ------------------------------------------------------------------------------------------------
nuclear@0 408 void LWOImporter::FindUVChannels(LWO::Surface& surf,
nuclear@0 409 LWO::SortedRep& sorted,LWO::Layer& layer,
nuclear@0 410 unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS])
nuclear@0 411 {
nuclear@0 412 unsigned int next = 0, extra = 0, num_extra = 0;
nuclear@0 413
nuclear@0 414 // Check whether we have an UV entry != 0 for one of the faces in 'sorted'
nuclear@0 415 for (unsigned int i = 0; i < layer.mUVChannels.size();++i) {
nuclear@0 416 LWO::UVChannel& uv = layer.mUVChannels[i];
nuclear@0 417
nuclear@0 418 for (LWO::SortedRep::const_iterator it = sorted.begin(); it != sorted.end(); ++it) {
nuclear@0 419
nuclear@0 420 LWO::Face& face = layer.mFaces[*it];
nuclear@0 421
nuclear@0 422 for (unsigned int n = 0; n < face.mNumIndices; ++n) {
nuclear@0 423 unsigned int idx = face.mIndices[n];
nuclear@0 424
nuclear@0 425 if (uv.abAssigned[idx] && ((aiVector2D*)&uv.rawData[0])[idx] != aiVector2D()) {
nuclear@0 426
nuclear@0 427 if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
nuclear@0 428
nuclear@0 429 DefaultLogger::get()->error("LWO: Maximum number of UV channels for "
nuclear@0 430 "this mesh reached. Skipping channel \'" + uv.name + "\'");
nuclear@0 431
nuclear@0 432 }
nuclear@0 433 else {
nuclear@0 434 // Search through all textures assigned to 'surf' and look for this UV channel
nuclear@0 435 char had = 0;
nuclear@0 436 had |= FindUVChannels(surf.mColorTextures,layer,uv,next);
nuclear@0 437 had |= FindUVChannels(surf.mDiffuseTextures,layer,uv,next);
nuclear@0 438 had |= FindUVChannels(surf.mSpecularTextures,layer,uv,next);
nuclear@0 439 had |= FindUVChannels(surf.mGlossinessTextures,layer,uv,next);
nuclear@0 440 had |= FindUVChannels(surf.mOpacityTextures,layer,uv,next);
nuclear@0 441 had |= FindUVChannels(surf.mBumpTextures,layer,uv,next);
nuclear@0 442 had |= FindUVChannels(surf.mReflectionTextures,layer,uv,next);
nuclear@0 443
nuclear@0 444 // We have a texture referencing this UV channel so we have to take special care
nuclear@0 445 // and are willing to drop unreferenced channels in favour of it.
nuclear@0 446 if (had != 0) {
nuclear@0 447 if (num_extra) {
nuclear@0 448
nuclear@0 449 for (unsigned int a = next; a < std::min( extra, AI_MAX_NUMBER_OF_TEXTURECOORDS-1u ); ++a) {
nuclear@0 450 out[a+1] = out[a];
nuclear@0 451 }
nuclear@0 452 }
nuclear@0 453 ++extra;
nuclear@0 454 out[next++] = i;
nuclear@0 455 }
nuclear@0 456 // Bäh ... seems not to be used at all. Push to end if enough space is available.
nuclear@0 457 else {
nuclear@0 458 out[extra++] = i;
nuclear@0 459 ++num_extra;
nuclear@0 460 }
nuclear@0 461 }
nuclear@0 462 it = sorted.end()-1;
nuclear@0 463 break;
nuclear@0 464 }
nuclear@0 465 }
nuclear@0 466 }
nuclear@0 467 }
nuclear@0 468 if (extra < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
nuclear@0 469 out[extra] = UINT_MAX;
nuclear@0 470 }
nuclear@0 471 }
nuclear@0 472
nuclear@0 473 // ------------------------------------------------------------------------------------------------
nuclear@0 474 void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorted, const LWO::Layer& layer,
nuclear@0 475 unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
nuclear@0 476 {
nuclear@0 477 unsigned int next = 0;
nuclear@0 478
nuclear@0 479 // Check whether we have an vc entry != 0 for one of the faces in 'sorted'
nuclear@0 480 for (unsigned int i = 0; i < layer.mVColorChannels.size();++i) {
nuclear@0 481 const LWO::VColorChannel& vc = layer.mVColorChannels[i];
nuclear@0 482
nuclear@0 483 if (surf.mVCMap == vc.name) {
nuclear@0 484 // The vertex color map is explicitely requested by the surface so we need to take special care of it
nuclear@0 485 for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
nuclear@0 486 out[a+1] = out[a];
nuclear@0 487 }
nuclear@0 488 out[0] = i;
nuclear@0 489 ++next;
nuclear@0 490 }
nuclear@0 491 else {
nuclear@0 492
nuclear@0 493 for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
nuclear@0 494 const LWO::Face& face = layer.mFaces[*it];
nuclear@0 495
nuclear@0 496 for (unsigned int n = 0; n < face.mNumIndices; ++n) {
nuclear@0 497 unsigned int idx = face.mIndices[n];
nuclear@0 498
nuclear@0 499 if (vc.abAssigned[idx] && ((aiColor4D*)&vc.rawData[0])[idx] != aiColor4D(0.f,0.f,0.f,1.f)) {
nuclear@0 500 if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
nuclear@0 501
nuclear@0 502 DefaultLogger::get()->error("LWO: Maximum number of vertex color channels for "
nuclear@0 503 "this mesh reached. Skipping channel \'" + vc.name + "\'");
nuclear@0 504
nuclear@0 505 }
nuclear@0 506 else {
nuclear@0 507 out[next++] = i;
nuclear@0 508 }
nuclear@0 509 it = sorted.end()-1;
nuclear@0 510 break;
nuclear@0 511 }
nuclear@0 512 }
nuclear@0 513 }
nuclear@0 514 }
nuclear@0 515 }
nuclear@0 516 if (next != AI_MAX_NUMBER_OF_COLOR_SETS) {
nuclear@0 517 out[next] = UINT_MAX;
nuclear@0 518 }
nuclear@0 519 }
nuclear@0 520
nuclear@0 521 // ------------------------------------------------------------------------------------------------
nuclear@0 522 void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
nuclear@0 523 {
nuclear@0 524 LE_NCONST uint8_t* const end = mFileBuffer + size;
nuclear@0 525 while (true)
nuclear@0 526 {
nuclear@0 527 if (mFileBuffer + 6 >= end)break;
nuclear@0 528 LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
nuclear@0 529
nuclear@0 530 if (mFileBuffer + head->length > end)
nuclear@0 531 throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
nuclear@0 532
nuclear@0 533 uint8_t* const next = mFileBuffer+head->length;
nuclear@0 534 switch (head->type)
nuclear@0 535 {
nuclear@0 536 case AI_LWO_PROJ:
nuclear@0 537 tex.mapMode = (Texture::MappingMode)GetU2();
nuclear@0 538 break;
nuclear@0 539 case AI_LWO_WRAP:
nuclear@0 540 tex.wrapModeWidth = (Texture::Wrap)GetU2();
nuclear@0 541 tex.wrapModeHeight = (Texture::Wrap)GetU2();
nuclear@0 542 break;
nuclear@0 543 case AI_LWO_AXIS:
nuclear@0 544 tex.majorAxis = (Texture::Axes)GetU2();
nuclear@0 545 break;
nuclear@0 546 case AI_LWO_IMAG:
nuclear@0 547 tex.mClipIdx = GetU2();
nuclear@0 548 break;
nuclear@0 549 case AI_LWO_VMAP:
nuclear@0 550 GetS0(tex.mUVChannelIndex,head->length);
nuclear@0 551 break;
nuclear@0 552 case AI_LWO_WRPH:
nuclear@0 553 tex.wrapAmountH = GetF4();
nuclear@0 554 break;
nuclear@0 555 case AI_LWO_WRPW:
nuclear@0 556 tex.wrapAmountW = GetF4();
nuclear@0 557 break;
nuclear@0 558 }
nuclear@0 559 mFileBuffer = next;
nuclear@0 560 }
nuclear@0 561 }
nuclear@0 562
nuclear@0 563 // ------------------------------------------------------------------------------------------------
nuclear@0 564 void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
nuclear@0 565 {
nuclear@0 566 // --- not supported at the moment
nuclear@0 567 DefaultLogger::get()->error("LWO2: Found procedural texture, this is not supported");
nuclear@0 568 tex.bCanUse = false;
nuclear@0 569 }
nuclear@0 570
nuclear@0 571 // ------------------------------------------------------------------------------------------------
nuclear@0 572 void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex )
nuclear@0 573 {
nuclear@0 574 // --- not supported at the moment
nuclear@0 575 DefaultLogger::get()->error("LWO2: Found gradient texture, this is not supported");
nuclear@0 576 tex.bCanUse = false;
nuclear@0 577 }
nuclear@0 578
nuclear@0 579 // ------------------------------------------------------------------------------------------------
nuclear@0 580 void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
nuclear@0 581 {
nuclear@0 582 LE_NCONST uint8_t* const end = mFileBuffer + size;
nuclear@0 583
nuclear@0 584 // get the ordinal string
nuclear@0 585 GetS0( tex.ordinal, size);
nuclear@0 586
nuclear@0 587 // we could crash later if this is an empty string ...
nuclear@0 588 if (!tex.ordinal.length())
nuclear@0 589 {
nuclear@0 590 DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
nuclear@0 591 tex.ordinal = "\x00";
nuclear@0 592 }
nuclear@0 593 while (true)
nuclear@0 594 {
nuclear@0 595 if (mFileBuffer + 6 >= end)break;
nuclear@0 596 LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
nuclear@0 597
nuclear@0 598 if (mFileBuffer + head->length > end)
nuclear@0 599 throw DeadlyImportError("LWO2: Invalid texture header chunk length");
nuclear@0 600
nuclear@0 601 uint8_t* const next = mFileBuffer+head->length;
nuclear@0 602 switch (head->type)
nuclear@0 603 {
nuclear@0 604 case AI_LWO_CHAN:
nuclear@0 605 tex.type = GetU4();
nuclear@0 606 break;
nuclear@0 607 case AI_LWO_ENAB:
nuclear@0 608 tex.enabled = GetU2() ? true : false;
nuclear@0 609 break;
nuclear@0 610 case AI_LWO_OPAC:
nuclear@0 611 tex.blendType = (Texture::BlendType)GetU2();
nuclear@0 612 tex.mStrength = GetF4();
nuclear@0 613 break;
nuclear@0 614 }
nuclear@0 615 mFileBuffer = next;
nuclear@0 616 }
nuclear@0 617 }
nuclear@0 618
nuclear@0 619 // ------------------------------------------------------------------------------------------------
nuclear@0 620 void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
nuclear@0 621 {
nuclear@0 622 ai_assert(!mSurfaces->empty());
nuclear@0 623 LWO::Surface& surf = mSurfaces->back();
nuclear@0 624 LWO::Texture tex;
nuclear@0 625
nuclear@0 626 // load the texture header
nuclear@0 627 LoadLWO2TextureHeader(head->length,tex);
nuclear@0 628 size -= head->length + 6;
nuclear@0 629
nuclear@0 630 // now get the exact type of the texture
nuclear@0 631 switch (head->type)
nuclear@0 632 {
nuclear@0 633 case AI_LWO_PROC:
nuclear@0 634 LoadLWO2Procedural(size,tex);
nuclear@0 635 break;
nuclear@0 636 case AI_LWO_GRAD:
nuclear@0 637 LoadLWO2Gradient(size,tex);
nuclear@0 638 break;
nuclear@0 639 case AI_LWO_IMAP:
nuclear@0 640 LoadLWO2ImageMap(size,tex);
nuclear@0 641 }
nuclear@0 642
nuclear@0 643 // get the destination channel
nuclear@0 644 TextureList* listRef = NULL;
nuclear@0 645 switch (tex.type)
nuclear@0 646 {
nuclear@0 647 case AI_LWO_COLR:
nuclear@0 648 listRef = &surf.mColorTextures;break;
nuclear@0 649 case AI_LWO_DIFF:
nuclear@0 650 listRef = &surf.mDiffuseTextures;break;
nuclear@0 651 case AI_LWO_SPEC:
nuclear@0 652 listRef = &surf.mSpecularTextures;break;
nuclear@0 653 case AI_LWO_GLOS:
nuclear@0 654 listRef = &surf.mGlossinessTextures;break;
nuclear@0 655 case AI_LWO_BUMP:
nuclear@0 656 listRef = &surf.mBumpTextures;break;
nuclear@0 657 case AI_LWO_TRAN:
nuclear@0 658 listRef = &surf.mOpacityTextures;break;
nuclear@0 659 case AI_LWO_REFL:
nuclear@0 660 listRef = &surf.mReflectionTextures;break;
nuclear@0 661 default:
nuclear@0 662 DefaultLogger::get()->warn("LWO2: Encountered unknown texture type");
nuclear@0 663 return;
nuclear@0 664 }
nuclear@0 665
nuclear@0 666 // now attach the texture to the parent surface - sort by ordinal string
nuclear@0 667 for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it) {
nuclear@0 668 if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
nuclear@0 669 listRef->insert(it,tex);
nuclear@0 670 return;
nuclear@0 671 }
nuclear@0 672 }
nuclear@0 673 listRef->push_back(tex);
nuclear@0 674 }
nuclear@0 675
nuclear@0 676 // ------------------------------------------------------------------------------------------------
nuclear@0 677 void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size )
nuclear@0 678 {
nuclear@0 679 LE_NCONST uint8_t* const end = mFileBuffer + size;
nuclear@0 680
nuclear@0 681 ai_assert(!mSurfaces->empty());
nuclear@0 682 LWO::Surface& surf = mSurfaces->back();
nuclear@0 683 LWO::Shader shader;
nuclear@0 684
nuclear@0 685 // get the ordinal string
nuclear@0 686 GetS0( shader.ordinal, size);
nuclear@0 687
nuclear@0 688 // we could crash later if this is an empty string ...
nuclear@0 689 if (!shader.ordinal.length())
nuclear@0 690 {
nuclear@0 691 DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
nuclear@0 692 shader.ordinal = "\x00";
nuclear@0 693 }
nuclear@0 694
nuclear@0 695 // read the header
nuclear@0 696 while (true)
nuclear@0 697 {
nuclear@0 698 if (mFileBuffer + 6 >= end)break;
nuclear@0 699 LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
nuclear@0 700
nuclear@0 701 if (mFileBuffer + head->length > end)
nuclear@0 702 throw DeadlyImportError("LWO2: Invalid shader header chunk length");
nuclear@0 703
nuclear@0 704 uint8_t* const next = mFileBuffer+head->length;
nuclear@0 705 switch (head->type)
nuclear@0 706 {
nuclear@0 707 case AI_LWO_ENAB:
nuclear@0 708 shader.enabled = GetU2() ? true : false;
nuclear@0 709 break;
nuclear@0 710
nuclear@0 711 case AI_LWO_FUNC:
nuclear@0 712 GetS0( shader.functionName, head->length );
nuclear@0 713 }
nuclear@0 714 mFileBuffer = next;
nuclear@0 715 }
nuclear@0 716
nuclear@0 717 // now attach the shader to the parent surface - sort by ordinal string
nuclear@0 718 for (ShaderList::iterator it = surf.mShaders.begin();it != surf.mShaders.end(); ++it) {
nuclear@0 719 if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
nuclear@0 720 surf.mShaders.insert(it,shader);
nuclear@0 721 return;
nuclear@0 722 }
nuclear@0 723 }
nuclear@0 724 surf.mShaders.push_back(shader);
nuclear@0 725 }
nuclear@0 726
nuclear@0 727 // ------------------------------------------------------------------------------------------------
nuclear@0 728 void LWOImporter::LoadLWO2Surface(unsigned int size)
nuclear@0 729 {
nuclear@0 730 LE_NCONST uint8_t* const end = mFileBuffer + size;
nuclear@0 731
nuclear@0 732 mSurfaces->push_back( LWO::Surface () );
nuclear@0 733 LWO::Surface& surf = mSurfaces->back();
nuclear@0 734
nuclear@0 735 GetS0(surf.mName,size);
nuclear@0 736
nuclear@0 737 // check whether this surface was derived from any other surface
nuclear@0 738 std::string derived;
nuclear@0 739 GetS0(derived,(unsigned int)(end - mFileBuffer));
nuclear@0 740 if (derived.length()) {
nuclear@0 741 // yes, find this surface
nuclear@0 742 for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) {
nuclear@0 743 if ((*it).mName == derived) {
nuclear@0 744 // we have it ...
nuclear@0 745 surf = *it;
nuclear@0 746 derived.clear();break;
nuclear@0 747 }
nuclear@0 748 }
nuclear@0 749 if (derived.size())
nuclear@0 750 DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived);
nuclear@0 751 }
nuclear@0 752
nuclear@0 753 while (true)
nuclear@0 754 {
nuclear@0 755 if (mFileBuffer + 6 >= end)
nuclear@0 756 break;
nuclear@0 757 LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
nuclear@0 758
nuclear@0 759 if (mFileBuffer + head->length > end)
nuclear@0 760 throw DeadlyImportError("LWO2: Invalid surface chunk length");
nuclear@0 761
nuclear@0 762 uint8_t* const next = mFileBuffer+head->length;
nuclear@0 763 switch (head->type)
nuclear@0 764 {
nuclear@0 765 // diffuse color
nuclear@0 766 case AI_LWO_COLR:
nuclear@0 767 {
nuclear@0 768 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,12);
nuclear@0 769 surf.mColor.r = GetF4();
nuclear@0 770 surf.mColor.g = GetF4();
nuclear@0 771 surf.mColor.b = GetF4();
nuclear@0 772 break;
nuclear@0 773 }
nuclear@0 774 // diffuse strength ... hopefully
nuclear@0 775 case AI_LWO_DIFF:
nuclear@0 776 {
nuclear@0 777 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,4);
nuclear@0 778 surf.mDiffuseValue = GetF4();
nuclear@0 779 break;
nuclear@0 780 }
nuclear@0 781 // specular strength ... hopefully
nuclear@0 782 case AI_LWO_SPEC:
nuclear@0 783 {
nuclear@0 784 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,4);
nuclear@0 785 surf.mSpecularValue = GetF4();
nuclear@0 786 break;
nuclear@0 787 }
nuclear@0 788 // transparency
nuclear@0 789 case AI_LWO_TRAN:
nuclear@0 790 {
nuclear@0 791 // transparency explicitly disabled?
nuclear@0 792 if (surf.mTransparency == 10e10f)
nuclear@0 793 break;
nuclear@0 794
nuclear@0 795 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,4);
nuclear@0 796 surf.mTransparency = GetF4();
nuclear@0 797 break;
nuclear@0 798 }
nuclear@0 799 // additive transparency
nuclear@0 800 case AI_LWO_ADTR:
nuclear@0 801 {
nuclear@0 802 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ADTR,4);
nuclear@0 803 surf.mAdditiveTransparency = GetF4();
nuclear@0 804 break;
nuclear@0 805 }
nuclear@0 806 // wireframe mode
nuclear@0 807 case AI_LWO_LINE:
nuclear@0 808 {
nuclear@0 809 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LINE,2);
nuclear@0 810 if (GetU2() & 0x1)
nuclear@0 811 surf.mWireframe = true;
nuclear@0 812 break;
nuclear@0 813 }
nuclear@0 814 // glossiness
nuclear@0 815 case AI_LWO_GLOS:
nuclear@0 816 {
nuclear@0 817 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,4);
nuclear@0 818 surf.mGlossiness = GetF4();
nuclear@0 819 break;
nuclear@0 820 }
nuclear@0 821 // bump intensity
nuclear@0 822 case AI_LWO_BUMP:
nuclear@0 823 {
nuclear@0 824 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BUMP,4);
nuclear@0 825 surf.mBumpIntensity = GetF4();
nuclear@0 826 break;
nuclear@0 827 }
nuclear@0 828 // color highlights
nuclear@0 829 case AI_LWO_CLRH:
nuclear@0 830 {
nuclear@0 831 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,CLRH,4);
nuclear@0 832 surf.mColorHighlights = GetF4();
nuclear@0 833 break;
nuclear@0 834 }
nuclear@0 835 // index of refraction
nuclear@0 836 case AI_LWO_RIND:
nuclear@0 837 {
nuclear@0 838 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,RIND,4);
nuclear@0 839 surf.mIOR = GetF4();
nuclear@0 840 break;
nuclear@0 841 }
nuclear@0 842 // polygon sidedness
nuclear@0 843 case AI_LWO_SIDE:
nuclear@0 844 {
nuclear@0 845 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SIDE,2);
nuclear@0 846 surf.bDoubleSided = (3 == GetU2());
nuclear@0 847 break;
nuclear@0 848 }
nuclear@0 849 // maximum smoothing angle
nuclear@0 850 case AI_LWO_SMAN:
nuclear@0 851 {
nuclear@0 852 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
nuclear@0 853 surf.mMaximumSmoothAngle = fabs( GetF4() );
nuclear@0 854 break;
nuclear@0 855 }
nuclear@0 856 // vertex color channel to be applied to the surface
nuclear@0 857 case AI_LWO_VCOL:
nuclear@0 858 {
nuclear@0 859 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,VCOL,12);
nuclear@0 860 surf.mDiffuseValue *= GetF4(); // strength
nuclear@0 861 ReadVSizedIntLWO2(mFileBuffer); // skip envelope
nuclear@0 862 surf.mVCMapType = GetU4(); // type of the channel
nuclear@0 863
nuclear@0 864 // name of the channel
nuclear@0 865 GetS0(surf.mVCMap, (unsigned int) (next - mFileBuffer ));
nuclear@0 866 break;
nuclear@0 867 }
nuclear@0 868 // surface bock entry
nuclear@0 869 case AI_LWO_BLOK:
nuclear@0 870 {
nuclear@0 871 AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BLOK,4);
nuclear@0 872 LE_NCONST IFF::SubChunkHeader* head2 = IFF::LoadSubChunk(mFileBuffer);
nuclear@0 873
nuclear@0 874 switch (head2->type)
nuclear@0 875 {
nuclear@0 876 case AI_LWO_PROC:
nuclear@0 877 case AI_LWO_GRAD:
nuclear@0 878 case AI_LWO_IMAP:
nuclear@0 879 LoadLWO2TextureBlock(head2, head->length);
nuclear@0 880 break;
nuclear@0 881 case AI_LWO_SHDR:
nuclear@0 882 LoadLWO2ShaderBlock(head2, head->length);
nuclear@0 883 break;
nuclear@0 884
nuclear@0 885 default:
nuclear@0 886 DefaultLogger::get()->warn("LWO2: Found an unsupported surface BLOK");
nuclear@0 887 };
nuclear@0 888
nuclear@0 889 break;
nuclear@0 890 }
nuclear@0 891 }
nuclear@0 892 mFileBuffer = next;
nuclear@0 893 }
nuclear@0 894 }
nuclear@0 895
nuclear@0 896 #endif // !! ASSIMP_BUILD_NO_X_IMPORTER