2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
5 This file is part of Quake 2 Tools source code.
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, 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 Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
26 ==============================================================================
28 PORTAL FILE GENERATION
30 Save out name.prt for qvis to read
31 ==============================================================================
35 #define PORTALFILE "PRT1"
38 int num_visclusters; // clusters the player can be in
41 void WriteFloat (FILE *f, vec_t v)
43 if ( fabs(v - Q_rint(v)) < 0.001 )
44 fprintf (f,"%i ",(int)Q_rint(v));
54 void WritePortalFile_r (node_t *node)
63 if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
65 WritePortalFile_r (node->children[0]);
66 WritePortalFile_r (node->children[1]);
70 if (node->contents & CONTENTS_SOLID)
73 for (p = node->portals ; p ; p=p->next[s])
76 s = (p->nodes[1] == node);
77 if (w && p->nodes[0] == node)
79 if (!Portal_VisFlood (p))
81 // write out to the file
83 // sometimes planes get turned around when they are very near
84 // the changeover point between different axis. interpret the
85 // plane the same way vis will, and flip the side orders if needed
86 // FIXME: is this still relevent?
87 WindingPlane (w, normal, &dist);
88 if ( DotProduct (p->plane.normal, normal) < 0.99 )
90 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
93 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
94 for (i=0 ; i<w->numpoints ; i++)
97 WriteFloat (pf, w->p[i][0]);
98 WriteFloat (pf, w->p[i][1]);
99 WriteFloat (pf, w->p[i][2]);
112 All of the leafs under node will have the same cluster
115 void FillLeafNumbers_r (node_t *node, int num)
117 if (node->planenum == PLANENUM_LEAF)
119 if (node->contents & CONTENTS_SOLID)
126 FillLeafNumbers_r (node->children[0], num);
127 FillLeafNumbers_r (node->children[1], num);
135 void NumberLeafs_r (node_t *node)
139 if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
142 NumberLeafs_r (node->children[0]);
143 NumberLeafs_r (node->children[1]);
147 // either a leaf or a detail cluster
149 if ( node->contents & CONTENTS_SOLID )
150 { // solid block, viewpoint never inside
155 FillLeafNumbers_r (node, num_visclusters);
159 for (p = node->portals ; p ; )
161 if (p->nodes[0] == node) // only write out from first leaf
163 if (Portal_VisFlood (p))
179 void CreateVisPortals_r (node_t *node)
181 // stop as soon as we get to a detail_seperator, which
182 // means that everything below is in a single cluster
183 if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
186 MakeNodePortal (node);
187 SplitNodePortals (node);
189 CreateVisPortals_r (node->children[0]);
190 CreateVisPortals_r (node->children[1]);
198 void FinishVisPortals2_r (node_t *node)
200 if (node->planenum == PLANENUM_LEAF)
203 MakeNodePortal (node);
204 SplitNodePortals (node);
206 FinishVisPortals2_r (node->children[0]);
207 FinishVisPortals2_r (node->children[1]);
210 void FinishVisPortals_r (node_t *node)
212 if (node->planenum == PLANENUM_LEAF)
215 if (node->detail_seperator)
217 FinishVisPortals2_r (node);
221 FinishVisPortals_r (node->children[0]);
222 FinishVisPortals_r (node->children[1]);
227 void SaveClusters_r (node_t *node)
229 if (node->planenum == PLANENUM_LEAF)
231 dleafs[clusterleaf++].cluster = node->cluster;
234 SaveClusters_r (node->children[0]);
235 SaveClusters_r (node->children[1]);
243 void WritePortalFile (tree_t *tree)
248 qprintf ("--- WritePortalFile ---\n");
250 headnode = tree->headnode;
254 FreeTreePortals_r (headnode);
256 MakeHeadnodePortals (tree);
258 CreateVisPortals_r (headnode);
260 // set the cluster field in every leaf and count the total number of portals
262 NumberLeafs_r (headnode);
265 sprintf (filename, "%s.prt", source);
266 printf ("writing %s\n", filename);
267 pf = fopen (filename, "w");
269 Error ("Error opening %s", filename);
271 fprintf (pf, "%s\n", PORTALFILE);
272 fprintf (pf, "%i\n", num_visclusters);
273 fprintf (pf, "%i\n", num_visportals);
275 qprintf ("%5i visclusters\n", num_visclusters);
276 qprintf ("%5i visportals\n", num_visportals);
278 WritePortalFile_r (headnode);
282 // we need to store the clusters out now because ordering
283 // issues made us do this after writebsp...
285 SaveClusters_r (headnode);