diff options
Diffstat (limited to 'src/render/Renderer.cpp')
-rw-r--r-- | src/render/Renderer.cpp | 452 |
1 files changed, 246 insertions, 206 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 88d412c9..0640f25e 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -7,6 +7,7 @@ #include "Ped.h" #include "Vehicle.h" #include "Heli.h" +#include "Bike.h" #include "Object.h" #include "PathFind.h" #include "Collision.h" @@ -18,13 +19,13 @@ #include "Streaming.h" #include "Shadows.h" #include "PointLights.h" +#include "Occlusion.h" #include "Renderer.h" -bool gbShowPedRoadGroups; -bool gbShowCarRoadGroups; +//--MIAMI: file done + bool gbShowCollisionPolys; bool gbShowCollisionLines; -bool gbShowCullZoneDebugStuff; bool gbBigWhiteDebugLightSwitchedOn; bool gbDontRenderBuildings; @@ -142,8 +143,11 @@ CRenderer::RenderOneNonRoad(CEntity *e) resetLights = e->SetupLighting(); - if(e->IsVehicle()) + if(e->IsVehicle()){ + // unfortunately can't use GetClump here + CVisibilityPlugins::SetupVehicleVariables((RpClump*)e->m_rwObject); CVisibilityPlugins::InitAlphaAtomicList(); + } // Render Peds in vehicle before vehicle itself if(e->IsVehicle()){ @@ -153,6 +157,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) for(i = 0; i < 8; i++) if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING) veh->pPassengers[i]->Render(); + SetCullMode(rwCULLMODECULLNONE); } e->Render(); @@ -160,6 +165,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) e->bImBeingRendered = true; CVisibilityPlugins::RenderAlphaAtomics(); e->bImBeingRendered = false; + SetCullMode(rwCULLMODECULLBACK); } e->RemoveLighting(resetLights); @@ -180,38 +186,40 @@ CRenderer::RenderFirstPersonVehicle(void) RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); } +inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CSimpleModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->m_wetRoadReflection; } + void CRenderer::RenderRoads(void) { int i; - CTreadable *t; + CEntity *e; RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ - t = (CTreadable*)ms_aVisibleEntityPtrs[i]; - if(t->IsBuilding() && t->GetIsATreadable()){ -#ifndef MASTER - if(gbShowCarRoadGroups || gbShowPedRoadGroups){ - int ind = 0; - if(gbShowCarRoadGroups) - ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_CAR][0]].group; - if(gbShowPedRoadGroups) - ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_PED][0]].group; - SetAmbientColoursToIndicateRoadGroup(ind); - } -#endif - RenderOneRoad(t); -#ifndef MASTER - if(gbShowCarRoadGroups || gbShowPedRoadGroups) - ReSetAmbientAndDirectionalColours(); -#endif - } + e = ms_aVisibleEntityPtrs[i]; + if(IsRoad(e)) + RenderOneRoad(e); } } +inline bool PutIntoSortedVehicleList(CVehicle *veh) +{ + if(veh->IsBoat()){ + int mode = TheCamera.Cams[TheCamera.ActiveCam].Mode; + if(mode == CCam::MODE_WHEELCAM || + mode == CCam::MODE_1STPERSON && TheCamera.GetLookDirection() != LOOKING_FORWARD && TheCamera.GetLookDirection() != LOOKING_BEHIND || + CVisibilityPlugins::GetClumpAlpha(veh->GetClump()) != 255) + return false; + return true; + }else + return veh->bTouchingWater; +} + void CRenderer::RenderEverythingBarRoads(void) { @@ -220,17 +228,20 @@ CRenderer::RenderEverythingBarRoads(void) CVector dist; EntityInfo ei; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); gSortedVehiclesAndPeds.Clear(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ e = ms_aVisibleEntityPtrs[i]; - if(e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable()) + if(IsRoad(e)) continue; if(e->IsVehicle() || e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){ - if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()){ + if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){ ei.ent = e; dist = ms_vecCameraPosition - e->GetPosition(); ei.sort = dist.MagnitudeSqr(); @@ -248,34 +259,19 @@ CRenderer::RenderEverythingBarRoads(void) } void -CRenderer::RenderVehiclesButNotBoats(void) -{ - // This function doesn't do anything - // because only boats are inserted into the list - CLink<EntityInfo> *node; - - for(node = gSortedVehiclesAndPeds.tail.prev; - node != &gSortedVehiclesAndPeds.head; - node = node->prev){ - // only boats in this list - CVehicle *v = (CVehicle*)node->item.ent; - if(!v->IsBoat()) - RenderOneNonRoad(v); - } -} - -void CRenderer::RenderBoats(void) { CLink<EntityInfo> *node; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); + for(node = gSortedVehiclesAndPeds.tail.prev; node != &gSortedVehiclesAndPeds.head; node = node->prev){ - // only boats in this list CVehicle *v = (CVehicle*)node->item.ent; - if(v->IsBoat()) - RenderOneNonRoad(v); + RenderOneNonRoad(v); } } @@ -283,12 +279,22 @@ void CRenderer::RenderFadingInEntities(void) { RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); CVisibilityPlugins::RenderFadingEntities(); } void +CRenderer::RenderFadingInUnderwaterEntities(void) +{ + DeActivateDirectional(); + SetAmbientColours(); + CVisibilityPlugins::RenderFadingUnderwaterEntities(); +} + +void CRenderer::RenderCollisionLines(void) { int i; @@ -336,7 +342,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) float dist; bool request = true; - if (mi->GetModelType() == MITYPE_TIME) { + if(mi->GetModelType() == MITYPE_TIME){ ti = (CTimeModelInfo*)mi; other = ti->GetOtherTimeModel(); if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){ @@ -352,25 +358,35 @@ CRenderer::SetupEntityVisibility(CEntity *ent) request = false; } }else{ - if (mi->GetModelType() != MITYPE_SIMPLE) { + if(mi->GetModelType() != MITYPE_SIMPLE && mi->GetModelType() != MITYPE_WEAPON){ if(FindPlayerVehicle() == ent && - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ + TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON && + !(FindPlayerVehicle()->IsBike() && ((CBike*)FindPlayerVehicle())->bWheelieCam)){ // Player's vehicle in first person mode - if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD || + CVehicle *veh = (CVehicle*)ent; + int model = veh->GetModelIndex(); + int direction = TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking; + if(direction == LOOKING_FORWARD || ent->GetModelIndex() == MI_RHINO || ent->GetModelIndex() == MI_COACH || - TheCamera.m_bInATunnelAndABigVehicle){ + TheCamera.m_bInATunnelAndABigVehicle || + direction == LOOKING_BEHIND && veh->pHandling->Flags & HANDLING_UNKNOWN){ ent->bNoBrightHeadLights = true; - }else{ + return VIS_OFFSCREEN; + } + + if(direction != LOOKING_BEHIND || + !veh->IsBoat() || model == MI_REEFER || model == MI_TROPIC || model == MI_PREDATOR || model == MI_SKIMMER){ m_pFirstPersonVehicle = (CVehicle*)ent; ent->bNoBrightHeadLights = false; + return VIS_OFFSCREEN; } - return VIS_OFFSCREEN; } + // All sorts of Clumps if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; - if(!ent->GetIsOnScreen()) + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()) return VIS_OFFSCREEN; if(ent->bDrawLast){ dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); @@ -380,22 +396,38 @@ CRenderer::SetupEntityVisibility(CEntity *ent) } return VIS_VISIBLE; } - if(ent->IsObject() && - ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){ + if(ent->bDontStream){ if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; - return ent->GetIsOnScreen() ? VIS_VISIBLE : VIS_OFFSCREEN; + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()) + return VIS_OFFSCREEN; + if(ent->bDrawLast){ + dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = false; + return VIS_INVISIBLE; + } + return VIS_VISIBLE; } } // Simple ModelInfo + if(!IsAreaVisible(ent->m_area)) + return VIS_INVISIBLE; + dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); - // This can only happen with multi-atomic models (e.g. railtracks) - // but why do we bump up the distance? can only be fading... - if(LOD_DISTANCE + STREAM_DISTANCE < dist && dist < mi->GetLargestLodDistance()) - dist = mi->GetLargestLodDistance(); +#ifndef FIX_BUGS + // Whatever this is supposed to do, it breaks fading for objects + // whose draw dist is > LOD_DISTANCE-FADE_DISTANCE, i.e. 280 + // because decreasing dist here makes the object visible above LOD_DISTANCE + // before fading normally once below LOD_DISTANCE. + // aha! this must be a workaround for the fact that we're not taking + // the LOD multiplier into account here anywhere + if(LOD_DISTANCE < dist && dist < mi->GetLargestLodDistance() + FADE_DISTANCE) + dist += mi->GetLargestLodDistance() - LOD_DISTANCE; +#endif if(ent->IsObject() && ent->bRenderDamaged) mi->m_isDamaged = true; @@ -415,7 +447,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; - if(!ent->GetIsOnScreen()){ + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){ mi->m_alpha = 255; return VIS_OFFSCREEN; } @@ -427,9 +459,10 @@ CRenderer::SetupEntityVisibility(CEntity *ent) } if(mi->m_drawLast || ent->bDrawLast){ - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = false; - return VIS_INVISIBLE; + if(CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist)){ + ent->bDistanceFade = false; + return VIS_INVISIBLE; + } } return VIS_VISIBLE; } @@ -465,7 +498,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; - if(!ent->GetIsOnScreen()){ + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){ mi->m_alpha = 255; return VIS_OFFSCREEN; }else{ @@ -478,19 +511,32 @@ CRenderer::SetupEntityVisibility(CEntity *ent) int32 CRenderer::SetupBigBuildingVisibility(CEntity *ent) { - CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); + CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); CTimeModelInfo *ti; int32 other; - if (mi->GetModelType() == MITYPE_TIME) { - ti = (CTimeModelInfo*)mi; + if(!IsAreaVisible(ent->m_area)) + return VIS_INVISIBLE; + + bool request = true; + if(mi->GetModelType() == MITYPE_TIME){ + ti = (CTimeModelInfo*)mi; other = ti->GetOtherTimeModel(); - // Hide objects not in time range if possible - if(CANTIMECULL) - if(!CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())) + if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){ + // don't fade in, or between time objects + if(CANTIMECULL) + ti->m_alpha = 255; + }else{ + // Hide if possible + if(CANTIMECULL){ + ent->DeleteRwObject(); return VIS_INVISIBLE; - // Draw like normal - } else if (mi->GetModelType() == MITYPE_VEHICLE) + } + // can't cull, so we'll try to draw this one, but don't request + // it since what we really want is the other one. + request = false; + } + }else if(mi->GetModelType() == MITYPE_VEHICLE) return ent->IsVisible() ? VIS_VISIBLE : VIS_INVISIBLE; float dist = (ms_vecCameraPosition-ent->GetPosition()).Magnitude(); @@ -499,7 +545,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // Find out whether to draw below near distance. // This is only the case if there is a non-LOD which is either not // loaded or not completely faded in yet. - if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE + STREAM_DISTANCE){ + if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE){ // No non-LOD or non-LOD is completely visible. if(nonLOD == nil || nonLOD->GetRwObject() && nonLOD->m_alpha == 255) @@ -507,7 +553,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // But if it is a time object, we'd rather draw the wrong // non-LOD than the right LOD. - if (nonLOD->GetModelType() == MITYPE_TIME) { + if(nonLOD->GetModelType() == MITYPE_TIME){ ti = (CTimeModelInfo*)nonLOD; other = ti->GetOtherTimeModel(); if(other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject()) @@ -515,7 +561,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) } } - RpAtomic *a = mi->GetAtomicFromDistance(dist); + RpAtomic *a = mi->GetFirstAtomicFromDistance(dist); if(a){ if(ent->m_rwObject == nil) ent->CreateRwObject(); @@ -526,8 +572,18 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // that of an atomic for another draw distance. if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - if(!ent->IsVisibleComplex()) + mi->IncreaseAlpha(); + if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){ + mi->m_alpha = 255; return VIS_INVISIBLE; + } + + if(mi->m_alpha != 255){ + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; + return VIS_INVISIBLE; + } + if(mi->m_drawLast){ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); ent->bDistanceFade = false; @@ -543,10 +599,14 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // get faded atomic - a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE); + a = mi->GetFirstAtomicFromDistance(dist - FADE_DISTANCE); if(a == nil){ - ent->DeleteRwObject(); - return VIS_INVISIBLE; + if(ent->bStreamBIGBuilding && dist-STREAM_DISTANCE < mi->GetLodDistance(0) && request){ + return ent->GetIsOnScreen() ? VIS_STREAMME : VIS_INVISIBLE; + }else{ + ent->DeleteRwObject(); + return VIS_INVISIBLE; + } } // Fade... @@ -556,14 +616,21 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - if(ent->IsVisibleComplex()) - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + mi->IncreaseAlpha(); + if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){ + mi->m_alpha = 255; + return VIS_INVISIBLE; + } + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; return VIS_INVISIBLE; } void CRenderer::ConstructRenderList(void) { + COcclusion::ProcessBeforeRendering(); + ms_nNoOfVisibleEntities = 0; ms_nNoOfInVisibleEntities = 0; ms_vecCameraPosition = TheCamera.GetPosition(); @@ -623,6 +690,15 @@ CRenderer::ScanWorld(void) CVisibilityPlugins::InitAlphaEntityList(); CWorld::AdvanceCurrentScanCode(); + // unused + static CVector prevPos; + static CVector prevFwd; + static bool smallMovement; + smallMovement = (TheCamera.GetPosition() - prevPos).MagnitudeSqr() < SQR(4.0f) && + DotProduct(TheCamera.GetForward(), prevFwd) > 0.98f; + prevPos = TheCamera.GetPosition(); + prevFwd = TheCamera.GetForward(); + if(cammatrix->at.z > 0.0f){ // looking up, bottom corners are further away vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_BOTLEFT] * LOD_DISTANCE/f; @@ -668,6 +744,7 @@ CRenderer::ScanWorld(void) for(int y = y1; y <= y2; y++) ScanSectorList(CWorld::GetSector(x1, y)->m_lists); }else{ +#ifdef GTA_TRAIN CVehicle *train = FindPlayerTrain(); if(train && train->GetPosition().z < 0.0f){ poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); @@ -677,7 +754,9 @@ CRenderer::ScanWorld(void) poly[2].x = CWorld::GetSectorX(vectors[CORNER_LOD_RIGHT].x); poly[2].y = CWorld::GetSectorY(vectors[CORNER_LOD_RIGHT].y); ScanSectorPoly(poly, 3, ScanSectorList_Subway); - }else{ + }else +#endif + { if(f > LOD_DISTANCE){ // priority poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); @@ -705,16 +784,8 @@ CRenderer::ScanWorld(void) poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y); ScanSectorPoly(poly, 3, ScanSectorList); } -#ifdef NO_ISLAND_LOADING - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_COMMERCIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_SUBURBAN)); -#else - #ifdef FIX_BUGS - if (CCollision::ms_collisionInMemory != LEVEL_GENERIC) - #endif - ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory)); -#endif + + ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel)); ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC)); } } @@ -746,6 +817,7 @@ CRenderer::RequestObjectsInFrustum(void) cammatrix = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); CWorld::AdvanceCurrentScanCode(); + ms_vecCameraPosition = TheCamera.GetPosition(); if(cammatrix->at.z > 0.0f){ // looking up, bottom corners are further away @@ -958,11 +1030,26 @@ CRenderer::ScanBigBuildingList(CPtrList &list) { CPtrNode *node; CEntity *ent; + int vis; + int f = CTimer::GetFrameCounter() & 3; for(node = list.first; node; node = node->next){ ent = (CEntity*)node->item; - if(!ent->bZoneCulled && SetupBigBuildingVisibility(ent) == VIS_VISIBLE) + if(ent->bOffscreen || (ent->m_randomSeed&3) != f){ + ent->bOffscreen = true; + vis = SetupBigBuildingVisibility(ent); + }else + vis = VIS_VISIBLE; + switch(vis){ + case VIS_VISIBLE: ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; + ent->bOffscreen = false; + break; + case VIS_STREAMME: + if(!CStreaming::ms_disableStreaming) + CStreaming::RequestModel(ent->GetModelIndex(), 0); + break; + } } } @@ -982,35 +1069,30 @@ CRenderer::ScanSectorList(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); + ent->bOffscreen = false; - if(IsEntityCullZoneVisible(ent)) - switch(SetupEntityVisibility(ent)){ - case VIS_VISIBLE: - ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; - break; - case VIS_INVISIBLE: - if(!IsGlass(ent->GetModelIndex())) - break; - // fall through - case VIS_OFFSCREEN: - dx = ms_vecCameraPosition.x - ent->GetPosition().x; - dy = ms_vecCameraPosition.y - ent->GetPosition().y; - if(dx > -65.0f && dx < 65.0f && - dy > -65.0f && dy < 65.0f && - ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) - ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; - break; - case VIS_STREAMME: - if(!CStreaming::ms_disableStreaming) - if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) - CStreaming::RequestModel(ent->GetModelIndex(), 0); + switch(SetupEntityVisibility(ent)){ + case VIS_VISIBLE: + ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; + break; + case VIS_INVISIBLE: + if(!IsGlass(ent->GetModelIndex())) break; - } - else if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){ + // fall through + case VIS_OFFSCREEN: + ent->bOffscreen = true; + dx = ms_vecCameraPosition.x - ent->GetPosition().x; + dy = ms_vecCameraPosition.y - ent->GetPosition().y; + if(dx > -30.0f && dx < 30.0f && + dy > -30.0f && dy < 30.0f && + ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) + ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; + break; + case VIS_STREAMME: if(!CStreaming::ms_disableStreaming) - if(SetupEntityVisibility(ent) == VIS_STREAMME) - if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) - CStreaming::RequestModel(ent->GetModelIndex(), 0); + if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) + CStreaming::RequestModel(ent->GetModelIndex(), 0); + break; } } } @@ -1032,41 +1114,38 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); + ent->bOffscreen = false; - if(IsEntityCullZoneVisible(ent)) - switch(SetupEntityVisibility(ent)){ - case VIS_VISIBLE: - ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; - break; - case VIS_INVISIBLE: - if(!IsGlass(ent->GetModelIndex())) - break; - // fall through - case VIS_OFFSCREEN: - dx = ms_vecCameraPosition.x - ent->GetPosition().x; - dy = ms_vecCameraPosition.y - ent->GetPosition().y; - if(dx > -65.0f && dx < 65.0f && - dy > -65.0f && dy < 65.0f && - ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) - ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; - break; - case VIS_STREAMME: - if(!CStreaming::ms_disableStreaming){ - CStreaming::RequestModel(ent->GetModelIndex(), 0); - if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED) - m_loadingPriority = true; - } + switch(SetupEntityVisibility(ent)){ + case VIS_VISIBLE: + ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; + break; + case VIS_INVISIBLE: + if(!IsGlass(ent->GetModelIndex())) break; + // fall through + case VIS_OFFSCREEN: + ent->bOffscreen = true; + dx = ms_vecCameraPosition.x - ent->GetPosition().x; + dy = ms_vecCameraPosition.y - ent->GetPosition().y; + if(dx > -30.0f && dx < 30.0f && + dy > -30.0f && dy < 30.0f && + ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) + ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; + break; + case VIS_STREAMME: + if(!CStreaming::ms_disableStreaming){ + CStreaming::RequestModel(ent->GetModelIndex(), 0); + if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED) + m_loadingPriority = true; } - else if(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable()){ - if(!CStreaming::ms_disableStreaming) - if(SetupEntityVisibility(ent) == VIS_STREAMME) - CStreaming::RequestModel(ent->GetModelIndex(), 0); + break; } } } } +#ifdef GTA_TRAIN void CRenderer::ScanSectorList_Subway(CPtrList *lists) { @@ -1083,15 +1162,17 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); + ent->bOffscreen = false; switch(SetupEntityVisibility(ent)){ case VIS_VISIBLE: ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; break; case VIS_OFFSCREEN: + ent->bOffscreen = true; dx = ms_vecCameraPosition.x - ent->GetPosition().x; dy = ms_vecCameraPosition.y - ent->GetPosition().y; - if(dx > -65.0f && dx < 65.0f && - dy > -65.0f && dy < 65.0f && + if(dx > -30.0f && dx < 30.0f && + dy > -30.0f && dy < 30.0f && ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; break; @@ -1099,6 +1180,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists) } } } +#endif void CRenderer::ScanSectorList_RequestModels(CPtrList *lists) @@ -1115,8 +1197,7 @@ CRenderer::ScanSectorList_RequestModels(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); - if(IsEntityCullZoneVisible(ent)) - if(ShouldModelBeStreamed(ent)) + if(ShouldModelBeStreamed(ent, ms_vecCameraPosition)) CStreaming::RequestModel(ent->GetModelIndex(), 0); } } @@ -1151,70 +1232,29 @@ CRenderer::SortBIGBuildingsForSectorList(CPtrList *list) } bool -CRenderer::ShouldModelBeStreamed(CEntity *ent) +CRenderer::ShouldModelBeStreamed(CEntity *ent, const CVector &campos) { - CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); - float dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); + if(!IsAreaVisible(ent->m_area)) + return false; + CTimeModelInfo *mi = (CTimeModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); + if(mi->GetModelType() == MITYPE_TIME) + if(!CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) + return false; + float dist = (ent->GetPosition() - campos).Magnitude(); if(mi->m_noFade) return dist - STREAM_DISTANCE < mi->GetLargestLodDistance(); else return dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance(); } -bool -CRenderer::IsEntityCullZoneVisible(CEntity *ent) -{ - CPed *ped; - CObject *obj; - - if(ent->bZoneCulled) - return false; - - switch(ent->GetType()){ - case ENTITY_TYPE_VEHICLE: - return IsVehicleCullZoneVisible(ent); - case ENTITY_TYPE_PED: - ped = (CPed*)ent; - if (ped->bInVehicle) { - if (ped->m_pMyVehicle) - return IsVehicleCullZoneVisible(ped->m_pMyVehicle); - else - return true; - } - return !(ped->m_pCurSurface && ped->m_pCurSurface->bZoneCulled2); - case ENTITY_TYPE_OBJECT: - obj = (CObject*)ent; - if(!obj->IsStatic()) - return true; - return !(obj->m_pCurSurface && obj->m_pCurSurface->bZoneCulled2); - default: break; - } - return true; -} - -bool -CRenderer::IsVehicleCullZoneVisible(CEntity *ent) -{ - CVehicle *v = (CVehicle*)ent; - switch(v->GetStatus()) { - case STATUS_SIMPLE: - case STATUS_PHYSICS: - case STATUS_ABANDONED: - case STATUS_WRECKED: - return !(v->m_pCurGroundEntity && v->m_pCurGroundEntity->bZoneCulled2); - default: break; - } - return true; -} - void CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset) { - if(ent->bRenderScorched){ - WorldReplaceScorchedLightsWithNormal(Scene.world); - return; + if(!ent->bRenderScorched){ + CPointLights::RemoveLightsAffectingObject(); + if(reset) + ReSetAmbientAndDirectionalColours(); } - CPointLights::RemoveLightsAffectingObject(); - if(reset) - ReSetAmbientAndDirectionalColours(); + SetAmbientColours(); + DeActivateDirectional(); } |