2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 ==============================================================================
27 PORTAL FILE GENERATION
29 Save out name.prt for qvis to read
30 ==============================================================================
34 #define PORTALFILE "PRT1"
37 int num_visclusters; // clusters the player can be in
40 void WriteFloat (FILE *f, vec_t v)
42 if ( fabs(v - Q_rint(v)) < 0.001 )
43 fprintf (f,"%i ",(int)Q_rint(v));
53 void WritePortalFile_r (node_t *node)
62 if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
64 WritePortalFile_r (node->children[0]);
65 WritePortalFile_r (node->children[1]);
69 if (node->contents & CONTENTS_SOLID)
72 for (p = node->portals ; p ; p=p->next[s])
75 s = (p->nodes[1] == node);
76 if (w && p->nodes[0] == node)
78 if (!Portal_VisFlood (p))
80 // write out to the file
82 // sometimes planes get turned around when they are very near
83 // the changeover point between different axis. interpret the
84 // plane the same way vis will, and flip the side orders if needed
85 // FIXME: is this still relevent?
86 WindingPlane (w, normal, &dist);
87 if ( DotProduct (p->plane.normal, normal) < 0.99 )
89 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
92 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
93 for (i=0 ; i<w->numpoints ; i++)
96 WriteFloat (pf, w->p[i][0]);
97 WriteFloat (pf, w->p[i][1]);
98 WriteFloat (pf, w->p[i][2]);
111 All of the leafs under node will have the same cluster
114 void FillLeafNumbers_r (node_t *node, int num)
116 if (node->planenum == PLANENUM_LEAF)
118 if (node->contents & CONTENTS_SOLID)
125 FillLeafNumbers_r (node->children[0], num);
126 FillLeafNumbers_r (node->children[1], num);
134 void NumberLeafs_r (node_t *node)
138 if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
141 NumberLeafs_r (node->children[0]);
142 NumberLeafs_r (node->children[1]);
146 // either a leaf or a detail cluster
148 if ( node->contents & CONTENTS_SOLID )
149 { // solid block, viewpoint never inside
154 FillLeafNumbers_r (node, num_visclusters);
158 for (p = node->portals ; p ; )
160 if (p->nodes[0] == node) // only write out from first leaf
162 if (Portal_VisFlood (p))
178 void CreateVisPortals_r (node_t *node)
180 // stop as soon as we get to a detail_seperator, which
181 // means that everything below is in a single cluster
182 if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
185 MakeNodePortal (node);
186 SplitNodePortals (node);
188 CreateVisPortals_r (node->children[0]);
189 CreateVisPortals_r (node->children[1]);
197 void FinishVisPortals2_r (node_t *node)
199 if (node->planenum == PLANENUM_LEAF)
202 MakeNodePortal (node);
203 SplitNodePortals (node);
205 FinishVisPortals2_r (node->children[0]);
206 FinishVisPortals2_r (node->children[1]);
209 void FinishVisPortals_r (node_t *node)
211 if (node->planenum == PLANENUM_LEAF)
214 if (node->detail_seperator)
216 FinishVisPortals2_r (node);
220 FinishVisPortals_r (node->children[0]);
221 FinishVisPortals_r (node->children[1]);
226 void SaveClusters_r (node_t *node)
228 if (node->planenum == PLANENUM_LEAF)
230 dleafs[clusterleaf++].cluster = node->cluster;
233 SaveClusters_r (node->children[0]);
234 SaveClusters_r (node->children[1]);
242 void WritePortalFile (tree_t *tree)
247 Sys_FPrintf( SYS_VRB, "--- WritePortalFile ---\n");
249 headnode = tree->headnode;
253 FreeTreePortals_r (headnode);
255 MakeHeadnodePortals (tree);
257 CreateVisPortals_r (headnode);
259 // set the cluster field in every leaf and count the total number of portals
261 NumberLeafs_r (headnode);
264 sprintf (filename, "%s.prt", source);
265 Sys_Printf ("writing %s\n", filename);
266 pf = fopen (filename, "w");
268 Error ("Error opening %s", filename);
270 fprintf (pf, "%s\n", PORTALFILE);
271 fprintf (pf, "%i\n", num_visclusters);
272 fprintf (pf, "%i\n", num_visportals);
274 Sys_FPrintf( SYS_VRB, "%5i visclusters\n", num_visclusters);
275 Sys_FPrintf( SYS_VRB, "%5i visportals\n", num_visportals);
277 WritePortalFile_r (headnode);
281 // we need to store the clusters out now because ordering
282 // issues made us do this after writebsp...
284 SaveClusters_r (headnode);