PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/tools/quake2/qdata_heretic2/common/trilib.c

https://gitlab.com/illwieckz/netradiant
C | 1039 lines | 591 code | 116 blank | 332 comment | 136 complexity | 6efcfa1bd4e29c880ceddae666c3fb72 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. Copyright (C) 1999-2006 Id Software, Inc. and contributors.
  3. For a list of contributors, see the accompanying CONTRIBUTORS file.
  4. This file is part of GtkRadiant.
  5. GtkRadiant is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. GtkRadiant is distributed in the hope that it will be useful,
  10. 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 GtkRadiant; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. //
  18. // trilib.c: library for loading triangles from an Alias triangle file
  19. //
  20. #include <stdio.h>
  21. #include "cmdlib.h"
  22. #include "inout.h"
  23. #include "mathlib.h"
  24. #include "trilib.h"
  25. #include "token.h"
  26. #include "l3dslib.h"
  27. #include "fmodel.h"
  28. #if 1
  29. #include "qd_skeletons.h"
  30. #endif
  31. // on disk representation of a face
  32. #define FLOAT_START 99999.0
  33. #define FLOAT_END -FLOAT_START
  34. #define MAGIC 123322
  35. #ifndef M_PI
  36. #define M_PI 3.14159265
  37. #endif
  38. float FixHTRRotateX = 0.0;
  39. float FixHTRRotateY = 0.0;
  40. float FixHTRRotateZ = 0.0;
  41. float FixHTRTranslateX = 0.0;
  42. float FixHTRTranslateY = 0.0;
  43. float FixHTRTranslateZ = 0.0;
  44. //#define NOISY 1
  45. typedef struct {
  46. float v[3];
  47. } vector;
  48. typedef struct
  49. {
  50. vector n; /* normal */
  51. vector p; /* point */
  52. vector c; /* color */
  53. float u; /* u */
  54. float v; /* v */
  55. } aliaspoint_t;
  56. typedef struct {
  57. aliaspoint_t pt[3];
  58. } tf_triangle;
  59. void ByteSwapTri( tf_triangle *tri ){
  60. int i;
  61. for ( i = 0 ; i < sizeof( tf_triangle ) / 4 ; i++ )
  62. {
  63. ( (int *)tri )[i] = BigLong( ( (int *)tri )[i] );
  64. }
  65. }
  66. void LoadTRI( char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes ){
  67. FILE *input;
  68. float start;
  69. char name[256], tex[256];
  70. int i, count, magic;
  71. tf_triangle tri;
  72. triangle_t *ptri;
  73. int iLevel;
  74. int exitpattern;
  75. float t;
  76. if ( nodesList ) {
  77. *num_mesh_nodes = 0;
  78. *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
  79. }
  80. t = -FLOAT_START;
  81. *( (unsigned char *)&exitpattern + 0 ) = *( (unsigned char *)&t + 3 );
  82. *( (unsigned char *)&exitpattern + 1 ) = *( (unsigned char *)&t + 2 );
  83. *( (unsigned char *)&exitpattern + 2 ) = *( (unsigned char *)&t + 1 );
  84. *( (unsigned char *)&exitpattern + 3 ) = *( (unsigned char *)&t + 0 );
  85. if ( ( input = fopen( filename, "rb" ) ) == 0 ) {
  86. Error( "reader: could not open file '%s'", filename );
  87. }
  88. iLevel = 0;
  89. fread( &magic, sizeof( int ), 1, input );
  90. if ( BigLong( magic ) != MAGIC ) {
  91. Error( "%s is not a Alias object separated triangle file, magic number is wrong.", filename );
  92. }
  93. ptri = malloc( MAXTRIANGLES * sizeof( triangle_t ) );
  94. *pptri = ptri;
  95. while ( feof( input ) == 0 ) {
  96. if ( fread( &start, sizeof( float ), 1, input ) < 1 ) {
  97. break;
  98. }
  99. *(int *)&start = BigLong( *(int *)&start );
  100. if ( *(int *)&start != exitpattern ) {
  101. if ( start == FLOAT_START ) {
  102. /* Start of an object or group of objects. */
  103. i = -1;
  104. do {
  105. /* There are probably better ways to read a string from */
  106. /* a file, but this does allow you to do error checking */
  107. /* (which I'm not doing) on a per character basis. */
  108. ++i;
  109. fread( &( name[i] ), sizeof( char ), 1, input );
  110. } while ( name[i] != '\0' );
  111. // indent();
  112. // fprintf(stdout,"OBJECT START: %s\n",name);
  113. fread( &count, sizeof( int ), 1, input );
  114. count = BigLong( count );
  115. ++iLevel;
  116. if ( count != 0 ) {
  117. // indent();
  118. // fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
  119. i = -1;
  120. do {
  121. ++i;
  122. fread( &( tex[i] ), sizeof( char ), 1, input );
  123. } while ( tex[i] != '\0' );
  124. // indent();
  125. // fprintf(stdout," Object texture name: '%s'\n",tex);
  126. }
  127. /* Else (count == 0) this is the start of a group, and */
  128. /* no texture name is present. */
  129. }
  130. else if ( start == FLOAT_END ) {
  131. /* End of an object or group. Yes, the name should be */
  132. /* obvious from context, but it is in here just to be */
  133. /* safe and to provide a little extra information for */
  134. /* those who do not wish to write a recursive reader. */
  135. /* Mia culpa. */
  136. --iLevel;
  137. i = -1;
  138. do {
  139. ++i;
  140. fread( &( name[i] ), sizeof( char ), 1, input );
  141. } while ( name[i] != '\0' );
  142. // indent();
  143. // fprintf(stdout,"OBJECT END: %s\n",name);
  144. continue;
  145. }
  146. }
  147. //
  148. // read the triangles
  149. //
  150. for ( i = 0; i < count; ++i ) {
  151. int j;
  152. fread( &tri, sizeof( tf_triangle ), 1, input );
  153. ByteSwapTri( &tri );
  154. for ( j = 0 ; j < 3 ; j++ )
  155. {
  156. int k;
  157. for ( k = 0 ; k < 3 ; k++ )
  158. {
  159. ptri->verts[j][k] = tri.pt[j].p.v[k];
  160. }
  161. }
  162. ptri++;
  163. if ( ( ptri - *pptri ) >= MAXTRIANGLES ) {
  164. Error( "Error: too many triangles; increase MAXTRIANGLES\n" );
  165. }
  166. }
  167. }
  168. *numtriangles = ptri - *pptri;
  169. fclose( input );
  170. DefaultNodesList( nodesList,num_mesh_nodes,numtriangles );
  171. }
  172. //==========================================================================
  173. //
  174. // LoadHRC
  175. //
  176. //==========================================================================
  177. float scaling[3];
  178. float rotation[3];
  179. float translation[3];
  180. static char *hrc_name;
  181. struct
  182. {
  183. float v[3];
  184. } vList[8192];
  185. void HandleHRCModel( triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,
  186. int ActiveNode, int Depth, int numVerts ){
  187. void ReadHRCClusterList( mesh_node_t *meshNode, int baseIndex );
  188. int i, j;
  189. int vertexCount;
  190. int triCount;
  191. triangle_t *tList;
  192. mesh_node_t *meshNode;
  193. float x, y, z;
  194. float x2, y2, z2;
  195. float rx, ry, rz;
  196. tokenType_t nextToken;
  197. float orig_scaling[3];
  198. float orig_rotation[3];
  199. float orig_translation[3];
  200. int start_tri;
  201. int pos,bit;
  202. int vertIndexBase;
  203. // Update Node Info
  204. if ( nodesList ) {
  205. TK_BeyondRequire( TK_NAME, TK_STRING );
  206. if ( Depth == 0 || tk_String[0] == '_' ) { // Root
  207. ActiveNode = *num_mesh_nodes;
  208. ( *num_mesh_nodes )++;
  209. if ( ( *num_mesh_nodes ) > MAX_FM_MESH_NODES ) {
  210. Error( "Too many mesh nodes in file %s\n", hrc_name );
  211. }
  212. meshNode = &( *nodesList )[ActiveNode];
  213. // memset(meshNode, 0, sizeof(mesh_node_t));
  214. strcpy( meshNode->name, tk_String );
  215. memset( meshNode->tris, 0, sizeof( meshNode->tris ) );
  216. memset( meshNode->verts, 0, sizeof( meshNode->verts ) );
  217. meshNode->start_glcmds = 0;
  218. meshNode->num_glcmds = 0;
  219. vertIndexBase = 0;
  220. }
  221. else
  222. { // Childs under the children
  223. meshNode = &( *nodesList )[ActiveNode];
  224. vertIndexBase = numVerts;
  225. }
  226. }
  227. else
  228. {
  229. meshNode = NULL;
  230. }
  231. // Get the scaling, rotation, and translation values
  232. TK_Beyond( TK_SCALING );
  233. for ( i = 0; i < 3; i++ )
  234. {
  235. orig_scaling[i] = scaling[i];
  236. TK_Require( TK_FLOATNUMBER );
  237. scaling[i] *= tk_FloatNumber;
  238. TK_Fetch();
  239. }
  240. TK_Beyond( TK_ROTATION );
  241. for ( i = 0; i < 3; i++ )
  242. {
  243. orig_rotation[i] = rotation[i];
  244. TK_Require( TK_FLOATNUMBER );
  245. rotation[i] = tk_FloatNumber;
  246. TK_Fetch();
  247. }
  248. TK_Beyond( TK_TRANSLATION );
  249. for ( i = 0; i < 3; i++ )
  250. {
  251. orig_translation[i] = translation[i];
  252. TK_Require( TK_FLOATNUMBER );
  253. translation[i] += tk_FloatNumber;
  254. TK_Fetch();
  255. }
  256. rx = ( ( rotation[0] - 90.0 ) / 360.0 ) * 2.0 * M_PI;
  257. ry = ( rotation[2] / 360.0 ) * 2.0 * M_PI;
  258. rz = ( rotation[1] / 360.0 ) * 2.0 * M_PI;
  259. // rjr - might not work if there an item doesn't have a mesh
  260. nextToken = tk_Token;
  261. if ( nextToken == TK_ACTOR_DATA ) {
  262. while ( nextToken != TK_MODEL && nextToken != TK_RBRACE )
  263. {
  264. nextToken = TK_Fetch();
  265. }
  266. }
  267. while ( nextToken == TK_SPLINE )
  268. { // spline node has two right braces
  269. nextToken = TK_Beyond( TK_RBRACE );
  270. nextToken = TK_Beyond( TK_RBRACE );
  271. }
  272. while ( nextToken == TK_MATERIAL )
  273. {
  274. nextToken = TK_Beyond( TK_RBRACE );
  275. }
  276. while ( nextToken == TK_MODEL )
  277. {
  278. HandleHRCModel( triList,triangleCount,nodesList,num_mesh_nodes,ActiveNode, Depth + 1, 0 );
  279. nextToken = TK_Fetch();
  280. }
  281. if ( nextToken == TK_MESH ) {
  282. // Get all the tri and vertex info
  283. TK_BeyondRequire( TK_VERTICES, TK_INTNUMBER );
  284. vertexCount = tk_IntNumber;
  285. for ( i = 0; i < vertexCount; i++ )
  286. {
  287. TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
  288. if ( tk_IntNumber != i ) {
  289. Error( "File '%s', line %d:\nVertex index mismatch.\n",
  290. tk_SourceName, tk_Line );
  291. }
  292. TK_Beyond( TK_POSITION );
  293. // Apply the scaling, rotation, and translation in the order
  294. // specified in the HRC file. This could be wrong.
  295. TK_Require( TK_FLOATNUMBER );
  296. x = tk_FloatNumber * scaling[0];
  297. TK_FetchRequire( TK_FLOATNUMBER );
  298. y = tk_FloatNumber * scaling[1];
  299. TK_FetchRequire( TK_FLOATNUMBER );
  300. z = tk_FloatNumber * scaling[2];
  301. y2 = y * cos( rx ) + z*sin( rx );
  302. z2 = -y*sin( rx ) + z*cos( rx );
  303. y = y2;
  304. z = z2;
  305. x2 = x * cos( ry ) - z*sin( ry );
  306. z2 = x * sin( ry ) + z*cos( ry );
  307. x = x2;
  308. z = z2;
  309. x2 = x * cos( rz ) + y*sin( rz );
  310. y2 = -x*sin( rz ) + y*cos( rz );
  311. x = x2;
  312. y = y2;
  313. vList[i].v[0] = x + translation[0];
  314. vList[i].v[1] = y - translation[2];
  315. vList[i].v[2] = z + translation[1];
  316. }
  317. TK_BeyondRequire( TK_POLYGONS, TK_INTNUMBER );
  318. triCount = tk_IntNumber;
  319. if ( triCount >= MAXTRIANGLES ) {
  320. Error( "Too many triangles in file %s\n", hrc_name );
  321. }
  322. start_tri = *triangleCount;
  323. *triangleCount += triCount;
  324. tList = *triList;
  325. for ( i = 0; i < triCount; i++ )
  326. {
  327. if ( meshNode ) { // Update the node
  328. pos = ( i + start_tri ) >> 3;
  329. bit = 1 << ( ( i + start_tri ) & 7 );
  330. meshNode->tris[pos] |= bit;
  331. }
  332. TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
  333. if ( tk_IntNumber != i ) {
  334. Error( "File '%s', line %d:\nTriangle index mismatch.\n",
  335. tk_SourceName, tk_Line );
  336. }
  337. TK_BeyondRequire( TK_NODES, TK_INTNUMBER );
  338. if ( tk_IntNumber != 3 ) {
  339. Error( "File '%s', line %d:\nBad polygon vertex count: %d.",
  340. tk_SourceName, tk_Line, tk_IntNumber );
  341. }
  342. tList[i + start_tri].HasUV = true;
  343. for ( j = 0; j < 3; j++ )
  344. {
  345. TK_BeyondRequire( TK_LBRACKET, TK_INTNUMBER );
  346. if ( tk_IntNumber != j ) {
  347. Error( "File '%s', line %d:\nTriangle vertex index"
  348. " mismatch. %d should be %d\n", tk_SourceName, tk_Line,
  349. tk_IntNumber, j );
  350. }
  351. TK_BeyondRequire( TK_VERTEX, TK_INTNUMBER );
  352. tList[i + start_tri].verts[2 - j][0] = vList[tk_IntNumber].v[0];
  353. tList[i + start_tri].verts[2 - j][1] = vList[tk_IntNumber].v[1];
  354. tList[i + start_tri].verts[2 - j][2] = vList[tk_IntNumber].v[2];
  355. #if 1
  356. tList[i + start_tri].indicies[2 - j] = tk_IntNumber + vertIndexBase;
  357. #endif
  358. TK_BeyondRequire( TK_UVTEXTURE, TK_FLOATNUMBER );
  359. tList[i + start_tri].uv[2 - j][0] = tk_FloatNumber;
  360. TK_Fetch();
  361. TK_Require( TK_FLOATNUMBER );
  362. tList[i + start_tri].uv[2 - j][1] = tk_FloatNumber;
  363. }
  364. /* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
  365. " v2: %f, %f, %f\n", i,
  366. tList[i].verts[0][0],
  367. tList[i].verts[0][1],
  368. tList[i].verts[0][2],
  369. tList[i].verts[1][0],
  370. tList[i].verts[1][1],
  371. tList[i].verts[1][2],
  372. tList[i].verts[2][0],
  373. tList[i].verts[2][1],
  374. tList[i].verts[2][2]);
  375. */
  376. }
  377. TK_Beyond( TK_RBRACE );
  378. TK_Beyond( TK_RBRACE );
  379. if ( tk_Token == TK_EDGES ) {
  380. // TK_Beyond(TK_EDGES);
  381. TK_Beyond( TK_RBRACE );
  382. }
  383. scaling[0] = scaling[1] = scaling[2] = 1.0;
  384. // rotation[0] = rotation[1] = rotation[2] = 0.0;
  385. // translation[0] = translation[1] = translation[2] = 0.0;
  386. // See if there are any other models belonging to this node
  387. #if 1
  388. TK_Fetch();
  389. nextToken = tk_Token;
  390. if ( nextToken == TK_CLUSTERS ) {
  391. if ( g_skelModel.clustered == -1 ) {
  392. ReadHRCClusterList( meshNode, vertIndexBase );
  393. }
  394. else
  395. {
  396. nextToken = TK_Get( TK_CLUSTER_NAME );
  397. while ( nextToken == TK_CLUSTER_NAME )
  398. {
  399. TK_BeyondRequire( TK_CLUSTER_STATE, TK_INTNUMBER );
  400. nextToken = TK_Fetch();
  401. }
  402. }
  403. // one right brace follow the list of clusters
  404. nextToken = TK_Beyond( TK_RBRACE );
  405. }
  406. else
  407. {
  408. if ( g_skelModel.clustered == -1 && !vertIndexBase ) {
  409. meshNode->clustered = false;
  410. }
  411. }
  412. #endif
  413. nextToken = tk_Token;
  414. if ( nextToken == TK_SPLINE ) {
  415. while ( nextToken == TK_SPLINE )
  416. { // spline node has two right braces
  417. nextToken = TK_Beyond( TK_RBRACE );
  418. nextToken = TK_Beyond( TK_RBRACE );
  419. }
  420. nextToken = TK_Beyond( TK_RBRACE );
  421. }
  422. while ( nextToken == TK_MATERIAL )
  423. {
  424. nextToken = TK_Beyond( TK_RBRACE );
  425. }
  426. while ( nextToken == TK_MODEL )
  427. {
  428. HandleHRCModel( triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth + 1, vertexCount + vertIndexBase );
  429. nextToken = TK_Fetch();
  430. }
  431. }
  432. for ( i = 0; i < 3; i++ )
  433. {
  434. scaling[i] = orig_scaling[i];
  435. rotation[i] = orig_rotation[i];
  436. translation[i] = orig_translation[i];
  437. }
  438. }
  439. static void LoadHRC( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
  440. if ( nodesList ) {
  441. *num_mesh_nodes = 0;
  442. if ( !*nodesList ) {
  443. *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
  444. }
  445. }
  446. hrc_name = fileName;
  447. scaling[0] = scaling[1] = scaling[2] = 1.0;
  448. rotation[0] = rotation[1] = rotation[2] = 0.0;
  449. translation[0] = translation[1] = translation[2] = 0.0;
  450. *triangleCount = 0;
  451. *triList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
  452. memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
  453. TK_OpenSource( fileName );
  454. TK_FetchRequire( TK_HRCH );
  455. TK_FetchRequire( TK_COLON );
  456. TK_FetchRequire( TK_SOFTIMAGE );
  457. // prime it
  458. TK_Beyond( TK_MODEL );
  459. HandleHRCModel( triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0 );
  460. TK_CloseSource();
  461. }
  462. //==========================================================================
  463. //
  464. // LoadHTR
  465. //
  466. //==========================================================================
  467. /*
  468. static int Version2;
  469. void HandleHTRModel(triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes,
  470. int ActiveNode, int Depth, int numVerts)
  471. {
  472. int i, j;
  473. int vertexCount;
  474. int vertexNum;
  475. int triCount;
  476. float origin[3];
  477. triangle_t *tList;
  478. float x, y, z;
  479. float x2, y2, z2;
  480. float rx, ry, rz;
  481. mesh_node_t *meshNode;
  482. int pos,bit;
  483. int vertIndexBase;
  484. int start_tri;
  485. if (nodesList)
  486. {
  487. TK_BeyondRequire(TK_NAME, TK_STRING);
  488. if (Depth == 0 || tk_String[0] == '_')
  489. { // Root
  490. ActiveNode = *num_mesh_nodes;
  491. (*num_mesh_nodes)++;
  492. if ((*num_mesh_nodes) > MAX_FM_MESH_NODES)
  493. {
  494. Error("Too many mesh nodes in file %s\n", hrc_name);
  495. }
  496. meshNode = &(*nodesList)[ActiveNode];
  497. // memset(meshNode, 0, sizeof(mesh_node_t));
  498. strcpy(meshNode->name, tk_String);
  499. memset(meshNode->tris, 0, sizeof(meshNode->tris));
  500. memset(meshNode->verts, 0, sizeof(meshNode->verts));
  501. meshNode->start_glcmds = 0;
  502. meshNode->num_glcmds = 0;
  503. vertIndexBase = 0;
  504. }
  505. else
  506. { // Childs under the children
  507. meshNode = &(*nodesList)[ActiveNode];
  508. vertIndexBase = numVerts;
  509. }
  510. }
  511. else
  512. {
  513. meshNode = NULL;
  514. }
  515. // Get vertex count
  516. TK_BeyondRequire(TK_VERTICES, TK_INTNUMBER);
  517. vertexCount = tk_IntNumber;
  518. // Get triangle count
  519. TK_BeyondRequire(TK_FACES, TK_INTNUMBER);
  520. triCount = tk_IntNumber;
  521. if(triCount >= MAXTRIANGLES)
  522. {
  523. Error("Too many triangles in file %s\n", hrc_name);
  524. }
  525. // Get origin
  526. TK_Beyond(TK_ORIGIN);
  527. TK_Require(TK_FLOATNUMBER);
  528. origin[0] = tk_FloatNumber;
  529. TK_FetchRequire(TK_FLOATNUMBER);
  530. origin[1] = tk_FloatNumber;
  531. TK_FetchRequire(TK_FLOATNUMBER);
  532. origin[2] = tk_FloatNumber;
  533. //rx = 90.0/360.0*2.0*M_PI;
  534. rx = FixHTRRotateX/360.0*2.0*M_PI;
  535. ry = FixHTRRotateY/360.0*2.0*M_PI;
  536. rz = FixHTRRotateZ/360.0*2.0*M_PI;
  537. // Get vertex list
  538. for(i = 0; i < vertexCount; i++)
  539. {
  540. TK_FetchRequire(TK_VERTEX);
  541. TK_FetchRequire(TK_FLOATNUMBER);
  542. x = tk_FloatNumber-origin[0];
  543. TK_FetchRequire(TK_FLOATNUMBER);
  544. y = tk_FloatNumber-origin[1];
  545. TK_FetchRequire(TK_FLOATNUMBER);
  546. z = tk_FloatNumber-origin[2];
  547. x += FixHTRTranslateX;
  548. y += FixHTRTranslateY;
  549. z += FixHTRTranslateZ;
  550. y2 = y*cos(rx)-z*sin(rx);
  551. z2 = y*sin(rx)+z*cos(rx);
  552. y = y2;
  553. z = z2;
  554. x2 = x*cos(ry)+z*sin(ry);
  555. z2 = -x*sin(ry)+z*cos(ry);
  556. x = x2;
  557. z = z2;
  558. x2 = x*cos(rz)-y*sin(rz);
  559. y2 = x*sin(rz)+y*cos(rz);
  560. x = x2;
  561. y = y2;
  562. vList[i].v[0] = x;
  563. vList[i].v[1] = y;
  564. vList[i].v[2] = z;
  565. }
  566. start_tri = *triangleCount;
  567. *triangleCount += triCount;
  568. tList = *triList;
  569. // Get face list
  570. for(i = 0; i < triCount; i++)
  571. {
  572. if (meshNode)
  573. { // Update the node
  574. pos = (i + start_tri) >> 3;
  575. bit = 1 << ((i + start_tri) & 7 );
  576. meshNode->tris[pos] |= bit;
  577. }
  578. TK_FetchRequire(TK_FACE);
  579. TK_FetchRequire(TK_LPAREN);
  580. for(j = 0; j < 3; j++)
  581. {
  582. TK_FetchRequire(TK_INTNUMBER);
  583. vertexNum = tk_IntNumber-1;
  584. if(vertexNum >= vertexCount)
  585. {
  586. Error("File '%s', line %d:\nVertex number"
  587. " >= vertexCount: %d\n", tk_SourceName, tk_Line,
  588. tk_IntNumber);
  589. }
  590. tList[i+start_tri].verts[2-j][0] = vList[vertexNum].v[0];
  591. tList[i+start_tri].verts[2-j][1] = vList[vertexNum].v[1];
  592. tList[i+start_tri].verts[2-j][2] = vList[vertexNum].v[2];
  593. }
  594. TK_FetchRequire(TK_RPAREN);
  595. #ifdef _QDATA
  596. if (Version2)
  597. {
  598. TK_FetchRequire(TK_FLOATNUMBER);
  599. tList[i+start_tri].uv[0][0]=tk_FloatNumber;
  600. TK_FetchRequire(TK_FLOATNUMBER);
  601. tList[i+start_tri].uv[0][1]=tk_FloatNumber;
  602. TK_FetchRequire(TK_FLOATNUMBER);
  603. tList[i+start_tri].uv[1][0]=tk_FloatNumber;
  604. TK_FetchRequire(TK_FLOATNUMBER);
  605. tList[i+start_tri].uv[1][1]=tk_FloatNumber;
  606. TK_FetchRequire(TK_FLOATNUMBER);
  607. tList[i+start_tri].uv[2][0]=tk_FloatNumber;
  608. TK_FetchRequire(TK_FLOATNUMBER);
  609. tList[i+start_tri].uv[2][1]=tk_FloatNumber;
  610. tList[i+start_tri].HasUV=1;
  611. }
  612. else
  613. tList[i+start_tri].HasUV=0;
  614. #endif
  615. // printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
  616. // " v2: %f, %f, %f\n", i,
  617. // tList[i].verts[0][0],
  618. // tList[i].verts[0][1],
  619. // tList[i].verts[0][2],
  620. // tList[i].verts[1][0],
  621. // tList[i].verts[1][1],
  622. // tList[i].verts[1][2],
  623. // tList[i].verts[2][0],
  624. // tList[i].verts[2][1],
  625. // tList[i].verts[2][2]);
  626. }
  627. TK_Fetch();
  628. if (tk_Token == TK_VERTICES)
  629. {
  630. HandleHTRModel(triList,triangleCount,nodesList, num_mesh_nodes, ActiveNode, Depth+1, vertexCount+vertIndexBase);
  631. }
  632. }
  633. static void LoadHTR(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)
  634. {
  635. if (nodesList)
  636. {
  637. *num_mesh_nodes = 0;
  638. if(!*nodesList)
  639. {
  640. *nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
  641. }
  642. }
  643. hrc_name = fileName;
  644. scaling[0] = scaling[1] = scaling[2] = 1.0;
  645. rotation[0] = rotation[1] = rotation[2] = 0.0;
  646. translation[0] = translation[1] = translation[2] = 0.0;
  647. *triangleCount = 0;
  648. *triList = SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");
  649. memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));
  650. TK_OpenSource(fileName);
  651. TK_Beyond(TK_C_HEXEN);
  652. TK_Beyond(TK_C_TRIANGLES);
  653. TK_BeyondRequire(TK_C_VERSION, TK_INTNUMBER);
  654. if(tk_IntNumber != 1&&tk_IntNumber != 2)
  655. {
  656. Error("Unsupported version (%d) in file %s\n", tk_IntNumber,
  657. fileName);
  658. }
  659. Version2=(tk_IntNumber==2);
  660. HandleHTRModel(triList, triangleCount, nodesList, num_mesh_nodes, 0, 0, 0);
  661. }
  662. */
  663. static void LoadHTR( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes ){
  664. int Version2 = 0;
  665. int i, j;
  666. int vertexCount;
  667. int vertexNum;
  668. struct
  669. {
  670. float v[3];
  671. } *vList;
  672. int triCount;
  673. float origin[3];
  674. triangle_t *tList;
  675. float x, y, z;
  676. float x2, y2, z2;
  677. float rx, ry, rz;
  678. if ( nodesList ) {
  679. *num_mesh_nodes = 0;
  680. *nodesList = (mesh_node_t *) SafeMalloc( MAX_FM_MESH_NODES * sizeof( mesh_node_t ), "Mesh Node List" );
  681. }
  682. TK_OpenSource( fileName );
  683. TK_Beyond( TK_C_HEXEN );
  684. TK_Beyond( TK_C_TRIANGLES );
  685. TK_BeyondRequire( TK_C_VERSION, TK_INTNUMBER );
  686. if ( tk_IntNumber != 1 && tk_IntNumber != 2 ) {
  687. Error( "Unsupported version (%d) in file %s\n", tk_IntNumber,
  688. fileName );
  689. }
  690. Version2 = ( tk_IntNumber == 2 );
  691. // Get vertex count
  692. TK_BeyondRequire( TK_VERTICES, TK_INTNUMBER );
  693. vertexCount = tk_IntNumber;
  694. vList = (void *) SafeMalloc( vertexCount * sizeof vList[0], "Vertex list" );
  695. // Get triangle count
  696. TK_BeyondRequire( TK_FACES, TK_INTNUMBER );
  697. triCount = tk_IntNumber;
  698. if ( triCount >= MAXTRIANGLES ) {
  699. Error( "Too many triangles in file %s\n", fileName );
  700. }
  701. *triangleCount = triCount;
  702. tList = (triangle_t *) SafeMalloc( MAXTRIANGLES * sizeof( triangle_t ), "Triangle list" );
  703. *triList = tList;
  704. memset( *triList,0,MAXTRIANGLES * sizeof( triangle_t ) );
  705. // Get origin
  706. TK_Beyond( TK_ORIGIN );
  707. TK_Require( TK_FLOATNUMBER );
  708. origin[0] = tk_FloatNumber;
  709. TK_FetchRequire( TK_FLOATNUMBER );
  710. origin[1] = tk_FloatNumber;
  711. TK_FetchRequire( TK_FLOATNUMBER );
  712. origin[2] = tk_FloatNumber;
  713. //rx = 90.0/360.0*2.0*M_PI;
  714. rx = FixHTRRotateX / 360.0 * 2.0 * M_PI;
  715. ry = FixHTRRotateY / 360.0 * 2.0 * M_PI;
  716. rz = FixHTRRotateZ / 360.0 * 2.0 * M_PI;
  717. // Get vertex list
  718. for ( i = 0; i < vertexCount; i++ )
  719. {
  720. TK_FetchRequire( TK_VERTEX );
  721. TK_FetchRequire( TK_FLOATNUMBER );
  722. x = tk_FloatNumber - origin[0];
  723. TK_FetchRequire( TK_FLOATNUMBER );
  724. y = tk_FloatNumber - origin[1];
  725. TK_FetchRequire( TK_FLOATNUMBER );
  726. z = tk_FloatNumber - origin[2];
  727. x += FixHTRTranslateX;
  728. y += FixHTRTranslateY;
  729. z += FixHTRTranslateZ;
  730. y2 = y * cos( rx ) - z*sin( rx );
  731. z2 = y * sin( rx ) + z*cos( rx );
  732. y = y2;
  733. z = z2;
  734. x2 = x * cos( ry ) + z*sin( ry );
  735. z2 = -x*sin( ry ) + z*cos( ry );
  736. x = x2;
  737. z = z2;
  738. x2 = x * cos( rz ) - y*sin( rz );
  739. y2 = x * sin( rz ) + y*cos( rz );
  740. x = x2;
  741. y = y2;
  742. vList[i].v[0] = x;
  743. vList[i].v[1] = y;
  744. vList[i].v[2] = z;
  745. }
  746. // Get face list
  747. for ( i = 0; i < triCount; i++ )
  748. {
  749. TK_FetchRequire( TK_FACE );
  750. TK_FetchRequire( TK_LPAREN );
  751. for ( j = 0; j < 3; j++ )
  752. {
  753. TK_FetchRequire( TK_INTNUMBER );
  754. vertexNum = tk_IntNumber - 1;
  755. if ( vertexNum >= vertexCount ) {
  756. Error( "File '%s', line %d:\nVertex number"
  757. " >= vertexCount: %d\n", tk_SourceName, tk_Line,
  758. tk_IntNumber );
  759. }
  760. tList[i].verts[2 - j][0] = vList[vertexNum].v[0];
  761. tList[i].verts[2 - j][1] = vList[vertexNum].v[1];
  762. tList[i].verts[2 - j][2] = vList[vertexNum].v[2];
  763. }
  764. TK_FetchRequire( TK_RPAREN );
  765. #if 1
  766. if ( Version2 ) {
  767. TK_FetchRequire( TK_FLOATNUMBER );
  768. tList[i].uv[2][0] = fmod( 1000 + tk_FloatNumber,1 );
  769. TK_FetchRequire( TK_FLOATNUMBER );
  770. tList[i].uv[2][1] = fmod( 1000 + tk_FloatNumber,1 );
  771. TK_FetchRequire( TK_FLOATNUMBER );
  772. tList[i].uv[1][0] = fmod( 1000 + tk_FloatNumber,1 );
  773. TK_FetchRequire( TK_FLOATNUMBER );
  774. tList[i].uv[1][1] = fmod( 1000 + tk_FloatNumber,1 );
  775. TK_FetchRequire( TK_FLOATNUMBER );
  776. tList[i].uv[0][0] = fmod( 1000 + tk_FloatNumber,1 );
  777. TK_FetchRequire( TK_FLOATNUMBER );
  778. tList[i].uv[0][1] = fmod( 1000 + tk_FloatNumber,1 );
  779. tList[i].HasUV = 1;
  780. }
  781. else{
  782. tList[i].HasUV = 0;
  783. }
  784. #endif
  785. /* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
  786. " v2: %f, %f, %f\n", i,
  787. tList[i].verts[0][0],
  788. tList[i].verts[0][1],
  789. tList[i].verts[0][2],
  790. tList[i].verts[1][0],
  791. tList[i].verts[1][1],
  792. tList[i].verts[1][2],
  793. tList[i].verts[2][0],
  794. tList[i].verts[2][1],
  795. tList[i].verts[2][2]);
  796. */
  797. }
  798. free( vList );
  799. TK_CloseSource();
  800. DefaultNodesList( nodesList,num_mesh_nodes,triangleCount );
  801. }
  802. //==========================================================================
  803. //
  804. // LoadTriangleList
  805. //
  806. //==========================================================================
  807. void LoadTriangleList( char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes ){
  808. FILE *file1;
  809. int dot = '.';
  810. char *dotstart;
  811. char InputFileName[256];
  812. dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
  813. if ( !dotstart ) {
  814. strcpy( InputFileName, fileName );
  815. strcat( InputFileName, ".hrc" );
  816. if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
  817. fclose( file1 );
  818. LoadHRC( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  819. printf( " - assuming .HRC\n" );
  820. return;
  821. }
  822. strcpy( InputFileName, fileName );
  823. strcat( InputFileName, ".asc" );
  824. if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
  825. fclose( file1 );
  826. LoadASC( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  827. printf( " - assuming .ASC\n" );
  828. return;
  829. }
  830. strcpy( InputFileName, fileName );
  831. strcat( InputFileName, ".tri" );
  832. if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
  833. fclose( file1 );
  834. LoadTRI( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  835. printf( " - assuming .TRI\n" );
  836. return;
  837. }
  838. strcpy( InputFileName, fileName );
  839. strcat( InputFileName, ".3ds" );
  840. if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
  841. fclose( file1 );
  842. Load3DSTriangleList( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  843. printf( " - assuming .3DS\n" );
  844. return;
  845. }
  846. strcpy( InputFileName, fileName );
  847. strcat( InputFileName, ".htr" );
  848. if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
  849. fclose( file1 );
  850. LoadHTR( InputFileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  851. printf( " - assuming .HTR\n" );
  852. return;
  853. }
  854. Error( "\n Could not open file '%s':\n"
  855. "No HRC, ASC, 3DS, HTR, or TRI match.\n", fileName );
  856. }
  857. else
  858. {
  859. if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
  860. printf( "\n" );
  861. fclose( file1 );
  862. if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
  863. LoadHRC( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  864. }
  865. else if ( strcmp( dotstart,".asc" ) == 0 || strcmp( dotstart,".ASC" ) == 0 ) {
  866. LoadASC( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  867. }
  868. else if ( strcmp( dotstart,".tri" ) == 0 || strcmp( dotstart,".TRI" ) == 0 ) {
  869. LoadTRI( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  870. }
  871. else if ( strcmp( dotstart,".3ds" ) == 0 || strcmp( dotstart,".3DS" ) == 0 ) {
  872. Load3DSTriangleList( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  873. }
  874. else if ( strcmp( dotstart,".htr" ) == 0 || strcmp( dotstart,".HTR" ) == 0 ) {
  875. LoadHTR( fileName, triList, triangleCount, ppmnodes, num_mesh_nodes );
  876. }
  877. else
  878. {
  879. Error( "Could not open file '%s':\n",fileName );
  880. return;
  881. }
  882. }
  883. else //failed to load file
  884. {
  885. Error( "Could not open file '%s':\n",fileName );
  886. }
  887. }
  888. }