From 23807ef4b33f603236580d82877c045d150bc0f1 Mon Sep 17 00:00:00 2001 From: divverent Date: Tue, 31 Mar 2009 06:28:17 +0000 Subject: [PATCH 01/32] some stuff by 27: - better BSP tree splitting (experimental, option -altsplit) - also compare shaders when sorting surfaces (should give slightly more fps) - misc_model spawnflag 32: set vertex alpha from vertex color (for terrain blending) git-svn-id: svn://svn.icculus.org/netradiant/trunk@240 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/bsp.c | 5 ++++ tools/quake3/q3map2/facebsp.c | 38 ++++++++++++++++++++++----- tools/quake3/q3map2/lightmaps_ydnar.c | 8 ++++++ tools/quake3/q3map2/model.c | 18 ++++++++++--- tools/quake3/q3map2/q3map2.h | 2 ++ 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index eb615e61..377ba687 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -842,6 +842,11 @@ int BSPMain( int argc, char **argv ){ Sys_Printf( "Debug portal surfaces enabled\n" ); debugPortals = qtrue; } + else if( !strcmp( argv[ i ], "-altsplit" ) ) + { + Sys_Printf( "Alternate BSP splitting (by 27) enabled\n" ); + bspAlternateSplitWeights = qtrue; + } else if ( !strcmp( argv[ i ], "-bsp" ) ) { Sys_Printf( "-bsp argument unnecessary\n" ); } diff --git a/tools/quake3/q3map2/facebsp.c b/tools/quake3/q3map2/facebsp.c index 66a009c2..0140a447 100644 --- a/tools/quake3/q3map2/facebsp.c +++ b/tools/quake3/q3map2/facebsp.c @@ -88,8 +88,8 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, vec3_t normal; float dist; int planenum; - - + float sizeBias; + /* ydnar: set some defaults */ *splitPlaneNum = -1; /* leaf */ *compileFlags = 0; @@ -148,11 +148,30 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, back++; } } - value = 5 * facing - 5 * splits; // - abs(front-back); - if ( plane->type < 3 ) { - value += 5; // axial is better + + if(bspAlternateSplitWeights) + { + // from 27 + + //Bigger is better + sizeBias=WindingArea(split->w); + + //Base score = 20000 perfectly balanced + value = 20000-(abs(front-back)); + value -= plane->counter;// If we've already used this plane sometime in the past try not to use it again + value -= facing ; // if we're going to have alot of other surfs use this plane, we want to get it in quickly. + value -= splits*5; //more splits = bad + value += sizeBias*10; //We want a huge score bias based on plane size } - value += split->priority; // prioritize hints higher + else + { + value = 5*facing - 5*splits; // - abs(front-back); + if ( plane->type < 3 ) { + value+=5; // axial is better + } + } + + value += split->priority; // prioritize hints higher if ( value > bestValue ) { bestValue = value; @@ -168,6 +187,8 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, /* set best split data */ *splitPlaneNum = bestSplit->planenum; *compileFlags = bestSplit->compileFlags; + + if (*splitPlaneNum>-1) mapplanes[ *splitPlaneNum ].counter++; } @@ -324,6 +345,11 @@ tree_t *FaceBSP( face_t *list ) { } Sys_FPrintf( SYS_VRB, "%9d faces\n", count ); + for( i = 0; i < nummapplanes; i++) + { + mapplanes[ i ].counter=0; + } + tree->headnode = AllocNode(); VectorCopy( tree->mins, tree->headnode->mins ); VectorCopy( tree->maxs, tree->headnode->maxs ); diff --git a/tools/quake3/q3map2/lightmaps_ydnar.c b/tools/quake3/q3map2/lightmaps_ydnar.c index e8114380..b3ac49ba 100644 --- a/tools/quake3/q3map2/lightmaps_ydnar.c +++ b/tools/quake3/q3map2/lightmaps_ydnar.c @@ -865,6 +865,14 @@ static int CompareSurfaceInfo( const void *a, const void *b ){ return -1; } + /* 27: then shader! */ + if ( aInfo->si < bInfo->si ) { + return 1; + } + else if ( aInfo->si > bInfo->si ) { + return -1; + } + /* then lightmap sample size */ if ( aInfo->sampleSize < bInfo->sampleSize ) { return 1; diff --git a/tools/quake3/q3map2/model.c b/tools/quake3/q3map2/model.c index 55948c5c..0e8e906b 100644 --- a/tools/quake3/q3map2/model.c +++ b/tools/quake3/q3map2/model.c @@ -389,10 +389,20 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade { dv->lightmap[ j ][ 0 ] = 0.0f; dv->lightmap[ j ][ 1 ] = 0.0f; - dv->color[ j ][ 0 ] = color[ 0 ]; - dv->color[ j ][ 1 ] = color[ 1 ]; - dv->color[ j ][ 2 ] = color[ 2 ]; - dv->color[ j ][ 3 ] = color[ 3 ]; + if(spawnFlags & 32) // spawnflag 32: model color -> alpha hack + { + dv->color[ j ][ 0 ] = 255.0f; + dv->color[ j ][ 1 ] = 255.0f; + dv->color[ j ][ 2 ] = 255.0f; + dv->color[ j ][ 3 ] = color[ 0 ] * 0.3f + color[ 1 ] * 0.59f + color[ 2 ] * 0.11f; + } + else + { + dv->color[ j ][ 0 ] = color[ 0 ]; + dv->color[ j ][ 1 ] = color[ 1 ]; + dv->color[ j ][ 2 ] = color[ 2 ]; + dv->color[ j ][ 3 ] = color[ 3 ]; + } } } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index f0adf73b..d8537a3c 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -801,6 +801,7 @@ typedef struct plane_s vec3_t normal; vec_t dist; int type; + int counter; struct plane_s *hash_chain; } plane_t; @@ -1946,6 +1947,7 @@ Q_EXTERN qboolean nofog Q_ASSIGN( qfalse ); Q_EXTERN qboolean noHint Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean renameModelShaders Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean skyFixHack Q_ASSIGN( qfalse ); /* ydnar */ +Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */ Q_EXTERN int patchSubdivisions Q_ASSIGN( 8 ); /* ydnar: -patchmeta subdivisions */ From 9a44eb324f9c143ec3ffb2ba45e3911b020eb795 Mon Sep 17 00:00:00 2001 From: divverent Date: Fri, 3 Apr 2009 13:51:31 +0000 Subject: [PATCH 02/32] add an option -mergeportals to speed up vis, while not making the vis data MUCH worse git-svn-id: svn://svn.icculus.org/netradiant/trunk@243 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/vis.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/vis.c b/tools/quake3/q3map2/vis.c index 5b38d12e..b301507d 100644 --- a/tools/quake3/q3map2/vis.c +++ b/tools/quake3/q3map2/vis.c @@ -1086,6 +1086,9 @@ int VisMain( int argc, char **argv ){ else if ( !strcmp( argv[i], "-merge" ) ) { Sys_Printf( "merge = true\n" ); mergevis = qtrue; + } else if (!strcmp(argv[i], "-mergeportals")) { + Sys_Printf ("mergeportals = true\n"); + mergevisportals = qtrue; } else if ( !strcmp( argv[i], "-nopassage" ) ) { Sys_Printf( "nopassage = true\n" ); @@ -1150,9 +1153,12 @@ int VisMain( int argc, char **argv ){ /* ydnar: for getting far plane */ ParseEntities(); - - if ( mergevis ) { + + if( mergevis ) { MergeLeaves(); + } + + if( mergevis || mergevisportals ) { MergeLeafPortals(); } From cfeea25febdc2bc06f8257ab47b4a93a35bb4882 Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 4 Apr 2009 11:56:32 +0000 Subject: [PATCH 03/32] new options: -bsp -deep - include detail brushes into BSP tree generation (but at lowest possible priority), but still ignore them for vis -vis -mergeportals - only merge vis portals on the same plane, but don't merge clusters (much faster vis, but only slightly worse - will evaluate later why it's worse vis at all) git-svn-id: svn://svn.icculus.org/netradiant/trunk@244 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/bsp.c | 8 ++- tools/quake3/q3map2/facebsp.c | 58 ++++++++++++---- tools/quake3/q3map2/prtfile.c | 122 +++++++++++++++++++++++++++++----- tools/quake3/q3map2/q3map2.h | 9 ++- 4 files changed, 167 insertions(+), 30 deletions(-) diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index 377ba687..6199d07f 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -847,7 +847,13 @@ int BSPMain( int argc, char **argv ){ Sys_Printf( "Alternate BSP splitting (by 27) enabled\n" ); bspAlternateSplitWeights = qtrue; } - else if ( !strcmp( argv[ i ], "-bsp" ) ) { + else if( !strcmp( argv[ i ], "-deep" ) ) + { + Sys_Printf( "Deep BSP tree generation enabled\n" ); + deepBSP = qtrue; + } + else if( !strcmp( argv[ i ], "-bsp" ) ) + { Sys_Printf( "-bsp argument unnecessary\n" ); } else{ diff --git a/tools/quake3/q3map2/facebsp.c b/tools/quake3/q3map2/facebsp.c index 0140a447..c1d7d939 100644 --- a/tools/quake3/q3map2/facebsp.c +++ b/tools/quake3/q3map2/facebsp.c @@ -117,14 +117,14 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, bestValue = -99999; bestSplit = list; - for ( split = list; split; split = split->next ) - split->checked = qfalse; + // div0: this check causes detail/structural mixes + //for( split = list; split; split = split->next ) + // split->checked = qfalse; for ( split = list; split; split = split->next ) { - if ( split->checked ) { - continue; - } + //if ( split->checked ) + // continue; plane = &mapplanes[ split->planenum ]; splits = 0; @@ -134,7 +134,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, for ( check = list ; check ; check = check->next ) { if ( check->planenum == split->planenum ) { facing++; - check->checked = qtrue; // won't need to test this plane again + //check->checked = qtrue; // won't need to test this plane again continue; } side = WindingOnPlaneSide( check->w, plane->normal, plane->dist ); @@ -188,7 +188,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, *splitPlaneNum = bestSplit->planenum; *compileFlags = bestSplit->compileFlags; - if (*splitPlaneNum>-1) mapplanes[ *splitPlaneNum ].counter++; + if (*splitPlaneNum>-1) mapplanes[ *splitPlaneNum ].counter++; } @@ -236,6 +236,7 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ /* if we don't have any more faces, this is a node */ if ( splitPlaneNum == -1 ) { node->planenum = PLANENUM_LEAF; + node->has_structural_children = qfalse; c_faceLeafs++; return; } @@ -243,9 +244,12 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ /* partition the list */ node->planenum = splitPlaneNum; node->compileFlags = compileFlags; + node->has_structural_children = !(compileFlags & C_DETAIL) && !node->opaque; plane = &mapplanes[ splitPlaneNum ]; childLists[0] = NULL; childLists[1] = NULL; + + qboolean isstruct = 0; for ( split = list; split; split = next ) { /* set next */ @@ -257,6 +261,9 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ continue; } + if(!(split->compileFlags & C_DETAIL)) + isstruct = 1; + /* determine which side the face falls on */ side = WindingOnPlaneSide( split->w, plane->normal, plane->dist ); @@ -311,9 +318,22 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ } } +#if 0 + if((node->compileFlags & C_DETAIL) && isstruct) + Sys_FPrintf(SYS_ERR, "I am detail, my child is structural, this is a wtf1\n", node->has_structural_children); +#endif + for ( i = 0 ; i < 2 ; i++ ) { BuildFaceTree_r( node->children[i], childLists[i] ); + node->has_structural_children |= node->children[i]->has_structural_children; } + +#if 0 + if((node->compileFlags & C_DETAIL) && !(node->children[0]->compileFlags & C_DETAIL) && node->children[0]->planenum != PLANENUM_LEAF) + Sys_FPrintf(SYS_ERR, "I am detail, my child is structural\n", node->has_structural_children); + if((node->compileFlags & C_DETAIL) && isstruct) + Sys_FPrintf(SYS_ERR, "I am detail, my child is structural, this is a wtf2\n", node->has_structural_children); +#endif } @@ -345,10 +365,10 @@ tree_t *FaceBSP( face_t *list ) { } Sys_FPrintf( SYS_VRB, "%9d faces\n", count ); - for( i = 0; i < nummapplanes; i++) - { - mapplanes[ i ].counter=0; - } + for ( i = 0; i < nummapplanes; i++ ) + { + mapplanes[ i ].counter = 0; + } tree->headnode = AllocNode(); VectorCopy( tree->mins, tree->headnode->mins ); @@ -380,7 +400,7 @@ face_t *MakeStructuralBSPFaceList( brush_t *list ){ flist = NULL; for ( b = list; b != NULL; b = b->next ) { - if ( b->detail ) { + if ( !deepBSP && b->detail ) { continue; } @@ -403,6 +423,9 @@ face_t *MakeStructuralBSPFaceList( brush_t *list ){ f->w = CopyWinding( w ); f->planenum = s->planenum & ~1; f->compileFlags = s->compileFlags; /* ydnar */ + if ( b->detail ) { + f->compileFlags |= C_DETAIL; + } /* ydnar: set priority */ f->priority = 0; @@ -415,6 +438,9 @@ face_t *MakeStructuralBSPFaceList( brush_t *list ){ if ( f->compileFlags & C_AREAPORTAL ) { f->priority += AREAPORTAL_PRIORITY; } + if ( f->compileFlags & C_DETAIL ) { + f->priority += DETAIL_PRIORITY; + } /* get next face */ f->next = flist; @@ -443,7 +469,7 @@ face_t *MakeVisibleBSPFaceList( brush_t *list ){ flist = NULL; for ( b = list; b != NULL; b = b->next ) { - if ( b->detail ) { + if ( !deepBSP && b->detail ) { continue; } @@ -466,6 +492,9 @@ face_t *MakeVisibleBSPFaceList( brush_t *list ){ f->w = CopyWinding( w ); f->planenum = s->planenum & ~1; f->compileFlags = s->compileFlags; /* ydnar */ + if ( b->detail ) { + f->compileFlags |= C_DETAIL; + } /* ydnar: set priority */ f->priority = 0; @@ -478,6 +507,9 @@ face_t *MakeVisibleBSPFaceList( brush_t *list ){ if ( f->compileFlags & C_AREAPORTAL ) { f->priority += AREAPORTAL_PRIORITY; } + if ( f->compileFlags & C_DETAIL ) { + f->priority += DETAIL_PRIORITY; + } /* get next face */ f->next = flist; diff --git a/tools/quake3/q3map2/prtfile.c b/tools/quake3/q3map2/prtfile.c index eeb3a800..55d47af6 100644 --- a/tools/quake3/q3map2/prtfile.c +++ b/tools/quake3/q3map2/prtfile.c @@ -64,6 +64,40 @@ void WriteFloat( FILE *f, vec_t v ){ } } +void CountVisportals_r(node_t *node) +{ + int i, s; + portal_t *p; + winding_t *w; + vec3_t normal; + vec_t dist; + + // decision node + if (node->planenum != PLANENUM_LEAF) { + CountVisportals_r (node->children[0]); + CountVisportals_r (node->children[1]); + return; + } + + if (node->opaque) { + return; + } + + for (p = node->portals ; p ; p=p->next[s]) + { + w = p->winding; + s = (p->nodes[1] == node); + if (w && p->nodes[0] == node) + { + if (!PortalPassable(p)) + continue; + if(p->nodes[0]->cluster == p->nodes[1]->cluster) + continue; + ++num_visportals; + } + } +} + /* ================= WritePortalFile_r @@ -95,16 +129,19 @@ void WritePortalFile_r( node_t *node ){ if ( !PortalPassable( p ) ) { continue; } + if(p->nodes[0]->cluster == p->nodes[1]->cluster) + continue; + --num_visportals; // write out to the file // sometimes planes get turned around when they are very near // the changeover point between different axis. interpret the // plane the same way vis will, and flip the side orders if needed // FIXME: is this still relevent? - WindingPlane( w, normal, &dist ); - - if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards... - fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster ); + WindingPlane (w, normal, &dist); + if ( DotProduct (p->plane.normal, normal) < 0.99 ) + { // backwards... + fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster); } else{ fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster ); @@ -133,6 +170,40 @@ void WritePortalFile_r( node_t *node ){ } +void CountSolidFaces_r (node_t *node) +{ + int i, s; + portal_t *p; + winding_t *w; + + // decision node + if (node->planenum != PLANENUM_LEAF) { + CountSolidFaces_r (node->children[0]); + CountSolidFaces_r (node->children[1]); + return; + } + + if (node->opaque) { + return; + } + + for (p = node->portals ; p ; p=p->next[s]) + { + w = p->winding; + s = (p->nodes[1] == node); + if (w) + { + if (PortalPassable(p)) + continue; + if(p->nodes[0]->cluster == p->nodes[1]->cluster) + continue; + // write out to the file + + ++num_solidfaces; + } + } +} + /* ================= WriteFaceFile_r @@ -162,6 +233,9 @@ void WriteFaceFile_r( node_t *node ){ if ( PortalPassable( p ) ) { continue; } + if(p->nodes[0]->cluster == p->nodes[1]->cluster) + continue; + --num_visportals; // write out to the file if ( p->nodes[0] == node ) { @@ -194,18 +268,30 @@ void WriteFaceFile_r( node_t *node ){ } /* - ================ - NumberLeafs_r - ================ - */ -void NumberLeafs_r( node_t *node ){ - portal_t *p; +================ +NumberLeafs_r +================ +*/ +void NumberLeafs_r (node_t *node, int c) +{ + portal_t *p; if ( node->planenum != PLANENUM_LEAF ) { // decision node node->cluster = -99; - NumberLeafs_r( node->children[0] ); - NumberLeafs_r( node->children[1] ); + + if(node->has_structural_children) + { + NumberLeafs_r (node->children[0], c); + NumberLeafs_r (node->children[1], c); + } + else + { + if(c < 0) + c = num_visclusters++; + NumberLeafs_r (node->children[0], c); + NumberLeafs_r (node->children[1], c); + } return; } @@ -217,9 +303,12 @@ void NumberLeafs_r( node_t *node ){ return; } - node->cluster = num_visclusters; - num_visclusters++; + if(c < 0) + c = num_visclusters++; + + node->cluster = c; +#if 0 // count the portals for ( p = node->portals ; p ; ) { @@ -240,6 +329,7 @@ void NumberLeafs_r( node_t *node ){ p = p->next[1]; } } +#endif } @@ -256,7 +346,9 @@ void NumberClusters( tree_t *tree ) { Sys_FPrintf( SYS_VRB,"--- NumberClusters ---\n" ); // set the cluster field in every leaf and count the total number of portals - NumberLeafs_r( tree->headnode ); + NumberLeafs_r (tree->headnode, -1); + CountVisportals_r (tree->headnode); + CountSolidFaces_r (tree->headnode); Sys_FPrintf( SYS_VRB, "%9d visclusters\n", num_visclusters ); Sys_FPrintf( SYS_VRB, "%9d visportals\n", num_visportals ); diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index d8537a3c..abfc262e 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -202,6 +202,7 @@ #define HINT_PRIORITY 1000 /* ydnar: force hint splits first and antiportal/areaportal splits last */ #define ANTIPORTAL_PRIORITY -1000 #define AREAPORTAL_PRIORITY -1000 +#define DETAIL_PRIORITY -3000 #define PSIDE_FRONT 1 #define PSIDE_BACK 2 @@ -789,7 +790,7 @@ typedef struct face_s struct face_s *next; int planenum; int priority; - qboolean checked; + //qboolean checked; int compileFlags; winding_t *w; } @@ -1116,6 +1117,8 @@ typedef struct node_s entity_t *occupant; /* for leak file testing */ struct portal_s *portals; /* also on nodes during construction */ + + qboolean has_structural_children; } node_t; @@ -1948,6 +1951,7 @@ Q_EXTERN qboolean noHint Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean renameModelShaders Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean skyFixHack Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */ +Q_EXTERN qboolean deepBSP Q_ASSIGN( qfalse ); /* div0 */ Q_EXTERN int patchSubdivisions Q_ASSIGN( 8 ); /* ydnar: -patchmeta subdivisions */ @@ -2081,10 +2085,13 @@ Q_EXTERN qboolean fastvis; Q_EXTERN qboolean noPassageVis; Q_EXTERN qboolean passageVisOnly; Q_EXTERN qboolean mergevis; +Q_EXTERN qboolean mergevisportals; Q_EXTERN qboolean nosort; Q_EXTERN qboolean saveprt; Q_EXTERN qboolean hint; /* ydnar */ Q_EXTERN char inbase[ MAX_QPATH ]; +Q_EXTERN char inbase[ MAX_QPATH ]; +Q_EXTERN char globalCelShader[ MAX_QPATH ]; /* other bits */ Q_EXTERN int totalvis; From 3597ccd23981c55fafe45558db16a6187f01be78 Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 25 Apr 2009 21:22:22 +0000 Subject: [PATCH 04/32] unfinished -minimap support in bsp.c, do not use yet, format is not correct yet git-svn-id: svn://svn.icculus.org/netradiant/trunk@328 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/bsp.c | 142 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 4 deletions(-) diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index 6199d07f..e3554257 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -44,6 +44,132 @@ ------------------------------------------------------------------------------- */ +static const char *miniMap = NULL; + +void WriteTGA24( char *filename, byte *data, int width, int height, qboolean flip ); +qboolean BrushIntersectionWithLine(bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out) +{ + int i; + qboolean in = qfalse, out = qfalse; + bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; + + for(i = 0; i < brush->numSides; ++i) + { + bspPlane_t *p = &bspPlanes[sides[i].planeNum]; + float sn = DotProduct(start, p->normal); + float dn = DotProduct(dir, p->normal); + if(dn == 0) + { + if(sn > p->dist) + return qfalse; // outside! + } + else + { + float t = (p->dist - sn) / dn; + if(dn < 0) + { + if(!in || t > *t_in) + { + *t_in = t; + in = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if(*t_in >= *t_out) + return qfalse; + } + } + else + { + if(!out || t < *t_out) + { + *t_out = t; + out = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if(*t_in >= *t_out) + return qfalse; + } + } + } + } + return in && out; +} + +static float MiniMapSample(float x, float y) +{ + vec3_t org, dir; + int i, bi; + float t0, t1; + float samp; + bspBrush_t *b; + int cnt; + + org[0] = x; + org[1] = y; + org[2] = 0; + dir[0] = 0; + dir[1] = 0; + dir[2] = 1; + + cnt = 0; + samp = 0; + for(i = 0; i < bspModels[0].numBSPBrushes; ++i) + { + bi = bspModels[0].firstBSPBrush + i; + if(opaqueBrushes[bi >> 3] & (1 << (bi & 7))) + { + b = &bspBrushes[bi]; + if(BrushIntersectionWithLine(b, org, dir, &t0, &t1)) + { + samp += t1 - t0; + ++cnt; + } + } + } + + return samp; +} + +#define MINIMAP_SIZE 512 +#define MINIMAP_SAMPLES 16 +static byte radarmapdata[MINIMAP_SIZE * MINIMAP_SIZE * 3]; +static vec3_t mi_min, mi_sz; +static void GenerateMiniMapRunner(int y) +{ + int x, i; + + float ymin = mi_min[1] + mi_sz[1] * ( y / (float) MINIMAP_SIZE); + float ymax = mi_min[1] + mi_sz[1] * ((y + 1) / (float) MINIMAP_SIZE); + for(x = 0; x < MINIMAP_SIZE; ++x) + { + byte *p = &radarmapdata[(y * MINIMAP_SIZE + x) * 3]; + float xmin = mi_min[0] + mi_sz[0] * ( x / (float) MINIMAP_SIZE); + float xmax = mi_min[0] + mi_sz[0] * ((x + 1) / (float) MINIMAP_SIZE); + float val = 0; + for(i = 0; i < MINIMAP_SAMPLES; ++i) + val += MiniMapSample( + xmin + Random() * (xmax - xmin), + ymin + Random() * (ymax - ymin) + ); + val /= MINIMAP_SAMPLES * mi_sz[2]; + if(val < 0) + val = 0; + if(val > 255.0/256.0) + val = 255.0/256.0; + p[0] = p[1] = p[2] = val * 256.0; + } +} + +static void GenerateMiniMap() +{ + VectorCopy(bspModels[0].mins, mi_min); + VectorSubtract(bspModels[0].maxs, bspModels[0].mins, mi_sz); + + SetupBrushes(); + + Sys_Printf( "\n--- GenerateMiniMap (%d) ---\n", MINIMAP_SIZE ); + RunThreadsOnIndividual(MINIMAP_SIZE, qtrue, GenerateMiniMapRunner); + + WriteTGA24(miniMap, radarmapdata, MINIMAP_SIZE, MINIMAP_SIZE, qfalse); +} /* ProcessAdvertisements() @@ -852,12 +978,16 @@ int BSPMain( int argc, char **argv ){ Sys_Printf( "Deep BSP tree generation enabled\n" ); deepBSP = qtrue; } - else if( !strcmp( argv[ i ], "-bsp" ) ) + else if( !strcmp( argv[ i ], "-minimap" ) ) { - Sys_Printf( "-bsp argument unnecessary\n" ); + miniMap = argv[i + 1]; + i++; } - else{ - Sys_FPrintf( SYS_WRN, "WARNING: Unknown option \"%s\"\n", argv[ i ] ); + else if( !strcmp( argv[ i ], "-bsp" ) ) + Sys_Printf( "-bsp argument unnecessary\n" ); + else + { + Sys_Printf( "WARNING: Unknown option \"%s\"\n", argv[ i ] ); } } @@ -924,6 +1054,10 @@ int BSPMain( int argc, char **argv ){ /* finish and write bsp */ EndBSPFile(); + + /* write the mini map if needed */ + if(miniMap) + GenerateMiniMap(); /* remove temp map source file if appropriate */ if ( strlen( tempSource ) > 0 ) { From 12f2c1032c509abcd704ce21f17a02d65b4d5114 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 09:34:11 +0000 Subject: [PATCH 05/32] -minimap is now a main option... to be used on already compiled BSPs git-svn-id: svn://svn.icculus.org/netradiant/trunk@329 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/bsp.c | 136 ------------------ tools/quake3/q3map2/main.c | 285 +++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+), 136 deletions(-) diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index e3554257..46a7956f 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -44,133 +44,6 @@ ------------------------------------------------------------------------------- */ -static const char *miniMap = NULL; - -void WriteTGA24( char *filename, byte *data, int width, int height, qboolean flip ); -qboolean BrushIntersectionWithLine(bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out) -{ - int i; - qboolean in = qfalse, out = qfalse; - bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; - - for(i = 0; i < brush->numSides; ++i) - { - bspPlane_t *p = &bspPlanes[sides[i].planeNum]; - float sn = DotProduct(start, p->normal); - float dn = DotProduct(dir, p->normal); - if(dn == 0) - { - if(sn > p->dist) - return qfalse; // outside! - } - else - { - float t = (p->dist - sn) / dn; - if(dn < 0) - { - if(!in || t > *t_in) - { - *t_in = t; - in = qtrue; - // as t_in can only increase, and t_out can only decrease, early out - if(*t_in >= *t_out) - return qfalse; - } - } - else - { - if(!out || t < *t_out) - { - *t_out = t; - out = qtrue; - // as t_in can only increase, and t_out can only decrease, early out - if(*t_in >= *t_out) - return qfalse; - } - } - } - } - return in && out; -} - -static float MiniMapSample(float x, float y) -{ - vec3_t org, dir; - int i, bi; - float t0, t1; - float samp; - bspBrush_t *b; - int cnt; - - org[0] = x; - org[1] = y; - org[2] = 0; - dir[0] = 0; - dir[1] = 0; - dir[2] = 1; - - cnt = 0; - samp = 0; - for(i = 0; i < bspModels[0].numBSPBrushes; ++i) - { - bi = bspModels[0].firstBSPBrush + i; - if(opaqueBrushes[bi >> 3] & (1 << (bi & 7))) - { - b = &bspBrushes[bi]; - if(BrushIntersectionWithLine(b, org, dir, &t0, &t1)) - { - samp += t1 - t0; - ++cnt; - } - } - } - - return samp; -} - -#define MINIMAP_SIZE 512 -#define MINIMAP_SAMPLES 16 -static byte radarmapdata[MINIMAP_SIZE * MINIMAP_SIZE * 3]; -static vec3_t mi_min, mi_sz; -static void GenerateMiniMapRunner(int y) -{ - int x, i; - - float ymin = mi_min[1] + mi_sz[1] * ( y / (float) MINIMAP_SIZE); - float ymax = mi_min[1] + mi_sz[1] * ((y + 1) / (float) MINIMAP_SIZE); - for(x = 0; x < MINIMAP_SIZE; ++x) - { - byte *p = &radarmapdata[(y * MINIMAP_SIZE + x) * 3]; - float xmin = mi_min[0] + mi_sz[0] * ( x / (float) MINIMAP_SIZE); - float xmax = mi_min[0] + mi_sz[0] * ((x + 1) / (float) MINIMAP_SIZE); - float val = 0; - for(i = 0; i < MINIMAP_SAMPLES; ++i) - val += MiniMapSample( - xmin + Random() * (xmax - xmin), - ymin + Random() * (ymax - ymin) - ); - val /= MINIMAP_SAMPLES * mi_sz[2]; - if(val < 0) - val = 0; - if(val > 255.0/256.0) - val = 255.0/256.0; - p[0] = p[1] = p[2] = val * 256.0; - } -} - -static void GenerateMiniMap() -{ - VectorCopy(bspModels[0].mins, mi_min); - VectorSubtract(bspModels[0].maxs, bspModels[0].mins, mi_sz); - - SetupBrushes(); - - Sys_Printf( "\n--- GenerateMiniMap (%d) ---\n", MINIMAP_SIZE ); - RunThreadsOnIndividual(MINIMAP_SIZE, qtrue, GenerateMiniMapRunner); - - WriteTGA24(miniMap, radarmapdata, MINIMAP_SIZE, MINIMAP_SIZE, qfalse); -} - /* ProcessAdvertisements() copies advertisement info into the BSP structures @@ -978,11 +851,6 @@ int BSPMain( int argc, char **argv ){ Sys_Printf( "Deep BSP tree generation enabled\n" ); deepBSP = qtrue; } - else if( !strcmp( argv[ i ], "-minimap" ) ) - { - miniMap = argv[i + 1]; - i++; - } else if( !strcmp( argv[ i ], "-bsp" ) ) Sys_Printf( "-bsp argument unnecessary\n" ); else @@ -1054,10 +922,6 @@ int BSPMain( int argc, char **argv ){ /* finish and write bsp */ EndBSPFile(); - - /* write the mini map if needed */ - if(miniMap) - GenerateMiniMap(); /* remove temp map source file if appropriate */ if ( strlen( tempSource ) > 0 ) { diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 3a92b6f5..8a310693 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -92,6 +92,287 @@ static void ExitQ3Map( void ){ } +/* minimap stuff */ + +/* borrowed from light.c */ +void WriteTGA24( char *filename, byte *data, int width, int height, qboolean flip ); +typedef struct minimap_s +{ + bspModel_t *model; + int width; + int height; + int samples; + float sharpen; + float sharpen_boxmult; + float sharpen_centermult; + float *data1f; + float *sharpendata1f; + vec3_t mins, size; +} +minimap_t; +static minimap_t minimap; + +qboolean BrushIntersectionWithLine(bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out) +{ + int i; + qboolean in = qfalse, out = qfalse; + bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; + + for(i = 0; i < brush->numSides; ++i) + { + bspPlane_t *p = &bspPlanes[sides[i].planeNum]; + float sn = DotProduct(start, p->normal); + float dn = DotProduct(dir, p->normal); + if(dn == 0) + { + if(sn > p->dist) + return qfalse; // outside! + } + else + { + float t = (p->dist - sn) / dn; + if(dn < 0) + { + if(!in || t > *t_in) + { + *t_in = t; + in = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if(out && *t_in >= *t_out) + return qfalse; + } + } + else + { + if(!out || t < *t_out) + { + *t_out = t; + out = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if(in && *t_in >= *t_out) + return qfalse; + } + } + } + } + return in && out; +} + +static float MiniMapSample(float x, float y) +{ + vec3_t org, dir; + int i, bi; + float t0, t1; + float samp; + bspBrush_t *b; + int cnt; + + org[0] = x; + org[1] = y; + org[2] = 0; + dir[0] = 0; + dir[1] = 0; + dir[2] = 1; + + cnt = 0; + samp = 0; + for(i = 0; i < minimap.model->numBSPBrushes; ++i) + { + bi = minimap.model->firstBSPBrush + i; + if(opaqueBrushes[bi >> 3] & (1 << (bi & 7))) + { + b = &bspBrushes[bi]; + + // sort out mins/maxs of the brush + bspBrushSide_t *s = &bspBrushSides[b->firstSide]; + if(x < -bspPlanes[s[0].planeNum].dist) + continue; + if(x > +bspPlanes[s[1].planeNum].dist) + continue; + if(y < -bspPlanes[s[2].planeNum].dist) + continue; + if(y > +bspPlanes[s[3].planeNum].dist) + continue; + + if(BrushIntersectionWithLine(b, org, dir, &t0, &t1)) + { + samp += t1 - t0; + ++cnt; + } + } + } + + return samp; +} + +static void GenerateMiniMapRunner(int y) +{ + int x, i; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); + float dx = minimap.size[0] / (float) minimap.width; + float dy = minimap.size[1] / (float) minimap.height; + + for(x = 0; x < minimap.width; ++x) + { + float xmin = minimap.mins[0] + minimap.size[0] * (x / (float) minimap.width); + float val = 0; + + for(i = 0; i < minimap.samples; ++i) + { + float thisval = MiniMapSample( + xmin + Random() * dx, + ymin + Random() * dy + ); + val += thisval; + } + val /= minimap.samples * minimap.size[2]; + *p++ = val; + } +} + +static void GenerateMiniMapRunnerNoSamples(int y) +{ + int x; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); + + for(x = 0; x < minimap.width; ++x) + { + float xmin = minimap.mins[0] + minimap.size[0] * (x / (float) minimap.width); + *p++ = MiniMapSample(xmin, ymin) / minimap.size[2]; + } +} + +static void SharpenMiniMapRunner(int y) +{ + int x; + qboolean up = (y > 0); + qboolean down = (y < minimap.height - 1); + float *p = &minimap.data1f[y * minimap.width]; + float *q = &minimap.sharpendata1f[y * minimap.width]; + + for(x = 0; x < minimap.width; ++x) + { + qboolean left = (x > 0); + qboolean right = (x < minimap.width - 1); + float val = p[0] * minimap.sharpen_centermult; + + if(left && up) + val += p[-1 -minimap.width] * minimap.sharpen_boxmult; + if(left && down) + val += p[-1 +minimap.width] * minimap.sharpen_boxmult; + if(right && up) + val += p[+1 -minimap.width] * minimap.sharpen_boxmult; + if(right && down) + val += p[+1 +minimap.width] * minimap.sharpen_boxmult; + + if(left) + val += p[-1] * minimap.sharpen_boxmult; + if(right) + val += p[+1] * minimap.sharpen_boxmult; + if(up) + val += p[-minimap.width] * minimap.sharpen_boxmult; + if(down) + val += p[+minimap.width] * minimap.sharpen_boxmult; + + ++p; + *q++ = val; + } +} + +int MiniMapBSPMain( int argc, char **argv ) +{ + char minimapFilename[1024]; + byte *data3b, *p; + float *q; + int x, y; + + /* arg checking */ + if( argc < 2 ) + { + Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen n] [-samples f] [-o filename.tga] \n" ); + return 0; + } + + strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); + StripExtension( source ); + DefaultExtension( source, ".bsp" ); + + strcpy( minimapFilename, ExpandArg( argv[ argc - 1 ] ) ); + StripExtension( minimapFilename ); + DefaultExtension( minimapFilename, ".tga" ); + + minimap.width = minimap.height = 512; + minimap.samples = 1; + minimap.sharpen = 1; + if(minimap.sharpen) + { + minimap.sharpen_centermult = 8 * minimap.sharpen + 1; + minimap.sharpen_boxmult = -minimap.sharpen; + } + + minimap.data1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); + data3b = safe_malloc(minimap.width * minimap.height * 3); + if(minimap.sharpen >= 0) + minimap.sharpendata1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); + + /* load the bsp */ + Sys_Printf( "Loading %s\n", source ); + LoadBSPFile( source ); + + minimap.model = &bspModels[0]; + VectorCopy(minimap.model->mins, minimap.mins); + VectorSubtract(minimap.model->maxs, minimap.model->mins, minimap.size); + + SetupBrushes(); + + if(minimap.samples <= 1) + { + Sys_Printf( "\n--- GenerateMiniMap (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, GenerateMiniMapRunnerNoSamples); + } + else + { + Sys_Printf( "\n--- GenerateMiniMap (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, GenerateMiniMapRunner); + } + + if(minimap.sharpendata1f) + { + Sys_Printf( "\n--- SharpenMiniMap (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, SharpenMiniMapRunner); + q = minimap.sharpendata1f; + } + else + { + q = minimap.data1f; + } + + Sys_Printf( "\nConverting..."); + p = data3b; + for(y = 0; y < minimap.height; ++y) + for(x = 0; x < minimap.width; ++x) + { + float v = *q++; + byte b; + if(v < 0) v = 0; + if(v > 255.0/256.0) v = 255.0/256.0; + b = v * 256; + *p++ = b; + *p++ = b; + *p++ = b; + } + + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA24(minimapFilename, data3b, minimap.width, minimap.height, qfalse); + + Sys_Printf( " done.\n" ); + + /* return to sender */ + return 0; +} + /* main() q3map mojo... @@ -248,6 +529,10 @@ int main( int argc, char **argv ){ r = ConvertBSPMain( argc - 1, argv + 1 ); } + /* div0: minimap */ + else if( !strcmp( argv[ 1 ], "-minimap" ) ) + r = MiniMapBSPMain(argc - 1, argv + 1); + /* ydnar: otherwise create a bsp */ else{ r = BSPMain( argc, argv ); From 48d3475f81001c134518710ff399575d8e5d1610 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 09:42:48 +0000 Subject: [PATCH 06/32] be compatible to nexuiz for minimaps :P git-svn-id: svn://svn.icculus.org/netradiant/trunk@330 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 8a310693..1c1ad907 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -281,6 +281,37 @@ static void SharpenMiniMapRunner(int y) } } +void MiniMapMakeMinsMaxs() +{ + vec3_t mins, maxs, extend; + VectorCopy(minimap.model->mins, mins); + VectorCopy(minimap.model->maxs, maxs); + VectorSubtract(maxs, mins, extend); + + if(extend[1] > extend[0]) + { + mins[0] -= (extend[1] - extend[0]) * 0.5; + maxs[0] += (extend[1] - extend[0]) * 0.5; + } + else + { + mins[1] -= (extend[0] - extend[1]) * 0.5; + maxs[1] += (extend[0] - extend[1]) * 0.5; + } + + VectorSubtract(maxs, mins, extend); + VectorScale(extend, 1.0 / 64.0, extend); + + VectorSubtract(mins, extend, mins); + VectorAdd(maxs, extend, maxs); + + VectorCopy(mins, minimap.mins); + VectorSubtract(maxs, mins, minimap.size); + + // line compatible to nexuiz mapinfo + Sys_Printf("size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); +} + int MiniMapBSPMain( int argc, char **argv ) { char minimapFilename[1024]; @@ -322,8 +353,7 @@ int MiniMapBSPMain( int argc, char **argv ) LoadBSPFile( source ); minimap.model = &bspModels[0]; - VectorCopy(minimap.model->mins, minimap.mins); - VectorSubtract(minimap.model->maxs, minimap.model->mins, minimap.size); + MiniMapMakeMinsMaxs(); SetupBrushes(); From ac00716877e1b921c12edb142a3ebc8a36a97446 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 10:52:11 +0000 Subject: [PATCH 07/32] command line options for minimap git-svn-id: svn://svn.icculus.org/netradiant/trunk@331 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 149 +++++++++++++++++++++++++++++-------- 1 file changed, 116 insertions(+), 33 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 1c1ad907..7825dd97 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -102,7 +102,7 @@ typedef struct minimap_s int width; int height; int samples; - float sharpen; + float *sample_offsets; float sharpen_boxmult; float sharpen_centermult; float *data1f; @@ -205,7 +205,7 @@ static float MiniMapSample(float x, float y) return samp; } -static void GenerateMiniMapRunner(int y) +static void MiniMapRandomlySubsampled(int y) { int x, i; float *p = &minimap.data1f[y * minimap.width]; @@ -231,7 +231,33 @@ static void GenerateMiniMapRunner(int y) } } -static void GenerateMiniMapRunnerNoSamples(int y) +static void MiniMapSubsampled(int y) +{ + int x, i; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); + float dx = minimap.size[0] / (float) minimap.width; + float dy = minimap.size[1] / (float) minimap.height; + + for(x = 0; x < minimap.width; ++x) + { + float xmin = minimap.mins[0] + minimap.size[0] * (x / (float) minimap.width); + float val = 0; + + for(i = 0; i < minimap.samples; ++i) + { + float thisval = MiniMapSample( + xmin + minimap.sample_offsets[2*i+0] * dx, + ymin + minimap.sample_offsets[2*i+1] * dy + ); + val += thisval; + } + val /= minimap.samples * minimap.size[2]; + *p++ = val; + } +} + +static void MiniMapNoSubsampling(int y) { int x; float *p = &minimap.data1f[y * minimap.width]; @@ -244,7 +270,7 @@ static void GenerateMiniMapRunnerNoSamples(int y) } } -static void SharpenMiniMapRunner(int y) +static void MiniMapSharpen(int y) { int x; qboolean up = (y > 0); @@ -286,6 +312,10 @@ void MiniMapMakeMinsMaxs() vec3_t mins, maxs, extend; VectorCopy(minimap.model->mins, mins); VectorCopy(minimap.model->maxs, maxs); + + // line compatible to nexuiz mapinfo + Sys_Printf("size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); + VectorSubtract(maxs, mins, extend); if(extend[1] > extend[0]) @@ -309,69 +339,122 @@ void MiniMapMakeMinsMaxs() VectorSubtract(maxs, mins, minimap.size); // line compatible to nexuiz mapinfo - Sys_Printf("size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); + Sys_Printf("size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); } int MiniMapBSPMain( int argc, char **argv ) { char minimapFilename[1024]; + float minimapSharpen; byte *data3b, *p; float *q; int x, y; + int i; /* arg checking */ if( argc < 2 ) { - Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen n] [-samples f] [-o filename.tga] \n" ); + Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen n] [-samples f] [-o filename.tga] [-minmax Xmin Ymin Zmin Xmax Ymax Zmax] \n" ); return 0; } + /* load the BSP first */ strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); StripExtension( source ); DefaultExtension( source, ".bsp" ); - - strcpy( minimapFilename, ExpandArg( argv[ argc - 1 ] ) ); - StripExtension( minimapFilename ); - DefaultExtension( minimapFilename, ".tga" ); - - minimap.width = minimap.height = 512; - minimap.samples = 1; - minimap.sharpen = 1; - if(minimap.sharpen) - { - minimap.sharpen_centermult = 8 * minimap.sharpen + 1; - minimap.sharpen_boxmult = -minimap.sharpen; - } - - minimap.data1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); - data3b = safe_malloc(minimap.width * minimap.height * 3); - if(minimap.sharpen >= 0) - minimap.sharpendata1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); - - /* load the bsp */ Sys_Printf( "Loading %s\n", source ); LoadBSPFile( source ); minimap.model = &bspModels[0]; MiniMapMakeMinsMaxs(); + *minimapFilename = 0; + minimapSharpen = 1; + minimap.width = minimap.height = 512; + minimap.samples = 1; + minimap.sample_offsets = NULL; + + /* process arguments */ + for( i = 1; i < (argc - 1); i++ ) + { + if( !strcmp( argv[ i ], "-size" ) ) + { + minimap.width = minimap.height = atoi(argv[i + 1]); + i++; + Sys_Printf( "Image size set to %i\n", minimap.width ); + } + else if( !strcmp( argv[ i ], "-sharpen" ) ) + { + minimapSharpen = atof(argv[i + 1]); + i++; + Sys_Printf( "Sharpening coefficient set to %f\n", minimapSharpen ); + } + else if( !strcmp( argv[ i ], "-samples" ) ) + { + minimap.samples = atoi(argv[i + 1]); + i++; + Sys_Printf( "Samples set to %i\n", minimap.samples ); + /* TODO generate a static subsampling pattern */ + } + else if( !strcmp( argv[ i ], "-o" ) ) + { + strcpy(minimapFilename, argv[i + 1]); + i++; + Sys_Printf( "Output file name set to %s\n", minimapFilename ); + } + else if( !strcmp( argv[ i ], "-minmax" ) && i < (argc - 7) ) + { + minimap.mins[0] = atof(argv[i + 1]); + minimap.mins[1] = atof(argv[i + 2]); + minimap.mins[2] = atof(argv[i + 3]); + minimap.size[0] = atof(argv[i + 4]) - minimap.mins[0]; + minimap.size[1] = atof(argv[i + 5]) - minimap.mins[1]; + minimap.size[2] = atof(argv[i + 6]) - minimap.mins[2]; + i += 6; + Sys_Printf( "Map mins/maxs overridden\n" ); + } + } + + strcpy( minimapFilename, ExpandArg( argv[ argc - 1 ] ) ); + StripExtension( minimapFilename ); + DefaultExtension( minimapFilename, ".tga" ); + + if(minimapSharpen >= 0) + { + minimap.sharpen_centermult = 8 * minimapSharpen + 1; + minimap.sharpen_boxmult = -minimapSharpen; + } + + minimap.data1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); + data3b = safe_malloc(minimap.width * minimap.height * 3); + if(minimapSharpen >= 0) + minimap.sharpendata1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); + SetupBrushes(); if(minimap.samples <= 1) { - Sys_Printf( "\n--- GenerateMiniMap (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, GenerateMiniMapRunnerNoSamples); + Sys_Printf( "\n--- MiniMapNoSubsampling (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapNoSubsampling); } else { - Sys_Printf( "\n--- GenerateMiniMap (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, GenerateMiniMapRunner); + if(minimap.sample_offsets) + { + Sys_Printf( "\n--- MiniMapSubsampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapSubsampled); + } + else + { + Sys_Printf( "\n--- MiniMapRandomlySubsampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapRandomlySubsampled); + } } if(minimap.sharpendata1f) { - Sys_Printf( "\n--- SharpenMiniMap (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, SharpenMiniMapRunner); + Sys_Printf( "\n--- MiniMapSharpen (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapSharpen); q = minimap.sharpendata1f; } else @@ -384,8 +467,8 @@ int MiniMapBSPMain( int argc, char **argv ) for(y = 0; y < minimap.height; ++y) for(x = 0; x < minimap.width; ++x) { - float v = *q++; byte b; + float v = *q++; if(v < 0) v = 0; if(v > 255.0/256.0) v = 255.0/256.0; b = v * 256; From 858727133f8c1f371ab8d63c4d699241459692e0 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 11:03:39 +0000 Subject: [PATCH 08/32] naming fixes, allow ordered supersampling git-svn-id: svn://svn.icculus.org/netradiant/trunk@332 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 58 +++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 7825dd97..930146e6 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -205,7 +205,7 @@ static float MiniMapSample(float x, float y) return samp; } -static void MiniMapRandomlySubsampled(int y) +static void MiniMapRandomlySupersampled(int y) { int x, i; float *p = &minimap.data1f[y * minimap.width]; @@ -221,8 +221,8 @@ static void MiniMapRandomlySubsampled(int y) for(i = 0; i < minimap.samples; ++i) { float thisval = MiniMapSample( - xmin + Random() * dx, - ymin + Random() * dy + xmin + (2 * Random() - 0.5) * dx, /* exaggerated random pattern for better results */ + ymin + (2 * Random() - 0.5) * dy /* exaggerated random pattern for better results */ ); val += thisval; } @@ -231,7 +231,7 @@ static void MiniMapRandomlySubsampled(int y) } } -static void MiniMapSubsampled(int y) +static void MiniMapSupersampled(int y) { int x, i; float *p = &minimap.data1f[y * minimap.width]; @@ -257,7 +257,7 @@ static void MiniMapSubsampled(int y) } } -static void MiniMapNoSubsampling(int y) +static void MiniMapNoSupersampling(int y) { int x; float *p = &minimap.data1f[y * minimap.width]; @@ -345,6 +345,9 @@ void MiniMapMakeMinsMaxs() int MiniMapBSPMain( int argc, char **argv ) { char minimapFilename[1024]; + char basename[1024]; + char path[1024]; + char parentpath[1024]; float minimapSharpen; byte *data3b, *p; float *q; @@ -354,7 +357,7 @@ int MiniMapBSPMain( int argc, char **argv ) /* arg checking */ if( argc < 2 ) { - Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen n] [-samples f] [-o filename.tga] [-minmax Xmin Ymin Zmin Xmax Ymax Zmax] \n" ); + Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen f] [-samples n | -random n] [-o filename.tga] [-minmax Xmin Ymin Zmin Xmax Ymax Zmax] \n" ); return 0; } @@ -394,7 +397,21 @@ int MiniMapBSPMain( int argc, char **argv ) minimap.samples = atoi(argv[i + 1]); i++; Sys_Printf( "Samples set to %i\n", minimap.samples ); - /* TODO generate a static subsampling pattern */ + if(minimap.sample_offsets) + free(minimap.sample_offsets); + minimap.sample_offsets = malloc(2 * sizeof(*minimap.sample_offsets) * minimap.samples); + /* TODO use a better pattern */ + for(x = 0; x < 2 * minimap.samples; ++x) + minimap.sample_offsets[x] = Random(); + } + else if( !strcmp( argv[ i ], "-random" ) ) + { + minimap.samples = atoi(argv[i + 1]); + i++; + Sys_Printf( "Random samples set to %i\n", minimap.samples ); + if(minimap.sample_offsets) + free(minimap.sample_offsets); + minimap.sample_offsets = NULL; } else if( !strcmp( argv[ i ], "-o" ) ) { @@ -415,9 +432,18 @@ int MiniMapBSPMain( int argc, char **argv ) } } - strcpy( minimapFilename, ExpandArg( argv[ argc - 1 ] ) ); - StripExtension( minimapFilename ); - DefaultExtension( minimapFilename, ".tga" ); + if(!*minimapFilename) + { + ExtractFileBase(source, basename); + ExtractFilePath(source, path); + if(*path) + path[strlen(path)-1] = 0; + ExtractFilePath(path, parentpath); + sprintf(minimapFilename, "%sgfx", parentpath); + Q_mkdir(minimapFilename); + sprintf(minimapFilename, "%sgfx/%s_mini.tga", parentpath, basename); + Sys_Printf("Output file name automatically set to %s\n", minimapFilename); + } if(minimapSharpen >= 0) { @@ -434,20 +460,20 @@ int MiniMapBSPMain( int argc, char **argv ) if(minimap.samples <= 1) { - Sys_Printf( "\n--- MiniMapNoSubsampling (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapNoSubsampling); + Sys_Printf( "\n--- MiniMapNoSupersampling (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapNoSupersampling); } else { if(minimap.sample_offsets) { - Sys_Printf( "\n--- MiniMapSubsampled (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapSubsampled); + Sys_Printf( "\n--- MiniMapSupersampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapSupersampled); } else { - Sys_Printf( "\n--- MiniMapRandomlySubsampled (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapRandomlySubsampled); + Sys_Printf( "\n--- MiniMapRandomlySupersampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapRandomlySupersampled); } } From 1b926fe925d2b0063d603553b9802d74bb27190f Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 18:57:18 +0000 Subject: [PATCH 09/32] ignore nonsolid brushes git-svn-id: svn://svn.icculus.org/netradiant/trunk@333 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 66 +++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 930146e6..2c969863 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -342,6 +342,68 @@ void MiniMapMakeMinsMaxs() Sys_Printf("size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); } +/* +MiniMapSetupBrushes() +determines solid non-sky brushes in the world +*/ + +void MiniMapSetupBrushes( void ) +{ + int i, j, b, compileFlags; + bspBrush_t *brush; + bspBrushSide_t *side; + bspShader_t *shader; + shaderInfo_t *si; + + + /* note it */ + Sys_FPrintf( SYS_VRB, "--- MiniMapSetupBrushes ---\n" ); + + /* allocate */ + if( opaqueBrushes == NULL ) + opaqueBrushes = safe_malloc( numBSPBrushes / 8 + 1 ); + + /* clear */ + memset( opaqueBrushes, 0, numBSPBrushes / 8 + 1 ); + numOpaqueBrushes = 0; + + /* walk the list of worldspawn brushes */ + for( i = 0; i < minimap.model->numBSPBrushes; i++ ) + { + /* get brush */ + b = minimap.model->firstBSPBrush + i; + brush = &bspBrushes[ b ]; + + /* check all sides */ + compileFlags = 0; + for( j = 0; j < brush->numSides; j++ ) + { + /* do bsp shader calculations */ + side = &bspBrushSides[ brush->firstSide + j ]; + shader = &bspShaders[ side->shaderNum ]; + + /* get shader info */ + si = ShaderInfoForShader( shader->shader ); + if( si == NULL ) + continue; + + /* or together compile flags */ + compileFlags |= si->compileFlags; + } + + /* determine if this brush is solid */ + if( (compileFlags & (C_SOLID | C_SKY)) == C_SOLID ) + { + opaqueBrushes[ b >> 3 ] |= (1 << (b & 7)); + numOpaqueBrushes++; + maxOpaqueBrush = i; + } + } + + /* emit some statistics */ + Sys_FPrintf( SYS_VRB, "%9d solid brushes\n", numOpaqueBrushes ); +} + int MiniMapBSPMain( int argc, char **argv ) { char minimapFilename[1024]; @@ -366,6 +428,8 @@ int MiniMapBSPMain( int argc, char **argv ) StripExtension( source ); DefaultExtension( source, ".bsp" ); Sys_Printf( "Loading %s\n", source ); + BeginMapShaderFile( source ); + LoadShaderInfo(); LoadBSPFile( source ); minimap.model = &bspModels[0]; @@ -456,7 +520,7 @@ int MiniMapBSPMain( int argc, char **argv ) if(minimapSharpen >= 0) minimap.sharpendata1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); - SetupBrushes(); + MiniMapSetupBrushes(); if(minimap.samples <= 1) { From bde58c1edd4fb2b71c2b7e4308f609918076fa30 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 19:05:49 +0000 Subject: [PATCH 10/32] simplify shader decision logic in MiniMapSetupBrushes git-svn-id: svn://svn.icculus.org/netradiant/trunk@335 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 2c969863..4dfa4151 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -374,6 +374,7 @@ void MiniMapSetupBrushes( void ) b = minimap.model->firstBSPBrush + i; brush = &bspBrushes[ b ]; +#if 0 /* check all sides */ compileFlags = 0; for( j = 0; j < brush->numSides; j++ ) @@ -390,6 +391,14 @@ void MiniMapSetupBrushes( void ) /* or together compile flags */ compileFlags |= si->compileFlags; } +#else + shader = &bspShaders[ brush->shaderNum ]; + si = ShaderInfoForShader( shader->shader ); + if( si == NULL ) + compileFlags = 0; + else + compileFlags = si->compileFlags; +#endif /* determine if this brush is solid */ if( (compileFlags & (C_SOLID | C_SKY)) == C_SOLID ) From f701f2e2681bf26488d03bf9ca8c76396f954e34 Mon Sep 17 00:00:00 2001 From: divverent Date: Sun, 26 Apr 2009 19:13:10 +0000 Subject: [PATCH 11/32] make -minmax work git-svn-id: svn://svn.icculus.org/netradiant/trunk@336 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 4dfa4151..edae0b53 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -307,11 +307,11 @@ static void MiniMapSharpen(int y) } } -void MiniMapMakeMinsMaxs() +void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in) { vec3_t mins, maxs, extend; - VectorCopy(minimap.model->mins, mins); - VectorCopy(minimap.model->maxs, maxs); + VectorCopy(mins_in, mins); + VectorCopy(maxs_in, maxs); // line compatible to nexuiz mapinfo Sys_Printf("size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); @@ -424,6 +424,7 @@ int MiniMapBSPMain( int argc, char **argv ) float *q; int x, y; int i; + vec3_t mins, maxs; /* arg checking */ if( argc < 2 ) @@ -442,8 +443,8 @@ int MiniMapBSPMain( int argc, char **argv ) LoadBSPFile( source ); minimap.model = &bspModels[0]; - MiniMapMakeMinsMaxs(); - + VectorCopy(minimap.model->mins, mins); + VectorCopy(minimap.model->maxs, maxs); *minimapFilename = 0; minimapSharpen = 1; minimap.width = minimap.height = 512; @@ -494,17 +495,19 @@ int MiniMapBSPMain( int argc, char **argv ) } else if( !strcmp( argv[ i ], "-minmax" ) && i < (argc - 7) ) { - minimap.mins[0] = atof(argv[i + 1]); - minimap.mins[1] = atof(argv[i + 2]); - minimap.mins[2] = atof(argv[i + 3]); - minimap.size[0] = atof(argv[i + 4]) - minimap.mins[0]; - minimap.size[1] = atof(argv[i + 5]) - minimap.mins[1]; - minimap.size[2] = atof(argv[i + 6]) - minimap.mins[2]; + mins[0] = atof(argv[i + 1]); + mins[1] = atof(argv[i + 2]); + mins[2] = atof(argv[i + 3]); + maxs[0] = atof(argv[i + 4]); + maxs[1] = atof(argv[i + 5]); + maxs[2] = atof(argv[i + 6]); i += 6; Sys_Printf( "Map mins/maxs overridden\n" ); } } + MiniMapMakeMinsMaxs(mins, maxs); + if(!*minimapFilename) { ExtractFileBase(source, basename); From a04a5b5fdacb3e510116a859713dfb848f91a739 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 08:54:52 +0000 Subject: [PATCH 12/32] probabilistic sample dispersion for minimap -samples git-svn-id: svn://svn.icculus.org/netradiant/trunk@339 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 121 +++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 5 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index edae0b53..899638bd 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -205,6 +205,16 @@ static float MiniMapSample(float x, float y) return samp; } +void RandomVector2f(float v[2]) +{ + do + { + v[0] = 2 * Random() - 1; + v[1] = 2 * Random() - 1; + } + while(v[0] * v[0] + v[1] * v[1] > 1); +} + static void MiniMapRandomlySupersampled(int y) { int x, i; @@ -212,6 +222,7 @@ static void MiniMapRandomlySupersampled(int y) float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); float dx = minimap.size[0] / (float) minimap.width; float dy = minimap.size[1] / (float) minimap.height; + float uv[2]; for(x = 0; x < minimap.width; ++x) { @@ -220,9 +231,10 @@ static void MiniMapRandomlySupersampled(int y) for(i = 0; i < minimap.samples; ++i) { + RandomVector2f(uv); float thisval = MiniMapSample( - xmin + (2 * Random() - 0.5) * dx, /* exaggerated random pattern for better results */ - ymin + (2 * Random() - 0.5) * dy /* exaggerated random pattern for better results */ + xmin + (uv[0] + 0.5) * dx, /* exaggerated random pattern for better results */ + ymin + (uv[1] + 0.5) * dy /* exaggerated random pattern for better results */ ); val += thisval; } @@ -413,6 +425,107 @@ void MiniMapSetupBrushes( void ) Sys_FPrintf( SYS_VRB, "%9d solid brushes\n", numOpaqueBrushes ); } +qboolean MiniMapEvaluateSampleOffsets(int *bestj, int *bestk, float *bestval) +{ + float val, dx, dy; + int j, k; + + *bestj = *bestk = -1; + *bestval = 3; /* max possible val is 2 */ + + for(j = 0; j < minimap.samples; ++j) + for(k = j + 1; k < minimap.samples; ++k) + { + dx = minimap.sample_offsets[2*j+0] - minimap.sample_offsets[2*k+0]; + dy = minimap.sample_offsets[2*j+1] - minimap.sample_offsets[2*k+1]; + if(dx > +0.5) dx -= 1; + if(dx < -0.5) dx += 1; + if(dy > +0.5) dy -= 1; + if(dy < -0.5) dy += 1; + val = dx * dx + dy * dy; + if(val < *bestval) + { + *bestj = j; + *bestk = k; + *bestval = val; + } + } + + return *bestval < 3; +} + +void MiniMapMakeSampleOffsets() +{ + int i, j, k, jj, kk; + float val, valj, valk, dx, dy, sx, sy, rx, ry; + + Sys_Printf( "Generating good sample offsets (this may take a while)...\n" ); + + /* start with entirely random samples */ + for(i = 0; i < minimap.samples; ++i) + { + minimap.sample_offsets[2*i+0] = Random(); + minimap.sample_offsets[2*i+1] = Random(); + } + + for(i = 0; i < 1000; ++i) + { + if(MiniMapEvaluateSampleOffsets(&j, &k, &val)) + { + sx = minimap.sample_offsets[2*j+0]; + sy = minimap.sample_offsets[2*j+1]; + minimap.sample_offsets[2*j+0] = rx = Random(); + minimap.sample_offsets[2*j+1] = ry = Random(); + if(!MiniMapEvaluateSampleOffsets(&jj, &kk, &valj)) + valj = -1; + minimap.sample_offsets[2*j+0] = sx; + minimap.sample_offsets[2*j+1] = sy; + + sx = minimap.sample_offsets[2*k+0]; + sy = minimap.sample_offsets[2*k+1]; + minimap.sample_offsets[2*k+0] = rx; + minimap.sample_offsets[2*k+1] = ry; + if(!MiniMapEvaluateSampleOffsets(&jj, &kk, &valk)) + valk = -1; + minimap.sample_offsets[2*k+0] = sx; + minimap.sample_offsets[2*k+1] = sy; + + if(valj > valk) + { + if(valj > val) + { + /* valj is the greatest */ + minimap.sample_offsets[2*j+0] = rx; + minimap.sample_offsets[2*j+1] = ry; + i = -1; + Sys_Printf("%f\n", val); + } + else + { + /* valj is the greater and it is useless - forget it */ + } + } + else + { + if(valk > val) + { + /* valk is the greatest */ + minimap.sample_offsets[2*k+0] = rx; + minimap.sample_offsets[2*k+1] = ry; + i = -1; + Sys_Printf("%f\n", val); + } + else + { + /* valk is the greater and it is useless - forget it */ + } + } + } + else + break; + } +} + int MiniMapBSPMain( int argc, char **argv ) { char minimapFilename[1024]; @@ -474,9 +587,7 @@ int MiniMapBSPMain( int argc, char **argv ) if(minimap.sample_offsets) free(minimap.sample_offsets); minimap.sample_offsets = malloc(2 * sizeof(*minimap.sample_offsets) * minimap.samples); - /* TODO use a better pattern */ - for(x = 0; x < 2 * minimap.samples; ++x) - minimap.sample_offsets[x] = Random(); + MiniMapMakeSampleOffsets(); } else if( !strcmp( argv[ i ], "-random" ) ) { From ac7d31060b0114b0d4fa4fc2d13b0db447700d15 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 09:16:40 +0000 Subject: [PATCH 13/32] fix a 0.5 error git-svn-id: svn://svn.icculus.org/netradiant/trunk@340 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 899638bd..0c3e5805 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -273,11 +273,11 @@ static void MiniMapNoSupersampling(int y) { int x; float *p = &minimap.data1f[y * minimap.width]; - float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); + float ymin = minimap.mins[1] + minimap.size[1] * ((y + 0.5) / (float) minimap.height); for(x = 0; x < minimap.width; ++x) { - float xmin = minimap.mins[0] + minimap.size[0] * (x / (float) minimap.width); + float xmin = minimap.mins[0] + minimap.size[0] * ((x + 0.5) / (float) minimap.width); *p++ = MiniMapSample(xmin, ymin) / minimap.size[2]; } } From 4f58d60bc37d3ec5d8097d27501b7b7a0b579943 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 09:20:03 +0000 Subject: [PATCH 14/32] remove two debug prints git-svn-id: svn://svn.icculus.org/netradiant/trunk@341 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 0c3e5805..696a4e14 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -498,7 +498,6 @@ void MiniMapMakeSampleOffsets() minimap.sample_offsets[2*j+0] = rx; minimap.sample_offsets[2*j+1] = ry; i = -1; - Sys_Printf("%f\n", val); } else { @@ -513,7 +512,6 @@ void MiniMapMakeSampleOffsets() minimap.sample_offsets[2*k+0] = rx; minimap.sample_offsets[2*k+1] = ry; i = -1; - Sys_Printf("%f\n", val); } else { From cf607a4986a1bd97060a7e2dd0112473116f572b Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 10:11:19 +0000 Subject: [PATCH 15/32] msvc shut up git-svn-id: svn://svn.icculus.org/netradiant/trunk@342 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 696a4e14..b15e3e6c 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -165,6 +165,7 @@ static float MiniMapSample(float x, float y) float t0, t1; float samp; bspBrush_t *b; + bspBrushSide_t *s; int cnt; org[0] = x; @@ -184,7 +185,7 @@ static float MiniMapSample(float x, float y) b = &bspBrushes[bi]; // sort out mins/maxs of the brush - bspBrushSide_t *s = &bspBrushSides[b->firstSide]; + s = &bspBrushSides[b->firstSide]; if(x < -bspPlanes[s[0].planeNum].dist) continue; if(x > +bspPlanes[s[1].planeNum].dist) @@ -223,6 +224,7 @@ static void MiniMapRandomlySupersampled(int y) float dx = minimap.size[0] / (float) minimap.width; float dy = minimap.size[1] / (float) minimap.height; float uv[2]; + float thisval; for(x = 0; x < minimap.width; ++x) { @@ -232,7 +234,7 @@ static void MiniMapRandomlySupersampled(int y) for(i = 0; i < minimap.samples; ++i) { RandomVector2f(uv); - float thisval = MiniMapSample( + thisval = MiniMapSample( xmin + (uv[0] + 0.5) * dx, /* exaggerated random pattern for better results */ ymin + (uv[1] + 0.5) * dy /* exaggerated random pattern for better results */ ); From e5d5b5a8667c261b835ceb0ba435d10db28a4412 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 13:54:44 +0000 Subject: [PATCH 16/32] option -border in minimap git-svn-id: svn://svn.icculus.org/netradiant/trunk@343 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index b15e3e6c..57193800 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -321,7 +321,7 @@ static void MiniMapSharpen(int y) } } -void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in) +void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border) { vec3_t mins, maxs, extend; VectorCopy(mins_in, mins); @@ -343,8 +343,11 @@ void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in) maxs[1] += (extend[0] - extend[1]) * 0.5; } + /* border: amount of black area around the image */ + /* input: border, 1-2*border, border but we need border/(1-2*border) */ + VectorSubtract(maxs, mins, extend); - VectorScale(extend, 1.0 / 64.0, extend); + VectorScale(extend, border / (1 - 2 * border), extend); VectorSubtract(mins, extend, mins); VectorAdd(maxs, extend, maxs); @@ -533,6 +536,7 @@ int MiniMapBSPMain( int argc, char **argv ) char path[1024]; char parentpath[1024]; float minimapSharpen; + float border; byte *data3b, *p; float *q; int x, y; @@ -563,6 +567,7 @@ int MiniMapBSPMain( int argc, char **argv ) minimap.width = minimap.height = 512; minimap.samples = 1; minimap.sample_offsets = NULL; + border = 1/66.0; /* good default for Nexuiz */ /* process arguments */ for( i = 1; i < (argc - 1); i++ ) @@ -598,6 +603,12 @@ int MiniMapBSPMain( int argc, char **argv ) free(minimap.sample_offsets); minimap.sample_offsets = NULL; } + else if( !strcmp( argv[ i ], "-border" ) ) + { + border = atof(argv[i + 1]); + i++; + Sys_Printf( "Border set to %f\n", border ); + } else if( !strcmp( argv[ i ], "-o" ) ) { strcpy(minimapFilename, argv[i + 1]); @@ -617,7 +628,7 @@ int MiniMapBSPMain( int argc, char **argv ) } } - MiniMapMakeMinsMaxs(mins, maxs); + MiniMapMakeMinsMaxs(mins, maxs, border); if(!*minimapFilename) { From 3ae3b209876c2ed0adc1fa82887d7876c23a9502 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 14:58:50 +0000 Subject: [PATCH 17/32] make minimap parameters game dependent git-svn-id: svn://svn.icculus.org/netradiant/trunk@344 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/game_ef.h | 4 +++ tools/quake3/q3map2/game_etut.h | 4 +++ tools/quake3/q3map2/game_ja.h | 4 +++ tools/quake3/q3map2/game_jk2.h | 4 +++ tools/quake3/q3map2/game_nexuiz.h | 4 +++ tools/quake3/q3map2/game_qfusion.h | 4 +++ tools/quake3/q3map2/game_quake3.h | 4 +++ tools/quake3/q3map2/game_quakelive.h | 4 +++ tools/quake3/q3map2/game_sof2.h | 4 +++ tools/quake3/q3map2/game_tenebrae.h | 4 +++ tools/quake3/q3map2/game_tremulous.h | 4 +++ tools/quake3/q3map2/game_wolf.h | 4 +++ tools/quake3/q3map2/game_wolfet.h | 4 +++ tools/quake3/q3map2/main.c | 45 ++++++++++++++++++++-------- tools/quake3/q3map2/q3map2.h | 4 +++ 15 files changed, 88 insertions(+), 13 deletions(-) diff --git a/tools/quake3/q3map2/game_ef.h b/tools/quake3/q3map2/game_ef.h index efce240d..e77194d2 100644 --- a/tools/quake3/q3map2/game_ef.h +++ b/tools/quake3/q3map2/game_ef.h @@ -114,6 +114,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_etut.h b/tools/quake3/q3map2/game_etut.h index 9482dd54..7244a27b 100644 --- a/tools/quake3/q3map2/game_etut.h +++ b/tools/quake3/q3map2/game_etut.h @@ -149,6 +149,10 @@ 128, /* lightmap width/height */ 2.2f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_ja.h b/tools/quake3/q3map2/game_ja.h index d9d4311d..d8450067 100644 --- a/tools/quake3/q3map2/game_ja.h +++ b/tools/quake3/q3map2/game_ja.h @@ -68,6 +68,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_jk2.h b/tools/quake3/q3map2/game_jk2.h index a990339f..ce8c4ba8 100644 --- a/tools/quake3/q3map2/game_jk2.h +++ b/tools/quake3/q3map2/game_jk2.h @@ -65,6 +65,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_nexuiz.h b/tools/quake3/q3map2/game_nexuiz.h index a11cd2f3..186b47ae 100644 --- a/tools/quake3/q3map2/game_nexuiz.h +++ b/tools/quake3/q3map2/game_nexuiz.h @@ -64,6 +64,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 1.0f/66.0f, /* minimap border */ + "../gfx/%s_mini.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index b17f9fa8..a61bb521 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -113,6 +113,10 @@ 512, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "FBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_quake3.h b/tools/quake3/q3map2/game_quake3.h index 2ffdc246..19856df6 100644 --- a/tools/quake3/q3map2/game_quake3.h +++ b/tools/quake3/q3map2/game_quake3.h @@ -113,6 +113,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_quakelive.h b/tools/quake3/q3map2/game_quakelive.h index ad014252..f22e28d1 100644 --- a/tools/quake3/q3map2/game_quakelive.h +++ b/tools/quake3/q3map2/game_quakelive.h @@ -77,6 +77,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_sof2.h b/tools/quake3/q3map2/game_sof2.h index 4c957714..cb620b26 100644 --- a/tools/quake3/q3map2/game_sof2.h +++ b/tools/quake3/q3map2/game_sof2.h @@ -140,6 +140,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_tenebrae.h b/tools/quake3/q3map2/game_tenebrae.h index c76d45de..84f7d508 100644 --- a/tools/quake3/q3map2/game_tenebrae.h +++ b/tools/quake3/q3map2/game_tenebrae.h @@ -113,6 +113,10 @@ 512, /* lightmap width/height */ 2.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_tremulous.h b/tools/quake3/q3map2/game_tremulous.h index 87601baa..f0013e56 100644 --- a/tools/quake3/q3map2/game_tremulous.h +++ b/tools/quake3/q3map2/game_tremulous.h @@ -71,6 +71,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_wolf.h b/tools/quake3/q3map2/game_wolf.h index 5d600612..9e1c7c02 100644 --- a/tools/quake3/q3map2/game_wolf.h +++ b/tools/quake3/q3map2/game_wolf.h @@ -130,6 +130,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_wolfet.h b/tools/quake3/q3map2/game_wolfet.h index fbcb6966..5fbd4d0e 100644 --- a/tools/quake3/q3map2/game_wolfet.h +++ b/tools/quake3/q3map2/game_wolfet.h @@ -67,6 +67,10 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 57193800..7b910c88 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -366,9 +366,8 @@ determines solid non-sky brushes in the world void MiniMapSetupBrushes( void ) { - int i, j, b, compileFlags; + int i, b, compileFlags; bspBrush_t *brush; - bspBrushSide_t *side; bspShader_t *shader; shaderInfo_t *si; @@ -462,7 +461,7 @@ qboolean MiniMapEvaluateSampleOffsets(int *bestj, int *bestk, float *bestval) void MiniMapMakeSampleOffsets() { int i, j, k, jj, kk; - float val, valj, valk, dx, dy, sx, sy, rx, ry; + float val, valj, valk, sx, sy, rx, ry; Sys_Printf( "Generating good sample offsets (this may take a while)...\n" ); @@ -529,12 +528,34 @@ void MiniMapMakeSampleOffsets() } } +void MergeRelativePath(char *out, const char *absolute, const char *relative) +{ + const char *endpos = absolute + strlen(absolute); + while(endpos != absolute && (endpos[-1] == '/' || endpos[-1] == '\\')) + --endpos; + while(relative[0] == '.' && relative[1] == '.' && (relative[2] == '/' || relative[2] == '\\')) + { + relative += 3; + while(endpos != absolute) + { + --endpos; + if(*endpos == '/' || *endpos == '\\') + break; + } + while(endpos != absolute && (endpos[-1] == '/' || endpos[-1] == '\\')) + --endpos; + } + memcpy(out, absolute, endpos - absolute); + out[endpos - absolute] = '/'; + strcpy(out + (endpos - absolute + 1), relative); +} + int MiniMapBSPMain( int argc, char **argv ) { char minimapFilename[1024]; char basename[1024]; char path[1024]; - char parentpath[1024]; + char relativeMinimapFilename[1024]; float minimapSharpen; float border; byte *data3b, *p; @@ -562,12 +583,14 @@ int MiniMapBSPMain( int argc, char **argv ) minimap.model = &bspModels[0]; VectorCopy(minimap.model->mins, mins); VectorCopy(minimap.model->maxs, maxs); + *minimapFilename = 0; - minimapSharpen = 1; - minimap.width = minimap.height = 512; + minimapSharpen = game->miniMapSharpen; + minimap.width = minimap.height = game->miniMapSize; + border = game->miniMapBorder; + minimap.samples = 1; minimap.sample_offsets = NULL; - border = 1/66.0; /* good default for Nexuiz */ /* process arguments */ for( i = 1; i < (argc - 1); i++ ) @@ -634,12 +657,8 @@ int MiniMapBSPMain( int argc, char **argv ) { ExtractFileBase(source, basename); ExtractFilePath(source, path); - if(*path) - path[strlen(path)-1] = 0; - ExtractFilePath(path, parentpath); - sprintf(minimapFilename, "%sgfx", parentpath); - Q_mkdir(minimapFilename); - sprintf(minimapFilename, "%sgfx/%s_mini.tga", parentpath, basename); + sprintf(relativeMinimapFilename, game->miniMapNameFormat, basename); + MergeRelativePath(minimapFilename, path, relativeMinimapFilename); Sys_Printf("Output file name automatically set to %s\n", minimapFilename); } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index abfc262e..2c074443 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -566,6 +566,10 @@ typedef struct game_s int lightmapSize; /* bsp lightmap width/height */ float lightmapGamma; /* default lightmap gamma */ float lightmapCompensate; /* default lightmap compensate value */ + int miniMapSize; /* minimap size */ + float miniMapSharpen; /* minimap sharpening coefficient */ + float miniMapBorder; /* minimap border amount */ + char *miniMapNameFormat; /* minimap name format */ char *bspIdent; /* 4-letter bsp file prefix */ int bspVersion; /* bsp version to use */ qboolean lumpSwap; /* cod-style len/ofs order */ From 597e5b5eeb9528635a584f582f264d3c0df1c6ff Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 15:03:55 +0000 Subject: [PATCH 18/32] allow not keeping aspect git-svn-id: svn://svn.icculus.org/netradiant/trunk@345 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/game_ef.h | 1 + tools/quake3/q3map2/game_etut.h | 1 + tools/quake3/q3map2/game_ja.h | 1 + tools/quake3/q3map2/game_jk2.h | 1 + tools/quake3/q3map2/game_nexuiz.h | 1 + tools/quake3/q3map2/game_qfusion.h | 3 ++- tools/quake3/q3map2/game_quake3.h | 1 + tools/quake3/q3map2/game_quakelive.h | 1 + tools/quake3/q3map2/game_sof2.h | 1 + tools/quake3/q3map2/game_tenebrae.h | 1 + tools/quake3/q3map2/game_tremulous.h | 1 + tools/quake3/q3map2/game_wolf.h | 1 + tools/quake3/q3map2/game_wolfet.h | 1 + tools/quake3/q3map2/main.c | 38 +++++++++++++++++++--------- tools/quake3/q3map2/q3map2.h | 1 + 15 files changed, 41 insertions(+), 13 deletions(-) diff --git a/tools/quake3/q3map2/game_ef.h b/tools/quake3/q3map2/game_ef.h index e77194d2..b37c3584 100644 --- a/tools/quake3/q3map2/game_ef.h +++ b/tools/quake3/q3map2/game_ef.h @@ -117,6 +117,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_etut.h b/tools/quake3/q3map2/game_etut.h index 7244a27b..d8609e10 100644 --- a/tools/quake3/q3map2/game_etut.h +++ b/tools/quake3/q3map2/game_etut.h @@ -152,6 +152,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_ja.h b/tools/quake3/q3map2/game_ja.h index d8450067..8069ed31 100644 --- a/tools/quake3/q3map2/game_ja.h +++ b/tools/quake3/q3map2/game_ja.h @@ -71,6 +71,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_jk2.h b/tools/quake3/q3map2/game_jk2.h index ce8c4ba8..410dc585 100644 --- a/tools/quake3/q3map2/game_jk2.h +++ b/tools/quake3/q3map2/game_jk2.h @@ -68,6 +68,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_nexuiz.h b/tools/quake3/q3map2/game_nexuiz.h index 186b47ae..8aed61d4 100644 --- a/tools/quake3/q3map2/game_nexuiz.h +++ b/tools/quake3/q3map2/game_nexuiz.h @@ -67,6 +67,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 1.0f/66.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "../gfx/%s_mini.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index a61bb521..838d87b9 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -114,8 +114,9 @@ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ 512, /* minimap size */ - 1.0f, /* minimap sharpener */ + 0.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qfalse, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "FBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_quake3.h b/tools/quake3/q3map2/game_quake3.h index 19856df6..2065dce1 100644 --- a/tools/quake3/q3map2/game_quake3.h +++ b/tools/quake3/q3map2/game_quake3.h @@ -116,6 +116,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_quakelive.h b/tools/quake3/q3map2/game_quakelive.h index f22e28d1..ec4c5622 100644 --- a/tools/quake3/q3map2/game_quakelive.h +++ b/tools/quake3/q3map2/game_quakelive.h @@ -80,6 +80,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_sof2.h b/tools/quake3/q3map2/game_sof2.h index cb620b26..25b31975 100644 --- a/tools/quake3/q3map2/game_sof2.h +++ b/tools/quake3/q3map2/game_sof2.h @@ -143,6 +143,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_tenebrae.h b/tools/quake3/q3map2/game_tenebrae.h index 84f7d508..b2141848 100644 --- a/tools/quake3/q3map2/game_tenebrae.h +++ b/tools/quake3/q3map2/game_tenebrae.h @@ -116,6 +116,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_tremulous.h b/tools/quake3/q3map2/game_tremulous.h index f0013e56..2ff8c8ac 100644 --- a/tools/quake3/q3map2/game_tremulous.h +++ b/tools/quake3/q3map2/game_tremulous.h @@ -74,6 +74,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_wolf.h b/tools/quake3/q3map2/game_wolf.h index 9e1c7c02..21702502 100644 --- a/tools/quake3/q3map2/game_wolf.h +++ b/tools/quake3/q3map2/game_wolf.h @@ -133,6 +133,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_wolfet.h b/tools/quake3/q3map2/game_wolfet.h index 5fbd4d0e..aba6cb67 100644 --- a/tools/quake3/q3map2/game_wolfet.h +++ b/tools/quake3/q3map2/game_wolfet.h @@ -70,6 +70,7 @@ 512, /* minimap size */ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 7b910c88..8553bc44 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -321,7 +321,7 @@ static void MiniMapSharpen(int y) } } -void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border) +void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border, qboolean keepaspect) { vec3_t mins, maxs, extend; VectorCopy(mins_in, mins); @@ -330,17 +330,19 @@ void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border) // line compatible to nexuiz mapinfo Sys_Printf("size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); - VectorSubtract(maxs, mins, extend); - - if(extend[1] > extend[0]) + if(keepaspect) { - mins[0] -= (extend[1] - extend[0]) * 0.5; - maxs[0] += (extend[1] - extend[0]) * 0.5; - } - else - { - mins[1] -= (extend[0] - extend[1]) * 0.5; - maxs[1] += (extend[0] - extend[1]) * 0.5; + VectorSubtract(maxs, mins, extend); + if(extend[1] > extend[0]) + { + mins[0] -= (extend[1] - extend[0]) * 0.5; + maxs[0] += (extend[1] - extend[0]) * 0.5; + } + else + { + mins[1] -= (extend[0] - extend[1]) * 0.5; + maxs[1] += (extend[0] - extend[1]) * 0.5; + } } /* border: amount of black area around the image */ @@ -563,6 +565,7 @@ int MiniMapBSPMain( int argc, char **argv ) int x, y; int i; vec3_t mins, maxs; + qboolean keepaspect; /* arg checking */ if( argc < 2 ) @@ -588,6 +591,7 @@ int MiniMapBSPMain( int argc, char **argv ) minimapSharpen = game->miniMapSharpen; minimap.width = minimap.height = game->miniMapSize; border = game->miniMapBorder; + keepaspect = game->miniMapKeepAspect; minimap.samples = 1; minimap.sample_offsets = NULL; @@ -632,6 +636,16 @@ int MiniMapBSPMain( int argc, char **argv ) i++; Sys_Printf( "Border set to %f\n", border ); } + else if( !strcmp( argv[ i ], "-keepaspect" ) ) + { + keepaspect = qtrue; + Sys_Printf( "Keeping aspect ratio by letterboxing\n", border ); + } + else if( !strcmp( argv[ i ], "-nokeepaspect" ) ) + { + keepaspect = qfalse; + Sys_Printf( "Not keeping aspect ratio\n", border ); + } else if( !strcmp( argv[ i ], "-o" ) ) { strcpy(minimapFilename, argv[i + 1]); @@ -651,7 +665,7 @@ int MiniMapBSPMain( int argc, char **argv ) } } - MiniMapMakeMinsMaxs(mins, maxs, border); + MiniMapMakeMinsMaxs(mins, maxs, border, keepaspect); if(!*minimapFilename) { diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 2c074443..7045c92e 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -569,6 +569,7 @@ typedef struct game_s int miniMapSize; /* minimap size */ float miniMapSharpen; /* minimap sharpening coefficient */ float miniMapBorder; /* minimap border amount */ + qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */ char *miniMapNameFormat; /* minimap name format */ char *bspIdent; /* 4-letter bsp file prefix */ int bspVersion; /* bsp version to use */ From 75ba6b77ecfed253ca7e7ca4b0e2e2a751a11ad7 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 16:36:51 +0000 Subject: [PATCH 19/32] use "minimaps" directory for warsow git-svn-id: svn://svn.icculus.org/netradiant/trunk@346 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/game_qfusion.h | 2 +- tools/quake3/q3map2/main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index 838d87b9..b73be53f 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -117,7 +117,7 @@ 0.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qfalse, /* minimap keep aspect */ - "%s.tga", /* minimap name format */ + "../minimaps/%s.tga", /* minimap name format */ "FBSP", /* bsp file prefix */ 1, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 8553bc44..a864ff0a 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -735,6 +735,8 @@ int MiniMapBSPMain( int argc, char **argv ) } Sys_Printf( " writing to %s...", minimapFilename ); + ExtractFilePath(minimapFilename, path); + Q_mkdir(path); WriteTGA24(minimapFilename, data3b, minimap.width, minimap.height, qfalse); Sys_Printf( " done.\n" ); From 0375a83f2bce9f8f67525ca71b8c86c3b80a43e9 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 16:57:55 +0000 Subject: [PATCH 20/32] new modes for minimap: -black = black on transparent, -white = white on transparent, -gray = white on black git-svn-id: svn://svn.icculus.org/netradiant/trunk@347 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/common/imagelib.c | 20 ++++++ tools/quake3/common/imagelib.h | 1 + tools/quake3/q3map2/game_ef.h | 1 + tools/quake3/q3map2/game_etut.h | 1 + tools/quake3/q3map2/game_ja.h | 1 + tools/quake3/q3map2/game_jk2.h | 1 + tools/quake3/q3map2/game_nexuiz.h | 1 + tools/quake3/q3map2/game_qfusion.h | 1 + tools/quake3/q3map2/game_quake3.h | 1 + tools/quake3/q3map2/game_quakelive.h | 1 + tools/quake3/q3map2/game_sof2.h | 1 + tools/quake3/q3map2/game_tenebrae.h | 1 + tools/quake3/q3map2/game_tremulous.h | 1 + tools/quake3/q3map2/game_wolf.h | 1 + tools/quake3/q3map2/game_wolfet.h | 1 + tools/quake3/q3map2/main.c | 96 ++++++++++++++++++++++------ tools/quake3/q3map2/q3map2.h | 8 +++ 17 files changed, 117 insertions(+), 21 deletions(-) diff --git a/tools/quake3/common/imagelib.c b/tools/quake3/common/imagelib.c index b6fba38d..dfe16168 100644 --- a/tools/quake3/common/imagelib.c +++ b/tools/quake3/common/imagelib.c @@ -1169,6 +1169,26 @@ void WriteTGA( const char *filename, byte *data, int width, int height ) { free( buffer ); } +void WriteTGAGray (const char *filename, byte *data, int width, int height) { + byte buffer[18]; + int i; + int c; + FILE *f; + + memset (buffer, 0, 18); + buffer[2] = 3; // uncompressed type + buffer[12] = width&255; + buffer[13] = width>>8; + buffer[14] = height&255; + buffer[15] = height>>8; + buffer[16] = 8; // pixel size + + f = fopen (filename, "wb"); + fwrite (buffer, 1, 18, f); + fwrite (data, 1, width * height, f); + fclose (f); +} + /* ============================================================================ diff --git a/tools/quake3/common/imagelib.h b/tools/quake3/common/imagelib.h index 37277170..f313881a 100644 --- a/tools/quake3/common/imagelib.h +++ b/tools/quake3/common/imagelib.h @@ -40,5 +40,6 @@ void LoadTGA( const char *filename, byte **pixels, int *width, int *height ); void LoadTGABuffer( const byte *buffer, const byte* enddata, byte **pic, int *width, int *height ); void WriteTGA( const char *filename, byte *data, int width, int height ); int LoadJPGBuff( void *src_buffer, int src_size, unsigned char **pic, int *width, int *height ); +void WriteTGAGray (const char *filename, byte *data, int width, int height); void Load32BitImage( const char *name, unsigned **pixels, int *width, int *height ); diff --git a/tools/quake3/q3map2/game_ef.h b/tools/quake3/q3map2/game_ef.h index b37c3584..0a8168a0 100644 --- a/tools/quake3/q3map2/game_ef.h +++ b/tools/quake3/q3map2/game_ef.h @@ -118,6 +118,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_etut.h b/tools/quake3/q3map2/game_etut.h index d8609e10..1f0a8962 100644 --- a/tools/quake3/q3map2/game_etut.h +++ b/tools/quake3/q3map2/game_etut.h @@ -153,6 +153,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_ja.h b/tools/quake3/q3map2/game_ja.h index 8069ed31..f4778043 100644 --- a/tools/quake3/q3map2/game_ja.h +++ b/tools/quake3/q3map2/game_ja.h @@ -72,6 +72,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_jk2.h b/tools/quake3/q3map2/game_jk2.h index 410dc585..90351e0f 100644 --- a/tools/quake3/q3map2/game_jk2.h +++ b/tools/quake3/q3map2/game_jk2.h @@ -69,6 +69,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_nexuiz.h b/tools/quake3/q3map2/game_nexuiz.h index 8aed61d4..e79a386c 100644 --- a/tools/quake3/q3map2/game_nexuiz.h +++ b/tools/quake3/q3map2/game_nexuiz.h @@ -68,6 +68,7 @@ 1.0f, /* minimap sharpener */ 1.0f/66.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "../gfx/%s_mini.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index b73be53f..46ca4918 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -117,6 +117,7 @@ 0.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qfalse, /* minimap keep aspect */ + MINIMAP_MODE_WHITE, /* minimap mode */ "../minimaps/%s.tga", /* minimap name format */ "FBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_quake3.h b/tools/quake3/q3map2/game_quake3.h index 2065dce1..07a1c9a2 100644 --- a/tools/quake3/q3map2/game_quake3.h +++ b/tools/quake3/q3map2/game_quake3.h @@ -117,6 +117,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_quakelive.h b/tools/quake3/q3map2/game_quakelive.h index ec4c5622..78b1329d 100644 --- a/tools/quake3/q3map2/game_quakelive.h +++ b/tools/quake3/q3map2/game_quakelive.h @@ -81,6 +81,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_sof2.h b/tools/quake3/q3map2/game_sof2.h index 25b31975..91b26df4 100644 --- a/tools/quake3/q3map2/game_sof2.h +++ b/tools/quake3/q3map2/game_sof2.h @@ -144,6 +144,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "RBSP", /* bsp file prefix */ 1, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_tenebrae.h b/tools/quake3/q3map2/game_tenebrae.h index b2141848..57e45eca 100644 --- a/tools/quake3/q3map2/game_tenebrae.h +++ b/tools/quake3/q3map2/game_tenebrae.h @@ -117,6 +117,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_tremulous.h b/tools/quake3/q3map2/game_tremulous.h index 2ff8c8ac..0f6d050f 100644 --- a/tools/quake3/q3map2/game_tremulous.h +++ b/tools/quake3/q3map2/game_tremulous.h @@ -75,6 +75,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_wolf.h b/tools/quake3/q3map2/game_wolf.h index 21702502..6fed3761 100644 --- a/tools/quake3/q3map2/game_wolf.h +++ b/tools/quake3/q3map2/game_wolf.h @@ -134,6 +134,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/game_wolfet.h b/tools/quake3/q3map2/game_wolfet.h index aba6cb67..57151e29 100644 --- a/tools/quake3/q3map2/game_wolfet.h +++ b/tools/quake3/q3map2/game_wolfet.h @@ -71,6 +71,7 @@ 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 47, /* bsp file version */ diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index a864ff0a..a4e446d6 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -94,8 +94,6 @@ static void ExitQ3Map( void ){ /* minimap stuff */ -/* borrowed from light.c */ -void WriteTGA24( char *filename, byte *data, int width, int height, qboolean flip ); typedef struct minimap_s { bspModel_t *model; @@ -560,10 +558,11 @@ int MiniMapBSPMain( int argc, char **argv ) char relativeMinimapFilename[1024]; float minimapSharpen; float border; - byte *data3b, *p; + byte *data4b, *p; float *q; int x, y; int i; + miniMapMode_t mode; vec3_t mins, maxs; qboolean keepaspect; @@ -592,6 +591,7 @@ int MiniMapBSPMain( int argc, char **argv ) minimap.width = minimap.height = game->miniMapSize; border = game->miniMapBorder; keepaspect = game->miniMapKeepAspect; + mode = game->miniMapMode; minimap.samples = 1; minimap.sample_offsets = NULL; @@ -663,6 +663,21 @@ int MiniMapBSPMain( int argc, char **argv ) i += 6; Sys_Printf( "Map mins/maxs overridden\n" ); } + else if( !strcmp( argv[ i ], "-gray" ) ) + { + mode = MINIMAP_MODE_GRAY; + Sys_Printf( "Writing as white-on-black image\n" ); + } + else if( !strcmp( argv[ i ], "-black" ) ) + { + mode = MINIMAP_MODE_BLACK; + Sys_Printf( "Writing as black alpha image\n" ); + } + else if( !strcmp( argv[ i ], "-white" ) ) + { + mode = MINIMAP_MODE_WHITE; + Sys_Printf( "Writing as white alpha image\n" ); + } } MiniMapMakeMinsMaxs(mins, maxs, border, keepaspect); @@ -675,6 +690,8 @@ int MiniMapBSPMain( int argc, char **argv ) MergeRelativePath(minimapFilename, path, relativeMinimapFilename); Sys_Printf("Output file name automatically set to %s\n", minimapFilename); } + ExtractFilePath(minimapFilename, path); + Q_mkdir(path); if(minimapSharpen >= 0) { @@ -683,7 +700,7 @@ int MiniMapBSPMain( int argc, char **argv ) } minimap.data1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); - data3b = safe_malloc(minimap.width * minimap.height * 3); + data4b = safe_malloc(minimap.width * minimap.height * 4); if(minimapSharpen >= 0) minimap.sharpendata1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); @@ -720,24 +737,61 @@ int MiniMapBSPMain( int argc, char **argv ) } Sys_Printf( "\nConverting..."); - p = data3b; - for(y = 0; y < minimap.height; ++y) - for(x = 0; x < minimap.width; ++x) - { - byte b; - float v = *q++; - if(v < 0) v = 0; - if(v > 255.0/256.0) v = 255.0/256.0; - b = v * 256; - *p++ = b; - *p++ = b; - *p++ = b; - } - Sys_Printf( " writing to %s...", minimapFilename ); - ExtractFilePath(minimapFilename, path); - Q_mkdir(path); - WriteTGA24(minimapFilename, data3b, minimap.width, minimap.height, qfalse); + switch(mode) + { + case MINIMAP_MODE_GRAY: + p = data4b; + for(y = 0; y < minimap.height; ++y) + for(x = 0; x < minimap.width; ++x) + { + byte b; + float v = *q++; + if(v < 0) v = 0; + if(v > 255.0/256.0) v = 255.0/256.0; + b = v * 256; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGAGray(minimapFilename, data4b, minimap.width, minimap.height); + break; + case MINIMAP_MODE_BLACK: + p = data4b; + for(y = 0; y < minimap.height; ++y) + for(x = 0; x < minimap.width; ++x) + { + byte b; + float v = *q++; + if(v < 0) v = 0; + if(v > 255.0/256.0) v = 255.0/256.0; + b = v * 256; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA(minimapFilename, data4b, minimap.width, minimap.height); + break; + case MINIMAP_MODE_WHITE: + p = data4b; + for(y = 0; y < minimap.height; ++y) + for(x = 0; x < minimap.width; ++x) + { + byte b; + float v = *q++; + if(v < 0) v = 0; + if(v > 255.0/256.0) v = 255.0/256.0; + b = v * 256; + *p++ = 255; + *p++ = 255; + *p++ = 255; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA(minimapFilename, data4b, minimap.width, minimap.height); + break; + } Sys_Printf( " done.\n" ); diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 7045c92e..42c94659 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -549,6 +549,13 @@ typedef struct surfaceParm_s } surfaceParm_t; +typedef enum +{ + MINIMAP_MODE_GRAY, + MINIMAP_MODE_BLACK, + MINIMAP_MODE_WHITE +} +miniMapMode_t; typedef struct game_s { @@ -570,6 +577,7 @@ typedef struct game_s float miniMapSharpen; /* minimap sharpening coefficient */ float miniMapBorder; /* minimap border amount */ qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */ + miniMapMode_t miniMapMode; /* minimap mode */ char *miniMapNameFormat; /* minimap name format */ char *bspIdent; /* 4-letter bsp file prefix */ int bspVersion; /* bsp version to use */ From 9f8d3f0a00b04b768dea4e58a3dbb616087d7103 Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 17:20:32 +0000 Subject: [PATCH 21/32] minimap: -boost = contrast boost (like in darkplaces) git-svn-id: svn://svn.icculus.org/netradiant/trunk@348 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/main.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index a4e446d6..41e76030 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -103,6 +103,7 @@ typedef struct minimap_s float *sample_offsets; float sharpen_boxmult; float sharpen_centermult; + float boost; float *data1f; float *sharpendata1f; vec3_t mins, size; @@ -319,6 +320,17 @@ static void MiniMapSharpen(int y) } } +static void MiniMapContrastBoost(int y) +{ + int x; + float *q = &minimap.data1f[y * minimap.width]; + for(x = 0; x < minimap.width; ++x) + { + *q = *q * minimap.boost / ((minimap.boost - 1) * *q + 1); + ++q; + } +} + void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border, qboolean keepaspect) { vec3_t mins, maxs, extend; @@ -595,6 +607,7 @@ int MiniMapBSPMain( int argc, char **argv ) minimap.samples = 1; minimap.sample_offsets = NULL; + minimap.boost = 1.0; /* process arguments */ for( i = 1; i < (argc - 1); i++ ) @@ -678,6 +691,12 @@ int MiniMapBSPMain( int argc, char **argv ) mode = MINIMAP_MODE_WHITE; Sys_Printf( "Writing as white alpha image\n" ); } + else if( !strcmp( argv[ i ], "-boost" ) ) + { + minimap.boost = atof(argv[i + 1]); + i++; + Sys_Printf( "Contrast boost set to %f\n", minimap.boost ); + } } MiniMapMakeMinsMaxs(mins, maxs, border, keepaspect); @@ -725,6 +744,12 @@ int MiniMapBSPMain( int argc, char **argv ) } } + if(minimap.boost != 1.0) + { + Sys_Printf( "\n--- MiniMapContrastBoost (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapContrastBoost); + } + if(minimap.sharpendata1f) { Sys_Printf( "\n--- MiniMapSharpen (%d) ---\n", minimap.height ); From e0b28da14b3c79fa37e010cd95c4b4e6e205c3bb Mon Sep 17 00:00:00 2001 From: divverent Date: Mon, 27 Apr 2009 17:33:27 +0000 Subject: [PATCH 22/32] qfusion now keeps aspect too git-svn-id: svn://svn.icculus.org/netradiant/trunk@349 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/game_qfusion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index 46ca4918..6939b388 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -116,7 +116,7 @@ 512, /* minimap size */ 0.0f, /* minimap sharpener */ 0.0f, /* minimap border */ - qfalse, /* minimap keep aspect */ + qtrue, /* minimap keep aspect */ MINIMAP_MODE_WHITE, /* minimap mode */ "../minimaps/%s.tga", /* minimap name format */ "FBSP", /* bsp file prefix */ From 2eb4247587b4252b26c8b937f4245d65e43ef420 Mon Sep 17 00:00:00 2001 From: divverent Date: Wed, 29 Apr 2009 15:54:29 +0000 Subject: [PATCH 23/32] use warsow defaults for minimap in qfusion game git-svn-id: svn://svn.icculus.org/netradiant/trunk@356 61c419a2-8eb2-4b30-bcec-8cead039b335 --- tools/quake3/q3map2/game_qfusion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/game_qfusion.h b/tools/quake3/q3map2/game_qfusion.h index 6939b388..9ddebdc1 100644 --- a/tools/quake3/q3map2/game_qfusion.h +++ b/tools/quake3/q3map2/game_qfusion.h @@ -113,8 +113,8 @@ 512, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ - 512, /* minimap size */ - 0.0f, /* minimap sharpener */ + 256, /* minimap size */ + 1.0f, /* minimap sharpener */ 0.0f, /* minimap border */ qtrue, /* minimap keep aspect */ MINIMAP_MODE_WHITE, /* minimap mode */ From 4d47b8ed5b5924f3ed7ffe29f882b741f2a10e63 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 9 Dec 2011 16:18:17 +0100 Subject: [PATCH 24/32] -autolevel for minimap --- tools/quake3/q3map2/main.c | 79 +++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 41e76030..9bad6044 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -103,7 +103,7 @@ typedef struct minimap_s float *sample_offsets; float sharpen_boxmult; float sharpen_centermult; - float boost; + float boost, brightness, contrast; float *data1f; float *sharpendata1f; vec3_t mins, size; @@ -331,6 +331,17 @@ static void MiniMapContrastBoost(int y) } } +static void MiniMapBrightnessContrast(int y) +{ + int x; + float *q = &minimap.data1f[y * minimap.width]; + for(x = 0; x < minimap.width; ++x) + { + *q = *q * minimap.contrast + minimap.brightness; + ++q; + } +} + void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border, qboolean keepaspect) { vec3_t mins, maxs, extend; @@ -568,6 +579,7 @@ int MiniMapBSPMain( int argc, char **argv ) char basename[1024]; char path[1024]; char relativeMinimapFilename[1024]; + qboolean autolevel; float minimapSharpen; float border; byte *data4b, *p; @@ -605,9 +617,12 @@ int MiniMapBSPMain( int argc, char **argv ) keepaspect = game->miniMapKeepAspect; mode = game->miniMapMode; + autolevel = qfalse; minimap.samples = 1; minimap.sample_offsets = NULL; minimap.boost = 1.0; + minimap.brightness = 0.0; + minimap.contrast = 1.0; /* process arguments */ for( i = 1; i < (argc - 1); i++ ) @@ -691,12 +706,34 @@ int MiniMapBSPMain( int argc, char **argv ) mode = MINIMAP_MODE_WHITE; Sys_Printf( "Writing as white alpha image\n" ); } - else if( !strcmp( argv[ i ], "-boost" ) ) + else if( !strcmp( argv[ i ], "-boost" ) && i < (argc - 2) ) { minimap.boost = atof(argv[i + 1]); i++; Sys_Printf( "Contrast boost set to %f\n", minimap.boost ); } + else if( !strcmp( argv[ i ], "-brightness" ) && i < (argc - 2) ) + { + minimap.brightness = atof(argv[i + 1]); + i++; + Sys_Printf( "Brightness set to %f\n", minimap.brightness ); + } + else if( !strcmp( argv[ i ], "-contrast" ) && i < (argc - 2) ) + { + minimap.contrast = atof(argv[i + 1]); + i++; + Sys_Printf( "Contrast set to %f\n", minimap.contrast ); + } + else if( !strcmp( argv[ i ], "-autolevel" ) ) + { + autolevel = qtrue; + Sys_Printf( "Auto level enabled\n", border ); + } + else if( !strcmp( argv[ i ], "-noautolevel" ) ) + { + autolevel = qfalse; + Sys_Printf( "Auto level disabled\n", border ); + } } MiniMapMakeMinsMaxs(mins, maxs, border, keepaspect); @@ -750,6 +787,44 @@ int MiniMapBSPMain( int argc, char **argv ) RunThreadsOnIndividual(minimap.height, qtrue, MiniMapContrastBoost); } + if(autolevel) + { + Sys_Printf( "\n--- MiniMapAutoLevel (%d) ---\n", minimap.height ); + float mi = 1, ma = 0; + float s, o; + + // TODO threads! + for(y = 0; y < minimap.height; ++y) + for(x = 0; x < minimap.width; ++x) + { + float v = *q++; + if(v < mi) + mi = v; + if(v > ma) + ma = v; + } + s = 1 / (ma - mi); + o = mi / (ma - mi); + + // equations: + // brightness + contrast * v + // after autolevel: + // brightness + contrast * (v * s - o) + // = + // (brightness - contrast * o) + (contrast * s) * v + minimap.brightness = minimap.brightness - minimap.contrast * o; + minimap.contrast *= s; + + Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.boost ); + Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); + } + + if(minimap.brightness != 0 || minimap.contrast != 1) + { + Sys_Printf( "\n--- MiniMapBrightnessContrast (%d) ---\n", minimap.height ); + RunThreadsOnIndividual(minimap.height, qtrue, MiniMapBrightnessContrast); + } + if(minimap.sharpendata1f) { Sys_Printf( "\n--- MiniMapSharpen (%d) ---\n", minimap.height ); From e089323ef23aebdbfb6ab4b0030cd5a1ed9bbb93 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 9 Dec 2011 16:36:07 +0100 Subject: [PATCH 25/32] PROPERLY ignore sky brushes for minimap --- tools/quake3/q3map2/light_ydnar.c | 16 +++++--- tools/quake3/q3map2/main.c | 65 ++----------------------------- tools/quake3/q3map2/q3map2.h | 1 + 3 files changed, 15 insertions(+), 67 deletions(-) diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 117167c2..4bfbd1da 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -2774,15 +2774,16 @@ void IlluminateVertexes( int num ){ determines opaque brushes in the world and find sky shaders for sunlight calculations */ -void SetupBrushes( void ){ +void SetupBrushesFlags( int mask, int test ) +{ int i, j, b, compileFlags; qboolean inside; bspBrush_t *brush; bspBrushSide_t *side; bspShader_t *shader; shaderInfo_t *si; - - + + /* note it */ Sys_FPrintf( SYS_VRB, "--- SetupBrushes ---\n" ); @@ -2822,8 +2823,9 @@ void SetupBrushes( void ){ } /* determine if this brush is opaque to light */ - if ( !( compileFlags & C_TRANSLUCENT ) ) { - opaqueBrushes[ b >> 3 ] |= ( 1 << ( b & 7 ) ); + if( (compileFlags & mask) == test ) + { + opaqueBrushes[ b >> 3 ] |= (1 << (b & 7)); numOpaqueBrushes++; maxOpaqueBrush = i; } @@ -2832,6 +2834,10 @@ void SetupBrushes( void ){ /* emit some statistics */ Sys_FPrintf( SYS_VRB, "%9d opaque brushes\n", numOpaqueBrushes ); } +void SetupBrushes( void ) +{ + SetupBrushesFlags(C_TRANSLUCENT, 0); +} diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 9bad6044..b1d5a547 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -389,67 +389,7 @@ determines solid non-sky brushes in the world void MiniMapSetupBrushes( void ) { - int i, b, compileFlags; - bspBrush_t *brush; - bspShader_t *shader; - shaderInfo_t *si; - - - /* note it */ - Sys_FPrintf( SYS_VRB, "--- MiniMapSetupBrushes ---\n" ); - - /* allocate */ - if( opaqueBrushes == NULL ) - opaqueBrushes = safe_malloc( numBSPBrushes / 8 + 1 ); - - /* clear */ - memset( opaqueBrushes, 0, numBSPBrushes / 8 + 1 ); - numOpaqueBrushes = 0; - - /* walk the list of worldspawn brushes */ - for( i = 0; i < minimap.model->numBSPBrushes; i++ ) - { - /* get brush */ - b = minimap.model->firstBSPBrush + i; - brush = &bspBrushes[ b ]; - -#if 0 - /* check all sides */ - compileFlags = 0; - for( j = 0; j < brush->numSides; j++ ) - { - /* do bsp shader calculations */ - side = &bspBrushSides[ brush->firstSide + j ]; - shader = &bspShaders[ side->shaderNum ]; - - /* get shader info */ - si = ShaderInfoForShader( shader->shader ); - if( si == NULL ) - continue; - - /* or together compile flags */ - compileFlags |= si->compileFlags; - } -#else - shader = &bspShaders[ brush->shaderNum ]; - si = ShaderInfoForShader( shader->shader ); - if( si == NULL ) - compileFlags = 0; - else - compileFlags = si->compileFlags; -#endif - - /* determine if this brush is solid */ - if( (compileFlags & (C_SOLID | C_SKY)) == C_SOLID ) - { - opaqueBrushes[ b >> 3 ] |= (1 << (b & 7)); - numOpaqueBrushes++; - maxOpaqueBrush = i; - } - } - - /* emit some statistics */ - Sys_FPrintf( SYS_VRB, "%9d solid brushes\n", numOpaqueBrushes ); + SetupBrushesFlags(C_SOLID | C_SKY, C_SOLID); } qboolean MiniMapEvaluateSampleOffsets(int *bestj, int *bestk, float *bestval) @@ -794,6 +734,7 @@ int MiniMapBSPMain( int argc, char **argv ) float s, o; // TODO threads! + q = minimap.data1f; for(y = 0; y < minimap.height; ++y) for(x = 0; x < minimap.width; ++x) { @@ -815,7 +756,7 @@ int MiniMapBSPMain( int argc, char **argv ) minimap.brightness = minimap.brightness - minimap.contrast * o; minimap.contrast *= s; - Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.boost ); + Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.brightness ); Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 42c94659..08e9b1c8 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1764,6 +1764,7 @@ void DirtyRawLightmap( int num ); void IlluminateRawLightmap( int num ); void IlluminateVertexes( int num ); +void SetupBrushesFlags( int mask, int test ); void SetupBrushes( void ); void SetupClusters( void ); qboolean ClusterVisible( int a, int b ); From 30813878774343fade9c88f957a8e4407e0d2584 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 9 Dec 2011 17:15:51 +0100 Subject: [PATCH 26/32] properly ignore caulk --- tools/quake3/q3map2/light_ydnar.c | 12 ++++++----- tools/quake3/q3map2/main.c | 34 +++++++++++++++++++------------ tools/quake3/q3map2/q3map2.h | 3 ++- tools/quake3/q3map2/shaders.c | 6 ++++++ 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 4bfbd1da..d2d0f9da 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -2774,9 +2774,10 @@ void IlluminateVertexes( int num ){ determines opaque brushes in the world and find sky shaders for sunlight calculations */ -void SetupBrushesFlags( int mask, int test ) +void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned int mask_all, unsigned int test_all ) { - int i, j, b, compileFlags; + int i, j, b; + unsigned int compileFlags, allCompileFlags; qboolean inside; bspBrush_t *brush; bspBrushSide_t *side; @@ -2806,6 +2807,7 @@ void SetupBrushesFlags( int mask, int test ) /* check all sides */ inside = qtrue; compileFlags = 0; + allCompileFlags = ~(0u); for ( j = 0; j < brush->numSides && inside; j++ ) { /* do bsp shader calculations */ @@ -2813,7 +2815,7 @@ void SetupBrushesFlags( int mask, int test ) shader = &bspShaders[ side->shaderNum ]; /* get shader info */ - si = ShaderInfoForShader( shader->shader ); + si = ShaderInfoForShaderNull( shader->shader ); if ( si == NULL ) { continue; } @@ -2823,7 +2825,7 @@ void SetupBrushesFlags( int mask, int test ) } /* determine if this brush is opaque to light */ - if( (compileFlags & mask) == test ) + if( (compileFlags & mask_any) == test_any && (allCompileFlags & mask_all) == test_all ) { opaqueBrushes[ b >> 3 ] |= (1 << (b & 7)); numOpaqueBrushes++; @@ -2836,7 +2838,7 @@ void SetupBrushesFlags( int mask, int test ) } void SetupBrushes( void ) { - SetupBrushesFlags(C_TRANSLUCENT, 0); + SetupBrushesFlags(C_TRANSLUCENT, 0, 0, 0); } diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index b1d5a547..6b85c3d2 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -389,7 +389,10 @@ determines solid non-sky brushes in the world void MiniMapSetupBrushes( void ) { - SetupBrushesFlags(C_SOLID | C_SKY, C_SOLID); + SetupBrushesFlags(C_SOLID | C_SKY, C_SOLID, C_NODRAW, 0); + // at least one must be solid + // none may be sky + // not all may be nodraw } qboolean MiniMapEvaluateSampleOffsets(int *bestj, int *bestk, float *bestval) @@ -744,20 +747,25 @@ int MiniMapBSPMain( int argc, char **argv ) if(v > ma) ma = v; } - s = 1 / (ma - mi); - o = mi / (ma - mi); + if(ma > mi) + { + s = 1 / (ma - mi); + o = mi / (ma - mi); - // equations: - // brightness + contrast * v - // after autolevel: - // brightness + contrast * (v * s - o) - // = - // (brightness - contrast * o) + (contrast * s) * v - minimap.brightness = minimap.brightness - minimap.contrast * o; - minimap.contrast *= s; + // equations: + // brightness + contrast * v + // after autolevel: + // brightness + contrast * (v * s - o) + // = + // (brightness - contrast * o) + (contrast * s) * v + minimap.brightness = minimap.brightness - minimap.contrast * o; + minimap.contrast *= s; - Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.brightness ); - Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); + Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.brightness ); + Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); + } + else + Sys_Printf( "Auto level: failed because all pixels are the same value\n" ); } if(minimap.brightness != 0 || minimap.contrast != 1) diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 08e9b1c8..ffb056ab 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1764,7 +1764,7 @@ void DirtyRawLightmap( int num ); void IlluminateRawLightmap( int num ); void IlluminateVertexes( int num ); -void SetupBrushesFlags( int mask, int test ); +void SetupBrushesFlags( int mask_any, int test_any, int mask_all, int test_all ); void SetupBrushes( void ); void SetupClusters( void ); qboolean ClusterVisible( int a, int b ); @@ -1820,6 +1820,7 @@ void EmitVertexRemapShader( char *from, char *to ); void LoadShaderInfo( void ); shaderInfo_t *ShaderInfoForShader( const char *shader ); +shaderInfo_t *ShaderInfoForShaderNull( const char *shader ); /* bspfile_abstract.c */ diff --git a/tools/quake3/q3map2/shaders.c b/tools/quake3/q3map2/shaders.c index 153f3daa..dfbc7f19 100644 --- a/tools/quake3/q3map2/shaders.c +++ b/tools/quake3/q3map2/shaders.c @@ -801,6 +801,12 @@ static void LoadShaderImages( shaderInfo_t *si ){ finds a shaderinfo for a named shader */ +shaderInfo_t *ShaderInfoForShaderNull( const char *shaderName ){ + if(!strcmp(shaderName, "noshader")) + return NULL; + return ShaderInfoForShader(shaderName); +} + shaderInfo_t *ShaderInfoForShader( const char *shaderName ){ int i; shaderInfo_t *si; From d590a482aafcd02836e8d8011584f917819e5e01 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 9 Dec 2011 17:17:31 +0100 Subject: [PATCH 27/32] no, we do NOT want to ignore caulk --- tools/quake3/q3map2/light_ydnar.c | 2 ++ tools/quake3/q3map2/main.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index d2d0f9da..6c5a82e4 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -2824,6 +2824,8 @@ void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned i compileFlags |= si->compileFlags; } + Sys_FPrintf( SYS_VRB, "flags: %d (all: %d)\n", compileFlags, allCompileFlags ); + /* determine if this brush is opaque to light */ if( (compileFlags & mask_any) == test_any && (allCompileFlags & mask_all) == test_all ) { diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 6b85c3d2..d0076999 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -389,7 +389,7 @@ determines solid non-sky brushes in the world void MiniMapSetupBrushes( void ) { - SetupBrushesFlags(C_SOLID | C_SKY, C_SOLID, C_NODRAW, 0); + SetupBrushesFlags(C_SOLID | C_SKY, C_SOLID, 0, 0); // at least one must be solid // none may be sky // not all may be nodraw From 83ff5cf016ad81ebd590765490177af66eb0f17c Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 9 Dec 2011 17:24:33 +0100 Subject: [PATCH 28/32] mark two shader checks nullable --- tools/quake3/q3map2/fog.c | 2 +- tools/quake3/q3map2/light_trace.c | 2 +- tools/quake3/q3map2/light_ydnar.c | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/quake3/q3map2/fog.c b/tools/quake3/q3map2/fog.c index 1b23bad2..35e288ba 100644 --- a/tools/quake3/q3map2/fog.c +++ b/tools/quake3/q3map2/fog.c @@ -787,7 +787,7 @@ void CreateMapFogs( void ){ /* set up fog */ fog = &mapFogs[ numMapFogs++ ]; - fog->si = ShaderInfoForShader( globalFog ); + fog->si = ShaderInfoForShaderNull( globalFog ); if ( fog->si == NULL ) { Error( "Invalid shader \"%s\" referenced trying to add global fog", globalFog ); } diff --git a/tools/quake3/q3map2/light_trace.c b/tools/quake3/q3map2/light_trace.c index cc27fcc3..5fe77d07 100644 --- a/tools/quake3/q3map2/light_trace.c +++ b/tools/quake3/q3map2/light_trace.c @@ -1094,7 +1094,7 @@ static void PopulateWithPicoModel( int castShadows, picoModel_t *model, m4x4_t t if ( shader == NULL ) { continue; } - ti.si = ShaderInfoForShader( PicoGetShaderName( shader ) ); + ti.si = ShaderInfoForShaderNull( PicoGetShaderName( shader ) ); if ( ti.si == NULL ) { continue; } diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 6c5a82e4..d2d0f9da 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -2824,8 +2824,6 @@ void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned i compileFlags |= si->compileFlags; } - Sys_FPrintf( SYS_VRB, "flags: %d (all: %d)\n", compileFlags, allCompileFlags ); - /* determine if this brush is opaque to light */ if( (compileFlags & mask_any) == test_any && (allCompileFlags & mask_all) == test_all ) { From 18f8b3a7f4b408eb7166735d1ab8b05b2ce0445b Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 20 Jul 2015 12:57:09 +0200 Subject: [PATCH 29/32] split minimap stuff from q3map2 --- tools/quake3/q3map2/main.c | 756 --------------------------------- tools/quake3/q3map2/minimap.c | 779 ++++++++++++++++++++++++++++++++++ tools/quake3/q3map2/q3map2.h | 2 + 3 files changed, 781 insertions(+), 756 deletions(-) create mode 100644 tools/quake3/q3map2/minimap.c diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index d0076999..802200c6 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -92,762 +92,6 @@ static void ExitQ3Map( void ){ } -/* minimap stuff */ - -typedef struct minimap_s -{ - bspModel_t *model; - int width; - int height; - int samples; - float *sample_offsets; - float sharpen_boxmult; - float sharpen_centermult; - float boost, brightness, contrast; - float *data1f; - float *sharpendata1f; - vec3_t mins, size; -} -minimap_t; -static minimap_t minimap; - -qboolean BrushIntersectionWithLine(bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out) -{ - int i; - qboolean in = qfalse, out = qfalse; - bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; - - for(i = 0; i < brush->numSides; ++i) - { - bspPlane_t *p = &bspPlanes[sides[i].planeNum]; - float sn = DotProduct(start, p->normal); - float dn = DotProduct(dir, p->normal); - if(dn == 0) - { - if(sn > p->dist) - return qfalse; // outside! - } - else - { - float t = (p->dist - sn) / dn; - if(dn < 0) - { - if(!in || t > *t_in) - { - *t_in = t; - in = qtrue; - // as t_in can only increase, and t_out can only decrease, early out - if(out && *t_in >= *t_out) - return qfalse; - } - } - else - { - if(!out || t < *t_out) - { - *t_out = t; - out = qtrue; - // as t_in can only increase, and t_out can only decrease, early out - if(in && *t_in >= *t_out) - return qfalse; - } - } - } - } - return in && out; -} - -static float MiniMapSample(float x, float y) -{ - vec3_t org, dir; - int i, bi; - float t0, t1; - float samp; - bspBrush_t *b; - bspBrushSide_t *s; - int cnt; - - org[0] = x; - org[1] = y; - org[2] = 0; - dir[0] = 0; - dir[1] = 0; - dir[2] = 1; - - cnt = 0; - samp = 0; - for(i = 0; i < minimap.model->numBSPBrushes; ++i) - { - bi = minimap.model->firstBSPBrush + i; - if(opaqueBrushes[bi >> 3] & (1 << (bi & 7))) - { - b = &bspBrushes[bi]; - - // sort out mins/maxs of the brush - s = &bspBrushSides[b->firstSide]; - if(x < -bspPlanes[s[0].planeNum].dist) - continue; - if(x > +bspPlanes[s[1].planeNum].dist) - continue; - if(y < -bspPlanes[s[2].planeNum].dist) - continue; - if(y > +bspPlanes[s[3].planeNum].dist) - continue; - - if(BrushIntersectionWithLine(b, org, dir, &t0, &t1)) - { - samp += t1 - t0; - ++cnt; - } - } - } - - return samp; -} - -void RandomVector2f(float v[2]) -{ - do - { - v[0] = 2 * Random() - 1; - v[1] = 2 * Random() - 1; - } - while(v[0] * v[0] + v[1] * v[1] > 1); -} - -static void MiniMapRandomlySupersampled(int y) -{ - int x, i; - float *p = &minimap.data1f[y * minimap.width]; - float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); - float dx = minimap.size[0] / (float) minimap.width; - float dy = minimap.size[1] / (float) minimap.height; - float uv[2]; - float thisval; - - for(x = 0; x < minimap.width; ++x) - { - float xmin = minimap.mins[0] + minimap.size[0] * (x / (float) minimap.width); - float val = 0; - - for(i = 0; i < minimap.samples; ++i) - { - RandomVector2f(uv); - thisval = MiniMapSample( - xmin + (uv[0] + 0.5) * dx, /* exaggerated random pattern for better results */ - ymin + (uv[1] + 0.5) * dy /* exaggerated random pattern for better results */ - ); - val += thisval; - } - val /= minimap.samples * minimap.size[2]; - *p++ = val; - } -} - -static void MiniMapSupersampled(int y) -{ - int x, i; - float *p = &minimap.data1f[y * minimap.width]; - float ymin = minimap.mins[1] + minimap.size[1] * (y / (float) minimap.height); - float dx = minimap.size[0] / (float) minimap.width; - float dy = minimap.size[1] / (float) minimap.height; - - for(x = 0; x < minimap.width; ++x) - { - float xmin = minimap.mins[0] + minimap.size[0] * (x / (float) minimap.width); - float val = 0; - - for(i = 0; i < minimap.samples; ++i) - { - float thisval = MiniMapSample( - xmin + minimap.sample_offsets[2*i+0] * dx, - ymin + minimap.sample_offsets[2*i+1] * dy - ); - val += thisval; - } - val /= minimap.samples * minimap.size[2]; - *p++ = val; - } -} - -static void MiniMapNoSupersampling(int y) -{ - int x; - float *p = &minimap.data1f[y * minimap.width]; - float ymin = minimap.mins[1] + minimap.size[1] * ((y + 0.5) / (float) minimap.height); - - for(x = 0; x < minimap.width; ++x) - { - float xmin = minimap.mins[0] + minimap.size[0] * ((x + 0.5) / (float) minimap.width); - *p++ = MiniMapSample(xmin, ymin) / minimap.size[2]; - } -} - -static void MiniMapSharpen(int y) -{ - int x; - qboolean up = (y > 0); - qboolean down = (y < minimap.height - 1); - float *p = &minimap.data1f[y * minimap.width]; - float *q = &minimap.sharpendata1f[y * minimap.width]; - - for(x = 0; x < minimap.width; ++x) - { - qboolean left = (x > 0); - qboolean right = (x < minimap.width - 1); - float val = p[0] * minimap.sharpen_centermult; - - if(left && up) - val += p[-1 -minimap.width] * minimap.sharpen_boxmult; - if(left && down) - val += p[-1 +minimap.width] * minimap.sharpen_boxmult; - if(right && up) - val += p[+1 -minimap.width] * minimap.sharpen_boxmult; - if(right && down) - val += p[+1 +minimap.width] * minimap.sharpen_boxmult; - - if(left) - val += p[-1] * minimap.sharpen_boxmult; - if(right) - val += p[+1] * minimap.sharpen_boxmult; - if(up) - val += p[-minimap.width] * minimap.sharpen_boxmult; - if(down) - val += p[+minimap.width] * minimap.sharpen_boxmult; - - ++p; - *q++ = val; - } -} - -static void MiniMapContrastBoost(int y) -{ - int x; - float *q = &minimap.data1f[y * minimap.width]; - for(x = 0; x < minimap.width; ++x) - { - *q = *q * minimap.boost / ((minimap.boost - 1) * *q + 1); - ++q; - } -} - -static void MiniMapBrightnessContrast(int y) -{ - int x; - float *q = &minimap.data1f[y * minimap.width]; - for(x = 0; x < minimap.width; ++x) - { - *q = *q * minimap.contrast + minimap.brightness; - ++q; - } -} - -void MiniMapMakeMinsMaxs(vec3_t mins_in, vec3_t maxs_in, float border, qboolean keepaspect) -{ - vec3_t mins, maxs, extend; - VectorCopy(mins_in, mins); - VectorCopy(maxs_in, maxs); - - // line compatible to nexuiz mapinfo - Sys_Printf("size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); - - if(keepaspect) - { - VectorSubtract(maxs, mins, extend); - if(extend[1] > extend[0]) - { - mins[0] -= (extend[1] - extend[0]) * 0.5; - maxs[0] += (extend[1] - extend[0]) * 0.5; - } - else - { - mins[1] -= (extend[0] - extend[1]) * 0.5; - maxs[1] += (extend[0] - extend[1]) * 0.5; - } - } - - /* border: amount of black area around the image */ - /* input: border, 1-2*border, border but we need border/(1-2*border) */ - - VectorSubtract(maxs, mins, extend); - VectorScale(extend, border / (1 - 2 * border), extend); - - VectorSubtract(mins, extend, mins); - VectorAdd(maxs, extend, maxs); - - VectorCopy(mins, minimap.mins); - VectorSubtract(maxs, mins, minimap.size); - - // line compatible to nexuiz mapinfo - Sys_Printf("size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); -} - -/* -MiniMapSetupBrushes() -determines solid non-sky brushes in the world -*/ - -void MiniMapSetupBrushes( void ) -{ - SetupBrushesFlags(C_SOLID | C_SKY, C_SOLID, 0, 0); - // at least one must be solid - // none may be sky - // not all may be nodraw -} - -qboolean MiniMapEvaluateSampleOffsets(int *bestj, int *bestk, float *bestval) -{ - float val, dx, dy; - int j, k; - - *bestj = *bestk = -1; - *bestval = 3; /* max possible val is 2 */ - - for(j = 0; j < minimap.samples; ++j) - for(k = j + 1; k < minimap.samples; ++k) - { - dx = minimap.sample_offsets[2*j+0] - minimap.sample_offsets[2*k+0]; - dy = minimap.sample_offsets[2*j+1] - minimap.sample_offsets[2*k+1]; - if(dx > +0.5) dx -= 1; - if(dx < -0.5) dx += 1; - if(dy > +0.5) dy -= 1; - if(dy < -0.5) dy += 1; - val = dx * dx + dy * dy; - if(val < *bestval) - { - *bestj = j; - *bestk = k; - *bestval = val; - } - } - - return *bestval < 3; -} - -void MiniMapMakeSampleOffsets() -{ - int i, j, k, jj, kk; - float val, valj, valk, sx, sy, rx, ry; - - Sys_Printf( "Generating good sample offsets (this may take a while)...\n" ); - - /* start with entirely random samples */ - for(i = 0; i < minimap.samples; ++i) - { - minimap.sample_offsets[2*i+0] = Random(); - minimap.sample_offsets[2*i+1] = Random(); - } - - for(i = 0; i < 1000; ++i) - { - if(MiniMapEvaluateSampleOffsets(&j, &k, &val)) - { - sx = minimap.sample_offsets[2*j+0]; - sy = minimap.sample_offsets[2*j+1]; - minimap.sample_offsets[2*j+0] = rx = Random(); - minimap.sample_offsets[2*j+1] = ry = Random(); - if(!MiniMapEvaluateSampleOffsets(&jj, &kk, &valj)) - valj = -1; - minimap.sample_offsets[2*j+0] = sx; - minimap.sample_offsets[2*j+1] = sy; - - sx = minimap.sample_offsets[2*k+0]; - sy = minimap.sample_offsets[2*k+1]; - minimap.sample_offsets[2*k+0] = rx; - minimap.sample_offsets[2*k+1] = ry; - if(!MiniMapEvaluateSampleOffsets(&jj, &kk, &valk)) - valk = -1; - minimap.sample_offsets[2*k+0] = sx; - minimap.sample_offsets[2*k+1] = sy; - - if(valj > valk) - { - if(valj > val) - { - /* valj is the greatest */ - minimap.sample_offsets[2*j+0] = rx; - minimap.sample_offsets[2*j+1] = ry; - i = -1; - } - else - { - /* valj is the greater and it is useless - forget it */ - } - } - else - { - if(valk > val) - { - /* valk is the greatest */ - minimap.sample_offsets[2*k+0] = rx; - minimap.sample_offsets[2*k+1] = ry; - i = -1; - } - else - { - /* valk is the greater and it is useless - forget it */ - } - } - } - else - break; - } -} - -void MergeRelativePath(char *out, const char *absolute, const char *relative) -{ - const char *endpos = absolute + strlen(absolute); - while(endpos != absolute && (endpos[-1] == '/' || endpos[-1] == '\\')) - --endpos; - while(relative[0] == '.' && relative[1] == '.' && (relative[2] == '/' || relative[2] == '\\')) - { - relative += 3; - while(endpos != absolute) - { - --endpos; - if(*endpos == '/' || *endpos == '\\') - break; - } - while(endpos != absolute && (endpos[-1] == '/' || endpos[-1] == '\\')) - --endpos; - } - memcpy(out, absolute, endpos - absolute); - out[endpos - absolute] = '/'; - strcpy(out + (endpos - absolute + 1), relative); -} - -int MiniMapBSPMain( int argc, char **argv ) -{ - char minimapFilename[1024]; - char basename[1024]; - char path[1024]; - char relativeMinimapFilename[1024]; - qboolean autolevel; - float minimapSharpen; - float border; - byte *data4b, *p; - float *q; - int x, y; - int i; - miniMapMode_t mode; - vec3_t mins, maxs; - qboolean keepaspect; - - /* arg checking */ - if( argc < 2 ) - { - Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen f] [-samples n | -random n] [-o filename.tga] [-minmax Xmin Ymin Zmin Xmax Ymax Zmax] \n" ); - return 0; - } - - /* load the BSP first */ - strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); - StripExtension( source ); - DefaultExtension( source, ".bsp" ); - Sys_Printf( "Loading %s\n", source ); - BeginMapShaderFile( source ); - LoadShaderInfo(); - LoadBSPFile( source ); - - minimap.model = &bspModels[0]; - VectorCopy(minimap.model->mins, mins); - VectorCopy(minimap.model->maxs, maxs); - - *minimapFilename = 0; - minimapSharpen = game->miniMapSharpen; - minimap.width = minimap.height = game->miniMapSize; - border = game->miniMapBorder; - keepaspect = game->miniMapKeepAspect; - mode = game->miniMapMode; - - autolevel = qfalse; - minimap.samples = 1; - minimap.sample_offsets = NULL; - minimap.boost = 1.0; - minimap.brightness = 0.0; - minimap.contrast = 1.0; - - /* process arguments */ - for( i = 1; i < (argc - 1); i++ ) - { - if( !strcmp( argv[ i ], "-size" ) ) - { - minimap.width = minimap.height = atoi(argv[i + 1]); - i++; - Sys_Printf( "Image size set to %i\n", minimap.width ); - } - else if( !strcmp( argv[ i ], "-sharpen" ) ) - { - minimapSharpen = atof(argv[i + 1]); - i++; - Sys_Printf( "Sharpening coefficient set to %f\n", minimapSharpen ); - } - else if( !strcmp( argv[ i ], "-samples" ) ) - { - minimap.samples = atoi(argv[i + 1]); - i++; - Sys_Printf( "Samples set to %i\n", minimap.samples ); - if(minimap.sample_offsets) - free(minimap.sample_offsets); - minimap.sample_offsets = malloc(2 * sizeof(*minimap.sample_offsets) * minimap.samples); - MiniMapMakeSampleOffsets(); - } - else if( !strcmp( argv[ i ], "-random" ) ) - { - minimap.samples = atoi(argv[i + 1]); - i++; - Sys_Printf( "Random samples set to %i\n", minimap.samples ); - if(minimap.sample_offsets) - free(minimap.sample_offsets); - minimap.sample_offsets = NULL; - } - else if( !strcmp( argv[ i ], "-border" ) ) - { - border = atof(argv[i + 1]); - i++; - Sys_Printf( "Border set to %f\n", border ); - } - else if( !strcmp( argv[ i ], "-keepaspect" ) ) - { - keepaspect = qtrue; - Sys_Printf( "Keeping aspect ratio by letterboxing\n", border ); - } - else if( !strcmp( argv[ i ], "-nokeepaspect" ) ) - { - keepaspect = qfalse; - Sys_Printf( "Not keeping aspect ratio\n", border ); - } - else if( !strcmp( argv[ i ], "-o" ) ) - { - strcpy(minimapFilename, argv[i + 1]); - i++; - Sys_Printf( "Output file name set to %s\n", minimapFilename ); - } - else if( !strcmp( argv[ i ], "-minmax" ) && i < (argc - 7) ) - { - mins[0] = atof(argv[i + 1]); - mins[1] = atof(argv[i + 2]); - mins[2] = atof(argv[i + 3]); - maxs[0] = atof(argv[i + 4]); - maxs[1] = atof(argv[i + 5]); - maxs[2] = atof(argv[i + 6]); - i += 6; - Sys_Printf( "Map mins/maxs overridden\n" ); - } - else if( !strcmp( argv[ i ], "-gray" ) ) - { - mode = MINIMAP_MODE_GRAY; - Sys_Printf( "Writing as white-on-black image\n" ); - } - else if( !strcmp( argv[ i ], "-black" ) ) - { - mode = MINIMAP_MODE_BLACK; - Sys_Printf( "Writing as black alpha image\n" ); - } - else if( !strcmp( argv[ i ], "-white" ) ) - { - mode = MINIMAP_MODE_WHITE; - Sys_Printf( "Writing as white alpha image\n" ); - } - else if( !strcmp( argv[ i ], "-boost" ) && i < (argc - 2) ) - { - minimap.boost = atof(argv[i + 1]); - i++; - Sys_Printf( "Contrast boost set to %f\n", minimap.boost ); - } - else if( !strcmp( argv[ i ], "-brightness" ) && i < (argc - 2) ) - { - minimap.brightness = atof(argv[i + 1]); - i++; - Sys_Printf( "Brightness set to %f\n", minimap.brightness ); - } - else if( !strcmp( argv[ i ], "-contrast" ) && i < (argc - 2) ) - { - minimap.contrast = atof(argv[i + 1]); - i++; - Sys_Printf( "Contrast set to %f\n", minimap.contrast ); - } - else if( !strcmp( argv[ i ], "-autolevel" ) ) - { - autolevel = qtrue; - Sys_Printf( "Auto level enabled\n", border ); - } - else if( !strcmp( argv[ i ], "-noautolevel" ) ) - { - autolevel = qfalse; - Sys_Printf( "Auto level disabled\n", border ); - } - } - - MiniMapMakeMinsMaxs(mins, maxs, border, keepaspect); - - if(!*minimapFilename) - { - ExtractFileBase(source, basename); - ExtractFilePath(source, path); - sprintf(relativeMinimapFilename, game->miniMapNameFormat, basename); - MergeRelativePath(minimapFilename, path, relativeMinimapFilename); - Sys_Printf("Output file name automatically set to %s\n", minimapFilename); - } - ExtractFilePath(minimapFilename, path); - Q_mkdir(path); - - if(minimapSharpen >= 0) - { - minimap.sharpen_centermult = 8 * minimapSharpen + 1; - minimap.sharpen_boxmult = -minimapSharpen; - } - - minimap.data1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); - data4b = safe_malloc(minimap.width * minimap.height * 4); - if(minimapSharpen >= 0) - minimap.sharpendata1f = safe_malloc(minimap.width * minimap.height * sizeof(*minimap.data1f)); - - MiniMapSetupBrushes(); - - if(minimap.samples <= 1) - { - Sys_Printf( "\n--- MiniMapNoSupersampling (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapNoSupersampling); - } - else - { - if(minimap.sample_offsets) - { - Sys_Printf( "\n--- MiniMapSupersampled (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapSupersampled); - } - else - { - Sys_Printf( "\n--- MiniMapRandomlySupersampled (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapRandomlySupersampled); - } - } - - if(minimap.boost != 1.0) - { - Sys_Printf( "\n--- MiniMapContrastBoost (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapContrastBoost); - } - - if(autolevel) - { - Sys_Printf( "\n--- MiniMapAutoLevel (%d) ---\n", minimap.height ); - float mi = 1, ma = 0; - float s, o; - - // TODO threads! - q = minimap.data1f; - for(y = 0; y < minimap.height; ++y) - for(x = 0; x < minimap.width; ++x) - { - float v = *q++; - if(v < mi) - mi = v; - if(v > ma) - ma = v; - } - if(ma > mi) - { - s = 1 / (ma - mi); - o = mi / (ma - mi); - - // equations: - // brightness + contrast * v - // after autolevel: - // brightness + contrast * (v * s - o) - // = - // (brightness - contrast * o) + (contrast * s) * v - minimap.brightness = minimap.brightness - minimap.contrast * o; - minimap.contrast *= s; - - Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.brightness ); - Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); - } - else - Sys_Printf( "Auto level: failed because all pixels are the same value\n" ); - } - - if(minimap.brightness != 0 || minimap.contrast != 1) - { - Sys_Printf( "\n--- MiniMapBrightnessContrast (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapBrightnessContrast); - } - - if(minimap.sharpendata1f) - { - Sys_Printf( "\n--- MiniMapSharpen (%d) ---\n", minimap.height ); - RunThreadsOnIndividual(minimap.height, qtrue, MiniMapSharpen); - q = minimap.sharpendata1f; - } - else - { - q = minimap.data1f; - } - - Sys_Printf( "\nConverting..."); - - switch(mode) - { - case MINIMAP_MODE_GRAY: - p = data4b; - for(y = 0; y < minimap.height; ++y) - for(x = 0; x < minimap.width; ++x) - { - byte b; - float v = *q++; - if(v < 0) v = 0; - if(v > 255.0/256.0) v = 255.0/256.0; - b = v * 256; - *p++ = b; - } - Sys_Printf( " writing to %s...", minimapFilename ); - WriteTGAGray(minimapFilename, data4b, minimap.width, minimap.height); - break; - case MINIMAP_MODE_BLACK: - p = data4b; - for(y = 0; y < minimap.height; ++y) - for(x = 0; x < minimap.width; ++x) - { - byte b; - float v = *q++; - if(v < 0) v = 0; - if(v > 255.0/256.0) v = 255.0/256.0; - b = v * 256; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = b; - } - Sys_Printf( " writing to %s...", minimapFilename ); - WriteTGA(minimapFilename, data4b, minimap.width, minimap.height); - break; - case MINIMAP_MODE_WHITE: - p = data4b; - for(y = 0; y < minimap.height; ++y) - for(x = 0; x < minimap.width; ++x) - { - byte b; - float v = *q++; - if(v < 0) v = 0; - if(v > 255.0/256.0) v = 255.0/256.0; - b = v * 256; - *p++ = 255; - *p++ = 255; - *p++ = 255; - *p++ = b; - } - Sys_Printf( " writing to %s...", minimapFilename ); - WriteTGA(minimapFilename, data4b, minimap.width, minimap.height); - break; - } - - Sys_Printf( " done.\n" ); - - /* return to sender */ - return 0; -} - /* main() q3map mojo... diff --git a/tools/quake3/q3map2/minimap.c b/tools/quake3/q3map2/minimap.c new file mode 100644 index 00000000..5fbc2323 --- /dev/null +++ b/tools/quake3/q3map2/minimap.c @@ -0,0 +1,779 @@ +/* ------------------------------------------------------------------------------- + + Copyright (C) 1999-2007 id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + ------------------------------------------------------------------------------- + + This code has been altered significantly from its original form, to support + several games based on the Quake III Arena engine, in the form of "Q3Map2." + + ------------------------------------------------------------------------------- */ + + + +/* dependencies */ +#include "q3map2.h" + +/* minimap stuff */ + +typedef struct minimap_s +{ + bspModel_t *model; + int width; + int height; + int samples; + float *sample_offsets; + float sharpen_boxmult; + float sharpen_centermult; + float boost, brightness, contrast; + float *data1f; + float *sharpendata1f; + vec3_t mins, size; +} +minimap_t; + +static minimap_t minimap; + +qboolean BrushIntersectionWithLine( bspBrush_t *brush, vec3_t start, vec3_t dir, float *t_in, float *t_out ){ + int i; + qboolean in = qfalse, out = qfalse; + bspBrushSide_t *sides = &bspBrushSides[brush->firstSide]; + + for ( i = 0; i < brush->numSides; ++i ) + { + bspPlane_t *p = &bspPlanes[sides[i].planeNum]; + float sn = DotProduct( start, p->normal ); + float dn = DotProduct( dir, p->normal ); + if ( dn == 0 ) { + if ( sn > p->dist ) { + return qfalse; // outside! + } + } + else + { + float t = ( p->dist - sn ) / dn; + if ( dn < 0 ) { + if ( !in || t > *t_in ) { + *t_in = t; + in = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if ( out && *t_in >= *t_out ) { + return qfalse; + } + } + } + else + { + if ( !out || t < *t_out ) { + *t_out = t; + out = qtrue; + // as t_in can only increase, and t_out can only decrease, early out + if ( in && *t_in >= *t_out ) { + return qfalse; + } + } + } + } + } + return in && out; +} + +static float MiniMapSample( float x, float y ){ + vec3_t org, dir; + int i, bi; + float t0, t1; + float samp; + bspBrush_t *b; + bspBrushSide_t *s; + int cnt; + + org[0] = x; + org[1] = y; + org[2] = 0; + dir[0] = 0; + dir[1] = 0; + dir[2] = 1; + + cnt = 0; + samp = 0; + for ( i = 0; i < minimap.model->numBSPBrushes; ++i ) + { + bi = minimap.model->firstBSPBrush + i; + if ( opaqueBrushes[bi >> 3] & ( 1 << ( bi & 7 ) ) ) { + b = &bspBrushes[bi]; + + // sort out mins/maxs of the brush + s = &bspBrushSides[b->firstSide]; + if ( x < -bspPlanes[s[0].planeNum].dist ) { + continue; + } + if ( x > +bspPlanes[s[1].planeNum].dist ) { + continue; + } + if ( y < -bspPlanes[s[2].planeNum].dist ) { + continue; + } + if ( y > +bspPlanes[s[3].planeNum].dist ) { + continue; + } + + if ( BrushIntersectionWithLine( b, org, dir, &t0, &t1 ) ) { + samp += t1 - t0; + ++cnt; + } + } + } + + return samp; +} + +void RandomVector2f( float v[2] ){ + do + { + v[0] = 2 * Random() - 1; + v[1] = 2 * Random() - 1; + } + while ( v[0] * v[0] + v[1] * v[1] > 1 ); +} + +static void MiniMapRandomlySupersampled( int y ){ + int x, i; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * ( y / (float) minimap.height ); + float dx = minimap.size[0] / (float) minimap.width; + float dy = minimap.size[1] / (float) minimap.height; + float uv[2]; + float thisval; + + for ( x = 0; x < minimap.width; ++x ) + { + float xmin = minimap.mins[0] + minimap.size[0] * ( x / (float) minimap.width ); + float val = 0; + + for ( i = 0; i < minimap.samples; ++i ) + { + RandomVector2f( uv ); + thisval = MiniMapSample( + xmin + ( uv[0] + 0.5 ) * dx, /* exaggerated random pattern for better results */ + ymin + ( uv[1] + 0.5 ) * dy /* exaggerated random pattern for better results */ + ); + val += thisval; + } + val /= minimap.samples * minimap.size[2]; + *p++ = val; + } +} + +static void MiniMapSupersampled( int y ){ + int x, i; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * ( y / (float) minimap.height ); + float dx = minimap.size[0] / (float) minimap.width; + float dy = minimap.size[1] / (float) minimap.height; + + for ( x = 0; x < minimap.width; ++x ) + { + float xmin = minimap.mins[0] + minimap.size[0] * ( x / (float) minimap.width ); + float val = 0; + + for ( i = 0; i < minimap.samples; ++i ) + { + float thisval = MiniMapSample( + xmin + minimap.sample_offsets[2 * i + 0] * dx, + ymin + minimap.sample_offsets[2 * i + 1] * dy + ); + val += thisval; + } + val /= minimap.samples * minimap.size[2]; + *p++ = val; + } +} + +static void MiniMapNoSupersampling( int y ){ + int x; + float *p = &minimap.data1f[y * minimap.width]; + float ymin = minimap.mins[1] + minimap.size[1] * ( ( y + 0.5 ) / (float) minimap.height ); + + for ( x = 0; x < minimap.width; ++x ) + { + float xmin = minimap.mins[0] + minimap.size[0] * ( ( x + 0.5 ) / (float) minimap.width ); + *p++ = MiniMapSample( xmin, ymin ) / minimap.size[2]; + } +} + +static void MiniMapSharpen( int y ){ + int x; + qboolean up = ( y > 0 ); + qboolean down = ( y < minimap.height - 1 ); + float *p = &minimap.data1f[y * minimap.width]; + float *q = &minimap.sharpendata1f[y * minimap.width]; + + for ( x = 0; x < minimap.width; ++x ) + { + qboolean left = ( x > 0 ); + qboolean right = ( x < minimap.width - 1 ); + float val = p[0] * minimap.sharpen_centermult; + + if ( left && up ) { + val += p[-1 - minimap.width] * minimap.sharpen_boxmult; + } + if ( left && down ) { + val += p[-1 + minimap.width] * minimap.sharpen_boxmult; + } + if ( right && up ) { + val += p[+1 - minimap.width] * minimap.sharpen_boxmult; + } + if ( right && down ) { + val += p[+1 + minimap.width] * minimap.sharpen_boxmult; + } + + if ( left ) { + val += p[-1] * minimap.sharpen_boxmult; + } + if ( right ) { + val += p[+1] * minimap.sharpen_boxmult; + } + if ( up ) { + val += p[-minimap.width] * minimap.sharpen_boxmult; + } + if ( down ) { + val += p[+minimap.width] * minimap.sharpen_boxmult; + } + + ++p; + *q++ = val; + } +} + +static void MiniMapContrastBoost( int y ){ + int x; + float *q = &minimap.data1f[y * minimap.width]; + for ( x = 0; x < minimap.width; ++x ) + { + *q = *q * minimap.boost / ( ( minimap.boost - 1 ) * *q + 1 ); + ++q; + } +} + +static void MiniMapBrightnessContrast( int y ){ + int x; + float *q = &minimap.data1f[y * minimap.width]; + for ( x = 0; x < minimap.width; ++x ) + { + *q = *q * minimap.contrast + minimap.brightness; + ++q; + } +} + +void MiniMapMakeMinsMaxs( vec3_t mins_in, vec3_t maxs_in, float border, qboolean keepaspect ){ + vec3_t mins, maxs, extend; + VectorCopy( mins_in, mins ); + VectorCopy( maxs_in, maxs ); + + // line compatible to nexuiz mapinfo + Sys_Printf( "size %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] ); + + if ( keepaspect ) { + VectorSubtract( maxs, mins, extend ); + if ( extend[1] > extend[0] ) { + mins[0] -= ( extend[1] - extend[0] ) * 0.5; + maxs[0] += ( extend[1] - extend[0] ) * 0.5; + } + else + { + mins[1] -= ( extend[0] - extend[1] ) * 0.5; + maxs[1] += ( extend[0] - extend[1] ) * 0.5; + } + } + + /* border: amount of black area around the image */ + /* input: border, 1-2*border, border but we need border/(1-2*border) */ + + VectorSubtract( maxs, mins, extend ); + VectorScale( extend, border / ( 1 - 2 * border ), extend ); + + VectorSubtract( mins, extend, mins ); + VectorAdd( maxs, extend, maxs ); + + VectorCopy( mins, minimap.mins ); + VectorSubtract( maxs, mins, minimap.size ); + + // line compatible to nexuiz mapinfo + Sys_Printf( "size_texcoords %f %f %f %f %f %f\n", mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2] ); +} + +/* + MiniMapSetupBrushes() + determines solid non-sky brushes in the world + */ + +void MiniMapSetupBrushes( void ){ + SetupBrushesFlags( C_SOLID | C_SKY, C_SOLID, 0, 0 ); + // at least one must be solid + // none may be sky + // not all may be nodraw +} + +qboolean MiniMapEvaluateSampleOffsets( int *bestj, int *bestk, float *bestval ){ + float val, dx, dy; + int j, k; + + *bestj = *bestk = -1; + *bestval = 3; /* max possible val is 2 */ + + for ( j = 0; j < minimap.samples; ++j ) + for ( k = j + 1; k < minimap.samples; ++k ) + { + dx = minimap.sample_offsets[2 * j + 0] - minimap.sample_offsets[2 * k + 0]; + dy = minimap.sample_offsets[2 * j + 1] - minimap.sample_offsets[2 * k + 1]; + if ( dx > +0.5 ) { + dx -= 1; + } + if ( dx < -0.5 ) { + dx += 1; + } + if ( dy > +0.5 ) { + dy -= 1; + } + if ( dy < -0.5 ) { + dy += 1; + } + val = dx * dx + dy * dy; + if ( val < *bestval ) { + *bestj = j; + *bestk = k; + *bestval = val; + } + } + + return *bestval < 3; +} + +void MiniMapMakeSampleOffsets(){ + int i, j, k, jj, kk; + float val, valj, valk, sx, sy, rx, ry; + + Sys_Printf( "Generating good sample offsets (this may take a while)...\n" ); + + /* start with entirely random samples */ + for ( i = 0; i < minimap.samples; ++i ) + { + minimap.sample_offsets[2 * i + 0] = Random(); + minimap.sample_offsets[2 * i + 1] = Random(); + } + + for ( i = 0; i < 1000; ++i ) + { + if ( MiniMapEvaluateSampleOffsets( &j, &k, &val ) ) { + sx = minimap.sample_offsets[2 * j + 0]; + sy = minimap.sample_offsets[2 * j + 1]; + minimap.sample_offsets[2 * j + 0] = rx = Random(); + minimap.sample_offsets[2 * j + 1] = ry = Random(); + if ( !MiniMapEvaluateSampleOffsets( &jj, &kk, &valj ) ) { + valj = -1; + } + minimap.sample_offsets[2 * j + 0] = sx; + minimap.sample_offsets[2 * j + 1] = sy; + + sx = minimap.sample_offsets[2 * k + 0]; + sy = minimap.sample_offsets[2 * k + 1]; + minimap.sample_offsets[2 * k + 0] = rx; + minimap.sample_offsets[2 * k + 1] = ry; + if ( !MiniMapEvaluateSampleOffsets( &jj, &kk, &valk ) ) { + valk = -1; + } + minimap.sample_offsets[2 * k + 0] = sx; + minimap.sample_offsets[2 * k + 1] = sy; + + if ( valj > valk ) { + if ( valj > val ) { + /* valj is the greatest */ + minimap.sample_offsets[2 * j + 0] = rx; + minimap.sample_offsets[2 * j + 1] = ry; + i = -1; + } + else + { + /* valj is the greater and it is useless - forget it */ + } + } + else + { + if ( valk > val ) { + /* valk is the greatest */ + minimap.sample_offsets[2 * k + 0] = rx; + minimap.sample_offsets[2 * k + 1] = ry; + i = -1; + } + else + { + /* valk is the greater and it is useless - forget it */ + } + } + } + else{ + break; + } + } +} + +void MergeRelativePath( char *out, const char *absolute, const char *relative ){ + const char *endpos = absolute + strlen( absolute ); + while ( endpos != absolute && ( endpos[-1] == '/' || endpos[-1] == '\\' ) ) + --endpos; + while ( relative[0] == '.' && relative[1] == '.' && ( relative[2] == '/' || relative[2] == '\\' ) ) + { + relative += 3; + while ( endpos != absolute ) + { + --endpos; + if ( *endpos == '/' || *endpos == '\\' ) { + break; + } + } + while ( endpos != absolute && ( endpos[-1] == '/' || endpos[-1] == '\\' ) ) + --endpos; + } + memcpy( out, absolute, endpos - absolute ); + out[endpos - absolute] = '/'; + strcpy( out + ( endpos - absolute + 1 ), relative ); +} + +int MiniMapBSPMain( int argc, char **argv ){ + char minimapFilename[1024]; + char basename[1024]; + char path[1024]; + char relativeMinimapFilename[1024]; + qboolean autolevel; + float minimapSharpen; + float border; + byte *data4b, *p; + float *q; + int x, y; + int i; + miniMapMode_t mode; + vec3_t mins, maxs; + qboolean keepaspect; + + /* arg checking */ + if ( argc < 2 ) { + Sys_Printf( "Usage: q3map [-v] -minimap [-size n] [-sharpen f] [-samples n | -random n] [-o filename.tga] [-minmax Xmin Ymin Zmin Xmax Ymax Zmax] \n" ); + return 0; + } + + /* load the BSP first */ + strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); + StripExtension( source ); + DefaultExtension( source, ".bsp" ); + Sys_Printf( "Loading %s\n", source ); + BeginMapShaderFile( source ); + LoadShaderInfo(); + LoadBSPFile( source ); + + minimap.model = &bspModels[0]; + VectorCopy( minimap.model->mins, mins ); + VectorCopy( minimap.model->maxs, maxs ); + + *minimapFilename = 0; + minimapSharpen = game->miniMapSharpen; + minimap.width = minimap.height = game->miniMapSize; + border = game->miniMapBorder; + keepaspect = game->miniMapKeepAspect; + mode = game->miniMapMode; + + autolevel = qfalse; + minimap.samples = 1; + minimap.sample_offsets = NULL; + minimap.boost = 1.0; + minimap.brightness = 0.0; + minimap.contrast = 1.0; + + /* process arguments */ + for ( i = 1; i < ( argc - 1 ); i++ ) + { + if ( !strcmp( argv[ i ], "-size" ) ) { + minimap.width = minimap.height = atoi( argv[i + 1] ); + i++; + Sys_Printf( "Image size set to %i\n", minimap.width ); + } + else if ( !strcmp( argv[ i ], "-sharpen" ) ) { + minimapSharpen = atof( argv[i + 1] ); + i++; + Sys_Printf( "Sharpening coefficient set to %f\n", minimapSharpen ); + } + else if ( !strcmp( argv[ i ], "-samples" ) ) { + minimap.samples = atoi( argv[i + 1] ); + i++; + Sys_Printf( "Samples set to %i\n", minimap.samples ); + if ( minimap.sample_offsets ) { + free( minimap.sample_offsets ); + } + minimap.sample_offsets = malloc( 2 * sizeof( *minimap.sample_offsets ) * minimap.samples ); + MiniMapMakeSampleOffsets(); + } + else if ( !strcmp( argv[ i ], "-random" ) ) { + minimap.samples = atoi( argv[i + 1] ); + i++; + Sys_Printf( "Random samples set to %i\n", minimap.samples ); + if ( minimap.sample_offsets ) { + free( minimap.sample_offsets ); + } + minimap.sample_offsets = NULL; + } + else if ( !strcmp( argv[ i ], "-border" ) ) { + border = atof( argv[i + 1] ); + i++; + Sys_Printf( "Border set to %f\n", border ); + } + else if ( !strcmp( argv[ i ], "-keepaspect" ) ) { + keepaspect = qtrue; + Sys_Printf( "Keeping aspect ratio by letterboxing\n", border ); + } + else if ( !strcmp( argv[ i ], "-nokeepaspect" ) ) { + keepaspect = qfalse; + Sys_Printf( "Not keeping aspect ratio\n", border ); + } + else if ( !strcmp( argv[ i ], "-o" ) ) { + strcpy( minimapFilename, argv[i + 1] ); + i++; + Sys_Printf( "Output file name set to %s\n", minimapFilename ); + } + else if ( !strcmp( argv[ i ], "-minmax" ) && i < ( argc - 7 ) ) { + mins[0] = atof( argv[i + 1] ); + mins[1] = atof( argv[i + 2] ); + mins[2] = atof( argv[i + 3] ); + maxs[0] = atof( argv[i + 4] ); + maxs[1] = atof( argv[i + 5] ); + maxs[2] = atof( argv[i + 6] ); + i += 6; + Sys_Printf( "Map mins/maxs overridden\n" ); + } + else if ( !strcmp( argv[ i ], "-gray" ) ) { + mode = MINIMAP_MODE_GRAY; + Sys_Printf( "Writing as white-on-black image\n" ); + } + else if ( !strcmp( argv[ i ], "-black" ) ) { + mode = MINIMAP_MODE_BLACK; + Sys_Printf( "Writing as black alpha image\n" ); + } + else if ( !strcmp( argv[ i ], "-white" ) ) { + mode = MINIMAP_MODE_WHITE; + Sys_Printf( "Writing as white alpha image\n" ); + } + else if ( !strcmp( argv[ i ], "-boost" ) && i < ( argc - 2 ) ) { + minimap.boost = atof( argv[i + 1] ); + i++; + Sys_Printf( "Contrast boost set to %f\n", minimap.boost ); + } + else if ( !strcmp( argv[ i ], "-brightness" ) && i < ( argc - 2 ) ) { + minimap.brightness = atof( argv[i + 1] ); + i++; + Sys_Printf( "Brightness set to %f\n", minimap.brightness ); + } + else if ( !strcmp( argv[ i ], "-contrast" ) && i < ( argc - 2 ) ) { + minimap.contrast = atof( argv[i + 1] ); + i++; + Sys_Printf( "Contrast set to %f\n", minimap.contrast ); + } + else if ( !strcmp( argv[ i ], "-autolevel" ) ) { + autolevel = qtrue; + Sys_Printf( "Auto level enabled\n", border ); + } + else if ( !strcmp( argv[ i ], "-noautolevel" ) ) { + autolevel = qfalse; + Sys_Printf( "Auto level disabled\n", border ); + } + } + + MiniMapMakeMinsMaxs( mins, maxs, border, keepaspect ); + + if ( !*minimapFilename ) { + ExtractFileBase( source, basename ); + ExtractFilePath( source, path ); + sprintf( relativeMinimapFilename, game->miniMapNameFormat, basename ); + MergeRelativePath( minimapFilename, path, relativeMinimapFilename ); + Sys_Printf( "Output file name automatically set to %s\n", minimapFilename ); + } + ExtractFilePath( minimapFilename, path ); + Q_mkdir( path ); + + if ( minimapSharpen >= 0 ) { + minimap.sharpen_centermult = 8 * minimapSharpen + 1; + minimap.sharpen_boxmult = -minimapSharpen; + } + + minimap.data1f = safe_malloc( minimap.width * minimap.height * sizeof( *minimap.data1f ) ); + data4b = safe_malloc( minimap.width * minimap.height * 4 ); + if ( minimapSharpen >= 0 ) { + minimap.sharpendata1f = safe_malloc( minimap.width * minimap.height * sizeof( *minimap.data1f ) ); + } + + MiniMapSetupBrushes(); + + if ( minimap.samples <= 1 ) { + Sys_Printf( "\n--- MiniMapNoSupersampling (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapNoSupersampling ); + } + else + { + if ( minimap.sample_offsets ) { + Sys_Printf( "\n--- MiniMapSupersampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapSupersampled ); + } + else + { + Sys_Printf( "\n--- MiniMapRandomlySupersampled (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapRandomlySupersampled ); + } + } + + if ( minimap.boost != 1.0 ) { + Sys_Printf( "\n--- MiniMapContrastBoost (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapContrastBoost ); + } + + if ( autolevel ) { + Sys_Printf( "\n--- MiniMapAutoLevel (%d) ---\n", minimap.height ); + float mi = 1, ma = 0; + float s, o; + + // TODO threads! + q = minimap.data1f; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + float v = *q++; + if ( v < mi ) { + mi = v; + } + if ( v > ma ) { + ma = v; + } + } + if ( ma > mi ) { + s = 1 / ( ma - mi ); + o = mi / ( ma - mi ); + + // equations: + // brightness + contrast * v + // after autolevel: + // brightness + contrast * (v * s - o) + // = + // (brightness - contrast * o) + (contrast * s) * v + minimap.brightness = minimap.brightness - minimap.contrast * o; + minimap.contrast *= s; + + Sys_Printf( "Auto level: Brightness changed to %f\n", minimap.brightness ); + Sys_Printf( "Auto level: Contrast changed to %f\n", minimap.contrast ); + } + else{ + Sys_Printf( "Auto level: failed because all pixels are the same value\n" ); + } + } + + if ( minimap.brightness != 0 || minimap.contrast != 1 ) { + Sys_Printf( "\n--- MiniMapBrightnessContrast (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapBrightnessContrast ); + } + + if ( minimap.sharpendata1f ) { + Sys_Printf( "\n--- MiniMapSharpen (%d) ---\n", minimap.height ); + RunThreadsOnIndividual( minimap.height, qtrue, MiniMapSharpen ); + q = minimap.sharpendata1f; + } + else + { + q = minimap.data1f; + } + + Sys_Printf( "\nConverting..." ); + + switch ( mode ) + { + case MINIMAP_MODE_GRAY: + p = data4b; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + byte b; + float v = *q++; + if ( v < 0 ) { + v = 0; + } + if ( v > 255.0 / 256.0 ) { + v = 255.0 / 256.0; + } + b = v * 256; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGAGray( minimapFilename, data4b, minimap.width, minimap.height ); + break; + case MINIMAP_MODE_BLACK: + p = data4b; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + byte b; + float v = *q++; + if ( v < 0 ) { + v = 0; + } + if ( v > 255.0 / 256.0 ) { + v = 255.0 / 256.0; + } + b = v * 256; + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA( minimapFilename, data4b, minimap.width, minimap.height ); + break; + case MINIMAP_MODE_WHITE: + p = data4b; + for ( y = 0; y < minimap.height; ++y ) + for ( x = 0; x < minimap.width; ++x ) + { + byte b; + float v = *q++; + if ( v < 0 ) { + v = 0; + } + if ( v > 255.0 / 256.0 ) { + v = 255.0 / 256.0; + } + b = v * 256; + *p++ = 255; + *p++ = 255; + *p++ = 255; + *p++ = b; + } + Sys_Printf( " writing to %s...", minimapFilename ); + WriteTGA( minimapFilename, data4b, minimap.width, minimap.height ); + break; + } + + Sys_Printf( " done.\n" ); + + /* return to sender */ + return 0; +} diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index ffb056ab..2a91b0b4 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1497,6 +1497,8 @@ int BSPInfoMain( int argc, char **argv ); /* bsp_scale.c */ int ScaleBSPMain( int argc, char **argv ); +/* minimap.c */ +int MiniMapBSPMain( int argc, char **argv ); /* convert_bsp.c */ int ConvertBSPMain( int argc, char **argv ); From aa696e8cf8396b1f6f798d8d24385a62c8865e16 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 11 Feb 2016 21:49:13 +0100 Subject: [PATCH 30/32] do not delete q3map2_*.shader on minimap generation --- tools/quake3/q3map2/minimap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/quake3/q3map2/minimap.c b/tools/quake3/q3map2/minimap.c index 5fbc2323..204e396c 100644 --- a/tools/quake3/q3map2/minimap.c +++ b/tools/quake3/q3map2/minimap.c @@ -483,7 +483,6 @@ int MiniMapBSPMain( int argc, char **argv ){ StripExtension( source ); DefaultExtension( source, ".bsp" ); Sys_Printf( "Loading %s\n", source ); - BeginMapShaderFile( source ); LoadShaderInfo(); LoadBSPFile( source ); From 6649445a467cf2b85a69b97f1c3f1c70d12fc1be Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 28 Jan 2018 04:27:19 +0100 Subject: [PATCH 31/32] add missing minimap support for games --- tools/quake3/q3map2/game__null.h | 6 ++++++ tools/quake3/q3map2/game_reaction.h | 6 ++++++ tools/quake3/q3map2/game_unvanquished.h | 6 ++++++ tools/quake3/q3map2/q3map2.vcxproj | 3 ++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/quake3/q3map2/game__null.h b/tools/quake3/q3map2/game__null.h index c291a50f..9191051b 100644 --- a/tools/quake3/q3map2/game__null.h +++ b/tools/quake3/q3map2/game__null.h @@ -64,6 +64,12 @@ 0, /* lightmap width/height */ 0, /* lightmap gamma */ 0, /* lightmap compensate */ + 0, /* minimap size */ + 0, /* minimap sharpener */ + 0, /* minimap border */ + qfalse, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ + NULL, /* minimap name format */ NULL, /* bsp file prefix */ 0, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_reaction.h b/tools/quake3/q3map2/game_reaction.h index 00016c3f..970ccd25 100644 --- a/tools/quake3/q3map2/game_reaction.h +++ b/tools/quake3/q3map2/game_reaction.h @@ -85,6 +85,12 @@ 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ + MINIMAP_MODE_GRAY, /* minimap mode */ + "%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/game_unvanquished.h b/tools/quake3/q3map2/game_unvanquished.h index 1c85c300..bf1a07e8 100644 --- a/tools/quake3/q3map2/game_unvanquished.h +++ b/tools/quake3/q3map2/game_unvanquished.h @@ -72,6 +72,12 @@ game_t struct 128, /* lightmap width/height */ 1.0f, /* lightmap gamma */ 1.0f, /* lightmap compensate */ + 512, /* minimap size */ + 1.0f, /* minimap sharpener */ + 0.0f, /* minimap border */ + qtrue, /* minimap keep aspect */ + MINIMAP_MODE_WHITE, /* minimap mode */ + "../minimaps/%s.tga", /* minimap name format */ "IBSP", /* bsp file prefix */ 46, /* bsp file version */ qfalse, /* cod-style lump len/ofs order */ diff --git a/tools/quake3/q3map2/q3map2.vcxproj b/tools/quake3/q3map2/q3map2.vcxproj index dd1120d7..bcde1258 100644 --- a/tools/quake3/q3map2/q3map2.vcxproj +++ b/tools/quake3/q3map2/q3map2.vcxproj @@ -167,6 +167,7 @@ + @@ -240,4 +241,4 @@ - \ No newline at end of file + From bf2da7441faf3183bcdbd134e50aa91fb27622ae Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 28 Jan 2018 04:32:58 +0100 Subject: [PATCH 32/32] reduce diff noise --- tools/quake3/common/imagelib.c | 32 +++--- tools/quake3/common/imagelib.h | 2 +- tools/quake3/q3map2/bsp.c | 4 +- tools/quake3/q3map2/facebsp.c | 12 --- tools/quake3/q3map2/game_nexuiz.h | 2 +- tools/quake3/q3map2/game_unvanquished.h | 8 +- tools/quake3/q3map2/light_ydnar.c | 25 +++-- tools/quake3/q3map2/main.c | 5 +- tools/quake3/q3map2/model.c | 3 +- tools/quake3/q3map2/prtfile.c | 126 ++++++++++++------------ tools/quake3/q3map2/q3map2.h | 49 +++++---- tools/quake3/q3map2/shaders.c | 7 +- 12 files changed, 129 insertions(+), 146 deletions(-) diff --git a/tools/quake3/common/imagelib.c b/tools/quake3/common/imagelib.c index dfe16168..bb422ec9 100644 --- a/tools/quake3/common/imagelib.c +++ b/tools/quake3/common/imagelib.c @@ -1169,24 +1169,24 @@ void WriteTGA( const char *filename, byte *data, int width, int height ) { free( buffer ); } -void WriteTGAGray (const char *filename, byte *data, int width, int height) { - byte buffer[18]; - int i; - int c; - FILE *f; +void WriteTGAGray( const char *filename, byte *data, int width, int height ) { + byte buffer[18]; + int i; + int c; + FILE *f; - memset (buffer, 0, 18); - buffer[2] = 3; // uncompressed type - buffer[12] = width&255; - buffer[13] = width>>8; - buffer[14] = height&255; - buffer[15] = height>>8; - buffer[16] = 8; // pixel size + memset( buffer, 0, 18 ); + buffer[2] = 3; // uncompressed type + buffer[12] = width & 255; + buffer[13] = width >> 8; + buffer[14] = height & 255; + buffer[15] = height >> 8; + buffer[16] = 8; // pixel size - f = fopen (filename, "wb"); - fwrite (buffer, 1, 18, f); - fwrite (data, 1, width * height, f); - fclose (f); + f = fopen( filename, "wb" ); + fwrite( buffer, 1, 18, f ); + fwrite( data, 1, width * height, f ); + fclose( f ); } /* diff --git a/tools/quake3/common/imagelib.h b/tools/quake3/common/imagelib.h index f313881a..2e6a6a98 100644 --- a/tools/quake3/common/imagelib.h +++ b/tools/quake3/common/imagelib.h @@ -39,7 +39,7 @@ void Save256Image( const char *name, byte *pixels, byte *palette, void LoadTGA( const char *filename, byte **pixels, int *width, int *height ); void LoadTGABuffer( const byte *buffer, const byte* enddata, byte **pic, int *width, int *height ); void WriteTGA( const char *filename, byte *data, int width, int height ); -int LoadJPGBuff( void *src_buffer, int src_size, unsigned char **pic, int *width, int *height ); void WriteTGAGray (const char *filename, byte *data, int width, int height); +int LoadJPGBuff( void *src_buffer, int src_size, unsigned char **pic, int *width, int *height ); void Load32BitImage( const char *name, unsigned **pixels, int *width, int *height ); diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index 46a7956f..929aa93c 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -841,12 +841,12 @@ int BSPMain( int argc, char **argv ){ Sys_Printf( "Debug portal surfaces enabled\n" ); debugPortals = qtrue; } - else if( !strcmp( argv[ i ], "-altsplit" ) ) + else if ( !strcmp( argv[ i ], "-altsplit" ) ) { Sys_Printf( "Alternate BSP splitting (by 27) enabled\n" ); bspAlternateSplitWeights = qtrue; } - else if( !strcmp( argv[ i ], "-deep" ) ) + else if ( !strcmp( argv[ i ], "-deep" ) ) { Sys_Printf( "Deep BSP tree generation enabled\n" ); deepBSP = qtrue; diff --git a/tools/quake3/q3map2/facebsp.c b/tools/quake3/q3map2/facebsp.c index c1d7d939..888a44ad 100644 --- a/tools/quake3/q3map2/facebsp.c +++ b/tools/quake3/q3map2/facebsp.c @@ -318,22 +318,10 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ } } -#if 0 - if((node->compileFlags & C_DETAIL) && isstruct) - Sys_FPrintf(SYS_ERR, "I am detail, my child is structural, this is a wtf1\n", node->has_structural_children); -#endif - for ( i = 0 ; i < 2 ; i++ ) { BuildFaceTree_r( node->children[i], childLists[i] ); node->has_structural_children |= node->children[i]->has_structural_children; } - -#if 0 - if((node->compileFlags & C_DETAIL) && !(node->children[0]->compileFlags & C_DETAIL) && node->children[0]->planenum != PLANENUM_LEAF) - Sys_FPrintf(SYS_ERR, "I am detail, my child is structural\n", node->has_structural_children); - if((node->compileFlags & C_DETAIL) && isstruct) - Sys_FPrintf(SYS_ERR, "I am detail, my child is structural, this is a wtf2\n", node->has_structural_children); -#endif } diff --git a/tools/quake3/q3map2/game_nexuiz.h b/tools/quake3/q3map2/game_nexuiz.h index e79a386c..f909c4bc 100644 --- a/tools/quake3/q3map2/game_nexuiz.h +++ b/tools/quake3/q3map2/game_nexuiz.h @@ -66,7 +66,7 @@ 1.0f, /* lightmap compensate */ 512, /* minimap size */ 1.0f, /* minimap sharpener */ - 1.0f/66.0f, /* minimap border */ + 1.0f / 66.0f, /* minimap border */ qtrue, /* minimap keep aspect */ MINIMAP_MODE_GRAY, /* minimap mode */ "../gfx/%s_mini.tga", /* minimap name format */ diff --git a/tools/quake3/q3map2/game_unvanquished.h b/tools/quake3/q3map2/game_unvanquished.h index bf1a07e8..e56d7347 100644 --- a/tools/quake3/q3map2/game_unvanquished.h +++ b/tools/quake3/q3map2/game_unvanquished.h @@ -41,6 +41,7 @@ several games based on the Quake III Arena engine, in the form of "Q3Map2." content and surface flags - also uses defines from game_quake3.h ------------------------------------------------------------------------------- */ + #define UNV_CONT_NOALIENBUILD 0x1000 #define UNV_CONT_NOHUMANBUILD 0x2000 #define UNV_CONT_NOBUILD 0x4000 @@ -90,13 +91,11 @@ game_t struct /* default */ { "default", Q_CONT_SOLID, -1, 0, -1, C_SOLID, -1 }, - /* ydnar */ { "lightgrid", 0, 0, 0, 0, C_LIGHTGRID, 0 }, { "antiportal", 0, 0, 0, 0, C_ANTIPORTAL, 0 }, { "skip", 0, 0, 0, 0, C_SKIP, 0 }, - /* compiler */ { "origin", Q_CONT_ORIGIN, Q_CONT_SOLID, 0, 0, C_ORIGIN | C_TRANSLUCENT, C_SOLID }, { "areaportal", Q_CONT_AREAPORTAL, Q_CONT_SOLID, 0, 0, C_AREAPORTAL | C_TRANSLUCENT, C_SOLID }, @@ -111,7 +110,6 @@ game_t struct { "nolightmap", 0, 0, Q_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, { "pointlight", 0, 0, Q_SURF_VERTEXLIT, 0, C_VERTEXLIT, 0 }, - /* game */ { "nonsolid", 0, Q_CONT_SOLID, Q_SURF_NONSOLID, 0, 0, C_SOLID }, @@ -144,7 +142,6 @@ game_t struct { "nodlight", 0, 0, Q_SURF_NODLIGHT, 0, 0, 0 }, { "dust", 0, 0, Q_SURF_DUST, 0, 0, 0 }, - /* unvanquished */ {"noalienbuild", UNV_CONT_NOALIENBUILD, 0, 0, 0, 0, 0 }, {"nohumanbuild", UNV_CONT_NOHUMANBUILD, 0, 0, 0, 0, 0 }, @@ -154,13 +151,10 @@ game_t struct {"nohumanbuildsurface", 0, 0, UNV_SURF_NOHUMANBUILDSURFACE, 0, 0, 0 }, {"nobuildsurface", 0, 0, UNV_SURF_NOBUILDSURFACE, 0, 0, 0 }, - /* null */ { NULL, 0, 0, 0, 0, 0, 0 } } } - - /* end marker */ #endif diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index d2d0f9da..38690791 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -1596,8 +1596,9 @@ void DirtyRawLightmap( int rawLightmapNum ){ static qboolean SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float by, int *sampleCluster, vec3_t sampleOrigin, vec3_t sampleNormal ){ int i, *cluster, *cluster2; - float *origin, *origin2, *normal; - vec3_t originVecs[ 2 ]; + float *origin, *origin2, *normal; //% , *normal2; + vec3_t originVecs[ 2 ]; //% , normalVecs[ 2 ]; + /* calulate x vector */ if ( ( x < ( lm->sw - 1 ) && bx >= 0.0f ) || ( x == 0 && bx <= 0.0f ) ) { @@ -1612,7 +1613,7 @@ static qboolean SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float cluster2 = SUPER_CLUSTER( x, y ); origin2 = SUPER_ORIGIN( x, y ); } - else{ + else { Sys_FPrintf( SYS_WRN, "WARNING: Spurious lightmap S vector\n" ); VectorClear( originVecs[0] ); origin = originVecs[0]; @@ -1634,7 +1635,7 @@ static qboolean SubmapRawLuxel( rawLightmap_t *lm, int x, int y, float bx, float cluster2 = SUPER_CLUSTER( x, y ); origin2 = SUPER_ORIGIN( x, y ); } - else{ + else { Sys_FPrintf( SYS_WRN, "WARNING: Spurious lightmap T vector\n" ); VectorClear( originVecs[1] ); origin = originVecs[1]; @@ -2783,8 +2784,7 @@ void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned i bspBrushSide_t *side; bspShader_t *shader; shaderInfo_t *si; - - + /* note it */ Sys_FPrintf( SYS_VRB, "--- SetupBrushes ---\n" ); @@ -2807,7 +2807,7 @@ void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned i /* check all sides */ inside = qtrue; compileFlags = 0; - allCompileFlags = ~(0u); + allCompileFlags = ~( 0u ); for ( j = 0; j < brush->numSides && inside; j++ ) { /* do bsp shader calculations */ @@ -2822,12 +2822,12 @@ void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned i /* or together compile flags */ compileFlags |= si->compileFlags; + allCompileFlags &= si->compileFlags; } /* determine if this brush is opaque to light */ - if( (compileFlags & mask_any) == test_any && (allCompileFlags & mask_all) == test_all ) - { - opaqueBrushes[ b >> 3 ] |= (1 << (b & 7)); + if ( ( compileFlags & mask_any ) == test_any && ( allCompileFlags & mask_all ) == test_all ) { + opaqueBrushes[ b >> 3 ] |= ( 1 << ( b & 7 ) ); numOpaqueBrushes++; maxOpaqueBrush = i; } @@ -2836,9 +2836,8 @@ void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned i /* emit some statistics */ Sys_FPrintf( SYS_VRB, "%9d opaque brushes\n", numOpaqueBrushes ); } -void SetupBrushes( void ) -{ - SetupBrushesFlags(C_TRANSLUCENT, 0, 0, 0); +void SetupBrushes( void ){ + SetupBrushesFlags( C_TRANSLUCENT, 0, 0, 0 ); } diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 802200c6..45d394fb 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -249,8 +249,9 @@ int main( int argc, char **argv ){ } /* div0: minimap */ - else if( !strcmp( argv[ 1 ], "-minimap" ) ) - r = MiniMapBSPMain(argc - 1, argv + 1); + else if ( !strcmp( argv[ 1 ], "-minimap" ) ) { + r = MiniMapBSPMain( argc - 1, argv + 1 ); + } /* ydnar: otherwise create a bsp */ else{ diff --git a/tools/quake3/q3map2/model.c b/tools/quake3/q3map2/model.c index 0e8e906b..68897e48 100644 --- a/tools/quake3/q3map2/model.c +++ b/tools/quake3/q3map2/model.c @@ -389,8 +389,7 @@ void InsertModel( char *name, int frame, m4x4_t transform, remap_t *remap, shade { dv->lightmap[ j ][ 0 ] = 0.0f; dv->lightmap[ j ][ 1 ] = 0.0f; - if(spawnFlags & 32) // spawnflag 32: model color -> alpha hack - { + if ( spawnFlags & 32 ) { // spawnflag 32: model color -> alpha hack dv->color[ j ][ 0 ] = 255.0f; dv->color[ j ][ 1 ] = 255.0f; dv->color[ j ][ 2 ] = 255.0f; diff --git a/tools/quake3/q3map2/prtfile.c b/tools/quake3/q3map2/prtfile.c index 55d47af6..ce2cff16 100644 --- a/tools/quake3/q3map2/prtfile.c +++ b/tools/quake3/q3map2/prtfile.c @@ -64,35 +64,35 @@ void WriteFloat( FILE *f, vec_t v ){ } } -void CountVisportals_r(node_t *node) -{ - int i, s; - portal_t *p; - winding_t *w; +void CountVisportals_r( node_t *node ){ + int s; + portal_t *p; + winding_t *w; vec3_t normal; vec_t dist; // decision node - if (node->planenum != PLANENUM_LEAF) { - CountVisportals_r (node->children[0]); - CountVisportals_r (node->children[1]); - return; - } - - if (node->opaque) { + if ( node->planenum != PLANENUM_LEAF ) { + CountVisportals_r( node->children[0] ); + CountVisportals_r( node->children[1] ); return; } - for (p = node->portals ; p ; p=p->next[s]) + if ( node->opaque ) { + return; + } + + for ( p = node->portals ; p ; p = p->next[s] ) { w = p->winding; - s = (p->nodes[1] == node); - if (w && p->nodes[0] == node) - { - if (!PortalPassable(p)) + s = ( p->nodes[1] == node ); + if ( w && p->nodes[0] == node ) { + if ( !PortalPassable( p ) ) { continue; - if(p->nodes[0]->cluster == p->nodes[1]->cluster) + } + if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) { continue; + } ++num_visportals; } } @@ -129,8 +129,9 @@ void WritePortalFile_r( node_t *node ){ if ( !PortalPassable( p ) ) { continue; } - if(p->nodes[0]->cluster == p->nodes[1]->cluster) + if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) { continue; + } --num_visportals; // write out to the file @@ -138,17 +139,17 @@ void WritePortalFile_r( node_t *node ){ // the changeover point between different axis. interpret the // plane the same way vis will, and flip the side orders if needed // FIXME: is this still relevent? - WindingPlane (w, normal, &dist); - if ( DotProduct (p->plane.normal, normal) < 0.99 ) - { // backwards... - fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster); + WindingPlane( w, normal, &dist ); + + if ( DotProduct( p->plane.normal, normal ) < 0.99 ) { // backwards... + fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster ); } else{ fprintf( pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster ); } /* ydnar: added this change to make antiportals work */ - if ( p->compileFlags & C_HINT ) { + if( p->compileFlags & C_HINT ) { fprintf( pf, "1 " ); } else{ @@ -170,33 +171,33 @@ void WritePortalFile_r( node_t *node ){ } -void CountSolidFaces_r (node_t *node) -{ - int i, s; - portal_t *p; - winding_t *w; +void CountSolidFaces_r( node_t *node ){ + int s; + portal_t *p; + winding_t *w; // decision node - if (node->planenum != PLANENUM_LEAF) { - CountSolidFaces_r (node->children[0]); - CountSolidFaces_r (node->children[1]); - return; - } - - if (node->opaque) { + if ( node->planenum != PLANENUM_LEAF ) { + CountSolidFaces_r( node->children[0] ); + CountSolidFaces_r( node->children[1] ); return; } - for (p = node->portals ; p ; p=p->next[s]) + if ( node->opaque ) { + return; + } + + for ( p = node->portals ; p ; p = p->next[s] ) { w = p->winding; - s = (p->nodes[1] == node); - if (w) - { - if (PortalPassable(p)) + s = ( p->nodes[1] == node ); + if ( w ) { + if ( PortalPassable( p ) ) { continue; - if(p->nodes[0]->cluster == p->nodes[1]->cluster) + } + if ( p->nodes[0]->cluster == p->nodes[1]->cluster ) { continue; + } // write out to the file ++num_solidfaces; @@ -268,29 +269,29 @@ void WriteFaceFile_r( node_t *node ){ } /* -================ -NumberLeafs_r -================ -*/ -void NumberLeafs_r (node_t *node, int c) -{ - portal_t *p; - + ================ + NumberLeafs_r + ================ + */ +void NumberLeafs_r( node_t *node, int c ){ +#if 0 + portal_t *p; +#endif if ( node->planenum != PLANENUM_LEAF ) { // decision node node->cluster = -99; - if(node->has_structural_children) - { - NumberLeafs_r (node->children[0], c); - NumberLeafs_r (node->children[1], c); + if ( node->has_structural_children ) { + NumberLeafs_r( node->children[0], c ); + NumberLeafs_r( node->children[1], c ); } else { - if(c < 0) + if ( c < 0 ) { c = num_visclusters++; - NumberLeafs_r (node->children[0], c); - NumberLeafs_r (node->children[1], c); + } + NumberLeafs_r( node->children[0], c ); + NumberLeafs_r( node->children[1], c ); } return; } @@ -303,9 +304,10 @@ void NumberLeafs_r (node_t *node, int c) return; } - if(c < 0) + if ( c < 0 ) { c = num_visclusters++; - + } + node->cluster = c; #if 0 @@ -346,9 +348,9 @@ void NumberClusters( tree_t *tree ) { Sys_FPrintf( SYS_VRB,"--- NumberClusters ---\n" ); // set the cluster field in every leaf and count the total number of portals - NumberLeafs_r (tree->headnode, -1); - CountVisportals_r (tree->headnode); - CountSolidFaces_r (tree->headnode); + NumberLeafs_r( tree->headnode, -1 ); + CountVisportals_r( tree->headnode ); + CountSolidFaces_r( tree->headnode ); Sys_FPrintf( SYS_VRB, "%9d visclusters\n", num_visclusters ); Sys_FPrintf( SYS_VRB, "%9d visportals\n", num_visportals ); diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 2a91b0b4..65b765fe 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -573,11 +573,11 @@ typedef struct game_s int lightmapSize; /* bsp lightmap width/height */ float lightmapGamma; /* default lightmap gamma */ float lightmapCompensate; /* default lightmap compensate value */ - int miniMapSize; /* minimap size */ - float miniMapSharpen; /* minimap sharpening coefficient */ - float miniMapBorder; /* minimap border amount */ - qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */ - miniMapMode_t miniMapMode; /* minimap mode */ + int miniMapSize; /* minimap size */ + float miniMapSharpen; /* minimap sharpening coefficient */ + float miniMapBorder; /* minimap border amount */ + qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */ + miniMapMode_t miniMapMode; /* minimap mode */ char *miniMapNameFormat; /* minimap name format */ char *bspIdent; /* 4-letter bsp file prefix */ int bspVersion; /* bsp version to use */ @@ -1131,7 +1131,7 @@ typedef struct node_s struct portal_s *portals; /* also on nodes during construction */ - qboolean has_structural_children; + qboolean has_structural_children; } node_t; @@ -1766,7 +1766,7 @@ void DirtyRawLightmap( int num ); void IlluminateRawLightmap( int num ); void IlluminateVertexes( int num ); -void SetupBrushesFlags( int mask_any, int test_any, int mask_all, int test_all ); +void SetupBrushesFlags( unsigned int mask_any, unsigned int test_any, unsigned int mask_all, unsigned int test_all ); void SetupBrushes( void ); void SetupClusters( void ); qboolean ClusterVisible( int a, int b ); @@ -1822,7 +1822,7 @@ void EmitVertexRemapShader( char *from, char *to ); void LoadShaderInfo( void ); shaderInfo_t *ShaderInfoForShader( const char *shader ); -shaderInfo_t *ShaderInfoForShaderNull( const char *shader ); +shaderInfo_t *ShaderInfoForShaderNull( const char *shader ); /* bspfile_abstract.c */ @@ -1897,7 +1897,7 @@ Q_EXTERN game_t games[] , #include "game_tremulous.h" /*LinuxManMikeC: must be after game_quake3.h, depends on #define's set in it */ , - #include "game_unvanquished.h" /* must be after game_quake3.h as they share defines! */ + #include "game_unvanquished.h" /* must be after game_tremulous.h as they share defines! */ , #include "game_tenebrae.h" , @@ -1919,7 +1919,7 @@ Q_EXTERN game_t games[] , #include "game_reaction.h" /* must be after game_quake3.h */ , - #include "game__null.h" /* null game (must be last item) */ + #include "game__null.h" /* null game (must be last item) */ }; #endif Q_EXTERN game_t *game Q_ASSIGN( &games[ 0 ] ); @@ -1967,8 +1967,8 @@ Q_EXTERN qboolean nofog Q_ASSIGN( qfalse ); Q_EXTERN qboolean noHint Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean renameModelShaders Q_ASSIGN( qfalse ); /* ydnar */ Q_EXTERN qboolean skyFixHack Q_ASSIGN( qfalse ); /* ydnar */ -Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */ -Q_EXTERN qboolean deepBSP Q_ASSIGN( qfalse ); /* div0 */ +Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */ +Q_EXTERN qboolean deepBSP Q_ASSIGN( qfalse ); /* div0 */ Q_EXTERN int patchSubdivisions Q_ASSIGN( 8 ); /* ydnar: -patchmeta subdivisions */ @@ -2098,17 +2098,16 @@ Q_EXTERN m4x4_t skyboxTransform; ------------------------------------------------------------------------------- */ /* commandline arguments */ -Q_EXTERN qboolean fastvis; -Q_EXTERN qboolean noPassageVis; -Q_EXTERN qboolean passageVisOnly; -Q_EXTERN qboolean mergevis; -Q_EXTERN qboolean mergevisportals; -Q_EXTERN qboolean nosort; -Q_EXTERN qboolean saveprt; -Q_EXTERN qboolean hint; /* ydnar */ -Q_EXTERN char inbase[ MAX_QPATH ]; -Q_EXTERN char inbase[ MAX_QPATH ]; -Q_EXTERN char globalCelShader[ MAX_QPATH ]; +Q_EXTERN qboolean fastvis; +Q_EXTERN qboolean noPassageVis; +Q_EXTERN qboolean passageVisOnly; +Q_EXTERN qboolean mergevis; +Q_EXTERN qboolean mergevisportals; +Q_EXTERN qboolean nosort; +Q_EXTERN qboolean saveprt; +Q_EXTERN qboolean hint; /* ydnar */ +Q_EXTERN char inbase[ MAX_QPATH ]; +Q_EXTERN char globalCelShader[ MAX_QPATH ]; /* other bits */ Q_EXTERN int totalvis; @@ -2394,7 +2393,7 @@ Q_EXTERN int numBSPBrushSides Q_ASSIGN( 0 ); Q_EXTERN bspBrushSide_t bspBrushSides[ MAX_MAP_BRUSHSIDES ]; Q_EXTERN int numBSPLightBytes Q_ASSIGN( 0 ); -Q_EXTERN byte *bspLightBytes Q_ASSIGN( NULL ); +Q_EXTERN byte *bspLightBytes Q_ASSIGN( NULL ); //% Q_EXTERN int numBSPGridPoints Q_ASSIGN( 0 ); //% Q_EXTERN byte *bspGridPoints Q_ASSIGN( NULL ); @@ -2406,7 +2405,7 @@ Q_EXTERN int numBSPVisBytes Q_ASSIGN( 0 ); Q_EXTERN byte bspVisBytes[ MAX_MAP_VISIBILITY ]; Q_EXTERN int numBSPDrawVerts Q_ASSIGN( 0 ); -Q_EXTERN bspDrawVert_t *bspDrawVerts Q_ASSIGN( NULL ); +Q_EXTERN bspDrawVert_t *bspDrawVerts Q_ASSIGN( NULL ); Q_EXTERN int numBSPDrawIndexes Q_ASSIGN( 0 ); Q_EXTERN int bspDrawIndexes[ MAX_MAP_DRAW_INDEXES ]; diff --git a/tools/quake3/q3map2/shaders.c b/tools/quake3/q3map2/shaders.c index dfbc7f19..160a5bb5 100644 --- a/tools/quake3/q3map2/shaders.c +++ b/tools/quake3/q3map2/shaders.c @@ -802,9 +802,10 @@ static void LoadShaderImages( shaderInfo_t *si ){ */ shaderInfo_t *ShaderInfoForShaderNull( const char *shaderName ){ - if(!strcmp(shaderName, "noshader")) + if ( !strcmp( shaderName, "noshader" ) ) { return NULL; - return ShaderInfoForShader(shaderName); + } + return ShaderInfoForShader( shaderName ); } shaderInfo_t *ShaderInfoForShader( const char *shaderName ){ @@ -1464,7 +1465,7 @@ static void ParseShaderFile( const char *filename ){ si->lightmapSampleSize = atoi( token ); } - /* q3map_lightmapSampleSffset */ + /* q3map_lightmapSampleOffset */ else if ( !Q_stricmp( token, "q3map_lightmapSampleOffset" ) ) { GetTokenAppend( shaderText, qfalse ); si->lightmapSampleOffset = atof( token );