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
25 ==============================================================================
\r
27 PORTAL FILE GENERATION
\r
29 Save out name.prt for qvis to read
\r
30 ==============================================================================
\r
34 #define PORTALFILE "PRT1"
\r
37 int num_visclusters; // clusters the player can be in
\r
40 void WriteFloat (FILE *f, vec_t v)
\r
42 if ( fabs(v - Q_rint(v)) < 0.001 )
\r
43 fprintf (f,"%i ",(int)Q_rint(v));
\r
45 fprintf (f,"%f ",v);
\r
53 void WritePortalFile_r (node_t *node)
\r
62 if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
\r
64 WritePortalFile_r (node->children[0]);
\r
65 WritePortalFile_r (node->children[1]);
\r
69 if (node->contents & CONTENTS_SOLID)
\r
72 for (p = node->portals ; p ; p=p->next[s])
\r
75 s = (p->nodes[1] == node);
\r
76 if (w && p->nodes[0] == node)
\r
78 if (!Portal_VisFlood (p))
\r
80 // write out to the file
\r
82 // sometimes planes get turned around when they are very near
\r
83 // the changeover point between different axis. interpret the
\r
84 // plane the same way vis will, and flip the side orders if needed
\r
85 // FIXME: is this still relevent?
\r
86 WindingPlane (w, normal, &dist);
\r
87 if ( DotProduct (p->plane.normal, normal) < 0.99 )
\r
89 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
\r
92 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
\r
93 for (i=0 ; i<w->numpoints ; i++)
\r
96 WriteFloat (pf, w->p[i][0]);
\r
97 WriteFloat (pf, w->p[i][1]);
\r
98 WriteFloat (pf, w->p[i][2]);
\r
111 All of the leafs under node will have the same cluster
\r
114 void FillLeafNumbers_r (node_t *node, int num)
\r
116 if (node->planenum == PLANENUM_LEAF)
\r
118 if (node->contents & CONTENTS_SOLID)
\r
119 node->cluster = -1;
\r
121 node->cluster = num;
\r
124 node->cluster = num;
\r
125 FillLeafNumbers_r (node->children[0], num);
\r
126 FillLeafNumbers_r (node->children[1], num);
\r
134 void NumberLeafs_r (node_t *node)
\r
138 if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
\r
140 node->cluster = -99;
\r
141 NumberLeafs_r (node->children[0]);
\r
142 NumberLeafs_r (node->children[1]);
\r
146 // either a leaf or a detail cluster
\r
148 if ( node->contents & CONTENTS_SOLID )
\r
149 { // solid block, viewpoint never inside
\r
150 node->cluster = -1;
\r
154 FillLeafNumbers_r (node, num_visclusters);
\r
157 // count the portals
\r
158 for (p = node->portals ; p ; )
\r
160 if (p->nodes[0] == node) // only write out from first leaf
\r
162 if (Portal_VisFlood (p))
\r
178 void CreateVisPortals_r (node_t *node)
\r
180 // stop as soon as we get to a detail_seperator, which
\r
181 // means that everything below is in a single cluster
\r
182 if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
\r
185 MakeNodePortal (node);
\r
186 SplitNodePortals (node);
\r
188 CreateVisPortals_r (node->children[0]);
\r
189 CreateVisPortals_r (node->children[1]);
\r
197 void FinishVisPortals2_r (node_t *node)
\r
199 if (node->planenum == PLANENUM_LEAF)
\r
202 MakeNodePortal (node);
\r
203 SplitNodePortals (node);
\r
205 FinishVisPortals2_r (node->children[0]);
\r
206 FinishVisPortals2_r (node->children[1]);
\r
209 void FinishVisPortals_r (node_t *node)
\r
211 if (node->planenum == PLANENUM_LEAF)
\r
214 if (node->detail_seperator)
\r
216 FinishVisPortals2_r (node);
\r
220 FinishVisPortals_r (node->children[0]);
\r
221 FinishVisPortals_r (node->children[1]);
\r
226 void SaveClusters_r (node_t *node)
\r
228 if (node->planenum == PLANENUM_LEAF)
\r
230 dleafs[clusterleaf++].cluster = node->cluster;
\r
233 SaveClusters_r (node->children[0]);
\r
234 SaveClusters_r (node->children[1]);
\r
242 void WritePortalFile (tree_t *tree)
\r
244 char filename[1024];
\r
247 Sys_FPrintf( SYS_VRB, "--- WritePortalFile ---\n");
\r
249 headnode = tree->headnode;
\r
250 num_visclusters = 0;
\r
251 num_visportals = 0;
\r
253 FreeTreePortals_r (headnode);
\r
255 MakeHeadnodePortals (tree);
\r
257 CreateVisPortals_r (headnode);
\r
259 // set the cluster field in every leaf and count the total number of portals
\r
261 NumberLeafs_r (headnode);
\r
264 sprintf (filename, "%s.prt", source);
\r
265 Sys_Printf ("writing %s\n", filename);
\r
266 pf = fopen (filename, "w");
\r
268 Error ("Error opening %s", filename);
\r
270 fprintf (pf, "%s\n", PORTALFILE);
\r
271 fprintf (pf, "%i\n", num_visclusters);
\r
272 fprintf (pf, "%i\n", num_visportals);
\r
274 Sys_FPrintf( SYS_VRB, "%5i visclusters\n", num_visclusters);
\r
275 Sys_FPrintf( SYS_VRB, "%5i visportals\n", num_visportals);
\r
277 WritePortalFile_r (headnode);
\r
281 // we need to store the clusters out now because ordering
\r
282 // issues made us do this after writebsp...
\r
284 SaveClusters_r (headnode);
\r