]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/surface.c
fix uninitialized use of an int when filtering a patch into a tree - possible perform...
[xonotic/netradiant.git] / tools / quake3 / q3map2 / surface.c
index 43ff1970c59246107e5c3babd4c64c6c762c04e6..b5dd724e15d9ee564b548f465129ec8d80108ff3 100644 (file)
@@ -291,7 +291,7 @@ deletes all empty or bad surfaces from the surface list
 void TidyEntitySurfaces( entity_t *e )
 {
        int                                     i, j, deleted;
-       mapDrawSurface_t        *out, *in;
+       mapDrawSurface_t        *out, *in = NULL;
        
        
        /* note it */
@@ -1207,7 +1207,7 @@ DrawSurfaceForFlare() - ydnar
 creates a flare draw surface
 */
 
-mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, char *flareShader, int lightStyle )
+mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, const char *flareShader, int lightStyle )
 {
        mapDrawSurface_t        *ds;
        
@@ -1970,7 +1970,7 @@ FilterPointConvexHullIntoTree_r() - ydnar
 filters the convex hull of multiple points from a surface into the tree
 */
 
-int FilterPointConvexHullIntoTree_r( vec_t **points, int npoints, mapDrawSurface_t *ds, node_t *node )
+int FilterPointConvexHullIntoTree_r( vec3_t **points, int npoints, mapDrawSurface_t *ds, node_t *node )
 {
        float                   d, dmin, dmax;
        plane_t                 *plane;
@@ -1986,10 +1986,10 @@ int FilterPointConvexHullIntoTree_r( vec_t **points, int npoints, mapDrawSurface
                /* classify the point in relation to the plane */
                plane = &mapplanes[ node->planenum ];
 
-               dmin = dmax = DotProduct( points[0], plane->normal ) - plane->dist;
+               dmin = dmax = DotProduct( *(points[0]), plane->normal ) - plane->dist;
                for(i = 1; i < npoints; ++i)
                {
-                       d = DotProduct( points[i], plane->normal ) - plane->dist;
+                       d = DotProduct( *(points[i]), plane->normal ) - plane->dist;
                        if(d > dmax)
                                dmax = d;
                        if(d < dmin)
@@ -2037,14 +2037,25 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node )
        {
                /* 'fatten' the winding by the shader mins/maxs (parsed from vertexDeform move) */
                /* note this winding is completely invalid (concave, nonplanar, etc) */
-               fat = AllocWinding( w->numpoints * 3 );
-               fat->numpoints = w->numpoints * 3;
+               fat = AllocWinding( w->numpoints * 3 + 3 );
+               fat->numpoints = w->numpoints * 3 + 3;
                for( i = 0; i < w->numpoints; i++ )
                {
                        VectorCopy( w->p[ i ], fat->p[ i ] );
-                       VectorAdd( w->p[ i ], si->mins, fat->p[ i * 2 ] );
-                       VectorAdd( w->p[ i ], si->maxs, fat->p[ i * 3 ] );
+                       VectorAdd( w->p[ i ], si->mins, fat->p[ i + (w->numpoints+1) ] );
+                       VectorAdd( w->p[ i ], si->maxs, fat->p[ i + (w->numpoints+1) * 2 ] );
                }
+               VectorCopy( w->p[ 0 ], fat->p[ i ] );
+               VectorAdd( w->p[ 0 ], si->mins, fat->p[ i + w->numpoints ] );
+               VectorAdd( w->p[ 0 ], si->maxs, fat->p[ i + w->numpoints * 2 ] );
+
+               /*
+                * note: this winding is STILL not suitable for ClipWindingEpsilon, and
+                * also does not really fulfill the intention as it only contains
+                * origin, +mins, +maxs, but thanks to the "closing" points I just
+                * added to the three sub-windings, the fattening at least doesn't make
+                * it worse
+                */
                
                FreeWinding( w );
                w = fat;
@@ -2136,21 +2147,21 @@ subdivides a patch into an approximate curve and filters it into the tree
 
 static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree )
 {
-       int                                     x, y, refs;
+       int                                     x, y, refs = 0;
        
        for(y = 0; y + 2 < ds->patchHeight; y += 2)
                for(x = 0; x + 2 < ds->patchWidth; x += 2)
                {
-                       vec_t *points[9];
-                       points[0] = ds->verts[(y+0) * ds->patchWidth + (x+0)].xyz;
-                       points[1] = ds->verts[(y+0) * ds->patchWidth + (x+1)].xyz;
-                       points[2] = ds->verts[(y+0) * ds->patchWidth + (x+2)].xyz;
-                       points[3] = ds->verts[(y+1) * ds->patchWidth + (x+0)].xyz;
-                       points[4] = ds->verts[(y+1) * ds->patchWidth + (x+1)].xyz;
-                       points[5] = ds->verts[(y+1) * ds->patchWidth + (x+2)].xyz;
-                       points[6] = ds->verts[(y+2) * ds->patchWidth + (x+0)].xyz;
-                       points[7] = ds->verts[(y+2) * ds->patchWidth + (x+1)].xyz;
-                       points[8] = ds->verts[(y+2) * ds->patchWidth + (x+2)].xyz;
+                       vec3_t *points[9];
+                       points[0] = &ds->verts[(y+0) * ds->patchWidth + (x+0)].xyz;
+                       points[1] = &ds->verts[(y+0) * ds->patchWidth + (x+1)].xyz;
+                       points[2] = &ds->verts[(y+0) * ds->patchWidth + (x+2)].xyz;
+                       points[3] = &ds->verts[(y+1) * ds->patchWidth + (x+0)].xyz;
+                       points[4] = &ds->verts[(y+1) * ds->patchWidth + (x+1)].xyz;
+                       points[5] = &ds->verts[(y+1) * ds->patchWidth + (x+2)].xyz;
+                       points[6] = &ds->verts[(y+2) * ds->patchWidth + (x+0)].xyz;
+                       points[7] = &ds->verts[(y+2) * ds->patchWidth + (x+1)].xyz;
+                       points[8] = &ds->verts[(y+2) * ds->patchWidth + (x+2)].xyz;
                        refs += FilterPointConvexHullIntoTree_r(points, 9, ds, tree->headnode);
                }
 
@@ -2839,7 +2850,10 @@ emits a bsp planar winding (brush face) drawsurface
 static void EmitFaceSurface(mapDrawSurface_t *ds )
 {
        /* strip/fan finding was moved elsewhere */
-       StripFaceSurface( ds );
+       if(maxAreaFaceSurface)
+               MaxAreaFaceSurface( ds );
+       else
+               StripFaceSurface( ds );
        EmitTriangleSurface(ds);
 }
 
@@ -3094,7 +3108,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b
                        /* roll the dice (model's odds scaled by vertex alpha) */
                        odds = model->odds * (tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ]) / 765.0f;
                        r = Random();
-                       if( r > model->odds )
+                       if( r > odds )
                                return 0;
                        
                        /* calculate scale */
@@ -3159,7 +3173,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b
                        }
                        
                        /* insert the model */
-                       InsertModel( (char *) model->model, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 );
+                       InsertModel( (char *) model->model, 0, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 );
                        
                        /* return to sender */
                        return 1;
@@ -3437,6 +3451,7 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree )
        vec3_t                          origin, mins, maxs;
        int                                     refs;
        int                                     numSurfs, numRefs, numSkyboxSurfaces;
+       qboolean        sb;
        
        
        /* note it */
@@ -3455,15 +3470,18 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree )
                
                /* get shader */
                si = ds->shaderInfo;
-               
+
                /* ydnar: skybox surfaces are special */
                if( ds->skybox )
                {
                        refs = AddReferenceToTree_r( ds, tree->headnode, qtrue );
                        ds->skybox = qfalse;
+                       sb = qtrue;
                }
                else
                {
+                       sb = qfalse;
+
                        /* refs initially zero */
                        refs = 0;
                        
@@ -3583,6 +3601,11 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree )
                                refs = 0;
                                break;
                }
+
+               /* maybe surface got marked as skybox again */
+               /* if we keep that flag, it will get scaled up AGAIN */
+               if(sb)
+                       ds->skybox = qfalse;
                
                /* tot up the references */
                if( refs > 0 )
@@ -3621,6 +3644,7 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree )
        Sys_FPrintf( SYS_VRB, "%9d (%d) emitted drawsurfs\n", numSurfs, numBSPDrawSurfaces );
        Sys_FPrintf( SYS_VRB, "%9d stripped face surfaces\n", numStripSurfaces );
        Sys_FPrintf( SYS_VRB, "%9d fanned face surfaces\n", numFanSurfaces );
+       Sys_FPrintf( SYS_VRB, "%9d maxarea'd face surfaces\n", numMaxAreaSurfaces );
        Sys_FPrintf( SYS_VRB, "%9d surface models generated\n", numSurfaceModels );
        Sys_FPrintf( SYS_VRB, "%9d skybox surfaces generated\n", numSkyboxSurfaces );
        for( i = 0; i < NUM_SURFACE_TYPES; i++ )