diff options
Diffstat (limited to 'src/renderer/Renderer.cpp')
-rw-r--r-- | src/renderer/Renderer.cpp | 764 |
1 files changed, 305 insertions, 459 deletions
diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 334f3954..96e3a329 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -9,6 +9,7 @@ #include "Vehicle.h" #include "Boat.h" #include "Heli.h" +#include "Bike.h" #include "Object.h" #include "PathFind.h" #include "Collision.h" @@ -20,17 +21,17 @@ #include "Streaming.h" #include "Shadows.h" #include "PointLights.h" +#include "Occlusion.h" #include "Renderer.h" -#include "Frontend.h" #include "custompipes.h" -#include "Debug.h" +#include "Frontend.h" bool gbShowPedRoadGroups; bool gbShowCarRoadGroups; bool gbShowCollisionPolys; +bool gbShowCollisionPolysReflections; +bool gbShowCollisionPolysNoShadows; bool gbShowCollisionLines; -bool gbShowCullZoneDebugStuff; -bool gbDisableZoneCull; // not original bool gbBigWhiteDebugLightSwitchedOn; bool gbDontRenderBuildings; @@ -39,21 +40,6 @@ bool gbDontRenderPeds; bool gbDontRenderObjects; bool gbDontRenderVehicles; -int32 EntitiesRendered; -int32 EntitiesNotRendered; -int32 RenderedBigBuildings; -int32 RenderedBuildings; -int32 RenderedCars; -int32 RenderedPeds; -int32 RenderedObjects; -int32 RenderedDummies; -int32 TestedBigBuildings; -int32 TestedBuildings; -int32 TestedCars; -int32 TestedPeds; -int32 TestedObjects; -int32 TestedDummies; - // unused int16 TestCloseThings; int16 TestBigThings; @@ -75,8 +61,6 @@ int32 CRenderer::ms_nNoOfVisibleVehicles; CEntity *CRenderer::ms_aVisibleVehiclePtrs[NUMVISIBLEENTITIES]; int32 CRenderer::ms_nNoOfVisibleBuildings; CEntity *CRenderer::ms_aVisibleBuildingPtrs[NUMVISIBLEENTITIES]; - -CLinkList<EntityInfo> gSortedBuildings; #endif CVector CRenderer::ms_vecCameraPosition; @@ -86,26 +70,20 @@ float CRenderer::ms_lodDistScale = 1.2f; // unused BlockedRange CRenderer::aBlockedRanges[16]; -BlockedRange *CRenderer::pFullBlockedRanges; -BlockedRange *CRenderer::pEmptyBlockedRanges; +BlockedRange* CRenderer::pFullBlockedRanges; +BlockedRange* CRenderer::pEmptyBlockedRanges; void CRenderer::Init(void) { gSortedVehiclesAndPeds.Init(40); SortBIGBuildings(); -#ifdef NEW_RENDERER - gSortedBuildings.Init(NUMVISIBLEENTITIES); -#endif } void CRenderer::Shutdown(void) { gSortedVehiclesAndPeds.Shutdown(); -#ifdef NEW_RENDERER - gSortedBuildings.Shutdown(); -#endif } void @@ -122,12 +100,8 @@ CRenderer::PreRender(void) for(i = 0; i < ms_nNoOfVisibleVehicles; i++) ms_aVisibleVehiclePtrs[i]->PreRender(); // How is this done with cWorldStream? - //for(i = 0; i < ms_nNoOfVisibleBuildings; i++) - // ms_aVisibleBuildingPtrs[i]->PreRender(); - for(CLink<EntityInfo> *node = gSortedBuildings.head.next; - node != &gSortedBuildings.tail; - node = node->next) - ((CEntity*)node->item.ent)->PreRender(); + for(i = 0; i < ms_nNoOfVisibleBuildings; i++) + ms_aVisibleBuildingPtrs[i]->PreRender(); for(node = CVisibilityPlugins::m_alphaBuildingList.head.next; node != &CVisibilityPlugins::m_alphaBuildingList.tail; node = node->next) @@ -154,26 +128,18 @@ CRenderer::PreRender(void) void CRenderer::RenderOneRoad(CEntity *e) { -#ifndef MASTER +#ifndef FINAL if(gbDontRenderBuildings) return; - if(gbShowCollisionPolys) +#endif +#ifndef MASTER + if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows) CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetColModel(e->GetModelIndex()), e->GetModelIndex()); else #endif { -#ifdef EXTENDED_PIPELINES - CustomPipes::AttachGlossPipe(e->GetAtomic()); -#endif PUSH_RENDERGROUP(CModelInfo::GetModelInfo(e->GetModelIndex())->GetModelName()); -#ifdef EXTRA_MODEL_FLAGS - if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){ - BACKFACE_CULLING_OFF; - e->Render(); - BACKFACE_CULLING_ON; - }else -#endif e->Render(); POP_RENDERGROUP(); @@ -189,12 +155,15 @@ CRenderer::RenderOneNonRoad(CEntity *e) bool resetLights; #ifndef MASTER - if(gbShowCollisionPolys){ + if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows){ if(!e->IsVehicle()){ CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetColModel(e->GetModelIndex()), e->GetModelIndex()); return; } - }else if(e->IsBuilding()){ + }else +#endif +#ifndef FINAL + if(e->IsBuilding()){ if(e->bIsBIGBuilding){ if(gbDontRenderBigBuildings) return; @@ -205,7 +174,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) }else #endif if(e->IsPed()){ -#ifndef MASTER +#ifndef FINAL if(gbDontRenderPeds) return; #endif @@ -213,7 +182,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) if(ped->m_nPedState == PED_DRIVING) return; } -#ifndef MASTER +#ifndef FINAL else if(e->IsObject() || e->IsDummy()){ if(gbDontRenderObjects) return; @@ -228,8 +197,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()){ @@ -239,23 +211,15 @@ 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(); - BACKFACE_CULLING_OFF; + SetCullMode(rwCULLMODECULLNONE); } -#ifdef EXTRA_MODEL_FLAGS - if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){ - BACKFACE_CULLING_OFF; - e->Render(); - BACKFACE_CULLING_ON; - }else -#endif e->Render(); if(e->IsVehicle()){ - BACKFACE_CULLING_OFF; e->bImBeingRendered = true; CVisibilityPlugins::RenderAlphaAtomics(); e->bImBeingRendered = false; - BACKFACE_CULLING_ON; + SetCullMode(rwCULLMODECULLBACK); } e->RemoveLighting(resetLights); @@ -278,53 +242,53 @@ CRenderer::RenderFirstPersonVehicle(void) RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); } -inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable(); } +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; PUSH_RENDERGROUP("CRenderer::RenderRoads"); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - BACKFACE_CULLING_ON; + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ - t = (CTreadable*)ms_aVisibleEntityPtrs[i]; - if(IsRoad(t)){ -#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); } POP_RENDERGROUP(); } +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) { int i; CEntity *e; - CVector dist; EntityInfo ei; PUSH_RENDERGROUP("CRenderer::RenderEverythingBarRoads"); - BACKFACE_CULLING_ON; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); gSortedVehiclesAndPeds.Clear(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ @@ -340,14 +304,12 @@ CRenderer::RenderEverythingBarRoads(void) 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(); + ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); gSortedVehiclesAndPeds.InsertSorted(ei); }else{ - dist = ms_vecCameraPosition - e->GetPosition(); - if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, dist.Magnitude())){ + if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, (ms_vecCameraPosition - e->GetPosition()).Magnitude())){ printf("Ran out of space in alpha entity list"); RenderOneNonRoad(e); } @@ -359,37 +321,38 @@ 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; PUSH_RENDERGROUP("CRenderer::RenderBoats"); - BACKFACE_CULLING_ON; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); + +#ifdef NEW_RENDERER + int i; + CEntity *e; + EntityInfo ei; + if(gbNewRenderer){ + gSortedVehiclesAndPeds.Clear(); + // not the real thing + for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ + e = ms_aVisibleVehiclePtrs[i]; + if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){ + ei.ent = e; + ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); + gSortedVehiclesAndPeds.InsertSorted(ei); + } + } + } +#endif 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); } POP_RENDERGROUP(); } @@ -407,8 +370,6 @@ enum { PASS_BLEND // normal blend }; -static RwRGBAReal black; - static void SetStencilState(int state) { @@ -449,14 +410,6 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist) RpAtomic *atomic = (RpAtomic*)ent->m_rwObject; CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->GetModelIndex()); -#ifdef EXTRA_MODEL_FLAGS - bool resetCull = false; - if(!ent->IsBuilding() || mi->RenderDoubleSided()){ - resetCull = true; - BACKFACE_CULLING_OFF; - } -#endif - int pass = PASS_BLEND; if(mi->m_additive) // very questionable pass = PASS_ADD; @@ -486,11 +439,6 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist) }else WorldRender::AtomicFirstPass(atomic, pass); -#ifdef EXTRA_MODEL_FLAGS - if(resetCull) - BACKFACE_CULLING_ON; -#endif - ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it? } @@ -502,7 +450,7 @@ CRenderer::RenderWorld(int pass) CLink<CVisibilityPlugins::AlphaObjectInfo> *node; RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - BACKFACE_CULLING_ON; + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); @@ -512,20 +460,11 @@ CRenderer::RenderWorld(int pass) // Roads PUSH_RENDERGROUP("CRenderer::RenderWorld - Roads"); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); -/* for(i = 0; i < ms_nNoOfVisibleBuildings; i++){ e = ms_aVisibleBuildingPtrs[i]; if(e->bIsBIGBuilding || IsRoad(e)) RenderOneBuilding(e); } -*/ - for(CLink<EntityInfo> *node = gSortedBuildings.tail.prev; - node != &gSortedBuildings.head; - node = node->prev){ - e = node->item.ent; - if(e->bIsBIGBuilding || IsRoad(e)) - RenderOneBuilding(e); - } for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev; node != &CVisibilityPlugins::m_alphaBuildingList.head; node = node->prev){ @@ -533,33 +472,17 @@ CRenderer::RenderWorld(int pass) if(e->bIsBIGBuilding || IsRoad(e)) RenderOneBuilding(e, node->item.sort); } - - // KLUDGE for road puddles which have to be rendered at road-time - // only very temporary, there are more rendering issues - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - WorldRender::RenderBlendPass(PASS_BLEND); - WorldRender::numBlendInsts[PASS_BLEND] = 0; POP_RENDERGROUP(); break; case 1: // Opaque PUSH_RENDERGROUP("CRenderer::RenderWorld - Opaque"); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); -/* for(i = 0; i < ms_nNoOfVisibleBuildings; i++){ e = ms_aVisibleBuildingPtrs[i]; if(!(e->bIsBIGBuilding || IsRoad(e))) RenderOneBuilding(e); } -*/ - for(CLink<EntityInfo> *node = gSortedBuildings.tail.prev; - node != &gSortedBuildings.head; - node = node->prev){ - e = node->item.ent; - if(!(e->bIsBIGBuilding || IsRoad(e))) - RenderOneBuilding(e); - } for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev; node != &CVisibilityPlugins::m_alphaBuildingList.head; node = node->prev){ @@ -618,8 +541,8 @@ CRenderer::RenderVehicles(void) e = ms_aVisibleVehiclePtrs[i]; if(!e->IsVehicle()) continue; -// if(PutIntoSortedVehicleList((CVehicle*)e)) -// continue; // boats handled elsewhere + if(PutIntoSortedVehicleList((CVehicle*)e)) + continue; // boats handled elsewhere ei.ent = e; ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); gSortedVehiclesAndPeds.InsertSorted(ei); @@ -633,12 +556,12 @@ CRenderer::RenderVehicles(void) } void -CRenderer::RenderWater(void) +CRenderer::RenderTransparentWater(void) { int i; CEntity *e; - PUSH_RENDERGROUP("CRenderer::RenderWater"); + PUSH_RENDERGROUP("CRenderer::RenderTransparentWater"); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); @@ -659,7 +582,7 @@ CRenderer::RenderWater(void) RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); SetStencilState(1); - CWaterLevel::RenderWater(); + CWaterLevel::RenderTransparentWater(); SetStencilState(0); POP_RENDERGROUP(); @@ -673,7 +596,6 @@ CRenderer::ClearForFrame(void) ms_nNoOfVisibleBuildings = 0; ms_nNoOfInVisibleEntities = 0; gSortedVehiclesAndPeds.Clear(); - gSortedBuildings.Clear(); WorldRender::numBlendInsts[PASS_NOZ] = 0; WorldRender::numBlendInsts[PASS_ADD] = 0; @@ -686,7 +608,8 @@ CRenderer::RenderFadingInEntities(void) { PUSH_RENDERGROUP("CRenderer::RenderFadingInEntities"); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - BACKFACE_CULLING_ON; + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); CVisibilityPlugins::RenderFadingEntities(); @@ -694,6 +617,16 @@ CRenderer::RenderFadingInEntities(void) } void +CRenderer::RenderFadingInUnderwaterEntities(void) +{ + PUSH_RENDERGROUP("CRenderer::RenderFadingInUnderwaterEntities"); + DeActivateDirectional(); + SetAmbientColours(); + CVisibilityPlugins::RenderFadingUnderwaterEntities(); + POP_RENDERGROUP(); +} + +void CRenderer::RenderCollisionLines(void) { int i; @@ -708,14 +641,6 @@ CRenderer::RenderCollisionLines(void) } } -// unused -void -CRenderer::RenderBlockBuildingLines(void) -{ - for(BlockedRange *br = pFullBlockedRanges; br; br = br->next) - printf("Blocked: %f %f\n", br->a, br->b); -} - enum Visbility { VIS_INVISIBLE, @@ -741,7 +666,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())){ @@ -750,32 +675,44 @@ CRenderer::SetupEntityVisibility(CEntity *ent) ti->m_alpha = 255; }else{ // Hide if possible - if(CANTIMECULL) + if(CANTIMECULL){ + ent->DeleteRwObject(); return VIS_INVISIBLE; + } // 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_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(); @@ -785,22 +722,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; @@ -820,7 +773,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; } @@ -832,9 +785,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; } @@ -870,7 +824,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{ @@ -883,19 +837,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(); @@ -904,7 +871,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) @@ -912,7 +879,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()) @@ -920,7 +887,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) } } - RpAtomic *a = mi->GetAtomicFromDistance(dist); + RpAtomic *a = mi->GetFirstAtomicFromDistance(dist); if(a){ if(ent->m_rwObject == nil) ent->CreateRwObject(); @@ -931,8 +898,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->IsVisible() || !ent->GetIsOnScreenComplex()) + mi->IncreaseAlpha(); + if(!ent->IsVisible() || !ent->GetIsOnScreenComplex() || 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; @@ -948,10 +925,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... @@ -961,14 +942,20 @@ 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->IsVisible() && ent->GetIsOnScreenComplex()) - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + mi->IncreaseAlpha(); + if(!ent->IsVisible() || !ent->GetIsOnScreenComplex() || 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(); #ifdef NEW_RENDERER if(!gbNewRenderer) #endif @@ -1027,24 +1014,6 @@ CRenderer::ScanWorld(void) RwMatrix *cammatrix; RwV2d poly[3]; -#ifndef MASTER - // missing in game but has to be done somewhere - EntitiesRendered = 0; - EntitiesNotRendered = 0; - RenderedBigBuildings = 0; - RenderedBuildings = 0; - RenderedCars = 0; - RenderedPeds = 0; - RenderedObjects = 0; - RenderedDummies = 0; - TestedBigBuildings = 0; - TestedBuildings = 0; - TestedCars = 0; - TestedPeds = 0; - TestedObjects = 0; - TestedDummies = 0; -#endif - memset(vectors, 0, sizeof(vectors)); vectors[CORNER_FAR_TOPLEFT].x = -vw.x * f; vectors[CORNER_FAR_TOPLEFT].y = vw.y * f; @@ -1065,6 +1034,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; @@ -1110,6 +1088,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); @@ -1119,7 +1098,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); @@ -1147,35 +1128,22 @@ CRenderer::ScanWorld(void) poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y); ScanSectorPoly(poly, 3, ScanSectorList); } + #ifdef NO_ISLAND_LOADING - if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_COMMERCIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_SUBURBAN)); + if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_BEACH)); + ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_MAINLAND)); } else #endif { - #ifdef FIX_BUGS - if (CCollision::ms_collisionInMemory != LEVEL_GENERIC) - #endif - ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory)); +#ifdef FIX_BUGS + if(CCollision::ms_collisionInMemory != LEVEL_GENERIC) +#endif + ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel)); } ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC)); } } - -#ifndef MASTER - if(gbShowCullZoneDebugStuff){ - sprintf(gString, "Rejected: %d/%d.", EntitiesNotRendered, EntitiesNotRendered + EntitiesRendered); - CDebug::PrintAt(gString, 10, 10); - sprintf(gString, "Tested:BBuild:%d Build:%d Peds:%d Cars:%d Obj:%d Dummies:%d", - TestedBigBuildings, TestedBuildings, TestedPeds, TestedCars, TestedObjects, TestedDummies); - CDebug::PrintAt(gString, 10, 11); - sprintf(gString, "Rendered:BBuild:%d Build:%d Peds:%d Cars:%d Obj:%d Dummies:%d", - RenderedBigBuildings, RenderedBuildings, RenderedPeds, RenderedCars, RenderedObjects, RenderedDummies); - CDebug::PrintAt(gString, 10, 12); - } -#endif } void @@ -1204,6 +1172,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 @@ -1262,8 +1231,6 @@ CRenderer::RequestObjectsInFrustum(void) bool CEntity::SetupLighting(void) { - DeActivateDirectional(); - SetAmbientColours(); return false; } @@ -1289,7 +1256,7 @@ CPed::SetupLighting(void) } else { // Note that this lightMult is only affected by LIGHT_DARKEN. If there's no LIGHT_DARKEN, it will be 1.0. float lightMult = CPointLights::GenerateLightsAffectingObject(&GetPosition()); - if (!bHasBlip && lightMult != 1.0f) { + if (lightMult != 1.0f) { SetAmbientAndDirectionalColours(lightMult); return true; } @@ -1300,7 +1267,13 @@ CPed::SetupLighting(void) void CPed::RemoveLighting(bool reset) { - CRenderer::RemoveVehiclePedLights(this, reset); + if (!bRenderScorched) { + CRenderer::RemoveVehiclePedLights(this, reset); + if (reset) + ReSetAmbientAndDirectionalColours(); + } + SetAmbientColours(); + DeActivateDirectional(); } float @@ -1472,13 +1445,9 @@ CRenderer::InsertEntityIntoList(CEntity *ent) // TODO: there are more flags being checked here if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed())) ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent; - else if(gbNewRenderer && ent->IsBuilding()){ - EntityInfo info; - info.ent = ent; - info.sort = -(ent->GetPosition() - ms_vecCameraPosition).MagnitudeSqr(); - gSortedBuildings.InsertSorted(info); -// ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent; - }else + else if(gbNewRenderer && ent->IsBuilding()) + ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent; + else #endif ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; } @@ -1488,22 +1457,25 @@ 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; -#ifndef MASTER - // all missing from game actually - TestedBigBuildings++; -#endif - if(!ent->bZoneCulled || gbDisableZoneCull){ - if(SetupBigBuildingVisibility(ent) == VIS_VISIBLE) - InsertEntityIntoList(ent); -#ifndef MASTER - EntitiesRendered++; - RenderedBigBuildings++; - }else{ - EntitiesNotRendered++; -#endif + if(ent->bOffscreen || (ent->m_randomSeed&3) != f){ + ent->bOffscreen = true; + vis = SetupBigBuildingVisibility(ent); + }else + vis = VIS_VISIBLE; + switch(vis){ + case VIS_VISIBLE: + InsertEntityIntoList(ent); + ent->bOffscreen = false; + break; + case VIS_STREAMME: + if(!CStreaming::ms_disableStreaming) + CStreaming::RequestModel(ent->GetModelIndex(), 0); + break; } } } @@ -1524,61 +1496,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: - InsertEntityIntoList(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); - break; - } -#ifndef MASTER - EntitiesRendered++; - switch(ent->GetType()){ - case ENTITY_TYPE_BUILDING: - if(ent->bIsBIGBuilding) - RenderedBigBuildings++; - else - RenderedBuildings++; - break; - case ENTITY_TYPE_VEHICLE: - RenderedCars++; - break; - case ENTITY_TYPE_PED: - RenderedPeds++; - break; - case ENTITY_TYPE_OBJECT: - RenderedObjects++; - break; - case ENTITY_TYPE_DUMMY: - RenderedDummies++; + switch(SetupEntityVisibility(ent)){ + case VIS_VISIBLE: + InsertEntityIntoList(ent); + break; + case VIS_INVISIBLE: + if(!IsGlass(ent->GetModelIndex())) break; - } -#endif - }else if(IsRoad(ent) && !CStreaming::ms_disableStreaming){ - if(SetupEntityVisibility(ent) == VIS_STREAMME) + // 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(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) CStreaming::RequestModel(ent->GetModelIndex(), 0); - }else{ -#ifndef MASTER - EntitiesNotRendered++; -#endif + break; } } } @@ -1600,69 +1541,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: - InsertEntityIntoList(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; - } - break; - } -#ifndef MASTER - // actually missing in game - EntitiesRendered++; - switch(ent->GetType()){ - case ENTITY_TYPE_BUILDING: - if(ent->bIsBIGBuilding) - RenderedBigBuildings++; - else - RenderedBuildings++; - break; - case ENTITY_TYPE_VEHICLE: - RenderedCars++; - break; - case ENTITY_TYPE_PED: - RenderedPeds++; - break; - case ENTITY_TYPE_OBJECT: - RenderedObjects++; - break; - case ENTITY_TYPE_DUMMY: - RenderedDummies++; + switch(SetupEntityVisibility(ent)){ + case VIS_VISIBLE: + InsertEntityIntoList(ent); + break; + case VIS_INVISIBLE: + if(!IsGlass(ent->GetModelIndex())) break; - } -#endif - }else if(IsRoad(ent) && !CStreaming::ms_disableStreaming){ - if(SetupEntityVisibility(ent) == VIS_STREAMME) + // 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); - }else{ -#ifndef MASTER - // actually missing in game - EntitiesNotRendered++; -#endif + if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED) + m_loadingPriority = true; + } + break; } } } } +#ifdef GTA_TRAIN void CRenderer::ScanSectorList_Subway(CPtrList *lists) { @@ -1679,15 +1589,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: InsertEntityIntoList(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; @@ -1695,6 +1607,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists) } } } +#endif void CRenderer::ScanSectorList_RequestModels(CPtrList *lists) @@ -1711,8 +1624,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); } } @@ -1747,95 +1659,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(gbDisableZoneCull) return true; - -#ifndef MASTER - switch(ent->GetType()){ - case ENTITY_TYPE_BUILDING: - if(ent->bIsBIGBuilding) - TestedBigBuildings++; - else - TestedBuildings++; - break; - case ENTITY_TYPE_VEHICLE: - TestedCars++; - break; - case ENTITY_TYPE_PED: - TestedPeds++; - break; - case ENTITY_TYPE_OBJECT: - TestedObjects++; - break; - case ENTITY_TYPE_DUMMY: - TestedDummies++; - break; - } -#endif - 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->GetIsStatic()) - 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(); } |