]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/tjunction.c
Merge branch 'smooth' into 'master'
[xonotic/netradiant.git] / tools / quake3 / q3map2 / tjunction.c
index 50e5d7c4d1536677f0a1a70fdb41a2b766060661..c405d3170b5de1d0001b3d913039d3703b164780 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 {
@@ -63,14 +63,14 @@ typedef struct {
        bspDrawVert_t   *dv[2];
 } originalEdge_t;
 
-#define MAX_ORIGINAL_EDGES  0x20000
-originalEdge_t originalEdges[MAX_ORIGINAL_EDGES];
+originalEdge_t  *originalEdges = NULL;
 int numOriginalEdges;
+int allocatedOriginalEdges = 0;
 
 
-#define MAX_EDGE_LINES      0x10000
-edgeLine_t edgeLines[MAX_EDGE_LINES];
+edgeLine_t      *edgeLines = NULL;
 int numEdgeLines;
+int allocatedEdgeLines = 0;
 
 int c_degenerateEdges;
 int c_addedVerts;
@@ -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 );
@@ -153,9 +153,7 @@ int AddEdge( vec3_t v1, vec3_t v2, qboolean createNonAxial ) {
 
        if ( !createNonAxial ) {
                if ( fabs( dir[0] + dir[1] + dir[2] ) != 1.0 ) {
-                       if ( numOriginalEdges == MAX_ORIGINAL_EDGES ) {
-                               Error( "MAX_ORIGINAL_EDGES" );
-                       }
+                       AUTOEXPAND_BY_REALLOC( originalEdges, numOriginalEdges, allocatedOriginalEdges, 1024 );
                        originalEdges[ numOriginalEdges ].dv[0] = (bspDrawVert_t *)v1;
                        originalEdges[ numOriginalEdges ].dv[1] = (bspDrawVert_t *)v2;
                        originalEdges[ numOriginalEdges ].length = d;
@@ -192,14 +190,13 @@ int AddEdge( vec3_t v1, vec3_t v2, qboolean createNonAxial ) {
        }
 
        // create a new edge
-       if ( numEdgeLines >= MAX_EDGE_LINES ) {
-               Error( "MAX_EDGE_LINES" );
-       }
+       AUTOEXPAND_BY_REALLOC( edgeLines, numEdgeLines, allocatedEdgeLines, 1024 );
 
        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 );
@@ -331,23 +328,18 @@ void FixSurfaceJunctions( mapDrawSurface_t *ds ) {
        int i, j, k;
        edgeLine_t  *e;
        edgePoint_t *p;
-       int originalVerts;
        int counts[MAX_SURFACE_VERTS];
        int originals[MAX_SURFACE_VERTS];
-       int firstVert[MAX_SURFACE_VERTS];
        bspDrawVert_t verts[MAX_SURFACE_VERTS], *v1, *v2;
        int numVerts;
        float start, end, frac, c;
        vec3_t delta;
 
 
-       originalVerts = ds->numVerts;
-
        numVerts = 0;
        for ( i = 0 ; i < ds->numVerts ; i++ )
        {
                counts[i] = 0;
-               firstVert[i] = numVerts;
 
                // copy first vert
                if ( numVerts == MAX_SURFACE_VERTS ) {
@@ -375,13 +367,13 @@ 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;
@@ -520,7 +512,6 @@ extern void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out );
 int c_broken = 0;
 
 qboolean FixBrokenSurface( mapDrawSurface_t *ds ){
-       qboolean valid = qtrue;
        bspDrawVert_t   *dv1, *dv2, avg;
        int i, j, k;
        float dist;
@@ -537,11 +528,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 ];
@@ -550,7 +536,6 @@ qboolean FixBrokenSurface( mapDrawSurface_t *ds ){
                VectorSubtract( dv1->xyz, dv2->xyz, avg.xyz );
                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 */
@@ -584,14 +569,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;
 }
 
 
@@ -610,8 +597,8 @@ qboolean FixBrokenSurface( mapDrawSurface_t *ds ){
 int EdgeCompare( const void *elem1, const void *elem2 ) {
        float d1, d2;
 
-       d1 = ( (originalEdge_t *)elem1 )->length;
-       d2 = ( (originalEdge_t *)elem2 )->length;
+       d1 = ( (const originalEdge_t *)elem1 )->length;
+       d2 = ( (const originalEdge_t *)elem2 )->length;
 
        if ( d1 < d2 ) {
                return -1;
@@ -635,7 +622,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 )
@@ -687,7 +674,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 );