Esempio n. 1
0
 public SpriteSheetParameters(SpriteSheetAsset sheetAsset, PlatformType platform)
 {
     SheetAsset = sheetAsset;
     Platform   = platform;
 }
            /// <summary>
            /// Creates and Saves texture atlas image from images in GroupAsset
            /// </summary>
            /// <param name="logger">Status Logger</param>
            /// <param name="spriteToPackedSprite">A map associating the packed sprite info to the original sprite</param>
            /// <returns>Status of building</returns>
            private ResultStatus CreateAtlasTextures(Logger logger, out Dictionary <SpriteInfo, PackedSpriteInfo> spriteToPackedSprite)
            {
                spriteToPackedSprite = new Dictionary <SpriteInfo, PackedSpriteInfo>();

                // Pack textures
                using (var texTool = new TextureTool())
                {
                    var textureElements = new List <AtlasTextureElement>();

                    // Input textures
                    var imageDictionary     = new Dictionary <string, Image>();
                    var imageInfoDictionary = new Dictionary <string, SpriteInfo>();

                    var sprites           = AssetParameters.SheetAsset.Sprites;
                    var packingParameters = AssetParameters.SheetAsset.Packing;

                    for (var i = 0; i < sprites.Count; ++i)
                    {
                        var sprite = sprites[i];
                        if (sprite.TextureRegion.Height == 0 || sprite.TextureRegion.Width == 0 || sprite.Source == null)
                        {
                            continue;
                        }

                        // Lazy load input texture and cache in the dictionary for the later use
                        Image texture;

                        if (!imageDictionary.ContainsKey(sprite.Source))
                        {
                            texture = LoadImage(texTool, new UFile(sprite.Source), AssetParameters.SheetAsset.SRgb);
                            imageDictionary[sprite.Source] = texture;
                        }
                        else
                        {
                            texture = imageDictionary[sprite.Source];
                        }

                        var key = Url + "_" + i;

                        var sourceRectangle = new RotableRectangle(sprite.TextureRegion, sprite.Orientation == ImageOrientation.Rotated90);
                        textureElements.Add(new AtlasTextureElement(key, texture, sourceRectangle, packingParameters.BorderSize, sprite.BorderModeU, sprite.BorderModeV, sprite.BorderColor));

                        imageInfoDictionary[key] = sprite;
                    }

                    // Initialize packing configuration from GroupAsset
                    var texturePacker = new TexturePacker
                    {
                        Algorithm      = packingParameters.PackingAlgorithm,
                        AllowMultipack = packingParameters.AllowMultipacking,
                        MaxHeight      = packingParameters.AtlasMaximumSize.Y,
                        MaxWidth       = packingParameters.AtlasMaximumSize.X,
                        AllowRotation  = packingParameters.AllowRotations,
                    };

                    var canPackAllTextures = texturePacker.PackTextures(textureElements);

                    if (!canPackAllTextures)
                    {
                        logger.Error("Failed to pack all textures");
                        return(ResultStatus.Failed);
                    }

                    // Create and save every generated texture atlas
                    for (var textureAtlasIndex = 0; textureAtlasIndex < texturePacker.AtlasTextureLayouts.Count; ++textureAtlasIndex)
                    {
                        var atlasLayout = texturePacker.AtlasTextureLayouts[textureAtlasIndex];

                        ResultStatus resultStatus;
                        using (var atlasImage = AtlasTextureFactory.CreateTextureAtlas(atlasLayout))
                            using (var texImage = texTool.Load(atlasImage))
                            {
                                var outputUrl         = SpriteSheetAsset.BuildTextureAtlasUrl(Url, textureAtlasIndex);
                                var convertParameters = new TextureHelper.ImportParameters(AssetParameters)
                                {
                                    OutputUrl = outputUrl
                                };
                                resultStatus = TextureHelper.ImportTextureImage(texTool, texImage, convertParameters, CancellationToken, logger);
                            }

                        foreach (var texture in atlasLayout.Textures)
                        {
                            spriteToPackedSprite.Add(imageInfoDictionary[texture.Name], new PackedSpriteInfo(texture.DestinationRegion, textureAtlasIndex, packingParameters.BorderSize));
                        }

                        if (resultStatus != ResultStatus.Successful)
                        {
                            // Dispose used textures
                            foreach (var image in imageDictionary.Values)
                            {
                                image.Dispose();
                            }

                            return(resultStatus);
                        }
                    }

                    // Dispose used textures
                    foreach (var image in imageDictionary.Values)
                    {
                        image.Dispose();
                    }
                }

                return(ResultStatus.Successful);
            }
Esempio n. 3
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new AssetManager();

                var imageGroupData = new SpriteSheet {
                    Sprites = new List <Graphics.Sprite>()
                };

                // add the sprite data to the sprite list.
                foreach (var image in AssetParameters.SheetAsset.Sprites)
                {
                    var newImage = new Graphics.Sprite
                    {
                        Name          = image.Name,
                        Region        = image.TextureRegion,
                        IsTransparent = AssetParameters.SheetAsset.Alpha != AlphaFormat.None, // todo analyze texture region texture data to auto-determine alpha?
                        Orientation   = image.Orientation,
                        Center        = image.Center + (image.CenterFromMiddle ? new Vector2(image.TextureRegion.Width, image.TextureRegion.Height) / 2 : Vector2.Zero),
                        Borders       = image.Borders,
                        PixelsPerUnit = new Vector2(image.PixelsPerUnit)
                    };

                    int imageIndex;
                    if (ImageToTextureIndex.TryGetValue(image, out imageIndex))
                    {
                        newImage.Texture = AttachedReferenceManager.CreateSerializableVersion <Texture>(Guid.Empty, SpriteSheetAsset.BuildTextureUrl(Url, ImageToTextureIndex[image]));
                    }
                    else
                    {
                        commandContext.Logger.Warning("Image '{0}' has an invalid image source file '{1}', resulting texture will be null.", image.Name, image.Source);
                    }

                    imageGroupData.Sprites.Add(newImage);
                }

                // save the imageData into the data base
                assetManager.Save(Url, imageGroupData);

                return(Task.FromResult(ResultStatus.Successful));
            }
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new AssetManager();

                // Create atlas texture
                Dictionary <SpriteInfo, PackedSpriteInfo> spriteToPackedSprite = null;

                // Generate texture atlas
                var isPacking = AssetParameters.SheetAsset.Packing.Enabled;

                if (isPacking)
                {
                    var resultStatus = CreateAtlasTextures(commandContext.Logger, out spriteToPackedSprite);

                    if (resultStatus != ResultStatus.Successful)
                    {
                        return(Task.FromResult(resultStatus));
                    }
                }

                var imageGroupData = new SpriteSheet {
                    Sprites = new List <Graphics.Sprite>()
                };

                // add the sprite data to the sprite list.
                foreach (var image in AssetParameters.SheetAsset.Sprites)
                {
                    string           textureUrl;
                    RectangleF       region;
                    ImageOrientation orientation;

                    var borders = image.Borders;
                    var center  = image.Center + (image.CenterFromMiddle ? new Vector2(image.TextureRegion.Width, image.TextureRegion.Height) / 2 : Vector2.Zero);

                    if (isPacking &&
                        spriteToPackedSprite.ContainsKey(image))    // ensure that unpackable elements (invalid because of null size/texture) are properly added in the sheet using the normal path
                    {
                        var packedSprite            = spriteToPackedSprite[image];
                        var isOriginalSpriteRotated = image.Orientation == ImageOrientation.Rotated90;

                        region      = packedSprite.Region;
                        orientation = (packedSprite.IsRotated ^ isOriginalSpriteRotated) ? ImageOrientation.Rotated90 : ImageOrientation.AsIs;
                        textureUrl  = SpriteSheetAsset.BuildTextureAtlasUrl(Url, spriteToPackedSprite[image].AtlasTextureIndex);

                        // update the center and border info, if the packer rotated the sprite
                        if (packedSprite.IsRotated)
                        {
                            // turned the sprite CCW
                            if (isOriginalSpriteRotated)
                            {
                                var oldCenterX = center.X;
                                center.X = center.Y;
                                center.Y = region.Height - oldCenterX;

                                var oldBorderW = borders.W;
                                borders.W = borders.X;
                                borders.X = borders.Z;
                                borders.Z = borders.Y;
                                borders.Y = oldBorderW;
                            }
                            else // turned the sprite CW
                            {
                                var oldCenterX = center.X;
                                center.X = region.Width - center.Y;
                                center.Y = oldCenterX;

                                var oldBorderW = borders.W;
                                borders.W = borders.Y;
                                borders.Y = borders.Z;
                                borders.Z = borders.X;
                                borders.X = oldBorderW;
                            }
                        }
                    }
                    else
                    {
                        region      = image.TextureRegion;
                        orientation = image.Orientation;
                        AssetParameters.ImageToTextureUrl.TryGetValue(image, out textureUrl);
                    }

                    // Affect the texture
                    Texture texture = null;
                    if (textureUrl != null)
                    {
                        texture = AttachedReferenceManager.CreateSerializableVersion <Texture>(Guid.Empty, textureUrl);
                    }
                    else
                    {
                        commandContext.Logger.Warning("Image '{0}' has an invalid image source file '{1}', resulting texture will be null.", image.Name, image.Source);
                    }

                    imageGroupData.Sprites.Add(new Graphics.Sprite
                    {
                        Name          = image.Name,
                        Region        = region,
                        IsTransparent = AssetParameters.SheetAsset.Alpha != AlphaFormat.None, // todo analyze texture region texture data to auto-determine alpha?
                        Orientation   = orientation,
                        Center        = center,
                        Borders       = borders,
                        PixelsPerUnit = new Vector2(image.PixelsPerUnit),
                        Texture       = texture
                    });
                }

                // save the imageData into the data base
                assetManager.Save(Url, imageGroupData);

                return(Task.FromResult(ResultStatus.Successful));
            }