mirror of
https://github.com/TeamMidnightDust/BetterLeavesLite.git
synced 2025-12-15 12:05:09 +01:00
78 lines
4.0 KiB
Python
78 lines
4.0 KiB
Python
import json
|
|
import os
|
|
import random
|
|
from PIL import Image
|
|
|
|
# Local imports
|
|
from src.texturepack_utils import scanPacksForTexture
|
|
from src.utilities import printOverride
|
|
|
|
def generateTexture(root, infile, useProgrammerArt=False):
|
|
outfolder = root.replace("assets", "").replace("input", "assets")
|
|
os.makedirs(outfolder, exist_ok=True)
|
|
|
|
# Check for texture stitching data
|
|
textureMap = createTextureMap(root, infile, useProgrammerArt)
|
|
|
|
root = scanPacksForTexture(root, infile)
|
|
if useProgrammerArt: root = scanPacksForTexture(root, infile, "./input/programmer_art")
|
|
|
|
outfile = os.path.splitext(os.path.join(outfolder, infile))[0] + ".png"
|
|
if infile != outfile:
|
|
try:
|
|
stitchTexture(textureMap, root, infile, outfile)
|
|
except IOError:
|
|
print("Error while generating texture for '%s'" % infile)
|
|
|
|
def createTextureMap(root, infile, useProgrammerArt):
|
|
textureMap = {}
|
|
if os.path.isfile(os.path.join(root, infile.replace(".png", ".betterleaves.json"))):
|
|
with open(os.path.join(root, infile.replace(".png", ".betterleaves.json")), "r") as f:
|
|
json_data = json.load(f)
|
|
if "textureStitching" in json_data:
|
|
printOverride("Using texture stitching data from: " + f.name)
|
|
# Create texture map from stitching data
|
|
for key, value in json_data["textureStitching"].items():
|
|
if "-" in key:
|
|
for i in range(int(key.split("-")[0]), int(key.split("-")[1])+1): textureMap[str(i)] = value
|
|
else: textureMap[key] = value
|
|
# Turn texture map into absolute paths
|
|
for key, value in textureMap.items():
|
|
textureRoot = f"./input/assets/{value.split(':')[0]}/textures/"
|
|
textureFile = value.split(":")[1] + ".png"
|
|
if "/" in textureFile:
|
|
textureRoot += textureFile.rsplit("/")[0]
|
|
textureFile = textureFile[len(textureFile.rsplit("/")[0])+1:] # The rest of the string, starting behind the first '/'
|
|
textureRoot = scanPacksForTexture(textureRoot, textureFile)
|
|
if useProgrammerArt: root = scanPacksForTexture(textureRoot, textureFile, "./input/programmer_art")
|
|
textureMap[key] = os.path.join(textureRoot, textureFile)
|
|
return textureMap
|
|
|
|
def stitchTexture(textureMap, root, infile, outfile):
|
|
# First, let's open the regular texture
|
|
vanilla = Image.open(os.path.join(root, infile))
|
|
width, height = vanilla.size
|
|
# Second, let's generate a transparent texture that's twice the size
|
|
transparent = Image.new("RGBA", [int(2 * s) for s in vanilla.size], (255, 255, 255, 0))
|
|
out = transparent.copy()
|
|
|
|
# Now we paste the regular texture in a 3x3 grid, centered in the middle
|
|
for x in range(-1, 2):
|
|
for y in range(-1, 2):
|
|
texture = vanilla
|
|
index = (x + 2) + (y + 1) * 3 # Turns coordinates into a number from 1 to 9
|
|
if str(index) in textureMap: # Load texture from texture stitching map
|
|
texture = Image.open(textureMap[str(index)])
|
|
out.paste(texture, (int(width / 2 + width * x), int(height / 2 + height * y)))
|
|
|
|
# As the last step, we apply our custom mask to round the edges and smoothen things out
|
|
mask_location = f"input/masks/{width}px" # If possible, use a mask designed for the texture's size
|
|
if not os.path.isdir(mask_location) or len(os.listdir(mask_location)) == 0: mask_location = "input/masks/16px"
|
|
random.seed(infile) # Use the filename as a seed. This ensures we always get the same mask per block.
|
|
mask_location += f"/{random.choice(os.listdir(mask_location))}" # Choose a random mask to get some variation between the different types of leaves
|
|
mask = Image.open(mask_location).convert('L').resize(out.size, resample=Image.NEAREST)
|
|
out = Image.composite(out, transparent, mask)
|
|
|
|
# Finally, we save the texture to the assets folder
|
|
out.save(outfile, vanilla.format)
|