/// <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>()) { metadata.AddAssetDependency(groupDesc.Texture); var groupTexture = manager.Load <Texture2D>(groupDesc.Texture, metadata.AssetDensity, true, metadata.IsLoadedFromSolution); 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)) { metadata.AddAssetDependency(frameDesc.Atlas); var atlas = manager.Load <TextureAtlas>(frameDesc.Atlas, metadata.AssetDensity, true, metadata.IsLoadedFromSolution); 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 { metadata.AddAssetDependency(frameDesc.Texture); var texture = manager.Load <Texture2D>(frameDesc.Texture, metadata.AssetDensity, true, metadata.IsLoadedFromSolution); 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)); }