Luis/vegetation videos (#5861)

* fixed pool increasing size fast.

* Fixed pools

* get the vehicle each frame

* Fixed bug when starting a new manual control script.

* Fixed xerces-c dependency

* fixed xerces-c dependencies

* Adding backup for xerces-c library

* Fix the duplication of collision capsules, and remove the impulse with static bones

* enable impulse force again, for static bones

* nullptr tile bug fixed

Co-authored-by: Axel <axellopez92@outlook.com>
Co-authored-by: bernatx <bernatx@gmail.com>
This commit is contained in:
LuisPoveda 2022-10-24 10:35:29 +02:00 committed by GitHub
parent bcf3471586
commit bc23f261e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 155 additions and 187 deletions

View File

@ -209,6 +209,17 @@ void ALargeMapManager::OnActorSpawned(
} }
ACarlaWheeledVehicle* ALargeMapManager::GetHeroVehicle()
{
if (ActorsToConsider.Num() > 0)
{
ACarlaWheeledVehicle* Hero = Cast<ACarlaWheeledVehicle>(ActorsToConsider[0]);
if (IsValid(Hero))
return Hero;
}
return nullptr;
}
void ALargeMapManager::OnActorDestroyed(AActor* DestroyedActor) void ALargeMapManager::OnActorDestroyed(AActor* DestroyedActor)
{ {
LM_LOG(Warning, "ALargeMapManager::OnActorDestroyed %s", *DestroyedActor->GetName()); LM_LOG(Warning, "ALargeMapManager::OnActorDestroyed %s", *DestroyedActor->GetName());

View File

@ -197,6 +197,8 @@ public:
FCarlaMapTile& LoadCarlaMapTile(FString TileMapPath, TileID TileId); FCarlaMapTile& LoadCarlaMapTile(FString TileMapPath, TileID TileId);
ACarlaWheeledVehicle* GetHeroVehicle();
protected: protected:
void UpdateTilesState(); void UpdateTilesState();

View File

@ -301,7 +301,7 @@ void USpringBasedVegetationComponent::GenerateSkeletonHierarchy()
} }
} }
UpdateGlobalTransform(); // UpdateGlobalTransform();
} }
void USpringBasedVegetationComponent::BeginPlay() void USpringBasedVegetationComponent::BeginPlay()
@ -330,47 +330,6 @@ void USpringBasedVegetationComponent::BeginPlay()
GenerateSkeletonHierarchy(); GenerateSkeletonHierarchy();
} }
// Get resting pose for bones
auto *AnimInst = SkeletalMesh->GetAnimInstance();
if (!AnimInst)
{
OTHER_LOG(Error, "Could not get animation instance.");
return;
}
UWalkerAnim *WalkerAnim = Cast<UWalkerAnim>(AnimInst);
if (!WalkerAnim)
{
OTHER_LOG(Error, "Could not get UWalkerAnim.");
return;
}
// get current pose
FPoseSnapshot TempSnapshot;
SkeletalMesh->SnapshotPose(TempSnapshot);
// copy pose
WalkerAnim->Snap = TempSnapshot;
for (int i=0; i<Skeleton.Joints.Num(); ++i)
{
FSkeletonJoint& Joint = Skeleton.Joints[i];
FTransform JointTransform = SkeletalMesh->GetSocketTransform(FName(*Joint.JointName), ERelativeTransformSpace::RTS_ParentBoneSpace);
Joint.Transform = JointTransform;
Joint.RestingAngles = JointTransform.Rotator();
OTHER_LOG(Log, "Getting info for bone %s, %f, %f, %f, %f", *Joint.JointName, Joint.RestingAngles.Pitch, Joint.RestingAngles.Yaw, Joint.RestingAngles.Roll);
if(i > 0)
{
FSkeletonJoint& ParentJoint = Skeleton.Joints[Joint.ParentId];
FVector BoneCOM = Joint.Transform.GetLocation()*0.5f;
float BoneLength = Joint.Transform.GetLocation().Size();
ParentJoint.Bones.Add({10, BoneLength, BoneCOM});
}
}
for (int i=0; i<TempSnapshot.BoneNames.Num(); ++i)
{
OTHER_LOG(Log, "Joint list: %s", *TempSnapshot.BoneNames[i].ToString());
}
UpdateGlobalTransform(); UpdateGlobalTransform();
GenerateCollisionCapsules(); GenerateCollisionCapsules();
if(bAutoComputeStrength) if(bAutoComputeStrength)

View File

@ -46,10 +46,16 @@ static FString GetVersionFromFString(const FString& String)
/********************************************************************************/ /********************************************************************************/
/********** POOLED ACTOR STRUCT *************************************************/ /********** POOLED ACTOR STRUCT *************************************************/
/********************************************************************************/ /********************************************************************************/
void FPooledActor::EnableActor() void FPooledActor::EnableActor(const FTransform& Transform, int32 NewIndex, FTileMeshComponent* NewTileMeshComponent)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(FPooledActor::EnableActor); TRACE_CPUPROFILER_EVENT_SCOPE(FPooledActor::EnableActor);
InUse = true; InUse = true;
GlobalTransform = Transform;
Index = NewIndex;
TileMeshComponent = NewTileMeshComponent;
TileMeshComponent->IndicesInUse.Emplace(Index);
Actor->SetActorHiddenInGame(false); Actor->SetActorHiddenInGame(false);
Actor->SetActorEnableCollision(true); Actor->SetActorEnableCollision(true);
Actor->SetActorTickEnabled(true); Actor->SetActorTickEnabled(true);
@ -65,8 +71,17 @@ void FPooledActor::EnableActor()
void FPooledActor::DisableActor() void FPooledActor::DisableActor()
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(FPooledActor::DisableActor); TRACE_CPUPROFILER_EVENT_SCOPE(FPooledActor::DisableActor);
if (TileMeshComponent)
{
if (TileMeshComponent->IndicesInUse.Num() > 0)
TileMeshComponent->IndicesInUse.RemoveSingle(Index);
}
InUse = false; InUse = false;
Actor->SetActorTransform(FTransform()); Index = -1;
TileMeshComponent = nullptr;
Actor->SetActorHiddenInGame(true); Actor->SetActorHiddenInGame(true);
Actor->SetActorEnableCollision(false); Actor->SetActorEnableCollision(false);
Actor->SetActorTickEnabled(false); Actor->SetActorTickEnabled(false);
@ -189,20 +204,32 @@ void AVegetationManager::Tick(float DeltaTime)
} }
if (!LargeMap) if (!LargeMap)
return; return;
bool FoundVehicles = CheckIfAnyVehicleInLevel(); if (!IsValid(HeroVehicle))
if (!FoundVehicles) {
return; HeroVehicle = LargeMap->GetHeroVehicle();
if (!IsValid(HeroVehicle))
UpdateVehiclesDetectionBoxes(); return;
}
HeroVehicle->UpdateDetectionBox();
TArray<FString> TilesInUse = GetTilesInUse(); TArray<FString> TilesInUse = GetTilesInUse();
if (TilesInUse.Num() == 0) if (TilesInUse.Num() == 0)
{
UE_LOG(LogCarla, Warning, TEXT("No tiles detected."));
return; return;
}
for (const FString& TileName : TilesInUse)
{
FTileData* Tile = TileCache.Find(TileName);
if (!Tile)
continue;
UpdateMaterials(Tile);
TArray<FElementsToSpawn> ElementsToSpawn = GetElementsToSpawn(Tile);
SpawnSkeletalFoliages(ElementsToSpawn);
DestroySkeletalFoliages();
}
UpdateMaterials(TilesInUse);
TArray<TPair<FFoliageBlueprint, TArray<FTransform>>> ElementsToSpawn = GetElementsToSpawn(TilesInUse);
SpawnSkeletalFoliages(ElementsToSpawn);
DestroySkeletalFoliages();
} }
/********************************************************************************/ /********************************************************************************/
@ -213,9 +240,7 @@ void AVegetationManager::AddVehicle(ACarlaWheeledVehicle* Vehicle)
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::AddVehicle); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::AddVehicle);
if (!IsValid(Vehicle)) if (!IsValid(Vehicle))
return; return;
if (VehiclesInLevel.Contains(Vehicle)) HeroVehicle = Vehicle;
return;
VehiclesInLevel.Emplace(Vehicle);
UE_LOG(LogCarla, Display, TEXT("Vehicle added.")); UE_LOG(LogCarla, Display, TEXT("Vehicle added."));
} }
@ -224,9 +249,7 @@ void AVegetationManager::RemoveVehicle(ACarlaWheeledVehicle* Vehicle)
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::RemoveVehicle); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::RemoveVehicle);
if (!IsValid(Vehicle)) if (!IsValid(Vehicle))
return; return;
if (!VehiclesInLevel.Contains(Vehicle)) HeroVehicle = nullptr;
return;
VehiclesInLevel.RemoveSingle(Vehicle);
UE_LOG(LogCarla, Display, TEXT("Vehicle removed.")); UE_LOG(LogCarla, Display, TEXT("Vehicle removed."));
} }
@ -245,6 +268,8 @@ void AVegetationManager::CreateOrUpdateTileCache(ULevel* InLevel)
TileData.InstancedFoliageActor = InstancedFoliageActor; TileData.InstancedFoliageActor = InstancedFoliageActor;
break; break;
} }
if (!IsValid(TileData.InstancedFoliageActor))
return;
for (AActor* Actor : InLevel->Actors) for (AActor* Actor : InLevel->Actors)
{ {
@ -254,18 +279,17 @@ void AVegetationManager::CreateOrUpdateTileCache(ULevel* InLevel)
TileData.ProceduralFoliageVolume = ProceduralFoliageVolume; TileData.ProceduralFoliageVolume = ProceduralFoliageVolume;
break; break;
} }
if (!IsValid(TileData.ProceduralFoliageVolume))
return;
const FString TileName = TileData.InstancedFoliageActor->GetLevel()->GetOuter()->GetName(); const FString TileName = TileData.InstancedFoliageActor->GetLevel()->GetOuter()->GetName();
FTileData* ExistingTileData = TileCache.Find(TileName); FTileData* ExistingTileData = TileCache.Find(TileName);
if (ExistingTileData) if (ExistingTileData)
{ {
ExistingTileData->InstancedFoliageActor = TileData.InstancedFoliageActor; ExistingTileData->InstancedFoliageActor = TileData.InstancedFoliageActor;
ExistingTileData->ProceduralFoliageVolume = TileData.ProceduralFoliageVolume; ExistingTileData->ProceduralFoliageVolume = TileData.ProceduralFoliageVolume;
for (FTileMeshComponent& Element : ExistingTileData->TileMeshesCache)
{
Element.InstancedStaticMeshComponent = nullptr;
Element.IndicesInUse.Empty();
}
ExistingTileData->TileMeshesCache.Empty(); ExistingTileData->TileMeshesCache.Empty();
ExistingTileData->MaterialInstanceDynamicCache.Empty();
SetTileDataInternals(*ExistingTileData); SetTileDataInternals(*ExistingTileData);
} }
else else
@ -273,7 +297,6 @@ void AVegetationManager::CreateOrUpdateTileCache(ULevel* InLevel)
SetTileDataInternals(TileData); SetTileDataInternals(TileData);
TileCache.Emplace(TileName, TileData); TileCache.Emplace(TileName, TileData);
} }
} }
void AVegetationManager::SetTileDataInternals(FTileData& TileData) void AVegetationManager::SetTileDataInternals(FTileData& TileData)
@ -316,7 +339,8 @@ void AVegetationManager::SetMaterialCache(FTileData& TileData)
if (TileData.MaterialInstanceDynamicCache.Num() > 0) if (TileData.MaterialInstanceDynamicCache.Num() > 0)
TileData.MaterialInstanceDynamicCache.Empty(); TileData.MaterialInstanceDynamicCache.Empty();
const float Distance = VehiclesInLevel.Last()->DetectionSize * 2.0f; #define MATERIAL_HIDE_DISTANCE 500.0f
const float Distance = MATERIAL_HIDE_DISTANCE;
for (FTileMeshComponent& Element : TileData.TileMeshesCache) for (FTileMeshComponent& Element : TileData.TileMeshesCache)
{ {
UInstancedStaticMeshComponent* Mesh = Element.InstancedStaticMeshComponent; UInstancedStaticMeshComponent* Mesh = Element.InstancedStaticMeshComponent;
@ -368,7 +392,7 @@ void AVegetationManager::UpdateFoliageBlueprintCache(ULevel* InLevel)
if (!NewFoliageBlueprint.IsValid()) if (!NewFoliageBlueprint.IsValid())
{ {
UE_LOG(LogCarla, Error, TEXT("Blueprint %s was invalid."), *NewFoliageBlueprint.BPFullClassName); UE_LOG(LogCarla, Warning, TEXT("Blueprint %s was invalid."), *NewFoliageBlueprint.BPFullClassName);
} }
else else
{ {
@ -384,7 +408,7 @@ void AVegetationManager::FreeTileCache(ULevel* InLevel)
{ {
if (!IsValid(InLevel)) if (!IsValid(InLevel))
return; return;
FTileData TileData {}; AInstancedFoliageActor* TileInstancedFoliageActor = nullptr;
for (AActor* Actor : InLevel->Actors) for (AActor* Actor : InLevel->Actors)
{ {
if (!IsValid(Actor)) if (!IsValid(Actor))
@ -392,12 +416,12 @@ void AVegetationManager::FreeTileCache(ULevel* InLevel)
AInstancedFoliageActor* InstancedFoliageActor = Cast<AInstancedFoliageActor>(Actor); AInstancedFoliageActor* InstancedFoliageActor = Cast<AInstancedFoliageActor>(Actor);
if (!IsValid(InstancedFoliageActor)) if (!IsValid(InstancedFoliageActor))
continue; continue;
TileData.InstancedFoliageActor = InstancedFoliageActor; TileInstancedFoliageActor = InstancedFoliageActor;
break; break;
} }
if (TileData.InstancedFoliageActor == nullptr) if (!IsValid(TileInstancedFoliageActor))
return; return;
const FString TileName = TileData.InstancedFoliageActor->GetLevel()->GetOuter()->GetName(); const FString TileName = TileInstancedFoliageActor->GetLevel()->GetOuter()->GetName();
FTileData* ExistingTileData = TileCache.Find(TileName); FTileData* ExistingTileData = TileCache.Find(TileName);
if (ExistingTileData) if (ExistingTileData)
{ {
@ -407,6 +431,9 @@ void AVegetationManager::FreeTileCache(ULevel* InLevel)
Element.IndicesInUse.Empty(); Element.IndicesInUse.Empty();
} }
ExistingTileData->TileMeshesCache.Empty(); ExistingTileData->TileMeshesCache.Empty();
ExistingTileData->InstancedFoliageActor = nullptr;
ExistingTileData->ProceduralFoliageVolume = nullptr;
TileCache.Remove(TileName); TileCache.Remove(TileName);
} }
} }
@ -414,100 +441,83 @@ void AVegetationManager::FreeTileCache(ULevel* InLevel)
/********************************************************************************/ /********************************************************************************/
/********** TICK ****************************************************************/ /********** TICK ****************************************************************/
/********************************************************************************/ /********************************************************************************/
void AVegetationManager::UpdateVehiclesDetectionBoxes() void AVegetationManager::UpdateMaterials(FTileData* Tile)
{
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::UpdateVehiclesDetectionBoxes);
for (ACarlaWheeledVehicle* Vehicle : VehiclesInLevel)
Vehicle->UpdateDetectionBox();
}
void AVegetationManager::UpdateMaterials(TArray<FString>& Tiles)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::UpdateMaterials); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::UpdateMaterials);
const FLinearColor Position = VehiclesInLevel.Last()->GetActorLocation(); const FTransform GlobalTransform = LargeMap->LocalToGlobalTransform(HeroVehicle->GetActorTransform());
for (const FString& TileName : Tiles) const FLinearColor Position = GlobalTransform.GetLocation();
{ Tile->UpdateMaterialCache(Position, DebugMaterials);
FTileData* TileData = TileCache.Find(TileName);
if (!TileData)
continue;
TileData->UpdateMaterialCache(Position, DebugMaterials);
}
} }
TArray<TPair<FFoliageBlueprint, TArray<FTransform>>> AVegetationManager::GetElementsToSpawn(const TArray<FString>& Tiles) TArray<FElementsToSpawn> AVegetationManager::GetElementsToSpawn(FTileData* Tile)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::GetElementsToSpawn); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::GetElementsToSpawn);
TArray<TPair<FFoliageBlueprint, TArray<FTransform>>> Results; TArray<FElementsToSpawn> Results;
for (const FString& TileKey : Tiles) int32 i = -1;
for (FTileMeshComponent& Element : Tile->TileMeshesCache)
{ {
FTileData* Tile = TileCache.Find(TileKey); TRACE_CPUPROFILER_EVENT_SCOPE(Update Foliage Usage);
if (!Tile) ++i;
UInstancedStaticMeshComponent* InstancedStaticMeshComponent = Element.InstancedStaticMeshComponent;
const FString Path = InstancedStaticMeshComponent->GetStaticMesh()->GetPathName();
FFoliageBlueprint* BP = FoliageBlueprintCache.Find(Path);
if (!BP)
continue;
TArray<int32> Indices = HeroVehicle->GetFoliageInstancesCloseToVehicle(InstancedStaticMeshComponent);
if (Indices.Num() == 0)
continue; continue;
for (FTileMeshComponent& Element : Tile->TileMeshesCache)
{
TRACE_CPUPROFILER_EVENT_SCOPE(Update Foliage Usage);
UInstancedStaticMeshComponent* InstancedStaticMeshComponent = Element.InstancedStaticMeshComponent;
const FString Path = InstancedStaticMeshComponent->GetStaticMesh()->GetPathName();
FFoliageBlueprint* BP = FoliageBlueprintCache.Find(Path);
if (!BP)
continue;
TArray<int32> Indices = VehiclesInLevel.Last()->GetFoliageInstancesCloseToVehicle(InstancedStaticMeshComponent);
if (Indices.Num() == 0)
continue;
TArray<int32> NewIndices; TArray<int32> NewIndices;
for (int32 Index : Indices) for (int32 Index : Indices)
{ {
if (Element.IndicesInUse.Contains(Index)) if (Element.IndicesInUse.Contains(Index))
continue; continue;
NewIndices.Emplace(Index); NewIndices.Emplace(Index);
}
Element.IndicesInUse = Indices;
TPair<FFoliageBlueprint, TArray<FTransform>> NewElement {};
NewElement.Key = *BP;
TArray<FTransform> Transforms;
for (int32 Index : NewIndices)
{
FTransform Transform;
InstancedStaticMeshComponent->GetInstanceTransform(Index, Transform, true);
FTransform GlobalTransform = LargeMap->LocalToGlobalTransform(Transform);
Transforms.Emplace(GlobalTransform);
}
if (Transforms.Num() > 0)
{
NewElement.Value = Transforms;
Results.Emplace(NewElement);
}
} }
FElementsToSpawn NewElement {};
NewElement.TileMeshComponent = &Tile->TileMeshesCache[i];
NewElement.BP = *BP;
for (int32 Index : NewIndices)
{
FTransform Transform;
InstancedStaticMeshComponent->GetInstanceTransform(Index, Transform, true);
FTransform GlobalTransform = LargeMap->LocalToGlobalTransform(Transform);
NewElement.TransformIndex.Emplace(TPair<FTransform, int32>(GlobalTransform, Index));
}
if (NewElement.TransformIndex.Num() > 0)
Results.Emplace(NewElement);
} }
return Results; return Results;
} }
void AVegetationManager::SpawnSkeletalFoliages(TArray<TPair<FFoliageBlueprint, TArray<FTransform>>>& ElementsToSpawn) void AVegetationManager::SpawnSkeletalFoliages(TArray<FElementsToSpawn>& ElementsToSpawn)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::SpawnSkeletalFoliages); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::SpawnSkeletalFoliages);
for (TPair<FFoliageBlueprint, TArray<FTransform>>& Element : ElementsToSpawn) for (FElementsToSpawn& Element : ElementsToSpawn)
{ {
FFoliageBlueprint BP = Element.Key; TArray<FPooledActor>* Pool = ActorPool.Find(Element.BP.BPFullClassName);
TArray<FPooledActor>* Pool = ActorPool.Find(BP.BPFullClassName); if (Pool == nullptr)
for (const FTransform& Transform : Element.Value) continue;
for (const TPair<FTransform, int32>& TransformIndex : Element.TransformIndex)
{ {
bool Ok = EnableActorFromPool(Transform, *Pool); const FTransform& Transform = TransformIndex.Key;
int32 Index = TransformIndex.Value;
if (Element.TileMeshComponent->IndicesInUse.Contains(Index))
continue;
bool Ok = EnableActorFromPool(Transform, Index, Element.TileMeshComponent, *Pool);
if (Ok) if (Ok)
{ {
UE_LOG(LogCarla, Display, TEXT("Pooled actor: %s"), *BP.BPFullClassName);
} }
else else
{ {
FPooledActor NewElement; FPooledActor NewElement;
NewElement.GlobalTransform = Transform; NewElement.Actor = CreateFoliage(Element.BP, {});
FTransform LocalTransform = LargeMap->GlobalToLocalTransform(Transform);
NewElement.Actor = CreateFoliage(BP, LocalTransform);
if (IsValid(NewElement.Actor)) if (IsValid(NewElement.Actor))
{ {
NewElement.EnableActor(); NewElement.EnableActor(Transform, Index, Element.TileMeshComponent);
Pool->Emplace(NewElement); Pool->Emplace(NewElement);
UE_LOG(LogCarla, Display, TEXT("Created actor: %s"), *BP.BPFullClassName);
} }
} }
} }
@ -525,31 +535,27 @@ void AVegetationManager::DestroySkeletalFoliages()
if (!Actor.InUse) if (!Actor.InUse)
continue; continue;
const FVector Location = Actor.GlobalTransform.GetLocation(); const FVector Location = Actor.GlobalTransform.GetLocation();
if (!VehiclesInLevel.Last()->IsInVehicleRange(Location)) if (!HeroVehicle->IsInVehicleRange(Location))
{ {
Actor.DisableActor(); Actor.DisableActor();
UE_LOG(LogCarla, Display, TEXT("Disabled Actor"));
} }
} }
} }
} }
bool AVegetationManager::EnableActorFromPool(const FTransform& Transform, TArray<FPooledActor>& Pool) bool AVegetationManager::EnableActorFromPool(const FTransform& Transform, int32 Index, FTileMeshComponent* TileMeshComponent, TArray<FPooledActor>& Pool)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::EnableActorFromPool); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::EnableActorFromPool);
for (FPooledActor& PooledActor : Pool) for (FPooledActor& PooledActor : Pool)
{ {
if (PooledActor.InUse) if (PooledActor.InUse)
continue; continue;
PooledActor.GlobalTransform = Transform; PooledActor.EnableActor(Transform, Index, TileMeshComponent);
FTransform LocalTransform = Transform; PooledActor.Actor->SetActorLocationAndRotation(Transform.GetLocation(), Transform.Rotator(), true, nullptr, ETeleportType::ResetPhysics);
LocalTransform = LargeMap->GlobalToLocalTransform(Transform);
PooledActor.EnableActor();
PooledActor.Actor->SetActorLocationAndRotation(LocalTransform.GetLocation(), LocalTransform.Rotator(), true, nullptr, ETeleportType::ResetPhysics);
if (SpawnScale <= 1.01f && SpawnScale >= 0.99f) if (SpawnScale <= 1.01f && SpawnScale >= 0.99f)
PooledActor.Actor->SetActorScale3D(LocalTransform.GetScale3D()); PooledActor.Actor->SetActorScale3D(Transform.GetScale3D());
else else
PooledActor.Actor->SetActorScale3D({SpawnScale, SpawnScale, SpawnScale}); PooledActor.Actor->SetActorScale3D({SpawnScale, SpawnScale, SpawnScale});
return true; return true;
} }
return false; return false;
@ -611,12 +617,6 @@ void AVegetationManager::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorl
FreeTileCache(InLevel); FreeTileCache(InLevel);
} }
bool AVegetationManager::CheckIfAnyVehicleInLevel() const
{
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::CheckIfAnyVehicleInLevel);
return VehiclesInLevel.Num() > 0;
}
bool AVegetationManager::IsFoliageTypeEnabled(const FString& Path) const bool AVegetationManager::IsFoliageTypeEnabled(const FString& Path) const
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::IsFoliageTypeEnabled); TRACE_CPUPROFILER_EVENT_SCOPE(AVegetationManager::IsFoliageTypeEnabled);
@ -675,18 +675,12 @@ TArray<FString> AVegetationManager::GetTilesInUse()
continue; continue;
const FBox Box = Procedural->ProceduralComponent->GetBounds(); const FBox Box = Procedural->ProceduralComponent->GetBounds();
if (!Box.IsValid) if (!Box.IsValid)
continue; continue;
if (Box.IsInside(HeroVehicle->GetActorLocation()))
for (ACarlaWheeledVehicle* Vehicle : VehiclesInLevel)
{
if (!IsValid(Vehicle))
continue;
if (Box.IsInside(Vehicle->GetActorLocation()))
{ {
Results.Emplace(Element.Key); Results.Emplace(Element.Key);
break; break;
} }
}
} }
return Results; return Results;
} }

View File

@ -60,11 +60,22 @@ struct FPooledActor
bool InUse { false }; bool InUse { false };
AActor* Actor { nullptr }; AActor* Actor { nullptr };
FTransform GlobalTransform {FTransform()}; FTransform GlobalTransform {FTransform()};
int32 Index {-1};
FTileMeshComponent* TileMeshComponent {nullptr};
void EnableActor(); void EnableActor(const FTransform& Transform, int32 NewIndex, FTileMeshComponent* NewTileMeshComponent);
void DisableActor(); void DisableActor();
}; };
USTRUCT()
struct FElementsToSpawn
{
GENERATED_BODY()
FTileMeshComponent* TileMeshComponent;
FFoliageBlueprint BP;
TArray<TPair<FTransform, int32>> TransformIndex;
};
UCLASS() UCLASS()
class CARLA_API AVegetationManager : public AActor class CARLA_API AVegetationManager : public AActor
{ {
@ -107,17 +118,15 @@ protected:
private: private:
bool IsFoliageTypeEnabled(const FString& Path) const; bool IsFoliageTypeEnabled(const FString& Path) const;
bool CheckIfAnyVehicleInLevel() const;
bool CheckForNewTiles() const; bool CheckForNewTiles() const;
TArray<FString> GetTilesInUse(); TArray<FString> GetTilesInUse();
void UpdateVehiclesDetectionBoxes(); void UpdateMaterials(FTileData* Tile);
void UpdateMaterials(TArray<FString>& Tiles); TArray<FElementsToSpawn> GetElementsToSpawn(FTileData* Tile);
TArray<TPair<FFoliageBlueprint, TArray<FTransform>>> GetElementsToSpawn(const TArray<FString>& Tiles); void SpawnSkeletalFoliages(TArray<FElementsToSpawn>& ElementsToSpawn);
void SpawnSkeletalFoliages(TArray<TPair<FFoliageBlueprint, TArray<FTransform>>>& ElementsToSpawn);
void DestroySkeletalFoliages(); void DestroySkeletalFoliages();
bool EnableActorFromPool(const FTransform& Transform, TArray<FPooledActor>& Pool); bool EnableActorFromPool(const FTransform& Transform, int32 Index, FTileMeshComponent* TileMeshComponent, TArray<FPooledActor>& Pool);
void CreateOrUpdateTileCache(ULevel* InLevel); void CreateOrUpdateTileCache(ULevel* InLevel);
void UpdateFoliageBlueprintCache(ULevel* InLevel); void UpdateFoliageBlueprintCache(ULevel* InLevel);
@ -138,7 +147,7 @@ private:
private: private:
//Actors //Actors
ALargeMapManager* LargeMap {nullptr}; ALargeMapManager* LargeMap {nullptr};
TArray<ACarlaWheeledVehicle*> VehiclesInLevel {}; ACarlaWheeledVehicle* HeroVehicle {nullptr};
//Caches //Caches
TMap<FString, FFoliageBlueprint> FoliageBlueprintCache {}; TMap<FString, FFoliageBlueprint> FoliageBlueprintCache {};
TMap<FString, FTileData> TileCache {}; TMap<FString, FTileData> TileCache {};

View File

@ -205,26 +205,19 @@ void ACarlaWheeledVehicle::BeginPlay()
bool ACarlaWheeledVehicle::IsInVehicleRange(const FVector& Location) const bool ACarlaWheeledVehicle::IsInVehicleRange(const FVector& Location) const
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(ACarlaWheeledVehicle::IsInVehicleRange); TRACE_CPUPROFILER_EVENT_SCOPE(ACarlaWheeledVehicle::IsInVehicleRange);
float Distance = 0.0f; return FoliageBoundingBox.IsInside(Location);
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(GetWorld());
if (LargeMap)
{
FTransform GlobalTransform = LargeMap->LocalToGlobalTransform(GetActorTransform());
Distance = FVector::Distance(Location, GlobalTransform.GetLocation());
}
else
{
Distance = FVector::Distance(Location, GetActorTransform().GetLocation());
}
return Distance < DetectionSize * 10.0f;
} }
void ACarlaWheeledVehicle::UpdateDetectionBox() void ACarlaWheeledVehicle::UpdateDetectionBox()
{ {
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(GetWorld());
if (!IsValid(LargeMap))
return;
FTransform GlobalTransform = LargeMap->LocalToGlobalTransform(GetActorTransform());
const FVector Vec { DetectionSize, DetectionSize, DetectionSize}; const FVector Vec { DetectionSize, DetectionSize, DetectionSize};
FBox Box = FBox(-Vec, Vec); FBox Box = FBox(-Vec, Vec);
FoliageBoundingBox = Box.TransformBy(GetActorTransform()); FoliageBoundingBox = Box.TransformBy(GlobalTransform);
} }
const TArray<int32> ACarlaWheeledVehicle::GetFoliageInstancesCloseToVehicle(const UInstancedStaticMeshComponent* Component) const const TArray<int32> ACarlaWheeledVehicle::GetFoliageInstancesCloseToVehicle(const UInstancedStaticMeshComponent* Component) const
@ -937,8 +930,8 @@ FVector ACarlaWheeledVehicle::GetVelocity() const
void ACarlaWheeledVehicle::EndPlay(const EEndPlayReason::Type EndPlayReason) void ACarlaWheeledVehicle::EndPlay(const EEndPlayReason::Type EndPlayReason)
{ {
ShowDebugTelemetry(false); ShowDebugTelemetry(false);
RemoveReferenceToManager();
Super::EndPlay(EndPlayReason); Super::EndPlay(EndPlayReason);
RemoveReferenceToManager();
} }
void ACarlaWheeledVehicle::OpenDoor(const EVehicleDoor DoorIdx) { void ACarlaWheeledVehicle::OpenDoor(const EVehicleDoor DoorIdx) {

View File

@ -354,7 +354,7 @@ private:
public: public:
UPROPERTY(Category = "CARLA Wheeled Vehicle", EditDefaultsOnly) UPROPERTY(Category = "CARLA Wheeled Vehicle", EditDefaultsOnly)
float DetectionSize { 200.0f }; float DetectionSize { 500.0f };
UPROPERTY(Category = "CARLA Wheeled Vehicle", VisibleAnywhere, BlueprintReadOnly) UPROPERTY(Category = "CARLA Wheeled Vehicle", VisibleAnywhere, BlueprintReadOnly)
FBox FoliageBoundingBox; FBox FoliageBoundingBox;