]> git.xonotic.org Git - xonotic/netradiant.git/commitdiff
-minimap is now a main option... to be used on already compiled BSPs
authordivverent <divverent@61c419a2-8eb2-4b30-bcec-8cead039b335>
Sun, 26 Apr 2009 09:34:11 +0000 (09:34 +0000)
committerdivverent <divverent@61c419a2-8eb2-4b30-bcec-8cead039b335>
Sun, 26 Apr 2009 09:34:11 +0000 (09:34 +0000)
git-svn-id: svn://svn.icculus.org/netradiant/trunk@329 61c419a2-8eb2-4b30-bcec-8cead039b335

tools/quake3/q3map2/bsp.c
tools/quake3/q3map2/main.c

index 4e7ab840159c3a0e791df22ebd2b0065959d620d..a5550975a2034036d30c57fb05e4597606321444 100644 (file)
@@ -44,133 +44,6 @@ functions
 
 ------------------------------------------------------------------------------- */
 
-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
@@ -1024,11 +897,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
@@ -1103,10 +971,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)
                remove( tempSource );
index b113247bd4205a5776c1d373d5abf46321b67df3..4b8f5f4e926f5b72ad65640e4dedb6d880703f38 100644 (file)
@@ -64,6 +64,291 @@ 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] <mapname>\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;
+}
+
+
+
+
+
 /*
 MD4BlockChecksum()
 calculates an md4 checksum for a block of data
@@ -74,8 +359,6 @@ static int MD4BlockChecksum( void *buffer, int length )
        return Com_BlockChecksum(buffer, length);
 }
 
-
-
 /*
 FixAAS()
 resets an aas checksum to match the given BSP
@@ -927,6 +1210,10 @@ int main( int argc, char **argv )
        else if( !strcmp( argv[ 1 ], "-convert" ) )
                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 );