ASEParser.cpp 55 KB

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