1 /* -------------------------------------------------------------------------------
3 Copyright (C) 1999-2007 id Software, Inc. and contributors.
4 For a list of contributors, see the accompanying CONTRIBUTORS file.
6 This file is part of GtkRadiant.
8 GtkRadiant is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 GtkRadiant is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GtkRadiant; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 ----------------------------------------------------------------------------------
24 This code has been altered significantly from its original form, to support
25 several games based on the Quake III Arena engine, in the form of "Q3Map2."
27 ------------------------------------------------------------------------------- */
42 ==============================================================================
44 PORTAL FILE GENERATION
46 Save out name.prt for qvis to read
47 ==============================================================================
51 #define PORTALFILE "PRT1"
54 int num_visclusters; // clusters the player can be in
58 void WriteFloat( FILE *f, vec_t v ){
59 if ( fabs( v - Q_rint( v ) ) < 0.001 ) {
60 fprintf( f,"%i ",(int)Q_rint( v ) );
72 void WritePortalFile_r( node_t *node ){
80 if ( node->planenum != PLANENUM_LEAF ) {
81 WritePortalFile_r( node->children[0] );
82 WritePortalFile_r( node->children[1] );
90 for ( p = node->portals ; p ; p = p->next[s] )
93 s = ( p->nodes[1] == node );
94 if ( w && p->nodes[0] == node ) {
95 if ( !PortalPassable( p ) ) {
98 // write out to the file
100 // sometimes planes get turned around when they are very near
101 // the changeover point between different axis. interpret the
102 // plane the same way vis will, and flip the side orders if needed
103 // FIXME: is this still relevent?
104 WindingPlane( w, normal, &dist );
105 if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards...
106 fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster );
109 fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster );
112 /* ydnar: added this change to make antiportals work */
113 if ( p->compileFlags & C_HINT ) {
120 /* write the winding */
121 for ( i = 0 ; i < w->numpoints ; i++ )
124 WriteFloat( pf, w->p[i][0] );
125 WriteFloat( pf, w->p[i][1] );
126 WriteFloat( pf, w->p[i][2] );
140 void WriteFaceFile_r( node_t *node ){
146 if ( node->planenum != PLANENUM_LEAF ) {
147 WriteFaceFile_r( node->children[0] );
148 WriteFaceFile_r( node->children[1] );
152 if ( node->opaque ) {
156 for ( p = node->portals ; p ; p = p->next[s] )
159 s = ( p->nodes[1] == node );
161 if ( PortalPassable( p ) ) {
164 // write out to the file
166 if ( p->nodes[0] == node ) {
167 fprintf( pf,"%i %i ",w->numpoints, p->nodes[0]->cluster );
168 for ( i = 0 ; i < w->numpoints ; i++ )
171 WriteFloat( pf, w->p[i][0] );
172 WriteFloat( pf, w->p[i][1] );
173 WriteFloat( pf, w->p[i][2] );
180 fprintf( pf,"%i %i ",w->numpoints, p->nodes[1]->cluster );
181 for ( i = w->numpoints - 1; i >= 0; i-- )
184 WriteFloat( pf, w->p[i][0] );
185 WriteFloat( pf, w->p[i][1] );
186 WriteFloat( pf, w->p[i][2] );
200 void NumberLeafs_r( node_t *node ){
203 if ( node->planenum != PLANENUM_LEAF ) {
206 NumberLeafs_r( node->children[0] );
207 NumberLeafs_r( node->children[1] );
213 if ( node->opaque ) {
214 // solid block, viewpoint never inside
219 node->cluster = num_visclusters;
223 for ( p = node->portals ; p ; )
225 if ( p->nodes[0] == node ) { // only write out from first leaf
226 if ( PortalPassable( p ) ) {
236 if ( !PortalPassable( p ) ) {
250 void NumberClusters( tree_t *tree ) {
255 Sys_FPrintf( SYS_VRB,"--- NumberClusters ---\n" );
257 // set the cluster field in every leaf and count the total number of portals
258 NumberLeafs_r( tree->headnode );
260 Sys_FPrintf( SYS_VRB, "%9d visclusters\n", num_visclusters );
261 Sys_FPrintf( SYS_VRB, "%9d visportals\n", num_visportals );
262 Sys_FPrintf( SYS_VRB, "%9d solidfaces\n", num_solidfaces );
270 void WritePortalFile( tree_t *tree ){
273 Sys_FPrintf( SYS_VRB,"--- WritePortalFile ---\n" );
276 sprintf( filename, "%s.prt", source );
277 Sys_Printf( "writing %s\n", filename );
278 pf = fopen( filename, "w" );
280 Error( "Error opening %s", filename );
283 fprintf( pf, "%s\n", PORTALFILE );
284 fprintf( pf, "%i\n", num_visclusters );
285 fprintf( pf, "%i\n", num_visportals );
286 fprintf( pf, "%i\n", num_solidfaces );
288 WritePortalFile_r( tree->headnode );
289 WriteFaceFile_r( tree->headnode );