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:
parent
bcf3471586
commit
bc23f261e5
|
@ -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());
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {};
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue