audit all uses of ClipWindingEpsilon and choose the strict variant or not, and explai...
authorRudolf Polzer <divverent@xonotic.org>
Wed, 23 Nov 2011 08:44:05 +0000 (09:44 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Wed, 23 Nov 2011 08:44:05 +0000 (09:44 +0100)
tools/quake3/q3map2/brush.c
tools/quake3/q3map2/decals.c
tools/quake3/q3map2/facebsp.c
tools/quake3/q3map2/fog.c
tools/quake3/q3map2/portals.c
tools/quake3/q3map2/surface.c

index b7c50f4..eefaa75 100644 (file)
@@ -1027,8 +1027,8 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
                w = s->winding;
                if (!w)
                        continue;
-               ClipWindingEpsilon (w, plane->normal, plane->dist,
-                       0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
+               ClipWindingEpsilonStrict (w, plane->normal, plane->dist,
+                       0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]); /* strict, in parallel case we get the face back because it also is the midwinding */
                for (j=0 ; j<2 ; j++)
                {
                        if (!cw[j])
index a130334..b500eef 100644 (file)
@@ -594,7 +594,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
        for( i = 0; i < dp->numPlanes; i++ )
        {
                /* chop winding by the plane */
-               ClipWindingEpsilon( w, dp->planes[ i ], dp->planes[ i ][ 3 ], 0.0625f, &front, &back );
+               ClipWindingEpsilonStrict( w, dp->planes[ i ], dp->planes[ i ][ 3 ], 0.0625f, &front, &back ); /* strict, if identical plane we don't want to keep it */
                FreeWinding( w );
                
                /* lose the front fragment */
index 1699784..2e4ffff 100644 (file)
@@ -295,8 +295,8 @@ void BuildFaceTree_r( node_t *node, face_t *list )
                /* switch on side */
                if( side == SIDE_CROSS )
                {
-                       ClipWindingEpsilon( split->w, plane->normal, plane->dist, CLIP_EPSILON * 2,
-                               &frontWinding, &backWinding );
+                       ClipWindingEpsilonStrict( split->w, plane->normal, plane->dist, CLIP_EPSILON * 2,
+                               &frontWinding, &backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */
                        if( frontWinding ) {
                                newFace = AllocBspFace();
                                newFace->w = frontWinding;
index c9ee6e2..ed59d7e 100644 (file)
@@ -408,7 +408,7 @@ qboolean ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b )
                        continue;
                
                /* general case */
-               ClipWindingEpsilon( w, plane->normal, plane->dist, ON_EPSILON, &front, &back );
+               ClipWindingEpsilonStrict( w, plane->normal, plane->dist, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */
                FreeWinding( w );
                
                if( back == NULL )
index 2efc1db..e16c12c 100644 (file)
@@ -410,7 +410,7 @@ void SplitNodePortals (node_t *node)
 // cut the portal into two portals, one on each side of the cut plane
 //
                ClipWindingEpsilon (p->winding, plane->normal, plane->dist,
-                       SPLIT_WINDING_EPSILON, &frontwinding, &backwinding);
+                       SPLIT_WINDING_EPSILON, &frontwinding, &backwinding); /* not strict, we want to always keep one of them even if coplanar */
 
                if (frontwinding && WindingIsTiny(frontwinding))
                {
index 5914c40..e2ec890 100644 (file)
@@ -1356,7 +1356,7 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_
                if( (subCeil - subFloor) > subdivisions )
                {
                        /* clip the winding */
-                       ClipWindingEpsilon( w, planeNormal, d, epsilon, &frontWinding, &backWinding );
+                       ClipWindingEpsilon( w, planeNormal, d, epsilon, &frontWinding, &backWinding ); /* not strict; we assume we always keep a winding */
 
                        /* the clip may not produce two polygons if it was epsilon close */
                        if( frontWinding == NULL )
@@ -1498,8 +1498,14 @@ void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node )
                }
 
                plane = &mapplanes[ node->planenum ];
-               ClipWindingEpsilon ( w, plane->normal, plane->dist,
-                               ON_EPSILON, &front, &back );
+               ClipWindingEpsilonStrict ( w, plane->normal, plane->dist,
+                               ON_EPSILON, &front, &back ); /* strict, we handle the "winding disappeared" case */
+               if(!front && !back)
+               {
+                       /* in doubt, register it in both nodes */
+                       front = CopyWinding(w);
+                       back = CopyWinding(w);
+               }
                FreeWinding( w );
 
                ClipSideIntoTree_r( front, side, node->children[0] );
@@ -2108,7 +2114,7 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node )
                }
                
                /* clip the winding by this plane */
-               ClipWindingEpsilonStrict( w, plane1, plane1[ 3 ], ON_EPSILON, &front, &back );
+               ClipWindingEpsilonStrict( w, plane1, plane1[ 3 ], ON_EPSILON, &front, &back ); /* strict; we handle the "winding disappeared" case */
                
                /* filter by this plane */
                refs = 0;