00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "qbsp.h"
00024 #include "l_mem.h"
00025 #include "../botlib/aasfile.h"
00026 #include "aas_store.h"
00027 #include "aas_cfg.h"
00028 #include "aas_file.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define Sign(x) (x < 0 ? 1 : 0)
00057
00058 #define MAX_TH_VERTEXES 128000
00059 #define MAX_TH_PLANES 128000
00060 #define MAX_TH_EDGES 512000
00061 #define MAX_TH_TRIANGLES 51200
00062 #define MAX_TH_TETRAHEDRONS 12800
00063
00064 #define PLANEHASH_SIZE 1024
00065 #define EDGEHASH_SIZE 1024
00066 #define TRIANGLEHASH_SIZE 1024
00067 #define VERTEXHASH_SHIFT 7
00068 #define VERTEXHASH_SIZE ((MAX_MAP_BOUNDS>>(VERTEXHASH_SHIFT-1))+1) //was 64
00069
00070 #define NORMAL_EPSILON 0.0001
00071 #define DIST_EPSILON 0.1
00072 #define VERTEX_EPSILON 0.01
00073 #define INTEGRAL_EPSILON 0.01
00074
00075
00076
00077 typedef struct th_plane_s
00078 {
00079 vec3_t normal;
00080 float dist;
00081 int type;
00082 int signbits;
00083 struct th_plane_s *hashnext;
00084 } th_plane_t;
00085
00086
00087 typedef struct th_vertex_s
00088 {
00089 vec3_t v;
00090 int usercount;
00091
00092 struct th_vertex_s *hashnext;
00093 } th_vertex_t;
00094
00095
00096 typedef struct th_edge_s
00097 {
00098 int v[2];
00099 int usercount;
00100
00101 struct th_edge_s *hashnext;
00102 } th_edge_t;
00103
00104
00105 typedef struct th_triangle_s
00106 {
00107 int edges[3];
00108 th_plane_t planes[3];
00109 int planenum;
00110 int front;
00111 int back;
00112 vec3_t mins, maxs;
00113 struct th_triangle_s *prev, *next;
00114 struct th_triangle_s *hashnext;
00115 } th_triangle_t;
00116
00117
00118 typedef struct th_tetrahedron_s
00119 {
00120 int triangles[4];
00121 float volume;
00122 } th_tetrahedron_t;
00123
00124 typedef struct th_s
00125 {
00126
00127 int numvertexes;
00128 th_vertex_t *vertexes;
00129 th_vertex_t *vertexhash[VERTEXHASH_SIZE * VERTEXHASH_SIZE];
00130
00131 int numplanes;
00132 th_plane_t *planes;
00133 th_plane_t *planehash[PLANEHASH_SIZE];
00134
00135 int numedges;
00136 th_edge_t *edges;
00137 th_edge_t *edgehash[EDGEHASH_SIZE];
00138
00139 int numtriangles;
00140 th_triangle_t *triangles;
00141 th_triangle_t *trianglehash[TRIANGLEHASH_SIZE];
00142
00143 int numtetrahedrons;
00144 th_tetrahedron_t *tetrahedrons;
00145 } th_t;
00146
00147 th_t thworld;
00148
00149
00150
00151
00152
00153
00154
00155 void TH_InitMaxTH(void)
00156 {
00157
00158 thworld.vertexes = (th_vertex_t *) GetClearedMemory(MAX_TH_VERTEXES * sizeof(th_vertex_t));
00159 thworld.planes = (th_plane_t *) GetClearedMemory(MAX_TH_PLANES * sizeof(th_plane_t));
00160 thworld.edges = (th_edge_t *) GetClearedMemory(MAX_TH_EDGES * sizeof(th_edge_t));
00161 thworld.triangles = (th_triangle_t *) GetClearedMemory(MAX_TH_TRIANGLES * sizeof(th_triangle_t));
00162 thworld.tetrahedrons = (th_tetrahedron_t *) GetClearedMemory(MAX_TH_TETRAHEDRONS * sizeof(th_tetrahedron_t));
00163
00164 memset(thworld.vertexhash, 0, VERTEXHASH_SIZE * sizeof(th_vertex_t *));
00165 memset(thworld.planehash, 0, PLANEHASH_SIZE * sizeof(th_plane_t *));
00166 memset(thworld.edgehash, 0, EDGEHASH_SIZE * sizeof(th_edge_t *));
00167 memset(thworld.trianglehash, 0, TRIANGLEHASH_SIZE * sizeof(th_triangle_t *));
00168 }
00169
00170
00171
00172
00173
00174
00175 void TH_FreeMaxTH(void)
00176 {
00177 if (thworld.vertexes) FreeMemory(thworld.vertexes);
00178 thworld.vertexes = NULL;
00179 thworld.numvertexes = 0;
00180 if (thworld.planes) FreeMemory(thworld.planes);
00181 thworld.planes = NULL;
00182 thworld.numplanes = 0;
00183 if (thworld.edges) FreeMemory(thworld.edges);
00184 thworld.edges = NULL;
00185 thworld.numedges = 0;
00186 if (thworld.triangles) FreeMemory(thworld.triangles);
00187 thworld.triangles = NULL;
00188 thworld.numtriangles = 0;
00189 if (thworld.tetrahedrons) FreeMemory(thworld.tetrahedrons);
00190 thworld.tetrahedrons = NULL;
00191 thworld.numtetrahedrons = 0;
00192 }
00193
00194
00195
00196
00197
00198
00199 float TH_TriangleArea(th_triangle_t *tri)
00200 {
00201 return 0;
00202 }
00203
00204
00205
00206
00207
00208
00209 float TH_TetrahedronVolume(th_tetrahedron_t *tetrahedron)
00210 {
00211 int edgenum, verts[3], i, j, v2;
00212 float volume, d;
00213 th_triangle_t *tri, *tri2;
00214 th_plane_t *plane;
00215
00216 tri = &thworld.triangles[abs(tetrahedron->triangles[0])];
00217 for (i = 0; i < 3; i++)
00218 {
00219 edgenum = tri->edges[i];
00220 if (edgenum < 0) verts[i] = thworld.edges[abs(edgenum)].v[1];
00221 else verts[i] = thworld.edges[edgenum].v[0];
00222 }
00223
00224 tri2 = &thworld.triangles[abs(tetrahedron->triangles[1])];
00225 for (j = 0; j < 3; j++)
00226 {
00227 edgenum = tri2->edges[i];
00228 if (edgenum < 0) v2 = thworld.edges[abs(edgenum)].v[1];
00229 else v2 = thworld.edges[edgenum].v[0];
00230 if (v2 != verts[0] &&
00231 v2 != verts[1] &&
00232 v2 != verts[2]) break;
00233 }
00234
00235 plane = &thworld.planes[tri->planenum];
00236 d = -(DotProduct (thworld.vertexes[v2].v, plane->normal) - plane->dist);
00237 volume = TH_TriangleArea(tri) * d / 3;
00238 return volume;
00239 }
00240
00241
00242
00243
00244
00245
00246 int TH_PlaneSignBits(vec3_t normal)
00247 {
00248 int i, signbits;
00249
00250 signbits = 0;
00251 for (i = 2; i >= 0; i--)
00252 {
00253 signbits = (signbits << 1) + Sign(normal[i]);
00254 }
00255 return signbits;
00256 }
00257
00258
00259
00260
00261
00262
00263 int TH_PlaneTypeForNormal(vec3_t normal)
00264 {
00265 vec_t ax, ay, az;
00266
00267
00268 if (normal[0] == 1.0 || normal[0] == -1.0)
00269 return PLANE_X;
00270 if (normal[1] == 1.0 || normal[1] == -1.0)
00271 return PLANE_Y;
00272 if (normal[2] == 1.0 || normal[2] == -1.0)
00273 return PLANE_Z;
00274
00275 ax = fabs(normal[0]);
00276 ay = fabs(normal[1]);
00277 az = fabs(normal[2]);
00278
00279 if (ax >= ay && ax >= az)
00280 return PLANE_ANYX;
00281 if (ay >= ax && ay >= az)
00282 return PLANE_ANYY;
00283 return PLANE_ANYZ;
00284 }
00285
00286
00287
00288
00289
00290
00291 qboolean TH_PlaneEqual(th_plane_t *p, vec3_t normal, vec_t dist)
00292 {
00293 if (
00294 fabs(p->normal[0] - normal[0]) < NORMAL_EPSILON
00295 && fabs(p->normal[1] - normal[1]) < NORMAL_EPSILON
00296 && fabs(p->normal[2] - normal[2]) < NORMAL_EPSILON
00297 && fabs(p->dist - dist) < DIST_EPSILON )
00298 return true;
00299 return false;
00300 }
00301
00302
00303
00304
00305
00306
00307 void TH_AddPlaneToHash(th_plane_t *p)
00308 {
00309 int hash;
00310
00311 hash = (int)fabs(p->dist) / 8;
00312 hash &= (PLANEHASH_SIZE-1);
00313
00314 p->hashnext = thworld.planehash[hash];
00315 thworld.planehash[hash] = p;
00316 }
00317
00318
00319
00320
00321
00322
00323 int TH_CreateFloatPlane(vec3_t normal, vec_t dist)
00324 {
00325 th_plane_t *p, temp;
00326
00327 if (VectorLength(normal) < 0.5)
00328 Error ("FloatPlane: bad normal");
00329
00330 if (thworld.numplanes+2 > MAX_TH_PLANES)
00331 Error ("MAX_TH_PLANES");
00332
00333 p = &thworld.planes[thworld.numplanes];
00334 VectorCopy (normal, p->normal);
00335 p->dist = dist;
00336 p->type = (p+1)->type = TH_PlaneTypeForNormal (p->normal);
00337 p->signbits = TH_PlaneSignBits(p->normal);
00338
00339 VectorSubtract (vec3_origin, normal, (p+1)->normal);
00340 (p+1)->dist = -dist;
00341 (p+1)->signbits = TH_PlaneSignBits((p+1)->normal);
00342
00343 thworld.numplanes += 2;
00344
00345
00346 if (p->type < 3)
00347 {
00348 if (p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0)
00349 {
00350
00351 temp = *p;
00352 *p = *(p+1);
00353 *(p+1) = temp;
00354
00355 TH_AddPlaneToHash(p);
00356 TH_AddPlaneToHash(p+1);
00357 return thworld.numplanes - 1;
00358 }
00359 }
00360
00361 TH_AddPlaneToHash(p);
00362 TH_AddPlaneToHash(p+1);
00363 return thworld.numplanes - 2;
00364 }
00365
00366
00367
00368
00369
00370
00371 void TH_SnapVector(vec3_t normal)
00372 {
00373 int i;
00374
00375 for (i = 0; i < 3; i++)
00376 {
00377 if ( fabs(normal[i] - 1) < NORMAL_EPSILON )
00378 {
00379 VectorClear (normal);
00380 normal[i] = 1;
00381 break;
00382 }
00383 if ( fabs(normal[i] - -1) < NORMAL_EPSILON )
00384 {
00385 VectorClear (normal);
00386 normal[i] = -1;
00387 break;
00388 }
00389 }
00390 }
00391
00392
00393
00394
00395
00396
00397 void TH_SnapPlane(vec3_t normal, vec_t *dist)
00398 {
00399 TH_SnapVector(normal);
00400
00401 if (fabs(*dist-Q_rint(*dist)) < DIST_EPSILON)
00402 *dist = Q_rint(*dist);
00403 }
00404
00405
00406
00407
00408
00409
00410 int TH_FindFloatPlane(vec3_t normal, vec_t dist)
00411 {
00412 int i;
00413 th_plane_t *p;
00414 int hash, h;
00415
00416 TH_SnapPlane (normal, &dist);
00417 hash = (int)fabs(dist) / 8;
00418 hash &= (PLANEHASH_SIZE-1);
00419
00420
00421 for (i = -1; i <= 1; i++)
00422 {
00423 h = (hash+i)&(PLANEHASH_SIZE-1);
00424 for (p = thworld.planehash[h]; p; p = p->hashnext)
00425 {
00426 if (TH_PlaneEqual(p, normal, dist))
00427 {
00428 return p - thworld.planes;
00429 }
00430 }
00431 }
00432 return TH_CreateFloatPlane(normal, dist);
00433 }
00434
00435
00436
00437
00438
00439
00440 int TH_PlaneFromPoints(int v1, int v2, int v3)
00441 {
00442 vec3_t t1, t2, normal;
00443 vec_t dist;
00444 float *p0, *p1, *p2;
00445
00446 p0 = thworld.vertexes[v1].v;
00447 p1 = thworld.vertexes[v2].v;
00448 p2 = thworld.vertexes[v3].v;
00449
00450 VectorSubtract(p0, p1, t1);
00451 VectorSubtract(p2, p1, t2);
00452 CrossProduct(t1, t2, normal);
00453 VectorNormalize(normal);
00454
00455 dist = DotProduct(p0, normal);
00456
00457 return TH_FindFloatPlane(normal, dist);
00458 }
00459
00460
00461
00462
00463
00464
00465 void TH_AddEdgeUser(int edgenum)
00466 {
00467 th_edge_t *edge;
00468
00469 edge = &thworld.edges[abs(edgenum)];
00470
00471 edge->usercount++;
00472
00473 thworld.vertexes[edge->v[0]].usercount++;
00474 thworld.vertexes[edge->v[1]].usercount++;
00475 }
00476
00477
00478
00479
00480
00481
00482 void TH_RemoveEdgeUser(int edgenum)
00483 {
00484 th_edge_t *edge;
00485
00486 edge = &thworld.edges[abs(edgenum)];
00487
00488 edge->usercount--;
00489
00490 thworld.vertexes[edge->v[0]].usercount--;
00491 thworld.vertexes[edge->v[1]].usercount--;
00492 }
00493
00494
00495
00496
00497
00498
00499 void TH_FreeTriangleEdges(th_triangle_t *tri)
00500 {
00501 int i;
00502
00503 for (i = 0; i < 3; i++)
00504 {
00505 TH_RemoveEdgeUser(abs(tri->edges[i]));
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514 unsigned TH_HashVec(vec3_t vec)
00515 {
00516 int x, y;
00517
00518 x = (MAX_MAP_BOUNDS + (int)(vec[0]+0.5)) >> VERTEXHASH_SHIFT;
00519 y = (MAX_MAP_BOUNDS + (int)(vec[1]+0.5)) >> VERTEXHASH_SHIFT;
00520
00521 if (x < 0 || x >= VERTEXHASH_SIZE || y < 0 || y >= VERTEXHASH_SIZE)
00522 Error("HashVec: point %f %f %f outside valid range", vec[0], vec[1], vec[2]);
00523
00524 return y*VERTEXHASH_SIZE + x;
00525 }
00526
00527
00528
00529
00530
00531
00532 int TH_FindVertex(vec3_t v)
00533 {
00534 int i, h;
00535 th_vertex_t *vertex;
00536 vec3_t vert;
00537
00538 for (i = 0; i < 3; i++)
00539 {
00540 if ( fabs(v[i] - Q_rint(v[i])) < INTEGRAL_EPSILON)
00541 vert[i] = Q_rint(v[i]);
00542 else
00543 vert[i] = v[i];
00544 }
00545
00546 h = TH_HashVec(vert);
00547
00548 for (vertex = thworld.vertexhash[h]; vertex; vertex = vertex->hashnext)
00549 {
00550 if (fabs(vertex->v[0] - vert[0]) < VERTEX_EPSILON &&
00551 fabs(vertex->v[1] - vert[1]) < VERTEX_EPSILON &&
00552 fabs(vertex->v[2] - vert[2]) < VERTEX_EPSILON)
00553 {
00554 return vertex - thworld.vertexes;
00555 }
00556 }
00557 return 0;
00558 }
00559
00560
00561
00562
00563
00564
00565 void TH_AddVertexToHash(th_vertex_t *vertex)
00566 {
00567 int hashvalue;
00568
00569 hashvalue = TH_HashVec(vertex->v);
00570 vertex->hashnext = thworld.vertexhash[hashvalue];
00571 thworld.vertexhash[hashvalue] = vertex;
00572 }
00573
00574
00575
00576
00577
00578
00579 int TH_CreateVertex(vec3_t v)
00580 {
00581 if (thworld.numvertexes == 0) thworld.numvertexes = 1;
00582 if (thworld.numvertexes >= MAX_TH_VERTEXES)
00583 Error("MAX_TH_VERTEXES");
00584 VectorCopy(v, thworld.vertexes[thworld.numvertexes].v);
00585 thworld.vertexes[thworld.numvertexes].usercount = 0;
00586 TH_AddVertexToHash(&thworld.vertexes[thworld.numvertexes]);
00587 thworld.numvertexes++;
00588 return thworld.numvertexes-1;
00589 }
00590
00591
00592
00593
00594
00595
00596 int TH_FindOrCreateVertex(vec3_t v)
00597 {
00598 int vertexnum;
00599
00600 vertexnum = TH_FindVertex(v);
00601 if (!vertexnum) vertexnum = TH_CreateVertex(v);
00602 return vertexnum;
00603 }
00604
00605
00606
00607
00608
00609
00610 int TH_FindEdge(int v1, int v2)
00611 {
00612 int hashvalue;
00613 th_edge_t *edge;
00614
00615 hashvalue = (v1 + v2) & (EDGEHASH_SIZE-1);
00616
00617 for (edge = thworld.edgehash[hashvalue]; edge; edge = edge->hashnext)
00618 {
00619 if (edge->v[0] == v1 && edge->v[1] == v2) return edge - thworld.edges;
00620 if (edge->v[1] == v1 && edge->v[0] == v2) return -(edge - thworld.edges);
00621 }
00622 return 0;
00623 }
00624
00625
00626
00627
00628
00629
00630 void TH_AddEdgeToHash(th_edge_t *edge)
00631 {
00632 int hashvalue;
00633
00634 hashvalue = (edge->v[0] + edge->v[1]) & (EDGEHASH_SIZE-1);
00635 edge->hashnext = thworld.edgehash[hashvalue];
00636 thworld.edgehash[hashvalue] = edge;
00637 }
00638
00639
00640
00641
00642
00643
00644 int TH_CreateEdge(int v1, int v2)
00645 {
00646 th_edge_t *edge;
00647
00648 if (thworld.numedges == 0) thworld.numedges = 1;
00649 if (thworld.numedges >= MAX_TH_EDGES)
00650 Error("MAX_TH_EDGES");
00651 edge = &thworld.edges[thworld.numedges++];
00652 edge->v[0] = v1;
00653 edge->v[1] = v2;
00654 TH_AddEdgeToHash(edge);
00655 return thworld.numedges-1;
00656 }
00657
00658
00659
00660
00661
00662
00663 int TH_FindOrCreateEdge(int v1, int v2)
00664 {
00665 int edgenum;
00666
00667 edgenum = TH_FindEdge(v1, v2);
00668 if (!edgenum) edgenum = TH_CreateEdge(v1, v2);
00669 return edgenum;
00670 }
00671
00672
00673
00674
00675
00676
00677 int TH_FindTriangle(int verts[3])
00678 {
00679 int i, hashvalue, edges[3];
00680 th_triangle_t *tri;
00681
00682 for (i = 0; i < 3; i++)
00683 {
00684 edges[i] = TH_FindEdge(verts[i], verts[(i+1)%3]);
00685 if (!edges[i]) return false;
00686 }
00687 hashvalue = (abs(edges[0]) + abs(edges[1]) + abs(edges[2])) & (TRIANGLEHASH_SIZE-1);
00688 for (tri = thworld.trianglehash[hashvalue]; tri; tri = tri->next)
00689 {
00690 for (i = 0; i < 3; i++)
00691 {
00692 if (abs(tri->edges[i]) != abs(edges[0]) &&
00693 abs(tri->edges[i]) != abs(edges[1]) &&
00694 abs(tri->edges[i]) != abs(edges[2])) break;
00695 }
00696 if (i >= 3) return tri - thworld.triangles;
00697 }
00698 return 0;
00699 }
00700
00701
00702
00703
00704
00705
00706 void TH_AddTriangleToHash(th_triangle_t *tri)
00707 {
00708 int hashvalue;
00709
00710 hashvalue = (abs(tri->edges[0]) + abs(tri->edges[1]) + abs(tri->edges[2])) & (TRIANGLEHASH_SIZE-1);
00711 tri->hashnext = thworld.trianglehash[hashvalue];
00712 thworld.trianglehash[hashvalue] = tri;
00713 }
00714
00715
00716
00717
00718
00719
00720 void TH_CreateTrianglePlanes(int verts[3], th_plane_t *triplane, th_plane_t *planes)
00721 {
00722 int i;
00723 vec3_t dir;
00724
00725 for (i = 0; i < 3; i++)
00726 {
00727 VectorSubtract(thworld.vertexes[verts[(i+1)%3]].v, thworld.vertexes[verts[i]].v, dir);
00728 CrossProduct(dir, triplane->normal, planes[i].normal);
00729 VectorNormalize(planes[i].normal);
00730 planes[i].dist = DotProduct(thworld.vertexes[verts[i]].v, planes[i].normal);
00731 }
00732 }
00733
00734
00735
00736
00737
00738
00739 int TH_CreateTriangle(int verts[3])
00740 {
00741 th_triangle_t *tri;
00742 int i;
00743
00744 if (thworld.numtriangles == 0) thworld.numtriangles = 1;
00745 if (thworld.numtriangles >= MAX_TH_TRIANGLES)
00746 Error("MAX_TH_TRIANGLES");
00747 tri = &thworld.triangles[thworld.numtriangles++];
00748 for (i = 0; i < 3; i++)
00749 {
00750 tri->edges[i] = TH_FindOrCreateEdge(verts[i], verts[(i+1)%3]);
00751 TH_AddEdgeUser(abs(tri->edges[i]));
00752 }
00753 tri->front = 0;
00754 tri->back = 0;
00755 tri->planenum = TH_PlaneFromPoints(verts[0], verts[1], verts[2]);
00756 tri->prev = NULL;
00757 tri->next = NULL;
00758 tri->hashnext = NULL;
00759 TH_CreateTrianglePlanes(verts, &thworld.planes[tri->planenum], tri->planes);
00760 TH_AddTriangleToHash(tri);
00761 ClearBounds(tri->mins, tri->maxs);
00762 for (i = 0; i < 3; i++)
00763 {
00764 AddPointToBounds(thworld.vertexes[verts[i]].v, tri->mins, tri->maxs);
00765 }
00766 return thworld.numtriangles-1;
00767 }
00768
00769
00770
00771
00772
00773
00774 int TH_CreateTetrahedron(int triangles[4])
00775 {
00776 th_tetrahedron_t *tetrahedron;
00777 int i;
00778
00779 if (thworld.numtetrahedrons == 0) thworld.numtetrahedrons = 1;
00780 if (thworld.numtetrahedrons >= MAX_TH_TETRAHEDRONS)
00781 Error("MAX_TH_TETRAHEDRONS");
00782 tetrahedron = &thworld.tetrahedrons[thworld.numtetrahedrons++];
00783 for (i = 0; i < 4; i++)
00784 {
00785 tetrahedron->triangles[i] = triangles[i];
00786 if (thworld.triangles[abs(triangles[i])].front)
00787 {
00788 thworld.triangles[abs(triangles[i])].back = thworld.numtetrahedrons-1;
00789 }
00790 else
00791 {
00792 thworld.triangles[abs(triangles[i])].front = thworld.numtetrahedrons-1;
00793 }
00794 }
00795 tetrahedron->volume = 0;
00796 return thworld.numtetrahedrons-1;
00797 }
00798
00799
00800
00801
00802
00803
00804 int TH_IntersectTrianglePlanes(int v1, int v2, th_plane_t *triplane, th_plane_t *planes)
00805 {
00806 float *p1, *p2, front, back, frac, d;
00807 int i, side, lastside;
00808 vec3_t mid;
00809
00810 p1 = thworld.vertexes[v1].v;
00811 p2 = thworld.vertexes[v2].v;
00812
00813 front = DotProduct(p1, triplane->normal) - triplane->dist;
00814 back = DotProduct(p2, triplane->normal) - triplane->dist;
00815
00816 if (front < 0.1 && back < 0.1) return false;
00817 if (front > -0.1 && back > -0.1) return false;
00818
00819 frac = front/(front-back);
00820 mid[0] = p1[0] + (p2[0] - p1[0]) * frac;
00821 mid[1] = p1[1] + (p2[1] - p1[1]) * frac;
00822 mid[2] = p1[2] + (p2[2] - p1[2]) * frac;
00823
00824 lastside = 0;
00825 for (i = 0; i < 3; i++)
00826 {
00827 d = DotProduct(mid, planes[i].normal) - planes[i].dist;
00828 side = d < 0;
00829 if (i && side != lastside) return false;
00830 lastside = side;
00831 }
00832 return true;
00833 }
00834
00835
00836
00837
00838
00839
00840 int TH_OutsideBoundingBox(int v1, int v2, vec3_t mins, vec3_t maxs)
00841 {
00842 float *p1, *p2;
00843 int i;
00844
00845 p1 = thworld.vertexes[v1].v;
00846 p2 = thworld.vertexes[v2].v;
00847
00848 for (i = 0; i < 3; i++)
00849 {
00850 if (p1[i] < mins[i] && p2[i] < mins[i]) return true;
00851 if (p1[i] > maxs[i] && p2[i] > maxs[i]) return true;
00852 }
00853 return false;
00854 }
00855
00856
00857
00858
00859
00860
00861 int TH_TryEdge(int v1, int v2)
00862 {
00863 int i, j, v;
00864 th_plane_t *plane;
00865 th_triangle_t *tri;
00866
00867
00868 if (TH_FindEdge(v1, v2)) return true;
00869
00870 for (i = 1; i < thworld.numtriangles; i++)
00871 {
00872 tri = &thworld.triangles[i];
00873
00874
00875
00876 if (tri->front && tri->back) continue;
00877
00878 if (TH_OutsideBoundingBox(v1, v2, tri->mins, tri->maxs)) continue;
00879
00880 for (j = 0; j < 3; j++)
00881 {
00882 v = thworld.edges[abs(tri->edges[j])].v[tri->edges[j] < 0];
00883 if (v == v1 || v == v2) break;
00884 }
00885 if (j < 3) continue;
00886
00887 plane = &thworld.planes[tri->planenum];
00888
00889 if (TH_IntersectTrianglePlanes(v1, v2, plane, tri->planes)) return false;
00890 }
00891 return true;
00892 }
00893
00894
00895
00896
00897
00898
00899 int TH_TryTriangle(int verts[3])
00900 {
00901 th_plane_t planes[3], triplane;
00902 vec3_t t1, t2;
00903 float *p0, *p1, *p2;
00904 int i, j;
00905
00906 p0 = thworld.vertexes[verts[0]].v;
00907 p1 = thworld.vertexes[verts[1]].v;
00908 p2 = thworld.vertexes[verts[2]].v;
00909
00910 VectorSubtract(p0, p1, t1);
00911 VectorSubtract(p2, p1, t2);
00912 CrossProduct(t1, t2, triplane.normal);
00913 VectorNormalize(triplane.normal);
00914 triplane.dist = DotProduct(p0, triplane.normal);
00915
00916 TH_CreateTrianglePlanes(verts, &triplane, planes);
00917
00918 for (i = 1; i < thworld.numedges; i++)
00919 {
00920
00921 if (!thworld.edges[i].usercount) continue;
00922
00923 for (j = 0; j < 3; j++)
00924 {
00925 if (verts[j] == thworld.edges[j].v[0] ||
00926 verts[j] == thworld.edges[j].v[1]) break;
00927 }
00928 if (j < 3) continue;
00929
00930 if (TH_IntersectTrianglePlanes(thworld.edges[i].v[0], thworld.edges[i].v[1], &triplane, planes)) return false;
00931 }
00932 return true;
00933 }
00934
00935
00936
00937
00938
00939
00940 void TH_AddTriangleToList(th_triangle_t **trianglelist, th_triangle_t *tri)
00941 {
00942 tri->prev = NULL;
00943 tri->next = *trianglelist;
00944 if (*trianglelist) (*trianglelist)->prev = tri;
00945 *trianglelist = tri;
00946 }
00947
00948
00949
00950
00951
00952
00953 void TH_RemoveTriangleFromList(th_triangle_t **trianglelist, th_triangle_t *tri)
00954 {
00955 if (tri->next) tri->next->prev = tri->prev;
00956 if (tri->prev) tri->prev->next = tri->next;
00957 else *trianglelist = tri->next;
00958 }
00959
00960
00961
00962
00963
00964
00965 int TH_FindTetrahedron1(th_triangle_t *tri, int *triangles)
00966 {
00967 int i, j, edgenum, side, v1, v2, v3, v4;
00968 int verts1[3], verts2[3];
00969 th_triangle_t *tri2;
00970
00971
00972 for (tri2 = tri->next; tri2; tri2 = tri2->next)
00973 {
00974
00975 if ((tri->planenum & ~1) == (tri2->planenum & ~1)) continue;
00976
00977 for (i = 0; i < 3; i++)
00978 {
00979 edgenum = abs(tri->edges[i]);
00980 for (j = 0; j < 3; j++)
00981 {
00982 if (edgenum == abs(tri2->edges[j])) break;
00983 }
00984 if (j < 3) break;
00985 }
00986
00987 if (i < 3)
00988 {
00989 edgenum = tri->edges[(i+1)%3];
00990 if (edgenum < 0) v1 = thworld.edges[abs(edgenum)].v[0];
00991 else v1 = thworld.edges[edgenum].v[1];
00992 edgenum = tri2->edges[(j+1)%3];
00993 if (edgenum < 0) v2 = thworld.edges[abs(edgenum)].v[0];
00994 else v2 = thworld.edges[edgenum].v[1];
00995
00996 if (TH_TryEdge(v1, v2))
00997 {
00998 edgenum = tri->edges[i];
00999 side = edgenum < 0;
01000
01001 v3 = thworld.edges[abs(edgenum)].v[side];
01002 v4 = thworld.edges[abs(edgenum)].v[!side];
01003
01004 verts1[0] = v1;
01005 verts1[1] = v2;
01006 verts1[2] = v3;
01007 triangles[2] = TH_FindTriangle(verts1);
01008 if (triangles[2] || TH_TryTriangle(verts1))
01009 {
01010 verts2[0] = v2;
01011 verts2[1] = v1;
01012 verts2[2] = v4;
01013 triangles[3] = TH_FindTriangle(verts2);
01014 if (triangles[3] || TH_TryTriangle(verts2))
01015 {
01016 triangles[0] = tri - thworld.triangles;
01017 triangles[1] = tri2 - thworld.triangles;
01018 if (!triangles[2]) triangles[2] = TH_CreateTriangle(verts1);
01019 if (!triangles[3]) triangles[3] = TH_CreateTriangle(verts2);
01020 return true;
01021 }
01022 }
01023 }
01024 }
01025 }
01026 return false;
01027 }
01028
01029
01030
01031
01032
01033
01034 int TH_FindTetrahedron2(th_triangle_t *tri, int *triangles)
01035 {
01036 int i, edgenum, v1, verts[3], triverts[3];
01037 float d;
01038 th_plane_t *plane;
01039
01040
01041 for (i = 0; i < 3; i++)
01042 {
01043 edgenum = tri->edges[i];
01044 if (edgenum < 0) verts[i] = thworld.edges[abs(edgenum)].v[1];
01045 else verts[i] = thworld.edges[edgenum].v[0];
01046 }
01047
01048 plane = &thworld.planes[tri->planenum];
01049 for (v1 = 0; v1 < thworld.numvertexes; v1++)
01050 {
01051
01052 if (!thworld.vertexes[v1].usercount) continue;
01053
01054 d = DotProduct(thworld.vertexes[v1].v, plane->normal) - plane->dist;
01055 if (fabs(d) < 1) continue;
01056
01057 for (i = 0; i < 3; i++)
01058 {
01059 if (v1 == verts[i]) break;
01060 if (!TH_TryEdge(v1, verts[i])) break;
01061 }
01062 if (i < 3) continue;
01063
01064 for (i = 0; i < 3; i++)
01065 {
01066 triverts[0] = v1;
01067 triverts[1] = verts[i];
01068 triverts[2] = verts[(i+1)%3];
01069
01070 triangles[i] = TH_FindTriangle(triverts);
01071 if (!triangles[i])
01072 {
01073 if (!TH_TryTriangle(triverts)) break;
01074 }
01075 }
01076 if (i < 3) continue;
01077
01078 for (i = 0; i < 3; i++)
01079 {
01080 if (!triangles[i])
01081 {
01082 triverts[0] = v1;
01083 triverts[1] = verts[i];
01084 triverts[2] = verts[(i+1)%3];
01085 triangles[i] = TH_CreateTriangle(triverts);
01086 }
01087 }
01088
01089 triangles[3] = tri - thworld.triangles;
01090
01091 return true;
01092 }
01093 return false;
01094 }
01095
01096
01097
01098
01099