prtfile.c (5821B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena 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. 11 12 Quake III Arena 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. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 23 #include "qbsp.h" 24 25 /* 26 ============================================================================== 27 28 PORTAL FILE GENERATION 29 30 Save out name.prt for qvis to read 31 ============================================================================== 32 */ 33 34 35 #define PORTALFILE "PRT1" 36 37 FILE *pf; 38 int num_visclusters; // clusters the player can be in 39 int num_visportals; 40 int num_solidfaces; 41 42 void WriteFloat (FILE *f, vec_t v) 43 { 44 if ( fabs(v - Q_rint(v)) < 0.001 ) 45 fprintf (f,"%i ",(int)Q_rint(v)); 46 else 47 fprintf (f,"%f ",v); 48 } 49 50 /* 51 ================= 52 WritePortalFile_r 53 ================= 54 */ 55 void WritePortalFile_r (node_t *node) 56 { 57 int i, s; 58 portal_t *p; 59 winding_t *w; 60 vec3_t normal; 61 vec_t dist; 62 63 // decision node 64 if (node->planenum != PLANENUM_LEAF) { 65 WritePortalFile_r (node->children[0]); 66 WritePortalFile_r (node->children[1]); 67 return; 68 } 69 70 if (node->opaque) { 71 return; 72 } 73 74 for (p = node->portals ; p ; p=p->next[s]) 75 { 76 w = p->winding; 77 s = (p->nodes[1] == node); 78 if (w && p->nodes[0] == node) 79 { 80 if (!Portal_Passable(p)) 81 continue; 82 // write out to the file 83 84 // sometimes planes get turned around when they are very near 85 // the changeover point between different axis. interpret the 86 // plane the same way vis will, and flip the side orders if needed 87 // FIXME: is this still relevent? 88 WindingPlane (w, normal, &dist); 89 if ( DotProduct (p->plane.normal, normal) < 0.99 ) 90 { // backwards... 91 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster); 92 } 93 else 94 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster); 95 if (p->hint) 96 fprintf (pf, "1 "); 97 else 98 fprintf (pf, "0 "); 99 for (i=0 ; i<w->numpoints ; i++) 100 { 101 fprintf (pf,"("); 102 WriteFloat (pf, w->p[i][0]); 103 WriteFloat (pf, w->p[i][1]); 104 WriteFloat (pf, w->p[i][2]); 105 fprintf (pf,") "); 106 } 107 fprintf (pf,"\n"); 108 } 109 } 110 111 } 112 113 /* 114 ================= 115 WriteFaceFile_r 116 ================= 117 */ 118 void WriteFaceFile_r (node_t *node) 119 { 120 int i, s; 121 portal_t *p; 122 winding_t *w; 123 124 // decision node 125 if (node->planenum != PLANENUM_LEAF) { 126 WriteFaceFile_r (node->children[0]); 127 WriteFaceFile_r (node->children[1]); 128 return; 129 } 130 131 if (node->opaque) { 132 return; 133 } 134 135 for (p = node->portals ; p ; p=p->next[s]) 136 { 137 w = p->winding; 138 s = (p->nodes[1] == node); 139 if (w) 140 { 141 if (Portal_Passable(p)) 142 continue; 143 // write out to the file 144 145 if (p->nodes[0] == node) 146 { 147 fprintf (pf,"%i %i ",w->numpoints, p->nodes[0]->cluster); 148 for (i=0 ; i<w->numpoints ; i++) 149 { 150 fprintf (pf,"("); 151 WriteFloat (pf, w->p[i][0]); 152 WriteFloat (pf, w->p[i][1]); 153 WriteFloat (pf, w->p[i][2]); 154 fprintf (pf,") "); 155 } 156 fprintf (pf,"\n"); 157 } 158 else 159 { 160 fprintf (pf,"%i %i ",w->numpoints, p->nodes[1]->cluster); 161 for (i = w->numpoints-1; i >= 0; i--) 162 { 163 fprintf (pf,"("); 164 WriteFloat (pf, w->p[i][0]); 165 WriteFloat (pf, w->p[i][1]); 166 WriteFloat (pf, w->p[i][2]); 167 fprintf (pf,") "); 168 } 169 fprintf (pf,"\n"); 170 } 171 } 172 } 173 } 174 175 /* 176 ================ 177 NumberLeafs_r 178 ================ 179 */ 180 void NumberLeafs_r (node_t *node) 181 { 182 portal_t *p; 183 184 if ( node->planenum != PLANENUM_LEAF ) { 185 // decision node 186 node->cluster = -99; 187 NumberLeafs_r (node->children[0]); 188 NumberLeafs_r (node->children[1]); 189 return; 190 } 191 192 node->area = -1; 193 194 if ( node->opaque ) { 195 // solid block, viewpoint never inside 196 node->cluster = -1; 197 return; 198 } 199 200 node->cluster = num_visclusters; 201 num_visclusters++; 202 203 // count the portals 204 for (p = node->portals ; p ; ) 205 { 206 if (p->nodes[0] == node) // only write out from first leaf 207 { 208 if (Portal_Passable(p)) 209 num_visportals++; 210 else 211 num_solidfaces++; 212 p = p->next[0]; 213 } 214 else 215 { 216 if (!Portal_Passable(p)) 217 num_solidfaces++; 218 p = p->next[1]; 219 } 220 } 221 } 222 223 224 /* 225 ================ 226 NumberClusters 227 ================ 228 */ 229 void NumberClusters(tree_t *tree) { 230 num_visclusters = 0; 231 num_visportals = 0; 232 num_solidfaces = 0; 233 234 qprintf ("--- NumberClusters ---\n"); 235 236 // set the cluster field in every leaf and count the total number of portals 237 NumberLeafs_r (tree->headnode); 238 239 qprintf ("%5i visclusters\n", num_visclusters); 240 qprintf ("%5i visportals\n", num_visportals); 241 qprintf ("%5i solidfaces\n", num_solidfaces); 242 } 243 244 /* 245 ================ 246 WritePortalFile 247 ================ 248 */ 249 void WritePortalFile (tree_t *tree) 250 { 251 char filename[1024]; 252 253 qprintf ("--- WritePortalFile ---\n"); 254 255 // write the file 256 sprintf (filename, "%s.prt", source); 257 _printf ("writing %s\n", filename); 258 pf = fopen (filename, "w"); 259 if (!pf) 260 Error ("Error opening %s", filename); 261 262 fprintf (pf, "%s\n", PORTALFILE); 263 fprintf (pf, "%i\n", num_visclusters); 264 fprintf (pf, "%i\n", num_visportals); 265 fprintf (pf, "%i\n", num_solidfaces); 266 267 WritePortalFile_r(tree->headnode); 268 WriteFaceFile_r(tree->headnode); 269 270 fclose (pf); 271 } 272