Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

prtfile.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 #include "qbsp.h"
00024 
00025 /*
00026 ==============================================================================
00027 
00028 PORTAL FILE GENERATION
00029 
00030 Save out name.prt for qvis to read
00031 ==============================================================================
00032 */
00033 
00034 
00035 #define PORTALFILE  "PRT1"
00036 
00037 FILE    *pf;
00038 int     num_visclusters;                // clusters the player can be in
00039 int     num_visportals;
00040 
00041 void WriteFloat2 (FILE *f, vec_t v)
00042 {
00043     if ( fabs(v - Q_rint(v)) < 0.001 )
00044         fprintf (f,"%i ",(int)Q_rint(v));
00045     else
00046         fprintf (f,"%f ",v);
00047 }
00048 
00049 /*
00050 =================
00051 WritePortalFile_r
00052 =================
00053 */
00054 void WritePortalFile_r (node_t *node)
00055 {
00056     int         i, s;   
00057     portal_t    *p;
00058     winding_t   *w;
00059     vec3_t      normal;
00060     vec_t       dist;
00061 
00062     // decision node
00063     if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
00064     {
00065         WritePortalFile_r (node->children[0]);
00066         WritePortalFile_r (node->children[1]);
00067         return;
00068     }
00069     
00070     if (node->contents & CONTENTS_SOLID)
00071         return;
00072 
00073     for (p = node->portals ; p ; p=p->next[s])
00074     {
00075         w = p->winding;
00076         s = (p->nodes[1] == node);
00077         if (w && p->nodes[0] == node)
00078         {
00079             if (!Portal_VisFlood (p))
00080                 continue;
00081         // write out to the file
00082         
00083         // sometimes planes get turned around when they are very near
00084         // the changeover point between different axis.  interpret the
00085         // plane the same way vis will, and flip the side orders if needed
00086             // FIXME: is this still relevent?
00087             WindingPlane (w, normal, &dist);
00088             if ( DotProduct (p->plane.normal, normal) < 0.99 )
00089             {   // backwards...
00090                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
00091             }
00092             else
00093                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
00094             for (i=0 ; i<w->numpoints ; i++)
00095             {
00096                 fprintf (pf,"(");
00097                 WriteFloat2 (pf, w->p[i][0]);
00098                 WriteFloat2 (pf, w->p[i][1]);
00099                 WriteFloat2 (pf, w->p[i][2]);
00100                 fprintf (pf,") ");
00101             }
00102             fprintf (pf,"\n");
00103         }
00104     }
00105 
00106 }
00107 
00108 /*
00109 ================
00110 FillLeafNumbers_r
00111 
00112 All of the leafs under node will have the same cluster
00113 ================
00114 */
00115 void FillLeafNumbers_r (node_t *node, int num)
00116 {
00117     if (node->planenum == PLANENUM_LEAF)
00118     {
00119         if (node->contents & CONTENTS_SOLID)
00120             node->cluster = -1;
00121         else
00122             node->cluster = num;
00123         return;
00124     }
00125     node->cluster = num;
00126     FillLeafNumbers_r (node->children[0], num);
00127     FillLeafNumbers_r (node->children[1], num);
00128 }
00129 
00130 /*
00131 ================
00132 NumberLeafs_r
00133 ================
00134 */
00135 void NumberLeafs_r (node_t *node)
00136 {
00137     portal_t    *p;
00138 
00139     if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
00140     {   // decision node
00141         node->cluster = -99;
00142         NumberLeafs_r (node->children[0]);
00143         NumberLeafs_r (node->children[1]);
00144         return;
00145     }
00146     
00147     // either a leaf or a detail cluster
00148 
00149     if ( node->contents & CONTENTS_SOLID )
00150     {   // solid block, viewpoint never inside
00151         node->cluster = -1;
00152         return;
00153     }
00154 
00155     FillLeafNumbers_r (node, num_visclusters);
00156     num_visclusters++;
00157 
00158     // count the portals
00159     for (p = node->portals ; p ; )
00160     {
00161         if (p->nodes[0] == node)        // only write out from first leaf
00162         {
00163             if (Portal_VisFlood (p))
00164                 num_visportals++;
00165             p = p->next[0];
00166         }
00167         else
00168             p = p->next[1];     
00169     }
00170 
00171 }
00172 
00173 
00174 /*
00175 ================
00176 CreateVisPortals_r
00177 ================
00178 */
00179 void CreateVisPortals_r (node_t *node)
00180 {
00181     // stop as soon as we get to a detail_seperator, which
00182     // means that everything below is in a single cluster
00183     if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
00184         return;
00185 
00186     MakeNodePortal (node);
00187     SplitNodePortals (node);
00188 
00189     CreateVisPortals_r (node->children[0]);
00190     CreateVisPortals_r (node->children[1]);
00191 }
00192 
00193 /*
00194 ================
00195 FinishVisPortals_r
00196 ================
00197 */
00198 void FinishVisPortals2_r (node_t *node)
00199 {
00200     if (node->planenum == PLANENUM_LEAF)
00201         return;
00202 
00203     MakeNodePortal (node);
00204     SplitNodePortals (node);
00205 
00206     FinishVisPortals2_r (node->children[0]);
00207     FinishVisPortals2_r (node->children[1]);
00208 }
00209 
00210 void FinishVisPortals_r (node_t *node)
00211 {
00212     if (node->planenum == PLANENUM_LEAF)
00213         return;
00214 
00215     if (node->detail_seperator)
00216     {
00217         FinishVisPortals2_r (node);
00218         return;
00219     }
00220 
00221     FinishVisPortals_r (node->children[0]);
00222     FinishVisPortals_r (node->children[1]);
00223 }
00224 
00225 
00226 int     clusterleaf;
00227 void SaveClusters_r (node_t *node)
00228 {
00229     if (node->planenum == PLANENUM_LEAF)
00230     {
00231         dleafs[clusterleaf++].cluster = node->cluster;
00232         return;
00233     }
00234     SaveClusters_r (node->children[0]);
00235     SaveClusters_r (node->children[1]);
00236 }
00237 
00238 /*
00239 ================
00240 WritePortalFile
00241 ================
00242 */
00243 void WritePortalFile (tree_t *tree)
00244 {
00245     char    filename[1024];
00246     node_t *headnode;
00247 
00248     qprintf ("--- WritePortalFile ---\n");
00249 
00250     headnode = tree->headnode;
00251     num_visclusters = 0;
00252     num_visportals = 0;
00253 
00254     Tree_FreePortals_r (headnode);
00255 
00256     MakeHeadnodePortals (tree);
00257 
00258     CreateVisPortals_r (headnode);
00259 
00260 // set the cluster field in every leaf and count the total number of portals
00261 
00262     NumberLeafs_r (headnode);
00263     
00264 // write the file
00265     sprintf (filename, "%s.prt", source);
00266     printf ("writing %s\n", filename);
00267     pf = fopen (filename, "w");
00268     if (!pf)
00269         Error ("Error opening %s", filename);
00270         
00271     fprintf (pf, "%s\n", PORTALFILE);
00272     fprintf (pf, "%i\n", num_visclusters);
00273     fprintf (pf, "%i\n", num_visportals);
00274 
00275     qprintf ("%5i visclusters\n", num_visclusters);
00276     qprintf ("%5i visportals\n", num_visportals);
00277 
00278     WritePortalFile_r (headnode);
00279 
00280     fclose (pf);
00281 
00282     // we need to store the clusters out now because ordering
00283     // issues made us do this after writebsp...
00284     clusterleaf = 1;
00285     SaveClusters_r (headnode);
00286 }
00287 

Generated on Thu Aug 25 12:37:19 2005 for Quake III Arena by  doxygen 1.3.9.1