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

Generated on Fri Dec 23 05:19:55 2005 for Particles by doxygen1.2.15