Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / build_gamedata / processes / shape / 2_build.py
blob86a3b6a994fc7e06afd98ebfb592105b331d584f
1 #!/usr/bin/python
2 #
3 # \file 2_build.py
4 # \brief Build shape
5 # \date 2010-05-24 13:42GMT
6 # \author Jan Boon (Kaetemi)
7 # Python port of game data build pipeline.
8 # Build shape
9 #
10 # NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
11 # Copyright (C) 2009-2014 by authors
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU Affero General Public License as
15 # published by the Free Software Foundation, either version 3 of the
16 # License, or (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU Affero General Public License for more details.
23 # You should have received a copy of the GNU Affero General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
27 import time, sys, os, shutil, subprocess, distutils.dir_util
28 sys.path.append("../../configuration")
30 if os.path.isfile("log.log"):
31 os.remove("log.log")
32 log = open("log.log", "w")
33 from scripts import *
34 from buildsite import *
35 from process import *
36 from tools import *
37 from directories import *
39 printLog(log, "")
40 printLog(log, "-------")
41 printLog(log, "--- Build shape")
42 printLog(log, "-------")
43 printLog(log, time.strftime("%Y-%m-%d %H:%MGMT", time.gmtime(time.time())))
44 printLog(log, "")
46 # Find tools
47 ExecTimeout = findTool(log, ToolDirectories, ExecTimeoutTool, ToolSuffix)
48 BuildShadowSkin = findTool(log, ToolDirectories, BuildShadowSkinTool, ToolSuffix)
49 BuildClodtex = findTool(log, ToolDirectories, BuildClodtexTool, ToolSuffix)
50 LightmapOptimizer = findTool(log, ToolDirectories, LightmapOptimizerTool, ToolSuffix)
51 TgaToDds = findTool(log, ToolDirectories, TgaToDdsTool, ToolSuffix)
52 BuildCoarseMesh = findTool(log, ToolDirectories, BuildCoarseMeshTool, ToolSuffix)
54 shapeDirectory = ExportBuildDirectory + "/" + ShapeNotOptimizedExportDirectory
55 if BuildShadowSkinEnabled:
56 mkPath(log, shapeDirectory)
57 shadowSkinBuildDirectory = ExportBuildDirectory + "/" + ShapeShadowSkinBuildDirectory
58 printLog(log, ">>> BuildShadowSkin <<<")
59 shadowSkinShapes = findFilesNoSubdir(log, shapeDirectory, ".shape")
60 for shadowSkinShape in shadowSkinShapes:
61 srcShape = shapeDirectory + "/" + shadowSkinShape
62 dstShape = shadowSkinBuildDirectory + "/" + shadowSkinShape
63 if needUpdateLogRemoveDest(log, srcShape, dstShape):
64 subprocess.call([ BuildShadowSkin, srcShape, dstShape, str(BuildShadowSkinRatio), str(BuildShadowSkinMaxface) ])
65 shapeDirectory = shadowSkinBuildDirectory
67 mkPath(log, shapeDirectory)
68 mkPath(log, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory)
69 if ClodConfigFile != "":
70 mkPath(log, ExportBuildDirectory + "/" + ClodExportDirectory)
71 printLog(log, ">>> Build CLodTex <<<")
72 subprocess.call([ BuildClodtex, "-d", DatabaseDirectory + "/" + ClodConfigFile, ExportBuildDirectory + "/" + ClodExportDirectory, shapeDirectory, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory ])
73 else:
74 printLog(log, ">>> Copy Shape <<<")
75 copyFilesExtNoTreeIfNeeded(log, shapeDirectory, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory, ".shape")
77 printLog(log, ">>> Copy non-ShadowSkin non-CLodTex Shape <<<")
78 shapeDirectory = ExportBuildDirectory + "/" + ShapeNotOptimizedExportDirectory
79 mkPath(log, shapeDirectory)
80 mkPath(log, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory)
81 copyFilesExtNoTreeIfNeeded(log, shapeDirectory, ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory, ".shape")
82 shapeDirectory = ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory
84 # copy lightmap_not_optimized to lightmap
85 printLog(log, ">>> Optimize lightmaps <<<")
86 loPathLightmapsOriginal = ExportBuildDirectory + "/" + ShapeLightmapNotOptimizedExportDirectory
87 loPathShapesOriginal = ExportBuildDirectory + "/" + ShapeClodtexBuildDirectory
88 mkPath(log, loPathLightmapsOriginal)
89 loPathLightmaps = ExportBuildDirectory + "/" + ShapeLightmapBuildDirectory
90 loPathShapes = ExportBuildDirectory + "/" + ShapeOptimizedBuildDirectory
91 loPathTags = ExportBuildDirectory + "/" + ShapeTagExportDirectory
92 mkPath(log, loPathLightmaps)
93 mkPath(log, loPathShapes)
94 mkPath(log, loPathTags)
95 if needUpdateDirByTagLog(log, loPathLightmapsOriginal, ".txt", loPathLightmaps, ".txt") or needUpdateDirNoSubdir(log, loPathLightmapsOriginal, loPathLightmaps) or needUpdateDirNoSubdir(log, loPathShapesOriginal, loPathShapes) or needUpdateDirNoSubdir(log, loPathShapes, loPathLightmaps) or needUpdateDirNoSubdir(log, loPathTags, loPathLightmaps):
96 removeFilesRecursive(log, loPathLightmaps)
97 copyFiles(log, loPathLightmapsOriginal, loPathLightmaps)
98 removeFilesRecursive(log, loPathShapes)
99 copyFiles(log, loPathShapesOriginal, loPathShapes)
100 # Optimize lightmaps if any. Additionnaly, output a file indicating which lightmaps are 8 bits
101 # lightmap_optimizer <path_lightmaps> <path_shapes> [path_tags] [path_flag8bit]
102 subprocess.call([ LightmapOptimizer, loPathLightmaps, loPathShapes, loPathTags, ExportBuildDirectory + "/" + ShapeLightmapBuildDirectory + "/list_lm_8bit.txt" ])
103 else:
104 printLog(log, "SKIP *")
106 # Convert lightmap in 16 bits mode if they are not 8 bits lightmap
107 printLog(log, ">>> Convert lightmaps in 16 or 8 bits <<<")
108 mkPath(log, ExportBuildDirectory + "/" + ShapeLightmapBuildDirectory)
109 mkPath(log, ExportBuildDirectory + "/" + ShapeLightmap16BitsBuildDirectory)
110 lightMapTgas = findFilesNoSubdir(log, ExportBuildDirectory + "/" + ShapeLightmapBuildDirectory, ".tga")
111 listLm8Bit = [ ]
112 listLm8BitFile = open(ExportBuildDirectory + "/" + ShapeLightmapBuildDirectory + "/list_lm_8bit.txt", "r")
113 for line in listLm8BitFile:
114 lineStrip = line.strip()
115 if (len(lineStrip) > 0):
116 listLm8Bit += [ lineStrip ]
117 for lightMapTga in lightMapTgas:
118 srcTga = ExportBuildDirectory + "/" + ShapeLightmapBuildDirectory + "/" + lightMapTga
119 dstTga = ExportBuildDirectory + "/" + ShapeLightmap16BitsBuildDirectory + "/" + lightMapTga
120 if needUpdateLogRemoveDest(log, srcTga, dstTga):
121 if lightMapTga in listLm8Bit: # THIS MAY NOT WORK, PLEASE VERIFY CONTENTS OF list_lm_8bit.txt!!!
122 subprocess.call([ TgaToDds, srcTga, "-o", dstTga, "-a", "tga8" ])
123 else:
124 subprocess.call([ TgaToDds, srcTga, "-o", dstTga, "-a", "tga16" ])
126 # Corse meshes for this process ?
127 if len(CoarseMeshTextureNames) > 0:
128 printLog(log, ">>> Build coarse meshes <<<")
129 shapeWithCoarseMesh = ExportBuildDirectory + "/" + ShapeWithCoarseMeshExportDirectory
130 mkPath(log, shapeWithCoarseMesh)
131 shapeWithCoarseMeshBuilded = ExportBuildDirectory + "/" + ShapeWithCoarseMeshBuildDirectory
132 mkPath(log, shapeWithCoarseMeshBuilded)
133 # This builds from shapeWithCoarseMesh .shape to shapeWithCoarseMesh .tga
134 # And from shapeWithCoarseMesh .shape to shapeWithCoarseMeshBuilded .shape
135 # Then builds from shapeWithCoarseMesh .tga to shapeWithCoarseMeshBuilded .tga
136 # Depends on MapLookupDirectories
137 needUpdateMaps = needUpdateMultiDirNoSubdirMultiFileExt(log, ExportBuildDirectory, MapLookupDirectories, shapeWithCoarseMesh, CoarseMeshTextureNames, ".tga") or needUpdateMultiDirNoSubdir(log, ExportBuildDirectory, MapLookupDirectories, shapeWithCoarseMeshBuilded)
138 if needUpdateMaps:
139 printLog(log, "DETECT UPDATE Maps->*")
140 else:
141 printLog(log, "DETECT SKIP Maps->*")
142 needUpdateShapeShape = needUpdateDirByTagLog(log, shapeWithCoarseMesh, ".shape", shapeWithCoarseMeshBuilded, ".shape")
143 if needUpdateShapeShape:
144 printLog(log, "DETECT UPDATE Shape->Shape")
145 else:
146 printLog(log, "DETECT SKIP Shape->Shape")
147 needUpdateShapeCoarse = needUpdateDirNoSubdirExtMultiFileExt(log, shapeWithCoarseMesh, ".shape", shapeWithCoarseMesh, CoarseMeshTextureNames, ".tga")
148 if needUpdateShapeCoarse:
149 printLog(log, "DETECT UPDATE Shape->Coarse")
150 else:
151 printLog(log, "DETECT SKIP Shape->Coarse")
152 if needUpdateMaps or needUpdateShapeShape or needUpdateShapeCoarse:
153 cf = open("config_generated.cfg", "w")
154 cf.write("texture_mul_size = " + TextureMulSizeValue + ";\n")
155 cf.write("\n")
156 cf.write("search_path = \n")
157 cf.write("{\n")
158 cf.write("\t\"" + shapeWithCoarseMesh + "\", \n")
159 for dir in MapLookupDirectories:
160 cf.write("\t\"" + ExportBuildDirectory + "/" + dir + "\", \n")
161 cf.write("};\n")
162 cf.write("\n")
163 cf.write("list_mesh = \n")
164 cf.write("{\n")
165 # For each shape with coarse mesh
166 files = findFiles(log, shapeWithCoarseMesh, "", ".shape")
167 for file in files:
168 sourceFile = shapeWithCoarseMesh + "/" + file
169 if os.path.isfile(sourceFile):
170 destFile = shapeWithCoarseMeshBuilded + "/" + file
171 cf.write("\t\"" + file + "\", \"" + destFile + "\", \n")
172 cf.write("};\n")
173 cf.write("\n")
174 cf.write("output_textures = \n")
175 cf.write("{\n")
176 # For each shape with coarse mesh
177 for tn in CoarseMeshTextureNames:
178 cf.write("\t\"" + shapeWithCoarseMesh + "/" + tn + ".tga\", \n")
179 cf.write("};\n")
180 cf.close()
181 subprocess.call([ BuildCoarseMesh, "config_generated.cfg" ])
182 os.remove("config_generated.cfg")
183 needUpdateCoarse = needUpdateDirNoSubdirExtMultiFileExt(log, shapeWithCoarseMesh, ".tga", shapeWithCoarseMeshBuilded, CoarseMeshTextureNames, ".dds")
184 if needUpdateCoarse:
185 printLog(log, "DETECT UPDATE Coarse->DDS")
186 else:
187 printLog(log, "DETECT SKIP Coarse->DDS")
188 # Convert the coarse texture to dds
189 if needUpdateCoarse:
190 for tn in CoarseMeshTextureNames:
191 subprocess.call([ TgaToDds, shapeWithCoarseMesh + "/" + tn + ".tga", "-o", shapeWithCoarseMeshBuilded + "/" + tn + ".dds", "-a", "5" ])
192 else:
193 printLog(log, ">>> No coarse meshes <<<")
195 log.close()
198 # end of file