diff --git a/LibCarla/source/carla/road/Map.cpp b/LibCarla/source/carla/road/Map.cpp index 1de891bb3..68a34cb44 100644 --- a/LibCarla/source/carla/road/Map.cpp +++ b/LibCarla/source/carla/road/Map.cpp @@ -16,6 +16,7 @@ #include "carla/road/element/RoadInfoLaneOffset.h" #include "carla/road/element/RoadInfoLaneWidth.h" #include "carla/road/element/RoadInfoMarkRecord.h" +#include "carla/road/element/RoadInfoSpeed.h" #include "carla/road/element/RoadInfoSignal.h" #include "simplify/Simplify.h" @@ -1133,7 +1134,7 @@ namespace road { return result; } - std::map>> + std::map>> Map::GenerateOrderedChunkedMesh( const rpc::OpendriveGenerationParameters& params) const { @@ -1154,7 +1155,7 @@ namespace road { for ( size_t i = 0; i < num_threads; ++i ) { std::thread neworker( [this, &write_mutex, &mesh_factory, &road_out_mesh_list, i, num_roads_per_thread]() { - std::map>> Current = + std::map>> Current = std::move(GenerateRoadsMultithreaded(mesh_factory, i, num_roads_per_thread)); std::lock_guard guard(write_mutex); for ( auto&& pair : Current ) { @@ -1220,7 +1221,38 @@ namespace road { return road_out_mesh_list; } + std::vector> Map::GetTreesPosition( + float distancebetweentrees, + float distancefromdrivinglineborder) const { + std::vector> positions; + for (auto &&pair : _data.GetRoads()) { + const auto &road = pair.second; + if (!road.IsJunction()) { + for (auto &&lane_section : road.GetLaneSections()) { + const auto min_lane = lane_section.GetLanes().begin()->first == 0 ? + 1 : lane_section.GetLanes().begin()->first; + const auto max_lane = lane_section.GetLanes().rbegin()->first == 0 ? + -1 : lane_section.GetLanes().rbegin()->first; + const road::Lane* lane = lane_section.GetLane(min_lane); + if( lane ) { + double s_current = lane_section.GetDistance(); + const double s_end = lane_section.GetDistance() + lane_section.GetLength(); + while(s_current < s_end){ + const auto edges = lane->GetCornerPositions(s_current, 0); + geom::Vector3D director = edges.second - edges.first; + geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder; + const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo(s_current); + positions.push_back(std::make_pair(treeposition,roadinfo->GetType())); + s_current += distancebetweentrees; + } + + } + } + } + } + return positions; + } geom::Mesh Map::GetAllCrosswalkMesh() const { geom::Mesh out_mesh; @@ -1326,20 +1358,20 @@ namespace road { } return A1 * sin((Kx1 * posx + Ky1 * posy + F1)) + - A2 * sin((Kx2 * posx + Ky2 * posy + F2)) + + A2 * sin((Kx2 * posx + Ky2 * posy + F2)) + A3 * bumpsoffset; } - std::map>> - Map::GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory, - const size_t index, const size_t number_of_roads_per_thread) const + std::map>> + Map::GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory, + const size_t index, const size_t number_of_roads_per_thread) const { std::map>> out; auto start = std::next( _data.GetRoads().begin(), (index ) * number_of_roads_per_thread); size_t endoffset = (index+1) * number_of_roads_per_thread; if( endoffset >= _data.GetRoads().size() ) { - endoffset = _data.GetRoads().size(); + endoffset = _data.GetRoads().size(); } auto end = std::next( _data.GetRoads().begin(), endoffset ); @@ -1449,7 +1481,7 @@ namespace road { auto start = std::next( roadsmesh.begin(), ( index ) * number_of_roads_per_thread); size_t endoffset = (index+1) * number_of_roads_per_thread; if( endoffset >= roadsmesh.size() ) { - endoffset = roadsmesh.size(); + endoffset = roadsmesh.size(); } auto end = std::next( roadsmesh.begin(), endoffset ); for ( auto it = start; it != end && it != roadsmesh.end(); ++it ) { @@ -1499,7 +1531,7 @@ namespace road { current_mesh->GetIndexes().push_back((Simplification.triangles[i].v[0]) + 1); current_mesh->GetIndexes().push_back((Simplification.triangles[i].v[1]) + 1); current_mesh->GetIndexes().push_back((Simplification.triangles[i].v[2]) + 1); - } + } } } diff --git a/LibCarla/source/carla/road/Map.h b/LibCarla/source/carla/road/Map.h index 999368c8e..a868e15cc 100644 --- a/LibCarla/source/carla/road/Map.h +++ b/LibCarla/source/carla/road/Map.h @@ -160,12 +160,16 @@ namespace road { std::vector> GenerateChunkedMesh( const rpc::OpendriveGenerationParameters& params) const; - std::map>> + std::map>> GenerateOrderedChunkedMesh( const rpc::OpendriveGenerationParameters& params) const; /// Buids a mesh of all crosswalks based on the OpenDRIVE geom::Mesh GetAllCrosswalkMesh() const; + std::vector> GetTreesPosition( + float distancebetweentrees, + float distancefromdrivinglineborder) const; + geom::Mesh GenerateWalls(const double distance, const float wall_height) const; /// Buids a list of meshes related with LineMarkings @@ -214,11 +218,11 @@ private: public: inline float GetZPosInDeformation(float posx, float posy) const; - std::map>> + std::map>> GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory, const size_t index, const size_t number_of_roads_per_thread) const; - void GenerateJunctions(const carla::geom::MeshFactory& mesh_factory, + void GenerateJunctions(const carla::geom::MeshFactory& mesh_factory, const rpc::OpendriveGenerationParameters& params, std::map>>* juntion_out_mesh_list) const; diff --git a/LibCarla/source/carla/road/element/RoadInfoSpeed.h b/LibCarla/source/carla/road/element/RoadInfoSpeed.h index d3bc51fe5..5de4aa47e 100644 --- a/LibCarla/source/carla/road/element/RoadInfoSpeed.h +++ b/LibCarla/source/carla/road/element/RoadInfoSpeed.h @@ -17,8 +17,13 @@ namespace element { RoadInfoSpeed(double s, double speed) : RoadInfo(s), - _speed(speed) {} + _speed(speed), + _type("Town") {} + RoadInfoSpeed(double s, double speed, std::string& type) + : RoadInfo(s), + _speed(speed), + _type(type) {} void AcceptVisitor(RoadInfoVisitor &v) final { v.Visit(*this); } @@ -27,9 +32,14 @@ namespace element { return _speed; } + std::string GetType() const{ + return _type; + } + private: const double _speed; + const std::string _type; }; } // namespace element diff --git a/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/BP_OpenDriveToMap.uasset b/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/BP_OpenDriveToMap.uasset new file mode 100644 index 000000000..5c0452ced Binary files /dev/null and b/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/BP_OpenDriveToMap.uasset differ diff --git a/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/DT_TreesGeneration.uasset b/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/DT_TreesGeneration.uasset new file mode 100644 index 000000000..189b78916 Binary files /dev/null and b/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/DT_TreesGeneration.uasset differ diff --git a/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/UW_OnRoadMainWidget.uasset b/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/UW_OnRoadMainWidget.uasset index 492aa2952..a7329a360 100644 Binary files a/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/UW_OnRoadMainWidget.uasset and b/Unreal/CarlaUE4/Plugins/CarlaTools/Content/OnroadMapGenerator/UW_OnRoadMainWidget.uasset differ diff --git a/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Private/OpenDriveToMap.cpp b/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Private/OpenDriveToMap.cpp index 3c3078078..1c09e2f2b 100644 --- a/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Private/OpenDriveToMap.cpp +++ b/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Private/OpenDriveToMap.cpp @@ -126,7 +126,7 @@ void UOpenDriveToMap::CreateMap() UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("Map Name Is Empty") ); return; } - if ( !IsValid(FileDownloader) ) + if ( !IsValid(FileDownloader) ) { FileDownloader = NewObject(); } @@ -166,7 +166,7 @@ void UOpenDriveToMap::LoadMap() std::string opendrive_xml = carla::rpc::FromLongFString(FileContent); boost::optional CarlaMap = carla::opendrive::OpenDriveParser::Load(opendrive_xml); - if (!CarlaMap.has_value()) + if (!CarlaMap.has_value()) { UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("Invalid Map")); } @@ -179,17 +179,19 @@ void UOpenDriveToMap::LoadMap() UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("MapName %s"), *MapName); GenerateAll(CarlaMap); + GenerationFinished(); } void UOpenDriveToMap::GenerateAll(const boost::optional& CarlaMap ) { - if (!CarlaMap.has_value()) + if (!CarlaMap.has_value()) { UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("Invalid Map")); }else { GenerateRoadMesh(CarlaMap); GenerateSpawnPoints(CarlaMap); + GenerateTreePositions(CarlaMap); GenerateLaneMarks(CarlaMap); } } @@ -207,7 +209,7 @@ void UOpenDriveToMap::GenerateRoadMesh( const boost::optional& start = FPlatformTime::Seconds(); int index = 0; - for (const auto &PairMap : Meshes) + for (const auto &PairMap : Meshes) { for( const auto &Mesh : PairMap.second ) { @@ -359,6 +361,20 @@ void UOpenDriveToMap::GenerateSpawnPoints( const boost::optional& CarlaMap ) +{ + const std::vector> Locations = + CarlaMap->GetTreesPosition(DistanceBetweenTrees, DistanceFromRoadEdge ); + int i = 0; + for (const auto &cl : Locations) + { + AActor *Spawner = GetWorld()->SpawnActor(AStaticMeshActor::StaticClass(), cl.first.ToFVector() * 100, FRotator(0,0,0)); + Spawner->Tags.Add(FName("TreeSpawnPosition")); + Spawner->Tags.Add(FName(cl.second.c_str())); + Spawner->SetActorLabel("TreeSpawnPosition" + FString::FromInt(i) ); + ++i; + } +} UStaticMesh* UOpenDriveToMap::CreateStaticMeshAsset( UProceduralMeshComponent* ProcMeshComp, int32 MeshIndex, FString FolderName ) { FMeshDescription MeshDescription = BuildMeshDescription(ProcMeshComp); diff --git a/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/OpenDriveToMap.h b/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/OpenDriveToMap.h index 764ac3abc..db1ca1eb6 100644 --- a/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/OpenDriveToMap.h +++ b/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/OpenDriveToMap.h @@ -20,7 +20,7 @@ class UMeshComponent; class UCustomFileDownloader; class UMaterialInstance; /** - * + * */ UCLASS(Blueprintable, BlueprintType) class CARLATOOLS_API UOpenDriveToMap : public UObject @@ -30,7 +30,7 @@ class CARLATOOLS_API UOpenDriveToMap : public UObject public: UFUNCTION() - void ConvertOSMInOpenDrive(); + void ConvertOSMInOpenDrive(); UFUNCTION( BlueprintCallable ) void CreateMap(); @@ -47,6 +47,11 @@ public: 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) UMaterialInstance* DefaultRoadMaterial; @@ -57,6 +62,9 @@ protected: UFUNCTION( BlueprintCallable ) void SaveMap(); + + UFUNCTION( BlueprintImplementableEvent ) + void GenerationFinished(); private: UFUNCTION() @@ -68,13 +76,14 @@ private: void GenerateAll(const boost::optional& CarlaMap); void GenerateRoadMesh(const boost::optional& CarlaMap); void GenerateSpawnPoints(const boost::optional& CarlaMap); + void GenerateTreePositions(const boost::optional& CarlaMap); void GenerateLaneMarks(const boost::optional& CarlaMap); carla::rpc::OpendriveGenerationParameters opg_parameters; UStaticMesh* CreateStaticMeshAsset(UProceduralMeshComponent* ProcMeshComp, int32 MeshIndex, FString FolderName); TArray CreateStaticMeshAssets(); - + UPROPERTY() UCustomFileDownloader* FileDownloader; UPROPERTY() diff --git a/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/TreeTableRow.h b/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/TreeTableRow.h new file mode 100644 index 000000000..8c97713b6 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/CarlaTools/Source/CarlaTools/Public/TreeTableRow.h @@ -0,0 +1,35 @@ +// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB). This work is licensed under the terms of the MIT license. For a copy, see . + +#pragma once + +#include "CoreMinimal.h" +#include "Engine/DataTable.h" +#include "TreeTableRow.generated.h" + +/** + * + */ + +UENUM(BlueprintType) +enum class ELaneDescriptor : uint8 { + None = 0x0, + Town = 0x1 << 0, + Motorway = 0x1 << 1, + Rural = 0x1 << 2, + Any = 255 // 0xFE +}; + +USTRUCT(BlueprintType) +struct FTreeTableRow : public FTableRowBase { + + GENERATED_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Category") + ELaneDescriptor TreesCategory; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "Trees") + TArray> Trees; + +};