From 95ad0f0535f505ae3b91150b9673ce17d89c5dcb Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 12 Aug 2020 18:17:43 +0200 Subject: [PATCH] added support for tinted textures --- .../bixilon/minosoft/render/MainWindow.java | 1 + .../minosoft/render/WorldRenderer.java | 10 +- .../render/blockModels/BlockDescription.java | 31 +++- .../render/blockModels/BlockModelLoader.java | 59 +++++- .../blockModels/BlockRenderInterface.java | 18 -- .../render/blockModels/DrawDescription.java | 4 +- .../minosoft/render/blockModels/Face.java | 2 +- .../render/blockModels/FullBlock.java | 29 --- .../minosoft/render/blockModels/SubBlock.java | 34 +++- .../render/texture/TextureLoader.java | 133 ++++++++------ .../assets/mapping/blockModels/minecraft.json | 171 ++++++++++++------ 11 files changed, 298 insertions(+), 194 deletions(-) delete mode 100644 src/main/java/de/bixilon/minosoft/render/blockModels/BlockRenderInterface.java delete mode 100644 src/main/java/de/bixilon/minosoft/render/blockModels/FullBlock.java diff --git a/src/main/java/de/bixilon/minosoft/render/MainWindow.java b/src/main/java/de/bixilon/minosoft/render/MainWindow.java index f1428a4cd..5c09d3b7b 100644 --- a/src/main/java/de/bixilon/minosoft/render/MainWindow.java +++ b/src/main/java/de/bixilon/minosoft/render/MainWindow.java @@ -48,6 +48,7 @@ public class MainWindow { renderMode = MAIN_MENU; mainMenu = new MainMenu(openGLWindow.getWidth(), openGLWindow.getHeight()); mainLoop(); + System.exit(0); }); guiThread.start(); } diff --git a/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java b/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java index 42f45f760..5b2a85228 100644 --- a/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java +++ b/src/main/java/de/bixilon/minosoft/render/WorldRenderer.java @@ -20,7 +20,6 @@ import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.render.blockModels.BlockModelLoader; import de.bixilon.minosoft.render.blockModels.Face; import de.bixilon.minosoft.render.fullFace.FaceOrientation; -import de.bixilon.minosoft.render.texture.TextureLoader; import java.util.HashMap; import java.util.HashSet; @@ -30,13 +29,10 @@ import static de.bixilon.minosoft.render.fullFace.RenderConstants.faceDir; import static org.lwjgl.opengl.GL11.*; public class WorldRenderer { - private final TextureLoader textureLoader; private final HashMap> faces; - private final int faceCount = 0; private BlockModelLoader modelLoader; public WorldRenderer() { - textureLoader = new TextureLoader(MainWindow.getOpenGLWindow().getWindow()); faces = new HashMap<>(); } @@ -87,7 +83,7 @@ public class WorldRenderer { public void draw() { glPushMatrix(); - glBindTexture(GL_TEXTURE_2D, textureLoader.getTextureID()); + glBindTexture(GL_TEXTURE_2D, modelLoader.getTextureLoader().getTextureID()); glBegin(GL_QUADS); synchronized (faces) { for (Map.Entry> entry : faces.entrySet()) { @@ -100,10 +96,6 @@ public class WorldRenderer { glPopMatrix(); } - public TextureLoader getTextureLoader() { - return textureLoader; - } - public BlockModelLoader getModelLoader() { return modelLoader; } diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockDescription.java b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockDescription.java index edba88f86..21664470c 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockDescription.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockDescription.java @@ -18,6 +18,7 @@ import com.google.gson.JsonObject; import de.bixilon.minosoft.Config; import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block; import de.bixilon.minosoft.render.fullFace.FaceOrientation; +import de.bixilon.minosoft.render.texture.TextureLoader; import java.io.IOException; import java.util.HashMap; @@ -31,23 +32,29 @@ public class BlockDescription { boolean isFull; public BlockDescription(JsonElement child, String identifier, String mod) { - if (child.getAsString().equals("invisible")) { + blockConfigurationStates = new HashMap<>(); + if (child.isJsonPrimitive() && child.getAsString().equals("invisible")) { + defaultState = new HashSet<>(); return; - } else if (child.getAsString().equals("regular")) { - defaultState = load(mod, identifier, new HashMap<>()); - } else { + } else if (child.isJsonPrimitive() && child.getAsString().equals("regular")) { + defaultState = load(mod, identifier); + } else if (child.isJsonPrimitive()) { + defaultState = load(mod, child.getAsString()); + } else if (child.isJsonObject()) { JsonObject childJson = child.getAsJsonObject(); for (String state : childJson.keySet()) { if (state.equals("else")) { defaultState = load(mod, childJson.get("else").getAsString(), new HashMap<>()); } - blockConfigurationStates.put(new BlockConfiguration(state), + BlockConfiguration configuration = new BlockConfiguration(state); + blockConfigurationStates.put(configuration, load(mod, childJson.get(state).getAsString())); } } for (SubBlock subBlock : defaultState) { if (subBlock.isFull()) { isFull = true; + break; } } } @@ -102,4 +109,18 @@ public class BlockDescription { } return result; } + + public HashSet getAllTextures() { + HashSet result = new HashSet<>(); + for (SubBlock subBlock : defaultState) { + result.addAll(subBlock.getTextures()); + } + return result; + } + + public void applyTextures(String mod, TextureLoader loader) { + for (SubBlock subBlock : defaultState) { + subBlock.applyTextures(mod, loader); + } + } } diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelLoader.java b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelLoader.java index e71ea9d81..cd9f12f37 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelLoader.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelLoader.java @@ -20,51 +20,88 @@ import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block; import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks; import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.render.fullFace.FaceOrientation; +import de.bixilon.minosoft.render.texture.TextureLoader; +import org.apache.commons.collections.primitives.ArrayFloatList; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import static de.bixilon.minosoft.util.Util.readJsonFromFile; public class BlockModelLoader { + private final HashMap> blockDescriptionMap; + TextureLoader textureLoader; + public BlockModelLoader() { blockDescriptionMap = new HashMap<>(); + HashMap> tints = new HashMap<>(); + HashMap> textures = new HashMap<>(); try { String folderPath = Config.homeDir + "assets/mapping/blockModels/"; for (File file : new File(folderPath).listFiles()) { - JsonObject blockList = readJsonFromFile(file.getAbsolutePath()); + JsonObject json = readJsonFromFile(file.getAbsolutePath()); String mod = file.getName().substring(0, file.getName().lastIndexOf('.')); - loadModels(blockList, mod); + tints.put(mod, readTints(json)); + textures.put(mod, loadModels(json.get("blocks").getAsJsonObject(), mod)); } - } catch (IOException | NullPointerException e) { + textureLoader = new TextureLoader(textures, tints); + applyTextures(); + } catch (IOException e) { e.printStackTrace(); } - Log.info("finished loading all block descriptions"); + Log.info("finished loading all blocks"); } - final HashMap> blockDescriptionMap; + private void applyTextures() { + for (Map.Entry> mod : blockDescriptionMap.entrySet()) { + for (Map.Entry block : mod.getValue().entrySet()) { + block.getValue().applyTextures(mod.getKey(), textureLoader); + } + } + } - private void loadModels(JsonObject blockList, String mod) { + private HashMap readTints(JsonObject json) { + HashMap result = new HashMap<>(); + if (json.has("tinted_textures")) { + JsonObject textures = json.get("tinted_textures").getAsJsonObject(); + for (String textureName : textures.keySet()) { + ArrayFloatList colorValues = new ArrayFloatList(); + for (JsonElement colorValue : textures.get(textureName).getAsJsonArray()) { + colorValues.add(colorValue.getAsFloat()); + } + float[] color = colorValues.toArray(); + result.put(textureName, color); + } + } + return result; + } + + private HashSet loadModels(JsonObject blockList, String mod) { + HashSet result = new HashSet<>(); blockDescriptionMap.put(mod, new HashMap<>()); for (String identifier : blockList.keySet()) { JsonElement child = blockList.get(identifier); - loadModel(mod, identifier, child); + result.addAll(loadModel(mod, identifier, child)); } + return result; } - private void loadModel(String mod, String identifier, JsonElement child) { + private HashSet loadModel(String mod, String identifier, JsonElement child) { + HashSet result = new HashSet<>(); try { HashMap modList = blockDescriptionMap.get(mod); BlockDescription description = new BlockDescription(child, identifier, mod); + result.addAll(description.getAllTextures()); modList.put(identifier, description); } catch (Exception e) { e.printStackTrace(); System.out.println(mod + ":" + identifier); System.exit(-1); } - + return result; } public BlockDescription getBlockDescription(Block block) { @@ -98,4 +135,8 @@ public class BlockModelLoader { } return description.prepare(block, adjacentBlocks); } + + public TextureLoader getTextureLoader() { + return textureLoader; + } } \ No newline at end of file diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockRenderInterface.java b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockRenderInterface.java deleted file mode 100644 index 5ee49a0ee..000000000 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockRenderInterface.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Codename Minosoft - * Copyright (C) 2020 Lukas Eisenhauer - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.render.blockModels; - -public interface BlockRenderInterface { - void draw(); -} diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/DrawDescription.java b/src/main/java/de/bixilon/minosoft/render/blockModels/DrawDescription.java index 68aa8add5..552e007a5 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/DrawDescription.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/DrawDescription.java @@ -36,7 +36,7 @@ public class DrawDescription { Map> faces; boolean full = false; // is the block a completely filled block? - public DrawDescription(JsonObject json) { + public DrawDescription(JsonObject json, String mod) { if (!(json.has("parent") && json.has("textures"))) return; faces = new HashMap<>(); @@ -49,7 +49,7 @@ public class DrawDescription { Pair texturePair; try { - texturePair = MainWindow.getRenderer().getTextureLoader().getTexture(texture); + texturePair = MainWindow.getRenderer().getModelLoader().getTextureLoader().getTexture(mod, texture); } catch (Exception e) { continue; } diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/Face.java b/src/main/java/de/bixilon/minosoft/render/blockModels/Face.java index 3409374cf..c47250a35 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/Face.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/Face.java @@ -32,7 +32,7 @@ public class Face { public Face(FaceOrientation orientation, Pair texture, InFaceUV uv, SubBlock subBlock) { this.orientation = orientation; - float step = MainWindow.getRenderer().getTextureLoader().getStep(); + float step = MainWindow.getRenderer().getModelLoader().getTextureLoader().getStep(); u1 = texture.getKey();// + (float) uv.u1 / (float) texturePackRes * step; u2 = texture.getValue();// - (float) (texturePackRes - uv.u2) / (float) texturePackRes * step; v1 = (float) uv.v1 / (float) texturePackRes; diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/FullBlock.java b/src/main/java/de/bixilon/minosoft/render/blockModels/FullBlock.java deleted file mode 100644 index a0991607e..000000000 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/FullBlock.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Codename Minosoft - * Copyright (C) 2020 Lukas Eisenhauer - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.render.blockModels; - -import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block; -import de.bixilon.minosoft.game.datatypes.world.BlockPosition; -import de.bixilon.minosoft.game.datatypes.world.World; - -public class FullBlock implements BlockRenderInterface { - public FullBlock(BlockPosition position, Block block, World world) { - - } - - @Override - public void draw() { - - } -} diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/SubBlock.java b/src/main/java/de/bixilon/minosoft/render/blockModels/SubBlock.java index c5a88afd2..258aef11b 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/SubBlock.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/SubBlock.java @@ -14,19 +14,21 @@ package de.bixilon.minosoft.render.blockModels; import com.google.gson.JsonObject; -import de.bixilon.minosoft.render.MainWindow; import de.bixilon.minosoft.render.fullFace.FaceOrientation; import de.bixilon.minosoft.render.fullFace.InFaceUV; +import de.bixilon.minosoft.render.texture.TextureLoader; import javafx.util.Pair; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; public class SubBlock { SubBlockPosition pos1; // the most negative Point of the SubBlock SubBlockPosition pos2; // the most positive Point of the SubBlock - HashMap> textures; + HashMap> textureCoordinates; + HashMap textures; HashMap cullFaceTextures; HashMap uv; @@ -35,6 +37,7 @@ public class SubBlock { public SubBlock(JsonObject json, HashMap variables) { uv = new HashMap<>(); textures = new HashMap<>(); + textureCoordinates = new HashMap<>(); cullFaceTextures = new HashMap<>(); pos1 = new SubBlockPosition(json.getAsJsonArray("from")); @@ -50,6 +53,7 @@ public class SubBlock { } private static String getRealTextureName(String textureName, HashMap variables) { + // read the variables and find the real texture name if (textureName.contains("#")) { if (variables.containsKey(textureName)) { String newName = variables.get(textureName); @@ -68,6 +72,15 @@ public class SubBlock { } } + public void applyTextures(String mod, TextureLoader loader) { + for (Map.Entry entry : textures.entrySet()) { + Pair texture = loader.getTexture(mod, entry.getValue()); + textureCoordinates.put(entry.getKey(), texture); + } + // clean up + textures.clear(); + } + private void applyTexture(JsonObject faceJson, FaceOrientation orientation, HashMap variables) { try { uv.put(orientation, new InFaceUV(faceJson.getAsJsonArray("uv"))); @@ -76,21 +89,18 @@ public class SubBlock { } String textureName = getRealTextureName(faceJson.get("texture").getAsString(), variables); - Pair texture = MainWindow.getRenderer().getTextureLoader().getTexture(textureName); - + textures.put(orientation, textureName); cullFaceTextures.put(orientation, faceJson.has("cullface")); - - textures.put(orientation, texture); } public HashSet getFaces(HashMap adjacentBlocks) { HashSet result = new HashSet<>(); for (FaceOrientation orientation : FaceOrientation.values()) { - if (!textures.containsKey(orientation)) { + if (!textureCoordinates.containsKey(orientation)) { continue; } if (!(adjacentBlocks.get(orientation) && cullFaceTextures.get(orientation))) { - result.add(new Face(orientation, textures.get(orientation), + result.add(new Face(orientation, textureCoordinates.get(orientation), uv.get(orientation), this)); } } @@ -100,4 +110,12 @@ public class SubBlock { public boolean isFull() { return isFull; } + + public HashSet getTextures() { + HashSet result = new HashSet<>(); + for (Map.Entry texture : textures.entrySet()) { + result.add(texture.getValue()); + } + return result; + } } diff --git a/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java b/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java index 2893e4f86..7c5ead2bb 100644 --- a/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java +++ b/src/main/java/de/bixilon/minosoft/render/texture/TextureLoader.java @@ -18,34 +18,34 @@ import de.matthiasmann.twl.utils.PNGDecoder; import javafx.util.Pair; import javax.imageio.ImageIO; +import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; +import java.util.HashSet; +import java.util.Map; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL30.glGenerateMipmap; public class TextureLoader { - int textureID; - int length; //describes the amount of loaded textures private final int TEXTURE_PACK_RES = 16; - private HashMap textureCoordinates; - int imageLength = 1; + private final HashMap> textureCoordinates; + int textureID; float step; + int totalTextures = 0; + HashMap> images; - public TextureLoader(long window) { - try { - textureCoordinates = new HashMap<>(); - loadTextures(Config.homeDir + "assets/minecraft/textures/block"); - } catch (IOException ioException) { - ioException.printStackTrace(); + public TextureLoader(HashMap> textures, HashMap> tints) { + textureCoordinates = new HashMap<>(); + images = new HashMap<>(); + for (String mod : textures.keySet()) { + loadTextures(mod, textures.get(mod), tints.get(mod)); } + combineTextures(); try { PNGDecoder decoder = new PNGDecoder(new FileInputStream( Config.homeDir + "assets/allTextures.png")); @@ -54,59 +54,77 @@ public class TextureLoader { textureID = bindTexture(buf, decoder.getWidth(), decoder.getHeight()); } catch (IOException e) { e.printStackTrace(); + System.exit(5); } - } - private void loadTextures(String textureFolder) throws IOException { - // Any animated block will be stationary - File[] textureFiles = new File(textureFolder).listFiles(); - - if (textureFiles == null) { - throw new IOException("Failed to load textures: Texture folder empty"); - } - List> allTextures = new ArrayList<>(); - for (int i = 0; i < textureFiles.length; i++) { - String fileName = textureFiles[i].getName(); - String textureName = fileName.substring(0, fileName.lastIndexOf('.')); - String fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1); - if (fileExtension.equals("png")) { - InputStream textureInputStream = new FileInputStream(textureFiles[i]); - BufferedImage img = ImageIO.read(textureInputStream); - allTextures.add(new Pair<>(img, textureName)); + private static void tintImage(BufferedImage image, float[] tintColor) { + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + Color color = new Color(image.getRGB(x, y)); + int r = (int) (color.getRed() * tintColor[0]); + int g = (int) (color.getGreen() * tintColor[1]); + int b = (int) (color.getBlue() * tintColor[2]); + int rgba = (color.getAlpha() << 24) | (r << 16) | (g << 8) | b; + image.setRGB(x, y, rgba); } - //else we have a .mcmeta file describing animated blocks } + } + private void loadTextures(String mod, HashSet textureNames, HashMap tint) { + HashMap modTextureMap = new HashMap<>(); + for (String textureName : textureNames) { + String path = Config.homeDir + "assets/" + mod + "/textures/" + textureName + ".png"; + try { + BufferedImage image = ImageIO.read(new File(path)); + if (tint.containsKey(textureName)) { + tintImage(image, tint.get(textureName)); + } + modTextureMap.put(textureName, image); + } catch (IOException e) { + System.out.println(textureName); + System.out.println(path); + e.printStackTrace(); + System.exit(6); + } + totalTextures++; + } + images.put(mod, modTextureMap); + } + + private void combineTextures() { // CONVERT ALL THE IMAGES INTO A SINGLE, VERY LONG IMAGE // greatly improves performance in opengl // TEXTURE_PACK_RESxTEXTURE_PACK_RES textures only - length = allTextures.size(); + int imageLength = 1; + while (totalTextures * TEXTURE_PACK_RES > imageLength) { + imageLength *= 2; //figure out the right length for the image + } + BufferedImage totalImage = new BufferedImage(imageLength, TEXTURE_PACK_RES, + BufferedImage.TYPE_4BYTE_ABGR); - while (length * TEXTURE_PACK_RES > imageLength) imageLength *= 2; //figure out the right length for the image - - BufferedImage totalImage = new BufferedImage(imageLength, TEXTURE_PACK_RES, BufferedImage.TYPE_4BYTE_ABGR); - for (int xPos = 0; xPos < length; xPos++) { - //copy the image into a part of the long image - BufferedImage img = allTextures.get(xPos).getKey(); - for (int y = 0; y < TEXTURE_PACK_RES; y++) { - for (int xPixel = 0; xPixel < TEXTURE_PACK_RES; xPixel++) { - int rgb = img.getRGB(xPixel, y); - totalImage.setRGB(xPos * TEXTURE_PACK_RES + xPixel, y, rgb); + int currentPos = 0; + for (Map.Entry> mod : images.entrySet()) { + HashMap modMap = new HashMap<>(); + for (Map.Entry texture : mod.getValue().entrySet()) { + for (int y = 0; y < TEXTURE_PACK_RES; y++) { + for (int xPixel = 0; xPixel < TEXTURE_PACK_RES; xPixel++) { + int rgb = texture.getValue().getRGB(xPixel, y); + totalImage.setRGB(currentPos * TEXTURE_PACK_RES + xPixel, y, rgb); + } } + modMap.put(texture.getKey(), currentPos++); } - String textureName = allTextures.get(xPos).getValue(); - textureCoordinates.put(textureName, xPos); + textureCoordinates.put(mod.getKey(), modMap); } try { - // save our long image to reload it later File outputFile = new File(Config.homeDir + "assets/allTextures.png"); ImageIO.write(totalImage, "png", outputFile); } catch (IOException e) { e.printStackTrace(); } - step = (float) 1 / (float) imageLength; + step = (float) 1 / (float) imageLength * TEXTURE_PACK_RES; } private int bindTexture(ByteBuffer buf, int width, int height) { @@ -123,24 +141,23 @@ public class TextureLoader { return textureID; } - public Pair getTexture(String name) { + public Pair getTexture(String mod, String textureName) { // returns the start and end u-coordinate of a specific texture to access it - if (name == null) { - throw new NullPointerException("received null string as texture name"); - } - if (name.contains("block/")) { - name = name.substring(name.lastIndexOf('/') + 1); + HashMap modMap = textureCoordinates.get(mod); + if (modMap == null) { + System.out.println("no mod " + mod + " loaded"); + System.exit(9); } + Integer pos = modMap.get(textureName); - Integer pos = textureCoordinates.get(name); if (pos == null) { - // the texture does not exist - throw new IllegalArgumentException(String.format("could not find texture %s", name)); + System.out.println("failed to find texture " + textureName); + System.exit(10); } - return new Pair( - (float) pos / ((float) imageLength / (float) TEXTURE_PACK_RES), - (float) (pos + 1) / ((float) imageLength / (float) TEXTURE_PACK_RES) + return new Pair<>( + pos * step, + (pos + 1) * step ); } diff --git a/src/main/resources/assets/mapping/blockModels/minecraft.json b/src/main/resources/assets/mapping/blockModels/minecraft.json index e091e2944..94878bdee 100644 --- a/src/main/resources/assets/mapping/blockModels/minecraft.json +++ b/src/main/resources/assets/mapping/blockModels/minecraft.json @@ -1,59 +1,120 @@ { - "stone": "regular", - "granite": "regular", - "polished_granite": "regular", - "diorite": "regular", - "polished_diorite": "regular", - "andesite": "regular", - "polished_andesite": "regular", - "grass_block": "regular", - "dirt": "regular", - "coarse_dirt": "regular", - "podzol": "regular", - "cobblestone": "regular", - "oak_planks": "regular", - "spruce_planks": "regular", - "birch_planks": "regular", - "jungle_planks": "regular", - "acacia_planks": "regular", - "dark_oak_planks": "regular", - "oak_sapling": "regular", - "spruce_sapling": "regular", - "birch_sapling": "regular", - "jungle_sapling": "regular", - "acacia_sapling": "regular", - "dark_oak_sapling": "regular", - "bedrock": "regular", - "sand": "regular", - "red_sand": "regular", - "gravel": "regular", - "gold_ore": "regular", - "iron_ore": "regular", - "coal_ore": "regular", - "spruce_log": "regular", - "birch_log": "regular", - "jungle_log": "regular", - "dark_oak_log": "regular", - "oak_leaves": "regular", - "spruce_leaves": "regular", - "jungle_leaves": "regular", - "birch_leaves": "regular", - "dark_oak_leaves": "regular", - "sponge": "regular", - "wet_sponge": "regular", - "glass": "regular", - "lapis_ore": "regular", - "lapis_block": "regular", - "dispenser": { - "orientation:vertical": "dispenser_vertical", - "else": "dispenser" + "blocks": { + "stone": "regular", + "granite": "regular", + "polished_granite": "regular", + "diorite": "regular", + "polished_diorite": "regular", + "andesite": "regular", + "polished_andesite": "regular", + "grass_block": "regular", + "dirt": "regular", + "coarse_dirt": "regular", + "podzol": "regular", + "cobblestone": "regular", + "oak_planks": "regular", + "spruce_planks": "regular", + "birch_planks": "regular", + "jungle_planks": "regular", + "acacia_planks": "regular", + "dark_oak_planks": "regular", + "oak_sapling": "regular", + "spruce_sapling": "regular", + "birch_sapling": "regular", + "jungle_sapling": "regular", + "acacia_sapling": "regular", + "dark_oak_sapling": "regular", + "bedrock": "regular", + "sand": "regular", + "red_sand": "regular", + "gravel": "regular", + "gold_ore": "regular", + "iron_ore": "regular", + "coal_ore": "regular", + "spruce_log": "regular", + "birch_log": "regular", + "jungle_log": "regular", + "dark_oak_log": "regular", + "oak_leaves": "regular", + "spruce_leaves": "regular", + "jungle_leaves": "regular", + "birch_leaves": "regular", + "dark_oak_leaves": "regular", + "sponge": "regular", + "wet_sponge": "regular", + "glass": "regular", + "lapis_ore": "regular", + "lapis_block": "regular", + "dispenser": { + "orientation:vertical": "dispenser_vertical", + "else": "dispenser" + }, + "sandstone": "regular", + "chiseled_sandstone": "regular", + "smooth_sandstone": "regular", + "note_block": "regular", + "bed": "invisible", + "powered_rail": { + "else": "powered_rail", + "not_powered": "powered_rail", + "powered": "powered_rail_on", + "powered,ascending_south": "powered_rail_on_raised_ne", + "powered,ascending_north": "powered_rail_on_raised_ne", + "powered,ascending_east": "powered_rail_on_raised_sw", + "powered,ascending_west": "powered_rail_on_raised_sw", + "not_powered,ascending_south": "powered_rail_raised_ne", + "not_powered,ascending_north": "powered_rail_raised_ne", + "not_powered,ascending_east": "powered_rail_raised_sw", + "not_powered,ascending_west": "powered_rail_raised_sw" + }, + "detector_rail": { + "else": "detector_rail", + "not_powered": "detector_rail", + "powered": "detector_rail_on", + "powered,ascending_south": "detector_rail_on_raised_ne", + "powered,ascending_north": "detector_rail_on_raised_ne", + "powered,ascending_east": "detector_rail_on_raised_sw", + "powered,ascending_west": "detector_rail_on_raised_sw", + "not_powered,ascending_south": "detector_rail_raised_ne", + "not_powered,ascending_north": "detector_rail_raised_ne", + "not_powered,ascending_east": "detector_rail_raised_sw", + "not_powered,ascending_west": "detector_rail_raised_sw" + }, + "sticky_piston": "regular", + "cobweb": "regular", + "shrub": "dead_bush", + "grass": "regular", + "fern": "regular", + "dead_bush": "regular", + "piston": "regular", + "piston_head": "regular", + "white_wool": "regular", + "orange_wool": "regular", + "magenta_wool": "regular", + "light_blue_wool": "regular", + "yellow_wool": "regular", + "lime_wool": "regular", + "pink_wool": "regular", + "gray_wool": "regular", + "light_gray_wool": "regular", + "cyan_wool": "regular", + "purple_wool": "regular", + "blue_wool": "regular", + "brown_wool": "regular", + "green_wool": "regular", + "red_wool": "regular", + "black_wool": "regular", + "dandelion": "regular", + "poppy": "regular", + "blue_orchid": "regular", + "allium": "regular", + "azure_bluet": "regular" }, - "sandstone": "regular", - "chiseled_sandstone": "regular", - "smooth_sandstone": "regular", - "note_block": "regular", - "bed": "regular", - "powered_rail": { - "" + "tinted_textures": { + "block/grass_block_top": [ + 0, + 1, + 0 + ] } } \ No newline at end of file