Mindustry/tools/build.gradle
2021-06-06 11:05:36 -04:00

284 lines
8.9 KiB
Groovy

sourceSets.main.java.srcDirs = ["src/"]
import arc.files.Fi
import arc.graphics.Color
import arc.graphics.Pixmap
import arc.packer.TexturePacker
import arc.struct.IntIntMap
import arc.struct.IntMap
import arc.util.async.Threads
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
def genFolder = "../core/assets-raw/sprites_out/generated/"
def doAntialias = !project.hasProperty("disableAntialias")
def colorMap = new IntMap<List<Color>>(), colorIndexMap = new IntIntMap()
//on my machine, I have a native Nim AA implementation that is ~10x faster
//it's not compiled for other platforms so they don't get it
def useFastAA = System.getProperty("user.name") == "anuke"
def transformColors = { List<List<String>> list ->
list.each{ colors ->
def newColors = []
colors.each{ hexc ->
newColors += Color.valueOf(hexc)
}
newColors.each{ color ->
colorMap.put(color.rgba(), newColors)
colorIndexMap.put(color.rgba(), newColors.indexOf(color))
}
}
}
//TODO implementing this in gradle is a bad idea
//d4816b
transformColors([["a387ea", "8a73c6", "5c5e9f"], ["6e7080", "989aa4", "b0bac0"], ["bc5452", "ea8878", "feb380"],
["de9458", "f8c266", "ffe18f"], ["feb380", "ea8878", "bc5452"], ["d4816b", "eab678", "ffd37f"],
["ffffff", "dcc6c6", "9d7f7f"], ["df7646", "b23a4d", "752249"], ["3c3837", "515151", "646567"]])
def antialias = { File file ->
if(!doAntialias) return
if(useFastAA){
"antialias ${file.absolutePath}".execute().waitFor()
return
}
def image = new Pixmap(new Fi(file))
def out = image.copy()
def getRGB = { int ix, int iy ->
return image.getRaw(Math.max(Math.min(ix, image.width - 1), 0), Math.max(Math.min(iy, image.height - 1), 0))
}
def color = new Color()
def sum = new Color()
def suma = new Color()
int[] p = new int[9]
for(int x = 0; x < image.width; x++){
for(int y = 0; y < image.height; y++){
int A = getRGB(x - 1, y + 1),
B = getRGB(x, y + 1),
C = getRGB(x + 1, y + 1),
D = getRGB(x - 1, y),
E = getRGB(x, y),
F = getRGB(x + 1, y),
G = getRGB(x - 1, y - 1),
H = getRGB(x, y - 1),
I = getRGB(x + 1, y - 1)
Arrays.fill(p, E)
if(D == B && D != H && B != F) p[0] = D
if((D == B && D != H && B != F && E != C) || (B == F && B != D && F != H && E != A)) p[1] = B
if(B == F && B != D && F != H) p[2] = F
if((H == D && H != F && D != B && E != A) || (D == B && D != H && B != F && E != G)) p[3] = D
if((B == F && B != D && F != H && E != I) || (F == H && F != B && H != D && E != C)) p[5] = F
if(H == D && H != F && D != B) p[6] = D
if((F == H && F != B && H != D && E != G) || (H == D && H != F && D != B && E != I)) p[7] = H
if(F == H && F != B && H != D) p[8] = F
suma.set(0)
for(int val : p){
color.rgba8888(val)
suma.r += color.r * color.a
suma.g += color.g * color.a
suma.b += color.b * color.a
suma.a += color.a
}
float fm = suma.a <= 0.001f ? 0f : (float)(1f / suma.a)
suma.mul(fm, fm, fm, fm)
float total = 0
sum.set(0)
for(int val : p){
color.rgba8888(val)
float a = color.a
color.lerp(suma, (float) (1f - a))
sum.r += color.r
sum.g += color.g
sum.b += color.b
sum.a += a
total += 1f
}
fm = (float)(1f / total)
sum.mul(fm, fm, fm, fm)
out.setRaw(x, y, sum.rgba8888())
sum.set(0)
}
}
image.dispose()
out.dispose()
new Fi(file).writePng(out)
}
def tileImage = { File file ->
def image = new Pixmap(new Fi(file))
for(x in 0..image.width-1){
for(y in 0..image.height-1){
if(x > (image.height - 1 - y)){
def rx = image.height - 1 - y
def ry = x
image.setRaw(x, y, image.getRaw(rx, image.height - 1 - ry))
}
}
}
def result = new Pixmap(image.width * 2, image.height * 2)
result.draw(image.flipX(), 0, 0)
result.draw(image, image.width, 0)
result.draw(image.flipX().flipY(), 0, image.height)
result.draw(image.flipY(), image.width, image.height)
for(x in 0..result.width-1){
for(y in 0..result.height-1){
int p = result.getRaw(x, y)
if(x <= y){
List<Color> list = colorMap.get(p)
int index = colorIndexMap.get(p, -1)
if(index != -1){
int resultIndex = (x == y ? 1 : index == 2 ? 0 : index == 0 ? 2 : 1);
result.setRaw(x, y, list[resultIndex].rgba())
}
}
}
}
new Fi(file).writePng(result)
result.dispose()
image.dispose()
}
task antialiasImages(){
doLast{
for(def img : project.getProperty("images").split(",")){
println(project.getProperty("startdir") + "/" + img)
antialias(new File(project.getProperty("startdir") + "/" + img))
}
}
}
task tileImages(){
doLast{
for(def img : project.getProperty("images").split(",")){
println(project.getProperty("startdir") + "/" + img)
tileImage(new File(project.getProperty("startdir") + "/" + img))
}
}
}
task pack(dependsOn: [classes, configurations.runtimeClasspath]){
doLast{
//cleanup old sprites
delete{
delete "../core/assets-raw/sprites_out/"
}
//copy in new sprites
copy{
from "../core/assets-raw/sprites/"
into "../core/assets-raw/sprites_out/"
}
//run generation task; generate all needed sprites
file(genFolder).mkdirs()
javaexec{
main = "mindustry.tools.ImagePacker"
classpath = sourceSets.main.runtimeClasspath
workingDir = genFolder
}
copy{
from "../core/assets-raw/sprites_out/ui/icons"
into "../core/assets-raw/sprites_out/ui/"
}
delete{
delete "../core/assets-raw/sprites_out/ui/icons"
}
ExecutorService executor = Executors.newFixedThreadPool(16)
long ms = System.currentTimeMillis()
//antialias everything except UI elements
fileTree(dir: new File(rootDir, 'core/assets-raw/sprites_out/').absolutePath, include: "**/*.png").visit{ file ->
if(file.isDirectory() || (file.toString().replace("\\", "/").contains("/ui/") && file.toString().startsWith("icon-")) || file.toString().contains(".9.png")) return
executor.submit{
antialias(file.file)
}
}
Threads.await(executor)
println "Time taken for AA: ${(System.currentTimeMillis() - ms) / 1000f}"
println("\n\nPacking normal 4096 sprites...\n\n")
//pack normal sprites
TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/").absolutePath, "sprites.aatls")
println("\n\nPacking fallback 2048 sprites...\n\n")
//replace config file contents
fileTree(dir: '../core/assets-raw/sprites_out/', include: "**/*.json").visit{ file ->
if(!file.isDirectory()) file.file.text = file.file.text.replace("4096", "2048")
}
//pack fallback 2048x2048 sprites
TexturePacker.process(new File(rootDir, "core/assets-raw/sprites_out/").absolutePath, new File(rootDir, "core/assets/sprites/fallback/").absolutePath, "sprites.aatls")
}
}
task genSprites(dependsOn: classes, type: JavaExec){
finalizedBy 'antialiasGen'
main = "mindustry.tools.ImagePacker"
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = genFolder
}
task updateBundles(dependsOn: classes, type: JavaExec){
file(genFolder).mkdirs()
main = "mindustry.tools.BundleLauncher"
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = "../core/assets/bundles/"
}
task fontgen(dependsOn: classes, type: JavaExec){
main = "mindustry.tools.FontGenerator"
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = "../"
}
task icongen(dependsOn: classes, type: JavaExec){
main = "mindustry.tools.IconConverter"
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = "../core/assets-raw"
}
task updateScripts(dependsOn: classes, type: JavaExec){
main = "mindustry.tools.ScriptMainGenerator"
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = "../"
}