2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
\r
5 This file is part of GtkRadiant.
\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
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
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
21 ----------------------------------------------------------------------------------
\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
26 ------------------------------------------------------------------------------- */
\r
41 ==============================================================================
\r
43 PORTAL FILE GENERATION
\r
45 Save out name.prt for qvis to read
\r
46 ==============================================================================
\r
50 #define PORTALFILE "PRT1"
\r
53 int num_visclusters; // clusters the player can be in
\r
57 void WriteFloat (FILE *f, vec_t v)
\r
59 if ( fabs(v - Q_rint(v)) < 0.001 )
\r
60 fprintf (f,"%i ",(int)Q_rint(v));
\r
62 fprintf (f,"%f ",v);
\r
70 void WritePortalFile_r (node_t *node)
\r
79 if (node->planenum != PLANENUM_LEAF) {
\r
80 WritePortalFile_r (node->children[0]);
\r
81 WritePortalFile_r (node->children[1]);
\r
89 for (p = node->portals ; p ; p=p->next[s])
\r
92 s = (p->nodes[1] == node);
\r
93 if (w && p->nodes[0] == node)
\r
95 if (!PortalPassable(p))
\r
97 // write out to the file
\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
106 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
\r
109 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
\r
111 /* ydnar: added this change to make antiportals work */
\r
112 if( p->compileFlags & C_HINT )
\r
113 fprintf( pf, "1 " );
\r
115 fprintf( pf, "0 " );
\r
117 /* write the winding */
\r
118 for (i=0 ; i<w->numpoints ; i++)
\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
137 void WriteFaceFile_r (node_t *node)
\r
144 if (node->planenum != PLANENUM_LEAF) {
\r
145 WriteFaceFile_r (node->children[0]);
\r
146 WriteFaceFile_r (node->children[1]);
\r
150 if (node->opaque) {
\r
154 for (p = node->portals ; p ; p=p->next[s])
\r
157 s = (p->nodes[1] == node);
\r
160 if (PortalPassable(p))
\r
162 // write out to the file
\r
164 if (p->nodes[0] == node)
\r
166 fprintf (pf,"%i %i ",w->numpoints, p->nodes[0]->cluster);
\r
167 for (i=0 ; i<w->numpoints ; i++)
\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
179 fprintf (pf,"%i %i ",w->numpoints, p->nodes[1]->cluster);
\r
180 for (i = w->numpoints-1; i >= 0; i--)
\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
199 void NumberLeafs_r (node_t *node)
\r
203 if ( node->planenum != PLANENUM_LEAF ) {
\r
205 node->cluster = -99;
\r
206 NumberLeafs_r (node->children[0]);
\r
207 NumberLeafs_r (node->children[1]);
\r
213 if ( node->opaque ) {
\r
214 // solid block, viewpoint never inside
\r
215 node->cluster = -1;
\r
219 node->cluster = num_visclusters;
\r
222 // count the portals
\r
223 for (p = node->portals ; p ; )
\r
225 if (p->nodes[0] == node) // only write out from first leaf
\r
227 if (PortalPassable(p))
\r
235 if (!PortalPassable(p))
\r
248 void NumberClusters(tree_t *tree) {
\r
249 num_visclusters = 0;
\r
250 num_visportals = 0;
\r
251 num_solidfaces = 0;
\r
253 Sys_FPrintf (SYS_VRB,"--- NumberClusters ---\n");
\r
255 // set the cluster field in every leaf and count the total number of portals
\r
256 NumberLeafs_r (tree->headnode);
\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
268 void WritePortalFile (tree_t *tree)
\r
270 char filename[1024];
\r
272 Sys_FPrintf (SYS_VRB,"--- WritePortalFile ---\n");
\r
275 sprintf (filename, "%s.prt", source);
\r
276 Sys_Printf ("writing %s\n", filename);
\r
277 pf = fopen (filename, "w");
\r
279 Error ("Error opening %s", filename);
\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
286 WritePortalFile_r(tree->headnode);
\r
287 WriteFaceFile_r(tree->headnode);
\r