1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-06 10:22:54 +08:00

Add support for limiting skin texture/animation dimensions

This commit is contained in:
Salman Ahmed 2023-09-03 01:20:01 +03:00
parent 2c81fe5613
commit 6674c70280
3 changed files with 30 additions and 10 deletions

View File

@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Timing; using osu.Framework.Timing;
using osuTK;
namespace osu.Game.Skinning namespace osu.Game.Skinning
{ {
@ -13,7 +14,7 @@ namespace osu.Game.Skinning
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This should not be used to start an animation immediately at the current time. /// This should not be used to start an animation immediately at the current time.
/// To do so, use <see cref="LegacySkinExtensions.GetAnimation(ISkin, string, WrapMode, WrapMode, bool, bool, bool, string, bool, double?)"/> with <code>startAtCurrentTime = true</code> instead. /// To do so, use <see cref="LegacySkinExtensions.GetAnimation(ISkin, string, WrapMode, WrapMode, bool, bool, bool, string, bool, double?, Vector2?)"/> with <code>startAtCurrentTime = true</code> instead.
/// </remarks> /// </remarks>
[Cached] [Cached]
public interface IAnimationTimeReference public interface IAnimationTimeReference

View File

@ -11,6 +11,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osuTK;
using static osu.Game.Skinning.SkinConfiguration; using static osu.Game.Skinning.SkinConfiguration;
namespace osu.Game.Skinning namespace osu.Game.Skinning
@ -18,16 +19,16 @@ namespace osu.Game.Skinning
public static partial class LegacySkinExtensions public static partial class LegacySkinExtensions
{ {
public static Drawable? GetAnimation(this ISkin? source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-", public static Drawable? GetAnimation(this ISkin? source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-",
bool startAtCurrentTime = true, double? frameLength = null) bool startAtCurrentTime = true, double? frameLength = null, Vector2? maxSize = null)
=> source.GetAnimation(componentName, default, default, animatable, looping, applyConfigFrameRate, animationSeparator, startAtCurrentTime, frameLength); => source.GetAnimation(componentName, default, default, animatable, looping, applyConfigFrameRate, animationSeparator, startAtCurrentTime, frameLength, maxSize);
public static Drawable? GetAnimation(this ISkin? source, string componentName, WrapMode wrapModeS, WrapMode wrapModeT, bool animatable, bool looping, bool applyConfigFrameRate = false, public static Drawable? GetAnimation(this ISkin? source, string componentName, WrapMode wrapModeS, WrapMode wrapModeT, bool animatable, bool looping, bool applyConfigFrameRate = false,
string animationSeparator = "-", bool startAtCurrentTime = true, double? frameLength = null) string animationSeparator = "-", bool startAtCurrentTime = true, double? frameLength = null, Vector2? maxSize = null)
{ {
if (source == null) if (source == null)
return null; return null;
var textures = GetTextures(source, componentName, wrapModeS, wrapModeT, animatable, animationSeparator, out var retrievalSource); var textures = GetTextures(source, componentName, wrapModeS, wrapModeT, animatable, animationSeparator, maxSize, out var retrievalSource);
switch (textures.Length) switch (textures.Length)
{ {
@ -53,7 +54,7 @@ namespace osu.Game.Skinning
} }
} }
public static Texture[] GetTextures(this ISkin? source, string componentName, WrapMode wrapModeS, WrapMode wrapModeT, bool animatable, string animationSeparator, out ISkin? retrievalSource) public static Texture[] GetTextures(this ISkin? source, string componentName, WrapMode wrapModeS, WrapMode wrapModeT, bool animatable, string animationSeparator, Vector2? maxSize, out ISkin? retrievalSource)
{ {
retrievalSource = null; retrievalSource = null;
@ -78,7 +79,9 @@ namespace osu.Game.Skinning
} }
// if an animation was not allowed or not found, fall back to a sprite retrieval. // if an animation was not allowed or not found, fall back to a sprite retrieval.
var singleTexture = retrievalSource.GetTexture(componentName, wrapModeS, wrapModeT); var singleTexture = maxSize != null
? retrievalSource.GetTextureWithMaxSize(componentName, maxSize.Value, wrapModeS, wrapModeT)
: retrievalSource.GetTexture(componentName, wrapModeS, wrapModeT);
return singleTexture != null return singleTexture != null
? new[] { singleTexture } ? new[] { singleTexture }
@ -88,9 +91,11 @@ namespace osu.Game.Skinning
{ {
for (int i = 0; true; i++) for (int i = 0; true; i++)
{ {
Texture? texture; var texture = maxSize != null
? skin.GetTextureWithMaxSize(getFrameName(i), maxSize.Value, wrapModeS, wrapModeT)
: skin.GetTexture(getFrameName(i), wrapModeS, wrapModeT);
if ((texture = skin.GetTexture(getFrameName(i), wrapModeS, wrapModeT)) == null) if (texture == null)
break; break;
yield return texture; yield return texture;
@ -100,6 +105,20 @@ namespace osu.Game.Skinning
string getFrameName(int frameIndex) => $"{componentName}{animationSeparator}{frameIndex}"; string getFrameName(int frameIndex) => $"{componentName}{animationSeparator}{frameIndex}";
} }
public static Texture? GetTextureWithMaxSize(this ISkin source, string componentName, Vector2 maxSize, WrapMode wrapModeS = WrapMode.None, WrapMode wrapModeT = WrapMode.None)
{
var texture = source.GetTexture(componentName, wrapModeS, wrapModeT);
if (texture == null)
return texture;
if (texture.DisplayWidth <= maxSize.X && texture.DisplayHeight <= maxSize.Y)
return texture;
// use scale adjust property for downscaling the texture in order to meet the specified maximum dimensions.
texture.ScaleAdjust *= Math.Max(texture.DisplayWidth / maxSize.X, texture.DisplayHeight / maxSize.Y);
return texture;
}
public static bool HasFont(this ISkin source, LegacyFont font) public static bool HasFont(this ISkin source, LegacyFont font)
{ {
return source.GetTexture($"{source.GetFontPrefix(font)}-0") != null; return source.GetTexture($"{source.GetFontPrefix(font)}-0") != null;

View File

@ -137,7 +137,7 @@ namespace osu.Game.Storyboards.Drawables
// When reading from a skin, we match stables weird behaviour where `FrameCount` is ignored // When reading from a skin, we match stables weird behaviour where `FrameCount` is ignored
// and resources are retrieved until the end of the animation. // and resources are retrieved until the end of the animation.
foreach (var texture in skin.GetTextures(Path.GetFileNameWithoutExtension(Animation.Path)!, default, default, true, string.Empty, out _)) foreach (var texture in skin.GetTextures(Path.GetFileNameWithoutExtension(Animation.Path)!, default, default, true, string.Empty, null, out _))
AddFrame(texture, Animation.FrameDelay); AddFrame(texture, Animation.FrameDelay);
} }