diff --git a/Minosoft.iml b/Minosoft.iml deleted file mode 100644 index 8bc82d596..000000000 --- a/Minosoft.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 742aa0dd9..dfc86f357 100644 --- a/pom.xml +++ b/pom.xml @@ -25,9 +25,15 @@ maven-compiler-plugin 3.8.1 - 15 - 15 - --enable-preview + + 14 + + + 14 + + + --enable-preview + diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModel.java b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModel.java index 7da6d5179..3a4ac2065 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModel.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModel.java @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * 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. * @@ -13,88 +13,55 @@ package de.bixilon.minosoft.render.blockModels; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import de.bixilon.minosoft.data.mappings.blocks.Block; +import de.bixilon.minosoft.data.mappings.blocks.BlockProperties; +import de.bixilon.minosoft.data.mappings.blocks.BlockRotations; +import de.bixilon.minosoft.data.mappings.blocks.Blocks; import de.bixilon.minosoft.data.world.BlockPosition; +import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.render.blockModels.Face.Axis; import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation; import de.bixilon.minosoft.render.blockModels.subBlocks.SubBlock; -import de.bixilon.minosoft.render.texture.TextureLoader; import org.apache.commons.collections.primitives.ArrayFloatList; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; +import java.util.stream.Collectors; -public class BlockModel { - private ArrayList subBlocks; - private boolean[] full; // minor memory improvement over a Map +public class BlockModel implements BlockModelInterface { + private final HashMap, HashSet> stateMap; + private final HashMap, boolean[]> full; // minor memory improvement over a Map FaceOrientation -> boolean and also performance should be boosted - public BlockModel(JsonObject block, JsonObject allModels) { - subBlocks = load(block, allModels); - } - - public BlockModel(BlockModel blockModel, JsonObject json) { - if (blockModel != null) { - subBlocks = blockModel.getSubBlocks(); - } else { - subBlocks = new ArrayList<>(); - } - if (json.has("x")) { - rotate(Axis.X, json.get("x").getAsInt()); - } - if (json.has("y")) { - rotate(Axis.Y, json.get("y").getAsInt()); - } - if (json.has("z")) { - rotate(Axis.Z, json.get("z").getAsInt()); - } - full = createFullValues(); - } - - private void rotate(Axis axis, int rotation) { - for (SubBlock subBlock : subBlocks) { - subBlock.rotate(axis, rotation); - } - } - - public BlockModel() { - } - - static ArrayList load(JsonObject json, JsonObject allModels, HashMap variables) { - ArrayList result = new ArrayList<>(); - if (json.has("textures")) { - // read the textures into a variable hashmap - JsonObject textures = json.getAsJsonObject("textures"); - for (String texture : textures.keySet()) { - if (texture.contains("#") && variables.containsKey(texture)) { - variables.put("#" + texture, variables.get(texture)); - } else { - variables.put("#" + texture, textures.get(texture).getAsString()); + public BlockModel(HashMap> blockModels, JsonArray states) { + stateMap = new HashMap<>(); + full = new HashMap<>(); + for (JsonElement element : states) { + JsonObject state = element.getAsJsonObject(); + HashSet model = blockModels.get(state.get("model").getAsString()).stream().map(SubBlock::new).collect(Collectors.toCollection(HashSet::new)); + HashSet properties = new HashSet<>(); + for (Map.Entry property : state.getAsJsonObject("properties").entrySet()) { + if (Blocks.getPropertiesMapping().containsKey(property.getKey())) { + properties.add(Blocks.getPropertiesMapping().get(property.getKey()).get(property.getValue().getAsString()).name()); + } else if (Blocks.getRotationMapping().containsKey(property.getValue().getAsString())) { + properties.add(Blocks.getRotationMapping().get(property.getValue().getAsString()).name()); } } - } - if (json.has("elements")) { - for (JsonElement subBlockJson : json.get("elements").getAsJsonArray()) { - result.add(new SubBlock(subBlockJson.getAsJsonObject(), variables)); + for (Axis axis : Axis.values()) { + String lowercase = axis.name().toLowerCase(); + if (state.has(lowercase)) { + BlockModelInterface.rotateModel(model, axis, state.get(lowercase).getAsInt()); + } } - } else if (json.has("parent") && !json.get("parent").getAsString().equals("block/block")) { - String parent = json.get("parent").getAsString(); - if (parent.equals("block/block")) { - return result; - } - String parentIdentifier = parent.substring(parent.lastIndexOf("/") + 1); - result.addAll(load(allModels.get(parentIdentifier).getAsJsonObject(), allModels, variables)); + stateMap.put(properties, model); + full.put(properties, createFullValues(model)); } - return result; } - static ArrayList load(JsonObject json, JsonObject allModels) { - return load(json, allModels, new HashMap<>()); - } - - private boolean[] createFullValues() { + private static boolean[] createFullValues(HashSet subBlocks) { boolean[] result = new boolean[6]; outer: for (FaceOrientation orientation : FaceOrientation.values()) { @@ -108,41 +75,60 @@ public class BlockModel { return result; } - public boolean isFull(FaceOrientation orientation) { - return full[orientation.getId()]; + private static HashSet getProperties(Block block) { + HashSet result = new HashSet<>(); + if (block.getRotation() != BlockRotations.NONE) { + result.add(block.getRotation().name()); + } + for (BlockProperties property : block.getProperties()) { + result.add(property.name()); + } + return result; + } + + public boolean full(Block block, FaceOrientation orientation) { + HashSet properties = getProperties(block); + for (Map.Entry, boolean[]> entry : full.entrySet()) { + if (properties.containsAll(entry.getKey())) { + return entry.getValue()[orientation.getId()]; + } + } + properties.add(BlockRotations.NONE.name()); + for (Map.Entry, boolean[]> entry : full.entrySet()) { + if (properties.containsAll(entry.getKey())) { + return entry.getValue()[orientation.getId()]; + } + } + Log.warn(String.format("could not find a corresponding block model for block %s", block.toString())); + return false; } public ArrayFloatList prepare(HashSet facesToDraw, BlockPosition position, Block block) { - ArrayFloatList result = new ArrayFloatList(); - for (SubBlock subBlock : subBlocks) { - result.addAll(subBlock.getFaces(facesToDraw, position)); + HashSet properties = getProperties(block); + for (Map.Entry, HashSet> entry : stateMap.entrySet()) { + if (properties.containsAll(entry.getKey())) { + ArrayFloatList result = new ArrayFloatList(); + for (SubBlock subBlock : entry.getValue()) { + result.addAll(subBlock.getFaces(facesToDraw, position)); + } + return result; + } } - return result; + properties.add(BlockRotations.NONE.name()); + for (Map.Entry, HashSet> entry : stateMap.entrySet()) { + if (properties.containsAll(entry.getKey())) { + ArrayFloatList result = new ArrayFloatList(); + for (SubBlock subBlock : entry.getValue()) { + result.addAll(subBlock.getFaces(facesToDraw, position)); + } + return result; + } + } + Log.warn(String.format("could not find a corresponding block model for block %s", block.toString())); + return new ArrayFloatList(); } public boolean isFull() { return true; } - - public HashSet getAllTextures() { - HashSet result = new HashSet<>(); - for (SubBlock subBlock : subBlocks) { - result.addAll(subBlock.getTextures()); - } - return result; - } - - public void applyTextures(String mod, TextureLoader loader) { - for (SubBlock subBlock : subBlocks) { - subBlock.applyTextures(mod, loader); - } - } - - public ArrayList getSubBlocks() { - return subBlocks; - } - - public boolean[] getFull() { - return full; - } } diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelBlockWrapper.java b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelBlockWrapper.java deleted file mode 100644 index 0896a8b42..000000000 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelBlockWrapper.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * 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.data.mappings.blocks.Block; -import de.bixilon.minosoft.data.mappings.blocks.BlockRotations; - -public class BlockModelBlockWrapper { - Block block; - - public BlockModelBlockWrapper(Block block) { - this.block = block; - } - - public Block getBlock() { - return block; - } - - @Override - public int hashCode() { - return block.getMod().hashCode() * block.getIdentifier().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (super.equals(obj)) { - return true; - } - BlockModelBlockWrapper their = (BlockModelBlockWrapper) obj; - if (block.equals(their.getBlock())) { - return true; - } - if (!(block.getMod().equals(their.getBlock().getMod()) && block.getIdentifier().equals(their.getBlock().getIdentifier()))) { - return false; - } - if (block.getRotation() == BlockRotations.NONE || their.getBlock().getRotation() == BlockRotations.NONE || block.getProperties().size() == 0 || their.getBlock().getProperties().size() == 0) { - return true; - } - return block.getProperties().equals(their.getBlock().getProperties()) && block.getMod().equals(their.getBlock().getMod()); - } -} diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelInterface.java b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelInterface.java new file mode 100644 index 000000000..0b172e5b8 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelInterface.java @@ -0,0 +1,72 @@ +/* + * minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * 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 com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import de.bixilon.minosoft.data.mappings.blocks.Block; +import de.bixilon.minosoft.data.world.BlockPosition; +import de.bixilon.minosoft.render.blockModels.Face.Axis; +import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation; +import de.bixilon.minosoft.render.blockModels.subBlocks.SubBlock; +import org.apache.commons.collections.primitives.ArrayFloatList; + +import java.util.HashMap; +import java.util.HashSet; + +public interface BlockModelInterface { + static HashSet load(JsonObject block, JsonObject allModels, HashMap variables) { + HashSet result = new HashSet<>(); + if (block.has("textures")) { + // read the textures into a variable hashmap + JsonObject textures = block.getAsJsonObject("textures"); + for (String texture : textures.keySet()) { + if (texture.contains("#") && variables.containsKey(texture)) { + variables.put("#" + texture, variables.get(texture)); + } else { + variables.put("#" + texture, textures.get(texture).getAsString()); + } + } + } + if (block.has("elements")) { + for (JsonElement subBlockJson : block.get("elements").getAsJsonArray()) { + result.add(new SubBlock(subBlockJson.getAsJsonObject(), variables)); + } + } else if (block.has("parent") && !block.get("parent").getAsString().equals("block/block")) { + String parent = block.get("parent").getAsString(); + if (parent.equals("block/block")) { + return result; + } + String parentIdentifier = parent.substring(parent.lastIndexOf("/") + 1); + result.addAll(load(allModels.get(parentIdentifier).getAsJsonObject(), allModels, variables)); + } + return result; + } + + static HashSet load(JsonObject json, JsonObject allModels) { + return load(json, allModels, new HashMap<>()); + } + + static void rotateModel(HashSet subBlocks, Axis axis, int rotation) { + for (SubBlock subBlock : subBlocks) { + subBlock.rotate(axis, rotation); + } + } + + boolean full(Block block, FaceOrientation orientation); + + boolean isFull(); + + ArrayFloatList prepare(HashSet facesToDraw, BlockPosition position, Block block); +} 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 7a488fa78..f07c47d25 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelLoader.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/BlockModelLoader.java @@ -20,6 +20,7 @@ import de.bixilon.minosoft.data.mappings.blocks.Block; import de.bixilon.minosoft.data.mappings.blocks.Blocks; import de.bixilon.minosoft.data.world.BlockPosition; import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation; +import de.bixilon.minosoft.render.blockModels.subBlocks.SubBlock; import de.bixilon.minosoft.render.texture.TextureLoader; import de.bixilon.minosoft.util.Util; import org.apache.commons.collections.primitives.ArrayFloatList; @@ -29,14 +30,13 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; - public class BlockModelLoader { - HashMap blockMap; TextureLoader textureLoader; public static BlockModelLoader blockModelLoader; + HashMap> modelMap; public BlockModelLoader() { - blockMap = new HashMap<>(); + modelMap = new HashMap<>(); HashSet mods = new HashSet<>(); HashMap> tints = new HashMap<>(); try { @@ -45,10 +45,14 @@ public class BlockModelLoader { } catch (IOException e) { e.printStackTrace(); } - HashMap> blockModels = new HashMap<>(); + HashMap>> blockModels = new HashMap<>(); for (JsonObject mod : mods) { - blockModels.put(mod.get("mod").getAsString(), loadModels(mod)); - tints.put(mod.get("mod").getAsString(), readTints(mod)); + String modName = mod.get("mod").getAsString(); + if (!modelMap.containsKey(mod.get("mod").getAsString())) { + modelMap.put(modName, new HashMap<>()); + } + blockModels.put(modName, loadModels(mod)); + tints.put(modName, readTints(mod)); } textureLoader = new TextureLoader(getTextures(blockModels), tints); applyTextures(blockModels); @@ -57,47 +61,46 @@ public class BlockModelLoader { } } - private void loadBlocks(JsonObject mod, HashMap blockModels) { + private void loadBlocks(JsonObject mod, HashMap> blockModels) { for (Map.Entry blockEntry : mod.get("blockStates").getAsJsonObject().entrySet()) { JsonObject block = blockEntry.getValue().getAsJsonObject(); if (block.has("states")) { JsonArray states = block.get("states").getAsJsonArray(); - for (JsonElement state : states) { - BlockModel model = blockModels.get(state.getAsJsonObject().get("model").getAsString()); - Block wrapper = new Block(mod.get("mod").getAsString(), blockEntry.getKey(), state.getAsJsonObject().get("properties").getAsJsonObject()); - blockMap.put(new BlockModelBlockWrapper(wrapper), new BlockModel(model, state.getAsJsonObject())); - } + modelMap.get(mod.get("mod").getAsString()).put(blockEntry.getKey(), new BlockModel(blockModels, states)); } else if (block.has("conditional")) { - Block wrapper = new Block(mod.get("mod").getAsString(), blockEntry.getKey()); - blockMap.put(new BlockModelBlockWrapper(wrapper), new ConditionalModel(blockModels, block.get("conditional").getAsJsonArray())); + modelMap.get(mod.get("mod").getAsString()).put(blockEntry.getKey(), new ConditionalModel(blockModels, block.get("conditional").getAsJsonArray())); } } } - private HashMap loadModels(JsonObject mod) { - HashMap modMap = new HashMap<>(); - for (Map.Entry block : mod.get("blockModels").getAsJsonObject().entrySet()) { - modMap.put(block.getKey(), new BlockModel(block.getValue().getAsJsonObject(), mod.get("blockModels").getAsJsonObject())); + private HashMap> loadModels(JsonObject mod) { + HashMap> modMap = new HashMap<>(); + for (Map.Entry block : mod.getAsJsonObject("blockModels").entrySet()) { + modMap.put(block.getKey(), BlockModelInterface.load(block.getValue().getAsJsonObject(), mod.getAsJsonObject("blockModels"))); } return modMap; } - public HashMap> getTextures(HashMap> blockModels) { + public HashMap> getTextures(HashMap>> blockModels) { HashMap> textures = new HashMap<>(); - for (Map.Entry> mod : blockModels.entrySet()) { + for (Map.Entry>> mod : blockModels.entrySet()) { HashSet modTextures = new HashSet<>(); - for (BlockModel blockModel : mod.getValue().values()) { - modTextures.addAll(blockModel.getAllTextures()); + for (HashSet subBlocks : mod.getValue().values()) { + for (SubBlock subBlock : subBlocks) { + modTextures.addAll(subBlock.getTextures()); + } } textures.put(mod.getKey(), modTextures); } return textures; } - public void applyTextures(HashMap> blockModels) { - for (Map.Entry> mod : blockModels.entrySet()) { - for (Map.Entry block : mod.getValue().entrySet()) { - block.getValue().applyTextures(mod.getKey(), textureLoader); + public void applyTextures(HashMap>> blockModels) { + for (Map.Entry>> mod : blockModels.entrySet()) { + for (Map.Entry> block : mod.getValue().entrySet()) { + for (SubBlock subBlock : block.getValue()) { + subBlock.applyTextures(mod.getKey(), textureLoader); + } } } } @@ -118,19 +121,19 @@ public class BlockModelLoader { return result; } - public BlockModel getBlockModel(Block block) { - BlockModel model = blockMap.get(new BlockModelBlockWrapper(block)); + public BlockModelInterface getBlockModel(Block block) { + BlockModelInterface model = modelMap.get(block.getMod()).get(block.getIdentifier()); if (model == null) { throw new RuntimeException("block " + block + " could not be found"); } - return blockMap.get(new BlockModelBlockWrapper(block)); + return model; } public boolean isFull(Block block, FaceOrientation orientation) { if (block == null || block.equals(Blocks.nullBlock)) { return false; } - return getBlockModel(block).isFull(orientation); + return getBlockModel(block).full(block, orientation); } public boolean isFull(Block block) { diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/ConditionalModel.java b/src/main/java/de/bixilon/minosoft/render/blockModels/ConditionalModel.java index 1a5dfc4fe..ef611b364 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/ConditionalModel.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/ConditionalModel.java @@ -19,16 +19,17 @@ import com.google.gson.JsonObject; import de.bixilon.minosoft.data.mappings.blocks.Block; import de.bixilon.minosoft.data.world.BlockPosition; import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation; +import de.bixilon.minosoft.render.blockModels.subBlocks.SubBlock; import org.apache.commons.collections.primitives.ArrayFloatList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; -public class ConditionalModel extends BlockModel { - HashMap conditionMap; +public class ConditionalModel implements BlockModelInterface { + HashMap> conditionMap; - public ConditionalModel(HashMap blockModels, JsonArray elements) { + public ConditionalModel(HashMap> blockModels, JsonArray elements) { conditionMap = new HashMap<>(); for (JsonElement element : elements) { JsonObject block = element.getAsJsonObject(); @@ -38,29 +39,31 @@ public class ConditionalModel extends BlockModel { } else { condition = BlockCondition.trueCondition; } - BlockModel model = blockModels.get(block.get("model").getAsString()); - conditionMap.put(condition, new BlockModel(model, block)); + HashSet model = blockModels.get(block.get("model").getAsString()); + conditionMap.put(condition, model); } } @Override public ArrayFloatList prepare(HashSet facesToDraw, BlockPosition position, Block block) { ArrayFloatList result = new ArrayFloatList(); - for (Map.Entry entry : conditionMap.entrySet()) { + for (Map.Entry> entry : conditionMap.entrySet()) { if (entry.getKey().contains(block)) { - result.addAll(entry.getValue().prepare(facesToDraw, position, block)); + for (SubBlock subBlock : entry.getValue()) { + result.addAll(subBlock.getFaces(facesToDraw, position)); + } } } return result; } @Override - public boolean isFull() { + public boolean full(Block block, FaceOrientation orientation) { return false; } @Override - public boolean isFull(FaceOrientation orientation) { + public boolean isFull() { return false; } } diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/Cuboid.java b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/Cuboid.java index 31e947efc..5fca08544 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/Cuboid.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/Cuboid.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.render.blockModels.subBlocks; -// a 3d object with 8 corners, 6 faces and 12 edges (example: cube, but can be deformed) +// a 3d object with 8 corners, 6 faces and 12 edges (cube, but can be deformed) import de.bixilon.minosoft.render.blockModels.Face.Axis; import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation; @@ -47,6 +47,13 @@ public class Cuboid { } } + public Cuboid(Cuboid cuboid) { + positions = new SubBlockPosition[cuboid.positions.length]; + for (int i = 0; i < positions.length; i++) { + positions[i] = new SubBlockPosition(cuboid.positions[i]); + } + } + public SubBlockPosition[] getFacePositions(FaceOrientation orientation) { int[] positionIds = facePositionMapTemplate[orientation.getId()]; SubBlockPosition[] result = new SubBlockPosition[positionIds.length]; diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlock.java b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlock.java index 0cd01cd3a..b2629dec5 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlock.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlock.java @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * 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. * @@ -27,7 +27,7 @@ import java.util.Map; public class SubBlock { private final HashMap textureCoordinates; - private final HashMap textures; + private HashMap textures; private final HashMap textureRotations; private final boolean[] full; private final HashMap uv; @@ -56,6 +56,14 @@ public class SubBlock { full = createFull(); } + public SubBlock(SubBlock subBlock) { + textureCoordinates = subBlock.textureCoordinates; + textureRotations = subBlock.textureRotations; + uv = subBlock.uv; + cuboid = new Cuboid(subBlock.cuboid); + full = createFull(); + } + private static String getRealTextureName(String textureName, HashMap variables) { // read the variables and find the real texture name if (textureName.contains("#")) { diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockPosition.java b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockPosition.java index 3b0a16c1c..95cbe69c9 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockPosition.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockPosition.java @@ -41,6 +41,10 @@ public class SubBlockPosition { this.vector = vector; } + public SubBlockPosition(SubBlockPosition position) { + vector = new Vec3(position.vector); + } + public SubBlockPosition rotated(Axis axis, int rotation) { return new SubBlockRotation(middlePos, axis, rotation).apply(this); } diff --git a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockRotation.java b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockRotation.java index dc6bcffdc..11e951ed5 100644 --- a/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockRotation.java +++ b/src/main/java/de/bixilon/minosoft/render/blockModels/subBlocks/SubBlockRotation.java @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * 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. * @@ -16,73 +16,52 @@ package de.bixilon.minosoft.render.blockModels.subBlocks; import com.google.gson.JsonObject; import de.bixilon.minosoft.render.blockModels.Face.Axis; import de.bixilon.minosoft.render.utility.Vec3; - +import javafx.util.Pair; public class SubBlockRotation { private final Vec3 origin; - private final double angle; - private final Vec3 direction; + private final Axis axis; + private final double sin; + private final double cos; - public SubBlockRotation(SubBlockPosition origin, Axis direction, float angle) { + public SubBlockRotation(SubBlockPosition origin, Axis axis, float angle) { this.origin = origin.getVector(); - this.direction = switch (direction) { - case X -> new Vec3(1, 0, 0); - case Y -> new Vec3(0, 1, 0); - case Z -> new Vec3(0, 0, 1); - }; - this.angle = angle; + this.axis = axis; + double angleRad = Math.toRadians(angle); + sin = Math.sin(angleRad); + cos = Math.cos(angleRad); } public SubBlockRotation(JsonObject rotation) { origin = new SubBlockPosition(rotation.get("origin").getAsJsonArray()).getVector(); - String axis = rotation.get("axis").getAsString(); - direction = switch (axis) { - case "x" -> new Vec3(1, 0, 0); - case "y" -> new Vec3(0, 1, 0); - case "z" -> new Vec3(0, 0, 1); - default -> throw new IllegalStateException("Unexpected value: " + axis); + String direction = rotation.get("axis").getAsString(); + axis = switch (direction) { + case "x" -> Axis.X; + case "y" -> Axis.Y; + case "z" -> Axis.Z; + default -> throw new IllegalStateException("Unexpected value: " + direction); }; - angle = Math.toRadians(rotation.get("angle").getAsFloat()); + double angleRad = Math.toRadians(rotation.get("angle").getAsDouble()); + sin = Math.sin(angleRad); + cos = Math.cos(angleRad); } - public SubBlockPosition apply(SubBlockPosition position) { - Vec3 transformed = Vec3.add(position.getVector(), Vec3.mul(origin, -1)); - - Vec3 result = Vec3.mul(transformed, Math.cos(angle)); - result.add(Vec3.mul(Vec3.cross(direction, transformed), Math.sin(angle))); - //result.add(Vec3.mul(direction, direction, transformed, )); - return new SubBlockPosition(Vec3.add(transformed, origin)); - } - - /* - public static Pair rotate(float x, float y, float angle) { - float angleRad = (float) Math.toRadians(angle); - float newX = x * (float) StrictMath.cos(angleRad) + y * (float) StrictMath.sin(angleRad); - float newY = - x * (float) StrictMath.sin(angleRad) + y * (float) StrictMath.cos(angleRad); + private Pair rotate(double x, double y) { + double newX = x * cos - y * sin; + double newY = x * sin + y * cos; return new Pair<>(newX, newY); } + public SubBlockPosition apply(SubBlockPosition position) { - SubBlockPosition transformed = SubBlockPosition.subtract(position, origin); - Pair rotated; - switch (direction) { - case X -> { - rotated = rotate(transformed.y, transformed.z, angle); - transformed.y = rotated.getKey(); - transformed.z = rotated.getValue(); - } - case Y -> { - rotated = rotate(transformed.x, transformed.z, angle); - transformed.x = rotated.getKey(); - transformed.z = rotated.getValue(); - } - case Z -> { - rotated = rotate(transformed.x, transformed.y, angle); - transformed.x = rotated.getKey(); - transformed.y = rotated.getValue(); - } - } - return SubBlockPosition.add(transformed, origin); + Vec3 transformedPosition = Vec3.add(position.getVector(), Vec3.mul(origin, -1)); + return switch (axis) { + case X: + Pair rotateX = rotate(transformedPosition.y, transformedPosition.z); transformedPosition.y = rotateX.getKey(); transformedPosition.z = rotateX.getValue(); yield new SubBlockPosition(Vec3.add(transformedPosition, origin)); + case Y: + Pair rotateY = rotate(transformedPosition.x, transformedPosition.z); transformedPosition.x = rotateY.getKey(); transformedPosition.z = rotateY.getValue(); yield new SubBlockPosition(Vec3.add(transformedPosition, origin)); + case Z: + Pair rotateZ = rotate(transformedPosition.x, transformedPosition.y); transformedPosition.x = rotateZ.getKey(); transformedPosition.y = rotateZ.getValue(); yield new SubBlockPosition(Vec3.add(transformedPosition, origin)); + }; } - */ } diff --git a/src/main/java/de/bixilon/minosoft/render/movement/PlayerController.java b/src/main/java/de/bixilon/minosoft/render/movement/PlayerController.java index 01d172818..c30728ba8 100644 --- a/src/main/java/de/bixilon/minosoft/render/movement/PlayerController.java +++ b/src/main/java/de/bixilon/minosoft/render/movement/PlayerController.java @@ -64,6 +64,7 @@ public class PlayerController { applyVelocity(deltaTime); if (gameMode == GameModes.SPECTATOR) { + glTranslated(-playerPos.x, -(playerPos.y + playerHeight - 0.2f), -playerPos.z); return; } handleCollisions(connection.getPlayer().getWorld()); diff --git a/src/main/java/de/bixilon/minosoft/render/utility/Vec3.java b/src/main/java/de/bixilon/minosoft/render/utility/Vec3.java index c8378e67b..3e8db08f9 100644 --- a/src/main/java/de/bixilon/minosoft/render/utility/Vec3.java +++ b/src/main/java/de/bixilon/minosoft/render/utility/Vec3.java @@ -35,6 +35,12 @@ public class Vec3 { z = (float) location.getZ(); } + public Vec3(Vec3 vector) { + x = vector.x; + y = vector.y; + z = vector.z; + } + public static Vec3 add(Vec3... vectors) { Vec3 result = new Vec3(0, 0, 0); for (Vec3 vector : vectors) {