Skip to content

Commit

Permalink
Remove redundant atlas size calculation
Browse files Browse the repository at this point in the history
Unity does its own calculation anyway
  • Loading branch information
nicoco007 committed Dec 20, 2023
1 parent f888888 commit 3d0d483
Showing 1 changed file with 23 additions and 66 deletions.
89 changes: 23 additions & 66 deletions BeatSaberMarkupLanguage/Animations/AnimationLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ public static void Process(AnimationType type, byte[] data, Action<Texture2D, Re
[Obsolete]
public static IEnumerator ProcessAnimationInfo(AnimationInfo animationInfo, Action<Texture2D, Rect[], float[], int, int> callback)
{
int textureSize = AtlasSizeLimit, width = 0, height = 0;
Texture2D texture = null;
Texture2D[] texList = new Texture2D[animationInfo.frames.Count];
Texture2D[] textures = new Texture2D[animationInfo.frames.Count];
float[] delays = new float[animationInfo.frames.Count];

float lastThrottleTime = Time.realtimeSinceStartup;
Expand All @@ -57,15 +55,6 @@ public static IEnumerator ProcessAnimationInfo(AnimationInfo animationInfo, Acti
lastThrottleTime = Time.realtimeSinceStartup;
}

if (texture == null)
{
textureSize = GetTextureSize(animationInfo, i);
texture = new Texture2D(animationInfo.frames[i].width, animationInfo.frames[i].height);

width = animationInfo.frames[i].width;
height = animationInfo.frames[i].height;
}

FrameInfo currentFrameInfo = animationInfo.frames[i];
delays[i] = currentFrameInfo.delay;

Expand All @@ -80,7 +69,7 @@ public static IEnumerator ProcessAnimationInfo(AnimationInfo animationInfo, Acti
yield break;
}

texList[i] = frameTexture;
textures[i] = frameTexture;

// Allow up to .5ms of thread usage for loading this anim
if (Time.realtimeSinceStartup > lastThrottleTime + 0.0005f)
Expand All @@ -90,13 +79,20 @@ public static IEnumerator ProcessAnimationInfo(AnimationInfo animationInfo, Acti
}
}

Rect[] atlas = texture.PackTextures(texList, 2, textureSize, true);
foreach (Texture2D frameTex in texList)
Texture2D atlasTexture = new(0, 0)
{
Object.Destroy(frameTex);
name = "AnimatedImageAtlas", // TODO: it'd be nice to have the actual image name here
};

Rect[] atlas = atlasTexture.PackTextures(textures, 2, AtlasSizeLimit, true);

foreach (Texture2D texture in textures)
{
Object.Destroy(texture);
}

callback?.Invoke(texture, atlas, delays, width, height);
FrameInfo firstFrame = animationInfo.frames[0];
callback?.Invoke(atlasTexture, atlas, delays, firstFrame.width, firstFrame.height);
}

public static async Task<AnimationData> ProcessApngAsync(byte[] data)
Expand All @@ -113,34 +109,21 @@ public static async Task<AnimationData> ProcessGifAsync(byte[] data)

private static async Task<AnimationData> ProcessAnimationInfoAsync(AnimationInfo animationInfo)
{
int textureSize = AtlasSizeLimit;
int width = 0;
int height = 0;
Texture2D texture = null;
Texture2D[] texList = new Texture2D[animationInfo.frames.Count];
Texture2D[] textures = new Texture2D[animationInfo.frames.Count];
float[] delays = new float[animationInfo.frames.Count];

float lastThrottleTime = Time.realtimeSinceStartup;

for (int i = 0; i < animationInfo.frames.Count; i++)
{
if (texture == null)
{
textureSize = GetTextureSize(animationInfo, i);
texture = new Texture2D(animationInfo.frames[i].width, animationInfo.frames[i].height);

width = animationInfo.frames[i].width;
height = animationInfo.frames[i].height;
}

FrameInfo currentFrameInfo = animationInfo.frames[i];
delays[i] = currentFrameInfo.delay;

Texture2D frameTexture = new(currentFrameInfo.width, currentFrameInfo.height, TextureFormat.BGRA32, false);
frameTexture.wrapMode = TextureWrapMode.Clamp;
frameTexture.LoadRawTextureData(currentFrameInfo.colors);

texList[i] = frameTexture;
textures[i] = frameTexture;

// Allow up to .5ms of thread usage for loading this anim
if (Time.realtimeSinceStartup > lastThrottleTime + 0.0005f)
Expand All @@ -150,46 +133,20 @@ private static async Task<AnimationData> ProcessAnimationInfoAsync(AnimationInfo
}
}

Rect[] atlas = texture.PackTextures(texList, 2, textureSize, true);
foreach (Texture2D frameTex in texList)
Texture2D atlasTexture = new(0, 0)
{
Object.Destroy(frameTex);
}
name = "AnimatedImageAtlas", // TODO: it'd be nice to have the actual image name here
};

return new AnimationData(texture, atlas, delays, width, height);
}
Rect[] atlas = atlasTexture.PackTextures(textures, 2, AtlasSizeLimit, true);

private static int GetTextureSize(AnimationInfo frameInfo, int i)
{
int testNum = 2;
int numFramesInRow;
int numFramesInColumn;
while (true)
foreach (Texture2D texture in textures)
{
int numFrames = frameInfo.frames.Count;

// Make sure the number of frames is cleanly divisible by our testNum
if (numFrames % testNum == 0)
{
numFrames += numFrames % testNum;
}

// Math.Max to ensure numFramesInRow never becomes 0 to prevent DivideByZeroException
// This would happen with single frame GIFs
numFramesInRow = Math.Max(numFrames / testNum, 1);
numFramesInColumn = numFrames / numFramesInRow;

if (numFramesInRow <= numFramesInColumn)
{
break;
}

testNum += 2;
Object.Destroy(texture);
}

int textureWidth = Mathf.Clamp(numFramesInRow * frameInfo.frames[i].width, 0, AtlasSizeLimit);
int textureHeight = Mathf.Clamp(numFramesInColumn * frameInfo.frames[i].height, 0, AtlasSizeLimit);
return Mathf.Max(textureWidth, textureHeight);
FrameInfo firstFrame = animationInfo.frames[0];
return new AnimationData(atlasTexture, atlas, delays, firstFrame.width, firstFrame.height);
}
}
}

0 comments on commit 3d0d483

Please sign in to comment.