Better mod sprite packing
This commit is contained in:
@@ -26,6 +26,20 @@ public class MultiPacker implements Disposable{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void printStats(){
|
||||||
|
for(PageType type : PageType.all){
|
||||||
|
var packer = packers[type.ordinal()];
|
||||||
|
Log.debug("[Atlas] [&ly@&fr]", type);
|
||||||
|
Log.debug("[Atlas] - " + (packer.getPages().size > 1 ? "&fb&lr" : "&lg") + "@ page@&r", packer.getPages().size, packer.getPages().size > 1 ? "s" : "");
|
||||||
|
int i = 0;
|
||||||
|
for(var page : packer.getPages()){
|
||||||
|
Log.debug("[Atlas] - [@] @x@", i, page.getPixmap().width, page.getPixmap().height);
|
||||||
|
|
||||||
|
i ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PixmapPacker getPacker(PageType type){
|
public PixmapPacker getPacker(PageType type){
|
||||||
return packers[type.ordinal()];
|
return packers[type.ordinal()];
|
||||||
}
|
}
|
||||||
@@ -78,10 +92,12 @@ public class MultiPacker implements Disposable{
|
|||||||
//rubble page - scorch textures for unit deaths & wrecks
|
//rubble page - scorch textures for unit deaths & wrecks
|
||||||
//ui page (sprites5.png) - content icons, white icons, fonts and UI elements
|
//ui page (sprites5.png) - content icons, white icons, fonts and UI elements
|
||||||
public enum PageType{
|
public enum PageType{
|
||||||
main(4096),
|
//main page can be massive.
|
||||||
|
main(8192),
|
||||||
|
|
||||||
environment(4096, 2048),
|
environment(4096, 2048),
|
||||||
editor(4096, 2048),
|
editor(4096, 2048),
|
||||||
rubble,
|
rubble(4096, 2048),
|
||||||
ui(4096);
|
ui(4096);
|
||||||
|
|
||||||
public static final PageType[] all = values();
|
public static final PageType[] all = values();
|
||||||
|
|||||||
@@ -182,8 +182,15 @@ public class Mods implements Loadable{
|
|||||||
boolean linear = Core.settings.getBool("linear", true);
|
boolean linear = Core.settings.getBool("linear", true);
|
||||||
|
|
||||||
for(Fi file : sprites){
|
for(Fi file : sprites){
|
||||||
|
String name = file.nameWithoutExtension();
|
||||||
|
|
||||||
|
//TODO !!! document this on the wiki !!!
|
||||||
|
//do not allow packing standard outline sprites for now, they are no longer necessary and waste space!
|
||||||
|
if(prefix && name.endsWith("-outline")) continue;
|
||||||
|
|
||||||
//read and bleed pixmaps in parallel
|
//read and bleed pixmaps in parallel
|
||||||
tasks.add(mainExecutor.submit(() -> {
|
tasks.add(mainExecutor.submit(() -> {
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Pixmap pix = new Pixmap(file.readBytes());
|
Pixmap pix = new Pixmap(file.readBytes());
|
||||||
//only bleeds when linear filtering is on at startup
|
//only bleeds when linear filtering is on at startup
|
||||||
@@ -192,7 +199,7 @@ public class Mods implements Loadable{
|
|||||||
}
|
}
|
||||||
//this returns a *runnable* which actually packs the resulting pixmap; this has to be done synchronously outside the method
|
//this returns a *runnable* which actually packs the resulting pixmap; this has to be done synchronously outside the method
|
||||||
return () -> {
|
return () -> {
|
||||||
packer.add(getPage(file), (prefix ? mod.name + "-" : "") + file.nameWithoutExtension(), new PixmapRegion(pix));
|
packer.add(getPage(file), (prefix ? mod.name + "-" : "") + name, new PixmapRegion(pix));
|
||||||
pix.dispose();
|
pix.dispose();
|
||||||
};
|
};
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
@@ -213,11 +220,41 @@ public class Mods implements Loadable{
|
|||||||
//get textures packed
|
//get textures packed
|
||||||
if(totalSprites > 0){
|
if(totalSprites > 0){
|
||||||
|
|
||||||
|
class RegionEntry{
|
||||||
|
String name;
|
||||||
|
PixmapRegion region;
|
||||||
|
int[] splits, pads;
|
||||||
|
|
||||||
|
RegionEntry(String name, PixmapRegion region, int[] splits, int[] pads){
|
||||||
|
this.name = name;
|
||||||
|
this.region = region;
|
||||||
|
this.splits = splits;
|
||||||
|
this.pads = pads;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Seq<RegionEntry>[] entries = new Seq[PageType.all.length];
|
||||||
|
for(int i = 0; i < PageType.all.length; i++){
|
||||||
|
entries[i] = new Seq<>();
|
||||||
|
}
|
||||||
|
|
||||||
for(AtlasRegion region : Core.atlas.getRegions()){
|
for(AtlasRegion region : Core.atlas.getRegions()){
|
||||||
//TODO PageType completely breaks down with multiple pages.
|
|
||||||
PageType type = getPage(region);
|
PageType type = getPage(region);
|
||||||
|
|
||||||
if(!packer.has(type, region.name)){
|
if(!packer.has(type, region.name)){
|
||||||
packer.add(type, region.name, Core.atlas.getPixmap(region), region.splits, region.pads);
|
entries[type.ordinal()].add(new RegionEntry(region.name, Core.atlas.getPixmap(region), region.splits, region.pads));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort each page type by size first, for optimal packing
|
||||||
|
for(int i = 0; i < PageType.all.length; i++){
|
||||||
|
var rects = entries[i];
|
||||||
|
var type = PageType.all[i];
|
||||||
|
//TODO is this in reverse order?
|
||||||
|
rects.sort(Structs.comparingInt(o -> -Math.max(o.region.width, o.region.height)));
|
||||||
|
|
||||||
|
for(var entry : rects){
|
||||||
|
packer.add(type, entry.name, entry.region, entry.splits, entry.pads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,6 +323,8 @@ public class Mods implements Loadable{
|
|||||||
}
|
}
|
||||||
Log.debug("Time to generate icons: @", Time.elapsed());
|
Log.debug("Time to generate icons: @", Time.elapsed());
|
||||||
|
|
||||||
|
packer.printStats();
|
||||||
|
|
||||||
//dispose old atlas data
|
//dispose old atlas data
|
||||||
Core.atlas = packer.flush(filter, new TextureAtlas());
|
Core.atlas = packer.flush(filter, new TextureAtlas());
|
||||||
|
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ org.gradle.caching=true
|
|||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
org.gradle.internal.http.socketTimeout=100000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
org.gradle.internal.http.connectionTimeout=100000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
archash=705de3b8ee
|
archash=e4b6af5949
|
||||||
|
|||||||
Reference in New Issue
Block a user