]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/common/trilib.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / common / trilib.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 //\r
22 // trilib.c: library for loading triangles from an Alias triangle file\r
23 //\r
24 \r
25 #include <stdio.h>\r
26 #include "cmdlib.h"\r
27 #include "inout.h"\r
28 #include "mathlib.h"\r
29 #include "trilib.h"\r
30 \r
31 // on disk representation of a face\r
32 \r
33 \r
34 #define FLOAT_START     99999.0\r
35 #define FLOAT_END       -FLOAT_START\r
36 #define MAGIC       123322\r
37 \r
38 //#define NOISY 1\r
39 \r
40 typedef struct {\r
41         float v[3];\r
42 } vector;\r
43 \r
44 typedef struct\r
45 {\r
46         vector n;    /* normal */\r
47         vector p;    /* point */\r
48         vector c;    /* color */\r
49         float  u;    /* u */\r
50         float  v;    /* v */\r
51 } aliaspoint_t;\r
52 \r
53 typedef struct {\r
54         aliaspoint_t    pt[3];\r
55 } tf_triangle;\r
56 \r
57 \r
58 void ByteSwapTri (tf_triangle *tri)\r
59 {\r
60         int             i;\r
61         \r
62         for (i=0 ; i<sizeof(tf_triangle)/4 ; i++)\r
63         {\r
64                 ((int *)tri)[i] = BigLong (((int *)tri)[i]);\r
65         }\r
66 }\r
67 \r
68 void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles)\r
69 {\r
70         FILE        *input;\r
71         float       start;\r
72         char        name[256], tex[256];\r
73         int         i, count, magic;\r
74         tf_triangle     tri;\r
75         triangle_t      *ptri;\r
76         int                     iLevel;\r
77         int                     exitpattern;\r
78         float           t;\r
79 \r
80         t = -FLOAT_START;\r
81         *((unsigned char *)&exitpattern + 0) = *((unsigned char *)&t + 3);\r
82         *((unsigned char *)&exitpattern + 1) = *((unsigned char *)&t + 2);\r
83         *((unsigned char *)&exitpattern + 2) = *((unsigned char *)&t + 1);\r
84         *((unsigned char *)&exitpattern + 3) = *((unsigned char *)&t + 0);\r
85 \r
86         if ((input = fopen(filename, "rb")) == 0)\r
87                 Error ("reader: could not open file '%s'", filename);\r
88 \r
89         iLevel = 0;\r
90 \r
91         fread(&magic, sizeof(int), 1, input);\r
92         if (BigLong(magic) != MAGIC)\r
93                 Error ("%s is not a Alias object separated triangle file, magic number is wrong.", filename);\r
94 \r
95         ptri = malloc (MAXTRIANGLES * sizeof(triangle_t));\r
96 \r
97         *pptri = ptri;\r
98 \r
99         while (feof(input) == 0) {\r
100                 if (fread(&start,  sizeof(float), 1, input) < 1)\r
101                         break;\r
102                 *(int *)&start = BigLong(*(int *)&start);\r
103                 if (*(int *)&start != exitpattern)\r
104                 {\r
105                         if (start == FLOAT_START) {\r
106                                 /* Start of an object or group of objects. */\r
107                                 i = -1;\r
108                                 do {\r
109                                         /* There are probably better ways to read a string from */\r
110                                         /* a file, but this does allow you to do error checking */\r
111                                         /* (which I'm not doing) on a per character basis.      */\r
112                                         ++i;\r
113                                         fread( &(name[i]), sizeof( char ), 1, input);\r
114                                 } while( name[i] != '\0' );\r
115         \r
116 //                              indent();\r
117 //                              fprintf(stdout,"OBJECT START: %s\n",name);\r
118                                 fread( &count, sizeof(int), 1, input);\r
119                                 count = BigLong(count);\r
120                                 ++iLevel;\r
121                                 if (count != 0) {\r
122 //                                      indent();\r
123 //                                      fprintf(stdout,"NUMBER OF TRIANGLES: %d\n",count);\r
124         \r
125                                         i = -1;\r
126                                         do {\r
127                                                 ++i;\r
128                                                 fread( &(tex[i]), sizeof( char ), 1, input);\r
129                                         } while( tex[i] != '\0' );\r
130         \r
131 //                                      indent();\r
132 //                                      fprintf(stdout,"  Object texture name: '%s'\n",tex);\r
133                                 }\r
134         \r
135                                 /* Else (count == 0) this is the start of a group, and */\r
136                                 /* no texture name is present. */\r
137                         }\r
138                         else if (start == FLOAT_END) {\r
139                                 /* End of an object or group. Yes, the name should be */\r
140                                 /* obvious from context, but it is in here just to be */\r
141                                 /* safe and to provide a little extra information for */\r
142                                 /* those who do not wish to write a recursive reader. */\r
143                                 /* Mia culpa. */\r
144                                 --iLevel;\r
145                                 i = -1;\r
146                                 do {\r
147                                         ++i;\r
148                                         fread( &(name[i]), sizeof( char ), 1, input);\r
149                                 } while( name[i] != '\0' );\r
150         \r
151 //                              indent();\r
152 //                              fprintf(stdout,"OBJECT END: %s\n",name);\r
153                                 continue;\r
154                         }\r
155                 }\r
156 \r
157 //\r
158 // read the triangles\r
159 //              \r
160                 for (i = 0; i < count; ++i) {\r
161                         int             j;\r
162 \r
163                         fread( &tri, sizeof(tf_triangle), 1, input );\r
164                         ByteSwapTri (&tri);\r
165                         for (j=0 ; j<3 ; j++)\r
166                         {\r
167                                 int             k;\r
168 \r
169                                 for (k=0 ; k<3 ; k++)\r
170                                 {\r
171                                         ptri->verts[j][k] = tri.pt[j].p.v[k];\r
172                                 }\r
173                         }\r
174 \r
175                         ptri++;\r
176 \r
177                         if ((ptri - *pptri) >= MAXTRIANGLES)\r
178                                 Error ("Error: too many triangles; increase MAXTRIANGLES\n");\r
179                 }\r
180         }\r
181 \r
182         *numtriangles = ptri - *pptri;\r
183 \r
184         fclose (input);\r
185 }\r
186 \r