Skip to content

Commit

Permalink
Added texture generation from stencils, renamed some classes
Browse files Browse the repository at this point in the history
  • Loading branch information
LatvianModder committed Nov 4, 2023
1 parent 9d540c7 commit e0df874
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package dev.latvian.mods.kubejs.client;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import dev.latvian.mods.kubejs.event.EventJS;
import dev.latvian.mods.kubejs.generator.AssetJsonGenerator;
import dev.latvian.mods.kubejs.util.ConsoleJS;
import net.minecraft.Util;
import net.minecraft.resources.ResourceLocation;

import java.io.IOException;
import java.util.function.Consumer;

public class GenerateClientAssetsEventJS extends EventJS {
Expand Down Expand Up @@ -38,4 +40,8 @@ public void addMultipartBlockState(ResourceLocation id, Consumer<MultipartBlockS
var gen = Util.make(new MultipartBlockStateGenerator(), consumer);
add(new ResourceLocation(id.getNamespace(), "blockstates/" + id.getPath()), gen.toJson());
}

public void stencil(ResourceLocation target, String stencil, JsonObject colors) throws IOException {
generator.stencil(target, stencil, colors);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ public void generate(Map<ResourceLocation, GeneratedData> map) {
}
}

@Override
protected boolean forgetFile(String path) {
return path.endsWith(".png") || path.endsWith(".ogg");
}

@Override
protected boolean skipFile(GeneratedData data) {
return data.id().getPath().startsWith("lang/");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package dev.latvian.mods.kubejs.client;

import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;

public class StencilTexture {
public int width;
public int height;
public int[] pixels;
public byte[] mcmeta;

public StencilTexture(BufferedImage img, byte[] mcmeta) {
this.width = img.getWidth();
this.height = img.getHeight();
this.pixels = new int[width * height];
img.getRGB(0, 0, width, height, pixels, 0, width);
this.mcmeta = mcmeta;
}

public byte[] create(JsonObject colors) {
var colorMap = new Int2IntArrayMap(colors.size());

for (var entry : colors.entrySet()) {
var k = entry.getKey();
var v = entry.getValue().getAsString();
int col = Integer.parseUnsignedInt(v.startsWith("#") ? v.substring(1) : v, 16);

if ((col & 0xFF000000) == 0) {
col |= 0xFF000000;
}

colorMap.put((Integer.parseUnsignedInt(k.startsWith("#") ? k.substring(1) : k, 16)) & 0xFFFFFF, col);
}

int[] result = new int[pixels.length];

for (int i = 0; i < pixels.length; i++) {
result[i] = ((pixels[i] & 0xFF000000) == 0) ? 0 : colorMap.getOrDefault(pixels[i] & 0xFFFFFF, pixels[i]);
}

var img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, width, height, result, 0, width);
var out = new ByteArrayOutputStream();

try {
ImageIO.write(img, "png", out);
} catch (Exception ex) {
throw new RuntimeException(ex);
}

return out.toByteArray();
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
package dev.latvian.mods.kubejs.generator;

import com.google.gson.JsonObject;
import dev.latvian.mods.kubejs.KubeJSPaths;
import dev.latvian.mods.kubejs.client.ModelGenerator;
import dev.latvian.mods.kubejs.client.MultipartBlockStateGenerator;
import dev.latvian.mods.kubejs.client.StencilTexture;
import dev.latvian.mods.kubejs.client.VariantBlockStateGenerator;
import dev.latvian.mods.kubejs.script.data.GeneratedData;
import dev.latvian.mods.kubejs.util.ConsoleJS;
import net.minecraft.Util;
import net.minecraft.resources.ResourceLocation;

import javax.imageio.ImageIO;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

public class AssetJsonGenerator extends JsonGenerator {
public class AssetJsonGenerator extends ResourceGenerator {
private final Map<String, StencilTexture> stencils;

public AssetJsonGenerator(Map<ResourceLocation, GeneratedData> m) {
super(ConsoleJS.CLIENT, m);
this.stencils = new HashMap<>();
}

public void blockState(ResourceLocation id, Consumer<VariantBlockStateGenerator> consumer) {
Expand All @@ -39,4 +50,35 @@ public void itemModel(ResourceLocation id, Consumer<ModelGenerator> consumer) {
public static ResourceLocation asItemModelLocation(ResourceLocation id) {
return new ResourceLocation(id.getNamespace(), "models/item/" + id.getPath());
}

public void stencil(ResourceLocation target, String stencil, JsonObject colors) throws IOException {
var st = stencils.get(stencil);

if (st == null) {
var path = KubeJSPaths.ASSETS.resolve("kubejs/textures/stencil/" + stencil + ".png");

if (Files.notExists(path)) {
throw new IllegalArgumentException("Stencil file 'kubejs/assets/kubejs/textures/stencil/'" + stencil + ".png' not found!");
}

try (var in = new BufferedInputStream(Files.newInputStream(path))) {
var metaPath = KubeJSPaths.ASSETS.resolve("kubejs/textures/stencil/" + stencil + ".png.mcmeta");
byte[] meta = null;

if (Files.exists(metaPath)) {
meta = Files.readAllBytes(metaPath);
}

st = new StencilTexture(ImageIO.read(in), meta);
stencils.put(stencil, st);
}
}

var st1 = st;
add(new ResourceLocation(target.getNamespace(), "textures/" + target.getPath() + ".png"), () -> st1.create(colors), true);

if (st.mcmeta != null) {
add(new ResourceLocation(target.getNamespace(), "textures/" + target.getPath() + ".png.mcmeta"), () -> st1.mcmeta, false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import java.util.Map;

public class DataJsonGenerator extends JsonGenerator {
public class DataJsonGenerator extends ResourceGenerator {
public DataJsonGenerator(Map<ResourceLocation, GeneratedData> m) {
super(ConsoleJS.SERVER, m);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@
import java.util.Map;
import java.util.function.Supplier;

public class JsonGenerator {
public class ResourceGenerator {
private final ConsoleJS console;
private final Map<ResourceLocation, GeneratedData> map;

public JsonGenerator(ConsoleJS c, Map<ResourceLocation, GeneratedData> m) {
public ResourceGenerator(ConsoleJS c, Map<ResourceLocation, GeneratedData> m) {
console = c;
map = m;
}

public void add(ResourceLocation id, Supplier<byte[]> data, boolean alwaysForget) {
map.put(id, new GeneratedData(id, Lazy.of(data), alwaysForget));
}

public void add(ResourceLocation id, Supplier<byte[]> data) {
map.put(id, new GeneratedData(id, Lazy.of(data)));
add(id, data, false);
}

public void json(ResourceLocation id, JsonElement json) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

public record GeneratedData(ResourceLocation id, Lazy<byte[]> data) implements IoSupplier<InputStream> {
public static final GeneratedData INTERNAL_RELOAD = new GeneratedData(KubeJS.id("__internal.reload"), Lazy.of(() -> new byte[0]));
public record GeneratedData(ResourceLocation id, Lazy<byte[]> data, boolean alwaysForget) implements IoSupplier<InputStream> {
public static final GeneratedData INTERNAL_RELOAD = new GeneratedData(KubeJS.id("__internal.reload"), Lazy.of(() -> new byte[0]), false);

public static final GeneratedData PACK_META = new GeneratedData(KubeJS.id("pack.mcmeta"), Lazy.of(() -> {
var json = new JsonObject();
Expand All @@ -23,7 +23,7 @@ public record GeneratedData(ResourceLocation id, Lazy<byte[]> data) implements I
pack.addProperty("pack_format", 15);
json.add("pack", pack);
return json.toString().getBytes(StandardCharsets.UTF_8);
}));
}), false);

public static final GeneratedData PACK_ICON = new GeneratedData(KubeJS.id("textures/kubejs_logo.png"), Lazy.of(() -> {
try {
Expand All @@ -32,12 +32,18 @@ public record GeneratedData(ResourceLocation id, Lazy<byte[]> data) implements I
ex.printStackTrace();
return new byte[0];
}
}));
}), true);

@Override
@NotNull
public InputStream get() {
return new ByteArrayInputStream(data.get());
var in = new ByteArrayInputStream(data.get());

if (alwaysForget) {
data.forget();
}

return in;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public Map<ResourceLocation, GeneratedData> getGenerated() {
ex.printStackTrace();
return new byte[0];
}
}));
}), forgetFile(pathStr));

if (debug) {
KubeJS.LOGGER.info("- File found: '" + data.id() + "' (" + data.data().get().length + " bytes)");
Expand Down Expand Up @@ -148,6 +148,10 @@ public Map<ResourceLocation, GeneratedData> getGenerated() {
return generated;
}

protected boolean forgetFile(String path) {
return false;
}

protected boolean skipFile(GeneratedData data) {
return false;
}
Expand Down

0 comments on commit e0df874

Please sign in to comment.