From 94bc711008ab64de84f8833a9d7d8bcacf352524 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 11 Mar 2023 09:38:13 -0500 Subject: [PATCH] Rewrite atlas size calculation logic and re-enable fast texture stitching --- .../core/config/ModernFixEarlyConfig.java | 2 +- .../modernfix/textures/StbStitcher.java | 31 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 97881fa5..760db6ae 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -53,7 +53,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.cache_model_materials", true); this.addMixinRule("perf.datapack_reload_exceptions", true); this.addMixinRule("perf.async_locator", true); - this.addMixinRule("perf.faster_texture_stitching", false); + this.addMixinRule("perf.faster_texture_stitching", true); this.addMixinRule("perf.kubejs", true); this.addMixinRule("perf.faster_singleplayer_load", false); /* Keep this off if JEI isn't installed to prevent breaking vanilla gameplay */ diff --git a/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java b/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java index d2fbb230..7f872371 100644 --- a/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java +++ b/src/main/java/org/embeddedt/modernfix/textures/StbStitcher.java @@ -135,7 +135,8 @@ public class StbStitcher { // Initialize the rectangles that we'll be using in the calculation // While that's happening, sum up the area needed to fit all of the images - int sqSize = 0; + int totalArea = 0; + int longestWidth = 0, longestHeight = 0; for (int j = 0; j < holderSize; ++j) { Stitcher.Holder holder = holders[j]; @@ -147,17 +148,29 @@ public class StbStitcher { setWrapper(rect, j, width, height, 0, 0, false); - sqSize += (width * height); + totalArea += (width * height); + longestWidth = Math.max(longestWidth, width); + longestHeight = Math.max(longestHeight, height); } - int size = Mth.smallestEncompassingPowerOfTwo((int) Math.sqrt(sqSize)); - int width = size * 2; // needed to fix weirdness in 1.16 - int height = size; + longestWidth = Mth.smallestEncompassingPowerOfTwo(longestWidth); + longestHeight = Mth.smallestEncompassingPowerOfTwo(longestHeight); + + /* + * The atlas needs to be at least this wide and tall to accomodate oddly shaped sprites. If this is + * not enough, keep doubling the smaller of the two values until its big enough. + */ + while((longestWidth*longestHeight) < totalArea) { + if(longestWidth <= longestHeight) + longestWidth *= 2; + else + longestHeight *= 2; + } // Internal node structure needed for STB - try (STBRPNode.Buffer nodes = STBRPNode.malloc(width + 10)) { + try (STBRPNode.Buffer nodes = STBRPNode.malloc(longestWidth + 10)) { // Initialize the rect packer - STBRectPack.stbrp_init_target(ctx, width, height, nodes); + STBRectPack.stbrp_init_target(ctx, longestWidth, longestHeight, nodes); // Perform rectangle packing STBRectPack.stbrp_pack_rects(ctx, rectBuf); @@ -172,11 +185,11 @@ public class StbStitcher { } // Initialize the sprite now with the position and size that we've calculated so far - infoList.add(new LoadableSpriteInfo(holder.spriteInfo, width, height, getX(rect), getY(rect))); + infoList.add(new LoadableSpriteInfo(holder.spriteInfo, longestWidth, longestHeight, getX(rect), getY(rect))); //holder.spriteInfo.initSprite(size, size, rect.x(), rect.y(), false); } - return Pair.of(Pair.of(width, height), infoList); + return Pair.of(Pair.of(longestWidth, longestHeight), infoList); } } }