Beispiel #1
0
        private void CopyAllocatedItemsToAtlas(List <TextureTools.AtlasItem> items, string atlasChain, int atlasId, Size size)
        {
            var atlasPath   = AssetCooker.GetAtlasPath(atlasChain, atlasId);
            var atlasPixels = new Color4[size.Width * size.Height];

            foreach (var item in items.Where(i => i.Allocated))
            {
                var atlasRect = item.AtlasRect;
                using (var bitmap = TextureTools.OpenAtlasItemBitmapAndRescaleIfNeeded(AssetCooker.Platform, item)) {
                    CopyPixels(bitmap, atlasPixels, atlasRect.A.X, atlasRect.A.Y, size.Width, size.Height);
                }
                var atlasPart = new TextureAtlasElement.Params {
                    AtlasRect = atlasRect,
                    AtlasPath = Path.ChangeExtension(atlasPath, null)
                };
                var srcPath = Path.ChangeExtension(item.Path, item.SourceExtension);
                InternalPersistence.Instance.WriteObjectToBundle(AssetCooker.OutputBundle, item.Path, atlasPart, Persistence.Format.Binary,
                                                                 item.SourceExtension, AssetCooker.InputBundle.GetFileLastWriteTime(srcPath), AssetAttributes.None, item.CookingRules.SHA1);
                // Delete non-atlased texture since now its useless
                var texturePath = Path.ChangeExtension(item.Path, AssetCooker.GetPlatformTextureExtension());
                if (AssetCooker.OutputBundle.FileExists(texturePath))
                {
                    AssetCooker.DeleteFileFromBundle(texturePath);
                }
                UserInterface.Instance.IncreaseProgressBar();
            }
            Console.WriteLine("+ " + atlasPath);
            var firstItem = items.First(i => i.Allocated);

            using (var atlas = new Bitmap(atlasPixels, size.Width, size.Height)) {
                AssetCooker.ImportTexture(atlasPath, atlas, firstItem.CookingRules, AssetCooker.InputBundle.GetFileLastWriteTime(atlasPath), CookingRulesSHA1: null);
            }
        }
 public void Action()
 {
     foreach (var maskPath in AssetCooker.AssetBundle.EnumerateFiles().ToList())
     {
         if (maskPath.EndsWith(maskExtension, StringComparison.OrdinalIgnoreCase))
         {
             var origImageFile = Path.ChangeExtension(maskPath, AssetCooker.GetPlatformTextureExtension());
             if (!AssetCooker.AssetBundle.FileExists(origImageFile))
             {
                 AssetCooker.DeleteFileFromBundle(maskPath);
             }
             UserInterface.Instance.IncreaseProgressBar();
         }
     }
 }
Beispiel #3
0
        public void Action()
        {
            var assetFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var fileInfo in The.Workspace.AssetFiles.Enumerate())
            {
                assetFiles.Add(fileInfo.Path);
            }
            foreach (var path in AssetCooker.AssetBundle.EnumerateFiles().ToList())
            {
                // Ignoring texture atlases
                if (path.StartsWith("Atlases"))
                {
                    continue;
                }
                // Ignore atlas parts, masks, animations
                var ext = Path.GetExtension(path);
                if (toDeleteExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase))
                {
                    continue;
                }
                var assetPath = Path.ChangeExtension(path, AssetCooker.GetOriginalAssetExtension(path));
                if (!assetFiles.Contains(assetPath))
                {
                    if (path.EndsWith(modelTanExtension, StringComparison.OrdinalIgnoreCase))
                    {
                        AssetCooker.DeleteModelExternalAnimations(AssetCooker.GetModelAnimationPathPrefix(path));
                    }
                    var modelAttachmentExtIndex = path.LastIndexOf(Model3DAttachment.FileExtension);
                    if (modelAttachmentExtIndex >= 0)
                    {
                        AssetCooker.ModelsToRebuild.Add(path.Remove(modelAttachmentExtIndex) + modelTanExtension);
                    }
                    AssetCooker.DeleteFileFromBundle(path);
                    UserInterface.Instance.IncreaseProgressBar();
                }
            }
        }
Beispiel #4
0
        public void Action()
        {
            var textures = new Dictionary <string, DateTime>(StringComparer.OrdinalIgnoreCase);

            foreach (var fileInfo in AssetCooker.InputBundle.EnumerateFileInfos(null, textureExtension))
            {
                textures[fileInfo.Path] = fileInfo.LastWriteTime;
            }
            var atlasChainsToRebuild = new HashSet <string>();

            // Figure out atlas chains to rebuild
            foreach (var atlasPartPath in AssetCooker.OutputBundle.EnumerateFiles().ToList())
            {
                if (!atlasPartPath.EndsWith(atlasPartExtension, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // If atlas part has been outdated we should rebuild full atlas chain
                var srcTexturePath = Path.ChangeExtension(atlasPartPath, textureExtension);
                var bundleSHA1     = AssetCooker.OutputBundle.GetCookingRulesSHA1(atlasPartPath);
                if (bundleSHA1 == null)
                {
                    throw new InvalidOperationException("CookingRules SHA1 for atlas part shouldn't be null");
                }
                if (
                    !textures.ContainsKey(srcTexturePath) ||
                    AssetCooker.OutputBundle.GetFileLastWriteTime(atlasPartPath) != textures[srcTexturePath] ||
                    (!AssetCooker.CookingRulesMap[srcTexturePath].SHA1.SequenceEqual(bundleSHA1))
                    )
                {
                    srcTexturePath = AssetPath.Combine(The.Workspace.AssetsDirectory, srcTexturePath);
                    var part       = InternalPersistence.Instance.ReadObjectFromBundle <TextureAtlasElement.Params>(AssetCooker.OutputBundle, atlasPartPath);
                    var atlasChain = Path.GetFileNameWithoutExtension(part.AtlasPath);
                    atlasChainsToRebuild.Add(atlasChain);
                    if (!textures.ContainsKey(srcTexturePath))
                    {
                        AssetCooker.DeleteFileFromBundle(atlasPartPath);
                    }
                    else
                    {
                        srcTexturePath = Path.ChangeExtension(atlasPartPath, textureExtension);
                        if (AssetCooker.CookingRulesMap[srcTexturePath].TextureAtlas != null)
                        {
                            var rules = AssetCooker.CookingRulesMap[srcTexturePath];
                            atlasChainsToRebuild.Add(rules.TextureAtlas);
                        }
                        else
                        {
                            AssetCooker.DeleteFileFromBundle(atlasPartPath);
                        }
                    }
                }
            }
            // Find which new textures must be added to the atlas chain
            foreach (var t in textures)
            {
                var atlasPartPath   = Path.ChangeExtension(t.Key, atlasPartExtension);
                var cookingRules    = AssetCooker.CookingRulesMap[t.Key];
                var atlasNeedRebuld = cookingRules.TextureAtlas != null && !AssetCooker.OutputBundle.FileExists(atlasPartPath);
                if (atlasNeedRebuld)
                {
                    atlasChainsToRebuild.Add(cookingRules.TextureAtlas);
                }
                else
                {
                    UserInterface.Instance.IncreaseProgressBar();
                }
            }
            foreach (var atlasChain in atlasChainsToRebuild)
            {
                AssetCooker.CheckCookCancelation();
                BuildAtlasChain(atlasChain);
            }
        }
Beispiel #5
0
        private void BuildAtlasChain(string atlasChain)
        {
            for (var i = 0; i < AssetCooker.MaxAtlasChainLength; i++)
            {
                var atlasPath = AssetCooker.GetAtlasPath(atlasChain, i);
                if (AssetCooker.OutputBundle.FileExists(atlasPath))
                {
                    AssetCooker.DeleteFileFromBundle(atlasPath);
                }
                else
                {
                    break;
                }
            }
            var pluginItems = new Dictionary <string, List <TextureTools.AtlasItem> >();
            var items       = new Dictionary <AtlasOptimization, List <TextureTools.AtlasItem> >();

            items[AtlasOptimization.Memory]    = new List <TextureTools.AtlasItem>();
            items[AtlasOptimization.DrawCalls] = new List <TextureTools.AtlasItem>();
            foreach (var fileInfo in AssetBundle.Current.EnumerateFileInfos(null, textureExtension))
            {
                var cookingRules = AssetCooker.CookingRulesMap[fileInfo.Path];
                if (cookingRules.TextureAtlas == atlasChain)
                {
                    var item = new TextureTools.AtlasItem {
                        Path            = Path.ChangeExtension(fileInfo.Path, atlasPartExtension),
                        CookingRules    = cookingRules,
                        SourceExtension = Path.GetExtension(fileInfo.Path)
                    };
                    var bitmapInfo = TextureTools.BitmapInfo.FromFile(AssetCooker.InputBundle, fileInfo.Path);
                    if (bitmapInfo == null)
                    {
                        using (var bitmap = TextureTools.OpenAtlasItemBitmapAndRescaleIfNeeded(AssetCooker.Platform, item)) {
                            item.BitmapInfo = TextureTools.BitmapInfo.FromBitmap(bitmap);
                        }
                    }
                    else
                    {
                        var srcTexturePath = AssetPath.Combine(The.Workspace.AssetsDirectory, Path.ChangeExtension(item.Path, item.SourceExtension));
                        if (TextureTools.ShouldDownscale(AssetCooker.Platform, bitmapInfo, item.CookingRules))
                        {
                            TextureTools.DownscaleTextureInfo(AssetCooker.Platform, bitmapInfo, srcTexturePath, item.CookingRules);
                        }
                        // Ensure that no image exceeded maxAtlasSize limit
                        TextureTools.DownscaleTextureToFitAtlas(bitmapInfo, srcTexturePath);
                        item.BitmapInfo = bitmapInfo;
                    }
                    var k = cookingRules.AtlasPacker;
                    if (!string.IsNullOrEmpty(k) && k != "Default")
                    {
                        List <TextureTools.AtlasItem> l;
                        if (!pluginItems.TryGetValue(k, out l))
                        {
                            pluginItems.Add(k, l = new List <TextureTools.AtlasItem>());
                        }
                        l.Add(item);
                    }
                    else
                    {
                        items[cookingRules.AtlasOptimization].Add(item);
                    }
                }
            }
            var initialAtlasId = 0;

            foreach (var kv in items)
            {
                if (kv.Value.Any())
                {
                    if (AssetCooker.Platform == TargetPlatform.iOS)
                    {
                        Predicate <PVRFormat> isRequireSquare = (format) => {
                            return
                                (format == PVRFormat.PVRTC2 ||
                                 format == PVRFormat.PVRTC4 ||
                                 format == PVRFormat.PVRTC4_Forced);
                        };
                        var square    = kv.Value.Where(item => isRequireSquare(item.CookingRules.PVRFormat)).ToList();
                        var nonSquare = kv.Value.Where(item => !isRequireSquare(item.CookingRules.PVRFormat)).ToList();
                        initialAtlasId = PackItemsToAtlas(atlasChain, square, kv.Key, initialAtlasId, true);
                        initialAtlasId = PackItemsToAtlas(atlasChain, nonSquare, kv.Key, initialAtlasId, false);
                    }
                    else
                    {
                        initialAtlasId = PackItemsToAtlas(atlasChain, kv.Value, kv.Key, initialAtlasId, false);
                    }
                }
            }
            var packers = PluginLoader.CurrentPlugin.AtlasPackers.ToDictionary(i => i.Metadata.Id, i => i.Value);

            foreach (var kv in pluginItems)
            {
                if (!packers.ContainsKey(kv.Key))
                {
                    throw new InvalidOperationException($"Packer {kv.Key} not found");
                }
                initialAtlasId = packers[kv.Key](atlasChain, kv.Value, initialAtlasId);
            }
        }