CARLA
CityMapMeshHolder.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2 // de Barcelona (UAB).
3 //
4 // This work is licensed under the terms of the MIT license.
5 // For a copy, see <https://opensource.org/licenses/MIT>.
6 
7 #include "Carla.h"
8 #include "CityMapMeshHolder.h"
9 #include "Engine/StaticMeshActor.h"
10 #include "Components/InstancedStaticMeshComponent.h"
11 #include "Engine/StaticMesh.h"
12 #include <vector>
13 #include "Settings/CarlaSettings.h"
14 #include "Game/CarlaGameInstance.h"
15 #include "Kismet/KismetSystemLibrary.h"
16 
17 
18 using tag_size_t = std::underlying_type<ECityMapMeshTag>::type;
19 
21 
22 // =============================================================================
23 // -- Construction and update related methods ----------------------------------
24 // =============================================================================
25 
26 ACityMapMeshHolder::ACityMapMeshHolder(const FObjectInitializer& ObjectInitializer)
27  : Super(ObjectInitializer)
28 {
29  PrimaryActorTick.bCanEverTick = false;
30 
32  ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComponent"));
33  SceneRootComponent->SetMobility(EComponentMobility::Static);
34  RootComponent = SceneRootComponent;
35 
36  for (tag_size_t i = 0u; i < NUMBER_OF_TAGS; ++i) {
37  // Add static mesh holder.
39  }
40 
41 }
42 
43 /*void ACityMapMeshHolder::LayoutDetails(IDetailLayoutBuilder& DetailLayout)
44 {
45  IDetailCategoryBuilder& DetailCategory = DetailLayout.EditCategory("Rendering");
46  IDetailPropertyRow& row = DetailCategory.AddProperty("Generation", TEXT(""));
47 
48 }*/
49 
51 {
52  Super::OnConstruction(Transform);
53 
54 }
55 
57 {
58  Super::PostInitializeComponents();
59 
60  if(IsValid(GetLevel())&&!GetLevel()->IsPendingKill())
61  {
62  TArray<AActor*> roadpieces;
63  GetAttachedActors(roadpieces);
64  if(roadpieces.Num()==0)
65  {
66  UE_LOG(LogCarla, Error, TEXT("Please regenerate the road in edit mode for '%s' actor"), *UKismetSystemLibrary::GetDisplayName(this));
68  UpdateMap();
69  }
70  }
71 
72 }
73 
74 #if WITH_EDITOR
75 void ACityMapMeshHolder::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
76 {
77  Super::PostEditChangeProperty(PropertyChangedEvent);
78  if (PropertyChangedEvent.Property)
79  {
80  DeletePieces();
82  UpdateMap();
83  }
84 }
85 #endif // WITH_EDITOR
86 
87 // =============================================================================
88 // -- Other protected methods --------------------------------------------------
89 // =============================================================================
90 
91 FVector ACityMapMeshHolder::GetTileLocation(uint32 X, uint32 Y) const
92 {
93  return {X * MapScale, Y * MapScale, 0.0f};
94 }
95 
97 {
98  StaticMeshes[Tag] = Mesh;
99  if (Mesh != nullptr) {
100  TagMap.Add(Mesh, Tag);
101  }
102 }
103 
105 {
106  return StaticMeshes[Tag];
107 }
108 
110 {
111  return StaticMeshes[Tag];
112 }
113 
114 ECityMapMeshTag ACityMapMeshHolder::GetTag(const UStaticMesh &StaticMesh) const
115 {
116  const ECityMapMeshTag *Tag = TagMap.Find(&StaticMesh);
117  return (Tag != nullptr ? *Tag : ECityMapMeshTag::INVALID);
118 }
119 
121 {
122  AddInstance(Tag, FTransform(GetTileLocation(X, Y)));
123 }
124 
125 void ACityMapMeshHolder::AddInstance(ECityMapMeshTag Tag, uint32 X, uint32 Y, float Angle)
126 {
127  const FQuat rotation(FVector(0.0f, 0.0f, 1.0f), Angle);
128  const FVector location = GetTileLocation(X, Y);
129  AddInstance(Tag, FTransform(rotation, location));
130 }
131 
133 {
134  FActorSpawnParameters params;
135  params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
136  FVector location = Transform.GetLocation();
137  FRotator rotation = Transform.Rotator();
138  AStaticMeshActor* StaticMeshActor = Cast<AStaticMeshActor>(GetWorld()->SpawnActor(AStaticMeshActor::StaticClass(),&location,&rotation,params));
139  StaticMeshActor->AttachToActor(this,FAttachmentTransformRules::KeepRelativeTransform);
140  StaticMeshActor->SetMobility(EComponentMobility::Static);
141  UStaticMeshComponent* staticmeshcomponent = StaticMeshActor->GetStaticMeshComponent();
142  staticmeshcomponent->SetMobility(EComponentMobility::Static);
143  staticmeshcomponent->SetStaticMesh(GetStaticMesh(Tag));
144  StaticMeshActor->Tags.Add(UCarlaSettings::CARLA_ROAD_TAG);
145  StaticMeshActor->bEnableAutoLODGeneration = true;
146 }
147 
148 // =============================================================================
149 // -- Private methods ----------------------------------------------------------
150 // =============================================================================
151 
153 
155 {
156  //this part will be deprecated: remove the instanced static mesh components
157  TArray<UInstancedStaticMeshComponent*> oldcomponents;
158  GetComponents(oldcomponents);
159  for(int32 i=0;i<oldcomponents.Num();i++)
160  {
161  oldcomponents[i]->DestroyComponent();
162  }
163 
164  TArray<AActor*> roadpieces;
165  GetAttachedActors(roadpieces);
166 
167  for(int32 i=roadpieces.Num()-1; i>=0; i--)
168  {
169  if(roadpieces[i]->ActorHasTag(UCarlaSettings::CARLA_ROAD_TAG))
170  {
171  roadpieces[i]->Destroy();
172  }
173  }
174 
175 }
176 
178 {
179  auto Tag = CityMapMeshTag::GetBaseMeshTag();
180  auto *mesh = GetStaticMesh(Tag);
181  if (mesh == nullptr) {
182  UE_LOG(
183  LogCarla,
184  Error,
185  TEXT("Cannot find mesh \"%s\" for computing tile size"),
187  MapScale = 1.0f;
188  } else {
189  FVector size = mesh->GetBoundingBox().GetSize();
190  MapScale = size.X;
191  }
192 }
193 
194 
void AddInstance(ECityMapMeshTag Tag, uint32 X, uint32 Y)
Add an instance of a mesh with a given tile location.
static FString ToString(ECityMapMeshTag Tag)
Get Tag name as FString.
static constexpr uint8 GetNumberOfTags()
Return the number of tags.
void DeletePieces()
Clear all instances of the static mesh actors.
virtual void OnConstruction(const FTransform &Transform) override
Initializes the instantiators.
static ECityMapMeshTag FromUInt(uint8 Value)
Convert an unsigned integer to a ECityMapMeshTag.
std::underlying_type< ECityMapMeshTag >::type tag_size_t
ECityMapMeshTag
Tag to identify the meshes used by the ProceduralMapGenerator.
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
void SetStaticMesh(ECityMapMeshTag Tag, UStaticMesh *Mesh)
Set the static mesh associated with Tag.
FVector GetTileLocation(uint32 X, uint32 Y) const
Return the 3D world location (relative to this actor) of the given 2D tile.
UStaticMesh * GetStaticMesh(ECityMapMeshTag Tag)
Return the static mesh corresponding to Tag.
TMap< UStaticMesh *, ECityMapMeshTag > TagMap
virtual void PostInitializeComponents() override
static constexpr tag_size_t NUMBER_OF_TAGS
static ECityMapMeshTag GetBaseMeshTag()
Return the base mesh. The base mesh defines the unit tile for map scaling.
ECityMapMeshTag GetTag(const UStaticMesh &StaticMesh) const
Return the tag corresponding to StaticMesh.
ACityMapMeshHolder(const FObjectInitializer &ObjectInitializer)
Initializes the mesh holders.
void UpdateMapScale()
Set the scale to the dimensions of the base mesh.
static const FName CARLA_ROAD_TAG
CARLA_ROAD name to tag road mesh actors.
Definition: CarlaSettings.h:60
USceneComponent * SceneRootComponent
TMap< ECityMapMeshTag, UStaticMesh * > StaticMeshes
geom::Transform Transform
Definition: rpc/Transform.h:16
virtual void UpdateMap()
Here does nothing, implement in derived classes.