2019-12-26 14:45:42 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-07-10 13:31:21 -04:00
# include "NavigationDirtyAreasController.h"
# include "NavigationData.h"
2020-02-24 18:43:44 -05:00
DEFINE_LOG_CATEGORY_STATIC ( LogNavigationDirtyArea , Warning , All ) ;
2019-07-10 13:31:21 -04:00
//----------------------------------------------------------------------//
// FNavigationDirtyAreasController
//----------------------------------------------------------------------//
FNavigationDirtyAreasController : : FNavigationDirtyAreasController ( )
: bCanAccumulateDirtyAreas ( true )
2019-07-10 13:40:29 -04:00
# if !UE_BUILD_SHIPPING
2019-07-10 13:31:21 -04:00
, bDirtyAreasReportedWhileAccumulationLocked ( false )
2020-02-24 18:43:44 -05:00
, bCanReportOversizedDirtyArea ( false )
, bNavigationBuildLocked ( false )
2019-07-10 13:40:29 -04:00
# endif // !UE_BUILD_SHIPPING
2019-07-10 13:31:21 -04:00
{
}
2019-11-12 16:04:24 -05:00
void FNavigationDirtyAreasController : : ForceRebuildOnNextTick ( )
{
float MinTimeForUpdate = ( DirtyAreasUpdateFreq ! = 0.f ? ( 1.0f / DirtyAreasUpdateFreq ) : 0.f ) ;
DirtyAreasUpdateTime = FMath : : Max ( DirtyAreasUpdateTime , MinTimeForUpdate ) ;
}
2019-07-10 13:31:21 -04:00
void FNavigationDirtyAreasController : : Tick ( const float DeltaSeconds , const TArray < ANavigationData * > & NavDataSet , bool bForceRebuilding )
{
DirtyAreasUpdateTime + = DeltaSeconds ;
const bool bCanRebuildNow = bForceRebuilding | | ( DirtyAreasUpdateFreq ! = 0.f & & DirtyAreasUpdateTime > = ( 1.0f / DirtyAreasUpdateFreq ) ) ;
if ( DirtyAreas . Num ( ) > 0 & & bCanRebuildNow )
{
for ( ANavigationData * NavData : NavDataSet )
{
if ( NavData )
{
NavData - > RebuildDirtyAreas ( DirtyAreas ) ;
}
}
DirtyAreasUpdateTime = 0.f ;
DirtyAreas . Reset ( ) ;
}
}
2020-02-24 18:43:44 -05:00
void FNavigationDirtyAreasController : : AddArea ( const FBox & NewArea , const int32 Flags , const TFunction < UObject * ( ) > & ObjectProviderFunc /*= nullptr*/ )
2019-07-10 13:31:21 -04:00
{
2020-02-24 18:43:44 -05:00
# if !UE_BUILD_SHIPPING
// always keep track of reported areas even when filtered out by invalid area as long as flags are valid
bDirtyAreasReportedWhileAccumulationLocked = bDirtyAreasReportedWhileAccumulationLocked | | ( Flags > 0 & & ! bCanAccumulateDirtyAreas ) ;
# endif // !UE_BUILD_SHIPPING
if ( ! NewArea . IsValid )
{
UE_LOG ( LogNavigationDirtyArea , Warning , TEXT ( " Skipping dirty area creation because of invalid bounds (object: %s) " ) , * GetFullNameSafe ( ObjectProviderFunc ? ObjectProviderFunc ( ) : nullptr ) ) ;
return ;
}
const FVector2D BoundsSize ( NewArea . GetSize ( ) ) ;
if ( BoundsSize . IsNearlyZero ( ) )
{
UE_LOG ( LogNavigationDirtyArea , Warning , TEXT ( " Skipping dirty area creation because of empty bounds (object: %s) " ) , * GetFullNameSafe ( ObjectProviderFunc ? ObjectProviderFunc ( ) : nullptr ) ) ;
return ;
}
# if !UE_BUILD_SHIPPING
2021-01-08 19:56:07 -04:00
auto DumpExtraInfo = [ ObjectProviderFunc , BoundsSize ] ( ) {
const UObject * ObjectProvider = nullptr ;
if ( ObjectProviderFunc )
{
ObjectProvider = ObjectProviderFunc ( ) ;
}
const UActorComponent * ObjectAsComponent = Cast < UActorComponent > ( ObjectProvider ) ;
const AActor * ComponentOwner = ObjectAsComponent ? ObjectAsComponent - > GetOwner ( ) : nullptr ;
return FString : : Printf ( TEXT ( " Adding dirty area object = % | Potential component's owner = %s | Bounds size = %s) " ) , * GetFullNameSafe ( ObjectProvider ) , * GetFullNameSafe ( ComponentOwner ) , * BoundsSize . ToString ( ) ) ;
} ;
UE_LOG ( LogNavigationDirtyArea , VeryVerbose , TEXT ( " %s " ) , * DumpExtraInfo ( ) ) ;
2020-08-11 01:36:57 -04:00
if ( ShouldReportOversizedDirtyArea ( ) & & BoundsSize . GetMax ( ) > DirtyAreaWarningSizeThreshold )
{
UE_LOG ( LogNavigationDirtyArea , Warning , TEXT ( " Adding an oversized dirty area (object:%s size:%s threshold:%.2f) " ) ,
* GetFullNameSafe ( ObjectProviderFunc ? ObjectProviderFunc ( ) : nullptr ) ,
* BoundsSize . ToString ( ) ,
DirtyAreaWarningSizeThreshold ) ;
}
2020-02-24 18:43:44 -05:00
# endif // !UE_BUILD_SHIPPING
if ( Flags > 0 & & bCanAccumulateDirtyAreas )
2019-07-10 13:31:21 -04:00
{
DirtyAreas . Add ( FNavigationDirtyArea ( NewArea , Flags ) ) ;
}
2020-02-24 18:43:44 -05:00
}
void FNavigationDirtyAreasController : : OnNavigationBuildLocked ( )
{
2019-07-10 13:31:21 -04:00
# if !UE_BUILD_SHIPPING
2020-02-24 18:43:44 -05:00
bNavigationBuildLocked = true ;
2019-07-10 13:31:21 -04:00
# endif // !UE_BUILD_SHIPPING
}
2020-02-24 18:43:44 -05:00
void FNavigationDirtyAreasController : : OnNavigationBuildUnlocked ( )
{
# if !UE_BUILD_SHIPPING
bNavigationBuildLocked = false ;
# endif // !UE_BUILD_SHIPPING
}
void FNavigationDirtyAreasController : : SetDirtyAreaWarningSizeThreshold ( const float Threshold )
{
# if !UE_BUILD_SHIPPING
DirtyAreaWarningSizeThreshold = Threshold ;
# endif // !UE_BUILD_SHIPPING
}
void FNavigationDirtyAreasController : : SetCanReportOversizedDirtyArea ( bool bCanReport )
{
# if !UE_BUILD_SHIPPING
bCanReportOversizedDirtyArea = bCanReport ;
# endif // !UE_BUILD_SHIPPING
}
# if !UE_BUILD_SHIPPING
bool FNavigationDirtyAreasController : : ShouldReportOversizedDirtyArea ( ) const
{
return bNavigationBuildLocked = = false & & bCanReportOversizedDirtyArea & & DirtyAreaWarningSizeThreshold > = 0.0f ;
}
# endif // !UE_BUILD_SHIPPING
2019-07-10 13:31:21 -04:00
void FNavigationDirtyAreasController : : Reset ( )
{
// discard all pending dirty areas, we are going to rebuild navmesh anyway
DirtyAreas . Reset ( ) ;
# if !UE_BUILD_SHIPPING
bDirtyAreasReportedWhileAccumulationLocked = false ;
# endif // !UE_BUILD_SHIPPING
}