00001 #include <windows.h>
00002 #include "portal.h"
00003 #include "locmath.h"
00004 #include "listnode.h"
00005 #include "collision.h"
00006 #include "general.h"
00007 #include "bsp.h"
00008 #include "tll.h"
00009 #include "mmgr.h"
00010
00011 extern float Min_X, Min_Y, Min_Z, Max_X, Max_Y, Max_Z;
00012 extern int numpartitions;
00013 extern ListNode* listnode;
00014 extern LinkedList<ListNode> LeafList;
00015 extern LinkedList<ListNode> PartitionList;
00016 extern LinkedList<PORTAL> PortalList;
00017 extern int numportals;
00018 extern PORTAL* portal;
00019 extern BSP_node* root;
00020
00021 PORTAL::PORTAL()
00022 {
00023 }
00024
00025 PORTAL::~PORTAL()
00026 {
00027 }
00028
00029 int PORTAL::Compare(const PORTAL& Portal)
00030 {
00031 if (linkPosition < Portal.linkPosition)
00032 return smaller;
00033 if (linkPosition > Portal.linkPosition)
00034 return bigger;
00035 else
00036 return same;
00037 }
00038
00039 VECTOR PORTAL::GetNormal()
00040 {
00041 VECTOR temp;
00042 float ux;
00043 float uy;
00044 float uz;
00045 float vx;
00046 float vy;
00047 float vz;
00048 ux = Vertex[1].x - Vertex[0].x;
00049 uy = Vertex[1].y - Vertex[0].y;
00050 uz = Vertex[1].z - Vertex[0].z;
00051 vx = Vertex[2].x - Vertex[0].x;
00052 vy = Vertex[2].y - Vertex[0].y;
00053 vz = Vertex[2].z - Vertex[0].z;
00054 temp.x = (uy*vz)-(vy*uz);
00055 temp.y = (uz*vx)-(vz*ux);
00056 temp.z = (ux*vy)-(vx*uy);
00057 return temp;
00058 }
00059
00060 void PORTAL::SetNormal()
00061 {
00062 float ux;
00063 float uy;
00064 float uz;
00065 float vx;
00066 float vy;
00067 float vz;
00068 ux = Vertex[1].x - Vertex[0].x;
00069 uy = Vertex[1].y - Vertex[0].y;
00070 uz = Vertex[1].z - Vertex[0].z;
00071 vx = Vertex[2].x - Vertex[0].x;
00072 vy = Vertex[2].y - Vertex[0].y;
00073 vz = Vertex[2].z - Vertex[0].z;
00074 Vertex[0].nx = (uy*vz)-(vy*uz);
00075 Vertex[0].ny = (uz*vx)-(vz*ux);
00076 Vertex[0].nz = (ux*vy)-(vx*uy);
00077 Vertex[1].nx = Vertex[0].nx;
00078 Vertex[1].ny = Vertex[0].ny;
00079 Vertex[1].nz = Vertex[0].nz;
00080 Vertex[2].nx = Vertex[0].nx;
00081 Vertex[2].ny = Vertex[0].ny;
00082 Vertex[2].nz = Vertex[0].nz;
00083 }
00084
00085 PORTAL* CopyPortal(PORTAL* portal)
00086 {
00087 PORTAL* tempportal = new PORTAL;
00088 *tempportal = *portal;
00089 tempportal->Vertex = new VERTEX[portal->numVertices];
00090 for (int loop = 0; loop < portal->numVertices; loop++)
00091 tempportal->Vertex[loop] = portal->Vertex[loop];
00092 return tempportal;
00093 }
00094
00095 void CreateLargePortal(POLYGON splittingPolygon, PORTAL* largePortal)
00096 {
00097
00098 largePortal->numVertices = 4;
00099 largePortal->Vertex = new VERTEX[4];
00100
00101 int flag = 0;
00102 VECTOR poly_normal = splittingPolygon.GetNormal();
00103 poly_normal.Normalize();
00104
00105 if (fabs(poly_normal.x) > fabs(poly_normal.y) && fabs(poly_normal.x) > fabs(poly_normal.z))
00106 {
00107 flag = 1;
00108 largePortal->Vertex[0].y = Min_Y;
00109 largePortal->Vertex[0].z = Max_Z;
00110 largePortal->Vertex[1].y = Min_Y;
00111 largePortal->Vertex[1].z = Min_Z;
00112 largePortal->Vertex[2].y = Max_Y;
00113 largePortal->Vertex[2].z = Min_Z;
00114 largePortal->Vertex[3].y = Max_Y;
00115 largePortal->Vertex[3].z = Max_Z;
00116 }
00117 else if (fabs(poly_normal.y) > fabs(poly_normal.x) && fabs(poly_normal.y) > fabs(poly_normal.z))
00118 {
00119 flag = 2;
00120 largePortal->Vertex[0].x = Min_X;
00121 largePortal->Vertex[0].z = Max_Z;
00122 largePortal->Vertex[1].x = Max_X;
00123 largePortal->Vertex[1].z = Max_Z;
00124 largePortal->Vertex[2].x = Max_X;
00125 largePortal->Vertex[2].z = Min_Z;
00126 largePortal->Vertex[3].x = Min_X;
00127 largePortal->Vertex[3].z = Min_Z;
00128 }
00129 else
00130 {
00131 flag = 3;
00132 largePortal->Vertex[0].x = Min_X;
00133 largePortal->Vertex[0].y = Min_Y;
00134 largePortal->Vertex[1].x = Max_X;
00135 largePortal->Vertex[1].y = Min_Y;
00136 largePortal->Vertex[2].x = Max_X;
00137 largePortal->Vertex[2].y = Max_Y;
00138 largePortal->Vertex[3].x = Min_X;
00139 largePortal->Vertex[3].y = Max_Y;
00140 }
00141
00142 float X, Y, Z;
00143 float Distance = - (poly_normal.x * splittingPolygon.Vertex[0].x + poly_normal.y * splittingPolygon.Vertex[0].y + poly_normal.z * splittingPolygon.Vertex[0].z);
00144 switch (flag)
00145 {
00146 case 1:
00147 X = - ( poly_normal.y * Min_Y + poly_normal.z * Max_Z + Distance ) / poly_normal.x;
00148 largePortal->Vertex[0].x = X;
00149 X = - ( poly_normal.y * Min_Y + poly_normal.z * Min_Z + Distance ) / poly_normal.x;
00150 largePortal->Vertex[1].x = X;
00151 X = - ( poly_normal.y * Max_Y + poly_normal.z * Min_Z + Distance ) / poly_normal.x;
00152 largePortal->Vertex[2].x = X;
00153 X = - ( poly_normal.y * Max_Y + poly_normal.z * Max_Z + Distance ) / poly_normal.x;
00154 largePortal->Vertex[3].x = X;
00155 break;
00156 case 2:
00157 Y = - ( poly_normal.x * Min_X + poly_normal.z * Max_Z + Distance ) / poly_normal.y;
00158 largePortal->Vertex[0].y = Y;
00159 Y = - ( poly_normal.x * Max_X + poly_normal.z * Max_Z + Distance ) / poly_normal.y;
00160 largePortal->Vertex[1].y = Y;
00161 Y = - ( poly_normal.x * Max_X + poly_normal.z * Min_Z + Distance ) / poly_normal.y;
00162 largePortal->Vertex[2].y = Y;
00163 Y = - ( poly_normal.x * Min_X + poly_normal.z * Min_Z + Distance ) / poly_normal.y;
00164 largePortal->Vertex[3].y = Y;
00165 break;
00166 case 3:
00167 Z = - ( poly_normal.x * Min_X + poly_normal.y * Min_Y + Distance ) / poly_normal.z;
00168 largePortal->Vertex[0].z = Z;
00169 Z = - ( poly_normal.x * Max_X + poly_normal.y * Min_Y + Distance ) / poly_normal.z;
00170 largePortal->Vertex[1].z = Z;
00171 Z = - ( poly_normal.x * Max_X + poly_normal.y * Max_Y + Distance ) / poly_normal.z;
00172 largePortal->Vertex[2].z = Z;
00173 Z = - ( poly_normal.x * Min_X + poly_normal.y * Max_Y + Distance ) / poly_normal.z;
00174 largePortal->Vertex[3].z = Z;
00175 break;
00176 }
00177 largePortal->SetNormal();
00178 }
00179
00180 int SplitPortal(PORTAL* portalToSplit, POLYGON planePolygon, PORTAL* front, PORTAL* back)
00181 {
00182 const int MaxVerts = 100;
00183 int numVerts = portalToSplit->numVertices;
00184 int count = 0, out_c = 0, in_c = 0, sideA, sideB, loop;
00185 VECTOR planeNormal, polysNormal, pointOnPlane, edge1, edge2, temp;
00186 VERTEX ptA, ptB, intersection, outpts[MaxVerts], inpts[MaxVerts];
00187
00188
00189 pointOnPlane.x = planePolygon.Vertex[0].x;
00190 pointOnPlane.y = planePolygon.Vertex[0].y;
00191 pointOnPlane.z = planePolygon.Vertex[0].z;
00192
00193
00194 edge1.x = planePolygon.Vertex[1].x - planePolygon.Vertex[0].x;
00195 edge1.y = planePolygon.Vertex[1].y - planePolygon.Vertex[0].y;
00196 edge1.z = planePolygon.Vertex[1].z - planePolygon.Vertex[0].z;
00197 edge2.x = planePolygon.Vertex[2].x - planePolygon.Vertex[0].x;
00198 edge2.y = planePolygon.Vertex[2].y - planePolygon.Vertex[0].y;
00199 edge2.z = planePolygon.Vertex[2].z - planePolygon.Vertex[0].z;
00200 planeNormal = CrossVector(edge1, edge2);
00201
00202
00203 edge1.x = portalToSplit->Vertex[1].x - portalToSplit->Vertex[0].x;
00204 edge1.y = portalToSplit->Vertex[1].y - portalToSplit->Vertex[0].y;
00205 edge1.z = portalToSplit->Vertex[1].z - portalToSplit->Vertex[0].z;
00206 edge2.x = portalToSplit->Vertex[2].x - portalToSplit->Vertex[0].x;
00207 edge2.y = portalToSplit->Vertex[2].y - portalToSplit->Vertex[0].y;
00208 edge2.z = portalToSplit->Vertex[2].z - portalToSplit->Vertex[0].z;
00209 polysNormal = CrossVector(edge1, edge2);
00210
00211
00212 for (int loop = 0; loop < numVerts; loop++)
00213 {
00214 temp.x = portalToSplit->Vertex[loop].x;
00215 temp.y = portalToSplit->Vertex[loop].y;
00216 temp.z = portalToSplit->Vertex[loop].z;
00217 if (ClassifyPoint(temp, pointOnPlane, planeNormal) == 0)
00218 count++;
00219 else
00220 break;
00221 }
00222 if (count == numVerts)
00223 {
00224 if (ClassifyPoint(polysNormal, pointOnPlane, planeNormal) == 1)
00225 return Front;
00226 if (ClassifyPoint(polysNormal, pointOnPlane, planeNormal) == -1)
00227 return Back;
00228 }
00229
00230
00231 int frontcount = 0, backcount = 0;
00232 for (int loop = 0; loop < numVerts; loop++)
00233 {
00234 temp.x = portalToSplit->Vertex[loop].x;
00235 temp.y = portalToSplit->Vertex[loop].y;
00236 temp.z = portalToSplit->Vertex[loop].z;
00237 if (ClassifyPoint(temp, pointOnPlane, planeNormal) == 0)
00238 {
00239 frontcount++;
00240 backcount++;
00241 }
00242 else if (ClassifyPoint(temp, pointOnPlane, planeNormal) == 1)
00243 frontcount++;
00244 else if (ClassifyPoint(temp, pointOnPlane, planeNormal) == -1)
00245 backcount++;
00246 }
00247 if (frontcount == numVerts)
00248 return Front;
00249 if (backcount == numVerts)
00250 return Back;
00251
00252
00253 ptA = portalToSplit->Vertex[numVerts - 1];
00254 temp.x = ptA.x;
00255 temp.y = ptA.y;
00256 temp.z = ptA.z;
00257 sideA = ClassifyPoint(temp, pointOnPlane, planeNormal);
00258 for (int i = -1; ++i < numVerts;)
00259 {
00260 ptB = portalToSplit->Vertex[i];
00261 temp.x = ptB.x;
00262 temp.y = ptB.y;
00263 temp.z = ptB.z;
00264 sideB = ClassifyPoint(temp, pointOnPlane, planeNormal);
00265 if (sideB > 0)
00266 {
00267 if (sideA < 0)
00268 {
00269
00270 edge1.x = ptA.x;
00271 edge1.y = ptA.y;
00272 edge1.z = ptA.z;
00273 edge2.x = ptB.x;
00274 edge2.y = ptB.y;
00275 edge2.z = ptB.z;
00276
00277 temp = GetEdgeIntersection(edge1, edge2, planePolygon);
00278 intersection.x = temp.x;
00279 intersection.y = temp.y;
00280 intersection.z = temp.z;
00281
00282 outpts[out_c++] = inpts[in_c++] = intersection;
00283 }
00284 inpts[in_c++] = ptB;
00285 }
00286 else if (sideB < 0)
00287 {
00288 if (sideA > 0)
00289 {
00290
00291 edge1.x = ptA.x;
00292 edge1.y = ptA.y;
00293 edge1.z = ptA.z;
00294 edge2.x = ptB.x;
00295 edge2.y = ptB.y;
00296 edge2.z = ptB.z;
00297
00298 temp = GetEdgeIntersection(edge1, edge2, planePolygon);
00299 intersection.x = temp.x;
00300 intersection.y = temp.y;
00301 intersection.z = temp.z;
00302
00303 outpts[out_c++] = inpts[in_c++] = intersection;
00304 }
00305 outpts[out_c++] = ptB;
00306 }
00307 else
00308 outpts[out_c++] = inpts[in_c++] = ptB;
00309 ptA = ptB;
00310 sideA = sideB;
00311 }
00312
00313 if (out_c == 0 || in_c == 0)
00314 {
00315 int side;
00316
00317 for (int loop = 0; loop < numVerts; loop++)
00318 {
00319 temp.x = portalToSplit->Vertex[loop].x;
00320 temp.y = portalToSplit->Vertex[loop].y;
00321 temp.z = portalToSplit->Vertex[loop].z;
00322 side = ClassifyPoint(temp, pointOnPlane, planeNormal);
00323 if (side == 1)
00324 return Front;
00325 else if (side == -1)
00326 return Back;
00327 }
00328 }
00329 else
00330 {
00331 front->Vertex = new VERTEX[in_c];
00332 back->Vertex = new VERTEX[out_c];
00333 front->numVertices = in_c;
00334 back->numVertices = out_c;
00335
00336 for (loop = 0; loop < in_c; loop++)
00337 front->Vertex[loop] = inpts[loop];
00338 for (loop = 0; loop < out_c; loop++)
00339 back->Vertex[loop] = outpts[loop];
00340 return PortalWasSplit;
00341 }
00342 return 0;
00343 }
00344
00345 void MakePortalList()
00346 {
00347
00348 for (int loop = 1; loop <= numpartitions; loop++)
00349 {
00350 listnode = PartitionList.Get(loop);
00351 portal = new PORTAL;
00352 portal->Vertex = 0;
00353 portal->linkPosition = loop;
00354 portal->PartitionNodeId = loop;
00355 CreateLargePortal(listnode->node->partition, portal);
00356 PortalList.Insert(portal);
00357 }
00358
00359
00360 numportals = numpartitions;
00361 int result, portalToSplit;
00362 PORTAL* frontportal;
00363 PORTAL* backportal;
00364 for (int partition = 1; partition <= numpartitions; partition++)
00365 {
00366 listnode = PartitionList.Get(partition);
00367 portalToSplit = numportals;
00368 while (portalToSplit > 0)
00369 {
00370 frontportal = new PORTAL;
00371 backportal = new PORTAL;
00372
00373 portal = PortalList.Get(portalToSplit);
00374 result = SplitPortal(portal, listnode->node->partition, frontportal, backportal);
00375
00376 if (result == PortalWasSplit)
00377 {
00378 frontportal->PartitionNodeId = portal->PartitionNodeId;
00379 backportal->PartitionNodeId = portal->PartitionNodeId;
00380
00381 delete[] portal->Vertex;
00382 portal->Vertex = 0;
00383 PortalList.Delete(portalToSplit);
00384 delete portal;
00385 numportals--;
00386
00387 frontportal->linkPosition = ++numportals;
00388 PortalList.Insert(frontportal);
00389 backportal->linkPosition = ++numportals;
00390 PortalList.Insert(backportal);
00391 }
00392 else
00393 {
00394 delete frontportal;
00395 delete backportal;
00396 }
00397 portalToSplit--;
00398 }
00399 }
00400
00401
00402 for (int loop = 1; loop <= numportals; loop++)
00403 {
00404 portal = PortalList.Get(loop);
00405 portal->PortalId = loop;
00406 }
00407 }
00408
00409 int ClassifyPortal(PORTAL* portal, POLYGON planePolygon)
00410 {
00411 int numVerts = portal->numVertices;
00412 int count = 0;
00413 VECTOR planeNormal, polysNormal, pointOnPlane, edge1, edge2, temp;
00414
00415
00416 pointOnPlane.x = planePolygon.Vertex[0].x;
00417 pointOnPlane.y = planePolygon.Vertex[0].y;
00418 pointOnPlane.z = planePolygon.Vertex[0].z;
00419
00420
00421 edge1.x = planePolygon.Vertex[1].x - planePolygon.Vertex[0].x;
00422 edge1.y = planePolygon.Vertex[1].y - planePolygon.Vertex[0].y;
00423 edge1.z = planePolygon.Vertex[1].z - planePolygon.Vertex[0].z;
00424 edge2.x = planePolygon.Vertex[2].x - planePolygon.Vertex[0].x;
00425 edge2.y = planePolygon.Vertex[2].y - planePolygon.Vertex[0].y;
00426 edge2.z = planePolygon.Vertex[2].z - planePolygon.Vertex[0].z;
00427 planeNormal = CrossVector(edge1, edge2);
00428
00429
00430 edge1.x = portal->Vertex[1].x - portal->Vertex[0].x;
00431 edge1.y = portal->Vertex[1].y - portal->Vertex[0].y;
00432 edge1.z = portal->Vertex[1].z - portal->Vertex[0].z;
00433 edge2.x = portal->Vertex[2].x - portal->Vertex[0].x;
00434 edge2.y = portal->Vertex[2].y - portal->Vertex[0].y;
00435 edge2.z = portal->Vertex[2].z - portal->Vertex[0].z;
00436 polysNormal = CrossVector(edge1, edge2);
00437
00438
00439 for (int loop = 0; loop < numVerts; loop++)
00440 {
00441 temp.x = portal->Vertex[loop].x;
00442 temp.y = portal->Vertex[loop].y;
00443 temp.z = portal->Vertex[loop].z;
00444 if (ClassifyPoint(temp, pointOnPlane, planeNormal) == 0)
00445 count++;
00446 else
00447 break;
00448 }
00449 if (count == numVerts)
00450 return OnPartition;
00451
00452
00453 int result, frontcount = 0, backcount = 0;
00454 for (int loop = 0; loop < numVerts; loop++)
00455 {
00456 temp.x = portal->Vertex[loop].x;
00457 temp.y = portal->Vertex[loop].y;
00458 temp.z = portal->Vertex[loop].z;
00459 result = ClassifyPoint(temp, pointOnPlane, planeNormal);
00460 if (result == 0)
00461 {
00462 frontcount++;
00463 backcount++;
00464 }
00465 else
00466 if (result == 1)
00467 frontcount++;
00468 else
00469 if (result == -1)
00470 backcount++;
00471 }
00472 if (frontcount == numVerts)
00473 return Front;
00474 if (backcount == numVerts)
00475 return Back;
00476
00477 return 0;
00478 }
00479
00480 int ClassifyInvertedPortal(PORTAL* portal, POLYGON planePolygon)
00481 {
00482 int numVerts = portal->numVertices;
00483 int count = 0;
00484 VECTOR planeNormal, polysNormal, pointOnPlane, edge1, edge2, temp;
00485
00486
00487 pointOnPlane.x = planePolygon.Vertex[0].x;
00488 pointOnPlane.y = planePolygon.Vertex[0].y;
00489 pointOnPlane.z = planePolygon.Vertex[0].z;
00490
00491
00492 edge1.x = planePolygon.Vertex[1].x - planePolygon.Vertex[0].x;
00493 edge1.y = planePolygon.Vertex[1].y - planePolygon.Vertex[0].y;
00494 edge1.z = planePolygon.Vertex[1].z - planePolygon.Vertex[0].z;
00495 edge2.x = planePolygon.Vertex[2].x - planePolygon.Vertex[0].x;
00496 edge2.y = planePolygon.Vertex[2].y - planePolygon.Vertex[0].y;
00497 edge2.z = planePolygon.Vertex[2].z - planePolygon.Vertex[0].z;
00498 planeNormal = CrossVector(edge1, edge2);
00499
00500
00501 edge1.x = portal->Vertex[1].x - portal->Vertex[0].x;
00502 edge1.y = portal->Vertex[1].y - portal->Vertex[0].y;
00503 edge1.z = portal->Vertex[1].z - portal->Vertex[0].z;
00504 edge2.x = portal->Vertex[2].x - portal->Vertex[0].x;
00505 edge2.y = portal->Vertex[2].y - portal->Vertex[0].y;
00506 edge2.z = portal->Vertex[2].z - portal->Vertex[0].z;
00507 polysNormal = CrossVector(edge1, edge2);
00508 polysNormal.x *= -1;
00509 polysNormal.y *= -1;
00510 polysNormal.z *= -1;
00511
00512
00513 for (int loop = 0; loop < numVerts; loop++)
00514 {
00515 temp.x = portal->Vertex[loop].x;
00516 temp.y = portal->Vertex[loop].y;
00517 temp.z = portal->Vertex[loop].z;
00518 if (ClassifyPoint(temp, pointOnPlane, planeNormal) == 0)
00519 count++;
00520 else
00521 break;
00522 }
00523 if (count == numVerts)
00524 {
00525 if (ClassifyPoint(polysNormal, pointOnPlane, planeNormal) == 1)
00526 return Front;
00527 if (ClassifyPoint(polysNormal, pointOnPlane, planeNormal) == -1)
00528 return Back;
00529 }
00530
00531
00532 int result, frontcount = 0, backcount = 0;
00533 for (int loop = 0; loop < numVerts; loop++)
00534 {
00535 temp.x = portal->Vertex[loop].x;
00536 temp.y = portal->Vertex[loop].y;
00537 temp.z = portal->Vertex[loop].z;
00538 result = ClassifyPoint(temp, pointOnPlane, planeNormal);
00539 if (result == 0)
00540 {
00541 frontcount++;
00542 backcount++;
00543 }
00544 else
00545 if (result == 1)
00546 frontcount++;
00547 else
00548 if (result == -1)
00549 backcount++;
00550 }
00551 if (frontcount == numVerts)
00552 return Front;
00553 if (backcount == numVerts)
00554 return Back;
00555
00556 return 0;
00557 }
00558
00559 void InvertPortal(PORTAL* portal)
00560 {
00561 PORTAL* tempportal = CopyPortal(portal);
00562 int numverts = portal->numVertices;
00563 for (int loop = 0; loop < numverts; loop++)
00564 portal->Vertex[loop] = tempportal->Vertex[(numverts - 1) - loop];
00565 delete[] tempportal->Vertex;
00566 tempportal->Vertex = 0;
00567 delete tempportal;
00568 return;
00569 }
00570
00571 void InvertPortals(BSP_node* node)
00572 {
00573 VECTOR planeNormal, polysNormal, pointOnPlane, edge1, edge2, temp;
00574 int flag;
00575 for (int loop = 1; loop <= node->numportals; loop++)
00576 {
00577 PORTAL* tempportal = node->portallist.Get(loop);
00578
00579 pointOnPlane.x = tempportal->Vertex[0].x;
00580 pointOnPlane.y = tempportal->Vertex[0].y;
00581 pointOnPlane.z = tempportal->Vertex[0].z;
00582
00583
00584 edge1.x = tempportal->Vertex[1].x - tempportal->Vertex[0].x;
00585 edge1.y = tempportal->Vertex[1].y - tempportal->Vertex[0].y;
00586 edge1.z = tempportal->Vertex[1].z - tempportal->Vertex[0].z;
00587 edge2.x = tempportal->Vertex[2].x - tempportal->Vertex[0].x;
00588 edge2.y = tempportal->Vertex[2].y - tempportal->Vertex[0].y;
00589 edge2.z = tempportal->Vertex[2].z - tempportal->Vertex[0].z;
00590 planeNormal = CrossVector(edge1, edge2);
00591
00592 flag = 0;
00593 for (int polygon = 0; polygon < node->numpolys; polygon++)
00594 {
00595 for (int vert = 0; vert < 3; vert++)
00596 {
00597 temp.x = node->nodepolylist[polygon].Vertex[vert].x;
00598 temp.y = node->nodepolylist[polygon].Vertex[vert].y;
00599 temp.z = node->nodepolylist[polygon].Vertex[vert].z;
00600
00601 flag = ClassifyPoint(temp, pointOnPlane, planeNormal);
00602 if (flag == -1)
00603 {
00604 InvertPortal(tempportal);
00605 }
00606 if (flag == 1 || flag == -1)
00607 {
00608 if (tempportal->frontleaf->nodeid != node->nodeid)
00609 {
00610 BSP_node* tempnode = tempportal->backleaf;
00611 tempportal->backleaf = tempportal->frontleaf;
00612 tempportal->frontleaf = tempnode;
00613 }
00614 break;
00615 }
00616 }
00617 if (flag == 1 || flag == -1)
00618 break;
00619 }
00620 }
00621 }
00622
00623 void AddPortal(PORTAL* thisportal, BSP_node* node)
00624 {
00625 if (node->leaf == true)
00626 {
00627 node->numportals++;
00628 thisportal->linkPosition = node->numportals;
00629 node->portallist.Insert(thisportal);
00630 return;
00631 }
00632
00633 int side = ClassifyPortal(thisportal, node->partition);
00634 if (side == Front)
00635 {
00636 AddPortal(thisportal, node->frontnode);
00637 }
00638 if (side == Back)
00639 {
00640 AddPortal(thisportal, node->backnode);
00641 }
00642 if (side == OnPartition)
00643 {
00644 AddPortal(thisportal, node->frontnode);
00645 PORTAL* tempportal = CopyPortal(thisportal);
00646 AddPortal(tempportal, node->backnode);
00647 }
00648 return;
00649 }
00650
00651 void AddPortalsToLeaves(BSP_node* root)
00652 {
00653 for (int loop = 1; loop <= numportals; loop++)
00654 {
00655 PORTAL* tempportal = CopyPortal(PortalList.Get(loop));
00656 AddPortal(tempportal, root);
00657 }
00658 }
00659
00660 int ClipPortalToFrontLeaf(PORTAL* portal)
00661 {
00662 int result, returnvalue = 0;
00663 for (int polygon = 0; polygon < portal->frontleaf->numpolys; polygon++)
00664 {
00665 PORTAL* front = new PORTAL;
00666 PORTAL* back = new PORTAL;
00667 result = SplitPortal(portal, portal->frontleaf->nodepolylist[polygon], front, back);
00668
00669 if (result == PortalWasSplit)
00670 {
00671 returnvalue = PortalWasSplit;
00672 delete[] back->Vertex;
00673 back->Vertex = 0;
00674 delete back;
00675 delete[] portal->Vertex;
00676 portal->Vertex = 0;
00677 portal->numVertices = front->numVertices;
00678 portal->Vertex = front->Vertex;
00679 delete front;
00680 }
00681
00682 else
00683 {
00684 delete back;
00685 delete front;
00686 }
00687 }
00688 return returnvalue;
00689 }
00690
00691 int ClipPortalToBackLeaf(PORTAL* portal)
00692 {
00693 int result, returnvalue = 0;
00694 for (int polygon = 0; polygon < portal->backleaf->numpolys; polygon++)
00695 {
00696 PORTAL* front = new PORTAL;
00697 PORTAL* back = new PORTAL;
00698 result = SplitPortal(portal, portal->backleaf->nodepolylist[polygon], front, back);
00699
00700 if (result == PortalWasSplit)
00701 {
00702 returnvalue = PortalWasSplit;
00703 delete[] back->Vertex;
00704 back->Vertex = 0;
00705 delete back;
00706 delete[] portal->Vertex;
00707 portal->Vertex = 0;
00708 portal->numVertices = front->numVertices;
00709 portal->Vertex = front->Vertex;
00710 delete front;
00711 }
00712 else
00713 {
00714 delete back;
00715 delete front;
00716 }
00717 }
00718 return returnvalue;
00719 }
00720
00721 void CheckForSinglePortals(BSP_node* node, BSP_node* originalnode, PORTAL* portal, int* flag)
00722 {
00723 PORTAL* tempportal;
00724 if (node->leaf == true)
00725 {
00726 if (node->nodeid != originalnode->nodeid)
00727 {
00728 for (int portalnum = node->numportals; portalnum > 0; portalnum--)
00729 {
00730 tempportal = node->portallist.Get(portalnum);
00731 if (tempportal->PortalId == portal->PortalId)
00732 {
00733 portal->frontleaf = originalnode;
00734 portal->backleaf = node;
00735 *flag += 1;
00736 }
00737 }
00738 }
00739 return;
00740 }
00741 else
00742 {
00743 CheckForSinglePortals(node->frontnode, originalnode, portal, flag);
00744 CheckForSinglePortals(node->backnode, originalnode, portal, flag);
00745 return;
00746 }
00747 }
00748
00749 int RemoveExtraPortals(PORTAL* portal)
00750 {
00751 int result, count = 0;
00752 POLYGON temppoly;
00753 BSP_node* tempnode = portal->backleaf;
00754 for (int loop = 0; loop < tempnode->numpolys; loop++)
00755 {
00756 temppoly = tempnode->nodepolylist[loop];
00757 result = ClassifyInvertedPortal(portal, temppoly);
00758 if (result == Front)
00759 count++;
00760 }
00761 if (count != portal->backleaf->numpolys)
00762 return true;
00763 else
00764 return false;
00765 }
00766
00767 void FindTruePortals(BSP_node* node)
00768 {
00769 int flag;
00770 if (node->leaf == true)
00771 {
00772 for (int portalnumber = node->numportals; portalnumber > 0; portalnumber--)
00773 {
00774 flag = 0;
00775 PORTAL* tempportal = node->portallist.Get(portalnumber);
00776 CheckForSinglePortals(root, node, tempportal, &flag);
00777 if (flag == 0)
00778 {
00779 delete[] tempportal->Vertex;
00780 tempportal->Vertex = 0;
00781 node->portallist.Delete(portalnumber);
00782 delete tempportal;
00783 node->numportals--;
00784 }
00785 else
00786 {
00787 ClipPortalToFrontLeaf(tempportal);
00788 ClipPortalToBackLeaf(tempportal);
00789 }
00790 }
00791
00792 InvertPortals(node);
00793
00794 for (int portalnumber = node->numportals; portalnumber > 0; portalnumber--)
00795 {
00796 PORTAL* tempportal = node->portallist.Get(portalnumber);
00797 flag = RemoveExtraPortals(tempportal);
00798 if (flag == true)
00799 {
00800 delete[] tempportal->Vertex;
00801 tempportal->Vertex = 0;
00802 node->portallist.Delete(portalnumber);
00803 delete tempportal;
00804 node->numportals--;
00805 }
00806 }
00807 return;
00808 }
00809 else
00810 {
00811 FindTruePortals(node->frontnode);
00812 FindTruePortals(node->backnode);
00813 return;
00814 }
00815 }
00816