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];
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];
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;
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
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
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
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
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:
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:
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:
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];
00314 lightmap[iX + iY * Height * 4 + 1] = (char)lumelcolor[iX / 4][iY][1];
00315 lightmap[iX + iY * Height * 4 + 2] = (char)lumelcolor[iX / 4][iY][2];
00316 lightmap[iX + iY * Height * 4 + 3] = 255;
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_CLAMP, GL_CLAMP, 1);
00349
00350 }
00351 return;
00352 }
00353 LoadBSPLightmaps(node->frontnode);
00354 LoadBSPLightmaps(node->backnode);
00355 }
00356