vrshoot

annotate libs/assimp/ASEParser.cpp @ 1:e7ca128b8713

looks nice :)
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Feb 2014 00:35:22 +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 ASEParser.cpp
nuclear@0 43 * @brief Implementation of the ASE parser class
nuclear@0 44 */
nuclear@0 45
nuclear@0 46 #include "AssimpPCH.h"
nuclear@0 47 #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
nuclear@0 48
nuclear@0 49 // internal headers
nuclear@0 50 #include "TextureTransform.h"
nuclear@0 51 #include "ASELoader.h"
nuclear@0 52 #include "MaterialSystem.h"
nuclear@0 53 #include "fast_atof.h"
nuclear@0 54
nuclear@0 55 using namespace Assimp;
nuclear@0 56 using namespace Assimp::ASE;
nuclear@0 57
nuclear@0 58
nuclear@0 59 // ------------------------------------------------------------------------------------------------
nuclear@0 60 // Begin an ASE parsing function
nuclear@0 61
nuclear@0 62 #define AI_ASE_PARSER_INIT() \
nuclear@0 63 int iDepth = 0;
nuclear@0 64
nuclear@0 65 // ------------------------------------------------------------------------------------------------
nuclear@0 66 // Handle a "top-level" section in the file. EOF is no error in this case.
nuclear@0 67
nuclear@0 68 #define AI_ASE_HANDLE_TOP_LEVEL_SECTION() \
nuclear@0 69 else if ('{' == *filePtr)iDepth++; \
nuclear@0 70 else if ('}' == *filePtr) \
nuclear@0 71 { \
nuclear@0 72 if (0 == --iDepth) \
nuclear@0 73 { \
nuclear@0 74 ++filePtr; \
nuclear@0 75 SkipToNextToken(); \
nuclear@0 76 return; \
nuclear@0 77 } \
nuclear@0 78 } \
nuclear@0 79 else if ('\0' == *filePtr) \
nuclear@0 80 { \
nuclear@0 81 return; \
nuclear@0 82 } \
nuclear@0 83 if(IsLineEnd(*filePtr) && !bLastWasEndLine) \
nuclear@0 84 { \
nuclear@0 85 ++iLineNumber; \
nuclear@0 86 bLastWasEndLine = true; \
nuclear@0 87 } else bLastWasEndLine = false; \
nuclear@0 88 ++filePtr;
nuclear@0 89
nuclear@0 90 // ------------------------------------------------------------------------------------------------
nuclear@0 91 // Handle a nested section in the file. EOF is an error in this case
nuclear@0 92 // @param level "Depth" of the section
nuclear@0 93 // @param msg Full name of the section (including the asterisk)
nuclear@0 94
nuclear@0 95 #define AI_ASE_HANDLE_SECTION(level, msg) \
nuclear@0 96 if ('{' == *filePtr)iDepth++; \
nuclear@0 97 else if ('}' == *filePtr) \
nuclear@0 98 { \
nuclear@0 99 if (0 == --iDepth) \
nuclear@0 100 { \
nuclear@0 101 ++filePtr; \
nuclear@0 102 SkipToNextToken(); \
nuclear@0 103 return; \
nuclear@0 104 } \
nuclear@0 105 } \
nuclear@0 106 else if ('\0' == *filePtr) \
nuclear@0 107 { \
nuclear@0 108 LogError("Encountered unexpected EOL while parsing a " msg \
nuclear@0 109 " chunk (Level " level ")"); \
nuclear@0 110 } \
nuclear@0 111 if(IsLineEnd(*filePtr) && !bLastWasEndLine) \
nuclear@0 112 { \
nuclear@0 113 ++iLineNumber; \
nuclear@0 114 bLastWasEndLine = true; \
nuclear@0 115 } else bLastWasEndLine = false; \
nuclear@0 116 ++filePtr;
nuclear@0 117
nuclear@0 118 // ------------------------------------------------------------------------------------------------
nuclear@0 119 Parser::Parser (const char* szFile, unsigned int fileFormatDefault)
nuclear@0 120 {
nuclear@0 121 ai_assert(NULL != szFile);
nuclear@0 122 filePtr = szFile;
nuclear@0 123 iFileFormat = fileFormatDefault;
nuclear@0 124
nuclear@0 125 // make sure that the color values are invalid
nuclear@0 126 m_clrBackground.r = get_qnan();
nuclear@0 127 m_clrAmbient.r = get_qnan();
nuclear@0 128
nuclear@0 129 // setup some default values
nuclear@0 130 iLineNumber = 0;
nuclear@0 131 iFirstFrame = 0;
nuclear@0 132 iLastFrame = 0;
nuclear@0 133 iFrameSpeed = 30; // use 30 as default value for this property
nuclear@0 134 iTicksPerFrame = 1; // use 1 as default value for this property
nuclear@0 135 bLastWasEndLine = false; // need to handle \r\n seqs due to binary file mapping
nuclear@0 136 }
nuclear@0 137
nuclear@0 138 // ------------------------------------------------------------------------------------------------
nuclear@0 139 void Parser::LogWarning(const char* szWarn)
nuclear@0 140 {
nuclear@0 141 ai_assert(NULL != szWarn);
nuclear@0 142
nuclear@0 143 char szTemp[1024];
nuclear@0 144 #if _MSC_VER >= 1400
nuclear@0 145 sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
nuclear@0 146 #else
nuclear@0 147 snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
nuclear@0 148 #endif
nuclear@0 149
nuclear@0 150 // output the warning to the logger ...
nuclear@0 151 DefaultLogger::get()->warn(szTemp);
nuclear@0 152 }
nuclear@0 153
nuclear@0 154 // ------------------------------------------------------------------------------------------------
nuclear@0 155 void Parser::LogInfo(const char* szWarn)
nuclear@0 156 {
nuclear@0 157 ai_assert(NULL != szWarn);
nuclear@0 158
nuclear@0 159 char szTemp[1024];
nuclear@0 160 #if _MSC_VER >= 1400
nuclear@0 161 sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
nuclear@0 162 #else
nuclear@0 163 snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
nuclear@0 164 #endif
nuclear@0 165
nuclear@0 166 // output the information to the logger ...
nuclear@0 167 DefaultLogger::get()->info(szTemp);
nuclear@0 168 }
nuclear@0 169
nuclear@0 170 // ------------------------------------------------------------------------------------------------
nuclear@0 171 void Parser::LogError(const char* szWarn)
nuclear@0 172 {
nuclear@0 173 ai_assert(NULL != szWarn);
nuclear@0 174
nuclear@0 175 char szTemp[1024];
nuclear@0 176 #if _MSC_VER >= 1400
nuclear@0 177 sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
nuclear@0 178 #else
nuclear@0 179 snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
nuclear@0 180 #endif
nuclear@0 181
nuclear@0 182 // throw an exception
nuclear@0 183 throw DeadlyImportError(szTemp);
nuclear@0 184 }
nuclear@0 185
nuclear@0 186 // ------------------------------------------------------------------------------------------------
nuclear@0 187 bool Parser::SkipToNextToken()
nuclear@0 188 {
nuclear@0 189 while (true)
nuclear@0 190 {
nuclear@0 191 char me = *filePtr;
nuclear@0 192
nuclear@0 193 // increase the line number counter if necessary
nuclear@0 194 if (IsLineEnd(me) && !bLastWasEndLine)
nuclear@0 195 {
nuclear@0 196 ++iLineNumber;
nuclear@0 197 bLastWasEndLine = true;
nuclear@0 198 }
nuclear@0 199 else bLastWasEndLine = false;
nuclear@0 200 if ('*' == me || '}' == me || '{' == me)return true;
nuclear@0 201 if ('\0' == me)return false;
nuclear@0 202
nuclear@0 203 ++filePtr;
nuclear@0 204 }
nuclear@0 205 }
nuclear@0 206
nuclear@0 207 // ------------------------------------------------------------------------------------------------
nuclear@0 208 bool Parser::SkipSection()
nuclear@0 209 {
nuclear@0 210 // must handle subsections ...
nuclear@0 211 int iCnt = 0;
nuclear@0 212 while (true)
nuclear@0 213 {
nuclear@0 214 if ('}' == *filePtr)
nuclear@0 215 {
nuclear@0 216 --iCnt;
nuclear@0 217 if (0 == iCnt)
nuclear@0 218 {
nuclear@0 219 // go to the next valid token ...
nuclear@0 220 ++filePtr;
nuclear@0 221 SkipToNextToken();
nuclear@0 222 return true;
nuclear@0 223 }
nuclear@0 224 }
nuclear@0 225 else if ('{' == *filePtr)
nuclear@0 226 {
nuclear@0 227 ++iCnt;
nuclear@0 228 }
nuclear@0 229 else if ('\0' == *filePtr)
nuclear@0 230 {
nuclear@0 231 LogWarning("Unable to parse block: Unexpected EOF, closing bracket \'}\' was expected [#1]");
nuclear@0 232 return false;
nuclear@0 233 }
nuclear@0 234 else if(IsLineEnd(*filePtr))++iLineNumber;
nuclear@0 235 ++filePtr;
nuclear@0 236 }
nuclear@0 237 }
nuclear@0 238
nuclear@0 239 // ------------------------------------------------------------------------------------------------
nuclear@0 240 void Parser::Parse()
nuclear@0 241 {
nuclear@0 242 AI_ASE_PARSER_INIT();
nuclear@0 243 while (true)
nuclear@0 244 {
nuclear@0 245 if ('*' == *filePtr)
nuclear@0 246 {
nuclear@0 247 ++filePtr;
nuclear@0 248
nuclear@0 249 // Version should be 200. Validate this ...
nuclear@0 250 if (TokenMatch(filePtr,"3DSMAX_ASCIIEXPORT",18))
nuclear@0 251 {
nuclear@0 252 unsigned int fmt;
nuclear@0 253 ParseLV4MeshLong(fmt);
nuclear@0 254
nuclear@0 255 if (fmt > 200)
nuclear@0 256 {
nuclear@0 257 LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \
nuclear@0 258 be <= 200");
nuclear@0 259 }
nuclear@0 260 // *************************************************************
nuclear@0 261 // - fmt will be 0 if we're unable to read the version number
nuclear@0 262 // there are some faulty files without a version number ...
nuclear@0 263 // in this case we'll guess the exact file format by looking
nuclear@0 264 // at the file extension (ASE, ASK, ASC)
nuclear@0 265 // *************************************************************
nuclear@0 266
nuclear@0 267 if (fmt)iFileFormat = fmt;
nuclear@0 268 continue;
nuclear@0 269 }
nuclear@0 270 // main scene information
nuclear@0 271 if (TokenMatch(filePtr,"SCENE",5))
nuclear@0 272 {
nuclear@0 273 ParseLV1SceneBlock();
nuclear@0 274 continue;
nuclear@0 275 }
nuclear@0 276 // "group" - no implementation yet, in facte
nuclear@0 277 // we're just ignoring them for the moment
nuclear@0 278 if (TokenMatch(filePtr,"GROUP",5))
nuclear@0 279 {
nuclear@0 280 Parse();
nuclear@0 281 continue;
nuclear@0 282 }
nuclear@0 283 // material list
nuclear@0 284 if (TokenMatch(filePtr,"MATERIAL_LIST",13))
nuclear@0 285 {
nuclear@0 286 ParseLV1MaterialListBlock();
nuclear@0 287 continue;
nuclear@0 288 }
nuclear@0 289 // geometric object (mesh)
nuclear@0 290 if (TokenMatch(filePtr,"GEOMOBJECT",10))
nuclear@0 291
nuclear@0 292 {
nuclear@0 293 m_vMeshes.push_back(Mesh());
nuclear@0 294 ParseLV1ObjectBlock(m_vMeshes.back());
nuclear@0 295 continue;
nuclear@0 296 }
nuclear@0 297 // helper object = dummy in the hierarchy
nuclear@0 298 if (TokenMatch(filePtr,"HELPEROBJECT",12))
nuclear@0 299
nuclear@0 300 {
nuclear@0 301 m_vDummies.push_back(Dummy());
nuclear@0 302 ParseLV1ObjectBlock(m_vDummies.back());
nuclear@0 303 continue;
nuclear@0 304 }
nuclear@0 305 // light object
nuclear@0 306 if (TokenMatch(filePtr,"LIGHTOBJECT",11))
nuclear@0 307
nuclear@0 308 {
nuclear@0 309 m_vLights.push_back(Light());
nuclear@0 310 ParseLV1ObjectBlock(m_vLights.back());
nuclear@0 311 continue;
nuclear@0 312 }
nuclear@0 313 // camera object
nuclear@0 314 if (TokenMatch(filePtr,"CAMERAOBJECT",12))
nuclear@0 315 {
nuclear@0 316 m_vCameras.push_back(Camera());
nuclear@0 317 ParseLV1ObjectBlock(m_vCameras.back());
nuclear@0 318 continue;
nuclear@0 319 }
nuclear@0 320 // comment - print it on the console
nuclear@0 321 if (TokenMatch(filePtr,"COMMENT",7))
nuclear@0 322 {
nuclear@0 323 std::string out = "<unknown>";
nuclear@0 324 ParseString(out,"*COMMENT");
nuclear@0 325 LogInfo(("Comment: " + out).c_str());
nuclear@0 326 continue;
nuclear@0 327 }
nuclear@0 328 // ASC bone weights
nuclear@0 329 if (AI_ASE_IS_OLD_FILE_FORMAT() && TokenMatch(filePtr,"MESH_SOFTSKINVERTS",18))
nuclear@0 330 {
nuclear@0 331 ParseLV1SoftSkinBlock();
nuclear@0 332 }
nuclear@0 333 }
nuclear@0 334 AI_ASE_HANDLE_TOP_LEVEL_SECTION();
nuclear@0 335 }
nuclear@0 336 return;
nuclear@0 337 }
nuclear@0 338
nuclear@0 339 // ------------------------------------------------------------------------------------------------
nuclear@0 340 void Parser::ParseLV1SoftSkinBlock()
nuclear@0 341 {
nuclear@0 342 // TODO: fix line counting here
nuclear@0 343
nuclear@0 344 // **************************************************************
nuclear@0 345 // The soft skin block is formatted differently. There are no
nuclear@0 346 // nested sections supported and the single elements aren't
nuclear@0 347 // marked by keywords starting with an asterisk.
nuclear@0 348
nuclear@0 349 /**
nuclear@0 350 FORMAT BEGIN
nuclear@0 351
nuclear@0 352 *MESH_SOFTSKINVERTS {
nuclear@0 353 <nodename>
nuclear@0 354 <number of vertices>
nuclear@0 355
nuclear@0 356 [for <number of vertices> times:]
nuclear@0 357 <number of weights> [for <number of weights> times:] <bone name> <weight>
nuclear@0 358 }
nuclear@0 359
nuclear@0 360 FORMAT END
nuclear@0 361 */
nuclear@0 362 // **************************************************************
nuclear@0 363 while (true)
nuclear@0 364 {
nuclear@0 365 if (*filePtr == '}' ) {++filePtr;return;}
nuclear@0 366 else if (*filePtr == '\0') return;
nuclear@0 367 else if (*filePtr == '{' ) ++filePtr;
nuclear@0 368
nuclear@0 369 else // if (!IsSpace(*filePtr) && !IsLineEnd(*filePtr))
nuclear@0 370 {
nuclear@0 371 ASE::Mesh* curMesh = NULL;
nuclear@0 372 unsigned int numVerts = 0;
nuclear@0 373
nuclear@0 374 const char* sz = filePtr;
nuclear@0 375 while (!IsSpaceOrNewLine(*filePtr))++filePtr;
nuclear@0 376
nuclear@0 377 const unsigned int diff = (unsigned int)(filePtr-sz);
nuclear@0 378 if (diff)
nuclear@0 379 {
nuclear@0 380 std::string name = std::string(sz,diff);
nuclear@0 381 for (std::vector<ASE::Mesh>::iterator it = m_vMeshes.begin();
nuclear@0 382 it != m_vMeshes.end(); ++it)
nuclear@0 383 {
nuclear@0 384 if ((*it).mName == name)
nuclear@0 385 {
nuclear@0 386 curMesh = & (*it);
nuclear@0 387 break;
nuclear@0 388 }
nuclear@0 389 }
nuclear@0 390 if (!curMesh)
nuclear@0 391 {
nuclear@0 392 LogWarning("Encountered unknown mesh in *MESH_SOFTSKINVERTS section");
nuclear@0 393
nuclear@0 394 // Skip the mesh data - until we find a new mesh
nuclear@0 395 // or the end of the *MESH_SOFTSKINVERTS section
nuclear@0 396 while (true)
nuclear@0 397 {
nuclear@0 398 SkipSpacesAndLineEnd(&filePtr);
nuclear@0 399 if (*filePtr == '}')
nuclear@0 400 {++filePtr;return;}
nuclear@0 401 else if (!IsNumeric(*filePtr))
nuclear@0 402 break;
nuclear@0 403
nuclear@0 404 SkipLine(&filePtr);
nuclear@0 405 }
nuclear@0 406 }
nuclear@0 407 else
nuclear@0 408 {
nuclear@0 409 SkipSpacesAndLineEnd(&filePtr);
nuclear@0 410 ParseLV4MeshLong(numVerts);
nuclear@0 411
nuclear@0 412 // Reserve enough storage
nuclear@0 413 curMesh->mBoneVertices.reserve(numVerts);
nuclear@0 414
nuclear@0 415 for (unsigned int i = 0; i < numVerts;++i)
nuclear@0 416 {
nuclear@0 417 SkipSpacesAndLineEnd(&filePtr);
nuclear@0 418 unsigned int numWeights;
nuclear@0 419 ParseLV4MeshLong(numWeights);
nuclear@0 420
nuclear@0 421 curMesh->mBoneVertices.push_back(ASE::BoneVertex());
nuclear@0 422 ASE::BoneVertex& vert = curMesh->mBoneVertices.back();
nuclear@0 423
nuclear@0 424 // Reserve enough storage
nuclear@0 425 vert.mBoneWeights.reserve(numWeights);
nuclear@0 426
nuclear@0 427 for (unsigned int w = 0; w < numWeights;++w)
nuclear@0 428 {
nuclear@0 429 std::string bone;
nuclear@0 430 ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
nuclear@0 431
nuclear@0 432 // Find the bone in the mesh's list
nuclear@0 433 std::pair<int,float> me;
nuclear@0 434 me.first = -1;
nuclear@0 435
nuclear@0 436 for (unsigned int n = 0; n < curMesh->mBones.size();++n)
nuclear@0 437 {
nuclear@0 438 if (curMesh->mBones[n].mName == bone)
nuclear@0 439 {
nuclear@0 440 me.first = n;
nuclear@0 441 break;
nuclear@0 442 }
nuclear@0 443 }
nuclear@0 444 if (-1 == me.first)
nuclear@0 445 {
nuclear@0 446 // We don't have this bone yet, so add it to the list
nuclear@0 447 me.first = (int)curMesh->mBones.size();
nuclear@0 448 curMesh->mBones.push_back(ASE::Bone(bone));
nuclear@0 449 }
nuclear@0 450 ParseLV4MeshFloat( me.second );
nuclear@0 451
nuclear@0 452 // Add the new bone weight to list
nuclear@0 453 vert.mBoneWeights.push_back(me);
nuclear@0 454 }
nuclear@0 455 }
nuclear@0 456 }
nuclear@0 457 }
nuclear@0 458 }
nuclear@0 459 ++filePtr;
nuclear@0 460 SkipSpacesAndLineEnd(&filePtr);
nuclear@0 461 }
nuclear@0 462 }
nuclear@0 463
nuclear@0 464 // ------------------------------------------------------------------------------------------------
nuclear@0 465 void Parser::ParseLV1SceneBlock()
nuclear@0 466 {
nuclear@0 467 AI_ASE_PARSER_INIT();
nuclear@0 468 while (true)
nuclear@0 469 {
nuclear@0 470 if ('*' == *filePtr)
nuclear@0 471 {
nuclear@0 472 ++filePtr;
nuclear@0 473 if (TokenMatch(filePtr,"SCENE_BACKGROUND_STATIC",23))
nuclear@0 474
nuclear@0 475 {
nuclear@0 476 // parse a color triple and assume it is really the bg color
nuclear@0 477 ParseLV4MeshFloatTriple( &m_clrBackground.r );
nuclear@0 478 continue;
nuclear@0 479 }
nuclear@0 480 if (TokenMatch(filePtr,"SCENE_AMBIENT_STATIC",20))
nuclear@0 481
nuclear@0 482 {
nuclear@0 483 // parse a color triple and assume it is really the bg color
nuclear@0 484 ParseLV4MeshFloatTriple( &m_clrAmbient.r );
nuclear@0 485 continue;
nuclear@0 486 }
nuclear@0 487 if (TokenMatch(filePtr,"SCENE_FIRSTFRAME",16))
nuclear@0 488 {
nuclear@0 489 ParseLV4MeshLong(iFirstFrame);
nuclear@0 490 continue;
nuclear@0 491 }
nuclear@0 492 if (TokenMatch(filePtr,"SCENE_LASTFRAME",15))
nuclear@0 493 {
nuclear@0 494 ParseLV4MeshLong(iLastFrame);
nuclear@0 495 continue;
nuclear@0 496 }
nuclear@0 497 if (TokenMatch(filePtr,"SCENE_FRAMESPEED",16))
nuclear@0 498 {
nuclear@0 499 ParseLV4MeshLong(iFrameSpeed);
nuclear@0 500 continue;
nuclear@0 501 }
nuclear@0 502 if (TokenMatch(filePtr,"SCENE_TICKSPERFRAME",19))
nuclear@0 503 {
nuclear@0 504 ParseLV4MeshLong(iTicksPerFrame);
nuclear@0 505 continue;
nuclear@0 506 }
nuclear@0 507 }
nuclear@0 508 AI_ASE_HANDLE_TOP_LEVEL_SECTION();
nuclear@0 509 }
nuclear@0 510 }
nuclear@0 511
nuclear@0 512 // ------------------------------------------------------------------------------------------------
nuclear@0 513 void Parser::ParseLV1MaterialListBlock()
nuclear@0 514 {
nuclear@0 515 AI_ASE_PARSER_INIT();
nuclear@0 516
nuclear@0 517 unsigned int iMaterialCount = 0;
nuclear@0 518 unsigned int iOldMaterialCount = (unsigned int)m_vMaterials.size();
nuclear@0 519 while (true)
nuclear@0 520 {
nuclear@0 521 if ('*' == *filePtr)
nuclear@0 522 {
nuclear@0 523 ++filePtr;
nuclear@0 524 if (TokenMatch(filePtr,"MATERIAL_COUNT",14))
nuclear@0 525 {
nuclear@0 526 ParseLV4MeshLong(iMaterialCount);
nuclear@0 527
nuclear@0 528 // now allocate enough storage to hold all materials
nuclear@0 529 m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
nuclear@0 530 continue;
nuclear@0 531 }
nuclear@0 532 if (TokenMatch(filePtr,"MATERIAL",8))
nuclear@0 533 {
nuclear@0 534 unsigned int iIndex = 0;
nuclear@0 535 ParseLV4MeshLong(iIndex);
nuclear@0 536
nuclear@0 537 if (iIndex >= iMaterialCount)
nuclear@0 538 {
nuclear@0 539 LogWarning("Out of range: material index is too large");
nuclear@0 540 iIndex = iMaterialCount-1;
nuclear@0 541 }
nuclear@0 542
nuclear@0 543 // get a reference to the material
nuclear@0 544 Material& sMat = m_vMaterials[iIndex+iOldMaterialCount];
nuclear@0 545 // parse the material block
nuclear@0 546 ParseLV2MaterialBlock(sMat);
nuclear@0 547 continue;
nuclear@0 548 }
nuclear@0 549 }
nuclear@0 550 AI_ASE_HANDLE_TOP_LEVEL_SECTION();
nuclear@0 551 }
nuclear@0 552 }
nuclear@0 553
nuclear@0 554 // ------------------------------------------------------------------------------------------------
nuclear@0 555 void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
nuclear@0 556 {
nuclear@0 557 AI_ASE_PARSER_INIT();
nuclear@0 558
nuclear@0 559 unsigned int iNumSubMaterials = 0;
nuclear@0 560 while (true)
nuclear@0 561 {
nuclear@0 562 if ('*' == *filePtr)
nuclear@0 563 {
nuclear@0 564 ++filePtr;
nuclear@0 565 if (TokenMatch(filePtr,"MATERIAL_NAME",13))
nuclear@0 566 {
nuclear@0 567 if (!ParseString(mat.mName,"*MATERIAL_NAME"))
nuclear@0 568 SkipToNextToken();
nuclear@0 569 continue;
nuclear@0 570 }
nuclear@0 571 // ambient material color
nuclear@0 572 if (TokenMatch(filePtr,"MATERIAL_AMBIENT",16))
nuclear@0 573 {
nuclear@0 574 ParseLV4MeshFloatTriple(&mat.mAmbient.r);
nuclear@0 575 continue;
nuclear@0 576 }
nuclear@0 577 // diffuse material color
nuclear@0 578 if (TokenMatch(filePtr,"MATERIAL_DIFFUSE",16) )
nuclear@0 579 {
nuclear@0 580 ParseLV4MeshFloatTriple(&mat.mDiffuse.r);
nuclear@0 581 continue;
nuclear@0 582 }
nuclear@0 583 // specular material color
nuclear@0 584 if (TokenMatch(filePtr,"MATERIAL_SPECULAR",17))
nuclear@0 585 {
nuclear@0 586 ParseLV4MeshFloatTriple(&mat.mSpecular.r);
nuclear@0 587 continue;
nuclear@0 588 }
nuclear@0 589 // material shading type
nuclear@0 590 if (TokenMatch(filePtr,"MATERIAL_SHADING",16))
nuclear@0 591 {
nuclear@0 592 if (TokenMatch(filePtr,"Blinn",5))
nuclear@0 593 {
nuclear@0 594 mat.mShading = Discreet3DS::Blinn;
nuclear@0 595 }
nuclear@0 596 else if (TokenMatch(filePtr,"Phong",5))
nuclear@0 597 {
nuclear@0 598 mat.mShading = Discreet3DS::Phong;
nuclear@0 599 }
nuclear@0 600 else if (TokenMatch(filePtr,"Flat",4))
nuclear@0 601 {
nuclear@0 602 mat.mShading = Discreet3DS::Flat;
nuclear@0 603 }
nuclear@0 604 else if (TokenMatch(filePtr,"Wire",4))
nuclear@0 605 {
nuclear@0 606 mat.mShading = Discreet3DS::Wire;
nuclear@0 607 }
nuclear@0 608 else
nuclear@0 609 {
nuclear@0 610 // assume gouraud shading
nuclear@0 611 mat.mShading = Discreet3DS::Gouraud;
nuclear@0 612 SkipToNextToken();
nuclear@0 613 }
nuclear@0 614 continue;
nuclear@0 615 }
nuclear@0 616 // material transparency
nuclear@0 617 if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
nuclear@0 618 {
nuclear@0 619 ParseLV4MeshFloat(mat.mTransparency);
nuclear@0 620 mat.mTransparency = 1.0f - mat.mTransparency;continue;
nuclear@0 621 }
nuclear@0 622 // material self illumination
nuclear@0 623 if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
nuclear@0 624 {
nuclear@0 625 float f = 0.0f;
nuclear@0 626 ParseLV4MeshFloat(f);
nuclear@0 627
nuclear@0 628 mat.mEmissive.r = f;
nuclear@0 629 mat.mEmissive.g = f;
nuclear@0 630 mat.mEmissive.b = f;
nuclear@0 631 continue;
nuclear@0 632 }
nuclear@0 633 // material shininess
nuclear@0 634 if (TokenMatch(filePtr,"MATERIAL_SHINE",14) )
nuclear@0 635 {
nuclear@0 636 ParseLV4MeshFloat(mat.mSpecularExponent);
nuclear@0 637 mat.mSpecularExponent *= 15;
nuclear@0 638 continue;
nuclear@0 639 }
nuclear@0 640 // two-sided material
nuclear@0 641 if (TokenMatch(filePtr,"MATERIAL_TWOSIDED",17) )
nuclear@0 642 {
nuclear@0 643 mat.mTwoSided = true;
nuclear@0 644 continue;
nuclear@0 645 }
nuclear@0 646 // material shininess strength
nuclear@0 647 if (TokenMatch(filePtr,"MATERIAL_SHINESTRENGTH",22))
nuclear@0 648 {
nuclear@0 649 ParseLV4MeshFloat(mat.mShininessStrength);
nuclear@0 650 continue;
nuclear@0 651 }
nuclear@0 652 // diffuse color map
nuclear@0 653 if (TokenMatch(filePtr,"MAP_DIFFUSE",11))
nuclear@0 654 {
nuclear@0 655 // parse the texture block
nuclear@0 656 ParseLV3MapBlock(mat.sTexDiffuse);
nuclear@0 657 continue;
nuclear@0 658 }
nuclear@0 659 // ambient color map
nuclear@0 660 if (TokenMatch(filePtr,"MAP_AMBIENT",11))
nuclear@0 661 {
nuclear@0 662 // parse the texture block
nuclear@0 663 ParseLV3MapBlock(mat.sTexAmbient);
nuclear@0 664 continue;
nuclear@0 665 }
nuclear@0 666 // specular color map
nuclear@0 667 if (TokenMatch(filePtr,"MAP_SPECULAR",12))
nuclear@0 668 {
nuclear@0 669 // parse the texture block
nuclear@0 670 ParseLV3MapBlock(mat.sTexSpecular);
nuclear@0 671 continue;
nuclear@0 672 }
nuclear@0 673 // opacity map
nuclear@0 674 if (TokenMatch(filePtr,"MAP_OPACITY",11))
nuclear@0 675 {
nuclear@0 676 // parse the texture block
nuclear@0 677 ParseLV3MapBlock(mat.sTexOpacity);
nuclear@0 678 continue;
nuclear@0 679 }
nuclear@0 680 // emissive map
nuclear@0 681 if (TokenMatch(filePtr,"MAP_SELFILLUM",13))
nuclear@0 682 {
nuclear@0 683 // parse the texture block
nuclear@0 684 ParseLV3MapBlock(mat.sTexEmissive);
nuclear@0 685 continue;
nuclear@0 686 }
nuclear@0 687 // bump map
nuclear@0 688 if (TokenMatch(filePtr,"MAP_BUMP",8))
nuclear@0 689 {
nuclear@0 690 // parse the texture block
nuclear@0 691 ParseLV3MapBlock(mat.sTexBump);
nuclear@0 692 }
nuclear@0 693 // specular/shininess map
nuclear@0 694 if (TokenMatch(filePtr,"MAP_SHINESTRENGTH",17))
nuclear@0 695 {
nuclear@0 696 // parse the texture block
nuclear@0 697 ParseLV3MapBlock(mat.sTexShininess);
nuclear@0 698 continue;
nuclear@0 699 }
nuclear@0 700 // number of submaterials
nuclear@0 701 if (TokenMatch(filePtr,"NUMSUBMTLS",10))
nuclear@0 702 {
nuclear@0 703 ParseLV4MeshLong(iNumSubMaterials);
nuclear@0 704
nuclear@0 705 // allocate enough storage
nuclear@0 706 mat.avSubMaterials.resize(iNumSubMaterials);
nuclear@0 707 }
nuclear@0 708 // submaterial chunks
nuclear@0 709 if (TokenMatch(filePtr,"SUBMATERIAL",11))
nuclear@0 710 {
nuclear@0 711
nuclear@0 712 unsigned int iIndex = 0;
nuclear@0 713 ParseLV4MeshLong(iIndex);
nuclear@0 714
nuclear@0 715 if (iIndex >= iNumSubMaterials)
nuclear@0 716 {
nuclear@0 717 LogWarning("Out of range: submaterial index is too large");
nuclear@0 718 iIndex = iNumSubMaterials-1;
nuclear@0 719 }
nuclear@0 720
nuclear@0 721 // get a reference to the material
nuclear@0 722 Material& sMat = mat.avSubMaterials[iIndex];
nuclear@0 723
nuclear@0 724 // parse the material block
nuclear@0 725 ParseLV2MaterialBlock(sMat);
nuclear@0 726 continue;
nuclear@0 727 }
nuclear@0 728 }
nuclear@0 729 AI_ASE_HANDLE_SECTION("2","*MATERIAL");
nuclear@0 730 }
nuclear@0 731 }
nuclear@0 732
nuclear@0 733 // ------------------------------------------------------------------------------------------------
nuclear@0 734 void Parser::ParseLV3MapBlock(Texture& map)
nuclear@0 735 {
nuclear@0 736 AI_ASE_PARSER_INIT();
nuclear@0 737
nuclear@0 738 // ***********************************************************
nuclear@0 739 // *BITMAP should not be there if *MAP_CLASS is not BITMAP,
nuclear@0 740 // but we need to expect that case ... if the path is
nuclear@0 741 // empty the texture won't be used later.
nuclear@0 742 // ***********************************************************
nuclear@0 743 bool parsePath = true;
nuclear@0 744 while (true)
nuclear@0 745 {
nuclear@0 746 if ('*' == *filePtr)
nuclear@0 747 {
nuclear@0 748 ++filePtr;
nuclear@0 749 // type of map
nuclear@0 750 if (TokenMatch(filePtr,"MAP_CLASS" ,9))
nuclear@0 751 {
nuclear@0 752 std::string temp;
nuclear@0 753 if(!ParseString(temp,"*MAP_CLASS"))
nuclear@0 754 SkipToNextToken();
nuclear@0 755 if (temp != "Bitmap" && temp != "Normal Bump")
nuclear@0 756 {
nuclear@0 757 DefaultLogger::get()->warn("ASE: Skipping unknown map type: " + temp);
nuclear@0 758 parsePath = false;
nuclear@0 759 }
nuclear@0 760 continue;
nuclear@0 761 }
nuclear@0 762 // path to the texture
nuclear@0 763 if (parsePath && TokenMatch(filePtr,"BITMAP" ,6))
nuclear@0 764 {
nuclear@0 765 if(!ParseString(map.mMapName,"*BITMAP"))
nuclear@0 766 SkipToNextToken();
nuclear@0 767
nuclear@0 768 if (map.mMapName == "None")
nuclear@0 769 {
nuclear@0 770 // Files with 'None' as map name are produced by
nuclear@0 771 // an Maja to ASE exporter which name I forgot ..
nuclear@0 772 DefaultLogger::get()->warn("ASE: Skipping invalid map entry");
nuclear@0 773 map.mMapName = "";
nuclear@0 774 }
nuclear@0 775
nuclear@0 776 continue;
nuclear@0 777 }
nuclear@0 778 // offset on the u axis
nuclear@0 779 if (TokenMatch(filePtr,"UVW_U_OFFSET" ,12))
nuclear@0 780 {
nuclear@0 781 ParseLV4MeshFloat(map.mOffsetU);
nuclear@0 782 continue;
nuclear@0 783 }
nuclear@0 784 // offset on the v axis
nuclear@0 785 if (TokenMatch(filePtr,"UVW_V_OFFSET" ,12))
nuclear@0 786 {
nuclear@0 787 ParseLV4MeshFloat(map.mOffsetV);
nuclear@0 788 continue;
nuclear@0 789 }
nuclear@0 790 // tiling on the u axis
nuclear@0 791 if (TokenMatch(filePtr,"UVW_U_TILING" ,12))
nuclear@0 792 {
nuclear@0 793 ParseLV4MeshFloat(map.mScaleU);
nuclear@0 794 continue;
nuclear@0 795 }
nuclear@0 796 // tiling on the v axis
nuclear@0 797 if (TokenMatch(filePtr,"UVW_V_TILING" ,12))
nuclear@0 798 {
nuclear@0 799 ParseLV4MeshFloat(map.mScaleV);
nuclear@0 800 continue;
nuclear@0 801 }
nuclear@0 802 // rotation around the z-axis
nuclear@0 803 if (TokenMatch(filePtr,"UVW_ANGLE" ,9))
nuclear@0 804 {
nuclear@0 805 ParseLV4MeshFloat(map.mRotation);
nuclear@0 806 continue;
nuclear@0 807 }
nuclear@0 808 // map blending factor
nuclear@0 809 if (TokenMatch(filePtr,"MAP_AMOUNT" ,10))
nuclear@0 810 {
nuclear@0 811 ParseLV4MeshFloat(map.mTextureBlend);
nuclear@0 812 continue;
nuclear@0 813 }
nuclear@0 814 }
nuclear@0 815 AI_ASE_HANDLE_SECTION("3","*MAP_XXXXXX");
nuclear@0 816 }
nuclear@0 817 return;
nuclear@0 818 }
nuclear@0 819
nuclear@0 820 // ------------------------------------------------------------------------------------------------
nuclear@0 821 bool Parser::ParseString(std::string& out,const char* szName)
nuclear@0 822 {
nuclear@0 823 char szBuffer[1024];
nuclear@0 824 if (!SkipSpaces(&filePtr))
nuclear@0 825 {
nuclear@0 826
nuclear@0 827 sprintf(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
nuclear@0 828 LogWarning(szBuffer);
nuclear@0 829 return false;
nuclear@0 830 }
nuclear@0 831 // there must be '"'
nuclear@0 832 if ('\"' != *filePtr)
nuclear@0 833 {
nuclear@0 834
nuclear@0 835 sprintf(szBuffer,"Unable to parse %s block: Strings are expected "
nuclear@0 836 "to be enclosed in double quotation marks",szName);
nuclear@0 837 LogWarning(szBuffer);
nuclear@0 838 return false;
nuclear@0 839 }
nuclear@0 840 ++filePtr;
nuclear@0 841 const char* sz = filePtr;
nuclear@0 842 while (true)
nuclear@0 843 {
nuclear@0 844 if ('\"' == *sz)break;
nuclear@0 845 else if ('\0' == *sz)
nuclear@0 846 {
nuclear@0 847 sprintf(szBuffer,"Unable to parse %s block: Strings are expected to "
nuclear@0 848 "be enclosed in double quotation marks but EOF was reached before "
nuclear@0 849 "a closing quotation mark was encountered",szName);
nuclear@0 850 LogWarning(szBuffer);
nuclear@0 851 return false;
nuclear@0 852 }
nuclear@0 853 sz++;
nuclear@0 854 }
nuclear@0 855 out = std::string(filePtr,(uintptr_t)sz-(uintptr_t)filePtr);
nuclear@0 856 filePtr = sz+1;
nuclear@0 857 return true;
nuclear@0 858 }
nuclear@0 859
nuclear@0 860 // ------------------------------------------------------------------------------------------------
nuclear@0 861 void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node)
nuclear@0 862 {
nuclear@0 863 AI_ASE_PARSER_INIT();
nuclear@0 864 while (true)
nuclear@0 865 {
nuclear@0 866 if ('*' == *filePtr)
nuclear@0 867 {
nuclear@0 868 ++filePtr;
nuclear@0 869
nuclear@0 870 // first process common tokens such as node name and transform
nuclear@0 871 // name of the mesh/node
nuclear@0 872 if (TokenMatch(filePtr,"NODE_NAME" ,9))
nuclear@0 873 {
nuclear@0 874 if(!ParseString(node.mName,"*NODE_NAME"))
nuclear@0 875 SkipToNextToken();
nuclear@0 876 continue;
nuclear@0 877 }
nuclear@0 878 // name of the parent of the node
nuclear@0 879 if (TokenMatch(filePtr,"NODE_PARENT" ,11) )
nuclear@0 880 {
nuclear@0 881 if(!ParseString(node.mParent,"*NODE_PARENT"))
nuclear@0 882 SkipToNextToken();
nuclear@0 883 continue;
nuclear@0 884 }
nuclear@0 885 // transformation matrix of the node
nuclear@0 886 if (TokenMatch(filePtr,"NODE_TM" ,7))
nuclear@0 887 {
nuclear@0 888 ParseLV2NodeTransformBlock(node);
nuclear@0 889 continue;
nuclear@0 890 }
nuclear@0 891 // animation data of the node
nuclear@0 892 if (TokenMatch(filePtr,"TM_ANIMATION" ,12))
nuclear@0 893 {
nuclear@0 894 ParseLV2AnimationBlock(node);
nuclear@0 895 continue;
nuclear@0 896 }
nuclear@0 897
nuclear@0 898 if (node.mType == BaseNode::Light)
nuclear@0 899 {
nuclear@0 900 // light settings
nuclear@0 901 if (TokenMatch(filePtr,"LIGHT_SETTINGS" ,14))
nuclear@0 902 {
nuclear@0 903 ParseLV2LightSettingsBlock((ASE::Light&)node);
nuclear@0 904 continue;
nuclear@0 905 }
nuclear@0 906 // type of the light source
nuclear@0 907 if (TokenMatch(filePtr,"LIGHT_TYPE" ,10))
nuclear@0 908 {
nuclear@0 909 if (!ASSIMP_strincmp("omni",filePtr,4))
nuclear@0 910 {
nuclear@0 911 ((ASE::Light&)node).mLightType = ASE::Light::OMNI;
nuclear@0 912 }
nuclear@0 913 else if (!ASSIMP_strincmp("target",filePtr,6))
nuclear@0 914 {
nuclear@0 915 ((ASE::Light&)node).mLightType = ASE::Light::TARGET;
nuclear@0 916 }
nuclear@0 917 else if (!ASSIMP_strincmp("free",filePtr,4))
nuclear@0 918 {
nuclear@0 919 ((ASE::Light&)node).mLightType = ASE::Light::FREE;
nuclear@0 920 }
nuclear@0 921 else if (!ASSIMP_strincmp("directional",filePtr,11))
nuclear@0 922 {
nuclear@0 923 ((ASE::Light&)node).mLightType = ASE::Light::DIRECTIONAL;
nuclear@0 924 }
nuclear@0 925 else
nuclear@0 926 {
nuclear@0 927 LogWarning("Unknown kind of light source");
nuclear@0 928 }
nuclear@0 929 continue;
nuclear@0 930 }
nuclear@0 931 }
nuclear@0 932 else if (node.mType == BaseNode::Camera)
nuclear@0 933 {
nuclear@0 934 // Camera settings
nuclear@0 935 if (TokenMatch(filePtr,"CAMERA_SETTINGS" ,15))
nuclear@0 936 {
nuclear@0 937 ParseLV2CameraSettingsBlock((ASE::Camera&)node);
nuclear@0 938 continue;
nuclear@0 939 }
nuclear@0 940 else if (TokenMatch(filePtr,"CAMERA_TYPE" ,11))
nuclear@0 941 {
nuclear@0 942 if (!ASSIMP_strincmp("target",filePtr,6))
nuclear@0 943 {
nuclear@0 944 ((ASE::Camera&)node).mCameraType = ASE::Camera::TARGET;
nuclear@0 945 }
nuclear@0 946 else if (!ASSIMP_strincmp("free",filePtr,4))
nuclear@0 947 {
nuclear@0 948 ((ASE::Camera&)node).mCameraType = ASE::Camera::FREE;
nuclear@0 949 }
nuclear@0 950 else
nuclear@0 951 {
nuclear@0 952 LogWarning("Unknown kind of camera");
nuclear@0 953 }
nuclear@0 954 continue;
nuclear@0 955 }
nuclear@0 956 }
nuclear@0 957 else if (node.mType == BaseNode::Mesh)
nuclear@0 958 {
nuclear@0 959 // mesh data
nuclear@0 960 // FIX: Older files use MESH_SOFTSKIN
nuclear@0 961 if (TokenMatch(filePtr,"MESH" ,4) ||
nuclear@0 962 TokenMatch(filePtr,"MESH_SOFTSKIN",13))
nuclear@0 963 {
nuclear@0 964 ParseLV2MeshBlock((ASE::Mesh&)node);
nuclear@0 965 continue;
nuclear@0 966 }
nuclear@0 967 // mesh material index
nuclear@0 968 if (TokenMatch(filePtr,"MATERIAL_REF" ,12))
nuclear@0 969 {
nuclear@0 970 ParseLV4MeshLong(((ASE::Mesh&)node).iMaterialIndex);
nuclear@0 971 continue;
nuclear@0 972 }
nuclear@0 973 }
nuclear@0 974 }
nuclear@0 975 AI_ASE_HANDLE_TOP_LEVEL_SECTION();
nuclear@0 976 }
nuclear@0 977 return;
nuclear@0 978 }
nuclear@0 979
nuclear@0 980 // ------------------------------------------------------------------------------------------------
nuclear@0 981 void Parser::ParseLV2CameraSettingsBlock(ASE::Camera& camera)
nuclear@0 982 {
nuclear@0 983 AI_ASE_PARSER_INIT();
nuclear@0 984 while (true)
nuclear@0 985 {
nuclear@0 986 if ('*' == *filePtr)
nuclear@0 987 {
nuclear@0 988 ++filePtr;
nuclear@0 989 if (TokenMatch(filePtr,"CAMERA_NEAR" ,11))
nuclear@0 990 {
nuclear@0 991 ParseLV4MeshFloat(camera.mNear);
nuclear@0 992 continue;
nuclear@0 993 }
nuclear@0 994 if (TokenMatch(filePtr,"CAMERA_FAR" ,10))
nuclear@0 995 {
nuclear@0 996 ParseLV4MeshFloat(camera.mFar);
nuclear@0 997 continue;
nuclear@0 998 }
nuclear@0 999 if (TokenMatch(filePtr,"CAMERA_FOV" ,10))
nuclear@0 1000 {
nuclear@0 1001 ParseLV4MeshFloat(camera.mFOV);
nuclear@0 1002 continue;
nuclear@0 1003 }
nuclear@0 1004 }
nuclear@0 1005 AI_ASE_HANDLE_SECTION("2","CAMERA_SETTINGS");
nuclear@0 1006 }
nuclear@0 1007 return;
nuclear@0 1008 }
nuclear@0 1009
nuclear@0 1010 // ------------------------------------------------------------------------------------------------
nuclear@0 1011 void Parser::ParseLV2LightSettingsBlock(ASE::Light& light)
nuclear@0 1012 {
nuclear@0 1013 AI_ASE_PARSER_INIT();
nuclear@0 1014 while (true)
nuclear@0 1015 {
nuclear@0 1016 if ('*' == *filePtr)
nuclear@0 1017 {
nuclear@0 1018 ++filePtr;
nuclear@0 1019 if (TokenMatch(filePtr,"LIGHT_COLOR" ,11))
nuclear@0 1020 {
nuclear@0 1021 ParseLV4MeshFloatTriple(&light.mColor.r);
nuclear@0 1022 continue;
nuclear@0 1023 }
nuclear@0 1024 if (TokenMatch(filePtr,"LIGHT_INTENS" ,12))
nuclear@0 1025 {
nuclear@0 1026 ParseLV4MeshFloat(light.mIntensity);
nuclear@0 1027 continue;
nuclear@0 1028 }
nuclear@0 1029 if (TokenMatch(filePtr,"LIGHT_HOTSPOT" ,13))
nuclear@0 1030 {
nuclear@0 1031 ParseLV4MeshFloat(light.mAngle);
nuclear@0 1032 continue;
nuclear@0 1033 }
nuclear@0 1034 if (TokenMatch(filePtr,"LIGHT_FALLOFF" ,13))
nuclear@0 1035 {
nuclear@0 1036 ParseLV4MeshFloat(light.mFalloff);
nuclear@0 1037 continue;
nuclear@0 1038 }
nuclear@0 1039 }
nuclear@0 1040 AI_ASE_HANDLE_SECTION("2","LIGHT_SETTINGS");
nuclear@0 1041 }
nuclear@0 1042 return;
nuclear@0 1043 }
nuclear@0 1044
nuclear@0 1045 // ------------------------------------------------------------------------------------------------
nuclear@0 1046 void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
nuclear@0 1047 {
nuclear@0 1048 AI_ASE_PARSER_INIT();
nuclear@0 1049
nuclear@0 1050 ASE::Animation* anim = &mesh.mAnim;
nuclear@0 1051 while (true)
nuclear@0 1052 {
nuclear@0 1053 if ('*' == *filePtr)
nuclear@0 1054 {
nuclear@0 1055 ++filePtr;
nuclear@0 1056 if (TokenMatch(filePtr,"NODE_NAME" ,9))
nuclear@0 1057 {
nuclear@0 1058 std::string temp;
nuclear@0 1059 if(!ParseString(temp,"*NODE_NAME"))
nuclear@0 1060 SkipToNextToken();
nuclear@0 1061
nuclear@0 1062 // If the name of the node contains .target it
nuclear@0 1063 // represents an animated camera or spot light
nuclear@0 1064 // target.
nuclear@0 1065 if (std::string::npos != temp.find(".Target"))
nuclear@0 1066 {
nuclear@0 1067 if ((mesh.mType != BaseNode::Camera || ((ASE::Camera&)mesh).mCameraType != ASE::Camera::TARGET) &&
nuclear@0 1068 ( mesh.mType != BaseNode::Light || ((ASE::Light&)mesh).mLightType != ASE::Light::TARGET))
nuclear@0 1069 {
nuclear@0 1070
nuclear@0 1071 DefaultLogger::get()->error("ASE: Found target animation channel "
nuclear@0 1072 "but the node is neither a camera nor a spot light");
nuclear@0 1073 anim = NULL;
nuclear@0 1074 }
nuclear@0 1075 else anim = &mesh.mTargetAnim;
nuclear@0 1076 }
nuclear@0 1077 continue;
nuclear@0 1078 }
nuclear@0 1079
nuclear@0 1080 // position keyframes
nuclear@0 1081 if (TokenMatch(filePtr,"CONTROL_POS_TRACK" ,17) ||
nuclear@0 1082 TokenMatch(filePtr,"CONTROL_POS_BEZIER" ,18) ||
nuclear@0 1083 TokenMatch(filePtr,"CONTROL_POS_TCB" ,15))
nuclear@0 1084 {
nuclear@0 1085 if (!anim)SkipSection();
nuclear@0 1086 else ParseLV3PosAnimationBlock(*anim);
nuclear@0 1087 continue;
nuclear@0 1088 }
nuclear@0 1089 // scaling keyframes
nuclear@0 1090 if (TokenMatch(filePtr,"CONTROL_SCALE_TRACK" ,19) ||
nuclear@0 1091 TokenMatch(filePtr,"CONTROL_SCALE_BEZIER" ,20) ||
nuclear@0 1092 TokenMatch(filePtr,"CONTROL_SCALE_TCB" ,17))
nuclear@0 1093 {
nuclear@0 1094 if (!anim || anim == &mesh.mTargetAnim)
nuclear@0 1095 {
nuclear@0 1096 // Target animation channels may have no rotation channels
nuclear@0 1097 DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation");
nuclear@0 1098 SkipSection();
nuclear@0 1099 }
nuclear@0 1100 else ParseLV3ScaleAnimationBlock(*anim);
nuclear@0 1101 continue;
nuclear@0 1102 }
nuclear@0 1103 // rotation keyframes
nuclear@0 1104 if (TokenMatch(filePtr,"CONTROL_ROT_TRACK" ,17) ||
nuclear@0 1105 TokenMatch(filePtr,"CONTROL_ROT_BEZIER" ,18) ||
nuclear@0 1106 TokenMatch(filePtr,"CONTROL_ROT_TCB" ,15))
nuclear@0 1107 {
nuclear@0 1108 if (!anim || anim == &mesh.mTargetAnim)
nuclear@0 1109 {
nuclear@0 1110 // Target animation channels may have no rotation channels
nuclear@0 1111 DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation");
nuclear@0 1112 SkipSection();
nuclear@0 1113 }
nuclear@0 1114 else ParseLV3RotAnimationBlock(*anim);
nuclear@0 1115 continue;
nuclear@0 1116 }
nuclear@0 1117 }
nuclear@0 1118 AI_ASE_HANDLE_SECTION("2","TM_ANIMATION");
nuclear@0 1119 }
nuclear@0 1120 }
nuclear@0 1121 // ------------------------------------------------------------------------------------------------
nuclear@0 1122 void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
nuclear@0 1123 {
nuclear@0 1124 AI_ASE_PARSER_INIT();
nuclear@0 1125 unsigned int iIndex;
nuclear@0 1126
nuclear@0 1127 while (true)
nuclear@0 1128 {
nuclear@0 1129 if ('*' == *filePtr)
nuclear@0 1130 {
nuclear@0 1131 ++filePtr;
nuclear@0 1132
nuclear@0 1133 bool b = false;
nuclear@0 1134
nuclear@0 1135 // For the moment we're just reading the three floats -
nuclear@0 1136 // we ignore the ádditional information for bezier's and TCBs
nuclear@0 1137
nuclear@0 1138 // simple scaling keyframe
nuclear@0 1139 if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
nuclear@0 1140 {
nuclear@0 1141 b = true;
nuclear@0 1142 anim.mScalingType = ASE::Animation::TRACK;
nuclear@0 1143 }
nuclear@0 1144
nuclear@0 1145 // Bezier scaling keyframe
nuclear@0 1146 if (TokenMatch(filePtr,"CONTROL_BEZIER_SCALE_KEY" ,24))
nuclear@0 1147 {
nuclear@0 1148 b = true;
nuclear@0 1149 anim.mScalingType = ASE::Animation::BEZIER;
nuclear@0 1150 }
nuclear@0 1151 // TCB scaling keyframe
nuclear@0 1152 if (TokenMatch(filePtr,"CONTROL_TCB_SCALE_KEY" ,21))
nuclear@0 1153 {
nuclear@0 1154 b = true;
nuclear@0 1155 anim.mScalingType = ASE::Animation::TCB;
nuclear@0 1156 }
nuclear@0 1157 if (b)
nuclear@0 1158 {
nuclear@0 1159 anim.akeyScaling.push_back(aiVectorKey());
nuclear@0 1160 aiVectorKey& key = anim.akeyScaling.back();
nuclear@0 1161 ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
nuclear@0 1162 key.mTime = (double)iIndex;
nuclear@0 1163 }
nuclear@0 1164 }
nuclear@0 1165 AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
nuclear@0 1166 }
nuclear@0 1167 }
nuclear@0 1168 // ------------------------------------------------------------------------------------------------
nuclear@0 1169 void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
nuclear@0 1170 {
nuclear@0 1171 AI_ASE_PARSER_INIT();
nuclear@0 1172 unsigned int iIndex;
nuclear@0 1173 while (true)
nuclear@0 1174 {
nuclear@0 1175 if ('*' == *filePtr)
nuclear@0 1176 {
nuclear@0 1177 ++filePtr;
nuclear@0 1178
nuclear@0 1179 bool b = false;
nuclear@0 1180
nuclear@0 1181 // For the moment we're just reading the three floats -
nuclear@0 1182 // we ignore the ádditional information for bezier's and TCBs
nuclear@0 1183
nuclear@0 1184 // simple scaling keyframe
nuclear@0 1185 if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
nuclear@0 1186 {
nuclear@0 1187 b = true;
nuclear@0 1188 anim.mPositionType = ASE::Animation::TRACK;
nuclear@0 1189 }
nuclear@0 1190
nuclear@0 1191 // Bezier scaling keyframe
nuclear@0 1192 if (TokenMatch(filePtr,"CONTROL_BEZIER_POS_KEY" ,22))
nuclear@0 1193 {
nuclear@0 1194 b = true;
nuclear@0 1195 anim.mPositionType = ASE::Animation::BEZIER;
nuclear@0 1196 }
nuclear@0 1197 // TCB scaling keyframe
nuclear@0 1198 if (TokenMatch(filePtr,"CONTROL_TCB_POS_KEY" ,19))
nuclear@0 1199 {
nuclear@0 1200 b = true;
nuclear@0 1201 anim.mPositionType = ASE::Animation::TCB;
nuclear@0 1202 }
nuclear@0 1203 if (b)
nuclear@0 1204 {
nuclear@0 1205 anim.akeyPositions.push_back(aiVectorKey());
nuclear@0 1206 aiVectorKey& key = anim.akeyPositions.back();
nuclear@0 1207 ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
nuclear@0 1208 key.mTime = (double)iIndex;
nuclear@0 1209 }
nuclear@0 1210 }
nuclear@0 1211 AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
nuclear@0 1212 }
nuclear@0 1213 }
nuclear@0 1214 // ------------------------------------------------------------------------------------------------
nuclear@0 1215 void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
nuclear@0 1216 {
nuclear@0 1217 AI_ASE_PARSER_INIT();
nuclear@0 1218 unsigned int iIndex;
nuclear@0 1219 while (true)
nuclear@0 1220 {
nuclear@0 1221 if ('*' == *filePtr)
nuclear@0 1222 {
nuclear@0 1223 ++filePtr;
nuclear@0 1224
nuclear@0 1225 bool b = false;
nuclear@0 1226
nuclear@0 1227 // For the moment we're just reading the floats -
nuclear@0 1228 // we ignore the ádditional information for bezier's and TCBs
nuclear@0 1229
nuclear@0 1230 // simple scaling keyframe
nuclear@0 1231 if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))
nuclear@0 1232 {
nuclear@0 1233 b = true;
nuclear@0 1234 anim.mRotationType = ASE::Animation::TRACK;
nuclear@0 1235 }
nuclear@0 1236
nuclear@0 1237 // Bezier scaling keyframe
nuclear@0 1238 if (TokenMatch(filePtr,"CONTROL_BEZIER_ROT_KEY" ,22))
nuclear@0 1239 {
nuclear@0 1240 b = true;
nuclear@0 1241 anim.mRotationType = ASE::Animation::BEZIER;
nuclear@0 1242 }
nuclear@0 1243 // TCB scaling keyframe
nuclear@0 1244 if (TokenMatch(filePtr,"CONTROL_TCB_ROT_KEY" ,19))
nuclear@0 1245 {
nuclear@0 1246 b = true;
nuclear@0 1247 anim.mRotationType = ASE::Animation::TCB;
nuclear@0 1248 }
nuclear@0 1249 if (b)
nuclear@0 1250 {
nuclear@0 1251 anim.akeyRotations.push_back(aiQuatKey());
nuclear@0 1252 aiQuatKey& key = anim.akeyRotations.back();
nuclear@0 1253 aiVector3D v;float f;
nuclear@0 1254 ParseLV4MeshFloatTriple(&v.x,iIndex);
nuclear@0 1255 ParseLV4MeshFloat(f);
nuclear@0 1256 key.mTime = (double)iIndex;
nuclear@0 1257 key.mValue = aiQuaternion(v,f);
nuclear@0 1258 }
nuclear@0 1259 }
nuclear@0 1260 AI_ASE_HANDLE_SECTION("3","*CONTROL_ROT_TRACK");
nuclear@0 1261 }
nuclear@0 1262 }
nuclear@0 1263 // ------------------------------------------------------------------------------------------------
nuclear@0 1264 void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
nuclear@0 1265 {
nuclear@0 1266 AI_ASE_PARSER_INIT();
nuclear@0 1267 int mode = 0;
nuclear@0 1268 while (true)
nuclear@0 1269 {
nuclear@0 1270 if ('*' == *filePtr)
nuclear@0 1271 {
nuclear@0 1272 ++filePtr;
nuclear@0 1273 // name of the node
nuclear@0 1274 if (TokenMatch(filePtr,"NODE_NAME" ,9))
nuclear@0 1275 {
nuclear@0 1276 std::string temp;
nuclear@0 1277 if(!ParseString(temp,"*NODE_NAME"))
nuclear@0 1278 SkipToNextToken();
nuclear@0 1279
nuclear@0 1280 std::string::size_type s;
nuclear@0 1281 if (temp == mesh.mName)
nuclear@0 1282 {
nuclear@0 1283 mode = 1;
nuclear@0 1284 }
nuclear@0 1285 else if (std::string::npos != (s = temp.find(".Target")) &&
nuclear@0 1286 mesh.mName == temp.substr(0,s))
nuclear@0 1287 {
nuclear@0 1288 // This should be either a target light or a target camera
nuclear@0 1289 if ( (mesh.mType == BaseNode::Light && ((ASE::Light&)mesh) .mLightType == ASE::Light::TARGET) ||
nuclear@0 1290 (mesh.mType == BaseNode::Camera && ((ASE::Camera&)mesh).mCameraType == ASE::Camera::TARGET))
nuclear@0 1291 {
nuclear@0 1292 mode = 2;
nuclear@0 1293 }
nuclear@0 1294 else DefaultLogger::get()->error("ASE: Ignoring target transform, "
nuclear@0 1295 "this is no spot light or target camera");
nuclear@0 1296 }
nuclear@0 1297 else
nuclear@0 1298 {
nuclear@0 1299 DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp);
nuclear@0 1300 // mode = 0
nuclear@0 1301 }
nuclear@0 1302 continue;
nuclear@0 1303 }
nuclear@0 1304 if (mode)
nuclear@0 1305 {
nuclear@0 1306 // fourth row of the transformation matrix - and also the
nuclear@0 1307 // only information here that is interesting for targets
nuclear@0 1308 if (TokenMatch(filePtr,"TM_ROW3" ,7))
nuclear@0 1309 {
nuclear@0 1310 ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
nuclear@0 1311 continue;
nuclear@0 1312 }
nuclear@0 1313 if (mode == 1)
nuclear@0 1314 {
nuclear@0 1315 // first row of the transformation matrix
nuclear@0 1316 if (TokenMatch(filePtr,"TM_ROW0" ,7))
nuclear@0 1317 {
nuclear@0 1318 ParseLV4MeshFloatTriple(mesh.mTransform[0]);
nuclear@0 1319 continue;
nuclear@0 1320 }
nuclear@0 1321 // second row of the transformation matrix
nuclear@0 1322 if (TokenMatch(filePtr,"TM_ROW1" ,7))
nuclear@0 1323 {
nuclear@0 1324 ParseLV4MeshFloatTriple(mesh.mTransform[1]);
nuclear@0 1325 continue;
nuclear@0 1326 }
nuclear@0 1327 // third row of the transformation matrix
nuclear@0 1328 if (TokenMatch(filePtr,"TM_ROW2" ,7))
nuclear@0 1329 {
nuclear@0 1330 ParseLV4MeshFloatTriple(mesh.mTransform[2]);
nuclear@0 1331 continue;
nuclear@0 1332 }
nuclear@0 1333 // inherited position axes
nuclear@0 1334 if (TokenMatch(filePtr,"INHERIT_POS" ,11))
nuclear@0 1335 {
nuclear@0 1336 unsigned int aiVal[3];
nuclear@0 1337 ParseLV4MeshLongTriple(aiVal);
nuclear@0 1338
nuclear@0 1339 for (unsigned int i = 0; i < 3;++i)
nuclear@0 1340 mesh.inherit.abInheritPosition[i] = aiVal[i] != 0;
nuclear@0 1341 continue;
nuclear@0 1342 }
nuclear@0 1343 // inherited rotation axes
nuclear@0 1344 if (TokenMatch(filePtr,"INHERIT_ROT" ,11))
nuclear@0 1345 {
nuclear@0 1346 unsigned int aiVal[3];
nuclear@0 1347 ParseLV4MeshLongTriple(aiVal);
nuclear@0 1348
nuclear@0 1349 for (unsigned int i = 0; i < 3;++i)
nuclear@0 1350 mesh.inherit.abInheritRotation[i] = aiVal[i] != 0;
nuclear@0 1351 continue;
nuclear@0 1352 }
nuclear@0 1353 // inherited scaling axes
nuclear@0 1354 if (TokenMatch(filePtr,"INHERIT_SCL" ,11))
nuclear@0 1355 {
nuclear@0 1356 unsigned int aiVal[3];
nuclear@0 1357 ParseLV4MeshLongTriple(aiVal);
nuclear@0 1358
nuclear@0 1359 for (unsigned int i = 0; i < 3;++i)
nuclear@0 1360 mesh.inherit.abInheritScaling[i] = aiVal[i] != 0;
nuclear@0 1361 continue;
nuclear@0 1362 }
nuclear@0 1363 }
nuclear@0 1364 }
nuclear@0 1365 }
nuclear@0 1366 AI_ASE_HANDLE_SECTION("2","*NODE_TM");
nuclear@0 1367 }
nuclear@0 1368 return;
nuclear@0 1369 }
nuclear@0 1370 // ------------------------------------------------------------------------------------------------
nuclear@0 1371 void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
nuclear@0 1372 {
nuclear@0 1373 AI_ASE_PARSER_INIT();
nuclear@0 1374
nuclear@0 1375 unsigned int iNumVertices = 0;
nuclear@0 1376 unsigned int iNumFaces = 0;
nuclear@0 1377 unsigned int iNumTVertices = 0;
nuclear@0 1378 unsigned int iNumTFaces = 0;
nuclear@0 1379 unsigned int iNumCVertices = 0;
nuclear@0 1380 unsigned int iNumCFaces = 0;
nuclear@0 1381 while (true)
nuclear@0 1382 {
nuclear@0 1383 if ('*' == *filePtr)
nuclear@0 1384 {
nuclear@0 1385 ++filePtr;
nuclear@0 1386 // Number of vertices in the mesh
nuclear@0 1387 if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
nuclear@0 1388 {
nuclear@0 1389 ParseLV4MeshLong(iNumVertices);
nuclear@0 1390 continue;
nuclear@0 1391 }
nuclear@0 1392 // Number of texture coordinates in the mesh
nuclear@0 1393 if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
nuclear@0 1394 {
nuclear@0 1395 ParseLV4MeshLong(iNumTVertices);
nuclear@0 1396 continue;
nuclear@0 1397 }
nuclear@0 1398 // Number of vertex colors in the mesh
nuclear@0 1399 if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,15))
nuclear@0 1400 {
nuclear@0 1401 ParseLV4MeshLong(iNumCVertices);
nuclear@0 1402 continue;
nuclear@0 1403 }
nuclear@0 1404 // Number of regular faces in the mesh
nuclear@0 1405 if (TokenMatch(filePtr,"MESH_NUMFACES" ,13))
nuclear@0 1406 {
nuclear@0 1407 ParseLV4MeshLong(iNumFaces);
nuclear@0 1408 continue;
nuclear@0 1409 }
nuclear@0 1410 // Number of UVWed faces in the mesh
nuclear@0 1411 if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
nuclear@0 1412 {
nuclear@0 1413 ParseLV4MeshLong(iNumTFaces);
nuclear@0 1414 continue;
nuclear@0 1415 }
nuclear@0 1416 // Number of colored faces in the mesh
nuclear@0 1417 if (TokenMatch(filePtr,"MESH_NUMCVFACES" ,15))
nuclear@0 1418 {
nuclear@0 1419 ParseLV4MeshLong(iNumCFaces);
nuclear@0 1420 continue;
nuclear@0 1421 }
nuclear@0 1422 // mesh vertex list block
nuclear@0 1423 if (TokenMatch(filePtr,"MESH_VERTEX_LIST" ,16))
nuclear@0 1424 {
nuclear@0 1425 ParseLV3MeshVertexListBlock(iNumVertices,mesh);
nuclear@0 1426 continue;
nuclear@0 1427 }
nuclear@0 1428 // mesh face list block
nuclear@0 1429 if (TokenMatch(filePtr,"MESH_FACE_LIST" ,14))
nuclear@0 1430 {
nuclear@0 1431 ParseLV3MeshFaceListBlock(iNumFaces,mesh);
nuclear@0 1432 continue;
nuclear@0 1433 }
nuclear@0 1434 // mesh texture vertex list block
nuclear@0 1435 if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
nuclear@0 1436 {
nuclear@0 1437 ParseLV3MeshTListBlock(iNumTVertices,mesh);
nuclear@0 1438 continue;
nuclear@0 1439 }
nuclear@0 1440 // mesh texture face block
nuclear@0 1441 if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
nuclear@0 1442 {
nuclear@0 1443 ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);
nuclear@0 1444 continue;
nuclear@0 1445 }
nuclear@0 1446 // mesh color vertex list block
nuclear@0 1447 if (TokenMatch(filePtr,"MESH_CVERTLIST" ,14))
nuclear@0 1448 {
nuclear@0 1449 ParseLV3MeshCListBlock(iNumCVertices,mesh);
nuclear@0 1450 continue;
nuclear@0 1451 }
nuclear@0 1452 // mesh color face block
nuclear@0 1453 if (TokenMatch(filePtr,"MESH_CFACELIST" ,14))
nuclear@0 1454 {
nuclear@0 1455 ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);
nuclear@0 1456 continue;
nuclear@0 1457 }
nuclear@0 1458 // mesh normals
nuclear@0 1459 if (TokenMatch(filePtr,"MESH_NORMALS" ,12))
nuclear@0 1460 {
nuclear@0 1461 ParseLV3MeshNormalListBlock(mesh);
nuclear@0 1462 continue;
nuclear@0 1463 }
nuclear@0 1464 // another mesh UV channel ...
nuclear@0 1465 if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19))
nuclear@0 1466 {
nuclear@0 1467
nuclear@0 1468 unsigned int iIndex = 0;
nuclear@0 1469 ParseLV4MeshLong(iIndex);
nuclear@0 1470
nuclear@0 1471 if (iIndex < 2)
nuclear@0 1472 {
nuclear@0 1473 LogWarning("Mapping channel has an invalid index. Skipping UV channel");
nuclear@0 1474 // skip it ...
nuclear@0 1475 SkipSection();
nuclear@0 1476 }
nuclear@0 1477 if (iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS)
nuclear@0 1478 {
nuclear@0 1479 LogWarning("Too many UV channels specified. Skipping channel ..");
nuclear@0 1480 // skip it ...
nuclear@0 1481 SkipSection();
nuclear@0 1482 }
nuclear@0 1483 else
nuclear@0 1484 {
nuclear@0 1485 // parse the mapping channel
nuclear@0 1486 ParseLV3MappingChannel(iIndex-1,mesh);
nuclear@0 1487 }
nuclear@0 1488 continue;
nuclear@0 1489 }
nuclear@0 1490 // mesh animation keyframe. Not supported
nuclear@0 1491 if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
nuclear@0 1492 {
nuclear@0 1493
nuclear@0 1494 LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. "
nuclear@0 1495 "Keyframe animation is not supported by Assimp, this element "
nuclear@0 1496 "will be ignored");
nuclear@0 1497 //SkipSection();
nuclear@0 1498 continue;
nuclear@0 1499 }
nuclear@0 1500 if (TokenMatch(filePtr,"MESH_WEIGHTS" ,12))
nuclear@0 1501 {
nuclear@0 1502 ParseLV3MeshWeightsBlock(mesh);continue;
nuclear@0 1503 }
nuclear@0 1504 }
nuclear@0 1505 AI_ASE_HANDLE_SECTION("2","*MESH");
nuclear@0 1506 }
nuclear@0 1507 return;
nuclear@0 1508 }
nuclear@0 1509 // ------------------------------------------------------------------------------------------------
nuclear@0 1510 void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
nuclear@0 1511 {
nuclear@0 1512 AI_ASE_PARSER_INIT();
nuclear@0 1513
nuclear@0 1514 unsigned int iNumVertices = 0, iNumBones = 0;
nuclear@0 1515 while (true)
nuclear@0 1516 {
nuclear@0 1517 if ('*' == *filePtr)
nuclear@0 1518 {
nuclear@0 1519 ++filePtr;
nuclear@0 1520
nuclear@0 1521 // Number of bone vertices ...
nuclear@0 1522 if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
nuclear@0 1523 {
nuclear@0 1524 ParseLV4MeshLong(iNumVertices);
nuclear@0 1525 continue;
nuclear@0 1526 }
nuclear@0 1527 // Number of bones
nuclear@0 1528 if (TokenMatch(filePtr,"MESH_NUMBONE" ,11))
nuclear@0 1529 {
nuclear@0 1530 ParseLV4MeshLong(iNumBones);
nuclear@0 1531 continue;
nuclear@0 1532 }
nuclear@0 1533 // parse the list of bones
nuclear@0 1534 if (TokenMatch(filePtr,"MESH_BONE_LIST" ,14))
nuclear@0 1535 {
nuclear@0 1536 ParseLV4MeshBones(iNumBones,mesh);
nuclear@0 1537 continue;
nuclear@0 1538 }
nuclear@0 1539 // parse the list of bones vertices
nuclear@0 1540 if (TokenMatch(filePtr,"MESH_BONE_VERTEX_LIST" ,21) )
nuclear@0 1541 {
nuclear@0 1542 ParseLV4MeshBonesVertices(iNumVertices,mesh);
nuclear@0 1543 continue;
nuclear@0 1544 }
nuclear@0 1545 }
nuclear@0 1546 AI_ASE_HANDLE_SECTION("3","*MESH_WEIGHTS");
nuclear@0 1547 }
nuclear@0 1548 return;
nuclear@0 1549 }
nuclear@0 1550 // ------------------------------------------------------------------------------------------------
nuclear@0 1551 void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
nuclear@0 1552 {
nuclear@0 1553 AI_ASE_PARSER_INIT();
nuclear@0 1554 mesh.mBones.resize(iNumBones);
nuclear@0 1555 while (true)
nuclear@0 1556 {
nuclear@0 1557 if ('*' == *filePtr)
nuclear@0 1558 {
nuclear@0 1559 ++filePtr;
nuclear@0 1560
nuclear@0 1561 // Mesh bone with name ...
nuclear@0 1562 if (TokenMatch(filePtr,"MESH_BONE_NAME" ,16))
nuclear@0 1563 {
nuclear@0 1564 // parse an index ...
nuclear@0 1565 if(SkipSpaces(&filePtr))
nuclear@0 1566 {
nuclear@0 1567 unsigned int iIndex = strtoul10(filePtr,&filePtr);
nuclear@0 1568 if (iIndex >= iNumBones)
nuclear@0 1569 {
nuclear@0 1570 LogWarning("Bone index is out of bounds");
nuclear@0 1571 continue;
nuclear@0 1572 }
nuclear@0 1573 if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))
nuclear@0 1574 SkipToNextToken();
nuclear@0 1575 continue;
nuclear@0 1576 }
nuclear@0 1577 }
nuclear@0 1578 }
nuclear@0 1579 AI_ASE_HANDLE_SECTION("3","*MESH_BONE_LIST");
nuclear@0 1580 }
nuclear@0 1581 }
nuclear@0 1582 // ------------------------------------------------------------------------------------------------
nuclear@0 1583 void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh)
nuclear@0 1584 {
nuclear@0 1585 AI_ASE_PARSER_INIT();
nuclear@0 1586 mesh.mBoneVertices.resize(iNumVertices);
nuclear@0 1587 while (true)
nuclear@0 1588 {
nuclear@0 1589 if ('*' == *filePtr)
nuclear@0 1590 {
nuclear@0 1591 ++filePtr;
nuclear@0 1592
nuclear@0 1593 // Mesh bone vertex
nuclear@0 1594 if (TokenMatch(filePtr,"MESH_BONE_VERTEX" ,16))
nuclear@0 1595 {
nuclear@0 1596 // read the vertex index
nuclear@0 1597 unsigned int iIndex = strtoul10(filePtr,&filePtr);
nuclear@0 1598 if (iIndex >= mesh.mPositions.size())
nuclear@0 1599 {
nuclear@0 1600 iIndex = (unsigned int)mesh.mPositions.size()-1;
nuclear@0 1601 LogWarning("Bone vertex index is out of bounds. Using the largest valid "
nuclear@0 1602 "bone vertex index instead");
nuclear@0 1603 }
nuclear@0 1604
nuclear@0 1605 // --- ignored
nuclear@0 1606 float afVert[3];
nuclear@0 1607 ParseLV4MeshFloatTriple(afVert);
nuclear@0 1608
nuclear@0 1609 std::pair<int,float> pairOut;
nuclear@0 1610 while (true)
nuclear@0 1611 {
nuclear@0 1612 // first parse the bone index ...
nuclear@0 1613 if (!SkipSpaces(&filePtr))break;
nuclear@0 1614 pairOut.first = strtoul10(filePtr,&filePtr);
nuclear@0 1615
nuclear@0 1616 // then parse the vertex weight
nuclear@0 1617 if (!SkipSpaces(&filePtr))break;
nuclear@0 1618 filePtr = fast_atoreal_move<float>(filePtr,pairOut.second);
nuclear@0 1619
nuclear@0 1620 // -1 marks unused entries
nuclear@0 1621 if (-1 != pairOut.first)
nuclear@0 1622 {
nuclear@0 1623 mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut);
nuclear@0 1624 }
nuclear@0 1625 }
nuclear@0 1626 continue;
nuclear@0 1627 }
nuclear@0 1628 }
nuclear@0 1629 AI_ASE_HANDLE_SECTION("4","*MESH_BONE_VERTEX");
nuclear@0 1630 }
nuclear@0 1631 return;
nuclear@0 1632 }
nuclear@0 1633 // ------------------------------------------------------------------------------------------------
nuclear@0 1634 void Parser::ParseLV3MeshVertexListBlock(
nuclear@0 1635 unsigned int iNumVertices, ASE::Mesh& mesh)
nuclear@0 1636 {
nuclear@0 1637 AI_ASE_PARSER_INIT();
nuclear@0 1638
nuclear@0 1639 // allocate enough storage in the array
nuclear@0 1640 mesh.mPositions.resize(iNumVertices);
nuclear@0 1641 while (true)
nuclear@0 1642 {
nuclear@0 1643 if ('*' == *filePtr)
nuclear@0 1644 {
nuclear@0 1645 ++filePtr;
nuclear@0 1646
nuclear@0 1647 // Vertex entry
nuclear@0 1648 if (TokenMatch(filePtr,"MESH_VERTEX" ,11))
nuclear@0 1649 {
nuclear@0 1650
nuclear@0 1651 aiVector3D vTemp;
nuclear@0 1652 unsigned int iIndex;
nuclear@0 1653 ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
nuclear@0 1654
nuclear@0 1655 if (iIndex >= iNumVertices)
nuclear@0 1656 {
nuclear@0 1657 LogWarning("Invalid vertex index. It will be ignored");
nuclear@0 1658 }
nuclear@0 1659 else mesh.mPositions[iIndex] = vTemp;
nuclear@0 1660 continue;
nuclear@0 1661 }
nuclear@0 1662 }
nuclear@0 1663 AI_ASE_HANDLE_SECTION("3","*MESH_VERTEX_LIST");
nuclear@0 1664 }
nuclear@0 1665 return;
nuclear@0 1666 }
nuclear@0 1667 // ------------------------------------------------------------------------------------------------
nuclear@0 1668 void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
nuclear@0 1669 {
nuclear@0 1670 AI_ASE_PARSER_INIT();
nuclear@0 1671
nuclear@0 1672 // allocate enough storage in the face array
nuclear@0 1673 mesh.mFaces.resize(iNumFaces);
nuclear@0 1674 while (true)
nuclear@0 1675 {
nuclear@0 1676 if ('*' == *filePtr)
nuclear@0 1677 {
nuclear@0 1678 ++filePtr;
nuclear@0 1679
nuclear@0 1680 // Face entry
nuclear@0 1681 if (TokenMatch(filePtr,"MESH_FACE" ,9))
nuclear@0 1682 {
nuclear@0 1683
nuclear@0 1684 ASE::Face mFace;
nuclear@0 1685 ParseLV4MeshFace(mFace);
nuclear@0 1686
nuclear@0 1687 if (mFace.iFace >= iNumFaces)
nuclear@0 1688 {
nuclear@0 1689 LogWarning("Face has an invalid index. It will be ignored");
nuclear@0 1690 }
nuclear@0 1691 else mesh.mFaces[mFace.iFace] = mFace;
nuclear@0 1692 continue;
nuclear@0 1693 }
nuclear@0 1694 }
nuclear@0 1695 AI_ASE_HANDLE_SECTION("3","*MESH_FACE_LIST");
nuclear@0 1696 }
nuclear@0 1697 return;
nuclear@0 1698 }
nuclear@0 1699 // ------------------------------------------------------------------------------------------------
nuclear@0 1700 void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
nuclear@0 1701 ASE::Mesh& mesh, unsigned int iChannel)
nuclear@0 1702 {
nuclear@0 1703 AI_ASE_PARSER_INIT();
nuclear@0 1704
nuclear@0 1705 // allocate enough storage in the array
nuclear@0 1706 mesh.amTexCoords[iChannel].resize(iNumVertices);
nuclear@0 1707 while (true)
nuclear@0 1708 {
nuclear@0 1709 if ('*' == *filePtr)
nuclear@0 1710 {
nuclear@0 1711 ++filePtr;
nuclear@0 1712
nuclear@0 1713 // Vertex entry
nuclear@0 1714 if (TokenMatch(filePtr,"MESH_TVERT" ,10))
nuclear@0 1715 {
nuclear@0 1716 aiVector3D vTemp;
nuclear@0 1717 unsigned int iIndex;
nuclear@0 1718 ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
nuclear@0 1719
nuclear@0 1720 if (iIndex >= iNumVertices)
nuclear@0 1721 {
nuclear@0 1722 LogWarning("Tvertex has an invalid index. It will be ignored");
nuclear@0 1723 }
nuclear@0 1724 else mesh.amTexCoords[iChannel][iIndex] = vTemp;
nuclear@0 1725
nuclear@0 1726 if (0.0f != vTemp.z)
nuclear@0 1727 {
nuclear@0 1728 // we need 3 coordinate channels
nuclear@0 1729 mesh.mNumUVComponents[iChannel] = 3;
nuclear@0 1730 }
nuclear@0 1731 continue;
nuclear@0 1732 }
nuclear@0 1733 }
nuclear@0 1734 AI_ASE_HANDLE_SECTION("3","*MESH_TVERT_LIST");
nuclear@0 1735 }
nuclear@0 1736 return;
nuclear@0 1737 }
nuclear@0 1738 // ------------------------------------------------------------------------------------------------
nuclear@0 1739 void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
nuclear@0 1740 ASE::Mesh& mesh, unsigned int iChannel)
nuclear@0 1741 {
nuclear@0 1742 AI_ASE_PARSER_INIT();
nuclear@0 1743 while (true)
nuclear@0 1744 {
nuclear@0 1745 if ('*' == *filePtr)
nuclear@0 1746 {
nuclear@0 1747 ++filePtr;
nuclear@0 1748
nuclear@0 1749 // Face entry
nuclear@0 1750 if (TokenMatch(filePtr,"MESH_TFACE" ,10))
nuclear@0 1751 {
nuclear@0 1752 unsigned int aiValues[3];
nuclear@0 1753 unsigned int iIndex = 0;
nuclear@0 1754
nuclear@0 1755 ParseLV4MeshLongTriple(aiValues,iIndex);
nuclear@0 1756 if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
nuclear@0 1757 {
nuclear@0 1758 LogWarning("UV-Face has an invalid index. It will be ignored");
nuclear@0 1759 }
nuclear@0 1760 else
nuclear@0 1761 {
nuclear@0 1762 // copy UV indices
nuclear@0 1763 mesh.mFaces[iIndex].amUVIndices[iChannel][0] = aiValues[0];
nuclear@0 1764 mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1];
nuclear@0 1765 mesh.mFaces[iIndex].amUVIndices[iChannel][2] = aiValues[2];
nuclear@0 1766 }
nuclear@0 1767 continue;
nuclear@0 1768 }
nuclear@0 1769 }
nuclear@0 1770 AI_ASE_HANDLE_SECTION("3","*MESH_TFACE_LIST");
nuclear@0 1771 }
nuclear@0 1772 return;
nuclear@0 1773 }
nuclear@0 1774 // ------------------------------------------------------------------------------------------------
nuclear@0 1775 void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
nuclear@0 1776 {
nuclear@0 1777 AI_ASE_PARSER_INIT();
nuclear@0 1778
nuclear@0 1779 unsigned int iNumTVertices = 0;
nuclear@0 1780 unsigned int iNumTFaces = 0;
nuclear@0 1781 while (true)
nuclear@0 1782 {
nuclear@0 1783 if ('*' == *filePtr)
nuclear@0 1784 {
nuclear@0 1785 ++filePtr;
nuclear@0 1786
nuclear@0 1787 // Number of texture coordinates in the mesh
nuclear@0 1788 if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
nuclear@0 1789 {
nuclear@0 1790 ParseLV4MeshLong(iNumTVertices);
nuclear@0 1791 continue;
nuclear@0 1792 }
nuclear@0 1793 // Number of UVWed faces in the mesh
nuclear@0 1794 if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
nuclear@0 1795 {
nuclear@0 1796 ParseLV4MeshLong(iNumTFaces);
nuclear@0 1797 continue;
nuclear@0 1798 }
nuclear@0 1799 // mesh texture vertex list block
nuclear@0 1800 if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
nuclear@0 1801 {
nuclear@0 1802 ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel);
nuclear@0 1803 continue;
nuclear@0 1804 }
nuclear@0 1805 // mesh texture face block
nuclear@0 1806 if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
nuclear@0 1807 {
nuclear@0 1808 ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel);
nuclear@0 1809 continue;
nuclear@0 1810 }
nuclear@0 1811 }
nuclear@0 1812 AI_ASE_HANDLE_SECTION("3","*MESH_MAPPING_CHANNEL");
nuclear@0 1813 }
nuclear@0 1814 return;
nuclear@0 1815 }
nuclear@0 1816 // ------------------------------------------------------------------------------------------------
nuclear@0 1817 void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
nuclear@0 1818 {
nuclear@0 1819 AI_ASE_PARSER_INIT();
nuclear@0 1820
nuclear@0 1821 // allocate enough storage in the array
nuclear@0 1822 mesh.mVertexColors.resize(iNumVertices);
nuclear@0 1823 while (true)
nuclear@0 1824 {
nuclear@0 1825 if ('*' == *filePtr)
nuclear@0 1826 {
nuclear@0 1827 ++filePtr;
nuclear@0 1828
nuclear@0 1829 // Vertex entry
nuclear@0 1830 if (TokenMatch(filePtr,"MESH_VERTCOL" ,12))
nuclear@0 1831 {
nuclear@0 1832 aiColor4D vTemp;
nuclear@0 1833 vTemp.a = 1.0f;
nuclear@0 1834 unsigned int iIndex;
nuclear@0 1835 ParseLV4MeshFloatTriple(&vTemp.r,iIndex);
nuclear@0 1836
nuclear@0 1837 if (iIndex >= iNumVertices)
nuclear@0 1838 {
nuclear@0 1839 LogWarning("Vertex color has an invalid index. It will be ignored");
nuclear@0 1840 }
nuclear@0 1841 else mesh.mVertexColors[iIndex] = vTemp;
nuclear@0 1842 continue;
nuclear@0 1843 }
nuclear@0 1844 }
nuclear@0 1845 AI_ASE_HANDLE_SECTION("3","*MESH_CVERTEX_LIST");
nuclear@0 1846 }
nuclear@0 1847 return;
nuclear@0 1848 }
nuclear@0 1849 // ------------------------------------------------------------------------------------------------
nuclear@0 1850 void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
nuclear@0 1851 {
nuclear@0 1852 AI_ASE_PARSER_INIT();
nuclear@0 1853 while (true)
nuclear@0 1854 {
nuclear@0 1855 if ('*' == *filePtr)
nuclear@0 1856 {
nuclear@0 1857 ++filePtr;
nuclear@0 1858
nuclear@0 1859 // Face entry
nuclear@0 1860 if (TokenMatch(filePtr,"MESH_CFACE" ,11))
nuclear@0 1861 {
nuclear@0 1862 unsigned int aiValues[3];
nuclear@0 1863 unsigned int iIndex = 0;
nuclear@0 1864
nuclear@0 1865 ParseLV4MeshLongTriple(aiValues,iIndex);
nuclear@0 1866 if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
nuclear@0 1867 {
nuclear@0 1868 LogWarning("UV-Face has an invalid index. It will be ignored");
nuclear@0 1869 }
nuclear@0 1870 else
nuclear@0 1871 {
nuclear@0 1872 // copy color indices
nuclear@0 1873 mesh.mFaces[iIndex].mColorIndices[0] = aiValues[0];
nuclear@0 1874 mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1];
nuclear@0 1875 mesh.mFaces[iIndex].mColorIndices[2] = aiValues[2];
nuclear@0 1876 }
nuclear@0 1877 continue;
nuclear@0 1878 }
nuclear@0 1879 }
nuclear@0 1880 AI_ASE_HANDLE_SECTION("3","*MESH_CFACE_LIST");
nuclear@0 1881 }
nuclear@0 1882 return;
nuclear@0 1883 }
nuclear@0 1884 // ------------------------------------------------------------------------------------------------
nuclear@0 1885 void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
nuclear@0 1886 {
nuclear@0 1887 AI_ASE_PARSER_INIT();
nuclear@0 1888
nuclear@0 1889 // Allocate enough storage for the normals
nuclear@0 1890 sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
nuclear@0 1891 unsigned int index, faceIdx = UINT_MAX;
nuclear@0 1892
nuclear@0 1893 // FIXME: rewrite this and find out how to interpret the normals
nuclear@0 1894 // correctly. This is crap.
nuclear@0 1895
nuclear@0 1896 // Smooth the vertex and face normals together. The result
nuclear@0 1897 // will be edgy then, but otherwise everything would be soft ...
nuclear@0 1898 while (true) {
nuclear@0 1899 if ('*' == *filePtr) {
nuclear@0 1900 ++filePtr;
nuclear@0 1901 if (faceIdx != UINT_MAX && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17)) {
nuclear@0 1902 aiVector3D vNormal;
nuclear@0 1903 ParseLV4MeshFloatTriple(&vNormal.x,index);
nuclear@0 1904 if (faceIdx >= sMesh.mFaces.size())
nuclear@0 1905 continue;
nuclear@0 1906
nuclear@0 1907 // Make sure we assign it to the correct face
nuclear@0 1908 const ASE::Face& face = sMesh.mFaces[faceIdx];
nuclear@0 1909 if (index == face.mIndices[0])
nuclear@0 1910 index = 0;
nuclear@0 1911 else if (index == face.mIndices[1])
nuclear@0 1912 index = 1;
nuclear@0 1913 else if (index == face.mIndices[2])
nuclear@0 1914 index = 2;
nuclear@0 1915 else {
nuclear@0 1916 DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
nuclear@0 1917 continue;
nuclear@0 1918 }
nuclear@0 1919 // We'll renormalize later
nuclear@0 1920 sMesh.mNormals[faceIdx*3+index] += vNormal;
nuclear@0 1921 continue;
nuclear@0 1922 }
nuclear@0 1923 if (TokenMatch(filePtr,"MESH_FACENORMAL",15)) {
nuclear@0 1924 aiVector3D vNormal;
nuclear@0 1925 ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
nuclear@0 1926
nuclear@0 1927 if (faceIdx >= sMesh.mFaces.size()) {
nuclear@0 1928 DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
nuclear@0 1929 continue;
nuclear@0 1930 }
nuclear@0 1931
nuclear@0 1932 // We'll renormalize later
nuclear@0 1933 sMesh.mNormals[faceIdx*3] += vNormal;
nuclear@0 1934 sMesh.mNormals[faceIdx*3+1] += vNormal;
nuclear@0 1935 sMesh.mNormals[faceIdx*3+2] += vNormal;
nuclear@0 1936 continue;
nuclear@0 1937 }
nuclear@0 1938 }
nuclear@0 1939 AI_ASE_HANDLE_SECTION("3","*MESH_NORMALS");
nuclear@0 1940 }
nuclear@0 1941 return;
nuclear@0 1942 }
nuclear@0 1943 // ------------------------------------------------------------------------------------------------
nuclear@0 1944 void Parser::ParseLV4MeshFace(ASE::Face& out)
nuclear@0 1945 {
nuclear@0 1946 // skip spaces and tabs
nuclear@0 1947 if(!SkipSpaces(&filePtr))
nuclear@0 1948 {
nuclear@0 1949 LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]");
nuclear@0 1950 SkipToNextToken();
nuclear@0 1951 return;
nuclear@0 1952 }
nuclear@0 1953
nuclear@0 1954 // parse the face index
nuclear@0 1955 out.iFace = strtoul10(filePtr,&filePtr);
nuclear@0 1956
nuclear@0 1957 // next character should be ':'
nuclear@0 1958 if(!SkipSpaces(&filePtr))
nuclear@0 1959 {
nuclear@0 1960 // FIX: there are some ASE files which haven't got : here ....
nuclear@0 1961 LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]");
nuclear@0 1962 SkipToNextToken();
nuclear@0 1963 return;
nuclear@0 1964 }
nuclear@0 1965 // FIX: There are some ASE files which haven't got ':' here
nuclear@0 1966 if(':' == *filePtr)++filePtr;
nuclear@0 1967
nuclear@0 1968 // Parse all mesh indices
nuclear@0 1969 for (unsigned int i = 0; i < 3;++i)
nuclear@0 1970 {
nuclear@0 1971 unsigned int iIndex = 0;
nuclear@0 1972 if(!SkipSpaces(&filePtr))
nuclear@0 1973 {
nuclear@0 1974 LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL");
nuclear@0 1975 SkipToNextToken();
nuclear@0 1976 return;
nuclear@0 1977 }
nuclear@0 1978 switch (*filePtr)
nuclear@0 1979 {
nuclear@0 1980 case 'A':
nuclear@0 1981 case 'a':
nuclear@0 1982 break;
nuclear@0 1983 case 'B':
nuclear@0 1984 case 'b':
nuclear@0 1985 iIndex = 1;
nuclear@0 1986 break;
nuclear@0 1987 case 'C':
nuclear@0 1988 case 'c':
nuclear@0 1989 iIndex = 2;
nuclear@0 1990 break;
nuclear@0 1991 default:
nuclear@0 1992 LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
nuclear@0 1993 "A,B or C expected [#3]");
nuclear@0 1994 SkipToNextToken();
nuclear@0 1995 return;
nuclear@0 1996 };
nuclear@0 1997 ++filePtr;
nuclear@0 1998
nuclear@0 1999 // next character should be ':'
nuclear@0 2000 if(!SkipSpaces(&filePtr) || ':' != *filePtr)
nuclear@0 2001 {
nuclear@0 2002 LogWarning("Unable to parse *MESH_FACE Element: "
nuclear@0 2003 "Unexpected EOL. \':\' expected [#2]");
nuclear@0 2004 SkipToNextToken();
nuclear@0 2005 return;
nuclear@0 2006 }
nuclear@0 2007
nuclear@0 2008 ++filePtr;
nuclear@0 2009 if(!SkipSpaces(&filePtr))
nuclear@0 2010 {
nuclear@0 2011 LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
nuclear@0 2012 "Vertex index ecpected [#4]");
nuclear@0 2013 SkipToNextToken();
nuclear@0 2014 return;
nuclear@0 2015 }
nuclear@0 2016 out.mIndices[iIndex] = strtoul10(filePtr,&filePtr);
nuclear@0 2017 }
nuclear@0 2018
nuclear@0 2019 // now we need to skip the AB, BC, CA blocks.
nuclear@0 2020 while (true)
nuclear@0 2021 {
nuclear@0 2022 if ('*' == *filePtr)break;
nuclear@0 2023 if (IsLineEnd(*filePtr))
nuclear@0 2024 {
nuclear@0 2025 //iLineNumber++;
nuclear@0 2026 return;
nuclear@0 2027 }
nuclear@0 2028 filePtr++;
nuclear@0 2029 }
nuclear@0 2030
nuclear@0 2031 // parse the smoothing group of the face
nuclear@0 2032 if (TokenMatch(filePtr,"*MESH_SMOOTHING",15))
nuclear@0 2033 {
nuclear@0 2034 if(!SkipSpaces(&filePtr))
nuclear@0 2035 {
nuclear@0 2036 LogWarning("Unable to parse *MESH_SMOOTHING Element: "
nuclear@0 2037 "Unexpected EOL. Smoothing group(s) expected [#5]");
nuclear@0 2038 SkipToNextToken();
nuclear@0 2039 return;
nuclear@0 2040 }
nuclear@0 2041
nuclear@0 2042 // Parse smoothing groups until we don't anymore see commas
nuclear@0 2043 // FIX: There needn't always be a value, sad but true
nuclear@0 2044 while (true)
nuclear@0 2045 {
nuclear@0 2046 if (*filePtr < '9' && *filePtr >= '0')
nuclear@0 2047 {
nuclear@0 2048 out.iSmoothGroup |= (1 << strtoul10(filePtr,&filePtr));
nuclear@0 2049 }
nuclear@0 2050 SkipSpaces(&filePtr);
nuclear@0 2051 if (',' != *filePtr)
nuclear@0 2052 {
nuclear@0 2053 break;
nuclear@0 2054 }
nuclear@0 2055 ++filePtr;
nuclear@0 2056 SkipSpaces(&filePtr);
nuclear@0 2057 }
nuclear@0 2058 }
nuclear@0 2059
nuclear@0 2060 // *MESH_MTLID is optional, too
nuclear@0 2061 while (true)
nuclear@0 2062 {
nuclear@0 2063 if ('*' == *filePtr)break;
nuclear@0 2064 if (IsLineEnd(*filePtr))
nuclear@0 2065 {
nuclear@0 2066 return;
nuclear@0 2067 }
nuclear@0 2068 filePtr++;
nuclear@0 2069 }
nuclear@0 2070
nuclear@0 2071 if (TokenMatch(filePtr,"*MESH_MTLID",11))
nuclear@0 2072 {
nuclear@0 2073 if(!SkipSpaces(&filePtr))
nuclear@0 2074 {
nuclear@0 2075 LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. "
nuclear@0 2076 "Material index expected [#6]");
nuclear@0 2077 SkipToNextToken();
nuclear@0 2078 return;
nuclear@0 2079 }
nuclear@0 2080 out.iMaterial = strtoul10(filePtr,&filePtr);
nuclear@0 2081 }
nuclear@0 2082 return;
nuclear@0 2083 }
nuclear@0 2084 // ------------------------------------------------------------------------------------------------
nuclear@0 2085 void Parser::ParseLV4MeshLongTriple(unsigned int* apOut)
nuclear@0 2086 {
nuclear@0 2087 ai_assert(NULL != apOut);
nuclear@0 2088
nuclear@0 2089 for (unsigned int i = 0; i < 3;++i)
nuclear@0 2090 ParseLV4MeshLong(apOut[i]);
nuclear@0 2091 }
nuclear@0 2092 // ------------------------------------------------------------------------------------------------
nuclear@0 2093 void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut)
nuclear@0 2094 {
nuclear@0 2095 ai_assert(NULL != apOut);
nuclear@0 2096
nuclear@0 2097 // parse the index
nuclear@0 2098 ParseLV4MeshLong(rIndexOut);
nuclear@0 2099
nuclear@0 2100 // parse the three others
nuclear@0 2101 ParseLV4MeshLongTriple(apOut);
nuclear@0 2102 }
nuclear@0 2103 // ------------------------------------------------------------------------------------------------
nuclear@0 2104 void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
nuclear@0 2105 {
nuclear@0 2106 ai_assert(NULL != apOut);
nuclear@0 2107
nuclear@0 2108 // parse the index
nuclear@0 2109 ParseLV4MeshLong(rIndexOut);
nuclear@0 2110
nuclear@0 2111 // parse the three others
nuclear@0 2112 ParseLV4MeshFloatTriple(apOut);
nuclear@0 2113 }
nuclear@0 2114 // ------------------------------------------------------------------------------------------------
nuclear@0 2115 void Parser::ParseLV4MeshFloatTriple(float* apOut)
nuclear@0 2116 {
nuclear@0 2117 ai_assert(NULL != apOut);
nuclear@0 2118
nuclear@0 2119 for (unsigned int i = 0; i < 3;++i)
nuclear@0 2120 ParseLV4MeshFloat(apOut[i]);
nuclear@0 2121 }
nuclear@0 2122 // ------------------------------------------------------------------------------------------------
nuclear@0 2123 void Parser::ParseLV4MeshFloat(float& fOut)
nuclear@0 2124 {
nuclear@0 2125 // skip spaces and tabs
nuclear@0 2126 if(!SkipSpaces(&filePtr))
nuclear@0 2127 {
nuclear@0 2128 // LOG
nuclear@0 2129 LogWarning("Unable to parse float: unexpected EOL [#1]");
nuclear@0 2130 fOut = 0.0f;
nuclear@0 2131 ++iLineNumber;
nuclear@0 2132 return;
nuclear@0 2133 }
nuclear@0 2134 // parse the first float
nuclear@0 2135 filePtr = fast_atoreal_move<float>(filePtr,fOut);
nuclear@0 2136 }
nuclear@0 2137 // ------------------------------------------------------------------------------------------------
nuclear@0 2138 void Parser::ParseLV4MeshLong(unsigned int& iOut)
nuclear@0 2139 {
nuclear@0 2140 // Skip spaces and tabs
nuclear@0 2141 if(!SkipSpaces(&filePtr))
nuclear@0 2142 {
nuclear@0 2143 // LOG
nuclear@0 2144 LogWarning("Unable to parse long: unexpected EOL [#1]");
nuclear@0 2145 iOut = 0;
nuclear@0 2146 ++iLineNumber;
nuclear@0 2147 return;
nuclear@0 2148 }
nuclear@0 2149 // parse the value
nuclear@0 2150 iOut = strtoul10(filePtr,&filePtr);
nuclear@0 2151 }
nuclear@0 2152
nuclear@0 2153 #endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER