00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qbsp.h"
00025 #include "l_mem.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define USE_HASHING
00038
00039 #define INTEGRAL_EPSILON 0.01
00040 #define POINT_EPSILON 0.5
00041 #define OFF_EPSILON 0.5
00042
00043 int c_merge;
00044 int c_subdivide;
00045
00046 int c_totalverts;
00047 int c_uniqueverts;
00048 int c_degenerate;
00049 int c_tjunctions;
00050 int c_faceoverflows;
00051 int c_facecollapse;
00052 int c_badstartverts;
00053
00054 #define MAX_SUPERVERTS 512
00055 int superverts[MAX_SUPERVERTS];
00056 int numsuperverts;
00057
00058 face_t *edgefaces[MAX_MAP_EDGES][2];
00059 int firstmodeledge = 1;
00060 int firstmodelface;
00061
00062 int c_tryedges;
00063
00064 vec3_t edge_dir;
00065 vec3_t edge_start;
00066 vec_t edge_len;
00067
00068 int num_edge_verts;
00069 int edge_verts[MAX_MAP_VERTS];
00070
00071 face_t *NewFaceFromFace (face_t *f);
00072
00073
00074
00075 typedef struct hashvert_s
00076 {
00077 struct hashvert_s *next;
00078 int num;
00079 } hashvert_t;
00080
00081
00082 #define HASH_SIZE 64
00083
00084
00085 int vertexchain[MAX_MAP_VERTS];
00086 int hashverts[HASH_SIZE*HASH_SIZE];
00087
00088 face_t *edgefaces[MAX_MAP_EDGES][2];
00089
00090
00091
00092
00093 unsigned HashVec (vec3_t vec)
00094 {
00095 int x, y;
00096
00097 x = (4096 + (int)(vec[0]+0.5)) >> 7;
00098 y = (4096 + (int)(vec[1]+0.5)) >> 7;
00099
00100 if ( x < 0 || x >= HASH_SIZE || y < 0 || y >= HASH_SIZE )
00101 Error ("HashVec: point outside valid range");
00102
00103 return y*HASH_SIZE + x;
00104 }
00105
00106 #ifdef USE_HASHING
00107
00108
00109
00110
00111
00112
00113
00114 int GetVertexnum (vec3_t in)
00115 {
00116 int h;
00117 int i;
00118 float *p;
00119 vec3_t vert;
00120 int vnum;
00121
00122 c_totalverts++;
00123
00124 for (i=0 ; i<3 ; i++)
00125 {
00126 if ( fabs(in[i] - Q_rint(in[i])) < INTEGRAL_EPSILON)
00127 vert[i] = Q_rint(in[i]);
00128 else
00129 vert[i] = in[i];
00130 }
00131
00132 h = HashVec (vert);
00133
00134 for (vnum=hashverts[h] ; vnum ; vnum=vertexchain[vnum])
00135 {
00136 p = dvertexes[vnum].point;
00137 if ( fabs(p[0]-vert[0])<POINT_EPSILON
00138 && fabs(p[1]-vert[1])<POINT_EPSILON
00139 && fabs(p[2]-vert[2])<POINT_EPSILON )
00140 return vnum;
00141 }
00142
00143
00144 if (numvertexes == MAX_MAP_VERTS)
00145 Error ("numvertexes == MAX_MAP_VERTS");
00146
00147 dvertexes[numvertexes].point[0] = vert[0];
00148 dvertexes[numvertexes].point[1] = vert[1];
00149 dvertexes[numvertexes].point[2] = vert[2];
00150
00151 vertexchain[numvertexes] = hashverts[h];
00152 hashverts[h] = numvertexes;
00153
00154 c_uniqueverts++;
00155
00156 numvertexes++;
00157
00158 return numvertexes-1;
00159 }
00160 #else
00161
00162
00163
00164
00165
00166
00167
00168 int GetVertexnum (vec3_t v)
00169 {
00170 int i, j;
00171 dvertex_t *dv;
00172 vec_t d;
00173
00174 c_totalverts++;
00175
00176
00177 for (i=0 ; i<3 ; i++)
00178 {
00179 if ( fabs(v[i] - (int)(v[i]+0.5)) < INTEGRAL_EPSILON )
00180 v[i] = (int)(v[i]+0.5);
00181 if (v[i] < -4096 || v[i] > 4096)
00182 Error ("GetVertexnum: outside +/- 4096");
00183 }
00184
00185
00186 for (i=0, dv=dvertexes ; i<numvertexes ; i++, dv++)
00187 {
00188 for (j=0 ; j<3 ; j++)
00189 {
00190 d = v[j] - dv->point[j];
00191 if ( d > POINT_EPSILON || d < -POINT_EPSILON)
00192 break;
00193 }
00194 if (j == 3)
00195 return i;
00196 }
00197
00198
00199 if (numvertexes == MAX_MAP_VERTS)
00200 Error ("MAX_MAP_VERTS");
00201 VectorCopy (v, dv->point);
00202 numvertexes++;
00203 c_uniqueverts++;
00204
00205 return numvertexes-1;
00206 }
00207 #endif
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 void FaceFromSuperverts (node_t *node, face_t *f, int base)
00226 {
00227 face_t *newf;
00228 int remaining;
00229 int i;
00230
00231 remaining = numsuperverts;
00232 while (remaining > MAXEDGES)
00233 {
00234 c_faceoverflows++;
00235
00236 newf = f->split[0] = NewFaceFromFace (f);
00237 newf = f->split[0];
00238 newf->next = node->faces;
00239 node->faces = newf;
00240
00241 newf->numpoints = MAXEDGES;
00242 for (i=0 ; i<MAXEDGES ; i++)
00243 newf->vertexnums[i] = superverts[(i+base)%numsuperverts];
00244
00245 f->split[1] = NewFaceFromFace (f);
00246 f = f->split[1];
00247 f->next = node->faces;
00248 node->faces = f;
00249
00250 remaining -= (MAXEDGES-2);
00251 base = (base+MAXEDGES-1)%numsuperverts;
00252 }
00253
00254
00255 f->numpoints = remaining;
00256 for (i=0 ; i<remaining ; i++)
00257 f->vertexnums[i] = superverts[(i+base)%numsuperverts];
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 void EmitFaceVertexes (node_t *node, face_t *f)
00267 {
00268 winding_t *w;
00269 int i;
00270
00271 if (f->merged || f->split[0] || f->split[1])
00272 return;
00273
00274 w = f->w;
00275 for (i=0 ; i<w->numpoints ; i++)
00276 {
00277 if (noweld)
00278 {
00279 if (numvertexes == MAX_MAP_VERTS)
00280 Error ("MAX_MAP_VERTS");
00281 superverts[i] = numvertexes;
00282 VectorCopy (w->p[i], dvertexes[numvertexes].point);
00283 numvertexes++;
00284 c_uniqueverts++;
00285 c_totalverts++;
00286 }
00287 else
00288 superverts[i] = GetVertexnum (w->p[i]);
00289 }
00290 numsuperverts = w->numpoints;
00291
00292
00293 FaceFromSuperverts (node, f, 0);
00294 }
00295
00296
00297
00298
00299
00300
00301 void EmitVertexes_r (node_t *node)
00302 {
00303 int i;
00304 face_t *f;
00305
00306 if (node->planenum == PLANENUM_LEAF)
00307 return;
00308
00309 for (f=node->faces ; f ; f=f->next)
00310 {
00311 EmitFaceVertexes (node, f);
00312 }
00313
00314 for (i=0 ; i<2 ; i++)
00315 EmitVertexes_r (node->children[i]);
00316 }
00317
00318
00319 #ifdef USE_HASHING
00320
00321
00322
00323
00324
00325
00326
00327 void FindEdgeVerts (vec3_t v1, vec3_t v2)
00328 {
00329 int x1, x2, y1, y2, t;
00330 int x, y;
00331 int vnum;
00332
00333 #if 0
00334 {
00335 int i;
00336 num_edge_verts = numvertexes-1;
00337 for (i=0 ; i<numvertexes-1 ; i++)
00338 edge_verts[i] = i+1;
00339 }
00340 #endif
00341
00342 x1 = (4096 + (int)(v1[0]+0.5)) >> 7;
00343 y1 = (4096 + (int)(v1[1]+0.5)) >> 7;
00344 x2 = (4096 + (int)(v2[0]+0.5)) >> 7;
00345 y2 = (4096 + (int)(v2[1]+0.5)) >> 7;
00346
00347 if (x1 > x2)
00348 {
00349 t = x1;
00350 x1 = x2;
00351 x2 = t;
00352 }
00353 if (y1 > y2)
00354 {
00355 t = y1;
00356 y1 = y2;
00357 y2 = t;
00358 }
00359 #if 0
00360 x1--;
00361 x2++;
00362 y1--;
00363 y2++;
00364 if (x1 < 0)
00365 x1 = 0;
00366 if (x2 >= HASH_SIZE)
00367 x2 = HASH_SIZE;
00368 if (y1 < 0)
00369 y1 = 0;
00370 if (y2 >= HASH_SIZE)
00371 y2 = HASH_SIZE;
00372 #endif
00373 num_edge_verts = 0;
00374 for (x=x1 ; x <= x2 ; x++)
00375 {
00376 for (y=y1 ; y <= y2 ; y++)
00377 {
00378 for (vnum=hashverts[y*HASH_SIZE+x] ; vnum ; vnum=vertexchain[vnum])
00379 {
00380 edge_verts[num_edge_verts++] = vnum;
00381 }
00382 }
00383 }
00384 }
00385
00386 #else
00387
00388
00389
00390
00391
00392
00393
00394 void FindEdgeVerts (vec3_t v1, vec3_t v2)
00395 {
00396 int i;
00397
00398 num_edge_verts = numvertexes-1;
00399 for (i=0 ; i<num_edge_verts ; i++)
00400 edge_verts[i] = i+1;
00401 }
00402 #endif
00403
00404
00405
00406
00407
00408
00409
00410
00411 void TestEdge (vec_t start, vec_t end, int p1, int p2, int startvert)
00412 {
00413 int j, k;
00414 vec_t dist;
00415 vec3_t delta;
00416 vec3_t exact;
00417 vec3_t off;
00418 vec_t error;
00419 vec3_t p;
00420
00421 if (p1 == p2)
00422 {
00423 c_degenerate++;
00424 return;
00425 }
00426
00427 for (k=startvert ; k<num_edge_verts ; k++)
00428 {
00429 j = edge_verts[k];
00430 if (j==p1 || j == p2)
00431 continue;
00432
00433 VectorCopy (dvertexes[j].point, p);
00434
00435 VectorSubtract (p, edge_start, delta);
00436 dist = DotProduct (delta, edge_dir);
00437 if (dist <=start || dist >= end)
00438 continue;
00439 VectorMA (edge_start, dist, edge_dir, exact);
00440 VectorSubtract (p, exact, off);
00441 error = VectorLength (off);
00442
00443 if (fabs(error) > OFF_EPSILON)
00444 continue;
00445
00446
00447 c_tjunctions++;
00448 TestEdge (start, dist, p1, j, k+1);
00449 TestEdge (dist, end, j, p2, k+1);
00450 return;
00451 }
00452
00453
00454 if (numsuperverts >= MAX_SUPERVERTS)
00455 Error ("MAX_SUPERVERTS");
00456 superverts[numsuperverts] = p1;
00457 numsuperverts++;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466 void FixFaceEdges (node_t *node, face_t *f)
00467 {
00468 int p1, p2;
00469 int i;
00470 vec3_t e2;
00471 vec_t len;
00472 int count[MAX_SUPERVERTS], start[MAX_SUPERVERTS];
00473 int base;
00474
00475 if (f->merged || f->split[0] || f->split[1])
00476 return;
00477
00478 numsuperverts = 0;
00479
00480 for (i=0 ; i<f->numpoints ; i++)
00481 {
00482 p1 = f->vertexnums[i];
00483 p2 = f->vertexnums[(i+1)%f->numpoints];
00484
00485 VectorCopy (dvertexes[p1].point, edge_start);
00486 VectorCopy (dvertexes[p2].point, e2);
00487
00488 FindEdgeVerts (edge_start, e2);
00489
00490 VectorSubtract (e2, edge_start, edge_dir);
00491 len = VectorNormalize(edge_dir);
00492
00493 start[i] = numsuperverts;
00494 TestEdge (0, len, p1, p2, 0);
00495
00496 count[i] = numsuperverts - start[i];
00497 }
00498
00499 if (numsuperverts < 3)
00500 {
00501 f->numpoints = 0;
00502 c_facecollapse++;
00503 return;
00504 }
00505
00506
00507
00508
00509 for (i=0 ; i<f->numpoints ; i++)
00510 {
00511 if (count[i] == 1 && count[(i+f->numpoints-1)%f->numpoints] == 1)
00512 break;
00513 }
00514 if (i == f->numpoints)
00515 {
00516 f->badstartvert = true;
00517 c_badstartverts++;
00518 base = 0;
00519 }
00520 else
00521 {
00522 base = start[i];
00523 }
00524
00525
00526 FaceFromSuperverts (node, f, base);
00527 }
00528
00529
00530
00531
00532
00533
00534 void FixEdges_r (node_t *node)
00535 {
00536 int i;
00537 face_t *f;
00538
00539 if (node->planenum == PLANENUM_LEAF)
00540 return;
00541
00542 for (f=node->faces ; f ; f=f->next)
00543 FixFaceEdges (node, f);
00544
00545 for (i=0 ; i<2 ; i++)
00546 FixEdges_r (node->children[i]);
00547 }
00548
00549
00550
00551
00552
00553
00554
00555 void FixTjuncs (node_t *headnode)
00556 {
00557
00558 qprintf ("---- snap verts ----\n");
00559 memset (hashverts, 0, sizeof(hashverts));
00560 c_totalverts = 0;
00561 c_uniqueverts = 0;
00562 c_faceoverflows = 0;
00563 EmitVertexes_r (headnode);
00564 qprintf ("%i unique from %i\n", c_uniqueverts, c_totalverts);
00565
00566
00567 qprintf ("---- tjunc ----\n");
00568 c_tryedges = 0;
00569 c_degenerate = 0;
00570 c_facecollapse = 0;
00571 c_tjunctions = 0;
00572 if (!notjunc)
00573 FixEdges_r (headnode);
00574 qprintf ("%5i edges degenerated\n", c_degenerate);
00575 qprintf ("%5i faces degenerated\n", c_facecollapse);
00576 qprintf ("%5i edges added by tjunctions\n", c_tjunctions);
00577 qprintf ("%5i faces added by tjunctions\n", c_faceoverflows);
00578 qprintf ("%5i bad start verts\n", c_badstartverts);
00579 }
00580
00581
00582
00583
00584 int c_faces;
00585
00586 face_t *AllocFace (void)
00587 {
00588 face_t *f;
00589
00590 f = GetMemory(sizeof(*f));
00591 memset (f, 0, sizeof(*f));
00592 c_faces++;
00593
00594 return f;
00595 }
00596
00597 face_t *NewFaceFromFace (face_t *f)
00598 {
00599 face_t *newf;
00600
00601 newf = AllocFace ();
00602 *newf = *f;
00603 newf->merged = NULL;
00604 newf->split[0] = newf->split[1] = NULL;
00605 newf->w = NULL;
00606 return newf;
00607 }
00608
00609 void FreeFace (face_t *f)
00610 {
00611 if (f->w)
00612 FreeWinding (f->w);
00613 FreeMemory(f);
00614 c_faces--;
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 int GetEdge2 (int v1, int v2, face_t *f)
00628 {
00629 dedge_t *edge;
00630 int i;
00631
00632 c_tryedges++;
00633
00634 if (!noshare)
00635 {
00636 for (i=firstmodeledge ; i < numedges ; i++)
00637 {
00638 edge = &dedges[i];
00639 if (v1 == edge->v[1] && v2 == edge->v[0]
00640 && edgefaces[i][0]->contents == f->contents)
00641 {
00642 if (edgefaces[i][1])
00643
00644 continue;
00645 edgefaces[i][1] = f;
00646 return -i;
00647 }
00648 #if 0
00649 if (v1 == edge->v[0] && v2 == edge->v[1])
00650 {
00651 printf ("WARNING: multiple forward edge\n");
00652 return i;
00653 }
00654 #endif
00655 }
00656 }
00657
00658
00659 if (numedges >= MAX_MAP_EDGES)
00660 Error ("numedges == MAX_MAP_EDGES");
00661 edge = &dedges[numedges];
00662 numedges++;
00663 edge->v[0] = v1;
00664 edge->v[1] = v2;
00665 edgefaces[numedges-1][0] = f;
00666
00667 return numedges-1;
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 face_t *TryMerge (face_t *f1, face_t *f2, vec3_t planenormal)
00690 {
00691 face_t *newf;
00692 winding_t *nw;
00693
00694 if (!f1->w || !f2->w)
00695 return NULL;
00696 if (f1->texinfo != f2->texinfo)
00697 return NULL;
00698 if (f1->planenum != f2->planenum)
00699 return NULL;
00700 if (f1->contents != f2->contents)
00701 return NULL;
00702
00703
00704 nw = TryMergeWinding (f1->w, f2->w, planenormal);
00705 if (!nw)
00706 return NULL;
00707
00708 c_merge++;
00709 newf = NewFaceFromFace (f1);
00710 newf->w = nw;
00711
00712 f1->merged = newf;
00713 f2->merged = newf;
00714
00715 return newf;
00716 }
00717
00718
00719
00720
00721
00722
00723 void MergeNodeFaces (node_t *node)
00724 {
00725 face_t *f1, *f2, *end;
00726 face_t *merged;
00727 plane_t *plane;
00728
00729 plane = &mapplanes[node->planenum];
00730 merged = NULL;
00731
00732 for (f1 = node->faces ; f1 ; f1 = f1->next)
00733 {
00734 if (f1->merged || f1->split[0] || f1->split[1])
00735 continue;
00736
00737 for (f2 = node->faces ; f2 != f1 ; f2=f2->next)
00738 {
00739 if (f2->merged || f2->split[0] || f2->split[1])
00740 continue;
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 plane = &mapplanes[f1->planenum];
00752
00753 merged = TryMerge (f1, f2, plane->normal);
00754 if (!merged)
00755 continue;
00756
00757
00758
00759 for (end = node->faces ; end->next ; end = end->next)
00760 ;
00761 merged->next = NULL;
00762 end->next = merged;
00763 break;
00764 }
00765 }
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 void SubdivideFace (node_t *node, face_t *f)
00778 {
00779 float mins, maxs;
00780 vec_t v;
00781 int axis, i;
00782 texinfo_t *tex;
00783 vec3_t temp;
00784 vec_t dist;
00785 winding_t *w, *frontw, *backw;
00786
00787 if (f->merged)
00788 return;
00789
00790
00791 tex = &texinfo[f->texinfo];
00792
00793 if ( tex->flags & (SURF_WARP|SURF_SKY) )
00794 {
00795 return;
00796 }
00797
00798 for (axis = 0 ; axis < 2 ; axis++)
00799 {
00800 while (1)
00801 {
00802 mins = 999999;
00803 maxs = -999999;
00804
00805 VectorCopy (tex->vecs[axis], temp);
00806 w = f->w;
00807 for (i=0 ; i<w->numpoints ; i++)
00808 {
00809 v = DotProduct (w->p[i], temp);
00810 if (v < mins)
00811 mins = v;
00812 if (v > maxs)
00813 maxs = v;
00814 }
00815 #if 0
00816 if (maxs - mins <= 0)
00817 Error ("zero extents");
00818 #endif
00819 if (axis == 2)
00820 {
00821 if (maxs - mins <= subdivide_size)
00822 break;
00823 }
00824 else if (maxs - mins <= subdivide_size)
00825 break;
00826
00827
00828 c_subdivide++;
00829
00830 v = VectorNormalize (temp);
00831
00832 dist = (mins + subdivide_size - 16)/v;
00833
00834 ClipWindingEpsilon (w, temp, dist, ON_EPSILON, &frontw, &backw);
00835 if (!frontw || !backw)
00836 Error ("SubdivideFace: didn't split the polygon");
00837
00838 f->split[0] = NewFaceFromFace (f);
00839 f->split[0]->w = frontw;
00840 f->split[0]->next = node->faces;
00841 node->faces = f->split[0];
00842
00843 f->split[1] = NewFaceFromFace (f);
00844 f->split[1]->w = backw;
00845 f->split[1]->next = node->faces;
00846 node->faces = f->split[1];
00847
00848 SubdivideFace (node, f->split[0]);
00849 SubdivideFace (node, f->split[1]);
00850 return;
00851 }
00852 }
00853 }
00854
00855 void SubdivideNodeFaces (node_t *node)
00856 {
00857 face_t *f;
00858
00859 for (f = node->faces ; f ; f=f->next)
00860 {
00861 SubdivideFace (node, f);
00862 }
00863 }
00864
00865
00866
00867 int c_nodefaces;
00868
00869
00870
00871
00872
00873
00874
00875
00876 face_t *FaceFromPortal (portal_t *p, int pside)
00877 {
00878 face_t *f;
00879 side_t *side;
00880
00881 side = p->side;
00882 if (!side)
00883 return NULL;
00884
00885 f = AllocFace ();
00886
00887 f->texinfo = side->texinfo;
00888 f->planenum = (side->planenum & ~1) | pside;
00889 f->portal = p;
00890
00891 if ( (p->nodes[pside]->contents & CONTENTS_WINDOW)
00892 && VisibleContents(p->nodes[!pside]->contents^p->nodes[pside]->contents) == CONTENTS_WINDOW )
00893 return NULL;
00894
00895 if (pside)
00896 {
00897 f->w = ReverseWinding(p->winding);
00898 f->contents = p->nodes[1]->contents;
00899 }
00900 else
00901 {
00902 f->w = CopyWinding(p->winding);
00903 f->contents = p->nodes[0]->contents;
00904 }
00905 return f;
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 void MakeFaces_r (node_t *node)
00923 {
00924 portal_t *p;
00925 int s;
00926
00927
00928 if (node->planenum != PLANENUM_LEAF)
00929 {
00930 MakeFaces_r (node->children[0]);
00931 MakeFaces_r (node->children[1]);
00932
00933
00934 if (!nomerge)
00935 MergeNodeFaces (node);
00936 if (!nosubdiv)
00937 SubdivideNodeFaces (node);
00938
00939 return;
00940 }
00941
00942
00943 if (node->contents & CONTENTS_SOLID)
00944 return;
00945
00946
00947 for (p=node->portals ; p ; p = p->next[s])
00948 {
00949 s = (p->nodes[1] == node);
00950
00951 p->face[s] = FaceFromPortal (p, s);
00952 if (p->face[s])
00953 {
00954 c_nodefaces++;
00955 p->face[s]->next = p->onnode->faces;
00956 p->onnode->faces = p->face[s];
00957 }
00958 }
00959 }
00960
00961
00962
00963
00964
00965
00966 void MakeFaces (node_t *node)
00967 {
00968 qprintf ("--- MakeFaces ---\n");
00969 c_merge = 0;
00970 c_subdivide = 0;
00971 c_nodefaces = 0;
00972
00973 MakeFaces_r (node);
00974
00975 qprintf ("%5i makefaces\n", c_nodefaces);
00976 qprintf ("%5i merged\n", c_merge);
00977 qprintf ("%5i subdivided\n", c_subdivide);
00978 }