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
00024 #include "BaseType.h"
00025 #include "World.h"
00026 #include "Plane.h"
00027 #include "Vec3d.h"
00028 #include "Ram.h"
00029 #include "Surface.h"
00030 #include "Trace.h"
00031 #include "Camera.h"
00032 #include "Frustum.h"
00033 #include "System.h"
00034
00035 #include "Fog.h"
00036
00037 #ifdef _TSC
00038 #include "tsc.h"
00039 #endif
00040
00041
00042
00043 static void MarkVisibleParents(geWorld *World, int32 Leaf);
00044 static void FindParents(World_BSP *Bsp);
00045 static void VisFog(geEngine *Engine, geWorld *World, const geCamera *Camera, Frustum_Info *Fi, int32 Area);
00046
00047
00048
00049
00050 geBoolean Vis_WorldInit(geWorld *World)
00051 {
00052 World_BSP *BSP;
00053 int32 i;
00054 static int32 StartupParams[]={0x696C6345,0x21657370};
00055
00056 assert(World != NULL);
00057
00058 BSP = World->CurrentBSP;
00059
00060 assert(BSP != NULL);
00061
00062 if (!BSP)
00063 return GE_FALSE;
00064
00065 BSP->NodeVisFrame = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXNodes);
00066
00067 if (!BSP->NodeVisFrame)
00068 goto Error;
00069
00070 BSP->ClusterVisFrame = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXClusters);
00071
00072 if (!BSP->ClusterVisFrame)
00073 goto Error;
00074
00075 BSP->AreaVisFrame = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXAreas);
00076
00077 if (!BSP->AreaVisFrame)
00078 goto Error;
00079
00080 BSP->NodeParents = GE_RAM_ALLOCATE_ARRAY(int32, BSP->BSPData.NumGFXNodes);
00081
00082 if (!BSP->NodeParents)
00083 goto Error;
00084
00085 memset(BSP->NodeVisFrame, 0, sizeof(int32)*BSP->BSPData.NumGFXNodes);
00086 memset(BSP->ClusterVisFrame, 0, sizeof(int32)*BSP->BSPData.NumGFXClusters);
00087 memset(BSP->AreaVisFrame, 0, sizeof(int32)*BSP->BSPData.NumGFXAreas);
00088
00089 memset(BSP->NodeParents, 0, sizeof(int32)*BSP->BSPData.NumGFXNodes);
00090
00091 FindParents(World->CurrentBSP);
00092
00093
00094 for (i=0; i<256; i++)
00095 World->CurrentBSP->AreaConnections[i][i] = 1;
00096
00097 return GE_TRUE;
00098
00099 Error:
00100 if (BSP->NodeVisFrame)
00101 geRam_Free(BSP->NodeVisFrame);
00102 if (BSP->ClusterVisFrame)
00103 geRam_Free(BSP->ClusterVisFrame);
00104 if (BSP->AreaVisFrame)
00105 geRam_Free(BSP->AreaVisFrame);
00106 if (BSP->NodeParents)
00107 geRam_Free(BSP->NodeParents);
00108
00109 BSP->NodeVisFrame = NULL;
00110 BSP->ClusterVisFrame = NULL;
00111 BSP->AreaVisFrame = NULL;
00112 BSP->NodeParents = NULL;
00113 return GE_FALSE;
00114 }
00115
00116
00117
00118
00119 void Vis_WorldShutdown(geWorld *World)
00120 {
00121 World_BSP *BSP;
00122
00123 assert(World != NULL);
00124
00125 if (!World->CurrentBSP)
00126 return;
00127
00128 BSP = World->CurrentBSP;
00129
00130 if (BSP->NodeVisFrame)
00131 geRam_Free(BSP->NodeVisFrame);
00132 if (BSP->ClusterVisFrame)
00133 geRam_Free(BSP->ClusterVisFrame);
00134 if (BSP->AreaVisFrame)
00135 geRam_Free(BSP->AreaVisFrame);
00136 if (BSP->NodeParents)
00137 geRam_Free(BSP->NodeParents);
00138
00139 BSP->NodeVisFrame = NULL;
00140 BSP->ClusterVisFrame = NULL;
00141 BSP->AreaVisFrame = NULL;
00142 BSP->NodeParents = NULL;
00143 }
00144
00145
00146
00147
00148 geBoolean ModelVisible(geWorld *World, geWorld_Model *Model)
00149 {
00150 return Trace_BBoxInVisibleLeaf(World, &Model->TMins, &Model->TMaxs);
00151 }
00152
00153
00154
00155
00156 void Vis_FloodAreas_r(geWorld *World, int32 Area)
00157 {
00158 GBSP_BSPData *BSP;
00159 GFX_Area *a;
00160 GFX_AreaPortal *p;
00161 int32 i;
00162
00163 if (World->CurrentBSP->AreaVisFrame[Area] == World->CurFrameStatic)
00164 return;
00165
00166 World->CurrentBSP->AreaVisFrame[Area] = World->CurFrameStatic;
00167
00168 BSP = &World->CurrentBSP->BSPData;
00169
00170 a = &BSP->GFXAreas[Area];
00171
00172 p = &BSP->GFXAreaPortals[a->FirstAreaPortal];
00173
00174 for (i=0; i< a->NumAreaPortals; i++, p++)
00175 {
00176 geWorld_Model *Model;
00177
00178 Model = &World->CurrentBSP->Models[p->ModelNum];
00179
00180 if (Model->Open)
00181 Vis_FloodAreas_r(World, p->Area);
00182 }
00183 }
00184
00185
00186
00187
00188 geBoolean Vis_VisWorld(geEngine *Engine, geWorld *World, const geCamera *Camera, Frustum_Info *Fi)
00189 {
00190 uint8 *VisData;
00191 int32 k, i, Area;
00192 GFX_Node *GFXNodes;
00193 GFX_Leaf *GFXLeafs;
00194 Surf_SurfInfo *SurfInfo;
00195 uint8 *GFXVisData;
00196 int32 Leaf, Cluster;
00197 GFX_Model *GFXModels;
00198 int32 *GFXLeafFaces;
00199 GFX_Cluster *GFXClusters;
00200 GBSP_BSPData *BSPData;
00201 geWorld_Model *Models;
00202 const geVec3d *Pos;
00203 GFX_Leaf *pLeaf;
00204
00205 #ifdef _TSC
00206 pushTSC();
00207 #endif
00208
00209 Pos = geCamera_GetVisPov(Camera);
00210
00211 BSPData = &World->CurrentBSP->BSPData;
00212
00213 GFXNodes = BSPData->GFXNodes;
00214 GFXLeafs = BSPData->GFXLeafs;
00215 GFXClusters = BSPData->GFXClusters;
00216 GFXVisData = BSPData->GFXVisData;
00217 GFXModels = BSPData->GFXModels;
00218 GFXLeafFaces = BSPData->GFXLeafFaces;
00219
00220 SurfInfo = World->CurrentBSP->SurfInfo;
00221
00222 Leaf = Plane_FindLeaf(World, GFXModels[0].RootNode[0], Pos);
00223 Area = GFXLeafs[Leaf].Area;
00224
00225
00226 if (World->CurrentLeaf == Leaf && !World->ForceVis)
00227 goto LeafDidNotChange;
00228
00229 World->ForceVis = GE_FALSE;
00230
00231 World->CurrentLeaf = Leaf;
00232
00233 World->CurFrameStatic++;
00234
00235 Cluster = GFXLeafs[Leaf].Cluster;
00236
00237 if (Cluster == -1 || GFXClusters[Cluster].VisOfs == -1)
00238 {
00239 World->VisInfo = GE_FALSE;
00240 return GE_TRUE;
00241 }
00242
00243 if (Area)
00244 Vis_FloodAreas_r(World, Area);
00245
00246 World->VisInfo = GE_TRUE;
00247
00248 VisData = &GFXVisData[GFXClusters[Cluster].VisOfs];
00249
00250
00251 for (i=0; i<GFXModels[0].NumClusters; i++)
00252 {
00253 if (VisData[i>>3] & (1<<(i&7)) )
00254 World->CurrentBSP->ClusterVisFrame[i] = World->CurFrameStatic;
00255 }
00256
00257 pLeaf = &GFXLeafs[GFXModels[0].FirstLeaf];
00258
00259
00260 for (i=0; i< GFXModels[0].NumLeafs; i++, pLeaf++)
00261 {
00262 int32 *pFace;
00263
00264 Cluster = pLeaf->Cluster;
00265
00266 if (Cluster == -1)
00267 continue;
00268
00269
00270 if (World->CurrentBSP->ClusterVisFrame[Cluster] != World->CurFrameStatic)
00271 continue;
00272
00273
00274 if (World->CurrentBSP->AreaVisFrame[pLeaf->Area] != World->CurFrameStatic)
00275 continue;
00276
00277
00278 MarkVisibleParents(World, i);
00279
00280
00281 World->CurrentBSP->LeafData[i].VisFrame = World->CurFrameStatic;
00282
00283 pFace = &GFXLeafFaces[pLeaf->FirstFace];
00284
00285
00286 for (k=0; k< pLeaf->NumFaces; k++)
00287 {
00288
00289 SurfInfo[*pFace++].VisFrame = World->CurFrameStatic;
00290 }
00291 }
00292
00293 LeafDidNotChange:
00294
00295
00296 World->CurrentBSP->Models[0].VisFrame = World->CurFrameDynamic;
00297
00298 Models = &World->CurrentBSP->Models[1];
00299
00300 for (i=1; i< BSPData->NumGFXModels; i++, Models++)
00301 {
00302 #if 0
00303 int32 Cluster;
00304
00305
00306 Leaf = Plane_FindLeaf(World, GFXModels[0].RootNode[0], &Models->Pivot);
00307
00308 Cluster = GFXLeafs[Leaf].Cluster;
00309
00310 if (Cluster >= 0 && GFXClusters[Cluster].VisOfs >= 0)
00311 {
00312 if (World->CurrentBSP->LeafData[Leaf].VisFrame == World->CurFrameStatic)
00313 Models->VisFrame = World->CurFrameDynamic;
00314 else
00315 {
00316 GFX_Model *pModel;
00317
00318 pModel = &BSPData->GFXModels[i];
00319
00320 if (pModel->Areas[0] == Area || pModel->Areas[1] == Area &&
00321 World->CurrentBSP->ClusterVisFrame[Cluster] == World->CurFrameStatic)
00322 Models->VisFrame = World->CurFrameDynamic;
00323 }
00324 }
00325 else if (ModelVisible(World, Models))
00326 Models->VisFrame = World->CurFrameDynamic;
00327 #else
00328
00329 if (ModelVisible(World, Models))
00330 Models->VisFrame = World->CurFrameDynamic;
00331
00332 #endif
00333
00334 Models->ChangedFlags &= ~MODEL_CHANGED_XFORM;
00335 }
00336
00337 VisFog(Engine, World, Camera, Fi, Area);
00338
00339 #ifdef _TSC
00340 showPopTSC("Vis_VisWorld");
00341 #endif
00342
00343 return GE_TRUE;
00344 }
00345
00346
00347
00348
00349 geBoolean Vis_MarkWaterFaces(World_BSP *WBSP)
00350 {
00351 GFX_Leaf *GFXLeafs;
00352 int32 i, f, FNum;
00353 int32 NumLeafs, Contents;
00354 Surf_SurfInfo *SurfInfo;
00355 S32 *GFXLeafFaces;
00356
00357 assert(WBSP != NULL);
00358
00359 GFXLeafs = WBSP->BSPData.GFXLeafs;
00360 GFXLeafFaces = WBSP->BSPData.GFXLeafFaces;
00361
00362 NumLeafs = WBSP->BSPData.GFXModels[0].NumLeafs;
00363
00364 SurfInfo = WBSP->SurfInfo;
00365
00366 assert(SurfInfo != NULL);
00367
00368 for (i = 0; i< NumLeafs; i++)
00369 {
00370 Contents = GFXLeafs[i].Contents;
00371
00372 if (!(Contents & GE_CONTENTS_WAVY))
00373 continue;
00374
00375 for (f=0; f< GFXLeafs[i].NumFaces; f++)
00376 {
00377 FNum = GFXLeafFaces[GFXLeafs[i].FirstFace + f];
00378
00379
00380
00381 SurfInfo[FNum].Flags |= SURFINFO_WAVY;
00382 }
00383 }
00384
00385 return GE_TRUE;
00386 }
00387
00388 static GFX_Node *GFXNodes;
00389 static int32 *NodeParents;
00390 static geWorld_Leaf *LeafData;
00391
00392
00393
00394
00395 static void FindParents_r(int32 Node, int32 Parent)
00396 {
00397 if (Node < 0)
00398 {
00399 LeafData[-(Node+1)].Parent = Parent;
00400 return;
00401 }
00402
00403
00404 NodeParents[Node] = Parent;
00405
00406
00407 FindParents_r(GFXNodes[Node].Children[0], Node);
00408 FindParents_r(GFXNodes[Node].Children[1], Node);
00409 }
00410
00411
00412
00413
00414 static void FindParents(World_BSP *Bsp)
00415 {
00416 assert(Bsp != NULL);
00417
00418
00419 GFXNodes = Bsp->BSPData.GFXNodes;
00420 LeafData = Bsp->LeafData;
00421 NodeParents = Bsp->NodeParents;
00422
00423 FindParents_r(Bsp->BSPData.GFXModels[0].RootNode[0], -1);
00424 }
00425
00426
00427
00428
00429 static void MarkVisibleParents(geWorld *World, int32 Leaf)
00430 {
00431 int32 Node;
00432 World_BSP *Bsp;
00433
00434 assert(Leaf >= 0);
00435 assert(Leaf < World->CurrentBSP->BSPData.NumGFXLeafs);
00436
00437 Bsp = World->CurrentBSP;
00438
00439
00440 Node = Bsp->LeafData[Leaf].Parent;
00441
00442
00443 while (Node >= 0)
00444 {
00445 Bsp->NodeVisFrame[Node] = World->CurFrameStatic;
00446 Node = Bsp->NodeParents[Node];
00447 }
00448 }
00449
00450
00451
00452
00453
00454 static void VisFog(geEngine *Engine, geWorld *World, const geCamera *Camera, Frustum_Info *Fi, int32 Area)
00455 {
00456 GBSP_BSPData *BSPData;
00457 GFX_Leaf *GFXLeafs;
00458 geFog *Fog;
00459 World_BSP *CBSP;
00460 Frustum_Info WorldSpaceFrustum;
00461
00462
00463 assert(World);
00464 assert(Camera);
00465 assert(Fi);
00466
00467 World->NumVisibleFog = 0;
00468
00469 if (!World->FogList)
00470 return;
00471
00472
00473
00474
00475 Frustum_TransformToWorldSpace(Fi, Camera, &WorldSpaceFrustum);
00476
00477 CBSP = World->CurrentBSP;
00478
00479 BSPData = &CBSP->BSPData;
00480
00481 GFXLeafs = BSPData->GFXLeafs;
00482
00483 for (Fog = World->FogList; Fog; Fog = Fog->Next)
00484 {
00485 geWorld_FogData *FogData;
00486
00487 if (World->NumVisibleFog >= MAX_VISIBLE_FOG)
00488 return;
00489
00490 FogData = (geWorld_FogData*)geFog_GetUserData(Fog);
00491
00492 if (CBSP->LeafData[FogData->Leaf].VisFrame != World->CurFrameStatic)
00493 continue;
00494
00495 if (Area != GFXLeafs[FogData->Leaf].Area)
00496 continue;
00497
00498
00499 if (!Frustum_PointInFrustum(&WorldSpaceFrustum, &Fog->Pos, Fog->VolumeRadius-1.0f))
00500 continue;
00501
00502 FogData->VisFrame = World->CurFrameDynamic;
00503
00504
00505 World->VisibleFog[World->NumVisibleFog++] = Fog;
00506
00507
00508 Engine->DebugInfo.NumFog++;
00509 }
00510 }