private static Bitmap DownscaleTexture(Bitmap texture, string path, CookingRules rules) { int MaxSize = GetMaxAtlasSize().Width; int scaleThreshold = Platform == TargetPlatform.Android ? 32 : 256; var ratio = rules.TextureScaleFactor; if (texture.Width > MaxSize || texture.Height > MaxSize) { var max = (float)Math.Max(texture.Width, texture.Height); ratio *= MaxSize / max; } int newWidth = texture.Width; int newHeight = texture.Height; if (texture.Width > scaleThreshold) { newWidth = Math.Min((texture.Width * ratio).Round(), MaxSize); } if (texture.Height > scaleThreshold) { newHeight = Math.Min((texture.Height * ratio).Round(), MaxSize); } Console.WriteLine("{0} downscaled to {1}x{2}", path, newWidth, newHeight); return(texture.Rescale(newWidth, newHeight)); }
public static void AfterAssetUpdated(Lime.AssetBundle bundle, CookingRules cookingRules, string path) { foreach (var i in CurrentPlugin.AfterAssetUpdated) { i(bundle, cookingRules, path); } }
private static bool ShouldDownscale(Bitmap texture, CookingRules rules) { if (rules.TextureScaleFactor != 1.0f) { int scaleThreshold = Platform == TargetPlatform.Android ? 32 : 256; if (texture.Width > scaleThreshold || texture.Height > scaleThreshold) { return(true); } } return(false); }
public void SyncUpdated(string fileExtension, string bundleAssetExtension, Converter converter, Func <string, string, bool> extraOutOfDateChecker = null) { foreach (var fileInfo in InputBundle.EnumerateFileInfos(null, fileExtension)) { UserInterface.Instance.IncreaseProgressBar(); var srcPath = fileInfo.Path; var dstPath = Path.ChangeExtension(srcPath, bundleAssetExtension); var bundled = OutputBundle.FileExists(dstPath); var srcRules = CookingRulesMap[srcPath]; var needUpdate = !bundled || fileInfo.LastWriteTime != OutputBundle.GetFileLastWriteTime(dstPath); needUpdate = needUpdate || !srcRules.SHA1.SequenceEqual(OutputBundle.GetCookingRulesSHA1(dstPath)); needUpdate = needUpdate || (extraOutOfDateChecker?.Invoke(srcPath, dstPath) ?? false); if (needUpdate) { if (converter != null) { try { if (converter(srcPath, dstPath)) { Console.WriteLine((bundled ? "* " : "+ ") + dstPath); CookingRules rules = null; if (!string.IsNullOrEmpty(dstPath)) { CookingRulesMap.TryGetValue(dstPath, out rules); } PluginLoader.AfterAssetUpdated(OutputBundle, rules, dstPath); } } catch (System.Exception e) { Console.WriteLine( "An exception was caught while processing '{0}': {1}\n", srcPath, e.Message); throw; } } else { Console.WriteLine((bundled ? "* " : "+ ") + dstPath); using (var stream = InputBundle.OpenFile(srcPath)) { OutputBundle.ImportFile(dstPath, stream, 0, fileExtension, InputBundle.GetFileLastWriteTime(srcPath), AssetAttributes.None, CookingRulesMap[srcPath].SHA1); } } } } }
public CookingRules InheritClone() { var r = new CookingRules(false); r.Parent = this; foreach (var kv in TargetRules) { r.TargetRules.Add(kv.Key, kv.Value.InheritClone()); } if (EffectiveRules != null) { r.CommonRules = EffectiveRules.InheritClone(); r.EffectiveRules = EffectiveRules.InheritClone(); } else { r.CommonRules = CommonRules.InheritClone(); } return(r); }
static void SyncUpdated(string fileExtension, string bundleAssetExtension, AssetBundle bundle, Converter converter) { foreach (var srcFileInfo in The.Workspace.AssetFiles.Enumerate(fileExtension)) { var srcPath = srcFileInfo.Path; var dstPath = Path.ChangeExtension(srcPath, bundleAssetExtension); var bundled = bundle.FileExists(dstPath); var srcRules = cookingRulesMap[srcPath]; var needUpdate = !bundled || srcFileInfo.LastWriteTime > bundle.GetFileLastWriteTime(dstPath); needUpdate = needUpdate || !srcRules.SHA1.SequenceEqual(bundle.GetCookingRulesSHA1(dstPath)); if (needUpdate) { if (converter != null) { try { if (converter(srcPath, dstPath)) { Console.WriteLine((bundled ? "* " : "+ ") + dstPath); CookingRules rules = null; if (!string.IsNullOrEmpty(dstPath)) { cookingRulesMap.TryGetValue(dstPath, out rules); } PluginLoader.AfterAssetUpdated(bundle, rules, dstPath); } } catch (System.Exception e) { Console.WriteLine( "An exception was caught while processing '{0}': {1}\n", srcPath, e.Message); throw; } } else { Console.WriteLine((bundled ? "* " : "+ ") + dstPath); using (Stream stream = new FileStream(srcPath, FileMode.Open, FileAccess.Read)) { bundle.ImportFile(dstPath, stream, 0, fileExtension, AssetAttributes.None, cookingRulesMap[srcPath].SHA1); } } } } }
private static CookingRules ParseCookingRules(CookingRules basicRules, string path, Target target) { var rules = basicRules.InheritClone(); var currentRules = rules.CommonRules; try { rules.CommonRules.LastChangeTime = File.GetLastWriteTime(path); using (var s = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { TextReader r = new StreamReader(s); string line; while ((line = r.ReadLine()) != null) { line = line.Trim(); if (line == "") { continue; } var words = line.Split(' '); if (words.Length < 2) { throw new Lime.Exception("Invalid rule format"); } // target-specific cooking rules if (words[0].EndsWith(")")) { int cut = words[0].IndexOf('('); if (cut >= 0) { string targetName = words[0].Substring(cut + 1, words[0].Length - cut - 2); words[0] = words[0].Substring(0, cut); currentRules = null; Target currentTarget = null; foreach (var t in The.Workspace.Targets) { if (targetName == t.Name) { currentTarget = t; } } if (currentTarget == null) { throw new Lime.Exception($"Invalid target: {targetName}"); } currentRules = rules.TargetRules[currentTarget]; { var targetPlatformAttribute = (TargetPlatformsAttribute)typeof(ICookingRules) .GetProperty(words[0]).GetCustomAttribute(typeof(TargetPlatformsAttribute)); if (targetPlatformAttribute != null && !targetPlatformAttribute.TargetPlatforms.Contains(currentTarget.Platform)) { throw new Lime.Exception($"Invalid platform {currentTarget.Platform} for cooking rule {words[0]}"); } } } } else { currentRules = rules.CommonRules; } ParseRule(currentRules, words, path); } } } catch (Lime.Exception e) { if (!Path.IsPathRooted(path)) { path = Path.Combine(Directory.GetCurrentDirectory(), path); } throw new Lime.Exception("Syntax error in {0}: {1}", path, e.Message); } rules.DeduceEffectiveRules(target); return(rules); }
// pass target as null to build cooking rules disregarding targets public static Dictionary <string, CookingRules> Build(IFileEnumerator fileEnumerator, Target target) { var shouldRescanEnumerator = false; var pathStack = new Stack <string>(); var rulesStack = new Stack <CookingRules>(); var map = new Dictionary <string, CookingRules>(); pathStack.Push(""); var rootRules = new CookingRules(); rootRules.DeduceEffectiveRules(target); rulesStack.Push(rootRules); using (new DirectoryChanger(fileEnumerator.Directory)) { foreach (var fileInfo in fileEnumerator.Enumerate()) { var path = fileInfo.Path; while (!path.StartsWith(pathStack.Peek())) { rulesStack.Pop(); pathStack.Pop(); } if (Path.GetFileName(path) == CookingRulesFilename) { var dirName = Lime.AssetPath.GetDirectoryName(path); pathStack.Push(dirName == string.Empty ? "" : dirName + "/"); var rules = ParseCookingRules(rulesStack.Peek(), path, target); rules.SourceFilename = AssetPath.Combine(fileEnumerator.Directory, path); rulesStack.Push(rules); // Add 'ignore' cooking rules for this #CookingRules.txt itself var ignoreRules = rules.InheritClone(); ignoreRules.Ignore = true; map[path] = ignoreRules; var directoryName = pathStack.Peek(); if (!string.IsNullOrEmpty(directoryName)) { directoryName = directoryName.Remove(directoryName.Length - 1); // it is possible for map to not contain this directoryName since not every IFileEnumerator enumerates directories if (map.ContainsKey(directoryName)) { map[directoryName] = rules; } } } else { if (Path.GetExtension(path) == ".txt") { var filename = path.Remove(path.Length - 4); if (File.Exists(filename) || Directory.Exists(filename)) { continue; } } var rulesFile = path + ".txt"; var rules = rulesStack.Peek(); if (File.Exists(rulesFile)) { rules = ParseCookingRules(rulesStack.Peek(), rulesFile, target); rules.SourceFilename = AssetPath.Combine(fileEnumerator.Directory, rulesFile); // Add 'ignore' cooking rules for this cooking rules text file var ignoreRules = rules.InheritClone(); ignoreRules.Ignore = true; map[rulesFile] = ignoreRules; } if (rules.CommonRules.LastChangeTime > fileInfo.LastWriteTime) { try { File.SetLastWriteTime(path, rules.CommonRules.LastChangeTime); } catch (UnauthorizedAccessException) { // In case this is a folder } shouldRescanEnumerator = true; } map[path] = rules; } } } if (shouldRescanEnumerator) { fileEnumerator.Rescan(); } return(map); }
public static void DownscaleTextureInfo(TargetPlatform platform, BitmapInfo textureInfo, string path, CookingRules rules) { int newHeight; int newWidth; DownscaleTextureHelper(platform, textureInfo.Width, textureInfo.Height, path, rules, out newWidth, out newHeight); textureInfo.Height = newHeight; textureInfo.Width = newWidth; }
public static bool ShouldDownscale(TargetPlatform platform, BitmapInfo textureInfo, CookingRules rules) { return(ShouldDownscaleHelper(platform, textureInfo.Width, textureInfo.Height, rules)); }
private static bool ShouldDownscaleHelper(TargetPlatform platform, int width, int height, CookingRules rules) { if (rules.TextureScaleFactor != 1.0f) { int scaleThreshold = platform == TargetPlatform.Android ? 32 : 256; if (width > scaleThreshold || height > scaleThreshold) { return(true); } } return(false); }
private static void DownscaleTextureHelper(TargetPlatform platform, int width, int height, string path, CookingRules rules, out int newWidth, out int newHeight) { int MaxSize = GetMaxAtlasSize().Width; int scaleThreshold = platform == TargetPlatform.Android ? 32 : 256; var ratio = rules.TextureScaleFactor; if (width > MaxSize || height > MaxSize) { var max = (float)Math.Max(width, height); ratio *= MaxSize / max; } newWidth = width; newHeight = height; if (width > scaleThreshold) { newWidth = Math.Min((width * ratio).Round(), MaxSize); } if (height > scaleThreshold) { newHeight = Math.Min((height * ratio).Round(), MaxSize); } Console.WriteLine("{0} downscaled to {1}x{2}", path, newWidth, newHeight); }
public static Bitmap DownscaleTexture(TargetPlatform platform, Bitmap texture, string path, CookingRules rules) { int newHeight; int newWidth; DownscaleTextureHelper(platform, texture.Width, texture.Height, path, rules, out newWidth, out newHeight); return(texture.Rescale(newWidth, newHeight)); }