//===================================================================================== // geWorld_LinkPolyToLeaf //===================================================================================== void geWorld_LinkPolyToLeaf(const geWorld *World, gePoly *Poly) { #if SEARCH_ALL_VERTS_FOR_LEAF int32 i; #endif geWorld_Leaf *pLeafData; int32 Leaf; GE_LVertex *Verts; assert(World); assert(Poly); assert(geWorld_PolyIsValid(Poly)); assert(Poly->LeafData == NULL); Verts = Poly->Verts; #if SEARCH_ALL_VERTS_FOR_LEAF // Take the first vert that is in a valid leaf for (i=0; i<Poly->NumVerts; i++, Verts++) #endif { geVec3d Src; Src.X = Verts->X; Src.Y = Verts->Y; Src.Z = Verts->Z; Leaf = Plane_FindLeaf(World, gGFXModels[0].RootNode[0], &Src); #if SEARCH_ALL_VERTS_FOR_LEAF if (!(gGFXLeafs[Leaf].Contents & GE_CONTENTS_SOLID)) // Try to find the first leaf NOT in solid!!! break; #endif } assert(Leaf >=0 && Leaf < World->CurrentBSP->BSPData.NumGFXLeafs); pLeafData = &World->CurrentBSP->LeafData[Leaf]; // Insert into the beginning of the list if (pLeafData->PolyList) pLeafData->PolyList->Prev = Poly; Poly->Next = pLeafData->PolyList; Poly->Prev = NULL; // This is TRUE cause the poly is always added to the front of the list pLeafData->PolyList = Poly; Poly->LeafData = pLeafData; // Save the leaf data }
//===================================================================================== // Vis_VisWorld //===================================================================================== geBoolean Vis_VisWorld(geEngine *Engine, geWorld *World, const geCamera *Camera, Frustum_Info *Fi) { uint8 *VisData; int32 k, i, Area; GFX_Node *GFXNodes; GFX_Leaf *GFXLeafs; Surf_SurfInfo *SurfInfo; uint8 *GFXVisData; int32 Leaf, Cluster; GFX_Model *GFXModels; int32 *GFXLeafFaces; GFX_Cluster *GFXClusters; GBSP_BSPData *BSPData; geWorld_Model *Models; const geVec3d *Pos; GFX_Leaf *pLeaf; #ifdef _TSC pushTSC(); #endif Pos = geCamera_GetVisPov(Camera); BSPData = &World->CurrentBSP->BSPData; GFXNodes = BSPData->GFXNodes; GFXLeafs = BSPData->GFXLeafs; GFXClusters = BSPData->GFXClusters; GFXVisData = BSPData->GFXVisData; GFXModels = BSPData->GFXModels; GFXLeafFaces = BSPData->GFXLeafFaces; SurfInfo = World->CurrentBSP->SurfInfo; Leaf = Plane_FindLeaf(World, GFXModels[0].RootNode[0], Pos); Area = GFXLeafs[Leaf].Area; // Check to see if we cen get rid of most of the work load by seeing if the leaf has not changed... if (World->CurrentLeaf == Leaf && !World->ForceVis) goto LeafDidNotChange; World->ForceVis = GE_FALSE; // Reset force vis flag World->CurrentLeaf = Leaf; World->CurFrameStatic++; // Make all old vis info obsolete Cluster = GFXLeafs[Leaf].Cluster; if (Cluster == -1 || GFXClusters[Cluster].VisOfs == -1) { World->VisInfo = GE_FALSE; return GE_TRUE; } if (Area) Vis_FloodAreas_r(World, Area); World->VisInfo = GE_TRUE; VisData = &GFXVisData[GFXClusters[Cluster].VisOfs]; // Mark all visible clusters for (i=0; i<GFXModels[0].NumClusters; i++) { if (VisData[i>>3] & (1<<(i&7)) ) World->CurrentBSP->ClusterVisFrame[i] = World->CurFrameStatic; } pLeaf = &GFXLeafs[GFXModels[0].FirstLeaf]; // Go through and find all visible leafs based on the visible clusters the leafs are in for (i=0; i< GFXModels[0].NumLeafs; i++, pLeaf++) { int32 *pFace; Cluster = pLeaf->Cluster; if (Cluster == -1) // No cluster info for this leaf (must be solid) continue; // If the cluster is not visible, then the leaf is not visible if (World->CurrentBSP->ClusterVisFrame[Cluster] != World->CurFrameStatic) continue; // If the area is not visible, then the leaf is not visible if (World->CurrentBSP->AreaVisFrame[pLeaf->Area] != World->CurFrameStatic) continue; // Mark all visible nodes by bubbling up the tree from the leaf MarkVisibleParents(World, i); // Mark the leafs vis frame to worlds current frame World->CurrentBSP->LeafData[i].VisFrame = World->CurFrameStatic; pFace = &GFXLeafFaces[pLeaf->FirstFace]; // Go ahead and vis surfaces here... for (k=0; k< pLeaf->NumFaces; k++) { // Update each surface infos visframe thats touches each visible leaf SurfInfo[*pFace++].VisFrame = World->CurFrameStatic; } } LeafDidNotChange: // The world is always visible as a model World->CurrentBSP->Models[0].VisFrame = World->CurFrameDynamic; Models = &World->CurrentBSP->Models[1]; // Do models, skipping world models (it's always visible) for (i=1; i< BSPData->NumGFXModels; i++, Models++) { #if 0 int32 Cluster; // First, lets cheat, and see if the center is in a valid location to test for vis Leaf = Plane_FindLeaf(World, GFXModels[0].RootNode[0], &Models->Pivot); Cluster = GFXLeafs[Leaf].Cluster; if (Cluster >= 0 && GFXClusters[Cluster].VisOfs >= 0) // If there is vis data for this leaf { if (World->CurrentBSP->LeafData[Leaf].VisFrame == World->CurFrameStatic) Models->VisFrame = World->CurFrameDynamic; else { GFX_Model *pModel; pModel = &BSPData->GFXModels[i]; if (pModel->Areas[0] == Area || pModel->Areas[1] == Area && World->CurrentBSP->ClusterVisFrame[Cluster] == World->CurFrameStatic) Models->VisFrame = World->CurFrameDynamic; } } else if (ModelVisible(World, Models)) Models->VisFrame = World->CurFrameDynamic; #else if (ModelVisible(World, Models)) Models->VisFrame = World->CurFrameDynamic; #endif Models->ChangedFlags &= ~MODEL_CHANGED_XFORM; } VisFog(Engine, World, Camera, Fi, Area); #ifdef _TSC showPopTSC("Vis_VisWorld"); #endif return GE_TRUE; }