2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 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 GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 ==============================================================================
27 PORTAL FILE GENERATION
29 Save out name.prt for qvis to read
30 ==============================================================================
34 #define PORTALFILE "PRT1"
37 int num_visclusters; // clusters the player can be in
40 void WriteFloat( FILE *f, vec_t v ){
41 if ( fabs( v - Q_rint( v ) ) < 0.001 ) {
42 fprintf( f,"%i ",(int)Q_rint( v ) );
54 void WritePortalFile_r( node_t *node ){
62 if ( node->planenum != PLANENUM_LEAF && !node->detail_seperator ) {
63 WritePortalFile_r( node->children[0] );
64 WritePortalFile_r( node->children[1] );
68 if ( node->contents & CONTENTS_SOLID ) {
72 for ( p = node->portals ; p ; p = p->next[s] )
75 s = ( p->nodes[1] == node );
76 if ( w && p->nodes[0] == node ) {
77 if ( !Portal_VisFlood( p ) ) {
80 // write out to the file
82 // sometimes planes get turned around when they are very near
83 // the changeover point between different axis. interpret the
84 // plane the same way vis will, and flip the side orders if needed
85 // FIXME: is this still relevent?
86 WindingPlane( w, normal, &dist );
87 if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards...
88 fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster );
91 fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster );
93 for ( i = 0 ; i < w->numpoints ; i++ )
96 WriteFloat( pf, w->p[i][0] );
97 WriteFloat( pf, w->p[i][1] );
98 WriteFloat( pf, w->p[i][2] );
111 All of the leafs under node will have the same cluster
114 void FillLeafNumbers_r( node_t *node, int num ){
115 if ( node->planenum == PLANENUM_LEAF ) {
116 if ( node->contents & CONTENTS_SOLID ) {
125 FillLeafNumbers_r( node->children[0], num );
126 FillLeafNumbers_r( node->children[1], num );
134 void NumberLeafs_r( node_t *node ){
137 if ( node->planenum != PLANENUM_LEAF && !node->detail_seperator ) { // decision node
139 NumberLeafs_r( node->children[0] );
140 NumberLeafs_r( node->children[1] );
144 // either a leaf or a detail cluster
146 if ( node->contents & CONTENTS_SOLID ) { // solid block, viewpoint never inside
151 FillLeafNumbers_r( node, num_visclusters );
155 for ( p = node->portals ; p ; )
157 if ( p->nodes[0] == node ) { // only write out from first leaf
158 if ( Portal_VisFlood( p ) ) {
176 void CreateVisPortals_r( node_t *node ){
177 // stop as soon as we get to a detail_seperator, which
178 // means that everything below is in a single cluster
179 if ( node->planenum == PLANENUM_LEAF || node->detail_seperator ) {
183 MakeNodePortal( node );
184 SplitNodePortals( node );
186 CreateVisPortals_r( node->children[0] );
187 CreateVisPortals_r( node->children[1] );
195 void FinishVisPortals2_r( node_t *node ){
196 if ( node->planenum == PLANENUM_LEAF ) {
200 MakeNodePortal( node );
201 SplitNodePortals( node );
203 FinishVisPortals2_r( node->children[0] );
204 FinishVisPortals2_r( node->children[1] );
207 void FinishVisPortals_r( node_t *node ){
208 if ( node->planenum == PLANENUM_LEAF ) {
212 if ( node->detail_seperator ) {
213 FinishVisPortals2_r( node );
217 FinishVisPortals_r( node->children[0] );
218 FinishVisPortals_r( node->children[1] );
223 void SaveClusters_r( node_t *node ){
224 if ( node->planenum == PLANENUM_LEAF ) {
225 dleafs[clusterleaf++].cluster = node->cluster;
228 SaveClusters_r( node->children[0] );
229 SaveClusters_r( node->children[1] );
237 void WritePortalFile( tree_t *tree ){
241 Sys_FPrintf( SYS_VRB, "--- WritePortalFile ---\n" );
243 headnode = tree->headnode;
247 FreeTreePortals_r( headnode );
249 MakeHeadnodePortals( tree );
251 CreateVisPortals_r( headnode );
253 // set the cluster field in every leaf and count the total number of portals
255 NumberLeafs_r( headnode );
258 sprintf( filename, "%s.prt", source );
259 Sys_Printf( "writing %s\n", filename );
260 pf = fopen( filename, "w" );
262 Error( "Error opening %s", filename );
265 fprintf( pf, "%s\n", PORTALFILE );
266 fprintf( pf, "%i\n", num_visclusters );
267 fprintf( pf, "%i\n", num_visportals );
269 Sys_FPrintf( SYS_VRB, "%5i visclusters\n", num_visclusters );
270 Sys_FPrintf( SYS_VRB, "%5i visportals\n", num_visportals );
272 WritePortalFile_r( headnode );
276 // we need to store the clusters out now because ordering
277 // issues made us do this after writebsp...
279 SaveClusters_r( headnode );