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:
parent
133cd319d7
commit
80d3471171
|
@ -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
|
||||||
|
|
|
@ -58,9 +58,11 @@ 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 {
|
||||||
Road *road = GetRoad();
|
Road *road = GetRoad();
|
||||||
|
|
|
@ -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,13 +1224,13 @@ 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){
|
||||||
|
if(lane->GetWidth(s_current) != 0.0f){
|
||||||
const auto edges = lane->GetCornerPositions(s_current, 0);
|
const auto edges = lane->GetCornerPositions(s_current, 0);
|
||||||
geom::Vector3D director = edges.second - edges.first;
|
geom::Vector3D director = edges.second - edges.first;
|
||||||
geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder;
|
geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder;
|
||||||
|
@ -1226,6 +1238,7 @@ namespace road {
|
||||||
geom::Transform treeTransform(treeposition, lanetransform.rotation);
|
geom::Transform treeTransform(treeposition, lanetransform.rotation);
|
||||||
const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo<carla::road::element::RoadInfoSpeed>(s_current);
|
const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo<carla::road::element::RoadInfoSpeed>(s_current);
|
||||||
transforms.push_back(std::make_pair(treeTransform,roadinfo->GetType()));
|
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) {
|
|
||||||
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);
|
||||||
std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>();
|
for ( auto&& pair : junctionsofthisthread ) {
|
||||||
for (auto& lane : sidewalk_lane_meshes) {
|
if ((*junction_out_mesh_list).find(pair.first) != (*junction_out_mesh_list).end()) {
|
||||||
*sidewalk_mesh += *lane;
|
(*junction_out_mesh_list)[pair.first].insert((*junction_out_mesh_list)[pair.first].end(),
|
||||||
}
|
std::make_move_iterator(pair.second.begin()),
|
||||||
(*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh));
|
std::make_move_iterator(pair.second.end()));
|
||||||
} else {
|
} else {
|
||||||
std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
|
(*junction_out_mesh_list)[pair.first] = std::move(pair.second);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
workers.push_back(std::move(neworker));
|
||||||
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -825,15 +825,20 @@ 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()){
|
||||||
|
if( it->second != nullptr ){
|
||||||
it->second->_junctions.insert(junction.first);
|
it->second->_junctions.insert(junction.first);
|
||||||
for(const auto & signal : it->second->_signals) {
|
for(const auto & signal : it->second->_signals) {
|
||||||
auto signal_it = _map_data._signals.find(signal);
|
auto signal_it = _map_data._signals.find(signal);
|
||||||
|
if( signal_it->second != nullptr ){
|
||||||
signal_it->second->_controllers.insert(controller);
|
signal_it->second->_controllers.insert(controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MapBuilder::CreateJunctionBoundingBoxes(Map &map) {
|
void MapBuilder::CreateJunctionBoundingBoxes(Map &map) {
|
||||||
for (auto &junctionpair : map._data.GetJunctions()) {
|
for (auto &junctionpair : map._data.GetJunctions()) {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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();
|
||||||
|
};
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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)
|
||||||
|
|
|
@ -82,14 +82,18 @@ 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",
|
||||||
|
"StreetMapImporting",
|
||||||
|
"StreetMapRuntime"
|
||||||
// ... add private dependencies that you statically link with here ...
|
// ... add private dependencies that you statically link with here ...
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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,10 +71,9 @@ 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);
|
||||||
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,14 +61,19 @@ 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;
|
||||||
|
@ -116,7 +121,10 @@ 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 =
|
||||||
|
@ -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]);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||||
|
};
|
|
@ -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();
|
||||||
|
};
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -11,31 +11,12 @@
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -230,7 +230,7 @@ struct CARLATOOLS_API FTerrainROI : public FCarlaRegionOfInterest
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
UTextureRenderTarget2D* RoiHeightmapRenderTarget;
|
UTextureRenderTarget2D* RoiHeightmapRenderTarget;
|
||||||
|
|
||||||
FTerrainROI() : FCarlaRegionOfInterest(), RoiMaterialInstance()
|
FTerrainROI() : FCarlaRegionOfInterest(), RoiMaterialInstance(), RoiHeightmapRenderTarget()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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' -- "$@"`
|
||||||
|
|
|
@ -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%
|
|
@ -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!"
|
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue