diff --git a/Source/CarlaDigitalTwinsTool/Private/Generation/OpenDriveToMap.cpp b/Source/CarlaDigitalTwinsTool/Private/Generation/OpenDriveToMap.cpp index db4f1cc..8a5d17a 100644 --- a/Source/CarlaDigitalTwinsTool/Private/Generation/OpenDriveToMap.cpp +++ b/Source/CarlaDigitalTwinsTool/Private/Generation/OpenDriveToMap.cpp @@ -62,7 +62,7 @@ #include "DrawDebugHelpers.h" #include "Paths/GenerationPathsHelper.h" #include "StreetMapActor.h" - +#include "Misc/Paths.h" #if WITH_EDITOR #include "Generation/OpenDriveToMap.h" @@ -487,7 +487,14 @@ void UOpenDriveToMap::GenerateTileStandalone(){ #if PLATFORM_WINDOWS GenerateTile(); #else + + if (bSatelliteSegmentationTrees) + { + RunTreeSegmentation(); + } + GenerateTile(); + #endif UEditorLoadingAndSavingUtils::SaveDirtyPackages(true, true); UEditorLevelLibrary::SaveCurrentLevel(); @@ -797,13 +804,27 @@ void UOpenDriveToMap::GenerateAll(const boost::optional& Param { UE_LOG(LogCarlaDigitalTwinsTool, Log, TEXT("UOpenDriveToMap::GenerateAll() Generating Roads..... ")); GenerateRoadMesh(ParamCarlaMap, MinLocation, MaxLocation); + UE_LOG(LogCarlaDigitalTwinsTool, Log, TEXT("UOpenDriveToMap::GenerateAll() Generating Lane Marks..... ")); GenerateLaneMarks(ParamCarlaMap, MinLocation, MaxLocation); + // GenerateSpawnPoints(ParamCarlaMap, MinLocation, MaxLocation); + UE_LOG(LogCarlaDigitalTwinsTool, Log, TEXT("UOpenDriveToMap::GenerateAll() Generating Terrain..... ")); CreateTerrain(5,5, 64); + UE_LOG(LogCarlaDigitalTwinsTool, Log, TEXT("UOpenDriveToMap::GenerateAll() Generating Tree positions..... ")); - GenerateTreePositions(ParamCarlaMap, MinLocation, MaxLocation); + if (bSatelliteSegmentationTrees) + { + UE_LOG(LogTemp, Log, TEXT("Generate trees spawning points from satellite segmentation")); + GenerateSatelliteSegmentationTreePositions(); + } + else + { + UE_LOG(LogTemp, Log, TEXT("Generate trees spawning points from default method")); + GenerateDefaultTreePositions(ParamCarlaMap, MinLocation, MaxLocation); + } + UE_LOG(LogCarlaDigitalTwinsTool, Log, TEXT("UOpenDriveToMap::GenerateAll() Generating Misc stuff..... ")); GenerationFinished(MinLocation, MaxLocation); } @@ -1107,13 +1128,13 @@ void UOpenDriveToMap::GenerateSpawnPoints( const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation ) +void UOpenDriveToMap::GenerateDefaultTreePositions( const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation ) { carla::geom::Vector3D CarlaMinLocation(MinLocation.X / 100, MinLocation.Y / 100, MinLocation.Z /100); carla::geom::Vector3D CarlaMaxLocation(MaxLocation.X / 100, MaxLocation.Y / 100, MaxLocation.Z /100); std::vector> Locations = - ParamCarlaMap->GetTreesTransform(CarlaMinLocation, CarlaMaxLocation,DistanceBetweenTrees, DistanceFromRoadEdge ); + ParamCarlaMap->GetTreesTransform(CarlaMinLocation, CarlaMaxLocation, DistanceBetweenTrees, DistanceFromRoadEdge); int i = 0; for (auto &cl : Locations) { @@ -1135,6 +1156,201 @@ void UOpenDriveToMap::GenerateTreePositions( const boost::optional UOpenDriveToMap::ReadCSVCoordinates(FString path) +{ + UE_LOG(LogTemp, Warning, TEXT("Reading latlon coordinates")); + + TArray Coordinates; + + FString PluginPath = FPaths::ConvertRelativePathToFull(FPaths::ProjectPluginsDir() / TEXT("carla-digitaltwins")); + FString FilePositionsPath = PluginPath / path; + FString FileContent; + + if (FFileHelper::LoadFileToString(FileContent, *FilePositionsPath)) + { + TArray Lines; + FileContent.ParseIntoArrayLines(Lines); + + for (int32 i = 0; i < Lines.Num(); ++i) + { + FString Line = Lines[i]; + TArray Columns; + Line.ParseIntoArray(Columns, TEXT(","), true); + + if (Columns.Num() >= 2) + { + float X = FCString::Atof(*Columns[0]); + float Y = FCString::Atof(*Columns[1]); + FVector2D Pos = UMapGenFunctionLibrary::GetTransversemercProjection( Y, X, OriginGeoCoordinates.X, OriginGeoCoordinates.Y ); + Coordinates.Add(Pos); + } + } + } + else + { + UE_LOG(LogTemp, Warning, TEXT("Failed to read file at: %s"), *FilePositionsPath); + } + + return Coordinates; +} + +void UOpenDriveToMap::GenerateSatelliteSegmentationTreePositions() +{ + FString Path = FPaths::ConvertRelativePathToFull(FPaths::ProjectPluginsDir() / TEXT("carla-digitaltwins") / TEXT("PythonIntermediate/tree_masks.geojson")); + TArray Splines = UGeometryImporter::ImportGeoJsonPolygonsToSplines(UEditorLevelLibrary::GetEditorWorld(), Path, OriginGeoCoordinates); + + // TArray TreeCoordinates = ReadCSVCoordinates("PythonIntermediate/tree_points.csv"); + + // SpawnTrees(TreeCoordinates, "TreeSpawnPosition"); + + if (bShowDebugTreeAreas){ + + TArray PolylinesCoordinates = ReadCSVCoordinates("PythonIntermediate/tree_polylines.csv"); + + SpawnPlaceholders(PolylinesCoordinates, "PolylinesCoordinates"); + } + +} + +void UOpenDriveToMap::SpawnTrees(TArray TreeCoordinates, FString Label) +{ + int i = 0; + for (const FVector2D& Coord : TreeCoordinates) + { + FVector TreePos3D; + TreePos3D.X = Coord.X; + TreePos3D.Y = Coord.Y; + const FVector scale{ 1.0f, 1.0f, 1.0f }; + TreePos3D.Z = GetHeight(Coord.X, Coord.Y) + 0.3f; + FTransform NewTransform ( FRotator(), TreePos3D, scale ); + NewTransform = GetSnappedPosition(NewTransform); + + AActor* Spawner = UEditorLevelLibrary::GetEditorWorld()->SpawnActor(AStaticMeshActor::StaticClass(), + NewTransform.GetLocation(), NewTransform.Rotator()); + + Spawner->Tags.Add(FName(Label)); + Spawner->SetActorLabel(Label + FString::FromInt(i) + GetStringForCurrentTile() ); + ++i; + } +} + +void UOpenDriveToMap::SpawnPlaceholders(TArray Coordinates, FString Label) +{ + UStaticMesh* SphereMesh = LoadObject(nullptr, TEXT("/Engine/BasicShapes/Sphere.Sphere")); + UMaterialInterface* MarkerMaterial = LoadObject( + nullptr, + TEXT("/CarlaDigitalTwinsTool/digitalTwins/Static/Static/Materials/FireHydrant/M_FireHydrant.M_FireHydrant") +); // Use this material to better visualize the boundaries of the masks + + int i = 0; + for (const FVector2D& Coord : Coordinates) + { + FVector Pos3D; + Pos3D.X = Coord.X; + Pos3D.Y = Coord.Y; + Pos3D.Z = GetHeight(Coord.X, Coord.Y) + 0.3f; + + FTransform Transform(FRotator(), Pos3D, FVector(0.5f)); // Smaller spheres + + Transform = GetSnappedPosition(Transform); + + AStaticMeshActor* MarkerActor = UEditorLevelLibrary::GetEditorWorld()->SpawnActor( + AStaticMeshActor::StaticClass(), + Transform.GetLocation(), + Transform.Rotator() + ); + + if (MarkerActor && SphereMesh) + { + UStaticMeshComponent* MeshComp = MarkerActor->GetStaticMeshComponent(); + MeshComp->SetStaticMesh(SphereMesh); + + MeshComp->SetCollisionEnabled(ECollisionEnabled::NoCollision); + MeshComp->SetCollisionProfileName(TEXT("NoCollision")); + MarkerActor->SetActorEnableCollision(false); + MeshComp->SetSimulatePhysics(false); + MeshComp->SetEnableGravity(false); + + if (MarkerMaterial) + { + MeshComp->SetMaterial(0, MarkerMaterial); + } + + MarkerActor->Tags.Add(FName(Label)); + MarkerActor->SetActorLabel(Label + FString::FromInt(i) + GetStringForCurrentTile()); + } + + ++i; + } +} + float UOpenDriveToMap::GetHeight(float PosX, float PosY, bool bDrivingLane){ if (DefaultHeightmap && HeightmapPixels.Num() > 0) { @@ -1549,7 +1765,7 @@ void UOpenDriveToMap::RenderRoadToTexture(UWorld* World) FVector2D(Center.X, Center.Y), FVector2D(Extent.X, Extent.Y)); - auto JsonPath = PluginPath / TEXT("PythonIntermediate") / TEXT("contours.json"); + auto JsonPath = PluginPath / TEXT("PythonIntermediate") / TEXT("road_contours.json"); auto RoadSplines = UGeometryImporter::CreateSplinesFromJson( World, diff --git a/Source/CarlaDigitalTwinsTool/Private/Utils/GeometryImporter.cpp b/Source/CarlaDigitalTwinsTool/Private/Utils/GeometryImporter.cpp index 060ced6..5a38cbb 100644 --- a/Source/CarlaDigitalTwinsTool/Private/Utils/GeometryImporter.cpp +++ b/Source/CarlaDigitalTwinsTool/Private/Utils/GeometryImporter.cpp @@ -181,6 +181,8 @@ TArray UGeometryImporter::ImportGeoJsonPolygonsToSplines(UWor i++; } + UE_LOG(LogGeometryImporter, Log, TEXT("Splines created from GeoJson file.")); + return CreatedSplines; } diff --git a/Source/CarlaDigitalTwinsTool/Public/Generation/OpenDriveToMap.h b/Source/CarlaDigitalTwinsTool/Public/Generation/OpenDriveToMap.h index a65dd1c..0009468 100644 --- a/Source/CarlaDigitalTwinsTool/Public/Generation/OpenDriveToMap.h +++ b/Source/CarlaDigitalTwinsTool/Public/Generation/OpenDriveToMap.h @@ -150,6 +150,27 @@ class CARLADIGITALTWINSTOOL_API UOpenDriveToMap : public UEditorUtilityObject UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings") FVector2D OriginGeoCoordinates; + UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" ) + float DistanceBetweenTrees = 50.0f; + + UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" ) + float DistanceFromRoadEdge = 3.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings") + bool bSatelliteSegmentationTrees = true; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings") + int SatelliteSegmentationZoom = 20; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings") + float SatelliteSegmentationThreshold = 0.2f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings") + float TreeEffectiveRadius = 7.0f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings") + bool bShowDebugTreeAreas = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Defaults") UMaterialInstance* DefaultRoadMaterial; @@ -168,12 +189,6 @@ class CARLADIGITALTWINSTOOL_API UOpenDriveToMap : public UEditorUtilityObject UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Parameters") FOpenDriveFileGenerationParameters OpenDriveGenParams; - UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" ) - float DistanceBetweenTrees = 50.0f; - - UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" ) - float DistanceFromRoadEdge = 3.0f; - UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Stage" ) bool bHasStarted = false; @@ -266,9 +281,23 @@ class CARLADIGITALTWINSTOOL_API UOpenDriveToMap : public UEditorUtilityObject void LoadMap(); void GenerateAll(const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation); + void GenerateRoadMesh(const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation); + // void GenerateSpawnPoints(const carla::road::Map& ParamCarlaMap, FVector MinLocation, FVector MaxLocation); - void GenerateTreePositions(const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation); + + void GenerateDefaultTreePositions(const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation); + + void RunTreeSegmentation(); + + TArray ReadCSVCoordinates(FString path); + + void GenerateSatelliteSegmentationTreePositions(); + + void SpawnTrees(TArray TreeCoordinates, FString Label); + + void SpawnPlaceholders(TArray Coordinates, FString Label); + void GenerateLaneMarks(const boost::optional& ParamCarlaMap, FVector MinLocation, FVector MaxLocation); FTransform GetSnappedPosition(FTransform Origin);