fix two other bugs in the same function
[xonotic/netradiant.git] / tools / quake3 / q3map2 / tjunction.c
index 416d56c363986fc0eaed535a8c873cf4915891b6..f274f9580a38cff8791ce0608e5b119093272234 100644 (file)
@@ -55,7 +55,7 @@ typedef struct edgeLine_s {
        vec3_t          origin;
        vec3_t          dir;
 
-       edgePoint_t     chain;          // unused element of doubly linked list
+       edgePoint_t     *chain;         // unused element of doubly linked list
 } edgeLine_t;
 
 typedef struct {
@@ -100,14 +100,14 @@ void InsertPointOnEdge( vec3_t v, edgeLine_t *e ) {
        p->intercept = d;
        VectorCopy( v, p->xyz );
 
-       if ( e->chain.next == &e->chain ) {
-               e->chain.next = e->chain.prev = p;
-               p->next = p->prev = &e->chain;
+       if ( e->chain->next == e->chain ) {
+               e->chain->next = e->chain->prev = p;
+               p->next = p->prev = e->chain;
                return;
        }
 
-       scan = e->chain.next;
-       for ( ; scan != &e->chain ; scan = scan->next ) {
+       scan = e->chain->next;
+       for ( ; scan != e->chain ; scan = scan->next ) {
                d = p->intercept - scan->intercept;
                if ( d > -LINE_POSITION_EPSILON && d < LINE_POSITION_EPSILON ) {
                        free( p );
@@ -195,7 +195,8 @@ int AddEdge( vec3_t v1, vec3_t v2, qboolean createNonAxial ) {
        e = &edgeLines[ numEdgeLines ];
        numEdgeLines++;
 
-       e->chain.next = e->chain.prev = &e->chain;
+       e->chain = safe_malloc( sizeof(edgePoint_t) );
+       e->chain->next = e->chain->prev = e->chain;
 
        VectorCopy( v1, e->origin );
        VectorCopy( dir, e->dir );
@@ -373,12 +374,12 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) {
 
 
                if ( start < end ) {
-                       p = e->chain.next;
+                       p = e->chain->next;
                } else {
-                       p = e->chain.prev;
+                       p = e->chain->prev;
                }
 
-               for (  ; p != &e->chain ;  ) {
+               for (  ; p != e->chain ;  ) {
                        if ( start < end ) {
                                if ( p->intercept > end - ON_EPSILON ) {
                                        break;
@@ -515,7 +516,6 @@ int         c_broken = 0;
 
 qboolean FixBrokenSurface( mapDrawSurface_t *ds )
 {
-       qboolean        valid = qtrue;
        bspDrawVert_t   *dv1, *dv2, avg;
        int                     i, j, k;
        float           dist;
@@ -530,10 +530,6 @@ qboolean FixBrokenSurface( mapDrawSurface_t *ds )
        /* check all verts */
        for( i = 0; i < ds->numVerts; i++ )
        {
-               /* don't remove points if winding is a triangle */
-               if( ds->numVerts == 3 )
-                       return valid;
-               
                /* get verts */
                dv1 = &ds->verts[ i ];
                dv2 = &ds->verts[ (i + 1) % ds->numVerts ];
@@ -543,7 +539,6 @@ qboolean FixBrokenSurface( mapDrawSurface_t *ds )
                dist = VectorLength( avg.xyz );
                if( dist < DEGENERATE_EPSILON )
                {
-                       valid = qfalse;
                        Sys_FPrintf( SYS_VRB, "WARNING: Degenerate T-junction edge found, fixing...\n" );
 
                        /* create an average drawvert */
@@ -577,13 +572,16 @@ qboolean FixBrokenSurface( mapDrawSurface_t *ds )
                                memcpy( dv2, dv1, sizeof( bspDrawVert_t ) );
                        }
                        ds->numVerts--;
+                       
+                       /* after welding, we have to consider the same vertex again, as it now has a new neighbor dv2 */
+                       --i;
+
+                       /* should ds->numVerts have become 0, then i is now -1. In the next iteration, the loop will abort. */
                }
        }
        
        /* one last check and return */
-       if( ds->numVerts < 3 )
-               valid = qfalse;
-       return valid;
+       return ds->numVerts >= 3;
 }
 
 
@@ -628,7 +626,7 @@ void FixTJunctions( entity_t *ent )
        shaderInfo_t            *si;
        int                                     axialEdgeLines;
        originalEdge_t          *e;
-       
+       bspDrawVert_t   *dv;
        
        /* meta mode has its own t-junction code (currently not as good as this code) */
        //%     if( meta )
@@ -679,7 +677,8 @@ void FixTJunctions( entity_t *ent )
        // this gives the most accurate edge description
        for ( i = 0 ; i < numOriginalEdges ; i++ ) {
                e = &originalEdges[i];
-               e->dv[ 0 ]->lightmap[ 0 ][ 0 ] = AddEdge( e->dv[ 0 ]->xyz, e->dv[ 1 ]->xyz, qtrue );
+               dv = e->dv[0]; // e might change during AddEdge
+               dv->lightmap[ 0 ][ 0 ] = AddEdge( e->dv[ 0 ]->xyz, e->dv[ 1 ]->xyz, qtrue );
        }
 
        Sys_FPrintf( SYS_VRB, "%9d axial edge lines\n", axialEdgeLines );