aselib.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "aselib.h"
  19. #include <assert.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #define MAX_ASE_MATERIALS 32
  23. #define MAX_ASE_OBJECTS 64
  24. #define MAX_ASE_ANIMATIONS 32
  25. #define MAX_ASE_ANIMATION_FRAMES 512
  26. #define VERBOSE( x ) { if ( ase.verbose ) { printf x ; } }
  27. typedef struct
  28. {
  29. float x, y, z;
  30. float nx, ny, nz;
  31. float s, t;
  32. } aseVertex_t;
  33. typedef struct
  34. {
  35. float s, t;
  36. } aseTVertex_t;
  37. typedef int aseFace_t[3];
  38. typedef struct
  39. {
  40. int numFaces;
  41. int numVertexes;
  42. int numTVertexes;
  43. int timeValue;
  44. aseVertex_t *vertexes;
  45. aseTVertex_t *tvertexes;
  46. aseFace_t *faces, *tfaces;
  47. int currentFace, currentVertex;
  48. } aseMesh_t;
  49. typedef struct
  50. {
  51. int numFrames;
  52. aseMesh_t frames[MAX_ASE_ANIMATION_FRAMES];
  53. int currentFrame;
  54. } aseMeshAnimation_t;
  55. typedef struct
  56. {
  57. char name[128];
  58. } aseMaterial_t;
  59. /*
  60. ** contains the animate sequence of a single surface
  61. ** using a single material
  62. */
  63. typedef struct
  64. {
  65. char name[128];
  66. int materialRef;
  67. int numAnimations;
  68. aseMeshAnimation_t anim;
  69. } aseGeomObject_t;
  70. typedef struct
  71. {
  72. int numMaterials;
  73. aseMaterial_t materials[MAX_ASE_MATERIALS];
  74. aseGeomObject_t objects[MAX_ASE_OBJECTS];
  75. char *buffer;
  76. char *curpos;
  77. int len;
  78. int currentObject;
  79. qboolean verbose;
  80. qboolean grabAnims;
  81. } ase_t;
  82. static char s_token[1024];
  83. static ase_t ase;
  84. static void ASE_Process( void );
  85. static void ASE_FreeGeomObject( int ndx );
  86. /*
  87. ** ASE_Load
  88. */
  89. void ASE_Load( const char *filename, qboolean verbose, qboolean grabAnims )
  90. {
  91. FILE *fp = fopen( filename, "rb" );
  92. if ( !fp )
  93. Error( "File not found '%s'", filename );
  94. memset( &ase, 0, sizeof( ase ) );
  95. ase.verbose = verbose;
  96. ase.grabAnims = grabAnims;
  97. ase.len = Q_filelength( fp );
  98. ase.curpos = ase.buffer = malloc( ase.len );
  99. printf( "Processing '%s'\n", filename );
  100. if ( fread( ase.buffer, ase.len, 1, fp ) != 1 )
  101. {
  102. fclose( fp );
  103. Error( "fread() != -1 for '%s'", filename );
  104. }
  105. fclose( fp );
  106. ASE_Process();
  107. }
  108. /*
  109. ** ASE_Free
  110. */
  111. void ASE_Free( void )
  112. {
  113. int i;
  114. for ( i = 0; i < ase.currentObject; i++ )
  115. {
  116. ASE_FreeGeomObject( i );
  117. }
  118. }
  119. /*
  120. ** ASE_GetNumSurfaces
  121. */
  122. int ASE_GetNumSurfaces( void )
  123. {
  124. return ase.currentObject;
  125. }
  126. /*
  127. ** ASE_GetSurfaceName
  128. */
  129. const char *ASE_GetSurfaceName( int which )
  130. {
  131. aseGeomObject_t *pObject = &ase.objects[which];
  132. if ( !pObject->anim.numFrames )
  133. return 0;
  134. return pObject->name;
  135. }
  136. /*
  137. ** ASE_GetSurfaceAnimation
  138. **
  139. ** Returns an animation (sequence of polysets)
  140. */
  141. polyset_t *ASE_GetSurfaceAnimation( int which, int *pNumFrames, int skipFrameStart, int skipFrameEnd, int maxFrames )
  142. {
  143. aseGeomObject_t *pObject = &ase.objects[which];
  144. polyset_t *psets;
  145. int numFramesInAnimation;
  146. int numFramesToKeep;
  147. int i, f;
  148. if ( !pObject->anim.numFrames )
  149. return 0;
  150. if ( pObject->anim.numFrames > maxFrames && maxFrames != -1 )
  151. {
  152. numFramesInAnimation = maxFrames;
  153. }
  154. else
  155. {
  156. numFramesInAnimation = pObject->anim.numFrames;
  157. if ( maxFrames != -1 )
  158. printf( "WARNING: ASE_GetSurfaceAnimation maxFrames > numFramesInAnimation\n" );
  159. }
  160. if ( skipFrameEnd != -1 )
  161. numFramesToKeep = numFramesInAnimation - ( skipFrameEnd - skipFrameStart + 1 );
  162. else
  163. numFramesToKeep = numFramesInAnimation;
  164. *pNumFrames = numFramesToKeep;
  165. psets = calloc( sizeof( polyset_t ) * numFramesToKeep, 1 );
  166. for ( f = 0, i = 0; i < numFramesInAnimation; i++ )
  167. {
  168. int t;
  169. aseMesh_t *pMesh = &pObject->anim.frames[i];
  170. if ( skipFrameStart != -1 )
  171. {
  172. if ( i >= skipFrameStart && i <= skipFrameEnd )
  173. continue;
  174. }
  175. strcpy( psets[f].name, pObject->name );
  176. strcpy( psets[f].materialname, ase.materials[pObject->materialRef].name );
  177. psets[f].triangles = calloc( sizeof( triangle_t ) * pObject->anim.frames[i].numFaces, 1 );
  178. psets[f].numtriangles = pObject->anim.frames[i].numFaces;
  179. for ( t = 0; t < pObject->anim.frames[i].numFaces; t++ )
  180. {
  181. int k;
  182. for ( k = 0; k < 3; k++ )
  183. {
  184. psets[f].triangles[t].verts[k][0] = pMesh->vertexes[pMesh->faces[t][k]].x;
  185. psets[f].triangles[t].verts[k][1] = pMesh->vertexes[pMesh->faces[t][k]].y;
  186. psets[f].triangles[t].verts[k][2] = pMesh->vertexes[pMesh->faces[t][k]].z;
  187. if ( pMesh->tvertexes && pMesh->tfaces )
  188. {
  189. psets[f].triangles[t].texcoords[k][0] = pMesh->tvertexes[pMesh->tfaces[t][k]].s;
  190. psets[f].triangles[t].texcoords[k][1] = pMesh->tvertexes[pMesh->tfaces[t][k]].t;
  191. }
  192. }
  193. }
  194. f++;
  195. }
  196. return psets;
  197. }
  198. static void ASE_FreeGeomObject( int ndx )
  199. {
  200. aseGeomObject_t *pObject;
  201. int i;
  202. pObject = &ase.objects[ndx];
  203. for ( i = 0; i < pObject->anim.numFrames; i++ )
  204. {
  205. if ( pObject->anim.frames[i].vertexes )
  206. {
  207. free( pObject->anim.frames[i].vertexes );
  208. }
  209. if ( pObject->anim.frames[i].tvertexes )
  210. {
  211. free( pObject->anim.frames[i].tvertexes );
  212. }
  213. if ( pObject->anim.frames[i].faces )
  214. {
  215. free( pObject->anim.frames[i].faces );
  216. }
  217. if ( pObject->anim.frames[i].tfaces )
  218. {
  219. free( pObject->anim.frames[i].tfaces );
  220. }
  221. }
  222. memset( pObject, 0, sizeof( *pObject ) );
  223. }
  224. static aseMesh_t *ASE_GetCurrentMesh( void )
  225. {
  226. aseGeomObject_t *pObject;
  227. if ( ase.currentObject >= MAX_ASE_OBJECTS )
  228. {
  229. Error( "Too many GEOMOBJECTs" );
  230. return 0; // never called
  231. }
  232. pObject = &ase.objects[ase.currentObject];
  233. if ( pObject->anim.currentFrame >= MAX_ASE_ANIMATION_FRAMES )
  234. {
  235. Error( "Too many MESHes" );
  236. return 0;
  237. }
  238. return &pObject->anim.frames[pObject->anim.currentFrame];
  239. }
  240. static int CharIsTokenDelimiter( int ch )
  241. {
  242. if ( ch <= 32 )
  243. return 1;
  244. return 0;
  245. }
  246. static int ASE_GetToken( qboolean restOfLine )
  247. {
  248. int i = 0;
  249. if ( ase.buffer == 0 )
  250. return 0;
  251. if ( ( ase.curpos - ase.buffer ) == ase.len )
  252. return 0;
  253. // skip over crap
  254. while ( ( ( ase.curpos - ase.buffer ) < ase.len ) &&
  255. ( *ase.curpos <= 32 ) )
  256. {
  257. ase.curpos++;
  258. }
  259. while ( ( ase.curpos - ase.buffer ) < ase.len )
  260. {
  261. s_token[i] = *ase.curpos;
  262. ase.curpos++;
  263. i++;
  264. if ( ( CharIsTokenDelimiter( s_token[i-1] ) && !restOfLine ) ||
  265. ( ( s_token[i-1] == '\n' ) || ( s_token[i-1] == '\r' ) ) )
  266. {
  267. s_token[i-1] = 0;
  268. break;
  269. }
  270. }
  271. s_token[i] = 0;
  272. return 1;
  273. }
  274. static void ASE_ParseBracedBlock( void (*parser)( const char *token ) )
  275. {
  276. int indent = 0;
  277. while ( ASE_GetToken( qfalse ) )
  278. {
  279. if ( !strcmp( s_token, "{" ) )
  280. {
  281. indent++;
  282. }
  283. else if ( !strcmp( s_token, "}" ) )
  284. {
  285. --indent;
  286. if ( indent == 0 )
  287. break;
  288. else if ( indent < 0 )
  289. Error( "Unexpected '}'" );
  290. }
  291. else
  292. {
  293. if ( parser )
  294. parser( s_token );
  295. }
  296. }
  297. }
  298. static void ASE_SkipEnclosingBraces( void )
  299. {
  300. int indent = 0;
  301. while ( ASE_GetToken( qfalse ) )
  302. {
  303. if ( !strcmp( s_token, "{" ) )
  304. {
  305. indent++;
  306. }
  307. else if ( !strcmp( s_token, "}" ) )
  308. {
  309. indent--;
  310. if ( indent == 0 )
  311. break;
  312. else if ( indent < 0 )
  313. Error( "Unexpected '}'" );
  314. }
  315. }
  316. }
  317. static void ASE_SkipRestOfLine( void )
  318. {
  319. ASE_GetToken( qtrue );
  320. }
  321. static void ASE_KeyMAP_DIFFUSE( const char *token )
  322. {
  323. char buffer[1024], buff1[1024], buff2[1024];
  324. char *buf1, *buf2;
  325. int i = 0, count;
  326. if ( !strcmp( token, "*BITMAP" ) )
  327. {
  328. ASE_GetToken( qfalse );
  329. strcpy( buffer, s_token + 1 );
  330. if ( strchr( buffer, '"' ) )
  331. *strchr( buffer, '"' ) = 0;
  332. while ( buffer[i] )
  333. {
  334. if ( buffer[i] == '\\' )
  335. buffer[i] = '/';
  336. i++;
  337. }
  338. buf1 = buffer;
  339. buf2 = gamedir;
  340. // need to compare win32 volumes to potential unix junk
  341. //
  342. if ( (gamedir[1] == ':' && (buffer[0] == '/' && buffer[1] == '/')) ||
  343. (buffer[1] == ':' && (gamedir[0] == '/' && gamedir[1] == '/')) ) {
  344. if (buffer[1] == ':') {
  345. buf1 = buffer + 2;
  346. buf2 = gamedir + 2;
  347. } else {
  348. buf1 = gamedir + 2;
  349. buf2 = buffer +2;
  350. }
  351. count = 0;
  352. while (*buf2 && count < 2) {
  353. if (*buf2 == '/') {
  354. count++;
  355. }
  356. buf2++;
  357. }
  358. }
  359. strcpy(buff1, buf1);
  360. strlwr(buff1);
  361. strcpy(buff2, buf2);
  362. strlwr(buff2);
  363. if ( strstr( buff2, buff1 + 2 ) )
  364. {
  365. strcpy( ase.materials[ase.numMaterials].name, strstr( buff2, buff1 + 2 ) + strlen( buff1 ) - 2 );
  366. }
  367. else
  368. {
  369. sprintf( ase.materials[ase.numMaterials].name, "(not converted: '%s')", buffer );
  370. printf( "WARNING: illegal material name '%s'\n", buffer );
  371. }
  372. }
  373. else
  374. {
  375. }
  376. }
  377. static void ASE_KeyMATERIAL( const char *token )
  378. {
  379. if ( !strcmp( token, "*MAP_DIFFUSE" ) )
  380. {
  381. ASE_ParseBracedBlock( ASE_KeyMAP_DIFFUSE );
  382. }
  383. else
  384. {
  385. }
  386. }
  387. static void ASE_KeyMATERIAL_LIST( const char *token )
  388. {
  389. if ( !strcmp( token, "*MATERIAL_COUNT" ) )
  390. {
  391. ASE_GetToken( qfalse );
  392. VERBOSE( ( "..num materials: %s\n", s_token ) );
  393. if ( atoi( s_token ) > MAX_ASE_MATERIALS )
  394. {
  395. Error( "Too many materials!" );
  396. }
  397. ase.numMaterials = 0;
  398. }
  399. else if ( !strcmp( token, "*MATERIAL" ) )
  400. {
  401. VERBOSE( ( "..material %d ", ase.numMaterials ) );
  402. ASE_ParseBracedBlock( ASE_KeyMATERIAL );
  403. ase.numMaterials++;
  404. }
  405. }
  406. static void ASE_KeyMESH_VERTEX_LIST( const char *token )
  407. {
  408. aseMesh_t *pMesh = ASE_GetCurrentMesh();
  409. if ( !strcmp( token, "*MESH_VERTEX" ) )
  410. {
  411. ASE_GetToken( qfalse ); // skip number
  412. ASE_GetToken( qfalse );
  413. pMesh->vertexes[pMesh->currentVertex].y = atof( s_token );
  414. ASE_GetToken( qfalse );
  415. pMesh->vertexes[pMesh->currentVertex].x = -atof( s_token );
  416. ASE_GetToken( qfalse );
  417. pMesh->vertexes[pMesh->currentVertex].z = atof( s_token );
  418. pMesh->currentVertex++;
  419. if ( pMesh->currentVertex > pMesh->numVertexes )
  420. {
  421. Error( "pMesh->currentVertex >= pMesh->numVertexes" );
  422. }
  423. }
  424. else
  425. {
  426. Error( "Unknown token '%s' while parsing MESH_VERTEX_LIST", token );
  427. }
  428. }
  429. static void ASE_KeyMESH_FACE_LIST( const char *token )
  430. {
  431. aseMesh_t *pMesh = ASE_GetCurrentMesh();
  432. if ( !strcmp( token, "*MESH_FACE" ) )
  433. {
  434. ASE_GetToken( qfalse ); // skip face number
  435. ASE_GetToken( qfalse ); // skip label
  436. ASE_GetToken( qfalse ); // first vertex
  437. pMesh->faces[pMesh->currentFace][0] = atoi( s_token );
  438. ASE_GetToken( qfalse ); // skip label
  439. ASE_GetToken( qfalse ); // second vertex
  440. pMesh->faces[pMesh->currentFace][2] = atoi( s_token );
  441. ASE_GetToken( qfalse ); // skip label
  442. ASE_GetToken( qfalse ); // third vertex
  443. pMesh->faces[pMesh->currentFace][1] = atoi( s_token );
  444. ASE_GetToken( qtrue );
  445. /*
  446. if ( ( p = strstr( s_token, "*MESH_MTLID" ) ) != 0 )
  447. {
  448. p += strlen( "*MESH_MTLID" ) + 1;
  449. mtlID = atoi( p );
  450. }
  451. else
  452. {
  453. Error( "No *MESH_MTLID found for face!" );
  454. }
  455. */
  456. pMesh->currentFace++;
  457. }
  458. else
  459. {
  460. Error( "Unknown token '%s' while parsing MESH_FACE_LIST", token );
  461. }
  462. }
  463. static void ASE_KeyTFACE_LIST( const char *token )
  464. {
  465. aseMesh_t *pMesh = ASE_GetCurrentMesh();
  466. if ( !strcmp( token, "*MESH_TFACE" ) )
  467. {
  468. int a, b, c;
  469. ASE_GetToken( qfalse );
  470. ASE_GetToken( qfalse );
  471. a = atoi( s_token );
  472. ASE_GetToken( qfalse );
  473. c = atoi( s_token );
  474. ASE_GetToken( qfalse );
  475. b = atoi( s_token );
  476. pMesh->tfaces[pMesh->currentFace][0] = a;
  477. pMesh->tfaces[pMesh->currentFace][1] = b;
  478. pMesh->tfaces[pMesh->currentFace][2] = c;
  479. pMesh->currentFace++;
  480. }
  481. else
  482. {
  483. Error( "Unknown token '%s' in MESH_TFACE", token );
  484. }
  485. }
  486. static void ASE_KeyMESH_TVERTLIST( const char *token )
  487. {
  488. aseMesh_t *pMesh = ASE_GetCurrentMesh();
  489. if ( !strcmp( token, "*MESH_TVERT" ) )
  490. {
  491. char u[80], v[80], w[80];
  492. ASE_GetToken( qfalse );
  493. ASE_GetToken( qfalse );
  494. strcpy( u, s_token );
  495. ASE_GetToken( qfalse );
  496. strcpy( v, s_token );
  497. ASE_GetToken( qfalse );
  498. strcpy( w, s_token );
  499. pMesh->tvertexes[pMesh->currentVertex].s = atof( u );
  500. pMesh->tvertexes[pMesh->currentVertex].t = 1.0f - atof( v );
  501. pMesh->currentVertex++;
  502. if ( pMesh->currentVertex > pMesh->numTVertexes )
  503. {
  504. Error( "pMesh->currentVertex > pMesh->numTVertexes" );
  505. }
  506. }
  507. else
  508. {
  509. Error( "Unknown token '%s' while parsing MESH_TVERTLIST" );
  510. }
  511. }
  512. static void ASE_KeyMESH( const char *token )
  513. {
  514. aseMesh_t *pMesh = ASE_GetCurrentMesh();
  515. if ( !strcmp( token, "*TIMEVALUE" ) )
  516. {
  517. ASE_GetToken( qfalse );
  518. pMesh->timeValue = atoi( s_token );
  519. VERBOSE( ( ".....timevalue: %d\n", pMesh->timeValue ) );
  520. }
  521. else if ( !strcmp( token, "*MESH_NUMVERTEX" ) )
  522. {
  523. ASE_GetToken( qfalse );
  524. pMesh->numVertexes = atoi( s_token );
  525. VERBOSE( ( ".....TIMEVALUE: %d\n", pMesh->timeValue ) );
  526. VERBOSE( ( ".....num vertexes: %d\n", pMesh->numVertexes ) );
  527. }
  528. else if ( !strcmp( token, "*MESH_NUMFACES" ) )
  529. {
  530. ASE_GetToken( qfalse );
  531. pMesh->numFaces = atoi( s_token );
  532. VERBOSE( ( ".....num faces: %d\n", pMesh->numFaces ) );
  533. }
  534. else if ( !strcmp( token, "*MESH_NUMTVFACES" ) )
  535. {
  536. ASE_GetToken( qfalse );
  537. if ( atoi( s_token ) != pMesh->numFaces )
  538. {
  539. Error( "MESH_NUMTVFACES != MESH_NUMFACES" );
  540. }
  541. }
  542. else if ( !strcmp( token, "*MESH_NUMTVERTEX" ) )
  543. {
  544. ASE_GetToken( qfalse );
  545. pMesh->numTVertexes = atoi( s_token );
  546. VERBOSE( ( ".....num tvertexes: %d\n", pMesh->numTVertexes ) );
  547. }
  548. else if ( !strcmp( token, "*MESH_VERTEX_LIST" ) )
  549. {
  550. pMesh->vertexes = calloc( sizeof( aseVertex_t ) * pMesh->numVertexes, 1 );
  551. pMesh->currentVertex = 0;
  552. VERBOSE( ( ".....parsing MESH_VERTEX_LIST\n" ) );
  553. ASE_ParseBracedBlock( ASE_KeyMESH_VERTEX_LIST );
  554. }
  555. else if ( !strcmp( token, "*MESH_TVERTLIST" ) )
  556. {
  557. pMesh->currentVertex = 0;
  558. pMesh->tvertexes = calloc( sizeof( aseTVertex_t ) * pMesh->numTVertexes, 1 );
  559. VERBOSE( ( ".....parsing MESH_TVERTLIST\n" ) );
  560. ASE_ParseBracedBlock( ASE_KeyMESH_TVERTLIST );
  561. }
  562. else if ( !strcmp( token, "*MESH_FACE_LIST" ) )
  563. {
  564. pMesh->faces = calloc( sizeof( aseFace_t ) * pMesh->numFaces, 1 );
  565. pMesh->currentFace = 0;
  566. VERBOSE( ( ".....parsing MESH_FACE_LIST\n" ) );
  567. ASE_ParseBracedBlock( ASE_KeyMESH_FACE_LIST );
  568. }
  569. else if ( !strcmp( token, "*MESH_TFACELIST" ) )
  570. {
  571. pMesh->tfaces = calloc( sizeof( aseFace_t ) * pMesh->numFaces, 1 );
  572. pMesh->currentFace = 0;
  573. VERBOSE( ( ".....parsing MESH_TFACE_LIST\n" ) );
  574. ASE_ParseBracedBlock( ASE_KeyTFACE_LIST );
  575. }
  576. else if ( !strcmp( token, "*MESH_NORMALS" ) )
  577. {
  578. ASE_ParseBracedBlock( 0 );
  579. }
  580. }
  581. static void ASE_KeyMESH_ANIMATION( const char *token )
  582. {
  583. aseMesh_t *pMesh = ASE_GetCurrentMesh();
  584. // loads a single animation frame
  585. if ( !strcmp( token, "*MESH" ) )
  586. {
  587. VERBOSE( ( "...found MESH\n" ) );
  588. assert( pMesh->faces == 0 );
  589. assert( pMesh->vertexes == 0 );
  590. assert( pMesh->tvertexes == 0 );
  591. memset( pMesh, 0, sizeof( *pMesh ) );
  592. ASE_ParseBracedBlock( ASE_KeyMESH );
  593. if ( ++ase.objects[ase.currentObject].anim.currentFrame == MAX_ASE_ANIMATION_FRAMES )
  594. {
  595. Error( "Too many animation frames" );
  596. }
  597. }
  598. else
  599. {
  600. Error( "Unknown token '%s' while parsing MESH_ANIMATION", token );
  601. }
  602. }
  603. static void ASE_KeyGEOMOBJECT( const char *token )
  604. {
  605. if ( !strcmp( token, "*NODE_NAME" ) )
  606. {
  607. char *name = ase.objects[ase.currentObject].name;
  608. ASE_GetToken( qtrue );
  609. VERBOSE( ( " %s\n", s_token ) );
  610. strcpy( ase.objects[ase.currentObject].name, s_token + 1 );
  611. if ( strchr( ase.objects[ase.currentObject].name, '"' ) )
  612. *strchr( ase.objects[ase.currentObject].name, '"' ) = 0;
  613. if ( strstr( name, "tag" ) == name )
  614. {
  615. while ( strchr( name, '_' ) != strrchr( name, '_' ) )
  616. {
  617. *strrchr( name, '_' ) = 0;
  618. }
  619. while ( strrchr( name, ' ' ) )
  620. {
  621. *strrchr( name, ' ' ) = 0;
  622. }
  623. }
  624. }
  625. else if ( !strcmp( token, "*NODE_PARENT" ) )
  626. {
  627. ASE_SkipRestOfLine();
  628. }
  629. // ignore unused data blocks
  630. else if ( !strcmp( token, "*NODE_TM" ) ||
  631. !strcmp( token, "*TM_ANIMATION" ) )
  632. {
  633. ASE_ParseBracedBlock( 0 );
  634. }
  635. // ignore regular meshes that aren't part of animation
  636. else if ( !strcmp( token, "*MESH" ) && !ase.grabAnims )
  637. {
  638. /*
  639. if ( strstr( ase.objects[ase.currentObject].name, "tag_" ) == ase.objects[ase.currentObject].name )
  640. {
  641. s_forceStaticMesh = true;
  642. ASE_ParseBracedBlock( ASE_KeyMESH );
  643. s_forceStaticMesh = false;
  644. }
  645. */
  646. ASE_ParseBracedBlock( ASE_KeyMESH );
  647. if ( ++ase.objects[ase.currentObject].anim.currentFrame == MAX_ASE_ANIMATION_FRAMES )
  648. {
  649. Error( "Too many animation frames" );
  650. }
  651. ase.objects[ase.currentObject].anim.numFrames = ase.objects[ase.currentObject].anim.currentFrame;
  652. ase.objects[ase.currentObject].numAnimations++;
  653. /*
  654. // ignore meshes that aren't part of animations if this object isn't a
  655. // a tag
  656. else
  657. {
  658. ASE_ParseBracedBlock( 0 );
  659. }
  660. */
  661. }
  662. // according to spec these are obsolete
  663. else if ( !strcmp( token, "*MATERIAL_REF" ) )
  664. {
  665. ASE_GetToken( qfalse );
  666. ase.objects[ase.currentObject].materialRef = atoi( s_token );
  667. }
  668. // loads a sequence of animation frames
  669. else if ( !strcmp( token, "*MESH_ANIMATION" ) )
  670. {
  671. if ( ase.grabAnims )
  672. {
  673. VERBOSE( ( "..found MESH_ANIMATION\n" ) );
  674. if ( ase.objects[ase.currentObject].numAnimations )
  675. {
  676. Error( "Multiple MESH_ANIMATIONS within a single GEOM_OBJECT" );
  677. }
  678. ASE_ParseBracedBlock( ASE_KeyMESH_ANIMATION );
  679. ase.objects[ase.currentObject].anim.numFrames = ase.objects[ase.currentObject].anim.currentFrame;
  680. ase.objects[ase.currentObject].numAnimations++;
  681. }
  682. else
  683. {
  684. ASE_SkipEnclosingBraces();
  685. }
  686. }
  687. // skip unused info
  688. else if ( !strcmp( token, "*PROP_MOTIONBLUR" ) ||
  689. !strcmp( token, "*PROP_CASTSHADOW" ) ||
  690. !strcmp( token, "*PROP_RECVSHADOW" ) )
  691. {
  692. ASE_SkipRestOfLine();
  693. }
  694. }
  695. static void ConcatenateObjects( aseGeomObject_t *pObjA, aseGeomObject_t *pObjB )
  696. {
  697. }
  698. static void CollapseObjects( void )
  699. {
  700. int i;
  701. int numObjects = ase.currentObject;
  702. for ( i = 0; i < numObjects; i++ )
  703. {
  704. int j;
  705. // skip tags
  706. if ( strstr( ase.objects[i].name, "tag" ) == ase.objects[i].name )
  707. {
  708. continue;
  709. }
  710. if ( !ase.objects[i].numAnimations )
  711. {
  712. continue;
  713. }
  714. for ( j = i + 1; j < numObjects; j++ )
  715. {
  716. if ( strstr( ase.objects[j].name, "tag" ) == ase.objects[j].name )
  717. {
  718. continue;
  719. }
  720. if ( ase.objects[i].materialRef == ase.objects[j].materialRef )
  721. {
  722. if ( ase.objects[j].numAnimations )
  723. {
  724. ConcatenateObjects( &ase.objects[i], &ase.objects[j] );
  725. }
  726. }
  727. }
  728. }
  729. }
  730. /*
  731. ** ASE_Process
  732. */
  733. static void ASE_Process( void )
  734. {
  735. while ( ASE_GetToken( qfalse ) )
  736. {
  737. if ( !strcmp( s_token, "*3DSMAX_ASCIIEXPORT" ) ||
  738. !strcmp( s_token, "*COMMENT" ) )
  739. {
  740. ASE_SkipRestOfLine();
  741. }
  742. else if ( !strcmp( s_token, "*SCENE" ) )
  743. ASE_SkipEnclosingBraces();
  744. else if ( !strcmp( s_token, "*MATERIAL_LIST" ) )
  745. {
  746. VERBOSE( ("MATERIAL_LIST\n") );
  747. ASE_ParseBracedBlock( ASE_KeyMATERIAL_LIST );
  748. }
  749. else if ( !strcmp( s_token, "*GEOMOBJECT" ) )
  750. {
  751. VERBOSE( ("GEOMOBJECT" ) );
  752. ASE_ParseBracedBlock( ASE_KeyGEOMOBJECT );
  753. if ( strstr( ase.objects[ase.currentObject].name, "Bip" ) ||
  754. strstr( ase.objects[ase.currentObject].name, "ignore_" ) )
  755. {
  756. ASE_FreeGeomObject( ase.currentObject );
  757. VERBOSE( ( "(discarding BIP/ignore object)\n" ) );
  758. }
  759. else if ( ( strstr( ase.objects[ase.currentObject].name, "h_" ) != ase.objects[ase.currentObject].name ) &&
  760. ( strstr( ase.objects[ase.currentObject].name, "l_" ) != ase.objects[ase.currentObject].name ) &&
  761. ( strstr( ase.objects[ase.currentObject].name, "u_" ) != ase.objects[ase.currentObject].name ) &&
  762. ( strstr( ase.objects[ase.currentObject].name, "tag" ) != ase.objects[ase.currentObject].name ) &&
  763. ase.grabAnims )
  764. {
  765. VERBOSE( ( "(ignoring improperly labeled object '%s')\n", ase.objects[ase.currentObject].name ) );
  766. ASE_FreeGeomObject( ase.currentObject );
  767. }
  768. else
  769. {
  770. if ( ++ase.currentObject == MAX_ASE_OBJECTS )
  771. {
  772. Error( "Too many GEOMOBJECTs" );
  773. }
  774. }
  775. }
  776. else if ( s_token[0] )
  777. {
  778. printf( "Unknown token '%s'\n", s_token );
  779. }
  780. }
  781. if ( !ase.currentObject )
  782. Error( "No animation data!" );
  783. CollapseObjects();
  784. }