faces.c (18756B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 // faces.c 23 24 #include "qbsp.h" 25 #include "l_mem.h" 26 27 /* 28 29 some faces will be removed before saving, but still form nodes: 30 31 the insides of sky volumes 32 meeting planes of different water current volumes 33 34 */ 35 36 // undefine for dumb linear searches 37 #define USE_HASHING 38 39 #define INTEGRAL_EPSILON 0.01 40 #define POINT_EPSILON 0.5 41 #define OFF_EPSILON 0.5 42 43 int c_merge; 44 int c_subdivide; 45 46 int c_totalverts; 47 int c_uniqueverts; 48 int c_degenerate; 49 int c_tjunctions; 50 int c_faceoverflows; 51 int c_facecollapse; 52 int c_badstartverts; 53 54 #define MAX_SUPERVERTS 512 55 int superverts[MAX_SUPERVERTS]; 56 int numsuperverts; 57 58 face_t *edgefaces[MAX_MAP_EDGES][2]; 59 int firstmodeledge = 1; 60 int firstmodelface; 61 62 int c_tryedges; 63 64 vec3_t edge_dir; 65 vec3_t edge_start; 66 vec_t edge_len; 67 68 int num_edge_verts; 69 int edge_verts[MAX_MAP_VERTS]; 70 71 face_t *NewFaceFromFace (face_t *f); 72 73 //=========================================================================== 74 75 typedef struct hashvert_s 76 { 77 struct hashvert_s *next; 78 int num; 79 } hashvert_t; 80 81 82 #define HASH_SIZE 64 83 84 85 int vertexchain[MAX_MAP_VERTS]; // the next vertex in a hash chain 86 int hashverts[HASH_SIZE*HASH_SIZE]; // a vertex number, or 0 for no verts 87 88 face_t *edgefaces[MAX_MAP_EDGES][2]; 89 90 //============================================================================ 91 92 93 unsigned HashVec (vec3_t vec) 94 { 95 int x, y; 96 97 x = (4096 + (int)(vec[0]+0.5)) >> 7; 98 y = (4096 + (int)(vec[1]+0.5)) >> 7; 99 100 if ( x < 0 || x >= HASH_SIZE || y < 0 || y >= HASH_SIZE ) 101 Error ("HashVec: point outside valid range"); 102 103 return y*HASH_SIZE + x; 104 } 105 106 #ifdef USE_HASHING 107 /* 108 ============= 109 GetVertex 110 111 Uses hashing 112 ============= 113 */ 114 int GetVertexnum (vec3_t in) 115 { 116 int h; 117 int i; 118 float *p; 119 vec3_t vert; 120 int vnum; 121 122 c_totalverts++; 123 124 for (i=0 ; i<3 ; i++) 125 { 126 if ( fabs(in[i] - Q_rint(in[i])) < INTEGRAL_EPSILON) 127 vert[i] = Q_rint(in[i]); 128 else 129 vert[i] = in[i]; 130 } 131 132 h = HashVec (vert); 133 134 for (vnum=hashverts[h] ; vnum ; vnum=vertexchain[vnum]) 135 { 136 p = dvertexes[vnum].point; 137 if ( fabs(p[0]-vert[0])<POINT_EPSILON 138 && fabs(p[1]-vert[1])<POINT_EPSILON 139 && fabs(p[2]-vert[2])<POINT_EPSILON ) 140 return vnum; 141 } 142 143 // emit a vertex 144 if (numvertexes == MAX_MAP_VERTS) 145 Error ("numvertexes == MAX_MAP_VERTS"); 146 147 dvertexes[numvertexes].point[0] = vert[0]; 148 dvertexes[numvertexes].point[1] = vert[1]; 149 dvertexes[numvertexes].point[2] = vert[2]; 150 151 vertexchain[numvertexes] = hashverts[h]; 152 hashverts[h] = numvertexes; 153 154 c_uniqueverts++; 155 156 numvertexes++; 157 158 return numvertexes-1; 159 } 160 #else 161 /* 162 ================== 163 GetVertexnum 164 165 Dumb linear search 166 ================== 167 */ 168 int GetVertexnum (vec3_t v) 169 { 170 int i, j; 171 dvertex_t *dv; 172 vec_t d; 173 174 c_totalverts++; 175 176 // make really close values exactly integral 177 for (i=0 ; i<3 ; i++) 178 { 179 if ( fabs(v[i] - (int)(v[i]+0.5)) < INTEGRAL_EPSILON ) 180 v[i] = (int)(v[i]+0.5); 181 if (v[i] < -4096 || v[i] > 4096) 182 Error ("GetVertexnum: outside +/- 4096"); 183 } 184 185 // search for an existing vertex match 186 for (i=0, dv=dvertexes ; i<numvertexes ; i++, dv++) 187 { 188 for (j=0 ; j<3 ; j++) 189 { 190 d = v[j] - dv->point[j]; 191 if ( d > POINT_EPSILON || d < -POINT_EPSILON) 192 break; 193 } 194 if (j == 3) 195 return i; // a match 196 } 197 198 // new point 199 if (numvertexes == MAX_MAP_VERTS) 200 Error ("MAX_MAP_VERTS"); 201 VectorCopy (v, dv->point); 202 numvertexes++; 203 c_uniqueverts++; 204 205 return numvertexes-1; 206 } 207 #endif 208 209 210 /* 211 ================== 212 FaceFromSuperverts 213 214 The faces vertexes have been added to the superverts[] array, 215 and there may be more there than can be held in a face (MAXEDGES). 216 217 If less, the faces vertexnums[] will be filled in, otherwise 218 face will reference a tree of split[] faces until all of the 219 vertexnums can be added. 220 221 superverts[base] will become face->vertexnums[0], and the others 222 will be circularly filled in. 223 ================== 224 */ 225 void FaceFromSuperverts (node_t *node, face_t *f, int base) 226 { 227 face_t *newf; 228 int remaining; 229 int i; 230 231 remaining = numsuperverts; 232 while (remaining > MAXEDGES) 233 { // must split into two faces, because of vertex overload 234 c_faceoverflows++; 235 236 newf = f->split[0] = NewFaceFromFace (f); 237 newf = f->split[0]; 238 newf->next = node->faces; 239 node->faces = newf; 240 241 newf->numpoints = MAXEDGES; 242 for (i=0 ; i<MAXEDGES ; i++) 243 newf->vertexnums[i] = superverts[(i+base)%numsuperverts]; 244 245 f->split[1] = NewFaceFromFace (f); 246 f = f->split[1]; 247 f->next = node->faces; 248 node->faces = f; 249 250 remaining -= (MAXEDGES-2); 251 base = (base+MAXEDGES-1)%numsuperverts; 252 } 253 254 // copy the vertexes back to the face 255 f->numpoints = remaining; 256 for (i=0 ; i<remaining ; i++) 257 f->vertexnums[i] = superverts[(i+base)%numsuperverts]; 258 } 259 260 261 /* 262 ================== 263 EmitFaceVertexes 264 ================== 265 */ 266 void EmitFaceVertexes (node_t *node, face_t *f) 267 { 268 winding_t *w; 269 int i; 270 271 if (f->merged || f->split[0] || f->split[1]) 272 return; 273 274 w = f->w; 275 for (i=0 ; i<w->numpoints ; i++) 276 { 277 if (noweld) 278 { // make every point unique 279 if (numvertexes == MAX_MAP_VERTS) 280 Error ("MAX_MAP_VERTS"); 281 superverts[i] = numvertexes; 282 VectorCopy (w->p[i], dvertexes[numvertexes].point); 283 numvertexes++; 284 c_uniqueverts++; 285 c_totalverts++; 286 } 287 else 288 superverts[i] = GetVertexnum (w->p[i]); 289 } 290 numsuperverts = w->numpoints; 291 292 // this may fragment the face if > MAXEDGES 293 FaceFromSuperverts (node, f, 0); 294 } 295 296 /* 297 ================== 298 EmitVertexes_r 299 ================== 300 */ 301 void EmitVertexes_r (node_t *node) 302 { 303 int i; 304 face_t *f; 305 306 if (node->planenum == PLANENUM_LEAF) 307 return; 308 309 for (f=node->faces ; f ; f=f->next) 310 { 311 EmitFaceVertexes (node, f); 312 } 313 314 for (i=0 ; i<2 ; i++) 315 EmitVertexes_r (node->children[i]); 316 } 317 318 319 #ifdef USE_HASHING 320 /* 321 ========== 322 FindEdgeVerts 323 324 Uses the hash tables to cut down to a small number 325 ========== 326 */ 327 void FindEdgeVerts (vec3_t v1, vec3_t v2) 328 { 329 int x1, x2, y1, y2, t; 330 int x, y; 331 int vnum; 332 333 #if 0 334 { 335 int i; 336 num_edge_verts = numvertexes-1; 337 for (i=0 ; i<numvertexes-1 ; i++) 338 edge_verts[i] = i+1; 339 } 340 #endif 341 342 x1 = (4096 + (int)(v1[0]+0.5)) >> 7; 343 y1 = (4096 + (int)(v1[1]+0.5)) >> 7; 344 x2 = (4096 + (int)(v2[0]+0.5)) >> 7; 345 y2 = (4096 + (int)(v2[1]+0.5)) >> 7; 346 347 if (x1 > x2) 348 { 349 t = x1; 350 x1 = x2; 351 x2 = t; 352 } 353 if (y1 > y2) 354 { 355 t = y1; 356 y1 = y2; 357 y2 = t; 358 } 359 #if 0 360 x1--; 361 x2++; 362 y1--; 363 y2++; 364 if (x1 < 0) 365 x1 = 0; 366 if (x2 >= HASH_SIZE) 367 x2 = HASH_SIZE; 368 if (y1 < 0) 369 y1 = 0; 370 if (y2 >= HASH_SIZE) 371 y2 = HASH_SIZE; 372 #endif 373 num_edge_verts = 0; 374 for (x=x1 ; x <= x2 ; x++) 375 { 376 for (y=y1 ; y <= y2 ; y++) 377 { 378 for (vnum=hashverts[y*HASH_SIZE+x] ; vnum ; vnum=vertexchain[vnum]) 379 { 380 edge_verts[num_edge_verts++] = vnum; 381 } 382 } 383 } 384 } 385 386 #else 387 /* 388 ========== 389 FindEdgeVerts 390 391 Forced a dumb check of everything 392 ========== 393 */ 394 void FindEdgeVerts (vec3_t v1, vec3_t v2) 395 { 396 int i; 397 398 num_edge_verts = numvertexes-1; 399 for (i=0 ; i<num_edge_verts ; i++) 400 edge_verts[i] = i+1; 401 } 402 #endif 403 404 /* 405 ========== 406 TestEdge 407 408 Can be recursively reentered 409 ========== 410 */ 411 void TestEdge (vec_t start, vec_t end, int p1, int p2, int startvert) 412 { 413 int j, k; 414 vec_t dist; 415 vec3_t delta; 416 vec3_t exact; 417 vec3_t off; 418 vec_t error; 419 vec3_t p; 420 421 if (p1 == p2) 422 { 423 c_degenerate++; 424 return; // degenerate edge 425 } 426 427 for (k=startvert ; k<num_edge_verts ; k++) 428 { 429 j = edge_verts[k]; 430 if (j==p1 || j == p2) 431 continue; 432 433 VectorCopy (dvertexes[j].point, p); 434 435 VectorSubtract (p, edge_start, delta); 436 dist = DotProduct (delta, edge_dir); 437 if (dist <=start || dist >= end) 438 continue; // off an end 439 VectorMA (edge_start, dist, edge_dir, exact); 440 VectorSubtract (p, exact, off); 441 error = VectorLength (off); 442 443 if (fabs(error) > OFF_EPSILON) 444 continue; // not on the edge 445 446 // break the edge 447 c_tjunctions++; 448 TestEdge (start, dist, p1, j, k+1); 449 TestEdge (dist, end, j, p2, k+1); 450 return; 451 } 452 453 // the edge p1 to p2 is now free of tjunctions 454 if (numsuperverts >= MAX_SUPERVERTS) 455 Error ("MAX_SUPERVERTS"); 456 superverts[numsuperverts] = p1; 457 numsuperverts++; 458 } 459 460 /* 461 ================== 462 FixFaceEdges 463 464 ================== 465 */ 466 void FixFaceEdges (node_t *node, face_t *f) 467 { 468 int p1, p2; 469 int i; 470 vec3_t e2; 471 vec_t len; 472 int count[MAX_SUPERVERTS], start[MAX_SUPERVERTS]; 473 int base; 474 475 if (f->merged || f->split[0] || f->split[1]) 476 return; 477 478 numsuperverts = 0; 479 480 for (i=0 ; i<f->numpoints ; i++) 481 { 482 p1 = f->vertexnums[i]; 483 p2 = f->vertexnums[(i+1)%f->numpoints]; 484 485 VectorCopy (dvertexes[p1].point, edge_start); 486 VectorCopy (dvertexes[p2].point, e2); 487 488 FindEdgeVerts (edge_start, e2); 489 490 VectorSubtract (e2, edge_start, edge_dir); 491 len = VectorNormalize(edge_dir); 492 493 start[i] = numsuperverts; 494 TestEdge (0, len, p1, p2, 0); 495 496 count[i] = numsuperverts - start[i]; 497 } 498 499 if (numsuperverts < 3) 500 { // entire face collapsed 501 f->numpoints = 0; 502 c_facecollapse++; 503 return; 504 } 505 506 // we want to pick a vertex that doesn't have tjunctions 507 // on either side, which can cause artifacts on trifans, 508 // especially underwater 509 for (i=0 ; i<f->numpoints ; i++) 510 { 511 if (count[i] == 1 && count[(i+f->numpoints-1)%f->numpoints] == 1) 512 break; 513 } 514 if (i == f->numpoints) 515 { 516 f->badstartvert = true; 517 c_badstartverts++; 518 base = 0; 519 } 520 else 521 { // rotate the vertex order 522 base = start[i]; 523 } 524 525 // this may fragment the face if > MAXEDGES 526 FaceFromSuperverts (node, f, base); 527 } 528 529 /* 530 ================== 531 FixEdges_r 532 ================== 533 */ 534 void FixEdges_r (node_t *node) 535 { 536 int i; 537 face_t *f; 538 539 if (node->planenum == PLANENUM_LEAF) 540 return; 541 542 for (f=node->faces ; f ; f=f->next) 543 FixFaceEdges (node, f); 544 545 for (i=0 ; i<2 ; i++) 546 FixEdges_r (node->children[i]); 547 } 548 549 /* 550 =========== 551 FixTjuncs 552 553 =========== 554 */ 555 void FixTjuncs (node_t *headnode) 556 { 557 // snap and merge all vertexes 558 qprintf ("---- snap verts ----\n"); 559 memset (hashverts, 0, sizeof(hashverts)); 560 c_totalverts = 0; 561 c_uniqueverts = 0; 562 c_faceoverflows = 0; 563 EmitVertexes_r (headnode); 564 qprintf ("%i unique from %i\n", c_uniqueverts, c_totalverts); 565 566 // break edges on tjunctions 567 qprintf ("---- tjunc ----\n"); 568 c_tryedges = 0; 569 c_degenerate = 0; 570 c_facecollapse = 0; 571 c_tjunctions = 0; 572 if (!notjunc) 573 FixEdges_r (headnode); 574 qprintf ("%5i edges degenerated\n", c_degenerate); 575 qprintf ("%5i faces degenerated\n", c_facecollapse); 576 qprintf ("%5i edges added by tjunctions\n", c_tjunctions); 577 qprintf ("%5i faces added by tjunctions\n", c_faceoverflows); 578 qprintf ("%5i bad start verts\n", c_badstartverts); 579 } 580 581 582 //======================================================== 583 584 int c_faces; 585 586 face_t *AllocFace (void) 587 { 588 face_t *f; 589 590 f = GetMemory(sizeof(*f)); 591 memset (f, 0, sizeof(*f)); 592 c_faces++; 593 594 return f; 595 } 596 597 face_t *NewFaceFromFace (face_t *f) 598 { 599 face_t *newf; 600 601 newf = AllocFace (); 602 *newf = *f; 603 newf->merged = NULL; 604 newf->split[0] = newf->split[1] = NULL; 605 newf->w = NULL; 606 return newf; 607 } 608 609 void FreeFace (face_t *f) 610 { 611 if (f->w) 612 FreeWinding (f->w); 613 FreeMemory(f); 614 c_faces--; 615 } 616 617 //======================================================== 618 619 /* 620 ================== 621 GetEdge 622 623 Called by writebsp. 624 Don't allow four way edges 625 ================== 626 */ 627 int GetEdge2 (int v1, int v2, face_t *f) 628 { 629 dedge_t *edge; 630 int i; 631 632 c_tryedges++; 633 634 if (!noshare) 635 { 636 for (i=firstmodeledge ; i < numedges ; i++) 637 { 638 edge = &dedges[i]; 639 if (v1 == edge->v[1] && v2 == edge->v[0] 640 && edgefaces[i][0]->contents == f->contents) 641 { 642 if (edgefaces[i][1]) 643 // printf ("WARNING: multiple backward edge\n"); 644 continue; 645 edgefaces[i][1] = f; 646 return -i; 647 } 648 #if 0 649 if (v1 == edge->v[0] && v2 == edge->v[1]) 650 { 651 printf ("WARNING: multiple forward edge\n"); 652 return i; 653 } 654 #endif 655 } 656 } 657 658 // emit an edge 659 if (numedges >= MAX_MAP_EDGES) 660 Error ("numedges == MAX_MAP_EDGES"); 661 edge = &dedges[numedges]; 662 numedges++; 663 edge->v[0] = v1; 664 edge->v[1] = v2; 665 edgefaces[numedges-1][0] = f; 666 667 return numedges-1; 668 } 669 670 /* 671 =========================================================================== 672 673 FACE MERGING 674 675 =========================================================================== 676 */ 677 678 /* 679 ============= 680 TryMerge 681 682 If two polygons share a common edge and the edges that meet at the 683 common points are both inside the other polygons, merge them 684 685 Returns NULL if the faces couldn't be merged, or the new face. 686 The originals will NOT be freed. 687 ============= 688 */ 689 face_t *TryMerge (face_t *f1, face_t *f2, vec3_t planenormal) 690 { 691 face_t *newf; 692 winding_t *nw; 693 694 if (!f1->w || !f2->w) 695 return NULL; 696 if (f1->texinfo != f2->texinfo) 697 return NULL; 698 if (f1->planenum != f2->planenum) // on front and back sides 699 return NULL; 700 if (f1->contents != f2->contents) 701 return NULL; 702 703 704 nw = TryMergeWinding (f1->w, f2->w, planenormal); 705 if (!nw) 706 return NULL; 707 708 c_merge++; 709 newf = NewFaceFromFace (f1); 710 newf->w = nw; 711 712 f1->merged = newf; 713 f2->merged = newf; 714 715 return newf; 716 } 717 718 /* 719 =============== 720 MergeNodeFaces 721 =============== 722 */ 723 void MergeNodeFaces (node_t *node) 724 { 725 face_t *f1, *f2, *end; 726 face_t *merged; 727 plane_t *plane; 728 729 plane = &mapplanes[node->planenum]; 730 merged = NULL; 731 732 for (f1 = node->faces ; f1 ; f1 = f1->next) 733 { 734 if (f1->merged || f1->split[0] || f1->split[1]) 735 continue; 736 737 for (f2 = node->faces ; f2 != f1 ; f2=f2->next) 738 { 739 if (f2->merged || f2->split[0] || f2->split[1]) 740 continue; 741 742 //IDBUG: always passes the face's node's normal to TryMerge() 743 //regardless of which side the face is on. Approximately 50% of 744 //the time the face will be on the other side of node, and thus 745 //the result of the convex/concave test in TryMergeWinding(), 746 //which depends on the normal, is flipped. This causes faces 747 //that shouldn't be merged to be merged and faces that 748 //should be merged to not be merged. 749 //the following added line fixes this bug 750 //thanks to: Alexander Malmberg <alexander@malmberg.org> 751 plane = &mapplanes[f1->planenum]; 752 // 753 merged = TryMerge (f1, f2, plane->normal); 754 if (!merged) 755 continue; 756 757 // add merged to the end of the node face list 758 // so it will be checked against all the faces again 759 for (end = node->faces ; end->next ; end = end->next) 760 ; 761 merged->next = NULL; 762 end->next = merged; 763 break; 764 } 765 } 766 } 767 768 //===================================================================== 769 770 /* 771 =============== 772 SubdivideFace 773 774 Chop up faces that are larger than we want in the surface cache 775 =============== 776 */ 777 void SubdivideFace (node_t *node, face_t *f) 778 { 779 float mins, maxs; 780 vec_t v; 781 int axis, i; 782 texinfo_t *tex; 783 vec3_t temp; 784 vec_t dist; 785 winding_t *w, *frontw, *backw; 786 787 if (f->merged) 788 return; 789 790 // special (non-surface cached) faces don't need subdivision 791 tex = &texinfo[f->texinfo]; 792 793 if ( tex->flags & (SURF_WARP|SURF_SKY) ) 794 { 795 return; 796 } 797 798 for (axis = 0 ; axis < 2 ; axis++) 799 { 800 while (1) 801 { 802 mins = 999999; 803 maxs = -999999; 804 805 VectorCopy (tex->vecs[axis], temp); 806 w = f->w; 807 for (i=0 ; i<w->numpoints ; i++) 808 { 809 v = DotProduct (w->p[i], temp); 810 if (v < mins) 811 mins = v; 812 if (v > maxs) 813 maxs = v; 814 } 815 #if 0 816 if (maxs - mins <= 0) 817 Error ("zero extents"); 818 #endif 819 if (axis == 2) 820 { // allow double high walls 821 if (maxs - mins <= subdivide_size/* *2 */) 822 break; 823 } 824 else if (maxs - mins <= subdivide_size) 825 break; 826 827 // split it 828 c_subdivide++; 829 830 v = VectorNormalize (temp); 831 832 dist = (mins + subdivide_size - 16)/v; 833 834 ClipWindingEpsilon (w, temp, dist, ON_EPSILON, &frontw, &backw); 835 if (!frontw || !backw) 836 Error ("SubdivideFace: didn't split the polygon"); 837 838 f->split[0] = NewFaceFromFace (f); 839 f->split[0]->w = frontw; 840 f->split[0]->next = node->faces; 841 node->faces = f->split[0]; 842 843 f->split[1] = NewFaceFromFace (f); 844 f->split[1]->w = backw; 845 f->split[1]->next = node->faces; 846 node->faces = f->split[1]; 847 848 SubdivideFace (node, f->split[0]); 849 SubdivideFace (node, f->split[1]); 850 return; 851 } 852 } 853 } 854 855 void SubdivideNodeFaces (node_t *node) 856 { 857 face_t *f; 858 859 for (f = node->faces ; f ; f=f->next) 860 { 861 SubdivideFace (node, f); 862 } 863 } 864 865 //=========================================================================== 866 867 int c_nodefaces; 868 869 870 /* 871 ============ 872 FaceFromPortal 873 874 ============ 875 */ 876 face_t *FaceFromPortal (portal_t *p, int pside) 877 { 878 face_t *f; 879 side_t *side; 880 881 side = p->side; 882 if (!side) 883 return NULL; // portal does not bridge different visible contents 884 885 f = AllocFace (); 886 887 f->texinfo = side->texinfo; 888 f->planenum = (side->planenum & ~1) | pside; 889 f->portal = p; 890 891 if ( (p->nodes[pside]->contents & CONTENTS_WINDOW) 892 && VisibleContents(p->nodes[!pside]->contents^p->nodes[pside]->contents) == CONTENTS_WINDOW ) 893 return NULL; // don't show insides of windows 894 895 if (pside) 896 { 897 f->w = ReverseWinding(p->winding); 898 f->contents = p->nodes[1]->contents; 899 } 900 else 901 { 902 f->w = CopyWinding(p->winding); 903 f->contents = p->nodes[0]->contents; 904 } 905 return f; 906 } 907 908 909 /* 910 =============== 911 MakeFaces_r 912 913 If a portal will make a visible face, 914 mark the side that originally created it 915 916 solid / empty : solid 917 solid / water : solid 918 water / empty : water 919 water / water : none 920 =============== 921 */ 922 void MakeFaces_r (node_t *node) 923 { 924 portal_t *p; 925 int s; 926 927 // recurse down to leafs 928 if (node->planenum != PLANENUM_LEAF) 929 { 930 MakeFaces_r (node->children[0]); 931 MakeFaces_r (node->children[1]); 932 933 // merge together all visible faces on the node 934 if (!nomerge) 935 MergeNodeFaces (node); 936 if (!nosubdiv) 937 SubdivideNodeFaces (node); 938 939 return; 940 } 941 942 // solid leafs never have visible faces 943 if (node->contents & CONTENTS_SOLID) 944 return; 945 946 // see which portals are valid 947 for (p=node->portals ; p ; p = p->next[s]) 948 { 949 s = (p->nodes[1] == node); 950 951 p->face[s] = FaceFromPortal (p, s); 952 if (p->face[s]) 953 { 954 c_nodefaces++; 955 p->face[s]->next = p->onnode->faces; 956 p->onnode->faces = p->face[s]; 957 } 958 } 959 } 960 961 /* 962 ============ 963 MakeFaces 964 ============ 965 */ 966 void MakeFaces (node_t *node) 967 { 968 qprintf ("--- MakeFaces ---\n"); 969 c_merge = 0; 970 c_subdivide = 0; 971 c_nodefaces = 0; 972 973 MakeFaces_r (node); 974 975 qprintf ("%5i makefaces\n", c_nodefaces); 976 qprintf ("%5i merged\n", c_merge); 977 qprintf ("%5i subdivided\n", c_subdivide); 978 }