#include "qbsp.h"
Include dependency graph for tjunction.c:

Go to the source code of this file.
Data Structures | |
| struct | edgeLine_s |
| struct | edgePoint_s |
| struct | originalEdge_t |
Defines | |
| #define | LINE_POSITION_EPSILON 0.25 |
| #define | MAX_EDGE_LINES 0x10000 |
| #define | MAX_ORIGINAL_EDGES 0x10000 |
| #define | MAX_SURFACE_VERTS 256 |
| #define | POINT_ON_LINE_EPSILON 0.25 |
Typedefs | |
| typedef edgeLine_s | edgeLine_t |
| typedef edgePoint_s | edgePoint_t |
Functions | |
| int | AddEdge (vec3_t v1, vec3_t v2, qboolean createNonAxial) |
| void | AddPatchEdges (mapDrawSurface_t *ds) |
| void | AddSurfaceEdges (mapDrawSurface_t *ds) |
| qboolean | ColinearEdge (vec3_t v1, vec3_t v2, vec3_t v3) |
| int | EdgeCompare (const void *elem1, const void *elem2) |
| void | FixSurfaceJunctions (mapDrawSurface_t *ds) |
| void | FixTJunctions (entity_t *ent) |
| void | InsertPointOnEdge (vec3_t v, edgeLine_t *e) |
Variables | |
| int | c_addedVerts |
| int | c_cant |
| int | c_degenerateEdges |
| int | c_natural |
| int | c_rotate |
| int | c_totalVerts |
| edgeLine_t | edgeLines [MAX_EDGE_LINES] |
| int | numEdgeLines |
| int | numOriginalEdges |
| originalEdge_t | originalEdges [MAX_ORIGINAL_EDGES] |
|
|
Definition at line 65 of file tjunction.c. Referenced by InsertPointOnEdge(). |
|
|
Definition at line 53 of file tjunction.c. |
|
|
Definition at line 48 of file tjunction.c. |
|
|
Definition at line 304 of file tjunction.c. |
|
|
Definition at line 66 of file tjunction.c. Referenced by AddEdge(). |
|
|
Referenced by AddEdge(), FixSurfaceJunctions(), and InsertPointOnEdge(). |
|
|
Referenced by FixSurfaceJunctions(), and InsertPointOnEdge(). |
|
||||||||||||||||
|
Definition at line 122 of file tjunction.c. References c_degenerateEdges, edgeLine_s::chain, d, edgeLine_s::dir, edgeLine_s::dist1, edgeLine_s::dist2, DotProduct, originalEdge_t::dv, e, edgeLine_t, edgeLines, Error(), fabs(), i, InsertPointOnEdge(), originalEdge_t::length, MakeNormalVectors(), edgePoint_s::next, edgeLine_s::normal1, edgeLine_s::normal2, numEdgeLines, numOriginalEdges, edgeLine_s::origin, originalEdges, POINT_ON_LINE_EPSILON, edgePoint_s::prev, v1, v2, vec3_t, VectorCopy, VectorNormalize(), and VectorSubtract. Referenced by AddPatchEdges(), AddSurfaceEdges(), and FixTJunctions(). 00122 {
00123 int i;
00124 edgeLine_t *e;
00125 float d;
00126 vec3_t dir;
00127
00128 VectorSubtract( v2, v1, dir );
00129 d = VectorNormalize( dir, dir );
00130 if ( d < 0.1 ) {
00131 // if we added a 0 length vector, it would make degenerate planes
00132 c_degenerateEdges++;
00133 return -1;
00134 }
00135
00136 if ( !createNonAxial ) {
00137 if ( fabs( dir[0] + dir[1] + dir[2] ) != 1.0 ) {
00138 if ( numOriginalEdges == MAX_ORIGINAL_EDGES ) {
00139 Error( "MAX_ORIGINAL_EDGES" );
00140 }
00141 originalEdges[ numOriginalEdges ].dv[0] = (drawVert_t *)v1;
00142 originalEdges[ numOriginalEdges ].dv[1] = (drawVert_t *)v2;
00143 originalEdges[ numOriginalEdges ].length = d;
00144 numOriginalEdges++;
00145 return -1;
00146 }
00147 }
00148
00149 for ( i = 0 ; i < numEdgeLines ; i++ ) {
00150 e = &edgeLines[i];
00151
00152 d = DotProduct( v1, e->normal1 ) - e->dist1;
00153 if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
00154 continue;
00155 }
00156 d = DotProduct( v1, e->normal2 ) - e->dist2;
00157 if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
00158 continue;
00159 }
00160
00161 d = DotProduct( v2, e->normal1 ) - e->dist1;
00162 if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
00163 continue;
00164 }
00165 d = DotProduct( v2, e->normal2 ) - e->dist2;
00166 if ( d < -POINT_ON_LINE_EPSILON || d > POINT_ON_LINE_EPSILON ) {
00167 continue;
00168 }
00169
00170 // this is the edge
00171 InsertPointOnEdge( v1, e );
00172 InsertPointOnEdge( v2, e );
00173 return i;
00174 }
00175
00176 // create a new edge
00177 if ( numEdgeLines >= MAX_EDGE_LINES ) {
00178 Error( "MAX_EDGE_LINES" );
00179 }
00180
00181 e = &edgeLines[ numEdgeLines ];
00182 numEdgeLines++;
00183
00184 e->chain.next = e->chain.prev = &e->chain;
00185
00186 VectorCopy( v1, e->origin );
00187 VectorCopy( dir, e->dir );
00188
00189 MakeNormalVectors( e->dir, e->normal1, e->normal2 );
00190 e->dist1 = DotProduct( e->origin, e->normal1 );
00191 e->dist2 = DotProduct( e->origin, e->normal2 );
00192
00193 InsertPointOnEdge( v1, e );
00194 InsertPointOnEdge( v2, e );
00195
00196 return numEdgeLines - 1;
00197 }
|
Here is the call graph for this function:

|
|
Definition at line 251 of file tjunction.c. References AddEdge(), ColinearEdge(), i, mapDrawSurface_t, drawsurf_s::patchHeight, drawsurf_s::patchWidth, qfalse, v1, v2, drawsurf_s::verts, and drawVert_t::xyz. Referenced by FixTJunctions(). 00251 {
00252 int i;
00253 float *v1, *v2, *v3;
00254
00255 for ( i = 0 ; i < ds->patchWidth - 2; i+=2 ) {
00256 v1 = ds->verts[ i ].xyz;
00257 v2 = ds->verts[ i + 1 ].xyz;
00258 v3 = ds->verts[ i + 2 ].xyz;
00259
00260 // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
00261 if ( ColinearEdge( v1, v2, v3 ) ) {
00262 AddEdge( v1, v3, qfalse );
00263 }
00264
00265 v1 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i ].xyz;
00266 v2 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 1 ].xyz;
00267 v3 = ds->verts[ ( ds->patchHeight - 1 ) * ds->patchWidth + i + 2 ].xyz;
00268
00269 // if v2 is on the v1 to v3 line, add an edge from v1 to v3
00270 if ( ColinearEdge( v1, v2, v3 ) ) {
00271 AddEdge( v1, v3, qfalse );
00272 }
00273 }
00274
00275 for ( i = 0 ; i < ds->patchHeight - 2 ; i+=2 ) {
00276 v1 = ds->verts[ i * ds->patchWidth ].xyz;
00277 v2 = ds->verts[ ( i + 1 ) * ds->patchWidth ].xyz;
00278 v3 = ds->verts[ ( i + 2 ) * ds->patchWidth ].xyz;
00279
00280 // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
00281 if ( ColinearEdge( v1, v2, v3 ) ) {
00282 AddEdge( v1, v3, qfalse );
00283 }
00284
00285 v1 = ds->verts[ ( ds->patchWidth - 1 ) + i * ds->patchWidth ].xyz;
00286 v2 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 1 ) * ds->patchWidth ].xyz;
00287 v3 = ds->verts[ ( ds->patchWidth - 1 ) + ( i + 2 ) * ds->patchWidth ].xyz;
00288
00289 // if v2 is the midpoint of v1 to v3, add an edge from v1 to v3
00290 if ( ColinearEdge( v1, v2, v3 ) ) {
00291 AddEdge( v1, v3, qfalse );
00292 }
00293 }
00294
00295
00296 }
|
Here is the call graph for this function:

|
|
Definition at line 204 of file tjunction.c. References AddEdge(), i, drawVert_t::lightmap, mapDrawSurface_t, drawsurf_s::numVerts, qfalse, drawsurf_s::verts, and drawVert_t::xyz. Referenced by FixTJunctions(). 00204 {
00205 int i;
00206
00207 for ( i = 0 ; i < ds->numVerts ; i++ ) {
00208 // save the edge number in the lightmap field
00209 // so we don't need to look it up again
00210 ds->verts[i].lightmap[0] =
00211 AddEdge( ds->verts[i].xyz, ds->verts[(i+1) % ds->numVerts].xyz, qfalse );
00212 }
00213 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 220 of file tjunction.c. References d, DotProduct, offset, qboolean, v1, v2, vec3_t, VectorLength(), VectorNormalize(), VectorScale, and VectorSubtract. Referenced by AddPatchEdges(). 00220 {
00221 vec3_t midpoint, dir, offset, on;
00222 float d;
00223
00224 VectorSubtract( v2, v1, midpoint );
00225 VectorSubtract( v3, v1, dir );
00226 d = VectorNormalize( dir, dir );
00227 if ( d == 0 ) {
00228 return qfalse; // degenerate
00229 }
00230
00231 d = DotProduct( midpoint, dir );
00232 VectorScale( dir, d, on );
00233 VectorSubtract( midpoint, on, offset );
00234 d = VectorLength ( offset );
00235
00236 if ( d < 0.1 ) {
00237 return qtrue;
00238 }
00239
00240 return qfalse;
00241 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 468 of file tjunction.c. Referenced by FixTJunctions(). 00468 {
00469 float d1, d2;
00470
00471 d1 = ((originalEdge_t *)elem1)->length;
00472 d2 = ((originalEdge_t *)elem2)->length;
00473
00474 if ( d1 < d2 ) {
00475 return -1;
00476 }
00477 if ( d2 > d1 ) {
00478 return 1;
00479 }
00480 return 0;
00481 }
|
|
|
Definition at line 305 of file tjunction.c. References c_addedVerts, c_cant, c_natural, c_rotate, c_totalVerts, edgeLine_s::chain, edgeLine_s::dir, DotProduct, e, edgeLine_t, edgeLines, edgePoint_t, Error(), i, edgePoint_s::intercept, j, k, drawVert_t::lightmap, malloc(), mapDrawSurface_t, memcpy(), edgePoint_s::next, drawVert_t::normal, drawsurf_s::numVerts, edgeLine_s::origin, p, edgePoint_s::prev, drawVert_t::st, v1, v2, vec3_t, VectorCopy, VectorSubtract, drawsurf_s::verts, edgePoint_s::xyz, and drawVert_t::xyz. Referenced by FixTJunctions(). 00305 {
00306 int i, j, k;
00307 edgeLine_t *e;
00308 edgePoint_t *p;
00309 int originalVerts;
00310 int counts[MAX_SURFACE_VERTS];
00311 int originals[MAX_SURFACE_VERTS];
00312 int firstVert[MAX_SURFACE_VERTS];
00313 drawVert_t verts[MAX_SURFACE_VERTS], *v1, *v2;
00314 int numVerts;
00315 float start, end, frac;
00316 vec3_t delta;
00317
00318 originalVerts = ds->numVerts;
00319
00320 numVerts = 0;
00321 for ( i = 0 ; i < ds->numVerts ; i++ ) {
00322 counts[i] = 0;
00323 firstVert[i] = numVerts;
00324
00325 // copy first vert
00326 if ( numVerts == MAX_SURFACE_VERTS ) {
00327 Error( "MAX_SURFACE_VERTS" );
00328 }
00329 verts[numVerts] = ds->verts[i];
00330 originals[numVerts] = i;
00331 numVerts++;
00332
00333 // check to see if there are any t junctions before the next vert
00334 v1 = &ds->verts[i];
00335 v2 = &ds->verts[ (i+1) % ds->numVerts ];
00336
00337 j = (int)ds->verts[i].lightmap[0];
00338 if ( j == -1 ) {
00339 continue; // degenerate edge
00340 }
00341 e = &edgeLines[ j ];
00342
00343 VectorSubtract( v1->xyz, e->origin, delta );
00344 start = DotProduct( delta, e->dir );
00345
00346 VectorSubtract( v2->xyz, e->origin, delta );
00347 end = DotProduct( delta, e->dir );
00348
00349
00350 if ( start < end ) {
00351 p = e->chain.next;
00352 } else {
00353 p = e->chain.prev;
00354 }
00355
00356 for ( ; p != &e->chain ; ) {
00357 if ( start < end ) {
00358 if ( p->intercept > end - ON_EPSILON ) {
00359 break;
00360 }
00361 } else {
00362 if ( p->intercept < end + ON_EPSILON ) {
00363 break;
00364 }
00365 }
00366
00367 if (
00368 ( start < end && p->intercept > start + ON_EPSILON ) ||
00369 ( start > end && p->intercept < start - ON_EPSILON ) ) {
00370 // insert this point
00371 if ( numVerts == MAX_SURFACE_VERTS ) {
00372 Error( "MAX_SURFACE_VERTS" );
00373 }
00374
00375 // take the exact intercept point
00376 VectorCopy( p->xyz, verts[ numVerts ].xyz );
00377
00378 // copy the normal
00379 VectorCopy( v1->normal, verts[ numVerts ].normal );
00380
00381 // interpolate the texture coordinates
00382 frac = ( p->intercept - start ) / ( end - start );
00383 for ( j = 0 ; j < 2 ; j++ ) {
00384 verts[ numVerts ].st[j] = v1->st[j] +
00385 frac * ( v2->st[j] - v1->st[j] );
00386 }
00387 originals[numVerts] = i;
00388 numVerts++;
00389 counts[i]++;
00390 }
00391
00392 if ( start < end ) {
00393 p = p->next;
00394 } else {
00395 p = p->prev;
00396 }
00397 }
00398 }
00399
00400 c_addedVerts += numVerts - ds->numVerts;
00401 c_totalVerts += numVerts;
00402
00403
00404 // FIXME: check to see if the entire surface degenerated
00405 // after snapping
00406
00407 // rotate the points so that the initial vertex is between
00408 // two non-subdivided edges
00409 for ( i = 0 ; i < numVerts ; i++ ) {
00410 if ( originals[ (i+1) % numVerts ] == originals[ i ] ) {
00411 continue;
00412 }
00413 j = (i + numVerts - 1 ) % numVerts;
00414 k = (i + numVerts - 2 ) % numVerts;
00415 if ( originals[ j ] == originals[ k ] ) {
00416 continue;
00417 }
00418 break;
00419 }
00420
00421 if ( i == 0 ) {
00422 // fine the way it is
00423 c_natural++;
00424
00425 ds->numVerts = numVerts;
00426 ds->verts = malloc( numVerts * sizeof( *ds->verts ) );
00427 memcpy( ds->verts, verts, numVerts * sizeof( *ds->verts ) );
00428
00429 return;
00430 }
00431 if ( i == numVerts ) {
00432 // create a vertex in the middle to start the fan
00433 c_cant++;
00434
00435 /*
00436 memset ( &verts[numVerts], 0, sizeof( verts[numVerts] ) );
00437 for ( i = 0 ; i < numVerts ; i++ ) {
00438 for ( j = 0 ; j < 10 ; j++ ) {
00439 verts[numVerts].xyz[j] += verts[i].xyz[j];
00440 }
00441 }
00442 for ( j = 0 ; j < 10 ; j++ ) {
00443 verts[numVerts].xyz[j] /= numVerts;
00444 }
00445
00446 i = numVerts;
00447 numVerts++;
00448 */
00449 } else {
00450 // just rotate the vertexes
00451 c_rotate++;
00452
00453 }
00454
00455 ds->numVerts = numVerts;
00456 ds->verts = malloc( numVerts * sizeof( *ds->verts ) );
00457
00458 for ( j = 0 ; j < ds->numVerts ; j++ ) {
00459 ds->verts[j] = verts[ ( j + i ) % ds->numVerts ];
00460 }
00461 }
|
Here is the call graph for this function:

|
|
Definition at line 491 of file tjunction.c. References AddEdge(), AddPatchEdges(), AddSurfaceEdges(), shaderInfo_s::autosprite, c_addedVerts, c_cant, c_degenerateEdges, c_natural, c_rotate, c_totalVerts, originalEdge_t::dv, e, EdgeCompare(), entity_t::firstDrawSurf, FixSurfaceJunctions(), i, drawVert_t::lightmap, mapDrawSurface_t, mapDrawSurfs, drawsurf_s::miscModel, shaderInfo_s::notjunc, numEdgeLines, numOriginalEdges, originalEdges, drawsurf_s::patch, qprintf(), qsort(), qtrue, drawsurf_s::shaderInfo, and drawVert_t::xyz. Referenced by ProcessSubModel(), and ProcessWorldModel(). 00491 {
00492 int i;
00493 mapDrawSurface_t *ds;
00494 int axialEdgeLines;
00495 originalEdge_t *e;
00496
00497 qprintf("----- FixTJunctions -----\n");
00498
00499 numEdgeLines = 0;
00500 numOriginalEdges = 0;
00501
00502 // add all the edges
00503 // this actually creates axial edges, but it
00504 // only creates originalEdge_t structures
00505 // for non-axial edges
00506 for ( i = ent->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
00507 ds = &mapDrawSurfs[i];
00508 if ( ds->patch ) {
00509 AddPatchEdges( ds );
00510 } else if ( ds->shaderInfo->autosprite || ds->shaderInfo->notjunc || ds->miscModel ) {
00511 // miscModels don't add tjunctions
00512 } else {
00513 AddSurfaceEdges( ds );
00514 }
00515 }
00516
00517 axialEdgeLines = numEdgeLines;
00518
00519 // sort the non-axial edges by length
00520 qsort( originalEdges, numOriginalEdges, sizeof(originalEdges[0]), EdgeCompare );
00521
00522 // add the non-axial edges, longest first
00523 // this gives the most accurate edge description
00524 for ( i = 0 ; i < numOriginalEdges ; i++ ) {
00525 e = &originalEdges[i];
00526 e->dv[0]->lightmap[0] = AddEdge( e->dv[0]->xyz, e->dv[1]->xyz, qtrue );
00527 }
00528
00529 qprintf( "%6i axial edge lines\n", axialEdgeLines );
00530 qprintf( "%6i non-axial edge lines\n", numEdgeLines - axialEdgeLines );
00531 qprintf( "%6i degenerate edges\n", c_degenerateEdges );
00532
00533 // insert any needed vertexes
00534 for ( i = ent->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
00535 ds = &mapDrawSurfs[i];
00536 if ( ds->patch ) {
00537 continue;
00538 }
00539 if ( ds->shaderInfo->autosprite || ds->shaderInfo->notjunc || ds->miscModel ) {
00540 continue;
00541 }
00542
00543 FixSurfaceJunctions( ds );
00544 }
00545
00546 qprintf( "%6i verts added for tjunctions\n", c_addedVerts );
00547 qprintf( "%6i total verts\n", c_totalVerts );
00548 qprintf( "%6i naturally ordered\n", c_natural );
00549 qprintf( "%6i rotated orders\n", c_rotate );
00550 qprintf( "%6i can't order\n", c_cant );
00551 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 73 of file tjunction.c. References edgeLine_s::chain, d, edgeLine_s::dir, DotProduct, e, edgeLine_t, edgePoint_t, free(), edgePoint_s::intercept, LINE_POSITION_EPSILON, malloc(), edgePoint_s::next, edgeLine_s::origin, p, edgePoint_s::prev, v, vec3_t, VectorCopy, VectorSubtract, and edgePoint_s::xyz. Referenced by AddEdge(). 00073 {
00074 vec3_t delta;
00075 float d;
00076 edgePoint_t *p, *scan;
00077
00078 VectorSubtract( v, e->origin, delta );
00079 d = DotProduct( delta, e->dir );
00080
00081 p = malloc( sizeof(edgePoint_t) );
00082 p->intercept = d;
00083 VectorCopy( v, p->xyz );
00084
00085 if ( e->chain.next == &e->chain ) {
00086 e->chain.next = e->chain.prev = p;
00087 p->next = p->prev = &e->chain;
00088 return;
00089 }
00090
00091 scan = e->chain.next;
00092 for ( ; scan != &e->chain ; scan = scan->next ) {
00093 d = p->intercept - scan->intercept;
00094 if ( d > -LINE_POSITION_EPSILON && d < LINE_POSITION_EPSILON ) {
00095 free( p );
00096 return; // the point is already set
00097 }
00098
00099 if ( p->intercept < scan->intercept ) {
00100 // insert here
00101 p->prev = scan->prev;
00102 p->next = scan;
00103 scan->prev->next = p;
00104 scan->prev = p;
00105 return;
00106 }
00107 }
00108
00109 // add at the end
00110 p->prev = scan->prev;
00111 p->next = scan;
00112 scan->prev->next = p;
00113 scan->prev = p;
00114 }
|
Here is the call graph for this function:

|
|
Definition at line 58 of file tjunction.c. Referenced by FixSurfaceJunctions(), and FixTJunctions(). |
|
|
Definition at line 61 of file tjunction.c. Referenced by FixSurfaceJunctions(), and FixTJunctions(). |
|
|
Definition at line 57 of file tjunction.c. Referenced by AddEdge(), and FixTJunctions(). |
|
|
Definition at line 61 of file tjunction.c. Referenced by FixSurfaceJunctions(), and FixTJunctions(). |
|
|
Definition at line 61 of file tjunction.c. Referenced by FixSurfaceJunctions(), and FixTJunctions(). |
|
|
Definition at line 59 of file tjunction.c. Referenced by FixSurfaceJunctions(), and FixTJunctions(). |
|
|
Definition at line 54 of file tjunction.c. Referenced by AddEdge(), and FixSurfaceJunctions(). |
|
|
Definition at line 55 of file tjunction.c. Referenced by AddEdge(), and FixTJunctions(). |
|
|
Definition at line 50 of file tjunction.c. Referenced by AddEdge(), and FixTJunctions(). |
|
|
Definition at line 49 of file tjunction.c. Referenced by AddEdge(), and FixTJunctions(). |
1.3.9.1