2019-02-07 23:06:57 +08:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
# Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de
|
|
|
|
# Barcelona (UAB).
|
|
|
|
#
|
|
|
|
# This work is licensed under the terms of the MIT license.
|
|
|
|
# For a copy, see <https://opensource.org/licenses/MIT>.
|
|
|
|
|
|
|
|
"""Generate map from FBX"""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import json
|
|
|
|
import subprocess
|
2019-02-15 23:20:24 +08:00
|
|
|
import shutil
|
|
|
|
import argparse
|
2019-02-07 23:06:57 +08:00
|
|
|
|
|
|
|
|
|
|
|
if os.name == 'nt':
|
2019-02-15 23:20:24 +08:00
|
|
|
sys_name = 'Win64'
|
2019-02-07 23:06:57 +08:00
|
|
|
elif os.name == 'posix':
|
|
|
|
sys_name = 'Linux'
|
2019-02-15 23:20:24 +08:00
|
|
|
|
2019-02-07 23:06:57 +08:00
|
|
|
|
|
|
|
def main():
|
2019-03-15 18:19:33 +08:00
|
|
|
try:
|
|
|
|
args = parse_arguments()
|
|
|
|
if(args.force):
|
|
|
|
generate_all_maps_but_list([], args)
|
|
|
|
else:
|
|
|
|
maps = get_map_names()
|
|
|
|
generate_all_maps_but_list(maps, args)
|
|
|
|
dirname = os.path.dirname(os.path.abspath(__file__))
|
2019-03-29 01:53:35 +08:00
|
|
|
relative_path = os.path.join(dirname, "..", "Unreal", "CarlaUE4", "Content", "Carla", "ExportedMaps")
|
2019-03-15 18:19:33 +08:00
|
|
|
print('Map(s) exported to %s' % os.path.abspath(relative_path))
|
|
|
|
finally:
|
|
|
|
print('\ndone.')
|
2019-02-15 23:20:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
def get_map_names():
|
|
|
|
maps = []
|
|
|
|
dirname = os.getcwd()
|
2019-03-29 01:53:35 +08:00
|
|
|
map_place = os.path.join(dirname, "..", "Unreal", "CarlaUE4", "Content", "Carla", "ExportedMaps")
|
2019-02-15 23:20:24 +08:00
|
|
|
for filename in os.listdir(map_place):
|
|
|
|
if filename.endswith('.umap'):
|
|
|
|
maps.append(filename)
|
|
|
|
return maps
|
|
|
|
|
2019-03-15 18:19:33 +08:00
|
|
|
|
|
|
|
def generate_all_maps_but_list(existent_maps, args):
|
2019-02-15 23:20:24 +08:00
|
|
|
map_name = ""
|
|
|
|
dirname = os.getcwd()
|
2019-03-29 01:53:35 +08:00
|
|
|
fbx_place = os.path.join(dirname, "..", "RoadRunnerFiles")
|
2019-02-15 23:20:24 +08:00
|
|
|
for x in os.walk(fbx_place):
|
2019-02-25 22:46:06 +08:00
|
|
|
map_name = os.path.basename(x[0])
|
|
|
|
if map_name != "RoadRunnerFiles":
|
|
|
|
if not any(ext in "%s.umap" % map_name for ext in existent_maps):
|
|
|
|
print("Found map in fbx folder: %s" % map_name)
|
|
|
|
import_assets_commandlet(map_name)
|
2019-03-15 18:19:33 +08:00
|
|
|
# move_uassets(map_name)
|
2019-02-25 22:46:06 +08:00
|
|
|
print("Generating map asset for %s" % map_name)
|
2019-03-15 18:19:33 +08:00
|
|
|
generate_map(map_name, args)
|
2019-02-25 22:46:06 +08:00
|
|
|
print("Cleaning up directories")
|
|
|
|
cleanup_assets(map_name)
|
|
|
|
print("Finished %s" % map_name)
|
|
|
|
else:
|
|
|
|
print("WARNING: Found %s map in Content folder, skipping. Use \"--force\" to override\n" % map_name)
|
2019-02-15 23:20:24 +08:00
|
|
|
|
2019-03-15 18:19:33 +08:00
|
|
|
|
2019-02-15 23:20:24 +08:00
|
|
|
def parse_arguments():
|
|
|
|
argparser = argparse.ArgumentParser(
|
|
|
|
description=__doc__)
|
|
|
|
argparser.add_argument(
|
|
|
|
'-f', '--force',
|
|
|
|
action='store_true',
|
|
|
|
help='Force import. Will override maps with the same name')
|
|
|
|
argparser.add_argument(
|
|
|
|
'-m', '--map',
|
|
|
|
metavar='M',
|
|
|
|
type=str,
|
|
|
|
help='Map to import. If empty, all maps in the folder will be loaded')
|
|
|
|
argparser.add_argument(
|
|
|
|
'--usecarlamats',
|
|
|
|
action='store_true',
|
|
|
|
help='Avoid using RoadRunner materials. Use materials provided by Carla instead')
|
|
|
|
return argparser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
def cleanup_assets(map_name):
|
|
|
|
dirname = os.getcwd()
|
2019-03-29 01:53:35 +08:00
|
|
|
content_folder = os.path.join(dirname, "..", "Unreal", "CarlaUE4", "Content", "Carla")
|
2019-02-15 23:20:24 +08:00
|
|
|
origin_folder = os.path.join(content_folder, "Static", "Imported", map_name)
|
|
|
|
for filename in os.listdir(origin_folder):
|
|
|
|
if map_name in filename:
|
|
|
|
removal_path = os.path.join(origin_folder, filename)
|
|
|
|
os.remove(removal_path)
|
|
|
|
|
|
|
|
|
|
|
|
def import_assets_commandlet(map_name):
|
|
|
|
generate_json(map_name, "importsetting.json")
|
|
|
|
dirname = os.getcwd()
|
|
|
|
commandlet_name = "ImportAssets"
|
|
|
|
import_settings = os.path.join(dirname, "importsetting.json")
|
|
|
|
commandlet_arguments = "-importSettings=\"%s\" -AllowCommandletRendering -nosourcecontrol -replaceexisting" % import_settings
|
|
|
|
|
2019-03-29 01:53:35 +08:00
|
|
|
file_xodr_origin = os.path.join(dirname, "..", "RoadRunnerFiles", map_name, "%s.xodr" % map_name)
|
2019-03-15 18:19:33 +08:00
|
|
|
file_xodr_dest = os.path.join(
|
|
|
|
dirname,
|
|
|
|
"..",
|
|
|
|
"Unreal",
|
|
|
|
"CarlaUE4",
|
|
|
|
"Content",
|
|
|
|
"Carla",
|
|
|
|
"Maps",
|
|
|
|
"OpenDrive",
|
|
|
|
"%s.xodr" %
|
|
|
|
map_name)
|
2019-02-07 23:06:57 +08:00
|
|
|
|
2019-02-15 23:20:24 +08:00
|
|
|
shutil.copy2(file_xodr_origin, file_xodr_dest)
|
|
|
|
invoke_commandlet(commandlet_name, commandlet_arguments)
|
2019-03-15 18:19:33 +08:00
|
|
|
# Clean up
|
2019-02-15 23:20:24 +08:00
|
|
|
os.remove("importsetting.json")
|
|
|
|
|
2019-03-15 18:19:33 +08:00
|
|
|
|
|
|
|
def generate_map(map_name, args):
|
2019-02-15 23:20:24 +08:00
|
|
|
commandlet_name = "MapProcess"
|
|
|
|
commandlet_arguments = "-mapname=\"%s\"" % map_name
|
|
|
|
if args.usecarlamats:
|
|
|
|
commandlet_arguments += " -use-carla-materials"
|
|
|
|
invoke_commandlet(commandlet_name, commandlet_arguments)
|
2019-03-15 18:19:33 +08:00
|
|
|
# This line might be needed if Epic tells us anything about the current
|
|
|
|
# way of doing the movement. It shouldn't but just in case...
|
|
|
|
|
2019-02-15 23:20:24 +08:00
|
|
|
|
|
|
|
def move_uassets(map_name):
|
|
|
|
dirname = os.getcwd()
|
2019-03-29 01:53:35 +08:00
|
|
|
content_folder = os.path.join(dirname, "..", "Unreal", "CarlaUE4", "Content", "Carla")
|
2019-02-15 23:20:24 +08:00
|
|
|
origin_folder = os.path.join(content_folder, "Static", map_name)
|
|
|
|
dest_path = ""
|
|
|
|
src_path = ""
|
|
|
|
marking_dir = os.path.join(content_folder, "Static", "RoadLines", "%sLaneMarking" % map_name)
|
|
|
|
road_dir = os.path.join(content_folder, "Static", "Road", "Roads%s" % map_name)
|
|
|
|
terrain_dir = os.path.join(content_folder, "Static", "Terrain", "%sTerrain" % map_name)
|
|
|
|
if not os.path.exists(marking_dir):
|
|
|
|
os.makedirs(marking_dir)
|
|
|
|
if not os.path.exists(road_dir):
|
|
|
|
os.makedirs(road_dir)
|
|
|
|
if not os.path.exists(terrain_dir):
|
|
|
|
os.makedirs(terrain_dir)
|
|
|
|
for filename in os.listdir(origin_folder):
|
|
|
|
if "MarkingNode" in filename:
|
|
|
|
dest_path = os.path.join(marking_dir, filename)
|
|
|
|
if "RoadNode" in filename:
|
|
|
|
dest_path = os.path.join(road_dir, filename)
|
|
|
|
if "TerrainNode" in filename:
|
|
|
|
dest_path = os.path.join(terrain_dir, filename)
|
|
|
|
src_path = os.path.join(content_folder, "Static", map_name, filename)
|
|
|
|
os.rename(src_path, dest_path)
|
|
|
|
|
|
|
|
|
|
|
|
def invoke_commandlet(name, arguments):
|
2019-02-07 23:06:57 +08:00
|
|
|
ue4_path = os.environ['UE4_ROOT']
|
2019-02-15 23:20:24 +08:00
|
|
|
dirname = os.getcwd()
|
2019-02-07 23:06:57 +08:00
|
|
|
editor_path = "%s/Engine/Binaries/%s/UE4Editor" % (ue4_path, sys_name)
|
2019-03-29 01:53:35 +08:00
|
|
|
uproject_path = os.path.join(dirname, "..", "Unreal", "CarlaUE4", "CarlaUE4.uproject")
|
2019-02-15 23:20:24 +08:00
|
|
|
full_command = "%s %s -run=%s %s" % (editor_path, uproject_path, name, arguments)
|
2019-02-07 23:06:57 +08:00
|
|
|
subprocess.check_call([full_command], shell=True)
|
|
|
|
|
2019-02-15 23:20:24 +08:00
|
|
|
|
|
|
|
def generate_json(map_name, json_file):
|
2019-04-01 20:41:59 +08:00
|
|
|
with open(json_file, "w+") as fh:
|
2019-02-25 22:46:06 +08:00
|
|
|
import_groups = []
|
|
|
|
file_names = []
|
|
|
|
import_settings = []
|
2019-04-01 20:41:59 +08:00
|
|
|
fbx_path = os.path.join("..", "..", "RoadRunnerFiles", map_name, "%s.fbx" % map_name)
|
2019-02-25 22:46:06 +08:00
|
|
|
file_names.append(fbx_path)
|
|
|
|
|
|
|
|
import_settings.append({
|
2019-03-15 18:19:33 +08:00
|
|
|
"bImportMesh": 1,
|
|
|
|
"bConvertSceneUnit": 1,
|
|
|
|
"bConvertScene": 1,
|
|
|
|
"bCombineMeshes": 1,
|
|
|
|
"bImportTextures": 1,
|
|
|
|
"bImportMaterials": 1,
|
2019-02-25 22:46:06 +08:00
|
|
|
"bRemoveDegenerates": 1,
|
2019-03-15 18:19:33 +08:00
|
|
|
"AnimSequenceImportData": {},
|
|
|
|
"SkeletalMeshImportData": {},
|
|
|
|
"TextureImportData": {},
|
|
|
|
"StaticMeshImportData": {
|
|
|
|
"bRemoveDegenerates": 1,
|
|
|
|
"bAutoGenerateCollision": 0,
|
|
|
|
"bCombineMeshes": 0
|
2019-02-25 22:46:06 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
dest_path = "/Game/Carla/Static/Imported/%s" % map_name
|
|
|
|
import_groups.append({
|
2019-03-15 18:19:33 +08:00
|
|
|
"ImportSettings": import_settings,
|
|
|
|
"FactoryName": "FbxFactory",
|
|
|
|
"DestinationPath": dest_path,
|
|
|
|
"bReplaceExisting": "true",
|
|
|
|
"FileNames": file_names
|
2019-02-25 22:46:06 +08:00
|
|
|
})
|
|
|
|
fh.write(json.dumps({"ImportGroups": import_groups}))
|
|
|
|
fh.close()
|
2019-02-07 23:06:57 +08:00
|
|
|
|
|
|
|
|
2019-02-25 22:46:06 +08:00
|
|
|
if __name__ == '__main__':
|
2019-03-15 18:19:33 +08:00
|
|
|
|
|
|
|
main()
|