]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3map2/prtfile.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake3 / q3map2 / prtfile.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 \r
23 This code has been altered significantly from its original form, to support\r
24 several games based on the Quake III Arena engine, in the form of "Q3Map2."\r
25 \r
26 ------------------------------------------------------------------------------- */\r
27 \r
28 \r
29 \r
30 /* marker */\r
31 #define PRTFILE_C\r
32 \r
33 \r
34 \r
35 /* dependencies */\r
36 #include "q3map2.h"\r
37 \r
38 \r
39 \r
40 /*\r
41 ==============================================================================\r
42 \r
43 PORTAL FILE GENERATION\r
44 \r
45 Save out name.prt for qvis to read\r
46 ==============================================================================\r
47 */\r
48 \r
49 \r
50 #define PORTALFILE      "PRT1"\r
51 \r
52 FILE    *pf;\r
53 int             num_visclusters;                                // clusters the player can be in\r
54 int             num_visportals;\r
55 int             num_solidfaces;\r
56 \r
57 void WriteFloat (FILE *f, vec_t v)\r
58 {\r
59         if ( fabs(v - Q_rint(v)) < 0.001 )\r
60                 fprintf (f,"%i ",(int)Q_rint(v));\r
61         else\r
62                 fprintf (f,"%f ",v);\r
63 }\r
64 \r
65 /*\r
66 =================\r
67 WritePortalFile_r\r
68 =================\r
69 */\r
70 void WritePortalFile_r (node_t *node)\r
71 {\r
72         int                     i, s;   \r
73         portal_t        *p;\r
74         winding_t       *w;\r
75         vec3_t          normal;\r
76         vec_t           dist;\r
77 \r
78         // decision node\r
79         if (node->planenum != PLANENUM_LEAF) {\r
80                 WritePortalFile_r (node->children[0]);\r
81                 WritePortalFile_r (node->children[1]);\r
82                 return;\r
83         }\r
84         \r
85         if (node->opaque) {\r
86                 return;\r
87         }\r
88 \r
89         for (p = node->portals ; p ; p=p->next[s])\r
90         {\r
91                 w = p->winding;\r
92                 s = (p->nodes[1] == node);\r
93                 if (w && p->nodes[0] == node)\r
94                 {\r
95                         if (!PortalPassable(p))\r
96                                 continue;\r
97                         // write out to the file\r
98                         \r
99                         // sometimes planes get turned around when they are very near\r
100                         // the changeover point between different axis.  interpret the\r
101                         // plane the same way vis will, and flip the side orders if needed\r
102                         // FIXME: is this still relevent?\r
103                         WindingPlane (w, normal, &dist);\r
104                         if ( DotProduct (p->plane.normal, normal) < 0.99 )\r
105                         {       // backwards...\r
106                                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);\r
107                         }\r
108                         else\r
109                                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);\r
110                         \r
111                         /* ydnar: added this change to make antiportals work */\r
112                         if( p->compileFlags & C_HINT )\r
113                                 fprintf( pf, "1 " );\r
114                         else\r
115                                 fprintf( pf, "0 " );\r
116                         \r
117                         /* write the winding */\r
118                         for (i=0 ; i<w->numpoints ; i++)\r
119                         {\r
120                                 fprintf (pf,"(");\r
121                                 WriteFloat (pf, w->p[i][0]);\r
122                                 WriteFloat (pf, w->p[i][1]);\r
123                                 WriteFloat (pf, w->p[i][2]);\r
124                                 fprintf (pf,") ");\r
125                         }\r
126                         fprintf (pf,"\n");\r
127                 }\r
128         }\r
129 \r
130 }\r
131 \r
132 /*\r
133 =================\r
134 WriteFaceFile_r\r
135 =================\r
136 */\r
137 void WriteFaceFile_r (node_t *node)\r
138 {\r
139         int                     i, s;   \r
140         portal_t        *p;\r
141         winding_t       *w;\r
142 \r
143         // decision node\r
144         if (node->planenum != PLANENUM_LEAF) {\r
145                 WriteFaceFile_r (node->children[0]);\r
146                 WriteFaceFile_r (node->children[1]);\r
147                 return;\r
148         }\r
149         \r
150         if (node->opaque) {\r
151                 return;\r
152         }\r
153 \r
154         for (p = node->portals ; p ; p=p->next[s])\r
155         {\r
156                 w = p->winding;\r
157                 s = (p->nodes[1] == node);\r
158                 if (w)\r
159                 {\r
160                         if (PortalPassable(p))\r
161                                 continue;\r
162                         // write out to the file\r
163 \r
164                         if (p->nodes[0] == node)\r
165                         {\r
166                                 fprintf (pf,"%i %i ",w->numpoints, p->nodes[0]->cluster);\r
167                                 for (i=0 ; i<w->numpoints ; i++)\r
168                                 {\r
169                                         fprintf (pf,"(");\r
170                                         WriteFloat (pf, w->p[i][0]);\r
171                                         WriteFloat (pf, w->p[i][1]);\r
172                                         WriteFloat (pf, w->p[i][2]);\r
173                                         fprintf (pf,") ");\r
174                                 }\r
175                                 fprintf (pf,"\n");\r
176                         }\r
177                         else\r
178                         {\r
179                                 fprintf (pf,"%i %i ",w->numpoints, p->nodes[1]->cluster);\r
180                                 for (i = w->numpoints-1; i >= 0; i--)\r
181                                 {\r
182                                         fprintf (pf,"(");\r
183                                         WriteFloat (pf, w->p[i][0]);\r
184                                         WriteFloat (pf, w->p[i][1]);\r
185                                         WriteFloat (pf, w->p[i][2]);\r
186                                         fprintf (pf,") ");\r
187                                 }\r
188                                 fprintf (pf,"\n");\r
189                         }\r
190                 }\r
191         }\r
192 }\r
193 \r
194 /*\r
195 ================\r
196 NumberLeafs_r\r
197 ================\r
198 */\r
199 void NumberLeafs_r (node_t *node)\r
200 {\r
201         portal_t        *p;\r
202 \r
203         if ( node->planenum != PLANENUM_LEAF ) {\r
204                 // decision node\r
205                 node->cluster = -99;\r
206                 NumberLeafs_r (node->children[0]);\r
207                 NumberLeafs_r (node->children[1]);\r
208                 return;\r
209         }\r
210         \r
211         node->area = -1;\r
212 \r
213         if ( node->opaque ) {\r
214                 // solid block, viewpoint never inside\r
215                 node->cluster = -1;\r
216                 return;\r
217         }\r
218 \r
219         node->cluster = num_visclusters;\r
220         num_visclusters++;\r
221 \r
222         // count the portals\r
223         for (p = node->portals ; p ; )\r
224         {\r
225                 if (p->nodes[0] == node)                // only write out from first leaf\r
226                 {\r
227                         if (PortalPassable(p))\r
228                                 num_visportals++;\r
229                         else\r
230                                 num_solidfaces++;\r
231                         p = p->next[0];\r
232                 }\r
233                 else\r
234                 {\r
235                         if (!PortalPassable(p))\r
236                                 num_solidfaces++;\r
237                         p = p->next[1];         \r
238                 }\r
239         }\r
240 }\r
241 \r
242 \r
243 /*\r
244 ================\r
245 NumberClusters\r
246 ================\r
247 */\r
248 void NumberClusters(tree_t *tree) {\r
249         num_visclusters = 0;\r
250         num_visportals = 0;\r
251         num_solidfaces = 0;\r
252 \r
253         Sys_FPrintf (SYS_VRB,"--- NumberClusters ---\n");\r
254         \r
255         // set the cluster field in every leaf and count the total number of portals\r
256         NumberLeafs_r (tree->headnode);\r
257 \r
258         Sys_FPrintf( SYS_VRB, "%9d visclusters\n", num_visclusters );\r
259         Sys_FPrintf( SYS_VRB, "%9d visportals\n", num_visportals );\r
260         Sys_FPrintf( SYS_VRB, "%9d solidfaces\n", num_solidfaces );\r
261 }\r
262 \r
263 /*\r
264 ================\r
265 WritePortalFile\r
266 ================\r
267 */\r
268 void WritePortalFile (tree_t *tree)\r
269 {\r
270         char    filename[1024];\r
271 \r
272         Sys_FPrintf (SYS_VRB,"--- WritePortalFile ---\n");\r
273         \r
274         // write the file\r
275         sprintf (filename, "%s.prt", source);\r
276         Sys_Printf ("writing %s\n", filename);\r
277         pf = fopen (filename, "w");\r
278         if (!pf)\r
279                 Error ("Error opening %s", filename);\r
280                 \r
281         fprintf (pf, "%s\n", PORTALFILE);\r
282         fprintf (pf, "%i\n", num_visclusters);\r
283         fprintf (pf, "%i\n", num_visportals);\r
284         fprintf (pf, "%i\n", num_solidfaces);\r
285 \r
286         WritePortalFile_r(tree->headnode);\r
287         WriteFaceFile_r(tree->headnode);\r
288 \r
289         fclose (pf);\r
290 }\r
291 \r