Fix #15 Implement area detection

This commit is contained in:
nsubiron 2017-05-01 02:29:36 +02:00
parent a9f0049e03
commit 21528cf10f
15 changed files with 527 additions and 83 deletions

View File

@ -1,7 +1,7 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "0.2.1",
"VersionName": "0.2.2",
"FriendlyName": "CARLA",
"Description": "",
"Category": "Science",

View File

@ -4,6 +4,12 @@
#include "CityMapGenerator.h"
#include "MapGen/GraphGenerator.h"
#include "MapGen/RoadMap.h"
#include "Tagger.h"
#include "Components/InstancedStaticMeshComponent.h"
#include "Engine/World.h"
#include "Paths.h"
#include <algorithm>
@ -16,7 +22,10 @@
// =============================================================================
ACityMapGenerator::ACityMapGenerator(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) {}
: Super(ObjectInitializer)
{
RoadMap = ObjectInitializer.CreateDefaultSubobject<URoadMap>(this, TEXT("RoadMap"));
}
ACityMapGenerator::~ACityMapGenerator() {}
@ -24,15 +33,31 @@ ACityMapGenerator::~ACityMapGenerator() {}
// -- Map construction and update related methods ------------------------------
// =============================================================================
void ACityMapGenerator::UpdateMap() {
void ACityMapGenerator::BeginPlay()
{
Super::BeginPlay();
// We definitively need the map at this point.
check(RoadMap != nullptr);
if (!RoadMap->IsValid()) {
GenerateRoadMap();
}
}
void ACityMapGenerator::UpdateMap()
{
UpdateSeeds();
GenerateGraph();
if (bGenerateRoads) {
GenerateRoads();
}
if (bGenerateRoadMap) {
GenerateRoadMap();
}
}
void ACityMapGenerator::UpdateSeeds() {
void ACityMapGenerator::UpdateSeeds()
{
if (!bUseFixedSeed) {
bUseMultipleFixedSeeds = false;
FRandomStream randomStream;
@ -44,7 +69,8 @@ void ACityMapGenerator::UpdateSeeds() {
}
}
void ACityMapGenerator::GenerateGraph() {
void ACityMapGenerator::GenerateGraph()
{
if ((MapSizeX < 5u) || (MapSizeY < 5u)) {
MapSizeX = 5u;
MapSizeY = 5u;
@ -87,7 +113,8 @@ void ACityMapGenerator::GenerateGraph() {
#endif // CARLA_ROAD_GENERATOR_EXTRA_LOG
}
void ACityMapGenerator::GenerateRoads() {
void ACityMapGenerator::GenerateRoads()
{
check(Dcel != nullptr);
using Graph = MapGen::DoublyConnectedEdgeList;
const Graph &graph = *Dcel;
@ -157,3 +184,105 @@ void ACityMapGenerator::GenerateRoads() {
#undef ADD_INTERSECTION
}
// Find first component of type road (checking at its stencil value).
static bool LineTrace(
UWorld *World,
const FVector &Start,
const FVector &End,
FHitResult &HitResult)
{
TArray <FHitResult> OutHits;
static FName TraceTag = FName(TEXT("RoadTrace"));
const bool Success = World->LineTraceMultiByObjectType(
OutHits,
Start,
End,
FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldDynamic),
FCollisionQueryParams(TraceTag, true));
if (Success) {
for (FHitResult &Item : OutHits) {
if (Item.Component->CustomDepthStencilValue == static_cast<uint8>(CityObjectLabel::Roads)) {
HitResult = Item;
return true;
}
}
}
return false;
}
void ACityMapGenerator::GenerateRoadMap()
{
UE_LOG(LogCarla, Log, TEXT("Generating road map..."));
auto World = GetWorld();
check(GetWorld() != nullptr);
check(RoadMap != nullptr);
ATagger::TagActorsInLevel(*GetWorld()); // We need the tags.
const float IntersectionSize = CityMapMeshTag::GetRoadIntersectionSize();
const uint32 Margin = IntersectionSize / 2u;
const float Offset = GetMapScale() * Margin;
const float CmPerPixel = GetMapScale() / static_cast<float>(PixelsPerMapUnit);
const uint32 SizeX = PixelsPerMapUnit * (MapSizeX + 2u * Margin);
const uint32 SizeY = PixelsPerMapUnit * (MapSizeY + 2u * Margin);
const FTransform &ActorTransform = GetActorTransform();
RoadMap->RoadMap.Empty();
for (uint32 PixelY = 0u; PixelY < SizeY; ++PixelY) {
for (uint32 PixelX = 0u; PixelX < SizeX; ++PixelX) {
const float X = static_cast<float>(PixelX) * CmPerPixel - Offset;
const float Y = static_cast<float>(PixelY) * CmPerPixel - Offset;
const FVector Start = ActorTransform.TransformPosition(FVector(X, Y, 50.0f));
const FVector End = ActorTransform.TransformPosition(FVector(X, Y, -50.0f));
bool Success = false;
// Do the ray tracing.
FHitResult Hit;
if (LineTrace(World, Start, End, Hit)) {
auto InstancedStaticMeshComponent = Cast<UInstancedStaticMeshComponent>(Hit.Component.Get());
if (InstancedStaticMeshComponent == nullptr) {
UE_LOG(LogCarla, Error, TEXT("Road component is not UInstancedStaticMeshComponent"));
} else {
FTransform InstanceTransform;
if (!InstancedStaticMeshComponent->GetInstanceTransform(Hit.Item, InstanceTransform, true)) {
UE_LOG(LogCarla, Error, TEXT("Failed to get instance's transform"));
} else {
RoadMap->AppendPixel(
GetTag(*InstancedStaticMeshComponent->GetStaticMesh()),
InstanceTransform);
Success = true;
}
}
}
if (!Success) {
RoadMap->AppendEmptyPixel();
}
}
}
const FTransform FinalTransform(
ActorTransform.GetRotation(),
ActorTransform.GetTranslation() - FVector(Offset, Offset, 0.0f),
ActorTransform.GetScale3D());
RoadMap->Set(SizeX, SizeY, 1.0f / CmPerPixel, FinalTransform.Inverse());
UE_LOG(LogCarla, Log, TEXT("Generated road map %dx%d (%d)"), RoadMap->GetWidth(), RoadMap->GetHeight(), RoadMap->RoadMap.Num());
if (!RoadMap->IsValid()) {
UE_LOG(LogCarla, Error, TEXT("Error generating road map"));
return;
}
if (bSaveRoadMapToDisk) {
const FString MapName = World->GetMapName() + TEXT(".png");
const FString FilePath = FPaths::Combine(FPaths::GameSavedDir(), MapName);
RoadMap->SaveAsPNG(FilePath);
}
}

View File

@ -7,10 +7,12 @@
#include "MapGen/GraphParser.h"
#include "CityMapGenerator.generated.h"
class URoadMap;
/// Generates a random city using the meshes provided.
///
/// @note At this point it only generates roads and sidewalks.
UCLASS(HideCategories=(Rendering, Input))
UCLASS(HideCategories=(Input))
class CARLA_API ACityMapGenerator : public ACityMapMeshHolder
{
GENERATED_BODY()
@ -30,8 +32,17 @@ public:
/// @name Map construction and update related methods
// ===========================================================================
/// @{
public:
URoadMap *GetRoadMap()
{
return RoadMap;
}
private:
virtual void BeginPlay() override;
/// Update the map based on the current settings.
virtual void UpdateMap() override;
@ -44,6 +55,9 @@ private:
/// Add the road meshes to the scene based on the current DCEL.
void GenerateRoads();
/// Generate the road map image and save to disk if requested.
void GenerateRoadMap();
/// @}
// ===========================================================================
/// @name Map generation properties
@ -79,6 +93,25 @@ private:
UPROPERTY(Category = "Map Generation", EditAnywhere, AdvancedDisplay, meta = (EditCondition = bUseMultipleFixedSeeds))
int32 RoadPlanningSeed;
/// @}
// ===========================================================================
/// @name Road Map
// ===========================================================================
/// @{
private:
UPROPERTY(Category = "Road Map", EditAnywhere)
bool bGenerateRoadMap = false;
UPROPERTY(Category = "Road Map", EditAnywhere, meta = (ClampMin = "1", ClampMax = "500", EditCondition = bGenerateRoadMap))
uint32 PixelsPerMapUnit = 50u;
UPROPERTY(Category = "Road Map", EditAnywhere, meta = (EditCondition = bGenerateRoadMap))
bool bSaveRoadMapToDisk = true;
UPROPERTY(Category = "Road Map", VisibleAnywhere, AdvancedDisplay)
URoadMap *RoadMap;
/// @}
// ===========================================================================
/// @name Other private members

View File

@ -47,7 +47,9 @@ private:
CarlaGameControllerBase *GameController;
UPROPERTY()
UCarlaGameInstance *GameInstance;
UPROPERTY()
AController *PlayerController;
};

View File

@ -3,10 +3,13 @@
#include "Carla.h"
#include "CarlaVehicleController.h"
#include "SceneCaptureCamera.h"
#include "Camera/CameraComponent.h"
#include "Components/BoxComponent.h"
#include "EngineUtils.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/SpringArmComponent.h"
#include "SceneCaptureCamera.h"
#include "WheeledVehicle.h"
#include "WheeledVehicleMovementComponent.h"
@ -82,6 +85,14 @@ void ACarlaVehicleController::Possess(APawn *aPawn)
// Get vehicle movement component.
MovementComponent = WheeledVehicle->GetVehicleMovementComponent();
check(MovementComponent != nullptr);
// Get vehicle box component.
TArray<UBoxComponent *> BoundingBoxes;
WheeledVehicle->GetComponents<UBoxComponent>(BoundingBoxes);
if (BoundingBoxes.Num() > 0) {
VehicleBounds = BoundingBoxes[0];
} else {
UE_LOG(LogCarla, Error, TEXT("Pawn is missing the bounding box!"));
}
// Get custom player state.
CarlaPlayerState = Cast<ACarlaPlayerState>(PlayerState);
check(CarlaPlayerState != nullptr);
@ -111,6 +122,11 @@ void ACarlaVehicleController::BeginPlay()
Image.PostProcessEffect = Camera->GetPostProcessEffect();
}
}
TActorIterator<ACityMapGenerator> It(GetWorld());
if (It) {
RoadMap = It->GetRoadMap();
}
}
void ACarlaVehicleController::Tick(float DeltaTime)
@ -126,7 +142,7 @@ void ACarlaVehicleController::Tick(float DeltaTime)
const FVector CurrentSpeed = CarlaPlayerState->ForwardSpeed * CarlaPlayerState->Orientation;
CarlaPlayerState->Acceleration = (CurrentSpeed - PreviousSpeed) / DeltaTime;
CarlaPlayerState->CurrentGear = GetVehicleCurrentGear();
/// @todo #15 Set intersection factors.
IntersectPlayerWithRoadMap();
const auto NumberOfCameras = SceneCaptureCameras.Num();
check(NumberOfCameras == CarlaPlayerState->Images.Num());
for (auto i = 0; i < NumberOfCameras; ++i) {
@ -283,3 +299,29 @@ void ACarlaVehicleController::ChangeCameraRight(float Value)
Rotation.Yaw -= Value;
SpringArm->SetRelativeRotation(Rotation);
}
// =============================================================================
// -- Other --------------------------------------------------------------------
// =============================================================================
void ACarlaVehicleController::IntersectPlayerWithRoadMap()
{
if (RoadMap == nullptr) {
UE_LOG(LogCarla, Error, TEXT("Controller doesn't have a road map"));
return;
} else if (VehicleBounds == nullptr) {
UE_LOG(LogCarla, Error, TEXT("Vehicle doesn't have a bounding box"));
return;
}
constexpr float ChecksPerCentimeter = 0.1f;
constexpr bool LeftHandDriving = false;
auto Result = RoadMap->Intersect(
GetPawn()->GetTransform(),
VehicleBounds->GetScaledBoxExtent(),
ChecksPerCentimeter,
LeftHandDriving);
CarlaPlayerState->OffRoadIntersectionFactor = Result.OffRoad;
CarlaPlayerState->OtherLaneIntersectionFactor = Result.OppositeLane;
}

View File

@ -8,7 +8,9 @@
class ACarlaHUD;
class ACarlaPlayerState;
class ASceneCaptureCamera;
class UBoxComponent;
class UCameraComponent;
class URoadMap;
class USpringArmComponent;
class UWheeledVehicleMovementComponent;
struct FCameraDescription;
@ -160,6 +162,22 @@ private:
void SetupControllerInput();
/// @}
// ===========================================================================
/// @name Other
// ===========================================================================
/// @{
public:
void SetRoadMap(URoadMap *inRoadMap)
{
RoadMap = inRoadMap;
}
private:
void IntersectPlayerWithRoadMap();
/// @}
// ===========================================================================
// -- Member variables -------------------------------------------------------
@ -181,6 +199,12 @@ private:
UPROPERTY()
TArray<ASceneCaptureCamera *> SceneCaptureCameras;
UPROPERTY()
URoadMap *RoadMap;
UPROPERTY()
UBoxComponent *VehicleBounds;
// Cast for quick access to the custom player state.
UPROPERTY()
ACarlaPlayerState *CarlaPlayerState;

View File

@ -1,28 +0,0 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#include "Carla.h"
#include "RoadMap.h"
#include "CapturedImage.h"
static FVector2D Decode(const FColor &Color);
// void RoadMap::SetCapture(FCapturedImage &inMapCapture, const FVector2D &inMapSizeInCm)
// {
// MapCapture = &inMapCapture;
// MapSizeInCm = inMapSizeInCm
// }
// bool RoadMap::IsValid() const
// {
// return ((MapCapture != nullptr) &&
// (MapCapture->BitMap.Num() > 0) &&
// (MapSizeInCm.X > 0.0f) &&
// (MapSizeInCm.Y > 0.0f));
// }
// FVector2D RoadMap::GetDirectionAt(const FVector &Location) const
// {
// check(IsValid());
// return FVector2D();
// }

View File

@ -1,29 +0,0 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#pragma once
#include "Math/Vector.h"
struct FCapturedImage;
/// Road map of the level. Contains information in 2D of which areas are road
/// and lane directions.
class CARLA_API RoadMap
{
public:
void SetCapture(
const FCapturedImage &MapCapture,
const FVector2D &Origin,
const FVector2D &MapExtent);
bool IsValid() const;
FVector2D GetDirectionAt(const FVector &Location) const;
private:
uint32 GetPixelIndexAt(const FVector2D &Location) const;
TArray<FVector2D> DirectionMap;
};

View File

@ -67,6 +67,9 @@ FVector ACityMapMeshHolder::GetTileLocation(uint32 X, uint32 Y) const
void ACityMapMeshHolder::SetStaticMesh(ECityMapMeshTag Tag, UStaticMesh *Mesh)
{
StaticMeshes[Tag] = Mesh;
if (Mesh != nullptr) {
TagMap.Add(Mesh, Tag);
}
}
UStaticMesh *ACityMapMeshHolder::GetStaticMesh(ECityMapMeshTag Tag)
@ -79,6 +82,12 @@ const UStaticMesh *ACityMapMeshHolder::GetStaticMesh(ECityMapMeshTag Tag) const
return StaticMeshes[Tag];
}
ECityMapMeshTag ACityMapMeshHolder::GetTag(const UStaticMesh &StaticMesh) const
{
const ECityMapMeshTag *Tag = TagMap.Find(&StaticMesh);
return (Tag != nullptr ? *Tag : ECityMapMeshTag::INVALID);
}
void ACityMapMeshHolder::AddInstance(ECityMapMeshTag Tag, uint32 X, uint32 Y)
{
AddInstance(Tag, FTransform(GetTileLocation(X, Y)));

View File

@ -38,6 +38,11 @@ protected:
// ===========================================================================
protected:
float GetMapScale() const
{
return MapScale;
}
/// Return the 3D world location (relative to this actor) of the given 2D
/// tile.
FVector GetTileLocation(uint32 X, uint32 Y) const;
@ -51,6 +56,9 @@ protected:
/// Return the static mesh corresponding to @a Tag.
const UStaticMesh *GetStaticMesh(ECityMapMeshTag Tag) const;
/// Return the tag corresponding to @a StaticMesh.
ECityMapMeshTag GetTag(const UStaticMesh &StaticMesh) const;
/// Add an instance of a mesh with a given tile location.
/// @param Tag The mesh' tag
/// @param X Tile coordinate X
@ -92,6 +100,9 @@ private:
UPROPERTY(Category = "Meshes", EditAnywhere)
TMap<ECityMapMeshTag, UStaticMesh *> StaticMeshes;
UPROPERTY()
TMap<UStaticMesh *, ECityMapMeshTag> TagMap;
UPROPERTY(Category = "Meshes|Debug", VisibleAnywhere)
float MapScale;

View File

@ -46,7 +46,8 @@ enum class ECityMapMeshTag : uint8
RoadXIntersection_Sidewalk3 UMETA(DisplayName = "Road: X-Intersection - Sidewalk 3"),
RoadXIntersection_LaneMarking UMETA(DisplayName = "Road: X-Intersection - Lane Marking"),
NUMBER_OF_TAGS UMETA(Hidden)
NUMBER_OF_TAGS UMETA(Hidden),
INVALID UMETA(Hidden)
};
/// Helper class for working with ECityMapMeshTag.

View File

@ -0,0 +1,134 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#include "Carla.h"
#include "RoadMap.h"
#include "HighResScreenshot.h"
static uint32 ClampFloatToUInt(const float Value, int32 Min, int32 Max)
{
return FMath::Clamp(FMath::FloorToInt(Value), Min, Max);
}
const FRoadMapPixelData &URoadMap::GetDataAt(const FVector &WorldLocation) const
{
const FVector Location = WorldToMap.TransformPosition(WorldLocation);
uint32 X = ClampFloatToUInt(PixelsPerCentimeter * Location.X, 0, Width);
uint32 Y = ClampFloatToUInt(PixelsPerCentimeter * Location.Y, 0, Height);
return GetDataAt(X, Y);
}
FRoadMapIntersectionResult URoadMap::Intersect(
const FTransform &BoxTransform,
const FVector &BoxExtent,
float ChecksPerCentimeter,
const bool LeftHandDriving) const
{
auto DirectionOfMovement = BoxTransform.GetRotation().GetForwardVector();
if (LeftHandDriving) {
DirectionOfMovement *= -1.0f;
}
uint32 CheckCount = 0u;
FRoadMapIntersectionResult Result = {0.0f, 0.0f};
const float Step = 1.0f / ChecksPerCentimeter;
for (float X = -BoxExtent.X; X < BoxExtent.X; X += Step) {
for (float Y = -BoxExtent.Y; Y < BoxExtent.Y; Y += Step) {
++CheckCount;
auto Location = BoxTransform.TransformPosition(FVector(X, Y, 0.0f));
auto &Data = GetDataAt(Location);
if (Data.bIsOffRoad) {
Result.OffRoad += 1.0f;
} else if (Data.bHasDirection &&
0.0f < FVector::DotProduct(Data.Direction, DirectionOfMovement)) {
Result.OppositeLane += 1.0f;
}
}
}
if (CheckCount > 0u) {
Result.OffRoad /= static_cast<float>(CheckCount);
Result.OppositeLane /= static_cast<float>(CheckCount);
} else {
UE_LOG(LogCarla, Warning, TEXT("URoadMap::Intersect did zero checks"));
}
return Result;
}
static FColor Encode(const FRoadMapPixelData &Data)
{
if (Data.bIsOffRoad) {
return FColor(0u, 0u, 0u, 255u);
} else if (!Data.bHasDirection) {
return FColor(255u, 255u, 255u, 255u);
} else {
// Assumes normalized direction.
auto ToColor = [](float X){
return FMath::FloorToInt(255.0 * (X + 1.0f) / 2.0f);
};
return FColor(ToColor(Data.Direction.X), ToColor(Data.Direction.Y), ToColor(Data.Direction.Z));
}
}
bool URoadMap::SaveAsPNG(const FString &Path) const
{
if (!IsValid()) {
UE_LOG(LogCarla, Error, TEXT("Cannot save invalid road map to disk"));
return false;
}
TArray<FColor> BitMap;
for (auto &Data : RoadMap) {
BitMap.Emplace(Encode(Data));
}
FIntPoint DestSize(Width, Height);
FString ResultPath;
FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig();
HighResScreenshotConfig.SaveImage(Path, BitMap, DestSize, &ResultPath);
UE_LOG(LogCarla, Log, TEXT("Saved road map to \"%s\""), *ResultPath);
return true;
}
void URoadMap::AppendPixel(ECityMapMeshTag Tag, const FTransform &Transform)
{
AppendEmptyPixel();
auto &Data = RoadMap.Last();
Data.bIsOffRoad = false;
auto Rotator = Transform.GetRotation().Rotator();
switch (Tag) {
case ECityMapMeshTag::RoadTwoLanes_LaneRight:
case ECityMapMeshTag::Road90DegTurn_Lane0:
Data.bHasDirection = true;
break;
case ECityMapMeshTag::RoadTwoLanes_LaneLeft:
case ECityMapMeshTag::Road90DegTurn_Lane1:
Rotator.Yaw += 180.0f;
Data.bHasDirection = true;
break;
case ECityMapMeshTag::Road90DegTurn_Lane2:
Rotator.Yaw += 90.0f;
Data.bHasDirection = true;
break;
case ECityMapMeshTag::Road90DegTurn_Lane3:
Rotator.Yaw += 270.0f;
Data.bHasDirection = true;
break;
}
if (Data.bHasDirection) {
FQuat Rotation(Rotator);
Data.Direction = Rotation.GetForwardVector();
}
}
void URoadMap::Set(
const uint32 inWidth,
const uint32 inHeight,
const float inPinxelsPerCentimeter,
const FTransform &inWorldToMap)
{
Width = inWidth;
Height = inHeight;
PixelsPerCentimeter = inPinxelsPerCentimeter;
WorldToMap = inWorldToMap;
}

View File

@ -0,0 +1,116 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#pragma once
#include "UObject/NoExportTypes.h"
#include "RoadMap.generated.h"
USTRUCT()
struct FRoadMapIntersectionResult
{
GENERATED_BODY()
/** Percentage of the box lying off-road */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
float OffRoad;
/** Percentage of the box invading opposite lane (wrong direction) */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
float OppositeLane;
};
USTRUCT()
struct FRoadMapPixelData
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
bool bIsOffRoad = true;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
bool bHasDirection = false;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
FVector Direction;
};
/// Road map of the level. Contains information in 2D of which areas are road
/// and lane directions.
UCLASS()
class CARLA_API URoadMap : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
bool IsValid() const
{
return ((RoadMap.Num() > 0) && (RoadMap.Num() == Height * Width));
}
uint32 GetWidth() const
{
return Width;
}
uint32 GetHeight() const
{
return Height;
}
const FRoadMapPixelData &GetDataAt(uint32 PixelX, uint32 PixelY) const
{
check(IsValid());
return RoadMap[PixelX + Height * PixelY];
}
/** Clamps value if lies outside map limits */
UFUNCTION(BlueprintCallable)
const FRoadMapPixelData &GetDataAt(const FVector &WorldLocation) const;
/** Intersect actor bounds with map.
*
* Bounds box is projected to the map and checked against it for possible
* intersections with off-road areas and opposite lanes.
*/
UFUNCTION(BlueprintCallable)
FRoadMapIntersectionResult Intersect(
const FTransform &BoxTransform,
const FVector &BoxExtent,
float ChecksPerCentimeter,
bool LeftHandDriving) const;
UFUNCTION(BlueprintCallable)
bool SaveAsPNG(const FString &Path) const;
private:
friend class ACityMapGenerator;
void AppendEmptyPixel()
{
RoadMap.AddDefaulted(1);
}
void AppendPixel(ECityMapMeshTag Tag, const FTransform &Transform);
void Set(uint32 Width, uint32 Height, float PixelsPerCentimeter, const FTransform &WorldToMap);
UPROPERTY(VisibleAnywhere)
FTransform WorldToMap;
UPROPERTY(VisibleAnywhere)
float PixelsPerCentimeter = 0.0f;
/** Width of the map in pixels */
UPROPERTY(VisibleAnywhere)
uint32 Width = 0u;
/** Height of the map in pixels */
UPROPERTY(VisibleAnywhere)
uint32 Height = 0u;
UPROPERTY()
TArray<FRoadMapPixelData> RoadMap;
};

View File

@ -9,22 +9,6 @@
#include "Components/SkeletalMeshComponent.h"
#include "PhysicsEngine/PhysicsAsset.h"
enum class CityObjectLabel : uint8
{
None = 0u,
Buildings = 1u,
Fences = 2u,
Other = 3u,
Pedestrians = 4u,
Poles = 5u,
RoadLines = 6u,
Roads = 7u,
Sidewalks = 8u,
Vegetation = 9u,
Vehicles = 10u,
Walls = 11u,
};
#ifdef CARLA_TAGGER_EXTRA_LOG
static FString GetLabelAsString(const CityObjectLabel Label)
{

View File

@ -5,6 +5,22 @@
#include "GameFramework/Actor.h"
#include "Tagger.generated.h"
enum class CityObjectLabel : uint8
{
None = 0u,
Buildings = 1u,
Fences = 2u,
Other = 3u,
Pedestrians = 4u,
Poles = 5u,
RoadLines = 6u,
Roads = 7u,
Sidewalks = 8u,
Vegetation = 9u,
Vehicles = 10u,
Walls = 11u,
};
/// Sets actors' custom depth stencil value for semantic segmentation according
/// to their meshes.
///