diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.cpp index 1ec2d264d..670e06859 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.cpp @@ -55,17 +55,34 @@ void FPooledActor::EnableActor(const FTransform& Transform, int32 NewIndex, FTil TileMeshComponent = NewTileMeshComponent; TileMeshComponent->IndicesInUse.Emplace(Index); - Actor->SetActorHiddenInGame(false); - Actor->SetActorEnableCollision(true); Actor->SetActorTickEnabled(true); USpringBasedVegetationComponent* Component = Actor->FindComponentByClass(); if (Component) { Component->ResetComponent(); + } +} + +void FPooledActor::ActiveActor() +{ + TRACE_CPUPROFILER_EVENT_SCOPE(FPooledActor::ActiveActor); + + IsActive = true; + Actor->SetActorEnableCollision(true); + + USpringBasedVegetationComponent* Component = Actor->FindComponentByClass(); + if (Component) + { Component->SetComponentTickEnabled(true); } + + USkeletalMeshComponent* SkeletalMesh = Actor->FindComponentByClass(); + if (SkeletalMesh) + { + SkeletalMesh->bNoSkeletonUpdate = false; + } } void FPooledActor::DisableActor() @@ -79,19 +96,24 @@ void FPooledActor::DisableActor() } InUse = false; + IsActive = false; Index = -1; TileMeshComponent = nullptr; - Actor->SetActorHiddenInGame(true); Actor->SetActorEnableCollision(false); + Actor->SetActorHiddenInGame(true); Actor->SetActorTickEnabled(false); - Actor->SetTickableWhenPaused(false); USpringBasedVegetationComponent* Component = Actor->FindComponentByClass(); if (Component) { Component->SetComponentTickEnabled(false); - Component->SetTickableWhenPaused(false); + } + + USkeletalMeshComponent* SkeletalMesh = Actor->FindComponentByClass(); + if (SkeletalMesh) + { + SkeletalMesh->bNoSkeletonUpdate = true; } } @@ -229,6 +251,7 @@ void AVegetationManager::Tick(float DeltaTime) UpdateMaterials(Tile); TArray ElementsToSpawn = GetElementsToSpawn(Tile); SpawnSkeletalFoliages(ElementsToSpawn); + ActivePooledActors(); DestroySkeletalFoliages(); } @@ -496,6 +519,7 @@ void AVegetationManager::SpawnSkeletalFoliages(TArray& Element TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::SpawnSkeletalFoliages); const FTransform HeroTransform = LargeMap->LocalToGlobalTransform(HeroVehicle->GetActorTransform()); const FVector HeroLocation = HeroTransform.GetLocation(); + const float HeroDetectionSizeSquared = HeroVehicle->GetDetectionSize() * HeroVehicle->GetDetectionSize(); for (FElementsToSpawn& Element : ElementsToSpawn) { @@ -508,8 +532,8 @@ void AVegetationManager::SpawnSkeletalFoliages(TArray& Element int32 Index = TransformIndex.Value; if (Element.TileMeshComponent->IndicesInUse.Contains(Index)) continue; - const float Distance = FMath::Abs(FVector::Dist(Transform.GetLocation(), HeroLocation)); - if (Distance > HeroVehicle->GetDetectionSize()) + const float Distance = FMath::Abs(FVector::DistSquared(Transform.GetLocation(), HeroLocation)); + if (Distance > HeroDetectionSizeSquared) continue; bool Ok = EnableActorFromPool(Transform, Index, Element.TileMeshComponent, *Pool); if (Ok) @@ -530,11 +554,38 @@ void AVegetationManager::SpawnSkeletalFoliages(TArray& Element } } +void AVegetationManager::ActivePooledActors() +{ + TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::ActivePooledActors); + const FTransform HeroTransform = LargeMap->LocalToGlobalTransform(HeroVehicle->GetActorTransform()); + const FVector HeroLocation = HeroTransform.GetLocation(); + const float SquaredActiveActorDistance = ActiveActorDistance * ActiveActorDistance; + + for (TPair>& Element : ActorPool) + { + TArray& Pool = Element.Value; + for (FPooledActor& Actor : Pool) + { + if (!Actor.InUse) + continue; + if (Actor.IsActive) + continue; + const FVector Location = Actor.GlobalTransform.GetLocation(); + const float Distance = FMath::Abs(FVector::DistSquared(Location, HeroLocation)); + if (Distance < SquaredActiveActorDistance) + { + Actor.ActiveActor(); + } + } + } +} + void AVegetationManager::DestroySkeletalFoliages() { TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::DestroySkeletalFoliages); const FTransform HeroTransform = LargeMap->LocalToGlobalTransform(HeroVehicle->GetActorTransform()); const FVector HeroLocation = HeroTransform.GetLocation(); + const float HeroDetectionSizeSquared = HeroVehicle->GetDetectionSize() * HeroVehicle->GetDetectionSize(); for (TPair>& Element : ActorPool) { @@ -544,8 +595,8 @@ void AVegetationManager::DestroySkeletalFoliages() if (!Actor.InUse) continue; const FVector Location = Actor.GlobalTransform.GetLocation(); - const float Distance = FMath::Abs(FVector::Dist(Location, HeroLocation)); - if (Distance > HeroVehicle->GetDetectionSize()) + const float Distance = FMath::Abs(FVector::DistSquared(Location, HeroLocation)); + if (Distance > HeroDetectionSizeSquared) { Actor.DisableActor(); } @@ -616,7 +667,6 @@ void AVegetationManager::UpdatePoolBasePosition() TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::UpdatePoolBasePosition); if (!IsValid(HeroVehicle)) return; - UE_LOG(LogCarla, Display, TEXT("UpdatePoolBasePosition")); const FTransform HeroTransform = LargeMap->LocalToGlobalTransform(HeroVehicle->GetActorTransform()); const FVector HeroLocation = HeroTransform.GetLocation(); const FTransform PoolTransform(HeroTransform.GetRotation(), FVector(HeroLocation.X, HeroLocation.Y, -1000.0f), FVector(1.0f, 1.0f, 1.0f)); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.h index 8fe0ea626..45cd0ee38 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vegetation/VegetationManager.h @@ -58,12 +58,14 @@ struct FPooledActor { GENERATED_BODY() bool InUse { false }; + bool IsActive { false }; AActor* Actor { nullptr }; FTransform GlobalTransform {FTransform()}; int32 Index {-1}; FTileMeshComponent* TileMeshComponent {nullptr}; void EnableActor(const FTransform& Transform, int32 NewIndex, FTileMeshComponent* NewTileMeshComponent); + void ActiveActor(); void DisableActor(); }; @@ -95,6 +97,9 @@ public: UPROPERTY(Category = "CARLA Vegetation Spwaner", EditDefaultsOnly) float HideMaterialDistance {500.0f}; + UPROPERTY(Category = "CARLA Vegetation Spwaner", EditDefaultsOnly) + float ActiveActorDistance {500.0f}; + //Filters for debug UPROPERTY(Category = "CARLA Vegetation Spwaner", EditDefaultsOnly) bool SpawnBushes {true}; @@ -133,6 +138,7 @@ private: TArray GetElementsToSpawn(FTileData* Tile); void SpawnSkeletalFoliages(TArray& ElementsToSpawn); void DestroySkeletalFoliages(); + void ActivePooledActors(); bool EnableActorFromPool(const FTransform& Transform, int32 Index, FTileMeshComponent* TileMeshComponent, TArray& Pool); void CreateOrUpdateTileCache(ULevel* InLevel);