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 int     num_solidfaces;
00041 
00042 void WriteFloat (FILE *f, vec_t v)
00043 {
00044     if ( fabs(v - Q_rint(v)) < 0.001 )
00045         fprintf (f,"%i ",(int)Q_rint(v));
00046     else
00047         fprintf (f,"%f ",v);
00048 }
00049 
00050 /*
00051 =================
00052 WritePortalFile_r
00053 =================
00054 */
00055 void WritePortalFile_r (node_t *node)
00056 {
00057     int         i, s;   
00058     portal_t    *p;
00059     winding_t   *w;
00060     vec3_t      normal;
00061     vec_t       dist;
00062 
00063     // decision node
00064     if (node->planenum != PLANENUM_LEAF) {
00065         WritePortalFile_r (node->children[0]);
00066         WritePortalFile_r (node->children[1]);
00067         return;
00068     }
00069     
00070     if (node->opaque) {
00071         return;
00072     }
00073 
00074     for (p = node->portals ; p ; p=p->next[s])
00075     {
00076         w = p->winding;
00077         s = (p->nodes[1] == node);
00078         if (w && p->nodes[0] == node)
00079         {
00080             if (!Portal_Passable(p))
00081                 continue;
00082             // write out to the file
00083             
00084             // sometimes planes get turned around when they are very near
00085             // the changeover point between different axis.  interpret the
00086             // plane the same way vis will, and flip the side orders if needed
00087             // FIXME: is this still relevent?
00088             WindingPlane (w, normal, &dist);
00089             if ( DotProduct (p->plane.normal, normal) < 0.99 )
00090             {   // backwards...
00091                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
00092             }
00093             else
00094                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
00095             if (p->hint)
00096                 fprintf (pf, "1 ");
00097             else
00098                 fprintf (pf, "0 ");
00099             for (i=0 ; i<w->numpoints ; i++)
00100             {
00101                 fprintf (pf,"(");
00102                 WriteFloat (pf, w->p[i][0]);
00103                 WriteFloat (pf, w->p[i][1]);
00104                 WriteFloat (pf, w->p[i][2]);
00105                 fprintf (pf,") ");
00106             }
00107             fprintf (pf,"\n");
00108         }
00109     }
00110 
00111 }
00112 
00113 /*
00114 =================
00115 WriteFaceFile_r
00116 =================
00117 */
00118 void WriteFaceFile_r (node_t *node)
00119 {
00120     int         i, s;   
00121     portal_t    *p;
00122     winding_t   *w;
00123 
00124     // decision node
00125     if (node->planenum != PLANENUM_LEAF) {
00126         WriteFaceFile_r (node->children[0]);
00127         WriteFaceFile_r (node->children[1]);
00128         return;
00129     }
00130     
00131     if (node->opaque) {
00132         return;
00133     }
00134 
00135     for (p = node->portals ; p ; p=p->next[s])
00136     {
00137         w = p->winding;
00138         s = (p->nodes[1] == node);
00139         if (w)
00140         {
00141             if (Portal_Passable(p))
00142                 continue;
00143             // write out to the file
00144 
00145             if (p->nodes[0] == node)
00146             {
00147                 fprintf (pf,"%i %i ",w->numpoints, p->nodes[0]->cluster);
00148                 for (i=0 ; i<w->numpoints ; i++)
00149                 {
00150                     fprintf (pf,"(");
00151                     WriteFloat (pf, w->p[i][0]);
00152                     WriteFloat (pf, w->p[i][1]);
00153                     WriteFloat (pf, w->p[i][2]);
00154                     fprintf (pf,") ");
00155                 }
00156                 fprintf (pf,"\n");
00157             }
00158             else
00159             {
00160                 fprintf (pf,"%i %i ",w->numpoints, p->nodes[1]->cluster);
00161                 for (i = w->numpoints-1; i >= 0; i--)
00162                 {
00163                     fprintf (pf,"(");
00164                     WriteFloat (pf, w->p[i][0]);
00165                     WriteFloat (pf, w->p[i][1]);
00166                     WriteFloat (pf, w->p[i][2]);
00167                     fprintf (pf,") ");
00168                 }
00169                 fprintf (pf,"\n");
00170             }
00171         }
00172     }
00173 }
00174 
00175 /*
00176 ================
00177 NumberLeafs_r
00178 ================
00179 */
00180 void NumberLeafs_r (node_t *node)
00181 {
00182     portal_t    *p;
00183 
00184     if ( node->planenum != PLANENUM_LEAF ) {
00185         // decision node
00186         node->cluster = -99;
00187         NumberLeafs_r (node->children[0]);
00188         NumberLeafs_r (node->children[1]);
00189         return;
00190     }
00191     
00192     node->area = -1;
00193 
00194     if ( node->opaque ) {
00195         // solid block, viewpoint never inside
00196         node->cluster = -1;
00197         return;
00198     }
00199 
00200     node->cluster = num_visclusters;
00201     num_visclusters++;
00202 
00203     // count the portals
00204     for (p = node->portals ; p ; )
00205     {
00206         if (p->nodes[0] == node)        // only write out from first leaf
00207         {
00208             if (Portal_Passable(p))
00209                 num_visportals++;
00210             else
00211                 num_solidfaces++;
00212             p = p->next[0];
00213         }
00214         else
00215         {
00216             if (!Portal_Passable(p))
00217                 num_solidfaces++;
00218             p = p->next[1];     
00219         }
00220     }
00221 }
00222 
00223 
00224 /*
00225 ================
00226 NumberClusters
00227 ================
00228 */
00229 void NumberClusters(tree_t *tree) {
00230     num_visclusters = 0;
00231     num_visportals = 0;
00232     num_solidfaces = 0;
00233 
00234     qprintf ("--- NumberClusters ---\n");
00235     
00236     // set the cluster field in every leaf and count the total number of portals
00237     NumberLeafs_r (tree->headnode);
00238 
00239     qprintf ("%5i visclusters\n", num_visclusters);
00240     qprintf ("%5i visportals\n", num_visportals);
00241     qprintf ("%5i solidfaces\n", num_solidfaces);
00242 }
00243 
00244 /*
00245 ================
00246 WritePortalFile
00247 ================
00248 */
00249 void WritePortalFile (tree_t *tree)
00250 {
00251     char    filename[1024];
00252 
00253     qprintf ("--- WritePortalFile ---\n");
00254     
00255     // write the file
00256     sprintf (filename, "%s.prt", source);
00257     _printf ("writing %s\n", filename);
00258     pf = fopen (filename, "w");
00259     if (!pf)
00260         Error ("Error opening %s", filename);
00261         
00262     fprintf (pf, "%s\n", PORTALFILE);
00263     fprintf (pf, "%i\n", num_visclusters);
00264     fprintf (pf, "%i\n", num_visportals);
00265     fprintf (pf, "%i\n", num_solidfaces);
00266 
00267     WritePortalFile_r(tree->headnode);
00268     WriteFaceFile_r(tree->headnode);
00269 
00270     fclose (pf);
00271 }
00272 

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