Digital Twins 0.2 version (#6768)

* Bitmap sent and drawn in widget texture with bugs

* Map bitmap shown on widget

* Concated meshes generated in the same lane to avoid errors during simplification

* Navigation added to widget

* Avoid Simplify to remove border vertices and try to parallel assets creation process

* Road Generation 0.1 version ready

* Removing Engine Association, Formatting CarlaTools Build dependencies

* Change container type of generated procedural mesh componetns to be supported by UPROPERTY

* Fixed indices jumping by two

* Added in separate thread junctions generation

* Started dynamic database creation

* Dynamic database creation temporally removed

* First step of merge. Coords of bottom left corner and top right corner

* Libraries added to build system

* Git ignore for osmrenderer to avoid ThirdParties directory to be tracked

* Lat and Lon coords for corners sent from server to client

* Transformed to local coords meshes' vertices' coords

* Coords format error fixed

* Saving xodr and osm files inside of OpenDrive folder

* Widget fixed

* UI design improved

* WIP Windows build system for osm-world-renderer

* Socket implementation replaced by boost asio framework in osmrenderer

* Added multithreaded simplification of meshes

* Build system adapted to wndows

* Headers fixed to avoid windows specific heraders compilation

* Remove warnings

* Added widget to import building from houdini

* Added origin latitude and longituda to OSM to OpenDRIVE conversion functions. Fixed Houdini importer widgets.

* Add Houdini plugin download to the build system

* Moved houdini blueprint. Houdini plugin now dowloads by default

* Added houdini download for windows

* OpenDriveToMap Now is a UOBject instead of widget

* Added Lane mark generation.

* Roads materials and distance field scale set to 0

* M_PI macro fixed for windows osm-renderer build system

* Added Lane Marking generation

* Fixed compilation issue related with std pair non copyable lane

* Fix bug where different lanes were concating. Fix bug where end of roadmark was creating an artifact

* Lanes Marks material assignation

* Fix compilation issue and reading from not valid memory crash

* Middle Lane mark duplication bug fixed - temp solution

* Added bumps along road

* Adding marchingcubes library and added to create junctions

* Added junctions generations using marching cube and smoothed

* Fixed linux compilation and removed couple warnings

* Using previous algorithim for two road connections

* Code cleanup

* Remove debug state

* Format Files

* Format third parties files

* Spaces removal

* Fix code format

* Added spawnning for trees

* New branch to don`t loose modifications in code

* Removing unnecesary spaces

* Set trees for designer

* Tag static mesh actor from road type

* One tile with landscape and road cut

* Changed format of For

* WidgetCreated

* Widget progress

* LevelCreator Update

* Folder for basicParameters in father map

* Father map from template

* Terrain mesh generated from noise and road mask

Road mask not applied

* Assign SubLevel by position

* Changed to static functions

* StrigUpdate

* Added missing UFUNCTIONS

* Trying to move Houdini actors to tiles

* Meshes from Houdini to Tiles

* Number of X and Y tiles exposed

* Modify to new functions

* Modifying code to create a new variable-offset and table to ingest blueprints

* Update assignTile Function

* Updating widget and cpp file to relocate meshes

* Update Widget and create local copy of OpenDriveToMap

* Added planes as landscape

* RoadImported fixed

* Simplification done in UE side

* Update Houdini pipeline

* Fixed osmrenderer compilation for windows

* Generate landscape and set materials

* Generate UVs for lane meshes. Generate Normals and Tangets for lane meshes

* Delete unnecesary files

* Widget updated

* Exposing different variables to BPs

* Update Assets

* Asset path names fixed

* Fixed height for misc objects, set default landscape

* Rotate Light boxes

* Adding OSM Importer plugin

* Fixed normals on sidewalks

* Update adding buildings plugin

* Adding missing BP

* Update

* Fix BP_Instanced

* Update OSMImporter

* Creating BP_BuildingCreator

* LevelCreator Fixed

* Update building asset creation

* If def add for osm renderer

* Building block variation and styles

* Updated values and generation for demo3

* Fix Widget

* Changed unreal FSocket for boost sockets. Fixed road position errors

* Update building creation

* Updated Building Height

* Fixing line colors

* Added Planes in missing stuff

* Update for meshes

* Update deformation, avoid creation of individual buildings and add check for deformation

* Deleted unnecesary files

* New branch to work on building generation

* Added shorts walls and roofs

* Improve triangulation of polygons using UE

* Fixing pipeline

* Disabling shadows for roads and terrain

* Updated default values for BP_Opendrivetomap

* Updated OpenDriveToMap

* Use Editor world instead of GetWorld

* Added HTTP module

* Change customfiledownloader API

* Adding debuginformation

* Using OpenDriveToMapObject

* Adding Debug stuff

* Expose Buildings names in ue4

* Remove from root when generation finished

* Adding Slopes to building generation

* Table update

* Set pivot point at centre of building and Set use of material instances

* Updating Buildings plane stuff

* Fixing walls for building generator

* Update data table

* Updated road generation

* Update DT

* Update Origin of map and set moving for large map

* Remove logs prepare blueprints for getting new info

* Update slope fix and material for slopes

* Updated Digital Twins for 12/06

* Added direct URL support

* Avoid some crashes and improve QoL

* Height fix

* Tried to expose largemap in tick

* New vegetation scatter tool

* Added Full largemap support

* Edit building levels in some type of levels

* Updated static meshes instead of procedural meshes

* Updated building generation and reduced logs

* Vegetation tool into landscape pipeline

* Demo ready for digital twins

* Automated download of plugin

* Update linux build script for UE4 Plugins

* Disable sidewalks in junctions

* Re enable sidewalksin crossing lanes

* Removed asserts added checks to avoid generation of sidewalks on road

* Optimizations for VRAM

* Move actors slowly to sub levels

* Added optimizations and support for smaller or bigger maps in tiles, modified TileSize

* Garage and shed styles

* Update generation stages

* Update garage and shed parameters

* Changed method generation to tile by tile

* Fixed memory leak and UOpenDriveToMap is a uobject now

* Fixed tile by tile generation

* Added Heightmap support to map gen

* last update

* Commandlet generation working

* Merge finished

* Update DefaultEngine.ini to rever default rhi

* Clean up HoudiniImporterWidget.cpp

* Add with editor and make editor only code

* Setup dependencies for CarlaTools plugin

* Update StreetMap plugin commit and gitignore

* Update Content version

* Update next content version

* Changed based type of OpenDrivetomap

* Remove intermediate files if need similar to BuildCarlaUE4.sh

* Update order of execution of donwload

* Try to run download plugins everytime is used

* Update packages sh avoid to delete anything

* Fixing setup in windows

* Add UE Constructor to Commandlet

* More fixes

* content version

* Update package sh and update

* Update Streetmap version

* Update dependencies

* Update StreetMap commit

* Fix typo in gitignore

* Update STMap plugin commit

* Revert latest changes in windows package script

* Update comments

---------

Co-authored-by: aollero <aollero@cvc.uab.cat>
Co-authored-by: aollero <adriollero@gmail.com>
Co-authored-by: Axel <axellopez92@outlook.com>
Co-authored-by: marionzki <mnoriegazamora@gmail.com>
Co-authored-by: bernatx <bernatx@gmail.com>
This commit is contained in:
Blyron 2023-10-31 11:24:22 +01:00 committed by GitHub
parent 133cd319d7
commit 80d3471171
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 1681 additions and 675 deletions

2
.gitignore vendored
View File

@ -7,8 +7,10 @@ Util/Build
Install Install
Plugins Plugins
!Unreal/CarlaUE4/Plugins !Unreal/CarlaUE4/Plugins
Unreal/CarlaUE4/Plugins/Streetmap
Unreal/CarlaUE4/Plugins/HoudiniEngine Unreal/CarlaUE4/Plugins/HoudiniEngine
/ExportedMaps /ExportedMaps
/Import/* /Import/*
!/Import/README.md !/Import/README.md

View File

@ -58,8 +58,10 @@ namespace road {
double Lane::GetWidth(const double s) const { double Lane::GetWidth(const double s) const {
RELEASE_ASSERT(s <= GetRoad()->GetLength()); RELEASE_ASSERT(s <= GetRoad()->GetLength());
const auto width_info = GetInfo<element::RoadInfoLaneWidth>(s); const auto width_info = GetInfo<element::RoadInfoLaneWidth>(s);
RELEASE_ASSERT(width_info != nullptr); if(width_info != nullptr){
return width_info->GetPolynomial().Evaluate(s); return width_info->GetPolynomial().Evaluate(s);
}
return 0.0f;
} }
bool Lane::IsStraight() const { bool Lane::IsStraight() const {

View File

@ -1135,27 +1135,33 @@ namespace road {
} }
std::map<road::Lane::LaneType , std::vector<std::unique_ptr<geom::Mesh>>> std::map<road::Lane::LaneType , std::vector<std::unique_ptr<geom::Mesh>>>
Map::GenerateOrderedChunkedMesh( const rpc::OpendriveGenerationParameters& params) const Map::GenerateOrderedChunkedMeshInLocations( const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos) const
{ {
geom::MeshFactory mesh_factory(params); geom::MeshFactory mesh_factory(params);
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> road_out_mesh_list; std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> road_out_mesh_list;
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> junction_out_mesh_list; std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> junction_out_mesh_list;
std::thread juntction_thread( &Map::GenerateJunctions, this, mesh_factory, params, &junction_out_mesh_list); std::thread juntction_thread( &Map::GenerateJunctions, this, mesh_factory, params,
minpos, maxpos, &junction_out_mesh_list);
size_t num_roads = _data.GetRoads().size(); const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
size_t num_roads_per_thread = 20;
size_t num_roads = RoadsIDToGenerate.size();
size_t num_roads_per_thread = 30;
size_t num_threads = (num_roads / num_roads_per_thread) + 1; size_t num_threads = (num_roads / num_roads_per_thread) + 1;
num_threads = num_threads > 1 ? num_threads : 1; num_threads = num_threads > 1 ? num_threads : 1;
std::vector<std::thread> workers; std::vector<std::thread> workers;
std::mutex write_mutex; std::mutex write_mutex;
std::cout << "Generating " << std::to_string(num_roads) << " roads" << std::endl;
for ( size_t i = 0; i < num_threads; ++i ) { for ( size_t i = 0; i < num_threads; ++i ) {
std::thread neworker( std::thread neworker(
[this, &write_mutex, &mesh_factory, &road_out_mesh_list, i, num_roads_per_thread]() { [this, &write_mutex, &mesh_factory, &RoadsIDToGenerate, &road_out_mesh_list, i, num_roads_per_thread]() {
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> Current = std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> Current =
std::move(GenerateRoadsMultithreaded(mesh_factory, i, num_roads_per_thread)); std::move(GenerateRoadsMultithreaded(mesh_factory, RoadsIDToGenerate,i, num_roads_per_thread ));
std::lock_guard<std::mutex> guard(write_mutex); std::lock_guard<std::mutex> guard(write_mutex);
for ( auto&& pair : Current ) { for ( auto&& pair : Current ) {
if (road_out_mesh_list.find(pair.first) != road_out_mesh_list.end()) { if (road_out_mesh_list.find(pair.first) != road_out_mesh_list.end()) {
@ -1193,17 +1199,23 @@ namespace road {
road_out_mesh_list[pair.first] = std::move(pair.second); road_out_mesh_list[pair.first] = std::move(pair.second);
} }
} }
std::cout << "Generated " << std::to_string(num_roads) << " roads" << std::endl;
return road_out_mesh_list; return road_out_mesh_list;
} }
std::vector<std::pair<geom::Transform, std::string>> Map::GetTreesTransform( std::vector<std::pair<geom::Transform, std::string>> Map::GetTreesTransform(
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
float distancebetweentrees, float distancebetweentrees,
float distancefromdrivinglineborder, float distancefromdrivinglineborder,
float s_offset) const { float s_offset) const {
std::vector<std::pair<geom::Transform, std::string>> transforms; std::vector<std::pair<geom::Transform, std::string>> transforms;
for (auto &&pair : _data.GetRoads()) {
const auto &road = pair.second; const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
for ( RoadId id : RoadsIDToGenerate ) {
const auto& road = _data.GetRoads().at(id);
if (!road.IsJunction()) { if (!road.IsJunction()) {
for (auto &&lane_section : road.GetLaneSections()) { for (auto &&lane_section : road.GetLaneSections()) {
LaneId min_lane = 0; LaneId min_lane = 0;
@ -1212,20 +1224,21 @@ namespace road {
min_lane = pairlane.first; min_lane = pairlane.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); const road::Lane* lane = lane_section.GetLane(min_lane);
if( lane ) { if( lane ) {
double s_current = lane_section.GetDistance() + s_offset; double s_current = lane_section.GetDistance() + s_offset;
const double s_end = lane_section.GetDistance() + lane_section.GetLength(); const double s_end = lane_section.GetDistance() + lane_section.GetLength();
while(s_current < s_end){ while(s_current < s_end){
const auto edges = lane->GetCornerPositions(s_current, 0); if(lane->GetWidth(s_current) != 0.0f){
geom::Vector3D director = edges.second - edges.first; const auto edges = lane->GetCornerPositions(s_current, 0);
geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder; geom::Vector3D director = edges.second - edges.first;
geom::Transform lanetransform = lane->ComputeTransform(s_current); geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder;
geom::Transform treeTransform(treeposition, lanetransform.rotation); geom::Transform lanetransform = lane->ComputeTransform(s_current);
const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo<carla::road::element::RoadInfoSpeed>(s_current); geom::Transform treeTransform(treeposition, lanetransform.rotation);
transforms.push_back(std::make_pair(treeTransform,roadinfo->GetType())); const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo<carla::road::element::RoadInfoSpeed>(s_current);
transforms.push_back(std::make_pair(treeTransform,roadinfo->GetType()));
}
s_current += distancebetweentrees; s_current += distancebetweentrees;
} }
@ -1275,15 +1288,19 @@ namespace road {
/// Buids a list of meshes related with LineMarkings /// Buids a list of meshes related with LineMarkings
std::vector<std::unique_ptr<geom::Mesh>> Map::GenerateLineMarkings( std::vector<std::unique_ptr<geom::Mesh>> Map::GenerateLineMarkings(
const rpc::OpendriveGenerationParameters& params, const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::vector<std::string>& outinfo ) const std::vector<std::string>& outinfo ) const
{ {
std::vector<std::unique_ptr<geom::Mesh>> LineMarks; std::vector<std::unique_ptr<geom::Mesh>> LineMarks;
geom::MeshFactory mesh_factory(params); geom::MeshFactory mesh_factory(params);
for ( auto&& pair : _data.GetRoads() ) {
if ( pair.second.IsJunction() ) { const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
continue; for ( RoadId id : RoadsIDToGenerate ) {
const auto& road = _data.GetRoads().at(id);
if (!road.IsJunction()) {
mesh_factory.GenerateLaneMarkForRoad(road, LineMarks, outinfo);
} }
mesh_factory.GenerateLaneMarkForRoad(pair.second, LineMarks, outinfo);
} }
return std::move(LineMarks); return std::move(LineMarks);
@ -1308,91 +1325,126 @@ namespace road {
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>
Map::GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory, Map::GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory,
const std::vector<RoadId>& RoadsId,
const size_t index, const size_t number_of_roads_per_thread) const const size_t index, const size_t number_of_roads_per_thread) const
{ {
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> out; std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> out;
auto start = std::next( _data.GetRoads().begin(), (index ) * number_of_roads_per_thread); size_t start = index * number_of_roads_per_thread;
size_t endoffset = (index+1) * number_of_roads_per_thread; size_t endoffset = (index+1) * number_of_roads_per_thread;
if( endoffset >= _data.GetRoads().size() ) { size_t end = RoadsId.size();
endoffset = _data.GetRoads().size();
}
auto end = std::next( _data.GetRoads().begin(), endoffset );
for (auto pair = start; pair != end && pair != _data.GetRoads().end(); ++pair) { for (int i = start; i < endoffset && i < end; ++i) {
const auto& road = pair->second; const auto& road = _data.GetRoads().at(RoadsId[i]);
if (!road.IsJunction()) { if (!road.IsJunction()) {
mesh_factory.GenerateAllOrderedWithMaxLen(road, out); mesh_factory.GenerateAllOrderedWithMaxLen(road, out);
} }
} }
std::cout << "Generated roads from " + std::to_string(index * number_of_roads_per_thread) + " to " + std::to_string((index+1) * number_of_roads_per_thread ) << std::endl;
return out; return out;
} }
void Map::GenerateJunctions(const carla::geom::MeshFactory& mesh_factory, void Map::GenerateJunctions(const carla::geom::MeshFactory& mesh_factory,
const rpc::OpendriveGenerationParameters& params, const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::map<road::Lane::LaneType, std::map<road::Lane::LaneType,
std::vector<std::unique_ptr<geom::Mesh>>>* junction_out_mesh_list) const { std::vector<std::unique_ptr<geom::Mesh>>>* junction_out_mesh_list) const {
for (const auto& junc_pair : _data.GetJunctions()) { std::vector<JuncId> JunctionsToGenerate = FilterJunctionsByPosition(minpos, maxpos);
const auto& junction = junc_pair.second; size_t num_junctions = JunctionsToGenerate.size();
if (junction.GetConnections().size() > 2) { std::cout << "Generating " << std::to_string(num_junctions) << " junctions" << std::endl;
std::vector<std::unique_ptr<geom::Mesh>> lane_meshes; size_t junctionindex = 0;
std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes; size_t num_junctions_per_thread = 5;
std::vector<carla::geom::Vector3D> perimeterpoints; size_t num_threads = (num_junctions / num_junctions_per_thread) + 1;
num_threads = num_threads > 1 ? num_threads : 1;
std::vector<std::thread> workers;
std::mutex write_mutex;
auto pmesh = SDFToMesh(junction, perimeterpoints, 75); for ( size_t i = 0; i < num_threads; ++i ) {
(*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(pmesh)); std::thread neworker(
[this, &write_mutex, &mesh_factory, &junction_out_mesh_list, JunctionsToGenerate, i, num_junctions_per_thread, num_junctions]() {
std::map<road::Lane::LaneType,
std::vector<std::unique_ptr<geom::Mesh>>> junctionsofthisthread;
for (const auto& connection_pair : junction.GetConnections()) { size_t minimum = 0;
const auto& connection = connection_pair.second; if( (i + 1) * num_junctions_per_thread < num_junctions ){
const auto& road = _data.GetRoads().at(connection.connecting_road); minimum = (i + 1) * num_junctions_per_thread;
for (auto&& lane_section : road.GetLaneSections()) { }else{
for (auto&& lane_pair : lane_section.GetLanes()) { minimum = num_junctions;
const auto& lane = lane_pair.second; }
if (lane.GetType() == road::Lane::LaneType::Sidewalk) { std::cout << "Generating Junctions between " << std::to_string(i * num_junctions_per_thread) << " and " << std::to_string(minimum) << std::endl;
sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane));
} for ( size_t junctionindex = i * num_junctions_per_thread;
} junctionindex < minimum;
++junctionindex )
{
GenerateSingleJunction(mesh_factory, JunctionsToGenerate[junctionindex], &junctionsofthisthread);
}
std::cout << "Generated Junctions between " << std::to_string(i * num_junctions_per_thread) << " and " << std::to_string(minimum) << std::endl;
std::lock_guard<std::mutex> guard(write_mutex);
for ( auto&& pair : junctionsofthisthread ) {
if ((*junction_out_mesh_list).find(pair.first) != (*junction_out_mesh_list).end()) {
(*junction_out_mesh_list)[pair.first].insert((*junction_out_mesh_list)[pair.first].end(),
std::make_move_iterator(pair.second.begin()),
std::make_move_iterator(pair.second.end()));
} else {
(*junction_out_mesh_list)[pair.first] = std::move(pair.second);
} }
} }
std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>(); });
for (auto& lane : sidewalk_lane_meshes) { workers.push_back(std::move(neworker));
*sidewalk_mesh += *lane; }
}
(*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh));
} else {
std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes;
for (const auto& connection_pair : junction.GetConnections()) {
const auto& connection = connection_pair.second;
const auto& road = _data.GetRoads().at(connection.connecting_road);
for (auto&& lane_section : road.GetLaneSections()) {
for (auto&& lane_pair : lane_section.GetLanes()) {
const auto& lane = lane_pair.second;
if (lane.GetType() != road::Lane::LaneType::Sidewalk) {
lane_meshes.push_back(mesh_factory.GenerateTesselated(lane));
}
else {
sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane));
}
}
}
}
std::unique_ptr<geom::Mesh> merged_mesh = std::make_unique<geom::Mesh>();
for (auto& lane : lane_meshes) {
*merged_mesh += *lane;
}
std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>();
for (auto& lane : sidewalk_lane_meshes) {
*sidewalk_mesh += *lane;
}
(*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(merged_mesh)); for (size_t i = 0; i < workers.size(); ++i) {
(*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh)); workers[i].join();
}
workers.clear();
for (size_t i = 0; i < workers.size(); ++i) {
if (workers[i].joinable()) {
workers[i].join();
} }
} }
} }
std::vector<JuncId> Map::FilterJunctionsByPosition( const geom::Vector3D& minpos,
const geom::Vector3D& maxpos ) const {
std::cout << "Filtered from " + std::to_string(_data.GetJunctions().size() ) + " junctions " << std::endl;
std::vector<JuncId> ToReturn;
for( auto& junction : _data.GetJunctions() ){
geom::Location junctionLocation = junction.second.GetBoundingBox().location;
if( minpos.x < junctionLocation.x && junctionLocation.x < maxpos.x &&
minpos.y > junctionLocation.y && junctionLocation.y > maxpos.y ) {
ToReturn.push_back(junction.first);
}
}
std::cout << "To " + std::to_string(ToReturn.size() ) + " junctions " << std::endl;
return ToReturn;
}
std::vector<RoadId> Map::FilterRoadsByPosition( const geom::Vector3D& minpos,
const geom::Vector3D& maxpos ) const {
std::vector<RoadId> ToReturn;
std::cout << "Filtered from " + std::to_string(_data.GetRoads().size() ) + " roads " << std::endl;
for( auto& road : _data.GetRoads() ){
auto &&lane_section = (*road.second.GetLaneSections().begin());
const road::Lane* lane = lane_section.GetLane(-1);
if( lane ) {
const double s_check = lane_section.GetDistance() + lane_section.GetLength() * 0.5;
geom::Location roadLocation = lane->ComputeTransform(s_check).location;
if( minpos.x < roadLocation.x && roadLocation.x < maxpos.x &&
minpos.y > roadLocation.y && roadLocation.y > maxpos.y ) {
ToReturn.push_back(road.first);
}
}
}
std::cout << "To " + std::to_string(ToReturn.size() ) + " roads " << std::endl;
return ToReturn;
}
std::unique_ptr<geom::Mesh> Map::SDFToMesh(const road::Junction& jinput, std::unique_ptr<geom::Mesh> Map::SDFToMesh(const road::Junction& jinput,
const std::vector<geom::Vector3D>& sdfinput, const std::vector<geom::Vector3D>& sdfinput,
int grid_cells_per_dim) const { int grid_cells_per_dim) const {
@ -1441,42 +1493,18 @@ namespace road {
geom::Mesh out_mesh; geom::Mesh out_mesh;
for (auto& cv : mesh.vertices) { for (auto& cv : mesh.vertices) {
geom::Vector3D newvertex; geom::Vector3D newvertex;
newvertex.x = cv.x; newvertex.x = cv.x;
newvertex.y = cv.y; newvertex.y = cv.y;
newvertex.z = cv.z; newvertex.z = cv.z;
if ( std::find( out_mesh.GetVertices().begin(), out_mesh.GetVertices().end(), newvertex) == out_mesh.GetVertices().end() ) { out_mesh.AddVertex(newvertex);
out_mesh.AddVertex(newvertex);
}
} }
auto finalvertices = out_mesh.GetVertices(); auto finalvertices = out_mesh.GetVertices();
for (auto ct : mesh.triangles) { for (auto ct : mesh.triangles) {
auto cv = mesh.vertices[ct[1]]; out_mesh.AddIndex(ct[1] + 1);
geom::Vector3D newvertex; out_mesh.AddIndex(ct[0] + 1);
newvertex.x = cv.x; out_mesh.AddIndex(ct[2] + 1);
newvertex.y = cv.y;
newvertex.z = cv.z;
auto it = std::find(finalvertices.begin(), finalvertices.end(), newvertex);
out_mesh.AddIndex(it - finalvertices.begin() + 1);
cv = mesh.vertices[ct[0]];
newvertex.x = cv.x;
newvertex.y = cv.y;
newvertex.z = cv.z;
it = std::find(finalvertices.begin(), finalvertices.end(), newvertex);
out_mesh.AddIndex(it - finalvertices.begin() + 1);
cv = mesh.vertices[ct[2]];
newvertex.x = cv.x;
newvertex.y = cv.y;
newvertex.z = cv.z;
it = std::find(finalvertices.begin(), finalvertices.end(), newvertex);
out_mesh.AddIndex(it - finalvertices.begin() + 1);
} }
for (auto& cv : out_mesh.GetVertices() ) { for (auto& cv : out_mesh.GetVertices() ) {
@ -1493,5 +1521,73 @@ namespace road {
} }
return std::make_unique<geom::Mesh>(out_mesh); return std::make_unique<geom::Mesh>(out_mesh);
} }
void Map::GenerateSingleJunction(const carla::geom::MeshFactory& mesh_factory,
const JuncId Id,
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>*
junction_out_mesh_list) const {
const auto& junction = _data.GetJunctions().at(Id);
if (junction.GetConnections().size() > 2) {
std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes;
std::vector<carla::geom::Vector3D> perimeterpoints;
auto pmesh = SDFToMesh(junction, perimeterpoints, 75);
(*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(pmesh));
for (const auto& connection_pair : junction.GetConnections()) {
const auto& connection = connection_pair.second;
const auto& road = _data.GetRoads().at(connection.connecting_road);
for (auto&& lane_section : road.GetLaneSections()) {
for (auto&& lane_pair : lane_section.GetLanes()) {
const auto& lane = lane_pair.second;
if ( lane.GetType() == road::Lane::LaneType::Sidewalk ) {
boost::optional<element::Waypoint> sw =
GetWaypoint(road.GetId(), lane_pair.first, lane.GetDistance() + (lane.GetLength() * 0.5f));
if( GetWaypoint(ComputeTransform(*sw).location).get_ptr () == nullptr ){
sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane));
}
}
}
}
}
std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>();
for (auto& lane : sidewalk_lane_meshes) {
*sidewalk_mesh += *lane;
}
(*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh));
} else {
std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes;
for (const auto& connection_pair : junction.GetConnections()) {
const auto& connection = connection_pair.second;
const auto& road = _data.GetRoads().at(connection.connecting_road);
for (auto&& lane_section : road.GetLaneSections()) {
for (auto&& lane_pair : lane_section.GetLanes()) {
const auto& lane = lane_pair.second;
if (lane.GetType() != road::Lane::LaneType::Sidewalk) {
lane_meshes.push_back(mesh_factory.GenerateTesselated(lane));
}
else {
sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane));
}
}
}
}
std::unique_ptr<geom::Mesh> merged_mesh = std::make_unique<geom::Mesh>();
for (auto& lane : lane_meshes) {
*merged_mesh += *lane;
}
std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>();
for (auto& lane : sidewalk_lane_meshes) {
*sidewalk_mesh += *lane;
}
(*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(merged_mesh));
(*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh));
}
}
} // namespace road } // namespace road
} // namespace carla } // namespace carla

View File

@ -16,6 +16,7 @@
#include "carla/road/MapData.h" #include "carla/road/MapData.h"
#include "carla/road/RoadTypes.h" #include "carla/road/RoadTypes.h"
#include "carla/road/MeshFactory.h" #include "carla/road/MeshFactory.h"
#include "carla/geom/Vector3D.h"
#include "carla/rpc/OpendriveGenerationParameters.h" #include "carla/rpc/OpendriveGenerationParameters.h"
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -161,12 +162,16 @@ namespace road {
const rpc::OpendriveGenerationParameters& params) const; const rpc::OpendriveGenerationParameters& params) const;
std::map<road::Lane::LaneType , std::vector<std::unique_ptr<geom::Mesh>>> std::map<road::Lane::LaneType , std::vector<std::unique_ptr<geom::Mesh>>>
GenerateOrderedChunkedMesh( const rpc::OpendriveGenerationParameters& params) const; GenerateOrderedChunkedMeshInLocations( const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos) const;
/// Buids a mesh of all crosswalks based on the OpenDRIVE /// Buids a mesh of all crosswalks based on the OpenDRIVE
geom::Mesh GetAllCrosswalkMesh() const; geom::Mesh GetAllCrosswalkMesh() const;
std::vector<std::pair<geom::Transform, std::string>> GetTreesTransform( std::vector<std::pair<geom::Transform, std::string>> GetTreesTransform(
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
float distancebetweentrees, float distancebetweentrees,
float distancefromdrivinglineborder, float distancefromdrivinglineborder,
float s_offset = 0) const; float s_offset = 0) const;
@ -176,6 +181,8 @@ namespace road {
/// Buids a list of meshes related with LineMarkings /// Buids a list of meshes related with LineMarkings
std::vector<std::unique_ptr<geom::Mesh>> GenerateLineMarkings( std::vector<std::unique_ptr<geom::Mesh>> GenerateLineMarkings(
const rpc::OpendriveGenerationParameters& params, const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::vector<std::string>& outinfo ) const; std::vector<std::string>& outinfo ) const;
const std::unordered_map<SignId, std::unique_ptr<Signal>>& GetSignals() const { const std::unordered_map<SignId, std::unique_ptr<Signal>>& GetSignals() const {
@ -223,15 +230,32 @@ public:
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>
GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory, GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory,
const size_t index, const size_t number_of_roads_per_thread) const; const std::vector<RoadId>& RoadsID,
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, const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>* std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>*
juntion_out_mesh_list) const; juntion_out_mesh_list) const;
std::unique_ptr<geom::Mesh> SDFToMesh(const road::Junction& jinput, const std::vector<geom::Vector3D>& sdfinput, int grid_cells_per_dim) const; void GenerateSingleJunction(const carla::geom::MeshFactory& mesh_factory,
const JuncId Id,
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>*
junction_out_mesh_list) const;
// Return list of junction ID which are between those positions
std::vector<JuncId> FilterJunctionsByPosition(
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos) const;
// Return list of roads ID which are between those positions
std::vector<RoadId> FilterRoadsByPosition(
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos ) const;
std::unique_ptr<geom::Mesh> SDFToMesh(const road::Junction& jinput, const std::vector<geom::Vector3D>& sdfinput, int grid_cells_per_dim) const;
}; };
} // namespace road } // namespace road

View File

@ -825,11 +825,16 @@ namespace road {
for(const auto& junction : _map_data._junctions) { for(const auto& junction : _map_data._junctions) {
for(const auto& controller : junction.second._controllers) { for(const auto& controller : junction.second._controllers) {
auto it = _map_data._controllers.find(controller); auto it = _map_data._controllers.find(controller);
DEBUG_ASSERT(it != _map_data._controllers.end()); if(it != _map_data._controllers.end()){
it->second->_junctions.insert(junction.first); if( it->second != nullptr ){
for(const auto & signal : it->second->_signals) { it->second->_junctions.insert(junction.first);
auto signal_it = _map_data._signals.find(signal); for(const auto & signal : it->second->_signals) {
signal_it->second->_controllers.insert(controller); auto signal_it = _map_data._signals.find(signal);
if( signal_it->second != nullptr ){
signal_it->second->_controllers.insert(controller);
}
}
}
} }
} }
} }
@ -1052,7 +1057,7 @@ void MapBuilder::CreateController(
continue; continue;
} }
if(closest_waypoint_to_signal) { if(closest_waypoint_to_signal) {
auto road_transform = map.ComputeTransform(closest_waypoint_to_signal.get()); auto road_transform = map.ComputeTransform(closest_waypoint_to_signal.get());
auto distance_to_road = (road_transform.location -signal_position).Length(); auto distance_to_road = (road_transform.location -signal_position).Length();
double lane_width = map.GetLaneWidth(closest_waypoint_to_signal.get()); double lane_width = map.GetLaneWidth(closest_waypoint_to_signal.get());
int displacement_direction = 1; int displacement_direction = 1;

View File

@ -0,0 +1,228 @@
// Copyright (c) 2023 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 <https://opensource.org/licenses/MIT>.
#include "MapGenFunctionLibrary.h"
// Engine headers
#include "AssetRegistry/AssetRegistryModule.h"
#include "Materials/MaterialInstance.h"
#include "StaticMeshAttributes.h"
#include "RenderingThread.h"
// Carla C++ headers
// Carla plugin headers
DEFINE_LOG_CATEGORY(LogCarlaMapGenFunctionLibrary);
static const float OSMToCentimetersScaleFactor = 100.0f;
FMeshDescription UMapGenFunctionLibrary::BuildMeshDescriptionFromData(
const FProceduralCustomMesh& Data,
const TArray<FProcMeshTangent>& ParamTangents,
UMaterialInstance* MaterialInstance )
{
int32 VertexCount = Data.Vertices.Num();
int32 VertexInstanceCount = Data.Triangles.Num();
int32 PolygonCount = Data.Vertices.Num()/3;
FMeshDescription MeshDescription;
FStaticMeshAttributes AttributeGetter(MeshDescription);
AttributeGetter.Register();
TPolygonGroupAttributesRef<FName> PolygonGroupNames = AttributeGetter.GetPolygonGroupMaterialSlotNames();
TVertexAttributesRef<FVector> VertexPositions = AttributeGetter.GetVertexPositions();
TVertexInstanceAttributesRef<FVector> Tangents = AttributeGetter.GetVertexInstanceTangents();
TVertexInstanceAttributesRef<float> BinormalSigns = AttributeGetter.GetVertexInstanceBinormalSigns();
TVertexInstanceAttributesRef<FVector> Normals = AttributeGetter.GetVertexInstanceNormals();
TVertexInstanceAttributesRef<FVector4> Colors = AttributeGetter.GetVertexInstanceColors();
TVertexInstanceAttributesRef<FVector2D> UVs = AttributeGetter.GetVertexInstanceUVs();
// Calculate the totals for each ProcMesh element type
FPolygonGroupID PolygonGroupForSection;
MeshDescription.ReserveNewVertices(VertexCount);
MeshDescription.ReserveNewVertexInstances(VertexInstanceCount);
MeshDescription.ReserveNewPolygons(PolygonCount);
MeshDescription.ReserveNewEdges(PolygonCount * 2);
UVs.SetNumIndices(4);
// Create Materials
TMap<UMaterialInterface*, FPolygonGroupID> UniqueMaterials;
const int32 NumSections = 1;
UniqueMaterials.Reserve(1);
FPolygonGroupID NewPolygonGroup = MeshDescription.CreatePolygonGroup();
if( MaterialInstance != nullptr ){
UMaterialInterface *Material = MaterialInstance;
UniqueMaterials.Add(Material, NewPolygonGroup);
PolygonGroupNames[NewPolygonGroup] = Material->GetFName();
}else{
UE_LOG(LogCarla, Error, TEXT("MaterialInstance is nullptr"));
}
PolygonGroupForSection = NewPolygonGroup;
// Create the vertex
int32 NumVertex = Data.Vertices.Num();
TMap<int32, FVertexID> VertexIndexToVertexID;
VertexIndexToVertexID.Reserve(NumVertex);
for (int32 VertexIndex = 0; VertexIndex < NumVertex; ++VertexIndex)
{
const FVector &Vert = Data.Vertices[VertexIndex];
const FVertexID VertexID = MeshDescription.CreateVertex();
VertexPositions[VertexID] = Vert;
VertexIndexToVertexID.Add(VertexIndex, VertexID);
}
// Create the VertexInstance
int32 NumIndices = Data.Triangles.Num();
int32 NumTri = NumIndices / 3;
TMap<int32, FVertexInstanceID> IndiceIndexToVertexInstanceID;
IndiceIndexToVertexInstanceID.Reserve(NumVertex);
for (int32 IndiceIndex = 0; IndiceIndex < NumIndices; IndiceIndex++)
{
const int32 VertexIndex = Data.Triangles[IndiceIndex];
const FVertexID VertexID = VertexIndexToVertexID[VertexIndex];
const FVertexInstanceID VertexInstanceID =
MeshDescription.CreateVertexInstance(VertexID);
IndiceIndexToVertexInstanceID.Add(IndiceIndex, VertexInstanceID);
Normals[VertexInstanceID] = Data.Normals[VertexIndex];
if(ParamTangents.Num() == Data.Vertices.Num())
{
Tangents[VertexInstanceID] = ParamTangents[VertexIndex].TangentX;
BinormalSigns[VertexInstanceID] =
ParamTangents[VertexIndex].bFlipTangentY ? -1.f : 1.f;
}else{
}
Colors[VertexInstanceID] = FLinearColor(0,0,0);
if(Data.UV0.Num() == Data.Vertices.Num())
{
UVs.Set(VertexInstanceID, 0, Data.UV0[VertexIndex]);
}else{
UVs.Set(VertexInstanceID, 0, FVector2D(0,0));
}
UVs.Set(VertexInstanceID, 1, FVector2D(0,0));
UVs.Set(VertexInstanceID, 2, FVector2D(0,0));
UVs.Set(VertexInstanceID, 3, FVector2D(0,0));
}
for (int32 TriIdx = 0; TriIdx < NumTri; TriIdx++)
{
FVertexID VertexIndexes[3];
TArray<FVertexInstanceID> VertexInstanceIDs;
VertexInstanceIDs.SetNum(3);
for (int32 CornerIndex = 0; CornerIndex < 3; ++CornerIndex)
{
const int32 IndiceIndex = (TriIdx * 3) + CornerIndex;
const int32 VertexIndex = Data.Triangles[IndiceIndex];
VertexIndexes[CornerIndex] = VertexIndexToVertexID[VertexIndex];
VertexInstanceIDs[CornerIndex] =
IndiceIndexToVertexInstanceID[IndiceIndex];
}
// Insert a polygon into the mesh
MeshDescription.CreatePolygon(NewPolygonGroup, VertexInstanceIDs);
}
return MeshDescription;
}
UStaticMesh* UMapGenFunctionLibrary::CreateMesh(
const FProceduralCustomMesh& Data,
const TArray<FProcMeshTangent>& ParamTangents,
UMaterialInstance* MaterialInstance,
FString MapName,
FString FolderName,
FName MeshName)
{
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
UStaticMesh::FBuildMeshDescriptionsParams Params;
Params.bBuildSimpleCollision = true;
FString PackageName = "/Game/CustomMaps/" + MapName + "/Static/" + FolderName + "/" + MeshName.ToString();
if (!PlatformFile.DirectoryExists(*PackageName))
{
//PlatformFile.CreateDirectory(*PackageName);
}
FMeshDescription Description = BuildMeshDescriptionFromData(Data,ParamTangents, MaterialInstance);
if (Description.Polygons().Num() > 0)
{
UPackage* Package = CreatePackage(*PackageName);
check(Package);
UStaticMesh* Mesh = NewObject<UStaticMesh>( Package, MeshName, RF_Public | RF_Standalone);
Mesh->InitResources();
Mesh->LightingGuid = FGuid::NewGuid();
Mesh->StaticMaterials.Add(FStaticMaterial(MaterialInstance));
Mesh->BuildFromMeshDescriptions({ &Description }, Params);
Mesh->CreateBodySetup();
Mesh->BodySetup->CollisionTraceFlag = ECollisionTraceFlag::CTF_UseComplexAsSimple;
Mesh->BodySetup->CreatePhysicsMeshes();
// Build mesh from source
Mesh->NeverStream = false;
TArray<UObject*> CreatedAssets;
CreatedAssets.Add(Mesh);
// Notify asset registry of new asset
FAssetRegistryModule::AssetCreated(Mesh);
//UPackage::SavePackage(Package, Mesh, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *(MeshName.ToString()), GError, nullptr, true, true, SAVE_NoError);
Package->MarkPackageDirty();
return Mesh;
}
return nullptr;
}
FVector2D UMapGenFunctionLibrary::GetTransversemercProjection(float lat, float lon, float lat0, float lon0)
{
// earth radius in m
const float R = 6373000.0f;
float latt = FMath::DegreesToRadians(lat);
float lonn = FMath::DegreesToRadians(lon - lon0);
float latt0 = FMath::DegreesToRadians(lat0);
float eps = atan(tan(latt)/cos(lonn));
float nab = asinh(sin(lonn)/sqrt(tan(latt)*tan(latt)+cos(lonn)*cos(lonn)));
float x = R*nab;
float y = R*eps;
float eps0 = atan(tan(latt0)/cos(0));
float nab0 = asinh(sin(0)/sqrt(tan(latt0)*tan(latt0)+cos(0)*cos(0)));
float x0 = R*nab0;
float y0 = R*eps0;
FVector2D Result = FVector2D(x, -(y - y0)) * OSMToCentimetersScaleFactor;
return Result;
}
void UMapGenFunctionLibrary::SetThreadToSleep(float seconds){
//FGenericPlatformProcess::Sleep(seconds);
}
void UMapGenFunctionLibrary::FlushRenderingCommandsInBlueprint(){
FlushRenderingCommands(true);
FlushPendingDeleteRHIResources_GameThread();
}
void UMapGenFunctionLibrary::CleanupGEngine(){
GEngine->PerformGarbageCollectionAndCleanupActors();
#if WITH_EDITOR
FText TransResetText(FText::FromString("Clean up after Move actors to sublevels"));
if ( GEditor->Trans )
{
GEditor->Trans->Reset(TransResetText);
GEditor->Cleanse(true, true, TransResetText);
}
#endif
}

View File

@ -0,0 +1,54 @@
// Copyright (c) 2023 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 <https://opensource.org/licenses/MIT>.
#pragma once
// Engine headers
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MeshDescription.h"
#include "ProceduralMeshComponent.h"
// Carla C++ headers
// Carla plugin headers
#include "Carla/Util/ProceduralCustomMesh.h"
#include "MapGenFunctionLibrary.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogCarlaMapGenFunctionLibrary, Log, All);
UCLASS(BlueprintType)
class CARLA_API UMapGenFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static UStaticMesh* CreateMesh(
const FProceduralCustomMesh& Data,
const TArray<FProcMeshTangent>& ParamTangents,
UMaterialInstance* MaterialInstance,
FString MapName,
FString FolderName,
FName MeshName);
static FMeshDescription BuildMeshDescriptionFromData(
const FProceduralCustomMesh& Data,
const TArray<FProcMeshTangent>& ParamTangents,
UMaterialInstance* MaterialInstance );
UFUNCTION(BlueprintCallable)
static FVector2D GetTransversemercProjection(float lat, float lon, float lat0, float lon0);
UFUNCTION(BlueprintCallable)
static void SetThreadToSleep(float seconds);
UFUNCTION(BlueprintCallable)
static void FlushRenderingCommandsInBlueprint();
UFUNCTION(BlueprintCallable)
static void CleanupGEngine();
};

View File

@ -9,24 +9,24 @@
#include "ProceduralCustomMesh.generated.h" #include "ProceduralCustomMesh.generated.h"
/// A definition of a Carla Mesh. /// A definition of a Carla Mesh.
USTRUCT() USTRUCT(Blueprintable)
struct CARLA_API FProceduralCustomMesh struct CARLA_API FProceduralCustomMesh
{ {
GENERATED_BODY() GENERATED_BODY()
UPROPERTY() UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FVector> Vertices; TArray<FVector> Vertices;
UPROPERTY() UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<int32> Triangles; TArray<int32> Triangles;
UPROPERTY() UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FVector> Normals; TArray<FVector> Normals;
UPROPERTY() UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FVector2D> UV0; TArray<FVector2D> UV0;
UPROPERTY() UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FLinearColor> VertexColor; TArray<FLinearColor> VertexColor;
// This is commented due to an strange bug including ProceduralMeshComponent.h // This is commented due to an strange bug including ProceduralMeshComponent.h

View File

@ -18,7 +18,7 @@
{ {
"Name": "CarlaTools", "Name": "CarlaTools",
"Type": "Editor", "Type": "Editor",
"LoadingPhase": "PostEngineInit" "LoadingPhase": "Default"
} }
], ],
"Plugins": [ "Plugins": [
@ -37,6 +37,10 @@
{ {
"Name": "ProceduralMeshComponent", "Name": "ProceduralMeshComponent",
"Enabled": true "Enabled": true
},
{
"Name": "StreetMap",
"Enabled": true
} }
] ]
} }

View File

@ -0,0 +1,43 @@
#!/usr/bin/env python
import unreal
import argparse
import json
import os
import subprocess
"""Generic function for running a commandlet with its arguments."""
ue4_path = os.environ["UE4_ROOT"]
uproject_path = unreal.Paths.project_dir() + ("CarlaUE4.uproject")
run = "-run=%s" % ("GenerateTileCommandlet")
print("Before any Commandlet:")
argparser = argparse.ArgumentParser()
argparser.add_argument(
'-s', '--paramstring',
metavar='S',
default='',
type=str,
help='String to put as arguments')
args = argparser.parse_args()
arguments = args.paramstring
if os.name == "nt":
sys_name = "Win64"
editor_path = "%s/Engine/Binaries/%s/UE4Editor" % (ue4_path, sys_name)
command = [editor_path, uproject_path, run]
command.extend(arguments)
print("Commandlet:", command)
print("Arguments:", arguments)
subprocess.check_call(command, shell=True)
elif os.name == "posix":
sys_name = "Linux"
editor_path = "%s/Engine/Binaries/%s/UE4Editor" % (ue4_path, sys_name)
full_command = editor_path + " " + uproject_path + " " + run + " " + arguments
print("Commandlet:", full_command)
print("Arguments:", arguments)
subprocess.call([full_command], shell=True)

View File

@ -44,15 +44,15 @@ public class CarlaTools : ModuleRules
// ... add public include paths required here ... // ... add public include paths required here ...
} }
); );
PrivateIncludePaths.AddRange( PrivateIncludePaths.AddRange(
new string[] { new string[] {
// ... add other private include paths required here ... // ... add other private include paths required here ...
} }
); );
PublicDependencyModuleNames.AddRange( PublicDependencyModuleNames.AddRange(
new string[] new string[]
{ {
@ -64,8 +64,8 @@ public class CarlaTools : ModuleRules
// ... add other public dependencies that you statically link with here ... // ... add other public dependencies that you statically link with here ...
} }
); );
PrivateDependencyModuleNames.AddRange( PrivateDependencyModuleNames.AddRange(
new string[] new string[]
{ {
@ -82,15 +82,19 @@ public class CarlaTools : ModuleRules
"FoliageEdit", "FoliageEdit",
"MeshMergeUtilities", "MeshMergeUtilities",
"Carla", "Carla",
"StaticMeshDescription",
"PhysXVehicles", "PhysXVehicles",
"Json", "Json",
"JsonUtilities", "JsonUtilities",
"Networking", "Networking",
"Sockets", "Sockets",
"HTTP",
"RHI", "RHI",
"RenderCore", "RenderCore",
"MeshMergeUtilities" "MeshMergeUtilities",
// ... add private dependencies that you statically link with here ... "StreetMapImporting",
"StreetMapRuntime"
// ... add private dependencies that you statically link with here ...
} }
); );
if(UsingHoudini) if(UsingHoudini)
@ -145,7 +149,7 @@ public class CarlaTools : ModuleRules
foreach (string file in files) foreach (string file in files)
{ {
PublicAdditionalLibraries.Add(file); PublicAdditionalLibraries.Add(file);
} }
} }

View File

@ -0,0 +1,84 @@
// Copyright (c) 2021 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 <https://opensource.org/licenses/MIT>.
#include "GenerateTileCommandlet.h"
#include <iostream>
#include <fstream>
#if WITH_EDITOR
#include "FileHelpers.h"
#endif
#include "UObject/ConstructorHelpers.h"
DEFINE_LOG_CATEGORY(LogCarlaToolsMapGenerateTileCommandlet);
UGenerateTileCommandlet::UGenerateTileCommandlet()
{
#if WITH_EDITOR
ConstructorHelpers::FClassFinder<UOpenDriveToMap> OpenDrivelassFinder(TEXT("/CarlaTools/OnroadMapGenerator/BP_OpenDriveToMap"));
OpenDriveClass = OpenDrivelassFinder.Class;
#endif
}
UGenerateTileCommandlet::UGenerateTileCommandlet(const FObjectInitializer& Initializer)
: Super(Initializer)
{
#if WITH_EDITOR
ConstructorHelpers::FClassFinder<UOpenDriveToMap> OpenDrivelassFinder(TEXT("/CarlaTools/OnroadMapGenerator/BP_OpenDriveToMap"));
OpenDriveClass = OpenDrivelassFinder.Class;
#endif
}
#if WITH_EDITORONLY_DATA
int32 UGenerateTileCommandlet::Main(const FString &Params)
{
UE_LOG(LogCarlaToolsMapGenerateTileCommandlet, Log, TEXT("UGenerateTileCommandlet::Main Arguments %s"), *Params);
TArray<FString> Tokens;
TArray<FString> Switches;
TMap<FString,FString> ParamsMap;
ParseCommandLine(*Params, Tokens, Switches, ParamsMap );
std::string logstr = std::string(TCHAR_TO_UTF8(*Params));
std::ofstream file("CommandletParameters.txt", std::ios::app);
file << logstr << std::endl;
for( auto fstr : Tokens )
{
logstr = std::string(TCHAR_TO_UTF8(*fstr));
file << " Tokens " << logstr << std::endl;
}
for( auto fstr : Switches )
{
logstr = std::string(TCHAR_TO_UTF8(*fstr));
file << " SWITCHES " << logstr << std::endl;
}
for( auto PairMap : ParamsMap )
{
std::string key = std::string(TCHAR_TO_UTF8(*PairMap.Key));
std::string value = std::string(TCHAR_TO_UTF8(*PairMap.Value));
file << "Key: " << key << " Value: " << value << std::endl;
}
OpenDriveMap = NewObject<UOpenDriveToMap>(this, OpenDriveClass);
OpenDriveMap->FilePath = ParamsMap["FilePath"];
OpenDriveMap->BaseLevelName = ParamsMap["BaseLevelName"];
OpenDriveMap->OriginGeoCoordinates = FVector2D(FCString::Atof(*ParamsMap["GeoCoordsX"]),FCString::Atof(*ParamsMap["GeoCoordsY"]));
OpenDriveMap->CurrentTilesInXY = FIntVector(FCString::Atof(*ParamsMap["CTileX"]),FCString::Atof(*ParamsMap["CTileY"]), 0);
// Parse Params
OpenDriveMap->GenerateTile();
return 0;
}
#endif

View File

@ -0,0 +1,32 @@
// Copyright (c) 2023 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 <https://opensource.org/licenses/MIT>.
#include "DigitalTwinsBaseWidget.h"
#include "OpenDriveToMap.h"
static UOpenDriveToMap* OpenDriveToMapObject = nullptr;
UOpenDriveToMap* UDigitalTwinsBaseWidget::InitializeOpenDriveToMap(TSubclassOf<UOpenDriveToMap> BaseClass){
if( OpenDriveToMapObject == nullptr && BaseClass != nullptr ){
UE_LOG(LogCarlaTools, Error, TEXT("Creating New Object") );
OpenDriveToMapObject = NewObject<UOpenDriveToMap>(this, BaseClass);
}
return OpenDriveToMapObject;
}
UOpenDriveToMap* UDigitalTwinsBaseWidget::GetOpenDriveToMap(){
return OpenDriveToMapObject;
}
void UDigitalTwinsBaseWidget::SetOpenDriveToMap(UOpenDriveToMap* ToSet){
OpenDriveToMapObject = ToSet;
}
void UDigitalTwinsBaseWidget::DestroyOpenDriveToMap(){
OpenDriveToMapObject->ConditionalBeginDestroy();
OpenDriveToMapObject = nullptr;
}

View File

@ -10,6 +10,7 @@
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Kismet/KismetSystemLibrary.h" #include "Kismet/KismetSystemLibrary.h"
#include "FileHelpers.h" #include "FileHelpers.h"
#include "EditorLevelLibrary.h"
#include "Components/PrimitiveComponent.h" #include "Components/PrimitiveComponent.h"
void UHoudiniImporterWidget::CreateSubLevels(ALargeMapManager* LargeMapManager) void UHoudiniImporterWidget::CreateSubLevels(ALargeMapManager* LargeMapManager)
@ -46,8 +47,8 @@ void UHoudiniImporterWidget::MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Ac
FCarlaMapTile* Tile = LargeMapManager->GetCarlaMapTile(ActorLocation); FCarlaMapTile* Tile = LargeMapManager->GetCarlaMapTile(ActorLocation);
if(!Tile) if(!Tile)
{ {
UE_LOG(LogCarlaTools, Error, TEXT("Error: actor in location %s is outside the map"), UE_LOG(LogCarlaTools, Error, TEXT("Error: actor %s in location %s is outside the map"),
*ActorLocation.ToString()); *Actor->GetName(),*ActorLocation.ToString());
continue; continue;
} }
@ -70,14 +71,13 @@ void UHoudiniImporterWidget::MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Ac
{ {
continue; continue;
} }
UWorld* World = ActorList[0]->GetWorld();
UWorld* World = UEditorLevelLibrary::GetEditorWorld();
ULevelStreamingDynamic* StreamingLevel = Tile->StreamingLevel; ULevelStreamingDynamic* StreamingLevel = Tile->StreamingLevel;
UE_LOG(LogCarlaTools, Log, TEXT("Got Tile %s in location %s"),
*StreamingLevel->PackageNameToLoad.ToString(), *Tile->Location.ToString());
StreamingLevel->bShouldBlockOnLoad = true; StreamingLevel->bShouldBlockOnLoad = true;
StreamingLevel->SetShouldBeVisible(true); StreamingLevel->SetShouldBeVisible(true);
StreamingLevel->SetShouldBeLoaded(true); StreamingLevel->SetShouldBeLoaded(true);
ULevelStreaming* Level = ULevelStreaming* Level =
UEditorLevelUtils::AddLevelToWorld( UEditorLevelUtils::AddLevelToWorld(
World, *Tile->Name, ULevelStreamingDynamic::StaticClass(), FTransform()); World, *Tile->Name, ULevelStreamingDynamic::StaticClass(), FTransform());
int MovedActors = UEditorLevelUtils::MoveActorsToLevel(ActorList, Level, false, false); int MovedActors = UEditorLevelUtils::MoveActorsToLevel(ActorList, Level, false, false);
@ -86,15 +86,51 @@ void UHoudiniImporterWidget::MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Ac
FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr); FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr);
UEditorLevelUtils::RemoveLevelFromWorld(Level->GetLoadedLevel()); UEditorLevelUtils::RemoveLevelFromWorld(Level->GetLoadedLevel());
} }
GEngine->PerformGarbageCollectionAndCleanupActors();
FText TransResetText(FText::FromString("Clean up after Move actors to sublevels"));
if ( GEditor->Trans )
{
GEditor->Trans->Reset(TransResetText);
GEditor->Cleanse(true, true, TransResetText);
}
}
void UHoudiniImporterWidget::ForceStreamingLevelsToUnload( ALargeMapManager* LargeMapManager )
{
UWorld* World = UEditorLevelLibrary::GetGameWorld();
FIntVector NumTilesInXY = LargeMapManager->GetNumTilesInXY();
for(int x = 0; x < NumTilesInXY.X; ++x)
{
for(int y = 0; y < NumTilesInXY.Y; ++y)
{
FIntVector CurrentTileVector(x, y, 0);
FCarlaMapTile CarlaTile = LargeMapManager->GetCarlaMapTile(CurrentTileVector);
ULevelStreamingDynamic* StreamingLevel = CarlaTile.StreamingLevel;
ULevelStreaming* Level =
UEditorLevelUtils::AddLevelToWorld(
World, *CarlaTile.Name, ULevelStreamingDynamic::StaticClass(), FTransform());
FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr);
UEditorLevelUtils::RemoveLevelFromWorld(Level->GetLoadedLevel());
}
}
} }
void UHoudiniImporterWidget::MoveActorsToSubLevel(TArray<AActor*> Actors, ULevelStreaming* Level) void UHoudiniImporterWidget::MoveActorsToSubLevel(TArray<AActor*> Actors, ULevelStreaming* Level)
{ {
int MovedActors = UEditorLevelUtils::MoveActorsToLevel(Actors, Level, false, false); int MovedActors = UEditorLevelUtils::MoveActorsToLevel(Actors, Level, false, false);
// StreamingLevel->SetShouldBeLoaded(false);
UE_LOG(LogCarlaTools, Log, TEXT("Moved %d actors"), MovedActors); UE_LOG(LogCarlaTools, Log, TEXT("Moved %d actors"), MovedActors);
FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr); FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr);
UEditorLevelUtils::RemoveLevelFromWorld(Level->GetLoadedLevel()); UEditorLevelUtils::RemoveLevelFromWorld(Level->GetLoadedLevel());
FText TransResetText(FText::FromString("Clean up after Move actors to sublevels"));
if ( GEditor->Trans )
{
GEditor->Trans->Reset(TransResetText);
}
} }
void UHoudiniImporterWidget::UpdateGenericActorCoordinates( void UHoudiniImporterWidget::UpdateGenericActorCoordinates(
@ -102,8 +138,8 @@ void UHoudiniImporterWidget::UpdateGenericActorCoordinates(
{ {
FVector LocalLocation = Actor->GetActorLocation() - TileOrigin; FVector LocalLocation = Actor->GetActorLocation() - TileOrigin;
Actor->SetActorLocation(LocalLocation); Actor->SetActorLocation(LocalLocation);
UE_LOG(LogCarlaTools, Log, TEXT("New location %s"), UE_LOG(LogCarlaTools, Log, TEXT("%s New location %s"),
*LocalLocation.ToString()); *Actor->GetName(), *LocalLocation.ToString());
} }
void UHoudiniImporterWidget::UpdateInstancedMeshCoordinates( void UHoudiniImporterWidget::UpdateInstancedMeshCoordinates(
@ -133,13 +169,6 @@ void UHoudiniImporterWidget::UseCOMasActorLocation(TArray<AActor*> Actors)
FBodyInstance* BodyInstance = Primitive->GetBodyInstance(); FBodyInstance* BodyInstance = Primitive->GetBodyInstance();
FVector CenterOfMass = BodyInstance->COMNudge; FVector CenterOfMass = BodyInstance->COMNudge;
Actor->SetActorLocation(CenterOfMass); Actor->SetActorLocation(CenterOfMass);
UE_LOG(LogCarlaTools, Log, TEXT("Updating actor %s to %s"),
*Actor->GetName(), *CenterOfMass.ToString());
}
else
{
UE_LOG(LogCarlaTools, Log, TEXT("Not updating actor %s"),
*Actor->GetName());
} }
} }
} }
@ -147,7 +176,7 @@ void UHoudiniImporterWidget::UseCOMasActorLocation(TArray<AActor*> Actors)
bool UHoudiniImporterWidget::GetNumberOfClusters( bool UHoudiniImporterWidget::GetNumberOfClusters(
TArray<AActor*> ActorList, int& OutNumClusters) TArray<AActor*> ActorList, int& OutNumClusters)
{ {
for (AActor* Actor : ActorList) for (AActor* Actor : ActorList)
{ {
FString ObjectName = UKismetSystemLibrary::GetObjectName(Actor); FString ObjectName = UKismetSystemLibrary::GetObjectName(Actor);

View File

@ -61,24 +61,29 @@ void UMapPreviewUserWidget::ConnectToSocket(FString DatabasePath, FString Styles
// Send a message // Send a message
FString Message = "-C " + DatabasePath + " " + StylesheetPath + " " + FString::FromInt(Size); FString Message = "-C " + DatabasePath + " " + StylesheetPath + " " + FString::FromInt(Size);
SendStr(Message); if( !SendStr(Message) ){
return;
}
UE_LOG(LogTemp, Log, TEXT("Configuration Completed")); UE_LOG(LogTemp, Log, TEXT("Configuration Completed"));
} }
void UMapPreviewUserWidget::RenderMap(FString Latitude, FString Longitude, FString Zoom) void UMapPreviewUserWidget::RenderMap(FString Latitude, FString Longitude, FString Zoom)
{ {
FString Message = "-R " + Latitude + " " + Longitude + " " + Zoom; FString Message = "-R " + Latitude + " " + Longitude + " " + Zoom;
SendStr(Message); if( !SendStr(Message) ){
UE_LOG(LogTemp, Log, TEXT("Send Str failed"));
return;
}
TArray<uint8_t> ReceivedData; TArray<uint8_t> ReceivedData;
uint32 ReceivedDataSize = 0; uint32 ReceivedDataSize = 0;
{ {
SocketPtr->wait(boost::asio::ip::tcp::socket::wait_read); SocketPtr->wait(boost::asio::ip::tcp::socket::wait_read);
while (SocketPtr->available()) while (SocketPtr->available())
{ {
AsioStreamBuf Buffer; AsioStreamBuf Buffer;
std::size_t BytesReceived = std::size_t BytesReceived =
Asio::read(*SocketPtr, Buffer, Asio::transfer_at_least(2)); Asio::read(*SocketPtr, Buffer, Asio::transfer_at_least(2));
TArray<uint8_t> ThisReceivedData; TArray<uint8_t> ThisReceivedData;
const char* DataPtr = Asio::buffer_cast<const char*>(Buffer.data()); const char* DataPtr = Asio::buffer_cast<const char*>(Buffer.data());
@ -105,7 +110,7 @@ void UMapPreviewUserWidget::RenderMap(FString Latitude, FString Longitude, FStri
Region.DestY = 0; Region.DestY = 0;
Region.Width = Texture->GetSizeX(); Region.Width = Texture->GetSizeX();
Region.Height = Texture->GetSizeY(); Region.Height = Texture->GetSizeY();
FTexture2DResource* Resource = (FTexture2DResource*)Texture->Resource; FTexture2DResource* Resource = (FTexture2DResource*)Texture->Resource;
RHIUpdateTexture2D(Resource->GetTexture2DRHI(), 0, Region, Region.Width * sizeof(uint8_t) * 4, &NewData[0]); RHIUpdateTexture2D(Resource->GetTexture2DRHI(), 0, Region, Region.Width * sizeof(uint8_t) * 4, &NewData[0]);
} }
@ -116,13 +121,16 @@ void UMapPreviewUserWidget::RenderMap(FString Latitude, FString Longitude, FStri
FString UMapPreviewUserWidget::RecvCornersLatLonCoords() FString UMapPreviewUserWidget::RecvCornersLatLonCoords()
{ {
SendStr("-L"); if( !SendStr("-L") ){
UE_LOG(LogTemp, Error, TEXT("Error sending message: num bytes mismatch"));
return FString();
}
AsioStreamBuf Buffer; AsioStreamBuf Buffer;
std::size_t BytesReceived = std::size_t BytesReceived =
Asio::read(*SocketPtr, Buffer, Asio::transfer_at_least(2)); Asio::read(*SocketPtr, Buffer, Asio::transfer_at_least(2));
std::string BytesStr = Asio::buffer_cast<const char*>(Buffer.data()); std::string BytesStr = Asio::buffer_cast<const char*>(Buffer.data());
FString CoordStr = FString(BytesStr.size(), UTF8_TO_TCHAR(BytesStr.c_str())); FString CoordStr = FString(BytesStr.size(), UTF8_TO_TCHAR(BytesStr.c_str()));
UE_LOG(LogTemp, Log, TEXT("Received Coords %s"), *CoordStr); UE_LOG(LogTemp, Log, TEXT("Received Coords %s"), *CoordStr);
return CoordStr; return CoordStr;
@ -141,7 +149,10 @@ void UMapPreviewUserWidget::OpenServer()
void UMapPreviewUserWidget::CloseServer() void UMapPreviewUserWidget::CloseServer()
{ {
SendStr("-X"); if( !SendStr("-X") ){
UE_LOG(LogTemp, Error, TEXT("Error sending message"));
return;
}
} }
bool UMapPreviewUserWidget::SendStr(FString Msg) bool UMapPreviewUserWidget::SendStr(FString Msg)
@ -166,24 +177,29 @@ bool UMapPreviewUserWidget::SendStr(FString Msg)
if (BytesSent != MessageStr.size()) if (BytesSent != MessageStr.size())
{ {
UE_LOG(LogTemp, Error, TEXT("Error sending message: num bytes mismatch")); UE_LOG(LogTemp, Error, TEXT("Error sending message: num bytes mismatch"));
return true; return false;
} }
else else
{ {
UE_LOG(LogTemp, Log, TEXT("Sent %d bytes"), BytesSent); UE_LOG(LogTemp, Log, TEXT("Sent %d bytes"), BytesSent);
return false; return true;
} }
} }
void UMapPreviewUserWidget::UpdateLatLonCoordProperties() void UMapPreviewUserWidget::UpdateLatLonCoordProperties()
{ {
FString CoordStr = RecvCornersLatLonCoords(); FString CoordStr = RecvCornersLatLonCoords();
if(CoordStr.Len() == 0)
{
UE_LOG(LogTemp, Error, TEXT("Error during update of lat lon coord properties. Check osm server connection or use OSMURL to generate map") );
return;
}
UE_LOG(LogTemp, Log, TEXT("Received laton [%s] with size %d"), *CoordStr, CoordStr.Len()); UE_LOG(LogTemp, Log, TEXT("Received laton [%s] with size %d"), *CoordStr, CoordStr.Len());
TArray<FString> CoordsArray; TArray<FString> CoordsArray;
CoordStr.ParseIntoArray(CoordsArray, TEXT("&"), true); CoordStr.ParseIntoArray(CoordsArray, TEXT("&"), true);
check(CoordsArray.Num() >= 4); ensure(CoordsArray.Num() == 4);
TopRightLat = FCString::Atof(*CoordsArray[0]); TopRightLat = FCString::Atof(*CoordsArray[0]);
TopRightLon = FCString::Atof(*CoordsArray[1]); TopRightLon = FCString::Atof(*CoordsArray[1]);

View File

@ -3,6 +3,7 @@
#undef CreateDirectory #undef CreateDirectory
#include "Online/CustomFileDownloader.h" #include "Online/CustomFileDownloader.h"
#include "OpenDriveToMap.h"
#include "HttpModule.h" #include "HttpModule.h"
#include "Http.h" #include "Http.h"
#include "Misc/FileHelper.h" #include "Misc/FileHelper.h"
@ -20,16 +21,16 @@ void UCustomFileDownloader::ConvertOSMInOpenDrive(FString FilePath, float Lat_0,
// We use the LoadFileToString to load the file into // We use the LoadFileToString to load the file into
if (FFileHelper::LoadFileToString(FileContent, *FilePath, FFileHelper::EHashOptions::None)) if (FFileHelper::LoadFileToString(FileContent, *FilePath, FFileHelper::EHashOptions::None))
{ {
UE_LOG(LogCarla, Warning, TEXT("FileManipulation: Text From File: %s"), *FilePath); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: Text From File: %s"), *FilePath);
} }
else else
{ {
UE_LOG(LogCarla, Warning, TEXT("FileManipulation: Did not load text from file")); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: Did not load text from file"));
} }
} }
else else
{ {
UE_LOG(LogCarla, Warning, TEXT("File: %s does not exist"), *FilePath); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("File: %s does not exist"), *FilePath);
return; return;
} }
std::string OsmFile = std::string(TCHAR_TO_UTF8(*FileContent)); std::string OsmFile = std::string(TCHAR_TO_UTF8(*FileContent));
@ -45,17 +46,18 @@ void UCustomFileDownloader::ConvertOSMInOpenDrive(FString FilePath, float Lat_0,
// We use the LoadFileToString to load the file into // We use the LoadFileToString to load the file into
if (FFileHelper::SaveStringToFile(FString(OpenDriveFile.c_str()), *FilePath)) if (FFileHelper::SaveStringToFile(FString(OpenDriveFile.c_str()), *FilePath))
{ {
UE_LOG(LogCarla, Warning, TEXT("FileManipulation: Sucsesfuly Written: \"%s\" to the text file"), *FilePath); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: Sucsesfuly Written: \"%s\" to the text file"), *FilePath);
} }
else else
{ {
UE_LOG(LogCarla, Warning, TEXT("FileManipulation: Failed to write FString to file.")); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: Failed to write FString to file."));
} }
} }
void UCustomFileDownloader::StartDownload() void UCustomFileDownloader::StartDownload()
{ {
UE_LOG(LogCarla, Log, TEXT("FHttpDownloader CREATED")); UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("FHttpDownloader CREATED"));
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("Map Name Is %s"), *ResultFileName );
FHttpDownloader *Download = new FHttpDownloader("GET", Url, ResultFileName, DownloadDelegate); FHttpDownloader *Download = new FHttpDownloader("GET", Url, ResultFileName, DownloadDelegate);
Download->Run(); Download->Run();
} }
@ -65,10 +67,16 @@ FHttpDownloader::FHttpDownloader(const FString &InVerb, const FString &InUrl, co
{ {
} }
FHttpDownloader::FHttpDownloader()
{
}
void FHttpDownloader::Run(void) void FHttpDownloader::Run(void)
{ {
UE_LOG(LogCarla, Log, TEXT("Starting download [%s] Url=[%s]"), *Verb, *Url); UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("Starting download [%s] Url=[%s]"), *Verb, *Url);
TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest(); TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("Map Name Is %s"), *Filename );
Request->OnProcessRequestComplete().BindRaw(this, &FHttpDownloader::RequestComplete); Request->OnProcessRequestComplete().BindRaw(this, &FHttpDownloader::RequestComplete);
Request->SetURL(Url); Request->SetURL(Url);
Request->SetVerb(Verb); Request->SetVerb(Verb);
@ -77,31 +85,29 @@ void FHttpDownloader::Run(void)
void FHttpDownloader::RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) void FHttpDownloader::RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded)
{ {
if (!HttpResponse.IsValid()) if (!HttpResponse.IsValid() )
{ {
UE_LOG(LogCarla, Log, TEXT("Download failed. NULL response")); UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("Download failed. NULL response"));
} }
else else
{ {
// If we do not get success responses codes we do not do anything // If we do not get success responses codes we do not do anything
if (HttpResponse->GetResponseCode() < 200 || 300 <= HttpResponse->GetResponseCode()) if (HttpResponse->GetResponseCode() < 200 || 300 <= HttpResponse->GetResponseCode())
{ {
UE_LOG(LogCarla, Error, TEXT("Error during download [%s] Url=[%s] Response=[%d]"), UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("Error during download [%s] Url=[%s] Response=[%d]"),
*HttpRequest->GetVerb(), *HttpRequest->GetVerb(),
*HttpRequest->GetURL(), *HttpRequest->GetURL(),
HttpResponse->GetResponseCode()); HttpResponse->GetResponseCode());
delete this;
return; return;
} }
UE_LOG(LogCarla, Log, TEXT("Completed download [%s] Url=[%s] Response=[%d]"), UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("Completed download [%s] Url=[%s] Response=[%d]"),
*HttpRequest->GetVerb(), *HttpRequest->GetVerb(),
*HttpRequest->GetURL(), *HttpRequest->GetURL(),
HttpResponse->GetResponseCode()); HttpResponse->GetResponseCode());
HttpRequest->OnProcessRequestComplete().Unbind(); FString CurrentFile = FPaths::ProjectContentDir() + "CustomMaps/" + (Filename) + "/OpenDrive/";
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FHttpDownloader::RequestComplete CurrentFile %s."), *CurrentFile);
FString CurrentFile = FPaths::ProjectContentDir() + "CustomMaps/" + Filename + "/OpenDrive/";
// We will use this FileManager to deal with the file. // We will use this FileManager to deal with the file.
IPlatformFile &FileManager = FPlatformFileManager::Get().GetPlatformFile(); IPlatformFile &FileManager = FPlatformFileManager::Get().GetPlatformFile();
@ -116,14 +122,14 @@ void FHttpDownloader::RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponse
// We use the LoadFileToString to load the file into // We use the LoadFileToString to load the file into
if (FFileHelper::SaveStringToFile(StringToWrite, *CurrentFile, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM)) if (FFileHelper::SaveStringToFile(StringToWrite, *CurrentFile, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM))
{ {
UE_LOG(LogCarla, Warning, TEXT("FileManipulation: Sucsesfuly Written ")); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: Sucsesfuly Written "));
DelegateToCall.ExecuteIfBound();
} }
else else
{ {
UE_LOG(LogCarla, Warning, TEXT("FileManipulation: Failed to write FString to file.")); UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: Failed to write FString to file."));
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FileManipulation: CurrentFile %s."), *CurrentFile);
} }
} }
DelegateToCall.ExecuteIfBound();
delete this; delete this;
} }

View File

@ -64,10 +64,10 @@ void UUSDImporterWidget::ImportUSDVehicle(
} }
// Import Wheel and suspension data // Import Wheel and suspension data
TArray<FUSDCARLAWheelData> WheelsData = UUSDCARLAInterface::GetUSDWheelData(USDPath); TArray<FUSDCARLAWheelData> WheelsData = UUSDCARLAInterface::GetUSDWheelData(USDPath);
auto CreateVehicleWheel = auto CreateVehicleWheel =
[&](const FUSDCARLAWheelData& WheelData, [&](const FUSDCARLAWheelData& WheelData,
TSubclassOf<UVehicleWheel> TemplateClass, TSubclassOf<UVehicleWheel> TemplateClass,
const FString &PackagePathName) const FString &PackagePathName)
-> TSubclassOf<UVehicleWheel> -> TSubclassOf<UVehicleWheel>
{ {
// Get a reference to the editor subsystem // Get a reference to the editor subsystem
@ -161,7 +161,7 @@ bool UUSDImporterWidget::MergeStaticMeshComponents(
} }
TArray<UObject*> UUSDImporterWidget::MergeMeshComponents( TArray<UObject*> UUSDImporterWidget::MergeMeshComponents(
TArray<UPrimitiveComponent*> ComponentsToMerge, TArray<UPrimitiveComponent*> ComponentsToMerge,
const FString& DestMesh) const FString& DestMesh)
{ {
if(!ComponentsToMerge.Num()) if(!ComponentsToMerge.Num())
@ -275,7 +275,7 @@ FVehicleMeshParts UUSDImporterWidget::SplitVehicleParts(
} }
else if (ComponentName.Contains("Collision")) else if (ComponentName.Contains("Collision"))
{ {
} }
else else
{ {
@ -286,7 +286,7 @@ FVehicleMeshParts UUSDImporterWidget::SplitVehicleParts(
} }
} }
if(ComponentName.Contains("glass") || if(ComponentName.Contains("glass") ||
IsChildrenOf(Component, "glass")) IsChildrenOf(Component, "glass"))
{ {
GlassComponents.Add(Component); GlassComponents.Add(Component);
@ -330,7 +330,7 @@ FMergedVehicleMeshParts UUSDImporterWidget::GenerateVehicleMeshes(
const FVehicleMeshParts& VehicleMeshParts, const FString& DestPath) const FVehicleMeshParts& VehicleMeshParts, const FString& DestPath)
{ {
FMergedVehicleMeshParts Result; FMergedVehicleMeshParts Result;
auto MergePart = auto MergePart =
[](TArray<UPrimitiveComponent*> Components, const FString& DestMeshPath) [](TArray<UPrimitiveComponent*> Components, const FString& DestMeshPath)
-> UStaticMesh* -> UStaticMesh*
{ {
@ -430,7 +430,7 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
UWorld* World, UWorld* World,
UClass* BaseClass, UClass* BaseClass,
USkeletalMesh* NewSkeletalMesh, USkeletalMesh* NewSkeletalMesh,
const FString &DestPath, const FString &DestPath,
const FMergedVehicleMeshParts& VehicleMeshes, const FMergedVehicleMeshParts& VehicleMeshes,
const FWheelTemplates& WheelTemplates) const FWheelTemplates& WheelTemplates)
{ {
@ -468,11 +468,11 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
} }
// Get the skeletal mesh and modify it to match the vehicle parameters // Get the skeletal mesh and modify it to match the vehicle parameters
USkeletalMeshComponent* SkeletalMeshComponent = Cast<USkeletalMeshComponent>( USkeletalMeshComponent* SkeletalMeshComponent = Cast<USkeletalMeshComponent>(
TemplateActor->GetComponentByClass(USkeletalMeshComponent::StaticClass())); TemplateActor->GetComponentByClass(USkeletalMeshComponent::StaticClass()));
if(!SkeletalMeshComponent) if(!SkeletalMeshComponent)
{ {
UE_LOG(LogCarlaTools, Log, TEXT("Skeletal mesh component not found")); UE_LOG(LogCarlaTools, Log, TEXT("Skeletal mesh component not found"));
return nullptr; return nullptr;
} }
USkeletalMesh* SkeletalMesh = SkeletalMeshComponent->SkeletalMesh; USkeletalMesh* SkeletalMesh = SkeletalMeshComponent->SkeletalMesh;
@ -506,7 +506,7 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
ULocalLightComponent * LightComponent = NewObject<ULocalLightComponent>(TemplateActor, LightClass, FName(*FixedLightName)); ULocalLightComponent * LightComponent = NewObject<ULocalLightComponent>(TemplateActor, LightClass, FName(*FixedLightName));
LightComponent->RegisterComponent(); LightComponent->RegisterComponent();
LightComponent->AttachToComponent( LightComponent->AttachToComponent(
TemplateActor->GetRootComponent(), TemplateActor->GetRootComponent(),
FAttachmentTransformRules::KeepRelativeTransform); FAttachmentTransformRules::KeepRelativeTransform);
LightComponent->SetRelativeLocation(Light.Location); // Set the position of the light relative to the actor LightComponent->SetRelativeLocation(Light.Location); // Set the position of the light relative to the actor
LightComponent->SetIntensityUnits(ELightUnits::Lumens); LightComponent->SetIntensityUnits(ELightUnits::Lumens);
@ -514,7 +514,7 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
LightComponent->SetVolumetricScatteringIntensity(0.f); LightComponent->SetVolumetricScatteringIntensity(0.f);
if (FixedLightName.Contains("high_beam")) if (FixedLightName.Contains("high_beam"))
{ {
USpotLightComponent* SpotLight = USpotLightComponent* SpotLight =
Cast<USpotLightComponent>(LightComponent); Cast<USpotLightComponent>(LightComponent);
SpotLight->SetRelativeRotation(FRotator(-1.5f, 0, 0)); SpotLight->SetRelativeRotation(FRotator(-1.5f, 0, 0));
SpotLight->SetAttenuationRadius(5000.f); SpotLight->SetAttenuationRadius(5000.f);
@ -525,7 +525,7 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
} }
else if (FixedLightName.Contains("low_beam")) else if (FixedLightName.Contains("low_beam"))
{ {
USpotLightComponent* SpotLight = USpotLightComponent* SpotLight =
Cast<USpotLightComponent>(LightComponent); Cast<USpotLightComponent>(LightComponent);
LightComponent->SetRelativeRotation(FRotator(-3.f, 0, 0)); LightComponent->SetRelativeRotation(FRotator(-3.f, 0, 0));
LightComponent->SetAttenuationRadius(3000.f); LightComponent->SetAttenuationRadius(3000.f);
@ -553,11 +553,11 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
Setup.WheelClass = WheelTemplates.WheelRR; Setup.WheelClass = WheelTemplates.WheelRR;
Setup.BoneName = "Wheel_Rear_Right"; Setup.BoneName = "Wheel_Rear_Right";
WheelSetups.Add(Setup); WheelSetups.Add(Setup);
ACarlaWheeledVehicle* CarlaVehicle = ACarlaWheeledVehicle* CarlaVehicle =
Cast<ACarlaWheeledVehicle>(TemplateActor); Cast<ACarlaWheeledVehicle>(TemplateActor);
if(CarlaVehicle) if(CarlaVehicle)
{ {
UWheeledVehicleMovementComponent4W* MovementComponent = UWheeledVehicleMovementComponent4W* MovementComponent =
Cast<UWheeledVehicleMovementComponent4W>( Cast<UWheeledVehicleMovementComponent4W>(
CarlaVehicle->GetVehicleMovementComponent()); CarlaVehicle->GetVehicleMovementComponent());
MovementComponent->WheelSetups = WheelSetups; MovementComponent->WheelSetups = WheelSetups;
@ -582,12 +582,12 @@ AActor* UUSDImporterWidget::GenerateNewVehicleBlueprint(
} }
bool UUSDImporterWidget::EditSkeletalMeshBones( bool UUSDImporterWidget::EditSkeletalMeshBones(
USkeletalMesh* NewSkeletalMesh, USkeletalMesh* NewSkeletalMesh,
const TMap<FString, FTransform> &NewBoneTransforms) const TMap<FString, FTransform> &NewBoneTransforms)
{ {
if(!NewSkeletalMesh) if(!NewSkeletalMesh)
{ {
UE_LOG(LogCarlaTools, Log, TEXT("Skeletal mesh invalid")); UE_LOG(LogCarlaTools, Log, TEXT("Skeletal mesh invalid"));
return false; return false;
} }
FReferenceSkeleton& ReferenceSkeleton = NewSkeletalMesh->RefSkeleton; FReferenceSkeleton& ReferenceSkeleton = NewSkeletalMesh->RefSkeleton;
@ -599,7 +599,7 @@ bool UUSDImporterWidget::EditSkeletalMeshBones(
int32 BoneIdx = SkeletonModifier.FindBoneIndex(FName(*BoneName)); int32 BoneIdx = SkeletonModifier.FindBoneIndex(FName(*BoneName));
if (BoneIdx == INDEX_NONE) if (BoneIdx == INDEX_NONE)
{ {
UE_LOG(LogCarlaTools, Log, TEXT("Bone %s not found"), *BoneName); UE_LOG(LogCarlaTools, Log, TEXT("Bone %s not found"), *BoneName);
} }
UE_LOG(LogCarlaTools, Log, TEXT("Bone %s corresponds to index %d"), *BoneName, BoneIdx); UE_LOG(LogCarlaTools, Log, TEXT("Bone %s corresponds to index %d"), *BoneName, BoneIdx);
SkeletonModifier.UpdateRefPoseTransform(BoneIdx, BoneTransform); SkeletonModifier.UpdateRefPoseTransform(BoneIdx, BoneTransform);
@ -608,7 +608,7 @@ bool UUSDImporterWidget::EditSkeletalMeshBones(
NewSkeletalMesh->MarkPackageDirty(); NewSkeletalMesh->MarkPackageDirty();
UPackage* Package = NewSkeletalMesh->GetOutermost(); UPackage* Package = NewSkeletalMesh->GetOutermost();
return UPackage::SavePackage( return UPackage::SavePackage(
Package, NewSkeletalMesh, Package, NewSkeletalMesh,
EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone,
*(Package->GetName()), GError, nullptr, true, true, SAVE_NoError); *(Package->GetName()), GError, nullptr, true, true, SAVE_NoError);
} }

View File

@ -0,0 +1,46 @@
// Copyright (c) 2019 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 <https://opensource.org/licenses/MIT>.
#pragma once
#include "Runtime/Engine/Classes/Engine/ObjectLibrary.h"
#include "Commandlets/Commandlet.h"
#include <compiler/disable-ue4-macros.h>
#include <compiler/enable-ue4-macros.h>
#include "OpenDriveToMap.h"
#include "GenerateTileCommandlet.generated.h"
// Each commandlet should generate only 1 Tile
DECLARE_LOG_CATEGORY_EXTERN(LogCarlaToolsMapGenerateTileCommandlet, Log, All);
UCLASS()
class CARLATOOLS_API UGenerateTileCommandlet
: public UCommandlet
{
GENERATED_BODY()
public:
/// Default constructor.
UGenerateTileCommandlet();
UGenerateTileCommandlet(const FObjectInitializer &);
#if WITH_EDITORONLY_DATA
virtual int32 Main(const FString &Params) override;
#endif // WITH_EDITORONLY_DATA
UPROPERTY()
UOpenDriveToMap* OpenDriveMap;
UPROPERTY()
UClass* OpenDriveClass;
};

View File

@ -0,0 +1,34 @@
// Copyright (c) 2023 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 <https://opensource.org/licenses/MIT>.
#pragma once
#include "CoreMinimal.h"
#include "EditorUtilityWidget.h"
#include "CarlaTools.h"
#include "DigitalTwinsBaseWidget.generated.h"
class UOpenDriveToMap;
UCLASS(BlueprintType)
class CARLATOOLS_API UDigitalTwinsBaseWidget : public UEditorUtilityWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
UOpenDriveToMap* InitializeOpenDriveToMap(TSubclassOf<UOpenDriveToMap> BaseClass);
UFUNCTION(BlueprintPure)
UOpenDriveToMap* GetOpenDriveToMap();
UFUNCTION(BlueprintCallable)
void SetOpenDriveToMap(UOpenDriveToMap* ToSet);
UFUNCTION(BlueprintCallable)
void DestroyOpenDriveToMap();
};

View File

@ -18,13 +18,16 @@ UCLASS(BlueprintType)
class CARLATOOLS_API UHoudiniImporterWidget : public UEditorUtilityWidget class CARLATOOLS_API UHoudiniImporterWidget : public UEditorUtilityWidget
{ {
GENERATED_BODY() GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget") UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void CreateSubLevels(ALargeMapManager* LargeMapManager); static void CreateSubLevels(ALargeMapManager* LargeMapManager);
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget") UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Actors, ALargeMapManager* LargeMapManager); static void MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Actors, ALargeMapManager* LargeMapManager);
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void ForceStreamingLevelsToUnload( ALargeMapManager* LargeMapManager );
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget") UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void MoveActorsToSubLevel(TArray<AActor*> Actors, ULevelStreaming* Level); static void MoveActorsToSubLevel(TArray<AActor*> Actors, ULevelStreaming* Level);

View File

@ -6,45 +6,26 @@
#include "Interfaces/IHttpRequest.h" #include "Interfaces/IHttpRequest.h"
#include "CustomFileDownloader.generated.h" #include "CustomFileDownloader.generated.h"
/** /**
* *
*/ */
DECLARE_DELEGATE(FDownloadComplete) DECLARE_DELEGATE(FDownloadComplete)
UCLASS(Blueprintable)
class CARLA_API UCustomFileDownloader : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void StartDownload();
UFUNCTION(BlueprintCallable)
void ConvertOSMInOpenDrive(FString FilePath, float Lat_0 = 0, float Lon_0 = 0);
FString ResultFileName; struct FHttpDownloader
FString Url;
FDownloadComplete DownloadDelegate;
private:
void RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded);
FString Payload;
};
class FHttpDownloader
{ {
public: public:
FHttpDownloader();
/** /**
* *
* @param Verb - verb to use for request (GET,POST,DELETE,etc) * @param Verb - verb to use for request (GET,POST,DELETE,etc)
* @param Url - url address to connect to * @param Url - url address to connect to
*/ */
FHttpDownloader( const FString& InVerb, const FString& InUrl, const FString& InFilename, FDownloadComplete& Delegate ); FHttpDownloader( const FString& InVerb, const FString& InUrl, const FString& InFilename, FDownloadComplete& Delegate );
// Kick off the Http request and wait for delegate to be called // Kick off the Http request and wait for delegate to be called
void Run(void); void Run(void);
/** /**
* Delegate called when the request completes * Delegate called when the request completes
@ -61,3 +42,26 @@ private:
FString Filename; FString Filename;
FDownloadComplete DelegateToCall; FDownloadComplete DelegateToCall;
}; };
UCLASS(Blueprintable)
class CARLATOOLS_API UCustomFileDownloader : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void StartDownload();
UFUNCTION(BlueprintCallable)
void ConvertOSMInOpenDrive(FString FilePath, float Lat_0 = 0, float Lon_0 = 0);
FString ResultFileName;
FString Url;
FDownloadComplete DownloadDelegate;
private:
void RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded);
FString Payload;
};

View File

@ -6,6 +6,8 @@
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "ProceduralMeshComponent.h" #include "ProceduralMeshComponent.h"
#include "Math/Vector2D.h" #include "Math/Vector2D.h"
#include "EditorUtilityActor.h"
#include "EditorUtilityObject.h"
#include <compiler/disable-ue4-macros.h> #include <compiler/disable-ue4-macros.h>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -23,11 +25,13 @@ class UMaterialInstance;
* *
*/ */
UCLASS(Blueprintable, BlueprintType) UCLASS(Blueprintable, BlueprintType)
class CARLATOOLS_API UOpenDriveToMap : public UObject class CARLATOOLS_API UOpenDriveToMap : public UEditorUtilityObject
{ {
GENERATED_BODY() GENERATED_BODY()
#if WITH_EDITOR
public: public:
UOpenDriveToMap();
~UOpenDriveToMap();
UFUNCTION() UFUNCTION()
void ConvertOSMInOpenDrive(); void ConvertOSMInOpenDrive();
@ -36,12 +40,47 @@ public:
void CreateMap(); void CreateMap();
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void CreateTerrain(const int MeshGridSize, const float MeshGridSectionSize, void CreateTerrain(const int MeshGridSize, const float MeshGridSectionSize);
const class UTexture2D* HeightmapTexture);
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void CreateTerrainMesh(const int MeshIndex, const FVector2D Offset, const int GridSize, const float GridSectionSize, void CreateTerrainMesh(const int MeshIndex, const FVector2D Offset, const int GridSize, const float GridSectionSize);
const class UTexture2D* HeightmapTexture, class UTextureRenderTarget2D* RoadMask);
UFUNCTION(BlueprintCallable)
float GetHeight(float PosX, float PosY,bool bDrivingLane = false);
UFUNCTION(BlueprintCallable)
static AActor* SpawnActorWithCheckNoCollisions(UClass* ActorClassToSpawn, FTransform Transform);
UFUNCTION(BlueprintCallable)
float GetDistanceToDrivingLaneBorder(FVector Location) const{
return DistanceToLaneBorder(CarlaMap, Location);
}
UFUNCTION(BlueprintCallable)
bool GetIsInRoad(FVector Location) const {
return IsInRoad(CarlaMap, Location);
}
UFUNCTION(BlueprintCallable)
void GenerateTileStandalone();
UFUNCTION(BlueprintCallable)
void GenerateTile();
UFUNCTION(BlueprintCallable)
bool GoNextTile();
UFUNCTION(BlueprintCallable)
void ReturnToMainLevel();
UFUNCTION(BlueprintCallable)
void CorrectPositionForAllActorsInCurrentTile();
UFUNCTION(BlueprintCallable)
FString GetStringForCurrentTile();
UFUNCTION(BlueprintCallable)
AActor* SpawnActorInEditorWorld(UClass* Class, FVector Location, FRotator Rotation);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="File") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="File")
FString FilePath; FString FilePath;
@ -70,45 +109,97 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Defaults") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Defaults")
UMaterialInstance* DefaultLandscapeMaterial; UMaterialInstance* DefaultLandscapeMaterial;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Defaults")
UTexture2D* DefaultHeightmap;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" ) UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" )
float DistanceBetweenTrees = 50.0f; float DistanceBetweenTrees = 50.0f;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" ) UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" )
float DistanceFromRoadEdge = 3.0f; float DistanceFromRoadEdge = 3.0f;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Stage" )
bool bHasStarted = false;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Stage" )
bool bRoadsFinished = false;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Stage" )
bool bMapLoaded = false;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
FVector MinPosition;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
FVector MaxPosition;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
float TileSize;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
FVector Tile0Offset;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
bool bTileFinished;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
FIntVector NumTilesInXY;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
FIntVector CurrentTilesInXY;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="TileGeneration" )
FString BaseLevelName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Heightmap")
UTexture2D* DefaultHeightmap;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Heightmap" )
FVector WorldEndPosition;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Heightmap" )
FVector WorldOriginPosition;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Heightmap" )
float MinHeight;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Heightmap" )
float MaxHeight;
protected: protected:
UFUNCTION( BlueprintCallable )
void SaveMap();
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
TArray<AActor*> GenerateMiscActors(float Offset); TArray<AActor*> GenerateMiscActors(float Offset, FVector MinLocation, FVector MaxLocation );
UFUNCTION( BlueprintImplementableEvent ) UFUNCTION( BlueprintImplementableEvent )
void GenerationFinished(); void GenerationFinished(FVector MinLocation, FVector MaxLocation);
UFUNCTION( BlueprintImplementableEvent )
void DownloadFinished();
UFUNCTION( BlueprintImplementableEvent )
void ExecuteTileCommandlet();
UFUNCTION( BlueprintCallable )
void MoveActorsToSubLevels(TArray<AActor*> ActorsToMove);
private: private:
UFUNCTION() UFUNCTION()
void OpenFileDialog(); void OpenFileDialog();
UFUNCTION() UFUNCTION(BlueprintCallable)
void LoadMap(); void LoadMap();
void GenerateAll(const boost::optional<carla::road::Map>& CarlaMap); void GenerateAll(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
void GenerateRoadMesh(const boost::optional<carla::road::Map>& CarlaMap); void GenerateRoadMesh(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
void GenerateSpawnPoints(const boost::optional<carla::road::Map>& CarlaMap); void GenerateSpawnPoints(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
void GenerateTreePositions(const boost::optional<carla::road::Map>& CarlaMap); void GenerateTreePositions(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
void GenerateLaneMarks(const boost::optional<carla::road::Map>& CarlaMap); void GenerateLaneMarks(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
float GetHeight(float PosX, float PosY,bool bDrivingLane = false);
carla::rpc::OpendriveGenerationParameters opg_parameters; carla::rpc::OpendriveGenerationParameters opg_parameters;
boost::optional<carla::road::Map> CarlaMap; boost::optional<carla::road::Map> CarlaMap;
UStaticMesh* CreateStaticMeshAsset(UProceduralMeshComponent* ProcMeshComp, int32 MeshIndex, FString FolderName);
TArray<UStaticMesh*> CreateStaticMeshAssets();
FTransform GetSnappedPosition(FTransform Origin); FTransform GetSnappedPosition(FTransform Origin);
float GetHeightForLandscape(FVector Origin); float GetHeightForLandscape(FVector Origin);
@ -117,20 +208,16 @@ private:
FVector &location, FVector &location,
int32_t lane_type = static_cast<int32_t>(carla::road::Lane::LaneType::Driving)) const; int32_t lane_type = static_cast<int32_t>(carla::road::Lane::LaneType::Driving)) const;
bool IsInRoad(const boost::optional<carla::road::Map>& ParamCarlaMap,
FVector &location) const;
void InitTextureData();
UPROPERTY() UPROPERTY()
UCustomFileDownloader* FileDownloader; UCustomFileDownloader* FileDownloader;
UPROPERTY() UPROPERTY()
TArray<AActor*> ActorMeshList;
UPROPERTY()
TArray<AActor*> LaneMarkerActorList;
UPROPERTY()
TArray<UStaticMesh*> MeshesToSpawn;
UPROPERTY()
TArray<FString> RoadType;
UPROPERTY()
TArray<UProceduralMeshComponent*> RoadMesh;
UPROPERTY()
TArray<AActor*> Landscapes; TArray<AActor*> Landscapes;
UPROPERTY() UPROPERTY()
UTexture2D* Heightmap; UTexture2D* Heightmap;
#endif
}; };

View File

@ -20,8 +20,8 @@ UENUM(BlueprintType)
enum ERegionOfInterestType enum ERegionOfInterestType
{ {
NONE_REGION, NONE_REGION,
TERRAIN_REGION, TERRAIN_REGION,
WATERBODIES_REGION, // Not Supported yet WATERBODIES_REGION, // Not Supported yet
VEGETATION_REGION, VEGETATION_REGION,
MISC_SPREADED_ACTORS_REGION, MISC_SPREADED_ACTORS_REGION,
MISC_SPECIFIC_LOCATION_ACTORS_REGION, MISC_SPECIFIC_LOCATION_ACTORS_REGION,
@ -47,7 +47,7 @@ struct CARLATOOLS_API FRoiTile
int Y; int Y;
public: public:
FRoiTile() : X(-1), Y(-1) FRoiTile() : X(-1), Y(-1)
{}; {};
FRoiTile(int X, int Y) FRoiTile(int X, int Y)
@ -108,7 +108,7 @@ FORCEINLINE uint32 GetTypeHash(const FRoiTile& Thing)
} }
/** /**
* *
*/ */
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct CARLATOOLS_API FCarlaRegionOfInterest struct CARLATOOLS_API FCarlaRegionOfInterest
@ -141,8 +141,8 @@ struct CARLATOOLS_API FCarlaRegionOfInterest
template <typename R> template <typename R>
static FORCEINLINE bool IsTileInRegionsSet(FRoiTile RoiTile, TMap<FRoiTile, R> RoisMap) static FORCEINLINE bool IsTileInRegionsSet(FRoiTile RoiTile, TMap<FRoiTile, R> RoisMap)
{ {
static_assert(TIsDerivedFrom<R, FCarlaRegionOfInterest>::IsDerived, static_assert(TIsDerivedFrom<R, FCarlaRegionOfInterest>::IsDerived,
"ROIs Map Value type is not an URegionOfInterest derived type."); "ROIs Map Value type is not an URegionOfInterest derived type.");
return RoisMap.Contains(RoiTile); return RoisMap.Contains(RoiTile);
} }
@ -154,7 +154,7 @@ struct CARLATOOLS_API FCarlaRegionOfInterest
{ {
return false; return false;
} }
// Checking if the two regions have the same tiles. // Checking if the two regions have the same tiles.
TMap<FRoiTile, int> TileCount; TMap<FRoiTile, int> TileCount;
for(FRoiTile Tile : Other.TilesList) for(FRoiTile Tile : Other.TilesList)
@ -191,7 +191,7 @@ struct CARLATOOLS_API FVegetationROI : public FCarlaRegionOfInterest
UPROPERTY(BlueprintReadWrite) UPROPERTY(BlueprintReadWrite)
TArray<UProceduralFoliageSpawner*> FoliageSpawners; TArray<UProceduralFoliageSpawner*> FoliageSpawners;
FVegetationROI() : FCarlaRegionOfInterest() FVegetationROI() : FCarlaRegionOfInterest()
{ {
this->FoliageSpawners.Empty(); this->FoliageSpawners.Empty();
@ -230,12 +230,12 @@ struct CARLATOOLS_API FTerrainROI : public FCarlaRegionOfInterest
UPROPERTY(BlueprintReadWrite) UPROPERTY(BlueprintReadWrite)
UTextureRenderTarget2D* RoiHeightmapRenderTarget; UTextureRenderTarget2D* RoiHeightmapRenderTarget;
FTerrainROI() : FCarlaRegionOfInterest(), RoiMaterialInstance() FTerrainROI() : FCarlaRegionOfInterest(), RoiMaterialInstance(), RoiHeightmapRenderTarget()
{} {}
/** /**
* This function checks if a tile is on the boundary of a region of interest * This function checks if a tile is on the boundary of a region of interest
* *
* @param RoiTile The tile we're checking * @param RoiTile The tile we're checking
* @param RoisMap The map of RoiTiles to Rois. * @param RoisMap The map of RoiTiles to Rois.
* @param OutUp Is there a tile above this one? * @param OutUp Is there a tile above this one?
@ -276,7 +276,7 @@ struct CARLATOOLS_API FMiscSpreadedActorsROI : public FCarlaRegionOfInterest
{} {}
}; };
/// A struct that is used to store the information of a region of interest that is used to /// A struct that is used to store the information of a region of interest that is used to
/// spawn actors in specific locations. /// spawn actors in specific locations.
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct CARLATOOLS_API FMiscSpecificLocationActorsROI : public FCarlaRegionOfInterest struct CARLATOOLS_API FMiscSpecificLocationActorsROI : public FCarlaRegionOfInterest
@ -295,7 +295,11 @@ struct CARLATOOLS_API FMiscSpecificLocationActorsROI : public FCarlaRegionOfInte
UPROPERTY(BlueprintReadWrite) UPROPERTY(BlueprintReadWrite)
float MaxRotationRange; float MaxRotationRange;
FMiscSpecificLocationActorsROI() : FCarlaRegionOfInterest(), ActorClass(), ActorLocation(0.0f) FMiscSpecificLocationActorsROI() : FCarlaRegionOfInterest(),
ActorClass(),
ActorLocation(0.0f),
MinRotationRange(0.0f),
MaxRotationRange(0.0f)
{} {}
}; };

View File

@ -20,8 +20,8 @@ set USAGE_STRING=Usage: %FILE_N% [-h^|--help] [--rebuild] [--build] [--clean] [-
set REMOVE_INTERMEDIATE=false set REMOVE_INTERMEDIATE=false
set BUILD_OSM2ODR=false set BUILD_OSM2ODR=false
set GIT_PULL=true set GIT_PULL=true
set CURRENT_OSM2ODR_COMMIT=03f2f1de6dcbfde41f2af464829d96b582fc2909 set CURRENT_OSM2ODR_COMMIT=1835e1e9538d0778971acc8b19b111834aae7261
set OSM2ODR_BRANCH=carla_osm2odr set OSM2ODR_BRANCH=aaron/defaultsidewalkwidth
set OSM2ODR_REPO=https://github.com/carla-simulator/sumo.git set OSM2ODR_REPO=https://github.com/carla-simulator/sumo.git
:arg-parse :arg-parse

View File

@ -14,8 +14,8 @@ END
REMOVE_INTERMEDIATE=false REMOVE_INTERMEDIATE=false
BUILD_OSM2ODR=false BUILD_OSM2ODR=false
GIT_PULL=true GIT_PULL=true
CURRENT_OSM2ODR_COMMIT=03f2f1de6dcbfde41f2af464829d96b582fc2909 CURRENT_OSM2ODR_COMMIT=1835e1e9538d0778971acc8b19b111834aae7261
OSM2ODR_BRANCH=carla_osm2odr OSM2ODR_BRANCH=aaron/defaultsidewalkwidth
OSM2ODR_REPO=https://github.com/carla-simulator/sumo.git OSM2ODR_REPO=https://github.com/carla-simulator/sumo.git
OPTS=`getopt -o h --long help,rebuild,build,clean,carsim,no-pull -n 'parse-options' -- "$@"` OPTS=`getopt -o h --long help,rebuild,build,clean,carsim,no-pull -n 'parse-options' -- "$@"`
@ -101,7 +101,7 @@ if ${BUILD_OSM2ODR} ; then
-DPROJ_LIBRARY=${CARLA_BUILD_FOLDER}/proj-install/lib/libproj.a \ -DPROJ_LIBRARY=${CARLA_BUILD_FOLDER}/proj-install/lib/libproj.a \
-DXercesC_INCLUDE_DIR=${CARLA_BUILD_FOLDER}/xerces-c-3.2.3-install/include \ -DXercesC_INCLUDE_DIR=${CARLA_BUILD_FOLDER}/xerces-c-3.2.3-install/include \
-DXercesC_LIBRARY=${CARLA_BUILD_FOLDER}/xerces-c-3.2.3-install/lib/libxerces-c.a -DXercesC_LIBRARY=${CARLA_BUILD_FOLDER}/xerces-c-3.2.3-install/lib/libxerces-c.a
ninja osm2odr ninja osm2odr
ninja install ninja install
@ -111,7 +111,7 @@ if ${BUILD_OSM2ODR} ; then
LLVM_BASENAME=llvm-8.0 LLVM_BASENAME=llvm-8.0
LLVM_INCLUDE="$UE4_ROOT/Engine/Source/ThirdParty/Linux/LibCxx/include/c++/v1" LLVM_INCLUDE="$UE4_ROOT/Engine/Source/ThirdParty/Linux/LibCxx/include/c++/v1"
LLVM_LIBPATH="$UE4_ROOT/Engine/Source/ThirdParty/Linux/LibCxx/lib/Linux/x86_64-unknown-linux-gnu" LLVM_LIBPATH="$UE4_ROOT/Engine/Source/ThirdParty/Linux/LibCxx/lib/Linux/x86_64-unknown-linux-gnu"
echo $LLVM_INCLUDE echo $LLVM_INCLUDE
echo $LLVM_LIBPATH echo $LLVM_LIBPATH

View File

@ -0,0 +1,89 @@
@REM @echo off
setlocal enabledelayedexpansion
rem Run it through a cmd with the x64 Visual C++ Toolset enabled.
set LOCAL_PATH=%~dp0
set FILE_N=-[%~n0]:
rem Print batch params (debug purpose)
echo %FILE_N% [Batch params]: %*
rem ============================================================================
rem -- Parse arguments ---------------------------------------------------------
rem ============================================================================
set DOC_STRING=Build LibCarla.
set USAGE_STRING=Usage: %FILE_N% [-h^|--help] [--rebuild] [--build] [--clean] [--no-pull]
set BUILD_STREETMAP=false
set GIT_PULL=true
set CURRENT_STREETMAP_COMMIT=260273d6b7c3f28988cda31fd33441de7e272958
set STREETMAP_BRANCH=master
set STREETMAP_REPO=https://github.com/carla-simulator/StreetMap.git
:arg-parse
if not "%1"=="" (
if "%1"=="--rebuild" (
set REMOVE_INTERMEDIATE=true
set BUILD_STREETMAP=true
)
if "%1"=="--build" (
set BUILD_STREETMAP=true
)
if "%1"=="--no-pull" (
set GIT_PULL=false
)
if "%1"=="--clean" (
set REMOVE_INTERMEDIATE=true
)
if "%1"=="-h" (
echo %DOC_STRING%
echo %USAGE_STRING%
GOTO :eof
)
if "%1"=="--help" (
echo %DOC_STRING%
echo %USAGE_STRING%
GOTO :eof
)
shift
goto :arg-parse
)
rem ============================================================================
rem -- Local Variables ---------------------------------------------------------
rem ============================================================================
rem Set the visual studio solution directory
rem
set CARLA_PLUGINS_PATH=%ROOT_PATH:/=\%Unreal\CarlaUE4\Plugins\
set CARLA_STREETMAP_PLUGINS_PATH=%ROOT_PATH:/=\%Unreal\CarlaUE4\Plugins\StreetMap\
rem Build STREETMAP
if %GIT_PULL% == true (
if not exist "%CARLA_STREETMAP_PLUGINS_PATH%" git clone -b %STREETMAP_BRANCH% %STREETMAP_REPO% %CARLA_STREETMAP_PLUGINS_PATH%
cd "%CARLA_STREETMAP_PLUGINS_PATH%"
git fetch
git checkout %CURRENT_STREETMAP_COMMIT%
)
goto success
rem ============================================================================
rem -- Messages and Errors -----------------------------------------------------
rem ============================================================================
:success
if %BUILD_STREETMAP% == true echo %FILE_N% STREETMAP has been successfully installed in "%CARLA_PLUGINS_PATH%"!
goto good_exit
:good_exit
endlocal
exit /b 0
:bad_exit
endlocal
exit /b %errorlevel%

View File

@ -0,0 +1,90 @@
#! /bin/bash
DOC_STRING="Download StreetMapUE4 Plugin."
USAGE_STRING=$(cat <<- END
Usage: $0 [-h|--help]
commands
[--clean] Clean intermediate files.
[--rebuild] Clean and rebuild both configurations.
END
)
REMOVE_INTERMEDIATE=false
BUILD_STREETMAP=false
GIT_PULL=true
CURRENT_STREETMAP_COMMIT=260273d6b7c3f28988cda31fd33441de7e272958
STREETMAP_BRANCH=master
STREETMAP_REPO=https://github.com/carla-simulator/StreetMap.git
OPTS=`getopt -o h --long build,rebuild,clean, -n 'parse-options' -- "$@"`
eval set -- "$OPTS"
while [[ $# -gt 0 ]]; do
case "$1" in
--rebuild )
REMOVE_INTERMEDIATE=true;
BUILD_STREETMAP=true;
shift ;;
--build )
BUILD_STREETMAP=true;
shift ;;
--no-pull )
GIT_PULL=false
shift ;;
--clean )
REMOVE_INTERMEDIATE=true;
shift ;;
-h | --help )
echo "$DOC_STRING"
echo "$USAGE_STRING"
exit 1
;;
* )
shift ;;
esac
done
source $(dirname "$0")/Environment.sh
if ! { ${REMOVE_INTERMEDIATE} || ${BUILD_STREETMAP}; }; then
fatal_error "Nothing selected to be done."
fi
# ==============================================================================
# -- Clean intermediate files --------------------------------------------------
# ==============================================================================
if ${REMOVE_INTERMEDIATE} ; then
log "Cleaning intermediate files and folders."
UE4_INTERMEDIATE_FOLDERS="Binaries Build Intermediate DerivedDataCache"
pushd "${CARLAUE4_STREETMAP_FOLDER}" >/dev/null
rm -Rf ${UE4_INTERMEDIATE_FOLDERS}
popd >/dev/null
fi
# ==============================================================================
# -- Build library -------------------------------------------------------------
# ==============================================================================
if ${BUILD_STREETMAP} ; then
log "Downloading STREETMAP plugin."
if ${GIT_PULL} ; then
if [ ! -d ${CARLAUE4_STREETMAP_FOLDER} ] ; then
git clone -b ${STREETMAP_BRANCH} ${STREETMAP_REPO} ${CARLAUE4_STREETMAP_FOLDER}
fi
cd ${CARLAUE4_STREETMAP_FOLDER}
git fetch
git checkout ${CURRENT_STREETMAP_COMMIT}
fi
fi
log "StreetMap Success!"

View File

@ -3,7 +3,8 @@ default: help
help: help:
@less ${CARLA_BUILD_TOOLS_FOLDER}/Linux.mk.help @less ${CARLA_BUILD_TOOLS_FOLDER}/Linux.mk.help
launch: LibCarla.server.release osm2odr launch: LibCarla.server.release osm2odr downloadplugins
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --build $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --build --launch $(ARGS) @${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --build --launch $(ARGS)
launch-only: launch-only:
@ -27,6 +28,7 @@ clean.LibCarla:
clean.PythonAPI: clean.PythonAPI:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --clean @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --clean
clean.CarlaUE4Editor: clean.CarlaUE4Editor:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --clean $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --clean @${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --clean
clean.osm2odr: clean.osm2odr:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --clean @${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --clean
@ -36,9 +38,11 @@ rebuild: setup
@${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --rebuild @${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --rebuild
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --rebuild @${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --rebuild
@${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rebuild $(ARGS) @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rebuild $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --rebuild $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --rebuild $(ARGS) @${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --rebuild $(ARGS)
hard-clean: hard-clean:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --clean $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --hard-clean @${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --hard-clean
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --clean @${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --clean
@${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --clean @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --clean
@ -79,7 +83,8 @@ examples:
run-examples: run-examples:
@for D in ${CARLA_EXAMPLES_FOLDER}/*; do [ -d "$${D}" ] && make -C $${D} run.only; done @for D in ${CARLA_EXAMPLES_FOLDER}/*; do [ -d "$${D}" ] && make -C $${D} run.only; done
CarlaUE4Editor: LibCarla.server.release osm2odr CarlaUE4Editor: LibCarla.server.release osm2odr downloadplugins
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --build $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --build $(ARGS) @${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --build $(ARGS)
.PHONY: PythonAPI .PHONY: PythonAPI
@ -125,7 +130,7 @@ LibCarla.client.release: setup
LibCarla.client.rss: LibCarla.client.rss.debug LibCarla.client.rss.release LibCarla.client.rss: LibCarla.client.rss.debug LibCarla.client.rss.release
LibCarla.client.rss.debug: setup ad-rss LibCarla.client.rss.debug: setup ad-rss
@${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --client --debug --rss @${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --client --debug --rss
LibCarla.client.rss.release: setup ad-rss LibCarla.client.rss.release: setup ad-rss
@${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --client --release --rss @${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --client --release --rss
@ -133,7 +138,7 @@ LibCarla.client.rss.release: setup ad-rss
plugins: plugins:
@${CARLA_BUILD_TOOLS_FOLDER}/Plugins.sh $(ARGS) @${CARLA_BUILD_TOOLS_FOLDER}/Plugins.sh $(ARGS)
setup: setup downloadplugins:
@${CARLA_BUILD_TOOLS_FOLDER}/Setup.sh $(ARGS) @${CARLA_BUILD_TOOLS_FOLDER}/Setup.sh $(ARGS)
ad-rss: ad-rss:
@ -153,3 +158,6 @@ osm2odr:
osmrenderer: osmrenderer:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSMRenderer.sh @${CARLA_BUILD_TOOLS_FOLDER}/BuildOSMRenderer.sh
downloadplugins:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --build $(ARGS)

View File

@ -289,7 +289,7 @@ for PACKAGE_NAME in "${PACKAGES[@]}" ; do if [[ ${PACKAGE_NAME} != "Carla" ]] ;
# MAPS_TO_COOK is read into an array as tokens separated by IFS # MAPS_TO_COOK is read into an array as tokens separated by IFS
read -ra ADDR <<< "$MAPS_TO_COOK" read -ra ADDR <<< "$MAPS_TO_COOK"
for i in "${ADDR[@]}"; do # access each element of array for i in "${ADDR[@]}"; do # access each element of array
XODR_FILE_PATH="${CARLAUE4_ROOT_FOLDER}/Content${i:5}" XODR_FILE_PATH="${CARLAUE4_ROOT_FOLDER}/Content${i:5}"
MAP_NAME=${XODR_FILE_PATH##*/} MAP_NAME=${XODR_FILE_PATH##*/}
XODR_FILE=$(find "${CARLAUE4_ROOT_FOLDER}/Content" -name "${MAP_NAME}.xodr" -print -quit) XODR_FILE=$(find "${CARLAUE4_ROOT_FOLDER}/Content" -name "${MAP_NAME}.xodr" -print -quit)
@ -318,13 +318,13 @@ for PACKAGE_NAME in "${PACKAGES[@]}" ; do if [[ ${PACKAGE_NAME} != "Carla" ]] ;
done done
done done
rm -Rf "./CarlaUE4/Metadata" rm -Rf "./CarlaUE4/Metadata"
rm -Rf "./CarlaUE4/Plugins" rm -Rf "./CarlaUE4/Plugins"
rm -Rf "./CarlaUE4/Content/${PACKAGE_NAME}/Maps/${PROPS_MAP_NAME}" rm -Rf "./CarlaUE4/Content/${PACKAGE_NAME}/Maps/${PROPS_MAP_NAME}"
rm -f "./CarlaUE4/AssetRegistry.bin" rm -f "./CarlaUE4/AssetRegistry.bin"
if ${DO_TARBALL} ; then if ${DO_TARBALL} ; then
if ${SINGLE_PACKAGE} ; then if ${SINGLE_PACKAGE} ; then
tar -rf ${DESTINATION} * tar -rf ${DESTINATION} *
else else

View File

@ -1,5 +1,5 @@
@echo off @echo off
setlocal setlocal enabledelayedexpansion
rem BAT script that downloads and generates rem BAT script that downloads and generates
rem rpclib, gtest and boost libraries for CARLA (carla.org). rem rpclib, gtest and boost libraries for CARLA (carla.org).
@ -54,7 +54,7 @@ if not "%1"=="" (
if "%1"=="--help" ( if "%1"=="--help" (
goto help goto help
) )
shift shift
goto :arg-parse goto :arg-parse
) )

View File

@ -32,3 +32,6 @@ CMAKE_CONFIG_FILE=${CARLA_BUILD_FOLDER}/CMakeLists.txt.in
LIBCARLA_TEST_CONTENT_FOLDER=${CARLA_BUILD_FOLDER}/test-content LIBCARLA_TEST_CONTENT_FOLDER=${CARLA_BUILD_FOLDER}/test-content
CARLA_EXAMPLES_FOLDER=${CURDIR}/Examples CARLA_EXAMPLES_FOLDER=${CURDIR}/Examples
CARLAUE4_ADDPLUGINS_FOLDER=${CURDIR}/Unreal/CarlaUE4/Plugins
CARLAUE4_STREETMAP_FOLDER=${CARLAUE4_ADDPLUGINS_FOLDER}/Streetmap

View File

@ -71,9 +71,10 @@ client: setup
LibCarla: setup LibCarla: setup
@"${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.bat" --server --client --generator "$(GENERATOR)" @"${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.bat" --server --client --generator "$(GENERATOR)"
setup: setup: downloadplugin
@"${CARLA_BUILD_TOOLS_FOLDER}/Setup.bat" --boost-toolset msvc-14.2 --generator "$(GENERATOR)" $(ARGS) @"${CARLA_BUILD_TOOLS_FOLDER}/Setup.bat" --boost-toolset msvc-14.2 --generator "$(GENERATOR)" $(ARGS)
.PHONY: Plugins .PHONY: Plugins
plugins: plugins:
@"${CARLA_BUILD_TOOLS_FOLDER}/Plugins.bat" $(ARGS) @"${CARLA_BUILD_TOOLS_FOLDER}/Plugins.bat" $(ARGS)
@ -86,3 +87,6 @@ osm2odr:
osmrenderer: osmrenderer:
@"${CARLA_BUILD_TOOLS_FOLDER}/BuildOSMRenderer.bat" @"${CARLA_BUILD_TOOLS_FOLDER}/BuildOSMRenderer.bat"
downloadplugin:
@"${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.bat" --build $(ARGS)