Import maps in tiles
This commit is contained in:
parent
1aa53798a2
commit
bc4d23a5e9
|
@ -5,6 +5,7 @@
|
|||
* Upgrading to Unreal Engine 4.26
|
||||
* Added Lincoln 2020 vehicle dimensions for CarSim integration
|
||||
* Enabling the **no_delay** option to RPC and stream sockets
|
||||
* The special nomenclature to define roads (ROAD_ROAD), sidewalks (ROAD_SIDEWALK)... can be at any position of the asset name
|
||||
* Improved performance bencharmark script: sync, map and sensor selection, ...
|
||||
* Improved performance, destroyed PhysX state for vehicles when physics are disable
|
||||
* Improved parallelism of raycast sensors in system with large number of cores
|
||||
|
|
|
@ -105,28 +105,55 @@ void UPrepareAssetsForCookingCommandlet::LoadWorld(FAssetData &AssetData)
|
|||
}
|
||||
}
|
||||
|
||||
void UPrepareAssetsForCookingCommandlet::LoadWorldTile(FAssetData &AssetData)
|
||||
{
|
||||
// BaseTile path inside Carla
|
||||
const FString BaseTile = TEXT("/Game/Carla/Maps/TestMaps");
|
||||
|
||||
// Load Map folder using object library
|
||||
MapObjectLibrary = UObjectLibrary::CreateLibrary(UWorld::StaticClass(), false, GIsEditor);
|
||||
MapObjectLibrary->AddToRoot();
|
||||
MapObjectLibrary->LoadAssetDataFromPath(*BaseTile);
|
||||
MapObjectLibrary->LoadAssetsFromAssetData();
|
||||
MapObjectLibrary->GetAssetDataList(AssetDatas);
|
||||
|
||||
if (AssetDatas.Num() > 0)
|
||||
{
|
||||
// Extract first asset found in folder path (i.e. the BaseTile)
|
||||
AssetData = AssetDatas.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
TArray<AStaticMeshActor *> UPrepareAssetsForCookingCommandlet::SpawnMeshesToWorld(
|
||||
const TArray<FString> &AssetsPaths,
|
||||
bool bUseCarlaMaterials)
|
||||
bool bUseCarlaMaterials,
|
||||
int i,
|
||||
int j)
|
||||
{
|
||||
TArray<AStaticMeshActor *> SpawnedMeshes;
|
||||
|
||||
// Create default Transform for all assets to spawn
|
||||
const FTransform zeroTransform = FTransform();
|
||||
|
||||
// Load assets specified in AssetsPaths by using an object library
|
||||
// for building map world
|
||||
AssetsObjectLibrary = UObjectLibrary::CreateLibrary(UStaticMesh::StaticClass(), false, GIsEditor);
|
||||
AssetsObjectLibrary->AddToRoot();
|
||||
|
||||
AssetsObjectLibrary->LoadAssetDataFromPaths(AssetsPaths);
|
||||
AssetsObjectLibrary->LoadAssetsFromAssetData();
|
||||
MapContents.Empty();
|
||||
AssetsObjectLibrary->GetAssetDataList(MapContents);
|
||||
|
||||
// Create default Transform for all assets to spawn
|
||||
const FTransform zeroTransform = FTransform();
|
||||
|
||||
UStaticMesh *MeshAsset;
|
||||
AStaticMeshActor *MeshActor;
|
||||
|
||||
// name of current tile to cook
|
||||
FString TileName;
|
||||
if (i != -1)
|
||||
{
|
||||
TileName = FString::Printf(TEXT("_Tile_%d_%d"), i, j);
|
||||
}
|
||||
|
||||
// try to get the name of the map that precedes all assets name
|
||||
FString AssetName;
|
||||
for (auto MapAsset : MapContents)
|
||||
|
@ -135,43 +162,48 @@ TArray<AStaticMeshActor *> UPrepareAssetsForCookingCommandlet::SpawnMeshesToWorl
|
|||
MeshAsset = Cast<UStaticMesh>(MapAsset.GetAsset());
|
||||
if (MeshAsset && ValidateStaticMesh(MeshAsset))
|
||||
{
|
||||
MeshActor = World->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), zeroTransform);
|
||||
UStaticMeshComponent *MeshComponent = MeshActor->GetStaticMeshComponent();
|
||||
MeshComponent->SetStaticMesh(CastChecked<UStaticMesh>(MeshAsset));
|
||||
|
||||
// Rename asset
|
||||
// get asset name
|
||||
MapAsset.AssetName.ToString(AssetName);
|
||||
|
||||
// set complex collision as simple in asset
|
||||
UBodySetup *BodySetup = MeshAsset->BodySetup;
|
||||
if (BodySetup)
|
||||
// check to ignore meshes from other tiles
|
||||
if (i == -1 || (i != -1 && AssetName.Contains(TileName)))
|
||||
{
|
||||
BodySetup->CollisionTraceFlag = CTF_UseComplexAsSimple;
|
||||
MeshAsset->MarkPackageDirty();
|
||||
}
|
||||
MeshActor = World->SpawnActor<AStaticMeshActor>(AStaticMeshActor::StaticClass(), zeroTransform);
|
||||
UStaticMeshComponent *MeshComponent = MeshActor->GetStaticMeshComponent();
|
||||
MeshComponent->SetStaticMesh(CastChecked<UStaticMesh>(MeshAsset));
|
||||
MeshActor->SetActorLabel(AssetName, true);
|
||||
|
||||
SpawnedMeshes.Add(MeshActor);
|
||||
// set complex collision as simple in asset
|
||||
UBodySetup *BodySetup = MeshAsset->BodySetup;
|
||||
if (BodySetup)
|
||||
{
|
||||
BodySetup->CollisionTraceFlag = CTF_UseComplexAsSimple;
|
||||
MeshAsset->MarkPackageDirty();
|
||||
}
|
||||
|
||||
if (bUseCarlaMaterials)
|
||||
{
|
||||
// Set Carla Materials depending on RoadRunner's Semantic Segmentation
|
||||
// tag
|
||||
if (AssetName.Contains(SSTags::R_MARKING1) || AssetName.Contains(SSTags::R_MARKING2))
|
||||
SpawnedMeshes.Add(MeshActor);
|
||||
|
||||
if (bUseCarlaMaterials)
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, MarkingNodeMaterial);
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(1, MarkingNodeMaterialAux);
|
||||
}
|
||||
else if (AssetName.Contains(SSTags::R_ROAD1) || AssetName.Contains(SSTags::R_ROAD2))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, RoadNodeMaterial);
|
||||
}
|
||||
else if (AssetName.Contains(SSTags::R_TERRAIN))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, TerrainNodeMaterial);
|
||||
}
|
||||
else if (AssetName.Contains(SSTags::R_SIDEWALK1) || AssetName.Contains(SSTags::R_SIDEWALK2))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, SidewalkNodeMaterial);
|
||||
// Set Carla Materials depending on RoadRunner's Semantic Segmentation
|
||||
// tag
|
||||
if (AssetName.Contains(SSTags::R_MARKING1) || AssetName.Contains(SSTags::R_MARKING2))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, MarkingNodeMaterial);
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(1, MarkingNodeMaterialAux);
|
||||
}
|
||||
else if (AssetName.Contains(SSTags::R_ROAD1) || AssetName.Contains(SSTags::R_ROAD2))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, RoadNodeMaterial);
|
||||
}
|
||||
else if (AssetName.Contains(SSTags::R_TERRAIN))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, TerrainNodeMaterial);
|
||||
}
|
||||
else if (AssetName.Contains(SSTags::R_SIDEWALK1) || AssetName.Contains(SSTags::R_SIDEWALK2))
|
||||
{
|
||||
MeshActor->GetStaticMeshComponent()->SetMaterial(0, SidewalkNodeMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +218,45 @@ TArray<AStaticMeshActor *> UPrepareAssetsForCookingCommandlet::SpawnMeshesToWorl
|
|||
return SpawnedMeshes;
|
||||
}
|
||||
|
||||
bool UPrepareAssetsForCookingCommandlet::IsMapInTiles(const TArray<FString> &AssetsPaths)
|
||||
{
|
||||
// Load assets specified in AssetsPaths by using an object library
|
||||
// for building map world
|
||||
AssetsObjectLibrary = UObjectLibrary::CreateLibrary(UStaticMesh::StaticClass(), false, GIsEditor);
|
||||
AssetsObjectLibrary->AddToRoot();
|
||||
AssetsObjectLibrary->LoadAssetDataFromPaths(AssetsPaths);
|
||||
AssetsObjectLibrary->LoadAssetsFromAssetData();
|
||||
MapContents.Empty();
|
||||
AssetsObjectLibrary->GetAssetDataList(MapContents);
|
||||
|
||||
UStaticMesh *MeshAsset;
|
||||
|
||||
FString AssetName;
|
||||
bool Found = false;
|
||||
for (auto MapAsset : MapContents)
|
||||
{
|
||||
// Spawn Static Mesh
|
||||
MeshAsset = Cast<UStaticMesh>(MapAsset.GetAsset());
|
||||
if (MeshAsset && ValidateStaticMesh(MeshAsset))
|
||||
{
|
||||
// get asset name
|
||||
MapAsset.AssetName.ToString(AssetName);
|
||||
|
||||
// check if the asset is a tile
|
||||
if (AssetName.Contains("_Tile_"))
|
||||
{
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear loaded assets in library
|
||||
AssetsObjectLibrary->ClearLoaded();
|
||||
|
||||
return Found;
|
||||
}
|
||||
|
||||
void UPrepareAssetsForCookingCommandlet::DestroySpawnedActorsInWorld(
|
||||
TArray<AStaticMeshActor *> &SpawnedActors)
|
||||
{
|
||||
|
@ -397,11 +468,6 @@ void UPrepareAssetsForCookingCommandlet::PrepareMapsForCooking(
|
|||
const FString &PackageName,
|
||||
const TArray<FMapData> &MapsPaths)
|
||||
{
|
||||
// Load World
|
||||
FAssetData AssetData;
|
||||
LoadWorld(AssetData);
|
||||
World = CastChecked<UWorld>(AssetData.GetAsset());
|
||||
|
||||
FString BasePath = TEXT("/Game/") + PackageName + TEXT("/Static/");
|
||||
|
||||
for (const auto &Map : MapsPaths)
|
||||
|
@ -417,13 +483,59 @@ void UPrepareAssetsForCookingCommandlet::PrepareMapsForCooking(
|
|||
// Spawn assets located in semantic segmentation folders
|
||||
TArray<FString> DataPath = {DefaultPath, RoadsPath, RoadLinesPath, TerrainPath, SidewalkPath};
|
||||
|
||||
TArray<AStaticMeshActor *> SpawnedActors = SpawnMeshesToWorld(DataPath, Map.bUseCarlaMapMaterials);
|
||||
|
||||
// Save the World in specified path
|
||||
SaveWorld(AssetData, PackageName, Map.Path, Map.Name);
|
||||
|
||||
// Remove spawned actors from world to keep equal as BaseMap
|
||||
DestroySpawnedActorsInWorld(SpawnedActors);
|
||||
// check whether we have a single map or a map in tiles
|
||||
if (!IsMapInTiles(DataPath))
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Cooking map"));
|
||||
// Load World
|
||||
FAssetData AssetData;
|
||||
LoadWorld(AssetData);
|
||||
World = CastChecked<UWorld>(AssetData.GetAsset());
|
||||
// try to cook the whole map (no tiles)
|
||||
TArray<AStaticMeshActor *> SpawnedActors = SpawnMeshesToWorld(DataPath, Map.bUseCarlaMapMaterials, -1, -1);
|
||||
// Save the World in specified path
|
||||
SaveWorld(AssetData, PackageName, Map.Path, Map.Name);
|
||||
// Remove spawned actors from world to keep equal as BaseMap
|
||||
DestroySpawnedActorsInWorld(SpawnedActors);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Cooking tiles:"));
|
||||
// Load World
|
||||
FAssetData AssetData;
|
||||
LoadWorldTile(AssetData);
|
||||
World = CastChecked<UWorld>(AssetData.GetAsset());
|
||||
// try to create each possible tile of the map
|
||||
int i, j;
|
||||
bool Res;
|
||||
j = 0;
|
||||
do
|
||||
{
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
// Spawn
|
||||
TArray<AStaticMeshActor *> SpawnedActors = SpawnMeshesToWorld(DataPath, Map.bUseCarlaMapMaterials, i, j);
|
||||
Res = SpawnedActors.Num() > 0;
|
||||
if (Res)
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT(" Tile %d,%d found"), i, j);
|
||||
FString TileName;
|
||||
TileName = FString::Printf(TEXT("%s_Tile_%d_%d"), *Map.Name, i, j);
|
||||
// Save the World in specified path
|
||||
// UE_LOG(LogTemp, Log, TEXT("Saving as %s to %s"), *TileName, *Map.Path);
|
||||
SaveWorld(AssetData, PackageName, Map.Path, TileName);
|
||||
// Remove spawned actors from world to keep equal as BaseMap
|
||||
DestroySpawnedActorsInWorld(SpawnedActors);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
while (Res);
|
||||
++j;
|
||||
}
|
||||
while (i > 0);
|
||||
UE_LOG(LogTemp, Log, TEXT("End cooking tiles"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,10 @@ public:
|
|||
/// structure.
|
||||
void LoadWorld(FAssetData &AssetData);
|
||||
|
||||
/// Loads a UWorld object contained in Carla BaseTile into @a AssetData data
|
||||
/// structure.
|
||||
void LoadWorldTile(FAssetData &AssetData);
|
||||
|
||||
/// Spawns all the static meshes located in @a AssetsPaths inside the World.
|
||||
/// There is an option to use Carla materials by setting @a bUseCarlaMaterials
|
||||
/// to true, otherwise it will use RoadRunner materials.
|
||||
|
@ -82,7 +86,9 @@ public:
|
|||
/// @pre World is expected to be previously loaded
|
||||
TArray<AStaticMeshActor *> SpawnMeshesToWorld(
|
||||
const TArray<FString> &AssetsPaths,
|
||||
bool bUseCarlaMaterials);
|
||||
bool bUseCarlaMaterials,
|
||||
int i = -1,
|
||||
int j = -1);
|
||||
|
||||
/// Saves the current World, contained in @a AssetData, into @a DestPath
|
||||
/// composed of @a PackageName and with @a WorldName.
|
||||
|
@ -116,6 +122,9 @@ public:
|
|||
/// in a destination path built from @a PackageName and @a MapDestPath.
|
||||
void PreparePropsForCooking(FString &PackageName, const TArray<FString> &PropsPaths, FString &MapDestPath);
|
||||
|
||||
/// Return if there is any tile between the assets to cook
|
||||
bool IsMapInTiles(const TArray<FString> &AssetsPaths);
|
||||
|
||||
public:
|
||||
|
||||
/// Main method and entry of the commandlet, taking as input parameters @a
|
||||
|
|
|
@ -56,12 +56,17 @@ def generate_json_package(folder, package_name, use_carla_materials):
|
|||
# search for all .fbx and .xodr pair of files
|
||||
maps = []
|
||||
for root, _, filenames in os.walk(folder):
|
||||
files = fnmatch.filter(filenames, "*.fbx")
|
||||
files = fnmatch.filter(filenames, "*.xodr")
|
||||
for file_name in files:
|
||||
fbx = file_name[:-4]
|
||||
# check if exist the .xodr file
|
||||
if os.path.exists("%s/%s.xodr" % (root, fbx)):
|
||||
maps.append([os.path.relpath(root, folder), fbx])
|
||||
xodr = file_name[:-5]
|
||||
# check if exist the .fbx file
|
||||
if os.path.exists("%s/%s.fbx" % (root, xodr)):
|
||||
maps.append([os.path.relpath(root, folder), xodr, ["%s.fbx" % xodr]])
|
||||
else:
|
||||
# check if exist the map by tiles
|
||||
tiles = fnmatch.filter(filenames, "*_Tile_*.fbx")
|
||||
if (len(tiles) > 0):
|
||||
maps.append([os.path.relpath(root, folder), xodr, tiles])
|
||||
|
||||
# write the json
|
||||
if (len(maps) > 0):
|
||||
|
@ -70,12 +75,20 @@ def generate_json_package(folder, package_name, use_carla_materials):
|
|||
for map_name in maps:
|
||||
path = map_name[0].replace('\\', '/')
|
||||
name = map_name[1]
|
||||
json_maps.append({
|
||||
tiles = map_name[2]
|
||||
tiles = ["%s/%s" % (path, x) for x in tiles]
|
||||
map_dict = {
|
||||
'name': name,
|
||||
'source': '%s/%s.fbx' % (path, name),
|
||||
'xodr': '%s/%s.xodr' % (path, name),
|
||||
'use_carla_materials': use_carla_materials
|
||||
})
|
||||
}
|
||||
# check for only one 'source' or map in 'tiles'
|
||||
if (len(tiles) == 1):
|
||||
map_dict['source'] = tiles[0]
|
||||
else:
|
||||
map_dict['tiles'] = tiles
|
||||
# write
|
||||
json_maps.append(map_dict)
|
||||
# build and write the .json
|
||||
f = open("%s/%s.json" % (folder, package_name), "w")
|
||||
my_json = {'maps': json_maps, 'props': []}
|
||||
|
@ -194,8 +207,6 @@ def invoke_commandlet(name, arguments):
|
|||
subprocess.call([full_command], shell=True)
|
||||
|
||||
|
||||
|
||||
|
||||
def generate_import_setting_file(package_name, json_dirname, props, maps):
|
||||
"""Creates the PROPS and MAPS import_setting.json file needed
|
||||
as an argument for using the ImportAssets commandlet
|
||||
|
@ -241,13 +252,16 @@ def generate_import_setting_file(package_name, json_dirname, props, maps):
|
|||
for umap in maps:
|
||||
maps_dest = "/" + "/".join(["Game", package_name, "Maps", umap["name"]])
|
||||
|
||||
file_names = [os.path.join(json_dirname, umap["source"])]
|
||||
if "source" in umap:
|
||||
tiles = [os.path.join(json_dirname, umap["source"])]
|
||||
else:
|
||||
tiles = ["%s" % (os.path.join(json_dirname, x)) for x in umap["tiles"]]
|
||||
import_groups.append({
|
||||
"ImportSettings": import_settings,
|
||||
"FactoryName": "FbxFactory",
|
||||
"DestinationPath": maps_dest,
|
||||
"bReplaceExisting": "true",
|
||||
"FileNames": file_names
|
||||
"FileNames": tiles
|
||||
})
|
||||
|
||||
fh.write(json.dumps({"ImportGroups": import_groups}))
|
||||
|
@ -389,10 +403,11 @@ def import_assets_from_json_list(json_list):
|
|||
build_binary_for_navigation(package_name, dirname, maps)
|
||||
|
||||
# We prepare only the maps for cooking after moving them. Props cooking will be done from Package.sh script.
|
||||
prepare_maps_commandlet_for_cooking(package_name, only_prepare_maps=True)
|
||||
if len(maps) > 0:
|
||||
prepare_maps_commandlet_for_cooking(package_name, only_prepare_maps=True)
|
||||
|
||||
# We apply the carla materials to the imported maps
|
||||
load_asset_materials_commandlet(package_name)
|
||||
# We apply the carla materials to the imported maps
|
||||
load_asset_materials_commandlet(package_name)
|
||||
|
||||
|
||||
def load_asset_materials_commandlet(package_name):
|
||||
|
@ -400,7 +415,6 @@ def load_asset_materials_commandlet(package_name):
|
|||
commandlet_arguments = ["-PackageName=%s" % package_name]
|
||||
invoke_commandlet(commandlet_name, commandlet_arguments)
|
||||
|
||||
|
||||
def prepare_maps_commandlet_for_cooking(package_name, only_prepare_maps):
|
||||
commandlet_name = "PrepareAssetsForCooking"
|
||||
commandlet_arguments = ["-PackageName=%s" % package_name]
|
||||
|
@ -427,58 +441,68 @@ def build_binary_for_navigation(package_name, dirname, maps):
|
|||
# process each map
|
||||
for umap in maps:
|
||||
|
||||
# get the sources for the map (single or tiles)
|
||||
if ("source" in umap):
|
||||
tiles = [umap["source"]]
|
||||
elif ("tiles" in umap):
|
||||
tiles = umap["tiles"]
|
||||
else:
|
||||
continue
|
||||
|
||||
# get the target name
|
||||
target_name = umap["name"]
|
||||
xodr_filename = os.path.basename(umap["xodr"])
|
||||
|
||||
# copy the XODR file into docker utils folder
|
||||
if "xodr" in umap and umap["xodr"] and os.path.isfile(os.path.join(dirname, umap["xodr"])):
|
||||
# Make sure the `.xodr` file have the same name than the `.umap`
|
||||
xodr_path_source = os.path.abspath(os.path.join(dirname, umap["xodr"]))
|
||||
xodr_name = '.'.join([target_name, "xodr"])
|
||||
xodr_path_target = os.path.join(folder, xodr_name)
|
||||
xodr_path_target = os.path.join(folder, xodr_filename)
|
||||
# copy
|
||||
print('Copying "' + xodr_path_source + '" to "' + xodr_path_target + '"')
|
||||
shutil.copy2(xodr_path_source, xodr_path_target)
|
||||
|
||||
for tile in tiles:
|
||||
|
||||
# copy the FBX file into docker utils folder
|
||||
if "source" in umap and umap["source"] and os.path.isfile(os.path.join(dirname, umap["source"])):
|
||||
# Make sure the `.fbx` file have the same name than the `.umap`
|
||||
fbx_path_source = os.path.abspath(os.path.join(dirname, umap["source"]))
|
||||
fbx_name = '.'.join([target_name, "fbx"])
|
||||
fbx_path_target = os.path.join(folder, fbx_name)
|
||||
# copy
|
||||
print('Copying "' + fbx_path_source + '" to "' + fbx_path_target + '"')
|
||||
shutil.copy2(fbx_path_source, fbx_path_target)
|
||||
fbx_filename = os.path.basename(tile)
|
||||
fbx_name_no_ext = os.path.splitext(fbx_filename)[0]
|
||||
|
||||
# make the conversion
|
||||
if os.name == "nt":
|
||||
subprocess.call(["build.bat", target_name], cwd=folder, shell=True)
|
||||
else:
|
||||
subprocess.call(["chmod +x build.sh"], cwd=folder, shell=True)
|
||||
subprocess.call("./build.sh %s" % target_name, cwd=folder, shell=True)
|
||||
# copy the FBX file into docker utils folder
|
||||
if os.path.isfile(os.path.join(dirname, tile)):
|
||||
# Make sure the `.fbx` file have the same name than the `.umap`
|
||||
fbx_path_source = os.path.abspath(os.path.join(dirname, tile))
|
||||
fbx_path_target = os.path.join(folder, fbx_filename)
|
||||
# copy
|
||||
print('Copying "' + fbx_path_source + '" to "' + fbx_path_target + '"')
|
||||
shutil.copy2(fbx_path_source, fbx_path_target)
|
||||
|
||||
# copy the binary file
|
||||
nav_folder_target = os.path.join(
|
||||
CARLA_ROOT_PATH,
|
||||
"Unreal",
|
||||
"CarlaUE4",
|
||||
"Content",
|
||||
package_name,
|
||||
"Maps",
|
||||
target_name,
|
||||
"Nav")
|
||||
# rename the xodr with the same name of the source/tile
|
||||
os.rename(os.path.join(folder, xodr_filename), os.path.join(folder, "%s.xodr" % fbx_name_no_ext))
|
||||
|
||||
nav_path_source = os.path.join(folder, "%s.bin" % target_name)
|
||||
if os.path.exists(nav_path_source):
|
||||
# Skip this step for maps that do not use ped navmesh
|
||||
if not os.path.exists(nav_folder_target):
|
||||
os.makedirs(nav_folder_target)
|
||||
nav_path_target = os.path.join(nav_folder_target, "%s.bin" % target_name)
|
||||
print('Copying "' + nav_path_source + '" to "' + nav_path_target + '"')
|
||||
shutil.copy2(nav_path_source, nav_path_target)
|
||||
# make the conversion
|
||||
if os.name == "nt":
|
||||
subprocess.call(["build.bat", fbx_name_no_ext], cwd=folder, shell=True)
|
||||
else:
|
||||
subprocess.call(["chmod +x build.sh"], cwd=folder, shell=True)
|
||||
subprocess.call("./build.sh %s" % fbx_name_no_ext, cwd=folder, shell=True)
|
||||
|
||||
# rename the xodr with the original name
|
||||
os.rename(os.path.join(folder, "%s.xodr" % fbx_name_no_ext), os.path.join(folder, xodr_filename))
|
||||
|
||||
# copy the binary file
|
||||
nav_path_source = os.path.join(folder, "%s.bin" % fbx_name_no_ext)
|
||||
nav_folder_target = os.path.join(CARLA_ROOT_PATH, "Unreal", "CarlaUE4", "Content", package_name, "Maps", target_name, "Nav")
|
||||
if os.path.exists(nav_path_source):
|
||||
if not os.path.exists(nav_folder_target):
|
||||
os.makedirs(nav_folder_target)
|
||||
nav_path_target = os.path.join(nav_folder_target, "%s.bin" % fbx_name_no_ext)
|
||||
print('Copying "' + nav_path_source + '" to "' + nav_path_target + '"')
|
||||
shutil.copy2(nav_path_source, nav_path_target)
|
||||
|
||||
# remove files
|
||||
os.remove(nav_path_source)
|
||||
os.remove(fbx_path_target)
|
||||
|
||||
# remove files
|
||||
os.remove(fbx_path_target)
|
||||
os.remove(xodr_path_target)
|
||||
|
||||
def main():
|
||||
|
|
Loading…
Reference in New Issue