00001
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
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
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
00075 for (portalnumber = 1; portalnumber <= CurrentNode->node->numportals; portalnumber++)
00076 {
00077 counter = 0;
00078 CurrentPortal = CurrentNode->node->portallist.Get(portalnumber);
00079 flag = 1;
00080
00081 if (CurrentPortal->backleaf->nodeid != Parent)
00082 {
00083
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)
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
00103 if (counter == numPlanes)
00104 {
00105 FindVisibleLeaves(parentid, CurrentPortal, CurrentNode, portalnumber);
00106 }
00107 if (flag == 0)
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();
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
00133 for (portalnumber = 1; portalnumber <= CurrentNode->node->numportals; portalnumber++)
00134 {
00135 counter = 0;
00136 CurrentPortal = CurrentNode->node->portallist.Get(portalnumber);
00137 flag = 1;
00138
00139 for (planenumber = 0; planenumber < 6; planenumber++)
00140 {
00141
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)
00152 continue;
00153 else
00154
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)
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
00174 if (counter == 5)
00175 {
00176 FindVisibleLeaves(parentid, CurrentPortal, CurrentNode, portalnumber);
00177 }
00178 if (flag == 0)
00179 {
00180 delete[] CurrentPortal->Vertex;
00181 delete CurrentPortal;
00182 }
00183 }
00184 delete front;
00185 delete back;
00186 }