diff --git a/Urcheon/Action.py b/Urcheon/Action.py index b4ac496..ab0a093 100644 --- a/Urcheon/Action.py +++ b/Urcheon/Action.py @@ -180,14 +180,6 @@ def list(): # perhaps one day MergeBsp will be run on a copied bsp # so it must be called after that MergeBsp, - # those are probably the slowest compression image - # formats we know - ConvertKtx, - ConvertDds, - ConvertCrn, - ConvertNormalCrn, - ConvertLosslessWebp, - ConvertLossyWebp, # sloth needs previews to be done before sloth # TODO: be sure Sloth is not called before # all previews are generated @@ -197,6 +189,18 @@ def list(): SlothRun, # usually quick CompileIqm, + # compiling a map model may require shaders and other models + # being generated first. + CompileAse, + CompileObj, + # those are probably the slowest compression image + # formats we know + ConvertKtx, + ConvertDds, + ConvertCrn, + ConvertNormalCrn, + ConvertLosslessWebp, + ConvertLossyWebp, # can take some time but not blocking ConvertVorbis, ConvertOpus, @@ -957,7 +961,9 @@ class DumbTransient(Action): def createTransientPath(self): build_path = self.getTargetPath() self.transient_path = tempfile.mkdtemp(suffix="_" + os.path.basename(build_path) + "_transient" + os.path.extsep + "dir") - self.transient_maps_path = os.path.join(self.transient_path, "maps") + logging.debug("transient path: " + self.transient_path) + + self.transient_maps_path = os.path.join(self.transient_path, os.path.dirname(self.file_path)) os.makedirs(self.transient_maps_path, exist_ok=True) def buildTransientPath(self, disabled_action_list=[]): @@ -1115,3 +1121,48 @@ def effective_run(self): def getFileNewName(self): return self.switchExtension("bsp") + + +class CompileAse(DumbTransient): + keyword = "compile_ase" + description = "compile to ase format" + extension = "ase" + + def effective_run(self): + source_path = self.getSourcePath() + build_path = self.getTargetPath() + bsp_path = self.getFileBspName() + self.createSubdirs() + + self.createTransientPath() + + Ui.laconic("Compiling to " + self.extension + ": " + self.file_path) + + # Do not copy the map source when building in the source directory as a prepare step. + if self.source_dir == self.build_dir: + stage_done = ["copy"] + else: + stage_done = [] + + map_compiler = MapCompiler.Compiler(self.source_tree, map_profile=self.extension) + map_compiler.compile(source_path, self.transient_maps_path, stage_done=stage_done) + + os.remove(os.path.join(self.transient_path, bsp_path)) + + self.buildTransientPath(disabled_action_list=["copy_bsp", "compile_bsp"]) + + self.setTimeStamp() + + return self.getProducedUnitList() + + def getFileBspName(self): + return self.switchExtension("bsp") + + def getFileNewName(self): + return self.switchExtension(self.extension) + + +class CompileObj(CompileAse): + keyword = "compile_obj" + description = "compile to obj format" + extension = "obj" diff --git a/Urcheon/MapCompiler.py b/Urcheon/MapCompiler.py index 8a4942b..333cf1b 100644 --- a/Urcheon/MapCompiler.py +++ b/Urcheon/MapCompiler.py @@ -162,6 +162,7 @@ def readConfig(self, config_file_name, is_parent=False): "light": ["vis"], "minimap": ["vis"], "nav": ["vis"], + "convert": ["bsp"], } for profile_name in self.profile_dict.keys(): @@ -227,6 +228,7 @@ def __init__(self, source_tree, map_profile=None, is_parallel=True): def compile(self, map_path, build_prefix, stage_done=[]): self.map_path = map_path self.build_prefix = build_prefix + self.stage_done = stage_done stage_name = None stage_option_list = [] self.pakpath_list = [] @@ -365,7 +367,7 @@ def q3map2(self, option_list, tool_name="q3map2"): extended_option_list = [] # bsp stage is the one that calls -bsp, etc. - for stage in ["bsp", "vis", "light", "minimap", "nav"]: + for stage in ["bsp", "vis", "light", "minimap", "nav", "convert"]: if "-" + stage in option_list: stage_name = stage logging.debug("stage name: " + stage_name) @@ -383,6 +385,8 @@ def q3map2(self, option_list, tool_name="q3map2"): source_path = bsp_path elif "-minimap" in option_list: source_path = bsp_path + elif "-convert" in option_list: + source_path = bsp_path else: extended_option_list = ["-prtfile", self.prt_path, "-srffile", self.srf_path, "-bspfile", bsp_path] # TODO: define the name somewhere @@ -397,7 +401,7 @@ def q3map2(self, option_list, tool_name="q3map2"): Ui.error("command failed: '" + "' '".join(command_list) + "'") # keep map source - if "-bsp" in option_list and self.map_config.keep_source: + if "-bsp" in option_list and self.map_config.keep_source and "copy" not in self.stage_done: self.copy([]) diff --git a/profile/file/daemon.conf b/profile/file/daemon.conf index 61a2fe5..78e66bf 100644 --- a/profile/file/daemon.conf +++ b/profile/file/daemon.conf @@ -190,6 +190,13 @@ dir_ancestor_name = "maps" description = "Map" build = "compile_bsp" +[daemon_ase] +file_ext = "map" +dir_ancestor_name = "models" +description = "Map object" +prepare = "compile_ase" +build = "copy" + [daemon_bspdir_lump] dir_ancestor_name = "maps" dir_father_ext = ".bspdir" diff --git a/profile/map/common.conf b/profile/map/common.conf index f845dc8..294ca6f 100644 --- a/profile/map/common.conf +++ b/profile/map/common.conf @@ -10,3 +10,11 @@ game="${game}" [copy] copy = { tool="copy" } + +[ase] +bsp = { tool="q3map2", options="-bsp -meta -patchmeta" } +convert = { tool="q3map2", options="-convert -format ase" } + +[obj] +bsp = { tool="q3map2", options="-bsp -meta -patchmeta" } +convert = { tool="q3map2", options="-convert -format obj" }