/// <summary>
 /// Initializes a new instance of the <see cref="SpriteFrame"/> class.
 /// </summary>
 /// <param name="description">The frame description.</param>
 /// <param name="texture">The texture that contains the frame.</param>
 internal SpriteFrame(SpriteFrameDescription description, Texture2D texture)
 {
     this.atlas           = description.Atlas;
     this.atlasCell       = description.AtlasCell;
     this.texture         = description.Texture;
     this.textureResource = texture;
     this.x        = description.X ?? 0;
     this.y        = description.Y ?? 0;
     this.width    = description.Width ?? 0;
     this.height   = description.Height ?? 0;
     this.originX  = description.Origin?.X ?? 0;
     this.originY  = description.Origin?.Y ?? 0;
     this.duration = description.Duration ?? 0;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SpriteFrame"/> class.
 /// </summary>
 /// <param name="description">The frame description.</param>
 public SpriteFrame(SpriteFrameDescription description)
 {
     this.atlas = description.Atlas;
     this.atlasCell = description.AtlasCell;
     this.texture = description.Texture;
     this.textureResource = description.TextureResource;
     this.x = description.X;
     this.y = description.Y;
     this.width = description.Width;
     this.height = description.Height;
     this.originX = description.OriginX;
     this.originY = description.OriginY;
     this.duration = description.Duration;
 }
Exemple #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SpriteFrame"/> class.
 /// </summary>
 /// <param name="description">The frame description.</param>
 /// <param name="texture">The texture that contains the frame.</param>
 internal SpriteFrame(SpriteFrameDescription description, Texture2D texture)
 {
     this.atlas = description.Atlas;
     this.atlasCell = description.AtlasCell;
     this.texture = description.Texture;
     this.textureResource = texture;
     this.x = description.X ?? 0;
     this.y = description.Y ?? 0;
     this.width = description.Width ?? 0;
     this.height = description.Height ?? 0;
     this.originX = description.Origin?.X ?? 0;
     this.originY = description.Origin?.Y ?? 0;
     this.duration = description.Duration ?? 0;
 }
        /// <summary>
        /// Creates a sprite description from the specified input file.
        /// </summary>
        private static SpriteDescription CreateSpriteDescription(ContentManager manager, IContentProcessorMetadata metadata, XDocument input)
        {
            var spriteDescription = new SpriteDescription();

            // Get all of the sprite's animation elements.
            var animationElementsSingle = input.Root.Elements("Animation");
            var animationElementsGroup  = input.Root.Elements("Animations").SelectMany(x => x.Elements("Animation"));
            var animationElements       = Enumerable.Union(animationElementsSingle, animationElementsGroup).ToList();
            var animationList           = new List <SpriteAnimationDescription>();

            // Process each animation.
            foreach (var animationElement in animationElements)
            {
                var animationDesc = new SpriteAnimationDescription();
                animationDesc.Name   = (String)animationElement.Attribute("Name");
                animationDesc.Repeat = (String)animationElement.Attribute("Repeat");

                // Get all of the animation's frame elements.
                var frameElementsSingle = animationElement.Elements("Frame");
                var frameElementsGroup  = animationElement.Elements("Frames").SelectMany(x => x.Elements("Frame"));
                var frameElements       = Enumerable.Union(frameElementsSingle, frameElementsGroup).ToList();
                var frameList           = new List <SpriteFrameDescription>();
                animationDesc.Frames = new[] { new SpriteFrameBatchDescription()
                                               {
                                                   Items = frameList
                                               } };

                // Process each frame.
                foreach (var frameElement in frameElements)
                {
                    var frameDescription = new SpriteFrameDescription();
                    frameDescription.Atlas     = ResolveDependencyAssetPath(metadata, (String)GetFrameAttribute(frameElement, "Atlas"));
                    frameDescription.AtlasCell = (String)GetFrameAttribute(frameElement, "AtlasCell");
                    frameDescription.Texture   = ResolveDependencyAssetPath(metadata, (String)GetFrameAttribute(frameElement, "Texture"));
                    frameDescription.X         = (Int32?)GetFrameAttribute(frameElement, "X") ?? 0;
                    frameDescription.Y         = (Int32?)GetFrameAttribute(frameElement, "Y") ?? 0;
                    frameDescription.Width     = (Int32?)GetFrameAttribute(frameElement, "Width") ?? 0;
                    frameDescription.Height    = (Int32?)GetFrameAttribute(frameElement, "Height") ?? 0;
                    frameDescription.Origin    = new Point2(
                        (Int32?)GetFrameAttribute(frameElement, "OriginX") ?? 0,
                        (Int32?)GetFrameAttribute(frameElement, "OriginY") ?? 0);
                    frameDescription.Duration = (Int32?)GetFrameAttribute(frameElement, "Duration") ?? 0;

                    // VALIDATION: Both atlas and texture specified
                    if (frameDescription.Atlas != null && frameDescription.Texture != null)
                    {
                        throw new InvalidDataException(UltravioletStrings.SpriteContainsBothTextureAndAtlas);
                    }

                    // VALIDATION: Atlas cell, but no atlas
                    if (frameDescription.Atlas == null && frameDescription.AtlasCell != null)
                    {
                        throw new InvalidDataException(UltravioletStrings.SpriteContainsCellButNoAtlas);
                    }

                    // VALIDATION: Atlas, but no atlas cell
                    if (frameDescription.Atlas != null && frameDescription.AtlasCell == null)
                    {
                        throw new InvalidDataException(UltravioletStrings.SpriteContainsAtlasButNoCell);
                    }

                    frameList.Add(frameDescription);
                }

                // Get all of the animation's frame groups.
                var frameGroupElementsSingle = animationElement.Elements("FrameGroup");
                var frameGroupElementsGroup  = animationElement.Elements("FrameGroups").SelectMany(x => x.Elements("FrameGroup"));
                var frameGroupElements       = Enumerable.Union(frameGroupElementsSingle, frameGroupElementsGroup).ToList();
                var frameGroupList           = new List <SpriteFrameGroupDescription>();
                animationDesc.FrameGroups = new[] { new SpriteFrameGroupBatchDescription()
                                                    {
                                                        Items = frameGroupList
                                                    } };

                // Process eachh frame group.
                foreach (var frameGroupElement in frameGroupElements)
                {
                    var frameGroupDescription = new SpriteFrameGroupDescription();
                    frameGroupDescription.Texture     = ResolveDependencyAssetPath(metadata, (String)GetFrameAttribute(frameGroupElement, "Texture"));
                    frameGroupDescription.X           = (Int32?)GetFrameAttribute(frameGroupElement, "AreaX") ?? 0;
                    frameGroupDescription.Y           = (Int32?)GetFrameAttribute(frameGroupElement, "AreaY") ?? 0;
                    frameGroupDescription.Width       = (Int32?)GetFrameAttribute(frameGroupElement, "AreaWidth") ?? 0;
                    frameGroupDescription.Height      = (Int32?)GetFrameAttribute(frameGroupElement, "AreaHeight") ?? 0;
                    frameGroupDescription.FrameWidth  = (Int32?)GetFrameAttribute(frameGroupElement, "FrameWidth") ?? 0;
                    frameGroupDescription.FrameHeight = (Int32?)GetFrameAttribute(frameGroupElement, "FrameHeight") ?? 0;
                    frameGroupDescription.FrameCount  = (Int32?)GetFrameAttribute(frameGroupElement, "FrameCount") ?? 0;
                    frameGroupDescription.Origin      = new Point2(
                        (Int32?)GetFrameAttribute(frameGroupElement, "OriginX") ?? 0,
                        (Int32?)GetFrameAttribute(frameGroupElement, "OriginX") ?? 0);
                    frameGroupDescription.Duration = (Int32?)GetFrameAttribute(frameGroupElement, "Duration") ?? 0;

                    frameGroupList.Add(frameGroupDescription);
                }

                animationList.Add(animationDesc);
            }
            spriteDescription.Animations = new[] { new SpriteAnimationBatchDescription()
                                                   {
                                                       Items = animationList.ToArray()
                                                   } };

            return(spriteDescription);
        }
        /// <inheritdoc/>
        public override Sprite ImportPreprocessed(ContentManager manager, IContentProcessorMetadata metadata, BinaryReader reader)
        {
            var description = new SpriteDescription();

            var animationCount = reader.ReadInt32();

            if (animationCount > 0)
            {
                var animations = new SpriteAnimationDescription[animationCount];

                description.Animations          = new[] { new SpriteAnimationBatchDescription() };
                description.Animations[0].Items = animations;

                for (int i = 0; i < animationCount; i++)
                {
                    animations[i]        = new SpriteAnimationDescription();
                    animations[i].Name   = reader.ReadString();
                    animations[i].Repeat = reader.ReadString();

                    var groupCount = reader.ReadInt32();
                    var groups     = new SpriteFrameGroupDescription[groupCount];

                    animations[i].FrameGroups          = new[] { new SpriteFrameGroupBatchDescription() };
                    animations[i].FrameGroups[0].Items = groups;

                    for (int j = 0; j < groupCount; j++)
                    {
                        var group = new SpriteFrameGroupDescription();
                        group.Texture     = reader.ReadString();
                        group.X           = reader.ReadInt32();
                        group.Y           = reader.ReadInt32();
                        group.Width       = reader.ReadInt32();
                        group.Height      = reader.ReadInt32();
                        group.FrameWidth  = reader.ReadInt32();
                        group.FrameHeight = reader.ReadInt32();
                        group.FrameCount  = reader.ReadInt32();
                        group.Origin      = new Point2(
                            reader.ReadInt32(),
                            reader.ReadInt32());
                        group.Duration = reader.ReadInt32();

                        groups[j] = group;
                    }

                    var frameCount = reader.ReadInt32();
                    var frames     = new SpriteFrameDescription[frameCount];

                    animations[i].Frames          = new[] { new SpriteFrameBatchDescription() };
                    animations[i].Frames[0].Items = frames;

                    for (int j = 0; j < frameCount; j++)
                    {
                        var frame = new SpriteFrameDescription();
                        frame.Atlas     = reader.ReadString();
                        frame.AtlasCell = reader.ReadString();
                        frame.Texture   = reader.ReadString();
                        frame.X         = reader.ReadInt32();
                        frame.Y         = reader.ReadInt32();
                        frame.Width     = reader.ReadInt32();
                        frame.Height    = reader.ReadInt32();
                        frame.Origin    = new Point2(
                            reader.ReadInt32(),
                            reader.ReadInt32());
                        frame.Duration = reader.ReadInt32();

                        frames[j] = frame;
                    }
                }
            }

            return(CreateSprite(manager, metadata, description));
        }
        /// <summary>
        /// Creates a sprite from the specified description.
        /// </summary>
        private static Sprite CreateSprite(ContentManager manager, IContentProcessorMetadata metadata, SpriteDescription input)
        {
            // Process sprite's animation data.
            var animations = new List <SpriteAnimation>();

            foreach (var animBatch in input.Animations)
            {
                foreach (var animDesc in animBatch.Items)
                {
                    var animName   = animDesc.Name;
                    var animRepeat = animDesc.Repeat == "none" ? SpriteAnimationRepeat.None : SpriteAnimationRepeat.Loop;
                    var animation  = new SpriteAnimation(animName, animRepeat);

                    // Process the animation's frame groups.
                    foreach (var groupBatch in animDesc.FrameGroups ?? Enumerable.Empty <SpriteFrameGroupBatchDescription>())
                    {
                        foreach (var groupDesc in groupBatch.Items ?? Enumerable.Empty <SpriteFrameGroupDescription>())
                        {
                            var groupTexture = manager.Load <Texture2D>(groupDesc.Texture);

                            var groupFrameCount  = groupDesc.FrameCount ?? 0;
                            var groupFrameWidth  = groupDesc.FrameWidth ?? 0;
                            var groupFrameHeight = groupDesc.FrameHeight ?? 0;

                            var groupAreaX      = groupDesc.X ?? 0;
                            var groupAreaY      = groupDesc.Y ?? 0;
                            var groupAreaWidth  = groupDesc.Width ?? 0;
                            var groupAreaHeight = groupDesc.Height ?? 0;

                            var groupOrigin   = groupDesc?.Origin ?? Point2.Zero;
                            var groupDuration = groupDesc?.Duration ?? 0;

                            var groupX = groupAreaX;
                            var groupY = groupAreaY;

                            for (int i = 0; i < groupFrameCount; i++)
                            {
                                if (groupAreaHeight > 0 && groupY + groupFrameHeight > groupY + groupAreaHeight)
                                {
                                    break;
                                }

                                var frame = new SpriteFrameDescription();
                                frame.Texture  = groupDesc.Texture;
                                frame.X        = groupX;
                                frame.Y        = groupY;
                                frame.Width    = groupFrameWidth;
                                frame.Height   = groupFrameHeight;
                                frame.Origin   = groupOrigin;
                                frame.Duration = groupDuration;
                                animation.Frames.Add(new SpriteFrame(frame, groupTexture));

                                groupX += groupFrameWidth;
                                if (groupX + groupFrameWidth > groupAreaX + groupAreaWidth)
                                {
                                    groupX = groupAreaX;
                                    groupY = groupY + groupFrameHeight;
                                }
                            }
                        }
                    }

                    // Process the animation's frame data.
                    foreach (var frameBatch in animDesc.Frames ?? Enumerable.Empty <SpriteFrameBatchDescription>())
                    {
                        foreach (var frameDesc in frameBatch.Items ?? Enumerable.Empty <SpriteFrameDescription>())
                        {
                            var frame = new SpriteFrameDescription();
                            frame.Origin   = frameDesc.Origin ?? Point2.Zero;
                            frame.Duration = frameDesc.Duration ?? 0;

                            if (!String.IsNullOrWhiteSpace(frameDesc.Atlas))
                            {
                                var atlas = manager.Load <TextureAtlas>(frameDesc.Atlas);
                                if (!atlas.ContainsCell(frameDesc.AtlasCell))
                                {
                                    throw new InvalidDataException(UltravioletStrings.SpriteContainsInvalidAtlasCell.Format(frameDesc.AtlasCell));
                                }

                                var cell = atlas[frameDesc.AtlasCell];

                                frame.Atlas     = frameDesc.Atlas;
                                frame.AtlasCell = frameDesc.AtlasCell;
                                frame.X         = cell.X;
                                frame.Y         = cell.Y;
                                frame.Width     = cell.Width;
                                frame.Height    = cell.Height;
                                animation.Frames.Add(new SpriteFrame(frame, atlas));
                            }
                            else
                            {
                                var texture = manager.Load <Texture2D>(frameDesc.Texture);

                                frame.Texture = frameDesc.Texture;
                                frame.X       = frameDesc.X ?? 0;
                                frame.Y       = frameDesc.Y ?? 0;
                                frame.Width   = frameDesc.Width ?? 0;
                                frame.Height  = frameDesc.Height ?? 0;
                                animation.Frames.Add(new SpriteFrame(frame, texture));
                            }
                        }
                    }

                    // Initialize the animation's default controller.
                    animation.Controller.PlayAnimation(animation);
                    animations.Add(animation);
                }
            }
            return(new Sprite(animations));
        }