81 return FColor(0u, 0u, 0u, 255u);
85 return FColor(255u, 255u, 255u, 255u);
88 auto ToColor = [](
float X){
89 return FMath::FloorToInt(256.0 * (X + PI) / (2.0f * PI)) % 256;
94 return FColor(0u, 255u, ToColor(Azimuth), 255u);
154 const FTransform &Transform,
155 const bool bInvertDirection)
157 bool bIsRoad =
false;
158 bool bHasDirection =
false;
159 FVector Direction(0.0f, 0.0f, 0.0f);
162 auto Rotator = Transform.GetRotation().Rotator();
169 case ECityMapMeshTag::RoadTwoLanes_LaneRight:
170 case ECityMapMeshTag::Road90DegTurn_Lane1:
171 case ECityMapMeshTag::RoadTIntersection_Lane1:
172 case ECityMapMeshTag::RoadTIntersection_Lane9:
173 case ECityMapMeshTag::RoadXIntersection_Lane1:
174 case ECityMapMeshTag::RoadXIntersection_Lane9:
176 bHasDirection =
true;
178 Rotator.Yaw += 180.0f;
180 case ECityMapMeshTag::RoadTwoLanes_LaneLeft:
181 case ECityMapMeshTag::Road90DegTurn_Lane0:
182 case ECityMapMeshTag::RoadTIntersection_Lane0:
183 case ECityMapMeshTag::RoadTIntersection_Lane2:
184 case ECityMapMeshTag::RoadTIntersection_Lane5:
185 case ECityMapMeshTag::RoadTIntersection_Lane8:
186 case ECityMapMeshTag::RoadXIntersection_Lane0:
187 case ECityMapMeshTag::RoadXIntersection_Lane8:
189 bHasDirection =
true;
191 case ECityMapMeshTag::Road90DegTurn_Lane9:
192 case ECityMapMeshTag::RoadTIntersection_Lane7:
193 case ECityMapMeshTag::RoadXIntersection_Lane7:
194 case ECityMapMeshTag::RoadXIntersection_Lane5:
196 bHasDirection =
true;
198 Rotator.Yaw += 90.0f;
200 case ECityMapMeshTag::Road90DegTurn_Lane7:
202 bHasDirection =
true;
204 Rotator.Yaw += 90.0f;
206 case ECityMapMeshTag::Road90DegTurn_Lane5:
208 bHasDirection =
true;
210 Rotator.Yaw += 90.0f + 35.0f;
212 case ECityMapMeshTag::Road90DegTurn_Lane3:
214 bHasDirection =
true;
216 Rotator.Yaw += 90.0f + 45.0f + 20.5f;
218 case ECityMapMeshTag::Road90DegTurn_Lane8:
219 case ECityMapMeshTag::RoadTIntersection_Lane4:
220 case ECityMapMeshTag::RoadXIntersection_Lane2:
221 case ECityMapMeshTag::RoadXIntersection_Lane4:
223 bHasDirection =
true;
225 Rotator.Yaw += 270.0f;
227 case ECityMapMeshTag::Road90DegTurn_Lane6:
229 bHasDirection =
true;
231 Rotator.Yaw += 270.0f + 50.0f;
233 case ECityMapMeshTag::Road90DegTurn_Lane4:
235 bHasDirection =
true;
237 Rotator.Yaw += 270.0f + 80.0f;
239 case ECityMapMeshTag::Road90DegTurn_Lane2:
241 bHasDirection =
true;
244 case ECityMapMeshTag::RoadTIntersection_Lane3:
245 case ECityMapMeshTag::RoadTIntersection_Lane6:
246 case ECityMapMeshTag::RoadXIntersection_Lane3:
247 case ECityMapMeshTag::RoadXIntersection_Lane6:
249 bHasDirection =
false;
254 FQuat Rotation(Rotator);
257 if (bInvertDirection) {
297 const FTransform &BoxTransform,
298 const FVector &BoxExtent,
299 float ChecksPerCentimeter)
const
301 auto DirectionOfMovement = BoxTransform.GetRotation().GetForwardVector();
302 DirectionOfMovement.Z = 0.0f;
303 uint32 CheckCount = 0u;
305 const float Step = 1.0f / ChecksPerCentimeter;
306 for (
float X = -BoxExtent.X; X < BoxExtent.X; X += Step) {
307 for (
float Y = -BoxExtent.Y; Y < BoxExtent.Y; Y += Step) {
309 auto Location = BoxTransform.TransformPosition(FVector(X, Y, 0.0f));
311 if (!Data.IsRoad()) {
313 }
else if (Data.HasDirection() &&
314 0.0f > FVector::DotProduct(Data.GetDirection(), DirectionOfMovement)) {
320 if (CheckCount > 0u) {
322 Result.
OffRoad /=
static_cast<float>(CheckCount);
326 UE_LOG(LogCarla, Warning, TEXT(
"URoadMap::Intersect did zero checks"));
336 UE_LOG(LogCarla, Error, TEXT(
"Cannot save invalid road map to disk"));
341 const FString ImagePath = FPaths::Combine(Folder, MapName + TEXT(
".png"));
343 const FString MetadataPath = FPaths::Combine(Folder, MapName + TEXT(
".txt"));
348 TUniquePtr<TImagePixelData<FColor>> PixelData = MakeUnique<TImagePixelData<FColor>>(DestSize);
359 FFormatNamedArguments Args;
360 Args.Add(
"MapName", FText::FromString(MapName));
364 Args.Add(
"Transform", FText::FromString(
WorldToMap.ToString()));
365 Args.Add(
"Offset", FText::FromString(
MapOffset.ToString()));
368 const auto Contents = FText::Format(
369 LOCTEXT(
"RoadMapMetadata",
370 "Map name = {MapName}\n"
371 "Size = {Width}x{Height} pixels\n"
372 "Density = {CmPerPixel} cm/pixel\n"
373 "World-To-Map Transform (T|R|S) = ({Transform})\n"
374 "Map Offset = ({Offset})\n"),
377 if (!FFileHelper::SaveStringToFile(Contents.ToString(), *MetadataPath)) {
378 UE_LOG(LogCarla, Error, TEXT(
"Failed to save map metadata"));
382 UE_LOG(LogCarla, Log, TEXT(
"Saved road map to \"%s\""), *ImagePath);
433 DrawDebugDirectionalArrow(
World, Location, ArrowEnd, 60.0f, Color,
true);
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)