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
Plugins
!Unreal/CarlaUE4/Plugins
Unreal/CarlaUE4/Plugins/Streetmap
Unreal/CarlaUE4/Plugins/HoudiniEngine
/ExportedMaps
/Import/*
!/Import/README.md

View File

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

View File

@ -1135,27 +1135,33 @@ namespace road {
}
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);
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::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();
size_t num_roads_per_thread = 20;
const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
size_t num_roads = RoadsIDToGenerate.size();
size_t num_roads_per_thread = 30;
size_t num_threads = (num_roads / num_roads_per_thread) + 1;
num_threads = num_threads > 1 ? num_threads : 1;
std::vector<std::thread> workers;
std::mutex write_mutex;
std::cout << "Generating " << std::to_string(num_roads) << " roads" << std::endl;
for ( size_t i = 0; i < num_threads; ++i ) {
std::thread neworker(
[this, &write_mutex, &mesh_factory, &road_out_mesh_list, i, num_roads_per_thread]() {
[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::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);
for ( auto&& pair : Current ) {
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);
}
}
std::cout << "Generated " << std::to_string(num_roads) << " roads" << std::endl;
return road_out_mesh_list;
}
std::vector<std::pair<geom::Transform, std::string>> Map::GetTreesTransform(
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
float distancebetweentrees,
float distancefromdrivinglineborder,
float s_offset) const {
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()) {
for (auto &&lane_section : road.GetLaneSections()) {
LaneId min_lane = 0;
@ -1212,13 +1224,13 @@ namespace road {
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);
if( lane ) {
double s_current = lane_section.GetDistance() + s_offset;
const double s_end = lane_section.GetDistance() + lane_section.GetLength();
while(s_current < s_end){
if(lane->GetWidth(s_current) != 0.0f){
const auto edges = lane->GetCornerPositions(s_current, 0);
geom::Vector3D director = edges.second - edges.first;
geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder;
@ -1226,6 +1238,7 @@ namespace road {
geom::Transform treeTransform(treeposition, lanetransform.rotation);
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;
}
@ -1275,15 +1288,19 @@ namespace road {
/// Buids a list of meshes related with LineMarkings
std::vector<std::unique_ptr<geom::Mesh>> Map::GenerateLineMarkings(
const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::vector<std::string>& outinfo ) const
{
std::vector<std::unique_ptr<geom::Mesh>> LineMarks;
geom::MeshFactory mesh_factory(params);
for ( auto&& pair : _data.GetRoads() ) {
if ( pair.second.IsJunction() ) {
continue;
const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
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);
@ -1308,91 +1325,126 @@ namespace road {
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>
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
{
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;
if( endoffset >= _data.GetRoads().size() ) {
endoffset = _data.GetRoads().size();
}
auto end = std::next( _data.GetRoads().begin(), endoffset );
size_t end = RoadsId.size();
for (auto pair = start; pair != end && pair != _data.GetRoads().end(); ++pair) {
const auto& road = pair->second;
for (int i = start; i < endoffset && i < end; ++i) {
const auto& road = _data.GetRoads().at(RoadsId[i]);
if (!road.IsJunction()) {
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;
}
void Map::GenerateJunctions(const carla::geom::MeshFactory& mesh_factory,
const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::map<road::Lane::LaneType,
std::vector<std::unique_ptr<geom::Mesh>>>* junction_out_mesh_list) const {
for (const auto& junc_pair : _data.GetJunctions()) {
const auto& junction = junc_pair.second;
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;
std::vector<JuncId> JunctionsToGenerate = FilterJunctionsByPosition(minpos, maxpos);
size_t num_junctions = JunctionsToGenerate.size();
std::cout << "Generating " << std::to_string(num_junctions) << " junctions" << std::endl;
size_t junctionindex = 0;
size_t num_junctions_per_thread = 5;
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);
(*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(pmesh));
for ( size_t i = 0; i < num_threads; ++i ) {
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()) {
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) {
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));
size_t minimum = 0;
if( (i + 1) * num_junctions_per_thread < num_junctions ){
minimum = (i + 1) * num_junctions_per_thread;
}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));
minimum = num_junctions;
}
else {
sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane));
std::cout << "Generating Junctions between " << std::to_string(i * num_junctions_per_thread) << " and " << std::to_string(minimum) << std::endl;
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> 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;
});
workers.push_back(std::move(neworker));
}
(*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));
for (size_t i = 0; i < workers.size(); ++i) {
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,
const std::vector<geom::Vector3D>& sdfinput,
int grid_cells_per_dim) const {
@ -1441,42 +1493,18 @@ namespace road {
geom::Mesh out_mesh;
for (auto& cv : mesh.vertices) {
geom::Vector3D newvertex;
newvertex.x = cv.x;
newvertex.y = cv.y;
newvertex.z = cv.z;
if ( std::find( out_mesh.GetVertices().begin(), out_mesh.GetVertices().end(), newvertex) == out_mesh.GetVertices().end() ) {
out_mesh.AddVertex(newvertex);
}
}
auto finalvertices = out_mesh.GetVertices();
for (auto ct : mesh.triangles) {
auto cv = mesh.vertices[ct[1]];
geom::Vector3D newvertex;
newvertex.x = cv.x;
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);
out_mesh.AddIndex(ct[1] + 1);
out_mesh.AddIndex(ct[0] + 1);
out_mesh.AddIndex(ct[2] + 1);
}
for (auto& cv : out_mesh.GetVertices() ) {
@ -1493,5 +1521,73 @@ namespace road {
}
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 carla

View File

@ -16,6 +16,7 @@
#include "carla/road/MapData.h"
#include "carla/road/RoadTypes.h"
#include "carla/road/MeshFactory.h"
#include "carla/geom/Vector3D.h"
#include "carla/rpc/OpendriveGenerationParameters.h"
#include <boost/optional.hpp>
@ -161,12 +162,16 @@ namespace road {
const rpc::OpendriveGenerationParameters& params) const;
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
geom::Mesh GetAllCrosswalkMesh() const;
std::vector<std::pair<geom::Transform, std::string>> GetTreesTransform(
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
float distancebetweentrees,
float distancefromdrivinglineborder,
float s_offset = 0) const;
@ -176,6 +181,8 @@ namespace road {
/// Buids a list of meshes related with LineMarkings
std::vector<std::unique_ptr<geom::Mesh>> GenerateLineMarkings(
const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::vector<std::string>& outinfo ) 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>>>
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,
const rpc::OpendriveGenerationParameters& params,
const geom::Vector3D& minpos,
const geom::Vector3D& maxpos,
std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>*
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

View File

@ -825,15 +825,20 @@ namespace road {
for(const auto& junction : _map_data._junctions) {
for(const auto& controller : junction.second._controllers) {
auto it = _map_data._controllers.find(controller);
DEBUG_ASSERT(it != _map_data._controllers.end());
if(it != _map_data._controllers.end()){
if( it->second != nullptr ){
it->second->_junctions.insert(junction.first);
for(const auto & signal : it->second->_signals) {
auto signal_it = _map_data._signals.find(signal);
if( signal_it->second != nullptr ){
signal_it->second->_controllers.insert(controller);
}
}
}
}
}
}
}
void MapBuilder::CreateJunctionBoundingBoxes(Map &map) {
for (auto &junctionpair : map._data.GetJunctions()) {

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"
/// A definition of a Carla Mesh.
USTRUCT()
USTRUCT(Blueprintable)
struct CARLA_API FProceduralCustomMesh
{
GENERATED_BODY()
UPROPERTY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FVector> Vertices;
UPROPERTY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<int32> Triangles;
UPROPERTY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FVector> Normals;
UPROPERTY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FVector2D> UV0;
UPROPERTY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="VertexData")
TArray<FLinearColor> VertexColor;
// This is commented due to an strange bug including ProceduralMeshComponent.h

View File

@ -18,7 +18,7 @@
{
"Name": "CarlaTools",
"Type": "Editor",
"LoadingPhase": "PostEngineInit"
"LoadingPhase": "Default"
}
],
"Plugins": [
@ -37,6 +37,10 @@
{
"Name": "ProceduralMeshComponent",
"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

@ -82,14 +82,18 @@ public class CarlaTools : ModuleRules
"FoliageEdit",
"MeshMergeUtilities",
"Carla",
"StaticMeshDescription",
"PhysXVehicles",
"Json",
"JsonUtilities",
"Networking",
"Sockets",
"HTTP",
"RHI",
"RenderCore",
"MeshMergeUtilities"
"MeshMergeUtilities",
"StreetMapImporting",
"StreetMapRuntime"
// ... add private dependencies that you statically link with here ...
}
);

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/KismetSystemLibrary.h"
#include "FileHelpers.h"
#include "EditorLevelLibrary.h"
#include "Components/PrimitiveComponent.h"
void UHoudiniImporterWidget::CreateSubLevels(ALargeMapManager* LargeMapManager)
@ -46,8 +47,8 @@ void UHoudiniImporterWidget::MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Ac
FCarlaMapTile* Tile = LargeMapManager->GetCarlaMapTile(ActorLocation);
if(!Tile)
{
UE_LOG(LogCarlaTools, Error, TEXT("Error: actor in location %s is outside the map"),
*ActorLocation.ToString());
UE_LOG(LogCarlaTools, Error, TEXT("Error: actor %s in location %s is outside the map"),
*Actor->GetName(),*ActorLocation.ToString());
continue;
}
@ -70,10 +71,9 @@ void UHoudiniImporterWidget::MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Ac
{
continue;
}
UWorld* World = ActorList[0]->GetWorld();
UWorld* World = UEditorLevelLibrary::GetEditorWorld();
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->SetShouldBeVisible(true);
StreamingLevel->SetShouldBeLoaded(true);
@ -86,15 +86,51 @@ void UHoudiniImporterWidget::MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Ac
FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr);
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)
{
int MovedActors = UEditorLevelUtils::MoveActorsToLevel(Actors, Level, false, false);
// StreamingLevel->SetShouldBeLoaded(false);
UE_LOG(LogCarlaTools, Log, TEXT("Moved %d actors"), MovedActors);
FEditorFileUtils::SaveDirtyPackages(false, true, true, false, false, false, nullptr);
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(
@ -102,8 +138,8 @@ void UHoudiniImporterWidget::UpdateGenericActorCoordinates(
{
FVector LocalLocation = Actor->GetActorLocation() - TileOrigin;
Actor->SetActorLocation(LocalLocation);
UE_LOG(LogCarlaTools, Log, TEXT("New location %s"),
*LocalLocation.ToString());
UE_LOG(LogCarlaTools, Log, TEXT("%s New location %s"),
*Actor->GetName(), *LocalLocation.ToString());
}
void UHoudiniImporterWidget::UpdateInstancedMeshCoordinates(
@ -133,13 +169,6 @@ void UHoudiniImporterWidget::UseCOMasActorLocation(TArray<AActor*> Actors)
FBodyInstance* BodyInstance = Primitive->GetBodyInstance();
FVector CenterOfMass = BodyInstance->COMNudge;
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());
}
}
}

View File

@ -61,14 +61,19 @@ void UMapPreviewUserWidget::ConnectToSocket(FString DatabasePath, FString Styles
// Send a message
FString Message = "-C " + DatabasePath + " " + StylesheetPath + " " + FString::FromInt(Size);
SendStr(Message);
if( !SendStr(Message) ){
return;
}
UE_LOG(LogTemp, Log, TEXT("Configuration Completed"));
}
void UMapPreviewUserWidget::RenderMap(FString Latitude, FString Longitude, FString 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;
uint32 ReceivedDataSize = 0;
@ -116,7 +121,10 @@ void UMapPreviewUserWidget::RenderMap(FString Latitude, FString Longitude, FStri
FString UMapPreviewUserWidget::RecvCornersLatLonCoords()
{
SendStr("-L");
if( !SendStr("-L") ){
UE_LOG(LogTemp, Error, TEXT("Error sending message: num bytes mismatch"));
return FString();
}
AsioStreamBuf Buffer;
std::size_t BytesReceived =
@ -141,7 +149,10 @@ void UMapPreviewUserWidget::OpenServer()
void UMapPreviewUserWidget::CloseServer()
{
SendStr("-X");
if( !SendStr("-X") ){
UE_LOG(LogTemp, Error, TEXT("Error sending message"));
return;
}
}
bool UMapPreviewUserWidget::SendStr(FString Msg)
@ -166,24 +177,29 @@ bool UMapPreviewUserWidget::SendStr(FString Msg)
if (BytesSent != MessageStr.size())
{
UE_LOG(LogTemp, Error, TEXT("Error sending message: num bytes mismatch"));
return true;
return false;
}
else
{
UE_LOG(LogTemp, Log, TEXT("Sent %d bytes"), BytesSent);
return false;
return true;
}
}
void UMapPreviewUserWidget::UpdateLatLonCoordProperties()
{
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());
TArray<FString> CoordsArray;
CoordStr.ParseIntoArray(CoordsArray, TEXT("&"), true);
check(CoordsArray.Num() >= 4);
ensure(CoordsArray.Num() == 4);
TopRightLat = FCString::Atof(*CoordsArray[0]);
TopRightLon = FCString::Atof(*CoordsArray[1]);

View File

@ -3,6 +3,7 @@
#undef CreateDirectory
#include "Online/CustomFileDownloader.h"
#include "OpenDriveToMap.h"
#include "HttpModule.h"
#include "Http.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
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
{
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
{
UE_LOG(LogCarla, Warning, TEXT("File: %s does not exist"), *FilePath);
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("File: %s does not exist"), *FilePath);
return;
}
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
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
{
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()
{
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);
Download->Run();
}
@ -65,10 +67,16 @@ FHttpDownloader::FHttpDownloader(const FString &InVerb, const FString &InUrl, co
{
}
FHttpDownloader::FHttpDownloader()
{
}
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();
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("Map Name Is %s"), *Filename );
Request->OnProcessRequestComplete().BindRaw(this, &FHttpDownloader::RequestComplete);
Request->SetURL(Url);
Request->SetVerb(Verb);
@ -79,29 +87,27 @@ void FHttpDownloader::RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponse
{
if (!HttpResponse.IsValid() )
{
UE_LOG(LogCarla, Log, TEXT("Download failed. NULL response"));
UE_LOG(LogCarlaToolsMapGenerator, Log, TEXT("Download failed. NULL response"));
}
else
{
// If we do not get success responses codes we do not do anything
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->GetURL(),
HttpResponse->GetResponseCode());
delete this;
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->GetURL(),
HttpResponse->GetResponseCode());
HttpRequest->OnProcessRequestComplete().Unbind();
FString CurrentFile = FPaths::ProjectContentDir() + "CustomMaps/" + Filename + "/OpenDrive/";
FString CurrentFile = FPaths::ProjectContentDir() + "CustomMaps/" + (Filename) + "/OpenDrive/";
UE_LOG(LogCarlaToolsMapGenerator, Warning, TEXT("FHttpDownloader::RequestComplete CurrentFile %s."), *CurrentFile);
// We will use this FileManager to deal with the file.
IPlatformFile &FileManager = FPlatformFileManager::Get().GetPlatformFile();
@ -116,14 +122,14 @@ void FHttpDownloader::RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponse
// We use the LoadFileToString to load the file into
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
{
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;
}

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
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void CreateSubLevels(ALargeMapManager* LargeMapManager);
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void MoveActorsToSubLevelWithLargeMap(TArray<AActor*> Actors, ALargeMapManager* LargeMapManager);
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void ForceStreamingLevelsToUnload( ALargeMapManager* LargeMapManager );
UFUNCTION(BlueprintCallable, Category="HoudiniImporterWidget")
static void MoveActorsToSubLevel(TArray<AActor*> Actors, ULevelStreaming* Level);

View File

@ -11,31 +11,12 @@
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;
FString Url;
FDownloadComplete DownloadDelegate;
private:
void RequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded);
FString Payload;
};
class FHttpDownloader
struct FHttpDownloader
{
public:
FHttpDownloader();
/**
*
* @param Verb - verb to use for request (GET,POST,DELETE,etc)
@ -61,3 +42,26 @@ private:
FString Filename;
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 "ProceduralMeshComponent.h"
#include "Math/Vector2D.h"
#include "EditorUtilityActor.h"
#include "EditorUtilityObject.h"
#include <compiler/disable-ue4-macros.h>
#include <boost/optional.hpp>
@ -23,11 +25,13 @@ class UMaterialInstance;
*
*/
UCLASS(Blueprintable, BlueprintType)
class CARLATOOLS_API UOpenDriveToMap : public UObject
class CARLATOOLS_API UOpenDriveToMap : public UEditorUtilityObject
{
GENERATED_BODY()
#if WITH_EDITOR
public:
UOpenDriveToMap();
~UOpenDriveToMap();
UFUNCTION()
void ConvertOSMInOpenDrive();
@ -36,12 +40,47 @@ public:
void CreateMap();
UFUNCTION(BlueprintCallable)
void CreateTerrain(const int MeshGridSize, const float MeshGridSectionSize,
const class UTexture2D* HeightmapTexture);
void CreateTerrain(const int MeshGridSize, const float MeshGridSectionSize);
UFUNCTION(BlueprintCallable)
void CreateTerrainMesh(const int MeshIndex, const FVector2D Offset, const int GridSize, const float GridSectionSize,
const class UTexture2D* HeightmapTexture, class UTextureRenderTarget2D* RoadMask);
void CreateTerrainMesh(const int MeshIndex, const FVector2D Offset, const int GridSize, const float GridSectionSize);
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")
FString FilePath;
@ -70,45 +109,97 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Defaults")
UMaterialInstance* DefaultLandscapeMaterial;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Defaults")
UTexture2D* DefaultHeightmap;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" )
float DistanceBetweenTrees = 50.0f;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" )
float DistanceFromRoadEdge = 3.0f;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Stage" )
bool bHasStarted = false;
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:
UFUNCTION(BlueprintCallable)
void SaveMap();
UFUNCTION(BlueprintCallable)
TArray<AActor*> GenerateMiscActors(float Offset);
TArray<AActor*> GenerateMiscActors(float Offset, FVector MinLocation, FVector MaxLocation );
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:
UFUNCTION()
void OpenFileDialog();
UFUNCTION()
UFUNCTION(BlueprintCallable)
void LoadMap();
void GenerateAll(const boost::optional<carla::road::Map>& CarlaMap);
void GenerateRoadMesh(const boost::optional<carla::road::Map>& CarlaMap);
void GenerateSpawnPoints(const boost::optional<carla::road::Map>& CarlaMap);
void GenerateTreePositions(const boost::optional<carla::road::Map>& CarlaMap);
void GenerateLaneMarks(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>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
void GenerateSpawnPoints(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
void GenerateTreePositions(const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation);
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;
boost::optional<carla::road::Map> CarlaMap;
UStaticMesh* CreateStaticMeshAsset(UProceduralMeshComponent* ProcMeshComp, int32 MeshIndex, FString FolderName);
TArray<UStaticMesh*> CreateStaticMeshAssets();
FTransform GetSnappedPosition(FTransform Origin);
float GetHeightForLandscape(FVector Origin);
@ -117,20 +208,16 @@ private:
FVector &location,
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()
UCustomFileDownloader* FileDownloader;
UPROPERTY()
TArray<AActor*> ActorMeshList;
UPROPERTY()
TArray<AActor*> LaneMarkerActorList;
UPROPERTY()
TArray<UStaticMesh*> MeshesToSpawn;
UPROPERTY()
TArray<FString> RoadType;
UPROPERTY()
TArray<UProceduralMeshComponent*> RoadMesh;
UPROPERTY()
TArray<AActor*> Landscapes;
UPROPERTY()
UTexture2D* Heightmap;
#endif
};

View File

@ -230,7 +230,7 @@ struct CARLATOOLS_API FTerrainROI : public FCarlaRegionOfInterest
UPROPERTY(BlueprintReadWrite)
UTextureRenderTarget2D* RoiHeightmapRenderTarget;
FTerrainROI() : FCarlaRegionOfInterest(), RoiMaterialInstance()
FTerrainROI() : FCarlaRegionOfInterest(), RoiMaterialInstance(), RoiHeightmapRenderTarget()
{}
/**
@ -295,7 +295,11 @@ struct CARLATOOLS_API FMiscSpecificLocationActorsROI : public FCarlaRegionOfInte
UPROPERTY(BlueprintReadWrite)
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 BUILD_OSM2ODR=false
set GIT_PULL=true
set CURRENT_OSM2ODR_COMMIT=03f2f1de6dcbfde41f2af464829d96b582fc2909
set OSM2ODR_BRANCH=carla_osm2odr
set CURRENT_OSM2ODR_COMMIT=1835e1e9538d0778971acc8b19b111834aae7261
set OSM2ODR_BRANCH=aaron/defaultsidewalkwidth
set OSM2ODR_REPO=https://github.com/carla-simulator/sumo.git
:arg-parse

View File

@ -14,8 +14,8 @@ END
REMOVE_INTERMEDIATE=false
BUILD_OSM2ODR=false
GIT_PULL=true
CURRENT_OSM2ODR_COMMIT=03f2f1de6dcbfde41f2af464829d96b582fc2909
OSM2ODR_BRANCH=carla_osm2odr
CURRENT_OSM2ODR_COMMIT=1835e1e9538d0778971acc8b19b111834aae7261
OSM2ODR_BRANCH=aaron/defaultsidewalkwidth
OSM2ODR_REPO=https://github.com/carla-simulator/sumo.git
OPTS=`getopt -o h --long help,rebuild,build,clean,carsim,no-pull -n 'parse-options' -- "$@"`

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:
@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)
launch-only:
@ -27,6 +28,7 @@ clean.LibCarla:
clean.PythonAPI:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --clean
clean.CarlaUE4Editor:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --clean $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --clean
clean.osm2odr:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --clean
@ -36,9 +38,11 @@ rebuild: setup
@${CARLA_BUILD_TOOLS_FOLDER}/BuildLibCarla.sh --rebuild
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --rebuild
@${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rebuild $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --rebuild $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --rebuild $(ARGS)
hard-clean:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --clean $(ARGS)
@${CARLA_BUILD_TOOLS_FOLDER}/BuildCarlaUE4.sh --hard-clean
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSM2ODR.sh --clean
@${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --clean
@ -79,7 +83,8 @@ examples:
run-examples:
@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)
.PHONY: PythonAPI
@ -133,7 +138,7 @@ LibCarla.client.rss.release: setup ad-rss
plugins:
@${CARLA_BUILD_TOOLS_FOLDER}/Plugins.sh $(ARGS)
setup:
setup downloadplugins:
@${CARLA_BUILD_TOOLS_FOLDER}/Setup.sh $(ARGS)
ad-rss:
@ -153,3 +158,6 @@ osm2odr:
osmrenderer:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildOSMRenderer.sh
downloadplugins:
@${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.sh --build $(ARGS)

View File

@ -1,5 +1,5 @@
@echo off
setlocal
setlocal enabledelayedexpansion
rem BAT script that downloads and generates
rem rpclib, gtest and boost libraries for CARLA (carla.org).

View File

@ -32,3 +32,6 @@ CMAKE_CONFIG_FILE=${CARLA_BUILD_FOLDER}/CMakeLists.txt.in
LIBCARLA_TEST_CONTENT_FOLDER=${CARLA_BUILD_FOLDER}/test-content
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
@"${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)
.PHONY: Plugins
plugins:
@"${CARLA_BUILD_TOOLS_FOLDER}/Plugins.bat" $(ARGS)
@ -86,3 +87,6 @@ osm2odr:
osmrenderer:
@"${CARLA_BUILD_TOOLS_FOLDER}/BuildOSMRenderer.bat"
downloadplugin:
@"${CARLA_BUILD_TOOLS_FOLDER}/BuildUE4Plugins.bat" --build $(ARGS)