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