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

lightmap.cpp

Go to the documentation of this file.
00001 #include <windows.h>
00002 #include "lightmap.h"
00003 #include "collision.h"
00004 #include "bsp.h"
00005 #include "texture.h"
00006 #include "tga.h"
00007 #include "mmgr.h"
00008 
00009 extern int numStaticLights;
00010 extern char AppDirectory[MAX_PATH];
00011 extern int numLightmaps;
00012 extern StaticLight* staticlight;
00013 
00014 void SetStaticLights(StaticLight* staticlight)
00015 {
00016     staticlight[0].Position.x = -4.0;
00017     staticlight[0].Position.y = 9.0;
00018     staticlight[0].Position.z = -50.0;
00019     staticlight[0].Radius = 300.0;
00020     staticlight[0].Brightness = 5.0;
00021     staticlight[0].Red = 255.0;
00022     staticlight[0].Green = 255.0;
00023     staticlight[0].Blue = 255.0;
00024 
00025     staticlight[1].Position.x = -28.0;
00026     staticlight[1].Position.y = 9.0;
00027     staticlight[1].Position.z = -50.0;
00028     staticlight[1].Radius = 300.0;
00029     staticlight[1].Brightness = 5.0;
00030     staticlight[1].Red = 255.0;
00031     staticlight[1].Green = 255.0;
00032     staticlight[1].Blue = 255.0;
00033 
00034     staticlight[2].Position.x = -52.0;
00035     staticlight[2].Position.y = 9.0;
00036     staticlight[2].Position.z = -50.0;
00037     staticlight[2].Radius = 300.0;
00038     staticlight[2].Brightness = 5.0;
00039     staticlight[2].Red = 255.0;
00040     staticlight[2].Green = 255.0;
00041     staticlight[2].Blue = 255.0;
00042 
00043     staticlight[3].Position.x = -4.0;
00044     staticlight[3].Position.y = 9.0;
00045     staticlight[3].Position.z = 50.0;
00046     staticlight[3].Radius = 300.0;
00047     staticlight[3].Brightness = 5.0;
00048     staticlight[3].Red = 255.0;
00049     staticlight[3].Green = 255.0;
00050     staticlight[3].Blue = 255.0;
00051 
00052     staticlight[4].Position.x = -28.0;
00053     staticlight[4].Position.y = 9.0;
00054     staticlight[4].Position.z = 50.0;
00055     staticlight[4].Radius = 300.0;
00056     staticlight[4].Brightness = 5.0;
00057     staticlight[4].Red = 255.0;
00058     staticlight[4].Green = 255.0;
00059     staticlight[4].Blue = 255.0;
00060 
00061     staticlight[5].Position.x = -52.0;
00062     staticlight[5].Position.y = 9.0;
00063     staticlight[5].Position.z = 50.0;
00064     staticlight[5].Radius = 300.0;
00065     staticlight[5].Brightness = 5.0;
00066     staticlight[5].Red = 255.0;
00067     staticlight[5].Green = 255.0;
00068     staticlight[5].Blue = 255.0;
00069 
00070     staticlight[6].Position.x = 110.0;
00071     staticlight[6].Position.y = 5.0;
00072     staticlight[6].Position.z = 120.0;
00073     staticlight[6].Radius = 100.0;
00074     staticlight[6].Brightness = 30.0;
00075     staticlight[6].Red = 255.0;
00076     staticlight[6].Green = 255.0;
00077     staticlight[6].Blue = 255.0;
00078 
00079     staticlight[7].Position.x = 140.0;
00080     staticlight[7].Position.y = 0.0;
00081     staticlight[7].Position.z = -20.0;
00082     staticlight[7].Radius = 100.0;
00083     staticlight[7].Brightness = 10.0;
00084     staticlight[7].Red = 0.0;
00085     staticlight[7].Green = 255.0;
00086     staticlight[7].Blue = 255.0;
00087 
00088     staticlight[8].Position.x = 0.0;
00089     staticlight[8].Position.y = 25.0;
00090     staticlight[8].Position.z = 0.0;
00091     staticlight[8].Radius = 45.0;
00092     staticlight[8].Brightness = 12.0;
00093     staticlight[8].Red = 250.0;
00094     staticlight[8].Green = 170.0;
00095     staticlight[8].Blue = 50.0;
00096 }
00097 
00098 void CreateLightmaps(int numpolys, POLYGON* polylist, Lightmap* lightmaplist)
00099 {
00100     const int Width = 16;
00101     const int Height = 16;
00102     VECTOR lumels[Width][Height];               // world coordinates of lumels
00103     VECTOR edge1, edge2;
00104     VECTOR newedge1, newedge2;
00105     VECTOR Vect1, Vect2;
00106     VECTOR UVVector;
00107     VECTOR poly_normal;
00108     VECTOR lightvector;
00109     VECTOR pointonplane;
00110     float lumelcolor[Width][Height][3];  // array to hold lumel rgb values
00111     float lightdistance;
00112     float uvMin_U;
00113     float uvMin_V;
00114     float uvMax_U;
00115     float uvMax_V;
00116     float cosAngle;
00117     float X, Y, Z;
00118     float Distance;
00119     float uvDelta_U;
00120     float uvDelta_V;
00121     float ufactor;
00122     float vfactor;
00123     float combinedred;
00124     float combinedgreen;
00125     float combinedblue;
00126     float intensity;
00127     int flag; // set to 1, 2 or 3 depending on whether normal's X, Y or Z component is largest
00128     char temp[256];
00129     unsigned char* lightmap = new unsigned char[Width * Height * 4];
00130         
00131     for (int loop = 0; loop < numpolys; loop++)
00132     {
00133         // get uv's in 3D worldspace
00134         poly_normal = polylist[loop].GetNormal();
00135         poly_normal.Normalize();
00136         pointonplane.x = polylist[loop].Vertex[0].x;
00137         pointonplane.y = polylist[loop].Vertex[0].y;
00138         pointonplane.z = polylist[loop].Vertex[0].z;
00139 
00140         // find plane to map onto
00141         if (fabs(poly_normal.x) > fabs(poly_normal.y) && fabs(poly_normal.x) > fabs(poly_normal.z))
00142         {
00143             flag = 1;
00144             lightmaplist[loop].vertex_u[0] = polylist[loop].Vertex[0].y;
00145             lightmaplist[loop].vertex_v[0] = polylist[loop].Vertex[0].z;
00146             lightmaplist[loop].vertex_u[1] = polylist[loop].Vertex[1].y;
00147             lightmaplist[loop].vertex_v[1] = polylist[loop].Vertex[1].z;
00148             lightmaplist[loop].vertex_u[2] = polylist[loop].Vertex[2].y;
00149             lightmaplist[loop].vertex_v[2] = polylist[loop].Vertex[2].z;
00150         }
00151         else if (fabs(poly_normal.y) > fabs(poly_normal.x) && fabs(poly_normal.y) > fabs(poly_normal.z))
00152         {
00153             flag = 2;
00154             lightmaplist[loop].vertex_u[0] = polylist[loop].Vertex[0].x;
00155             lightmaplist[loop].vertex_v[0] = polylist[loop].Vertex[0].z;
00156             lightmaplist[loop].vertex_u[1] = polylist[loop].Vertex[1].x;
00157             lightmaplist[loop].vertex_v[1] = polylist[loop].Vertex[1].z;
00158             lightmaplist[loop].vertex_u[2] = polylist[loop].Vertex[2].x;
00159             lightmaplist[loop].vertex_v[2] = polylist[loop].Vertex[2].z;
00160         }
00161         else
00162         {
00163             flag = 3;
00164             lightmaplist[loop].vertex_u[0] = polylist[loop].Vertex[0].x;
00165             lightmaplist[loop].vertex_v[0] = polylist[loop].Vertex[0].y;
00166             lightmaplist[loop].vertex_u[1] = polylist[loop].Vertex[1].x;
00167             lightmaplist[loop].vertex_v[1] = polylist[loop].Vertex[1].y;
00168             lightmaplist[loop].vertex_u[2] = polylist[loop].Vertex[2].x;
00169             lightmaplist[loop].vertex_v[2] = polylist[loop].Vertex[2].y;
00170         }
00171 
00172         // convert to 2D texture space
00173         uvMin_U = lightmaplist[loop].vertex_u[0];
00174         uvMin_V = lightmaplist[loop].vertex_v[0];
00175         uvMax_U = lightmaplist[loop].vertex_u[0];
00176         uvMax_V = lightmaplist[loop].vertex_v[0];
00177 
00178         for (int i = 0; i < 3; i++)
00179         {
00180             if (lightmaplist[loop].vertex_u[i] < uvMin_U )
00181                 uvMin_U = lightmaplist[loop].vertex_u[i];
00182             if (lightmaplist[loop].vertex_v[i] < uvMin_V )
00183                 uvMin_V = lightmaplist[loop].vertex_v[i];
00184             if (lightmaplist[loop].vertex_u[i] > uvMax_U )
00185                 uvMax_U = lightmaplist[loop].vertex_u[i];
00186             if (lightmaplist[loop].vertex_v[i] > uvMax_V )
00187                 uvMax_V = lightmaplist[loop].vertex_v[i];
00188         }
00189 
00190         uvDelta_U = uvMax_U - uvMin_U;
00191         uvDelta_V = uvMax_V - uvMin_V;
00192 
00193         for (int i = 0; i < 3; i++)
00194         {
00195             lightmaplist[loop].vertex_u[i] -= uvMin_U;
00196             lightmaplist[loop].vertex_v[i] -= uvMin_V;
00197             lightmaplist[loop].vertex_u[i] /= uvDelta_U;
00198             lightmaplist[loop].vertex_v[i] /= uvDelta_V;
00199         }
00200 
00201         // calculate the world space position for each lumel
00202         Distance = - (poly_normal.x * pointonplane.x + poly_normal.y * pointonplane.y + poly_normal.z * pointonplane.z);
00203 
00204         switch (flag)
00205         {
00206             case 1: //YZ Plane
00207                 X = - ( poly_normal.y * uvMin_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.x;
00208                 UVVector.x = X;
00209                 UVVector.y = uvMin_U;
00210                 UVVector.z = uvMin_V;
00211                 X = - ( poly_normal.y * uvMax_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.x;
00212                 Vect1.x = X;
00213                 Vect1.y = uvMax_U;
00214                 Vect1.z = uvMin_V;
00215                 X = - ( poly_normal.y * uvMin_U + poly_normal.z * uvMax_V + Distance ) / poly_normal.x;
00216                 Vect2.x = X;
00217                 Vect2.y = uvMin_U;
00218                 Vect2.z = uvMax_V;
00219             break;
00220 
00221             case 2: //XZ Plane
00222                 Y = - ( poly_normal.x * uvMin_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.y;
00223                 UVVector.x = uvMin_U;
00224                 UVVector.y = Y;
00225                 UVVector.z = uvMin_V;
00226                 Y = - ( poly_normal.x * uvMax_U + poly_normal.z * uvMin_V + Distance ) / poly_normal.y;
00227                 Vect1.x = uvMax_U;
00228                 Vect1.y = Y;
00229                 Vect1.z = uvMin_V;
00230                 Y = - ( poly_normal.x * uvMin_U + poly_normal.z * uvMax_V + Distance ) / poly_normal.y;
00231                 Vect2.x = uvMin_U;
00232                 Vect2.y = Y;
00233                 Vect2.z = uvMax_V;
00234             break;
00235 
00236             case 3: //XY Plane
00237                 Z = - ( poly_normal.x * uvMin_U + poly_normal.y * uvMin_V + Distance ) / poly_normal.z;
00238                 UVVector.x = uvMin_U;
00239                 UVVector.y = uvMin_V;
00240                 UVVector.z = Z;
00241                 Z = - ( poly_normal.x * uvMax_U + poly_normal.y * uvMin_V + Distance ) / poly_normal.z;
00242                 Vect1.x = uvMax_U;
00243                 Vect1.y = uvMin_V;
00244                 Vect1.z = Z;
00245                 Z = - ( poly_normal.x * uvMin_U + poly_normal.y * uvMax_V + Distance ) / poly_normal.z;
00246                 Vect2.x = uvMin_U;
00247                 Vect2.y = uvMax_V;
00248                 Vect2.z = Z;
00249             break;
00250         }
00251 
00252         edge1.x = Vect1.x - UVVector.x;
00253         edge1.y = Vect1.y - UVVector.y;
00254         edge1.z = Vect1.z - UVVector.z;
00255         edge2.x = Vect2.x - UVVector.x;
00256         edge2.y = Vect2.y - UVVector.y;
00257         edge2.z = Vect2.z - UVVector.z;
00258         for(int iX = 0; iX < Width; iX++)
00259         {
00260             for(int iY = 0; iY < Height; iY++)
00261             {
00262                 ufactor = (iX / (float)Width);
00263                 vfactor = (iY / (float)Height);
00264                 newedge1.x = edge1.x * ufactor;
00265                 newedge1.y = edge1.y * ufactor;
00266                 newedge1.z = edge1.z * ufactor;
00267                 newedge2.x = edge2.x * vfactor;
00268                 newedge2.y = edge2.y * vfactor;
00269                 newedge2.z = edge2.z * vfactor;
00270 
00271                 lumels[iX][iY].x = UVVector.x + newedge2.x + newedge1.x;
00272                 lumels[iX][iY].y = UVVector.y + newedge2.y + newedge1.y;
00273                 lumels[iX][iY].z = UVVector.z + newedge2.z + newedge1.z;
00274 
00275                 combinedred = 0.0;
00276                 combinedgreen = 0.0;
00277                 combinedblue = 0.0;
00278                 for (int i = 0; i < numStaticLights; i++)
00279                 {
00280                     if (ClassifyPoint(staticlight[i].Position, pointonplane, poly_normal) == 1)
00281                     {
00282                         lightvector.x = staticlight[i].Position.x - lumels[iX][iY].x;
00283                         lightvector.y = staticlight[i].Position.y - lumels[iX][iY].y;
00284                         lightvector.z = staticlight[i].Position.z - lumels[iX][iY].z;
00285                         lightdistance = lightvector.GetMagnitude();
00286                         lightvector.Normalize();
00287                         cosAngle = DotProduct(poly_normal, lightvector);
00288                         if (lightdistance < staticlight[i].Radius)
00289                         {
00290                             intensity = (staticlight[i].Brightness * cosAngle) / lightdistance;
00291                             combinedred += staticlight[i].Red * intensity;
00292                             combinedgreen += staticlight[i].Green * intensity;
00293                             combinedblue += staticlight[i].Blue * intensity;
00294                         }
00295                     }
00296                 }
00297                 if (combinedred > 255.0)
00298                     combinedred = 255.0;
00299                 if (combinedgreen > 255.0)
00300                     combinedgreen = 255.0;
00301                 if (combinedblue > 255.0)
00302                     combinedblue = 255.0;
00303                 lumelcolor[iX][iY][0] = combinedred;
00304                 lumelcolor[iX][iY][1] = combinedgreen;
00305                 lumelcolor[iX][iY][2] = combinedblue;
00306             }
00307         }
00308 
00309         for(int iX = 0; iX < (Width * 4); iX += 4)
00310         {
00311             for(int iY = 0; iY < Height; iY += 1)
00312             {
00313                 lightmap[iX + iY * Height * 4] = (char)lumelcolor[iX / 4][iY][0];         // Red
00314                 lightmap[iX + iY * Height * 4 + 1] = (char)lumelcolor[iX / 4][iY][1];     // Green
00315                 lightmap[iX + iY * Height * 4 + 2] = (char)lumelcolor[iX / 4][iY][2];     // Blue
00316                 lightmap[iX + iY * Height * 4 + 3] = 255;                                 // Alpha
00317             }
00318         }
00319 
00320         sprintf(lightmaplist[loop].Texture.TexName, "%s", AppDirectory);
00321         strcat(lightmaplist[loop].Texture.TexName, "\\images\\lm");
00322         strcat(lightmaplist[loop].Texture.TexName, itoa(numLightmaps++, temp, 10));
00323         strcat(lightmaplist[loop].Texture.TexName, ".tga");
00324         tgaSave(lightmaplist[loop].Texture.TexName, Width, Height, 32, lightmap);
00325     }
00326     delete[] lightmap;
00327     return;
00328 }
00329 
00330 void CreateBSPLightmaps(BSP_node* node)
00331 {
00332     if (node->leaf)
00333     {
00334         node->nodelightmaplist = new Lightmap[node->numpolys];
00335         CreateLightmaps(node->numpolys, node->nodepolylist, node->nodelightmaplist);
00336         return;
00337     }
00338     CreateBSPLightmaps(node->frontnode);
00339     CreateBSPLightmaps(node->backnode);
00340 }
00341 
00342 void LoadBSPLightmaps(BSP_node* node)
00343 {
00344     if (node->leaf)
00345     {
00346     for (int i = 0; i < node->numpolys; i++)
00347     {
00348         node->nodelightmaplist[i].Texture.LoadTGA(GL_LINEAR, GL_NEAREST_MIPMAP_LINEAR/*GL_NEAREST, GL_NEAREST*/, GL_CLAMP, GL_CLAMP, 1);
00349                 
00350     }
00351     return;
00352     }
00353     LoadBSPLightmaps(node->frontnode);
00354     LoadBSPLightmaps(node->backnode);
00355 }
00356 

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