trilib.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. //
  19. // trilib.c: library for loading triangles from an Alias triangle file
  20. //
  21. #include <stdio.h>
  22. #include "cmdlib.h"
  23. #include "mathlib.h"
  24. #include "polyset.h"
  25. #include "trilib.h"
  26. // on disk representation of a face
  27. #define FLOAT_START 99999.0
  28. #define FLOAT_END -FLOAT_START
  29. #define MAGIC 123322
  30. //#define NOISY 1
  31. typedef struct {
  32. float v[3];
  33. } vector;
  34. typedef struct
  35. {
  36. vector n; /* normal */
  37. vector p; /* point */
  38. vector c; /* color */
  39. float u; /* u */
  40. float v; /* v */
  41. } aliaspoint_t;
  42. typedef struct {
  43. aliaspoint_t pt[3];
  44. } tf_triangle;
  45. static void ByteSwapTri (tf_triangle *tri)
  46. {
  47. int i;
  48. for (i=0 ; i<sizeof(tf_triangle)/4 ; i++)
  49. {
  50. ((int *)tri)[i] = BigLong (((int *)tri)[i]);
  51. }
  52. }
  53. static void ReadPolysetGeometry( triangle_t *tripool, FILE *input, int count, triangle_t *ptri )
  54. {
  55. tf_triangle tri;
  56. int i;
  57. for (i = 0; i < count; ++i) {
  58. int j;
  59. fread( &tri, sizeof(tf_triangle), 1, input );
  60. ByteSwapTri (&tri);
  61. for (j=0 ; j<3 ; j++)
  62. {
  63. int k;
  64. for (k=0 ; k<3 ; k++)
  65. {
  66. ptri->verts[j][k] = tri.pt[j].p.v[k];
  67. ptri->normals[j][k] = tri.pt[j].n.v[k];
  68. // ptri->colors[j][k] = tri.pt[j].c.v[k];
  69. }
  70. ptri->texcoords[j][0] = tri.pt[j].u;
  71. ptri->texcoords[j][1] = tri.pt[j].v;
  72. }
  73. ptri++;
  74. if ((ptri - tripool ) >= POLYSET_MAXTRIANGLES)
  75. Error ("Error: too many triangles; increase POLYSET_MAXTRIANGLES\n");
  76. }
  77. }
  78. void TRI_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets )
  79. {
  80. FILE *input;
  81. float start;
  82. char name[256], tex[256];
  83. int i, count, magic, pset = 0;
  84. triangle_t *ptri;
  85. polyset_t *pPSET;
  86. int iLevel;
  87. int exitpattern;
  88. float t;
  89. t = -FLOAT_START;
  90. *((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);
  91. *((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);
  92. *((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);
  93. *((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);
  94. if ((input = fopen(filename, "rb")) == 0)
  95. Error ("reader: could not open file '%s'", filename);
  96. iLevel = 0;
  97. fread(&magic, sizeof(int), 1, input);
  98. if (BigLong(magic) != MAGIC)
  99. Error ("%s is not a Alias object separated triangle file, magic number is wrong.", filename);
  100. pPSET = calloc( 1, POLYSET_MAXPOLYSETS * sizeof( polyset_t ) );
  101. ptri = calloc( 1, POLYSET_MAXTRIANGLES * sizeof( triangle_t ) );
  102. *ppPSET = pPSET;
  103. while (feof(input) == 0) {
  104. if (fread(&start, sizeof(float), 1, input) < 1)
  105. break;
  106. *(int *)&start = BigLong(*(int *)&start);
  107. if (*(int *)&start != exitpattern)
  108. {
  109. if (start == FLOAT_START) {
  110. /* Start of an object or group of objects. */
  111. i = -1;
  112. do {
  113. /* There are probably better ways to read a string from */
  114. /* a file, but this does allow you to do error checking */
  115. /* (which I'm not doing) on a per character basis. */
  116. ++i;
  117. fread( &(name[i]), sizeof( char ), 1, input);
  118. } while( name[i] != '\0' );
  119. if ( i != 0 )
  120. strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 );
  121. else
  122. strcpy( pPSET[pset].name , "(unnamed)" );
  123. strlwr( pPSET[pset].name );
  124. // indent();
  125. // fprintf(stdout,"OBJECT START: %s\n",name);
  126. fread( &count, sizeof(int), 1, input);
  127. count = BigLong(count);
  128. ++iLevel;
  129. if (count != 0) {
  130. // indent();
  131. // fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);
  132. i = -1;
  133. do {
  134. ++i;
  135. fread( &(tex[i]), sizeof( char ), 1, input);
  136. } while( tex[i] != '\0' );
  137. /*
  138. if ( i != 0 )
  139. strncpy( pPSET[pset].texname, tex, sizeof( pPSET[pset].texname ) - 1 );
  140. else
  141. strcpy( pPSET[pset].texname, "(unnamed)" );
  142. strlwr( pPSET[pset].texname );
  143. */
  144. // indent();
  145. // fprintf(stdout," Object texture name: '%s'\n",tex);
  146. }
  147. /* Else (count == 0) this is the start of a group, and */
  148. /* no texture name is present. */
  149. }
  150. else if (start == FLOAT_END) {
  151. /* End of an object or group. Yes, the name should be */
  152. /* obvious from context, but it is in here just to be */
  153. /* safe and to provide a little extra information for */
  154. /* those who do not wish to write a recursive reader. */
  155. /* Mea culpa. */
  156. --iLevel;
  157. i = -1;
  158. do {
  159. ++i;
  160. fread( &(name[i]), sizeof( char ), 1, input);
  161. } while( name[i] != '\0' );
  162. if ( i != 0 )
  163. strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 );
  164. else
  165. strcpy( pPSET[pset].name , "(unnamed)" );
  166. strlwr( pPSET[pset].name );
  167. // indent();
  168. // fprintf(stdout,"OBJECT END: %s\n",name);
  169. continue;
  170. }
  171. }
  172. //
  173. // read the triangles
  174. //
  175. if ( count > 0 )
  176. {
  177. pPSET[pset].triangles = ptri;
  178. ReadPolysetGeometry( pPSET[0].triangles, input, count, ptri );
  179. ptri += count;
  180. pPSET[pset].numtriangles = count;
  181. if ( ++pset >= POLYSET_MAXPOLYSETS )
  182. {
  183. Error ("Error: too many polysets; increase POLYSET_MAXPOLYSETS\n");
  184. }
  185. }
  186. }
  187. *numpsets = pset;
  188. fclose (input);
  189. }