00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Assert.h>
00023 #include <Windows.h>
00024 #include <Math.h>
00025
00026
00027 #include "BaseType.h"
00028 #include "System.h"
00029 #include "World.h"
00030 #include "Ram.h"
00031 #include "Surface.h"
00032 #include "WBitmap.h"
00033 #include "Vec3d.h"
00034 #include "Vis.h"
00035
00036 #include "Light.h"
00037
00038
00039
00040
00041 static geEngine *CEngine;
00042 static geWorld *CWorld;
00043 static GBSP_BSPData *BSPData;
00044
00045
00046
00047
00048
00049 static geBoolean GetTexVerts(World_BSP *BSP);
00050 static geBoolean GetSurfInfo(World_BSP *BSP);
00051 static geBoolean GetRGBVerts(World_BSP *BSP);
00052
00053
00054
00055
00056
00057 geBoolean Surf_EngineInit(geEngine *Engine)
00058 {
00059 return GE_TRUE;
00060 }
00061
00062
00063
00064
00065 void Surf_EngineShutdown(geEngine *Engine)
00066 {
00067 CEngine = NULL;
00068 CWorld = NULL;
00069 BSPData = NULL;
00070 }
00071
00072
00073
00074
00075
00076 geBoolean Surf_SetEngine(geEngine *Engine)
00077 {
00078 assert (Engine != NULL);
00079
00080 CEngine = Engine;
00081
00082 return GE_TRUE;
00083 }
00084
00085
00086
00087
00088
00089 geBoolean Surf_SetWorld(geWorld *World)
00090 {
00091 assert(World != NULL);
00092
00093 CWorld = World;
00094
00095 return GE_TRUE;
00096 }
00097
00098
00099
00100
00101 geBoolean Surf_SetGBSP(World_BSP *BSP)
00102 {
00103 assert(BSP != NULL);
00104
00105
00106 BSPData = &BSP->BSPData;
00107
00108 return GE_TRUE;
00109 }
00110
00111 void CalcSurfVectors (World_BSP *BSP);
00112
00113
00114
00115
00116 geBoolean Surf_WorldInit(geWorld *World)
00117 {
00118 World_BSP *BSP;
00119
00120 assert(World != NULL);
00121
00122 BSP = World->CurrentBSP;
00123
00124 assert(BSP != NULL);
00125
00126
00127 if (BSP->TexVerts)
00128 geRam_Free(BSP->TexVerts);
00129
00130 if (BSP->SurfInfo)
00131 geRam_Free(BSP->SurfInfo);
00132
00133
00134 BSP->TexVerts = GE_RAM_ALLOCATE_ARRAY(Surf_TexVert, BSP->BSPData.NumGFXVertIndexList);
00135 BSP->SurfInfo = GE_RAM_ALLOCATE_ARRAY(Surf_SurfInfo, BSP->BSPData.NumGFXFaces);
00136
00137
00138 if (!GetTexVerts(BSP))
00139 return GE_FALSE;
00140
00141 if (!GetSurfInfo(BSP))
00142 return GE_FALSE;
00143
00144 Light_SetWorld(World);
00145 Light_SetGBSP(BSP);
00146
00147 if (!GetRGBVerts(BSP))
00148 return GE_FALSE;
00149
00150 CalcSurfVectors (BSP);
00151
00152 return GE_TRUE;
00153 }
00154
00155
00156
00157
00158 void Surf_WorldShutdown(geWorld *World)
00159 {
00160 World_BSP *BSP;
00161
00162 assert(World != NULL);
00163
00164 BSP = World->CurrentBSP;
00165
00166 if (!BSP)
00167 return;
00168
00169 if (BSP->TexVerts)
00170 geRam_Free(BSP->TexVerts);
00171 if (BSP->SurfInfo)
00172 geRam_Free(BSP->SurfInfo);
00173
00174 BSP->TexVerts = NULL;
00175 BSP->SurfInfo = NULL;
00176 }
00177
00178
00179
00180
00181
00182 BOOL Surf_InSurfBoundingBox(Surf_SurfInfo *Surf, geVec3d *Pos, geFloat Box)
00183 {
00184 assert(Surf != NULL);
00185 assert(Pos != NULL);
00186
00187
00188
00189 if(Pos->Z+Box >= Surf->VMins.Z && Pos->Z-Box <= Surf->VMaxs.Z)
00190 {
00191 if(Pos->Y+Box >= Surf->VMins.Y && Pos->Y-Box <= Surf->VMaxs.Y)
00192 {
00193 if(Pos->X+Box >= Surf->VMins.X && Pos->X-Box <= Surf->VMaxs.X)
00194 {
00195 return TRUE;
00196 }
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 return FALSE;
00207 }
00208
00209
00210
00211
00212 static geBoolean GetTexVerts(World_BSP *BSP)
00213 {
00214 int32 i, v, vn;
00215 int32 *pIndex, TexInfo;
00216 geVec3d *pVert, *pVecU, *pVecV;
00217 geFloat U, V;
00218 Surf_TexVert *TexVerts;
00219 GFX_TexInfo *pTexInfo;
00220 GFX_Face *pFace;
00221
00222 TexVerts = BSP->TexVerts;
00223
00224 for (i=0; i< BSP->BSPData.NumGFXFaces; i++)
00225 {
00226 pFace = &BSP->BSPData.GFXFaces[i];
00227 TexInfo = BSP->BSPData.GFXFaces[i].TexInfo;
00228 pTexInfo = &BSP->BSPData.GFXTexInfo[TexInfo];
00229
00230 pVecU = &pTexInfo->Vecs[0];
00231 pVecV = &pTexInfo->Vecs[1];
00232
00233 pIndex = &BSP->BSPData.GFXVertIndexList[pFace->FirstVert];
00234 vn = pFace->FirstVert;
00235
00236 for (v= 0; v< pFace->NumVerts; v++, pIndex++, vn++)
00237 {
00238 pVert = &BSP->BSPData.GFXVerts[*pIndex];
00239
00240 U = geVec3d_DotProduct(pVert, pVecU);
00241 V = geVec3d_DotProduct(pVert, pVecV);
00242
00243 TexVerts[vn].u = U;
00244 TexVerts[vn].v = V;
00245 }
00246 }
00247
00248 return GE_TRUE;
00249 }
00250
00251
00252
00253
00254
00255 static geBoolean GetSurfInfo(World_BSP *BSP)
00256 {
00257 int32 NumLTypes;
00258 int32 i, k, v;
00259 int32 vn, Index;
00260 geFloat U, V;
00261 geFloat Mins[2], Maxs[2];
00262 geVec3d VMins, VMaxs;
00263 int32 Size[2];
00264 Surf_SurfInfo *SurfInfo;
00265 Surf_TexVert *TexVerts;
00266 GFX_Texture *pTexture;
00267 GFX_TexInfo *pTexInfo;
00268
00269 SurfInfo = BSP->SurfInfo;
00270 TexVerts = BSP->TexVerts;
00271
00272 assert(SurfInfo != NULL);
00273 assert(TexVerts != NULL);
00274
00275 geVec3d_Clear(&VMins);
00276 geVec3d_Clear(&VMaxs);
00277
00278 memset(SurfInfo, 0, sizeof(Surf_SurfInfo)*(BSP->BSPData.NumGFXFaces));
00279
00280 for (i=0; i< BSP->BSPData.NumGFXFaces; i++)
00281 {
00282 geFloat XScale, YScale;
00283
00284
00285 NumLTypes = 0;
00286 for (NumLTypes = 0; NumLTypes < 4; NumLTypes++)
00287 {
00288 if (BSP->BSPData.GFXFaces[i].LTypes[NumLTypes]==255)
00289 break;
00290
00291 if (BSP->BSPData.GFXFaces[i].LTypes[NumLTypes] != 0)
00292 SurfInfo[i].Flags |= SURFINFO_LTYPED;
00293 }
00294
00295 SurfInfo[i].NumLTypes = NumLTypes;
00296
00297 SurfInfo[i].TexInfo = BSP->BSPData.GFXFaces[i].TexInfo;
00298
00299 pTexInfo = &BSP->BSPData.GFXTexInfo[BSP->BSPData.GFXFaces[i].TexInfo];
00300 pTexture = &BSP->BSPData.GFXTextures[BSP->BSPData.GFXTexInfo[SurfInfo[i].TexInfo].Texture];
00301
00302 if (pTexInfo->Flags & TEXINFO_TRANS)
00303 SurfInfo[i].Flags |= SURFINFO_TRANS;
00304
00305
00306 k = BSP->BSPData.GFXFaces[i].TexInfo;
00307
00308 XScale = geVec3d_Length(&BSP->BSPData.GFXTexInfo[k].Vecs[0]);
00309 YScale = geVec3d_Length(&BSP->BSPData.GFXTexInfo[k].Vecs[1]);
00310
00311 SurfInfo[i].XStep = (int32)((16.0f / XScale) * (1<<10));
00312 SurfInfo[i].YStep = (int32)((16.0f / YScale) * (1<<10));
00313 SurfInfo[i].XScale = (int32)((1.0f/XScale) * (1<<10));
00314 SurfInfo[i].YScale = (int32)((1.0f/YScale) * (1<<10));
00315 }
00316
00317
00318
00319
00320 for (i=0; i< BSP->BSPData.NumGFXFaces; i++)
00321 {
00322 pTexInfo = &BSP->BSPData.GFXTexInfo[BSP->BSPData.GFXFaces[i].TexInfo];
00323 pTexture = &BSP->BSPData.GFXTextures[BSP->BSPData.GFXTexInfo[SurfInfo[i].TexInfo].Texture];
00324
00325 for (k=0; k<2; k++)
00326 {
00327 Mins[k] = 99999.0f;
00328 Maxs[k] =-99999.0f;
00329 }
00330 for (k=0; k<3; k++)
00331 {
00332 VectorToSUB(VMins, k) = 99999.0f;
00333 VectorToSUB(VMaxs, k) =-99999.0f;
00334 }
00335
00336 for (v= 0; v< BSP->BSPData.GFXFaces[i].NumVerts; v++)
00337 {
00338 vn = v + BSP->BSPData.GFXFaces[i].FirstVert;
00339 U = TexVerts[vn].u;
00340 V = TexVerts[vn].v;
00341
00342 if (U < Mins[0])
00343 Mins[0] = U;
00344 if (U > Maxs[0])
00345 Maxs[0] = U;
00346 if (V < Mins[1])
00347 Mins[1] = V;
00348 if (V > Maxs[1])
00349 Maxs[1] = V;
00350
00351 Index = BSP->BSPData.GFXVertIndexList[vn];
00352
00353 for (k=0; k<3; k++)
00354 {
00355 if (VectorToSUB(BSP->BSPData.GFXVerts[Index], k) < VectorToSUB(VMins, k))
00356 VectorToSUB(VMins, k) = VectorToSUB(BSP->BSPData.GFXVerts[Index], k);
00357 if (VectorToSUB(BSP->BSPData.GFXVerts[Index], k) > VectorToSUB(VMaxs, k))
00358 VectorToSUB(VMaxs, k) = VectorToSUB(BSP->BSPData.GFXVerts[Index], k);
00359 }
00360 }
00361
00362
00363 #if 1
00364 {
00365 int32 Width, Height;
00366 geFloat au, av, ScaleU, ScaleV;
00367
00368 #if 0
00369 pTexInfo->DrawScale[0] = 1.0f;
00370 pTexInfo->DrawScale[1] = 1.0f;
00371 #endif
00372
00373 ScaleU = 1.0f/pTexInfo->DrawScale[0];
00374 ScaleV = 1.0f/pTexInfo->DrawScale[1];
00375
00376 Width = pTexture->Width;
00377 Height = pTexture->Height;
00378
00379
00380 au = (geFloat)(((int32)((Mins[0]*ScaleU+pTexInfo->Shift[0])/Width ))*Width);
00381 av = (geFloat)(((int32)((Mins[1]*ScaleV+pTexInfo->Shift[1])/Height))*Height);
00382
00383
00384
00385 SurfInfo[i].ShiftU = pTexInfo->Shift[0] - au;
00386 SurfInfo[i].ShiftV = pTexInfo->Shift[1] - av;
00387 }
00388 #else
00389 {
00390 SurfInfo[i].ShiftU = pTexInfo->Shift[0];
00391 SurfInfo[i].ShiftV = pTexInfo->Shift[1];
00392 }
00393 #endif
00394
00395 SurfInfo[i].VMins = VMins;
00396 SurfInfo[i].VMaxs = VMaxs;
00397
00398 if (BSP->BSPData.GFXTexInfo[BSP->BSPData.GFXFaces[i].TexInfo].Flags & TEXINFO_NO_LIGHTMAP)
00399 continue;
00400
00401 for (k=0; k< 2; k++)
00402 {
00403 Mins[k] = (geFloat)floor(Mins[k]/16);
00404 Maxs[k] = (geFloat)ceil(Maxs[k]/16);
00405
00406 Size[k] = (S32)(Maxs[k] - Mins[k]) + 1;
00407
00408 if (Size[k] > MAX_LMAP_SIZE)
00409 {
00410 geErrorLog_Add(GE_ERR_BAD_LMAP_EXTENTS, NULL);
00411 return GE_FALSE;
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420
00421 Size[0] = BSP->BSPData.GFXFaces[i].LWidth;
00422 Size[1] = BSP->BSPData.GFXFaces[i].LHeight;
00423
00424 SurfInfo[i].LInfo.Width = (int16)Size[0];
00425 SurfInfo[i].LInfo.Height = (int16)Size[1];
00426
00427 SurfInfo[i].LInfo.MinU = (S32)(Mins[0] * 16);
00428 SurfInfo[i].LInfo.MinV = (S32)(Mins[1] * 16);
00429 SurfInfo[i].LInfo.Face = i;
00430
00431 #if 0
00432 {
00433 int32 LightOffset, p;
00434 uint8 *LightData;
00435
00436 LightOffset = BSP->BSPData.GFXFaces[i].LightOfs;
00437
00438 if (LightOffset >= 0)
00439 {
00440 LightData = &BSP->BSPData.GFXLightData[LightOffset+1];
00441
00442 for (p=0; p< SurfInfo[i].LInfo.lWidth*SurfInfo[i].LInfo.lHeight; p++)
00443 {
00444 LightData++;
00445 if (*LightData)
00446 return GE_FALSE;
00447
00448 LightData++;
00449 LightData++;
00450 }
00451 }
00452 }
00453 #endif
00454
00455 #if 0
00456
00457
00458
00459 for (v= 0; v< BSP->BSPData.GFXFaces[i].NumVerts; v++)
00460 {
00461 vn = v + BSP->BSPData.GFXFaces[i].FirstVert;
00462
00463 U = TexVerts[vn].u - SurfInfo[i].LInfo.MinU;
00464 V = TexVerts[vn].v - SurfInfo[i].LInfo.MinV;
00465
00466 if (U < 0 || V > 16*128)
00467 {
00468 SurfInfo[i].LInfo.Face = -1;
00469
00470
00471 }
00472 if (V < 0 || V > 16*128)
00473 {
00474 SurfInfo[i].LInfo.Face = -1;
00475
00476
00477 }
00478
00479 }
00480 #endif
00481
00482 SurfInfo[i].Flags |= SURFINFO_LIGHTMAP;
00483
00484 }
00485
00486 if (!Vis_MarkWaterFaces(BSP))
00487 return GE_FALSE;
00488
00489 return GE_TRUE;
00490 }
00491
00492
00493
00494
00495 static geBoolean GetRGBVerts(World_BSP *BSP)
00496 {
00497 Surf_TexVert *pTexVerts;
00498 GFX_Face *pGFXFace;
00499 int32 i;
00500 geVec3d *pGFXRGBVerts;
00501
00502 pTexVerts = BSP->TexVerts;
00503 pGFXFace = BSP->BSPData.GFXFaces;
00504 pGFXRGBVerts = BSP->BSPData.GFXRGBVerts;
00505
00506 for (i=0; i< BSP->BSPData.NumGFXFaces; i++, pGFXFace++)
00507 {
00508 GFX_TexInfo *pTexInfo;
00509 int32 v;
00510
00511 pTexInfo = &BSP->BSPData.GFXTexInfo[pGFXFace->TexInfo];
00512
00513 if (!(pTexInfo->Flags & TEXINFO_GOURAUD) && !(pTexInfo->Flags & TEXINFO_FLAT))
00514 {
00515 for (v= 0; v< pGFXFace->NumVerts; v++)
00516 {
00517 int32 vn;
00518
00519 vn = pGFXFace->FirstVert + v;
00520
00521 pTexVerts[vn].r = 255.0f;
00522 pTexVerts[vn].g = 255.0f;
00523 pTexVerts[vn].b = 255.0f;
00524 }
00525 continue;
00526 }
00527
00528 for (v= 0; v< pGFXFace->NumVerts; v++)
00529 {
00530 int32 vn;
00531
00532 vn = pGFXFace->FirstVert + v;
00533
00534 pTexVerts[vn].r = pGFXRGBVerts[vn].X;
00535 pTexVerts[vn].g = pGFXRGBVerts[vn].Y;
00536 pTexVerts[vn].b = pGFXRGBVerts[vn].Z;
00537 }
00538 }
00539
00540 return GE_TRUE;
00541 }
00542
00543
00544
00545
00546 void CalcSurfVectors (World_BSP *BSP)
00547 {
00548 Surf_SurfInfo *pSurfInfo, *Si;
00549 GFX_TexInfo *Tex;
00550 geVec3d TexNormal;
00551 geVec3d FaceNormal;
00552 geFloat DistScale, PlaneDist;
00553 geFloat Dist, Len;
00554 geVec3d Ws[3];
00555 int32 i, k;
00556 GBSP_BSPData *BSPData;
00557 GFX_Plane *GFXPlanes;
00558 GFX_Face *pFace;
00559 int32 Startx, Starty;
00560 geFloat UU, VV;
00561
00562 BSPData = &BSP->BSPData;
00563
00564 pSurfInfo = BSP->SurfInfo;
00565
00566 GFXPlanes = BSPData->GFXPlanes;
00567
00568 for (i=0; i< BSP->BSPData.NumGFXFaces; i++)
00569 {
00570 Si = &pSurfInfo[i];
00571
00572 pFace = &BSPData->GFXFaces[i];
00573
00574 Tex = &BSPData->GFXTexInfo[pFace->TexInfo];
00575
00576 geVec3d_CrossProduct(&Tex->Vecs[0], &Tex->Vecs[1], &TexNormal);
00577 geVec3d_Normalize(&TexNormal);
00578
00579
00580 FaceNormal = GFXPlanes[pFace->PlaneNum].Normal;
00581 PlaneDist = GFXPlanes[pFace->PlaneNum].Dist;
00582
00583 if (pFace->PlaneSide)
00584 {
00585 geVec3d_Inverse(&FaceNormal);
00586 PlaneDist = -PlaneDist;
00587 }
00588
00589 DistScale = geVec3d_DotProduct(&TexNormal, &FaceNormal);
00590
00591 if (DistScale < 0)
00592 {
00593 geVec3d_Inverse(&TexNormal);
00594 DistScale = -DistScale;
00595 }
00596
00597
00598
00599 DistScale = 1/DistScale;
00600
00601
00602 for (k=0 ; k<2 ; k++)
00603 {
00604 Len = geVec3d_Length(&Tex->Vecs[k]);
00605 Dist = geVec3d_DotProduct(&Tex->Vecs[k], &FaceNormal);
00606 Dist *= DistScale;
00607 geVec3d_MA(&Tex->Vecs[k], -Dist, &TexNormal, &Si->T2WVecs[k]);
00608 geVec3d_Scale(&Si->T2WVecs[k], (1/Len)*(1/Len), &Si->T2WVecs[k]);
00609 }
00610
00611
00612 for (k=0 ; k<3 ; k++)
00613 VectorToSUB(Si->TexOrg,k) =
00614 - Tex->Vecs[0].Z * VectorToSUB(Si->T2WVecs[0], k)
00615 - Tex->Vecs[1].Z * VectorToSUB(Si->T2WVecs[1], k);
00616
00617 Dist = geVec3d_DotProduct(&Si->TexOrg, &FaceNormal) - PlaneDist - 1;
00618 Dist *= DistScale;
00619 geVec3d_MA (&Si->TexOrg, -Dist, &TexNormal, &Si->TexOrg);
00620
00621 Startx = Si->LInfo.MinU;
00622 Starty = Si->LInfo.MinV;
00623
00624 UU = (geFloat)Startx;
00625 VV = (geFloat)Starty;
00626
00627 Ws[0].X = Si->TexOrg.X + Si->T2WVecs[0].X*UU + Si->T2WVecs[1].X*VV;
00628 Ws[0].Y = Si->TexOrg.Y + Si->T2WVecs[0].Y*UU + Si->T2WVecs[1].Y*VV;
00629 Ws[0].Z = Si->TexOrg.Z + Si->T2WVecs[0].Z*UU + Si->T2WVecs[1].Z*VV;
00630 UU = (geFloat)Startx+16.0f;
00631 VV = (geFloat)Starty;
00632 Ws[1].X = Si->TexOrg.X + Si->T2WVecs[0].X*UU + Si->T2WVecs[1].X*VV;
00633 Ws[1].Y = Si->TexOrg.Y + Si->T2WVecs[0].Y*UU + Si->T2WVecs[1].Y*VV;
00634 Ws[1].Z = Si->TexOrg.Z + Si->T2WVecs[0].Z*UU + Si->T2WVecs[1].Z*VV;
00635 UU = (geFloat)Startx;
00636 VV = (geFloat)Starty+16.0f;
00637 Ws[2].X = Si->TexOrg.X + Si->T2WVecs[0].X*UU + Si->T2WVecs[1].X*VV;
00638 Ws[2].Y = Si->TexOrg.Y + Si->T2WVecs[0].Y*UU + Si->T2WVecs[1].Y*VV;
00639 Ws[2].Z = Si->TexOrg.Z + Si->T2WVecs[0].Z*UU + Si->T2WVecs[1].Z*VV;
00640
00641 geVec3d_Subtract(&Ws[1], &Ws[0], &Si->T2WVecs[0]);
00642 geVec3d_Subtract(&Ws[2], &Ws[0], &Si->T2WVecs[1]);
00643 Si->TexOrg = Ws[0];
00644 }
00645
00646 }