]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/bsp.c
unfinished -minimap support in bsp.c, do not use yet, format is not correct yet
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bsp.c
index 2b29ff5ec6a34f5ecebb482faf371fd26b8e2253..4e7ab840159c3a0e791df22ebd2b0065959d620d 100644 (file)
@@ -44,6 +44,132 @@ 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()
@@ -264,7 +390,6 @@ void ProcessWorldModel( void )
        char            level[ 2 ], shader[ 1024 ];
        const char      *value;
        
-       
        /* sets integer blockSize from worldspawn "_blocksize" key if it exists */
        value = ValueForKey( &entities[ 0 ], "_blocksize" );
        if( value[ 0 ] == '\0' )
@@ -601,6 +726,9 @@ void ProcessModels( void )
        
        /* write fogs */
        EmitFogs();
+
+       /* vortex: emit meta stats */
+       EmitMetaStats();
 }
 
 
@@ -614,18 +742,34 @@ void OnlyEnts( void )
 {
        char out[ 1024 ];
 
+       char save_cmdline[1024], save_version[1024];
+       const char *p;
        
        /* note it */
        Sys_Printf( "--- OnlyEnts ---\n" );
        
        sprintf( out, "%s.bsp", source );
        LoadBSPFile( out );
+
+       ParseEntities();
+       p = ValueForKey(&entities[0], "_q3map2_cmdline");
+       strncpy(save_cmdline, p, sizeof(save_cmdline));
+       save_cmdline[sizeof(save_cmdline)-1] = 0;
+       p = ValueForKey(&entities[0], "_q3map2_version");
+       strncpy(save_version, p, sizeof(save_version));
+       save_version[sizeof(save_version)-1] = 0;
+
        numEntities = 0;
 
        LoadShaderInfo();
        LoadMapFile( name, qfalse );
        SetModelNumbers();
        SetLightStyles();
+
+       if(*save_cmdline)
+               SetKeyValue(&entities[0], "_q3map2_cmdline", save_cmdline);
+       if(*save_version)
+               SetKeyValue(&entities[0], "_q3map2_version", save_version);
        
        numBSPEntities = numEntities;
        UnparseEntities();
@@ -656,6 +800,7 @@ int BSPMain( int argc, char **argv )
        numMapDrawSurfs = 0;
        
        tempSource[ 0 ] = '\0';
+       globalCelShader[0] = 0;
        
        /* set standard game flags */
        maxSurfaceVerts = game->maxSurfaceVerts;
@@ -820,6 +965,15 @@ int BSPMain( int argc, char **argv )
                        Sys_Printf( "Flatshading enabled\n" );
                        flat = qtrue;
                }
+               else if( !strcmp( argv[ i ], "-celshader" ) )
+               {
+                       ++i;
+                       if(argv[i][0])
+                               sprintf( globalCelShader, "textures/%s", argv[ i ] );
+                       else
+                               *globalCelShader = 0;
+                       Sys_Printf( "Global cel shader set to \"%s\"\n", globalCelShader );
+               }
                else if( !strcmp( argv[ i ], "-meta" ) )
                {
                        Sys_Printf( "Creating meta surfaces from brush faces\n" );
@@ -860,6 +1014,21 @@ 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 ], "-deep" ) )
+               {
+                       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
@@ -913,6 +1082,9 @@ int BSPMain( int argc, char **argv )
        else
                LoadMapFile( name, qfalse );
        
+       /* div0: inject command line parameters */
+       InjectCommandLine(argv, 1, argc - 1);
+       
        /* ydnar: decal setup */
        ProcessDecals();
        
@@ -931,6 +1103,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)
                remove( tempSource );