Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

pvs.cpp

Go to the documentation of this file.
00001 // PVS routines      by Alan Baylis 2002
00002 
00003 int CountVisibleLeaves()
00004 {
00005     int counter = 0;
00006     ListNode* tempnode;
00007     for (int loop = 1; loop <= numleaves; loop++)
00008     {
00009         tempnode = LeafList.Get(loop);
00010         if (tempnode->node->visible)
00011         {
00012             counter++;
00013         }
00014     }
00015     return counter;
00016 }
00017 
00018 void FindVisibleLeaves(int Parent, PORTAL* CurrentPortal, ListNode* ParentNode, int portalnumber)
00019 {
00020     int loop, numPlanes, leafnumber, Nminus1, counter, flag, result, parentid, planenumber;
00021     VECTOR edge1, edge2, pointOnPlane, planesNormal;
00022     ListNode* CurrentNode;
00023     PORTAL* front = new PORTAL;
00024     PORTAL* back = new PORTAL;
00025     PORTAL* inputPortal;
00026 
00027     inputPortal = ParentNode->node->portallist.Get(portalnumber);
00028     parentid = inputPortal->backleaf->nodeid;
00029     CurrentNode = LeafList.Get(parentid);
00030     CurrentNode->node->visible = true;
00031 
00032     // Create the planes from CurrentPortal
00033     pointOnPlane = camera[currentCamera].Position;
00034 
00035     numPlanes = CurrentPortal->numVertices;
00036     PLANE* Planes = new PLANE[numPlanes];
00037     for (loop = 0; loop < numPlanes; loop++)
00038     {
00039         if (loop == 0)
00040             Nminus1 = numPlanes - 1;
00041         else
00042             Nminus1 = loop - 1;
00043         // get the normal from edges
00044         edge1.x = CurrentPortal->Vertex[loop].x - camera[currentCamera].Position.x;
00045         edge1.y = CurrentPortal->Vertex[loop].y - camera[currentCamera].Position.y;
00046         edge1.z = CurrentPortal->Vertex[loop].z - camera[currentCamera].Position.z;
00047         edge2.x = CurrentPortal->Vertex[Nminus1].x - camera[currentCamera].Position.x;
00048         edge2.y = CurrentPortal->Vertex[Nminus1].y - camera[currentCamera].Position.y;
00049         edge2.z = CurrentPortal->Vertex[Nminus1].z - camera[currentCamera].Position.z;
00050         planesNormal = CrossVector(edge1, edge2);
00051         Planes[loop].nx = planesNormal.x;
00052         Planes[loop].ny = planesNormal.y;
00053         Planes[loop].nz = planesNormal.z;
00054     }
00055 
00056     // loop through the portals of this leafnode
00057     for (portalnumber = 1; portalnumber <= CurrentNode->node->numportals; portalnumber++)
00058     {
00059         counter = 0;
00060         CurrentPortal = CurrentNode->node->portallist.Get(portalnumber);
00061         flag = 1;
00062         // if the backleaf isn't the parent
00063         if (CurrentPortal->backleaf->nodeid != Parent)
00064         {
00065             // loop through the planes
00066             for (planenumber = 0; planenumber < numPlanes; planenumber++)
00067             {
00068                 result = SplitPortal(CurrentPortal, Planes[planenumber], pointOnPlane, front, back);
00069                 if (result == PortalWasSplit)
00070                 {
00071                     delete[] back->Vertex;
00072                     if (flag == 0)   // if there has been a previous split polygon
00073                     {
00074                         delete[] CurrentPortal->Vertex;
00075                         delete CurrentPortal;
00076                     }
00077                     flag = 0;
00078                     CurrentPortal = front;
00079                     front = new PORTAL;
00080                 }
00081                 if (result != Back)
00082                     counter++;
00083             }
00084             // if the portal was split by or infront of all the planes
00085             if (counter == numPlanes)
00086             {
00087                 FindVisibleLeaves(parentid, CurrentPortal, CurrentNode, portalnumber);
00088             }
00089             if (flag == 0)   // if there has been at least one split polygon
00090             {
00091                 delete[] CurrentPortal->Vertex;
00092                 delete CurrentPortal;
00093             }
00094         }
00095     }
00096     delete[] Planes;
00097     delete front;
00098     delete back;
00099 }
00100 
00101 void CalculatePVS(int currentleaf)
00102 {
00103     int flag, result, counter, parentid, portalnumber, planenumber;
00104     VECTOR pointOnPlane;
00105     VECTOR ZUnit = camera[currentCamera].GetZUnit();    // camera's direction vector
00106     ListNode* CurrentNode;
00107     PORTAL* CurrentPortal;
00108     PORTAL* front = new PORTAL;
00109     PORTAL* back = new PORTAL;
00110 
00111     parentid = currentleaf;
00112     CurrentNode = LeafList.Get(currentleaf);
00113     CurrentNode->node->visible = true;
00114     // loop through the portals of the current leafnode
00115     for (portalnumber = 1; portalnumber <= CurrentNode->node->numportals; portalnumber++)
00116     {
00117         counter = 0;
00118         CurrentPortal = CurrentNode->node->portallist.Get(portalnumber);
00119         flag = 1;
00120         // loop through the frustum planes
00121         for (planenumber = 0; planenumber < 6; planenumber++)
00122         {
00123             // find a point on the far plane by projecting the camera's direction vector
00124             if (planenumber == 4)
00125             {
00126                 pointOnPlane.x = camera[currentCamera].Position.x;
00127                 pointOnPlane.x -= ZUnit.x * 500.0;
00128                 pointOnPlane.y = camera[currentCamera].Position.y;
00129                 pointOnPlane.y -= ZUnit.y * 500.0;
00130                 pointOnPlane.z = camera[currentCamera].Position.z;
00131                 pointOnPlane.z -= ZUnit.z * 500.0;
00132             }
00133             else if (planenumber == 5) // skip the near frustum plane test
00134                 continue;
00135             else
00136                 // the camera position is a point on the frustum planes
00137                 pointOnPlane = camera[currentCamera].Position;
00138 
00139             result = SplitPortal(CurrentPortal, frustum[planenumber], pointOnPlane, front, back);
00140             if (result == PortalWasSplit)
00141             {
00142                 delete[] back->Vertex;
00143                 if (flag == 0)   // if there has been a previous split portal
00144                 {
00145                     delete[] CurrentPortal->Vertex;
00146                     delete CurrentPortal;
00147                 }
00148                 flag = 0;
00149                 CurrentPortal = front;
00150                 front = new PORTAL;
00151             }
00152             if (result != Back)
00153                 counter++;
00154         }
00155         // if the portal was split by or infront of the planes
00156         if (counter == 5)
00157         {
00158             FindVisibleLeaves(parentid, CurrentPortal, CurrentNode, portalnumber);
00159         }
00160         if (flag == 0)  // if there has been at least one split portal
00161         {
00162             delete[] CurrentPortal->Vertex;
00163             delete CurrentPortal;
00164         }
00165     }
00166     delete front;
00167     delete back;
00168 }

Generated on Fri Dec 23 05:20:18 2005 for Portals by doxygen1.2.15