new block rendering system wip2

This commit is contained in:
Lukas 2020-08-01 13:38:16 +02:00
parent c3faa0e9e3
commit 76cef9baeb
9 changed files with 127 additions and 114 deletions

View File

@ -127,12 +127,6 @@
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>18.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -81,7 +81,7 @@ public class WorldRenderer {
}
}
synchronized (faces) {
faces.put(position, modelLoader.getBlockDescription(block).prepare(adjacentBlocks));
faces.put(position, modelLoader.prepare(block, adjacentBlocks));
}
}

View File

@ -60,6 +60,12 @@ public class BlockDescription {
} else {
throw new IllegalArgumentException("json does not have a parent nor subblocks");
}
for (SubBlock subBlock : subBlocks) {
if (subBlock.isFull()) {
isFull = true;
}
}
}
public BlockDescription(JsonObject json) {

View File

@ -19,34 +19,47 @@ import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.BlockProperties;
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.render.fullFace.FaceOrientation;
import java.io.IOException;
import java.util.HashMap;
import java.util.*;
import static de.bixilon.minosoft.util.Util.readJsonFromFile;
public class BlockModelLoader {
final HashMap<String, BlockDescription> blockDescriptionMap;
// a list of blocks not drawn by the world renderer
public static final List<String> ignoredBlocks = new ArrayList<>(Arrays.asList(
"air", "cave_air", "void_air", "moving_piston", "shrub", "structure_void", "water", "lava",
//TODO
"chest", "trapped_chest", "oak_fence"
));
public BlockModelLoader() {
blockDescriptionMap = new HashMap<>();
loadModels();
}
final HashMap<String, HashMap<String, BlockDescription>> blockDescriptionMap;
private void loadModels() {
for (Block block : Blocks.getBlockList()) {
String mod = block.getMod();
String identifier = block.getIdentifier();
if (ignoredBlocks.contains(identifier)) {
continue;
}
if (!blockDescriptionMap.containsKey(mod)) {
blockDescriptionMap.put(mod, new HashMap<>());
}
if (blockDescriptionMap.containsKey(mod + ":" + identifier)) {
continue;
}
if (!mod.equals("minecraft")) {
loadModel(mod, identifier);
continue;
}
if (identifier.equals("silver_glazed_terracotta")) {
// WHAT EVEN IS THIS BLOCK!?!?!
loadModel(mod, "light_gray_glazed_terracotta");
continue;
}
if (identifier.equals("flower_upper_block")) {
@ -54,17 +67,13 @@ public class BlockModelLoader {
continue;
}
if (identifier.equals("bubble_column")) {
// handled with client side particles
// handled with client side "particles"
continue;
}
if (identifier.equals("barrier")) {
// TODO: display barriers if setting is enabled
continue;
}
if (identifier.equals("shrub")) {
// no longer exists ?
continue;
}
if (identifier.equals("end_portal") || identifier.equals("end_gateway")) {
// TODO: display end portals (the portal itself, not the frames
// probably with a shader
@ -74,19 +83,15 @@ public class BlockModelLoader {
// is not displayed
continue;
}
if (identifier.contains("air")) {
// is not displayed
continue;
}
if (identifier.contains("infested")) {
// same block model as the not infested blocks
continue;
}
if (identifier.equals("conduit")) {
// shown as entity?
// shown as entity
continue;
}
if (identifier.equals("moving_piston") || identifier.equals("piston_extension")) {
if (identifier.equals("piston_extension")) {
// TODO: handle pistons
continue;
}
@ -308,10 +313,12 @@ public class BlockModelLoader {
continue;
}
if (identifier.equals("repeater")) {
loadRepeater(mod, identifier, "1");
loadRepeater(mod, identifier, "2");
loadRepeater(mod, identifier, "3");
loadRepeater(mod, identifier, "4");
for (int ticks = 1; ticks < 5; ticks++) {
loadModel(mod, identifier + "_" + ticks + "tick");
loadModel(mod, identifier + "_" + ticks + "tick_locked");
loadModel(mod, identifier + "_" + ticks + "tick_on");
loadModel(mod, identifier + "_" + ticks + "tick_on_locked");
}
continue;
}
if (identifier.contains("door")) {
@ -347,31 +354,25 @@ public class BlockModelLoader {
Log.info("finished loading all block descriptions");
}
private void loadRepeater(String mod, String identifier, String ticks) {
loadModel(mod, identifier + "_" + ticks + "tick");
loadModel(mod, identifier + "_" + ticks + "tick_locked");
loadModel(mod, identifier + "_" + ticks + "tick_on");
loadModel(mod, identifier + "_" + ticks + "tick_on_locked");
}
private boolean handleProperties(Block block) {
return !block.getProperties().contains(BlockProperties.NONE) && block.getProperties().size() != 0;
}
private void loadModel(String mod, String identifier) {
if (blockDescriptionMap.containsKey((mod + ":" + identifier))) {
// a description for that block already exists, checking because Blocks.getBlockList()
// returns all blocks with all possible combinations
if (blockDescriptionMap.containsKey(mod) && blockDescriptionMap.get(mod).containsKey(identifier)) {
// a description for that block already exists. checking because Blocks.getBlockList()
// returns all blocks with all possible combinations (rotation, etc.)
return;
}
try {
String path = Config.homeDir + "assets/" + mod + "/models/block/" + identifier + ".json";
JsonObject json = readJsonFromFile(path);
BlockDescription description = new BlockDescription(json);
blockDescriptionMap.put(mod + ":" + identifier, description);
//Log.info("Loaded model for " + mod + ":" + identifier);
HashMap<String, BlockDescription> modList = blockDescriptionMap.get(mod);
modList.put(identifier, description);
} catch (IOException e) {
Log.debug("could not load block model for block " + mod + ":" + identifier);
Log.debug("could not find block model for block " + mod + ":" + identifier);
} catch (Exception e) {
e.printStackTrace();
System.out.println(mod + ":" + identifier);
@ -381,18 +382,37 @@ public class BlockModelLoader {
}
public BlockDescription getBlockDescription(Block block) {
String blockName = block.getMod() + ":" + block.getIdentifier();
if (!blockDescriptionMap.containsKey(blockName)) {
System.out.println(String.format("No description for block %s found", blockName));
System.exit(-1);
if (ignoredBlocks.contains(block.getIdentifier())) {
return null;
}
return blockDescriptionMap.get(block.getMod() + ":" + block.getIdentifier());
if (!blockDescriptionMap.containsKey(block.getMod())) {
System.out.println(String.format("No mod %s found", block.getMod()));
//System.exit(-1);
}
HashMap<String, BlockDescription> modList = blockDescriptionMap.get(block.getMod());
if (!modList.containsKey(block.getIdentifier())) {
System.out.println(String.format("No block %s:%s found", block.getMod(), block.getIdentifier()));
//System.exit(-1);
}
return modList.get(block.getIdentifier());
}
public boolean isFull(Block block) {
if (block == Blocks.nullBlock || block == null) {
return false;
}
return getBlockDescription(block).isFull();
BlockDescription description = getBlockDescription(block);
if (description == null) {
return false;
}
return description.isFull();
}
public HashSet<Face> prepare(Block block, HashMap<FaceOrientation, Boolean> adjacentBlocks) {
BlockDescription description = getBlockDescription(block);
if (description == null) {
return new HashSet<>();
}
return description.prepare(adjacentBlocks);
}
}

View File

@ -26,111 +26,98 @@ import static org.lwjgl.opengl.GL11.glVertex3f;
public class Face {
FaceOrientation orientation;
Pair<Float, Float> texture;
InFaceUV uv;
SubBlock subBlock;
float x1, y1, z1, x2, y2, z2;
float u1, v1, u2, v2;
public Face(FaceOrientation orientation, Pair<Float, Float> texture, InFaceUV uv, SubBlock subBlock) {
this.orientation = orientation;
this.texture = texture;
this.uv = uv;
this.subBlock = subBlock;
}
public void draw(BlockPosition pos) {
float x1 = 0, y1 = 0, z1 = 0, x2 = 0, y2 = 0, z2 = 0;
float step = MainWindow.getRenderer().getTextureLoader().getStep();
float u1 = texture.getKey() + (float) uv.u1 / (float) blockRes * step;
float u2 = texture.getValue() + (float) uv.u1 / (float) blockRes * step;
float v1 = (float) uv.v1 / (float) texturePackRes;
float v2 = (float) uv.v2 / (float) texturePackRes;
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;
v2 = (float) uv.v2 / (float) texturePackRes;
x1 = subBlock.pos1.x;
y1 = subBlock.pos1.y;
z1 = subBlock.pos1.z;
x2 = subBlock.pos2.x;
y2 = subBlock.pos2.y;
z2 = subBlock.pos2.z;
switch (orientation) {
case EAST:
x1 = x2 = subBlock.pos2.x;
y1 = subBlock.pos1.y;
y2 = subBlock.pos2.y;
z1 = subBlock.pos1.z;
z2 = subBlock.pos2.z;
break;
case WEST:
x1 = x2 = subBlock.pos1.x;
y1 = subBlock.pos1.y;
y2 = subBlock.pos2.y;
z1 = subBlock.pos1.z;
z2 = subBlock.pos2.z;
break;
case UP:
y1 = y2 = subBlock.pos2.y;
x1 = subBlock.pos1.x;
x2 = subBlock.pos2.x;
z1 = subBlock.pos1.z;
z2 = subBlock.pos2.z;
break;
case DOWN:
y1 = y2 = subBlock.pos1.y;
x1 = subBlock.pos1.x;
x2 = subBlock.pos2.x;
z1 = subBlock.pos1.z;
z2 = subBlock.pos2.z;
break;
case SOUTH:
z1 = z2 = subBlock.pos2.z;
x1 = subBlock.pos1.x;
x2 = subBlock.pos2.x;
y1 = subBlock.pos1.y;
y2 = subBlock.pos2.y;
break;
case NORTH:
z1 = z2 = subBlock.pos1.z;
x1 = subBlock.pos1.x;
x2 = subBlock.pos2.x;
y1 = subBlock.pos1.y;
y2 = subBlock.pos2.y;
break;
}
x1 /= blockRes;
y1 /= blockRes;
z1 /= blockRes;
x2 /= blockRes;
y2 /= blockRes;
z2 /= blockRes;
}
public void draw(BlockPosition pos) {
switch (orientation) {
case EAST:
case WEST:
glTexCoord2f(u1, v2);
glVertex3f(x1 + pos.getX(), y1 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u1, v1);
glVertex3f(x1, y1, z1);
glVertex3f(x1 + pos.getX(), y2 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u2, v1);
glVertex3f(x1, y2, z1);
glVertex3f(x1 + pos.getX(), y2 + pos.getY(), z2 + pos.getZ());
glTexCoord2f(u2, v2);
glVertex3f(x1, y2, z2);
glTexCoord2f(u2, v2);
glVertex3f(x1, y2, z2);
glVertex3f(x1 + pos.getX(), y1 + pos.getY(), z2 + pos.getZ());
break;
case UP:
case DOWN:
glTexCoord2f(u1, v1);
glVertex3f(x1, y1, z1);
glVertex3f(x1 + pos.getX(), y1 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u2, v1);
glVertex3f(x2, y1, z1);
glVertex3f(x2 + pos.getX(), y1 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u2, v2);
glVertex3f(x2, y1, z2);
glVertex3f(x2 + pos.getX(), y1 + pos.getY(), z2 + pos.getZ());
glTexCoord2f(u2, v2);
glVertex3f(x1, y1, z2);
glTexCoord2f(u1, v2);
glVertex3f(x1 + pos.getX(), y1 + pos.getY(), z2 + pos.getZ());
break;
case NORTH:
case SOUTH:
glTexCoord2f(u2, v2);
glVertex3f(x1 + pos.getX(), y1 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u1, v2);
glVertex3f(x2 + pos.getX(), y1 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u1, v1);
glVertex3f(x1, y1, z1);
glVertex3f(x2 + pos.getX(), y2 + pos.getY(), z1 + pos.getZ());
glTexCoord2f(u2, v1);
glVertex3f(x2, y1, z1);
glTexCoord2f(u2, v2);
glVertex3f(x2, y2, z1);
glTexCoord2f(u2, v2);
glVertex3f(x1, y2, z1);
glVertex3f(x1 + pos.getX(), y2 + pos.getY(), z1 + pos.getZ());
break;
}
}

View File

@ -30,6 +30,7 @@ public class SubBlock {
HashMap<FaceOrientation, Boolean> cullFaceTextures;
HashMap<FaceOrientation, InFaceUV> uv;
private final boolean isFull;
public SubBlock(JsonObject json, HashMap<String, String> variables) {
uv = new HashMap<>();
@ -45,6 +46,7 @@ public class SubBlock {
orientation, variables);
}
}
isFull = (pos1.x == 0 && pos1.y == 0 && pos1.z == 0) && (pos2.x == 16 && pos2.y == 16 && pos2.z == 16);
}
private static String getRealTextureName(String textureName, HashMap<String, String> variables) {
@ -94,4 +96,8 @@ public class SubBlock {
}
return result;
}
public boolean isFull() {
return isFull;
}
}

View File

@ -71,9 +71,11 @@ public class CollisionHandler {
}
controller.playerPos.y = controller.oldPos.y;
controller.playerVelocity.y = 0;
//TODO: check if player is actually standing ON a block and is not hanging on the ceiling
if (deltaY < 0) {
controller.onGround = true;
}
}
private void zAxisCollision() {
float deltaZ = controller.playerPos.z - controller.oldPos.z;
@ -94,8 +96,8 @@ public class CollisionHandler {
int[] xPositions = valuesBetween(betterRound(testPos.x + width),
betterRound(testPos.x - width));
int[] yPositions = valuesBetween(betterRound(testPos.y + 1),
betterRound(testPos.y + controller.getPlayerHeight() + 1));
int[] yPositions = valuesBetween(betterRound(testPos.y),
betterRound(testPos.y + controller.getPlayerHeight()));
int[] zPositions = valuesBetween(betterRound(testPos.z + width),
betterRound(testPos.z - width));

View File

@ -16,7 +16,6 @@ package de.bixilon.minosoft.render.movement;
import de.bixilon.minosoft.game.datatypes.GameMode;
import de.bixilon.minosoft.game.datatypes.world.World;
import de.bixilon.minosoft.render.MainWindow;
import de.bixilon.minosoft.render.blockModels.BlockModelLoader;
import de.bixilon.minosoft.render.utility.Vec3;
import static de.bixilon.minosoft.render.utility.Vec3.mul;
@ -45,7 +44,7 @@ public class PlayerController {
oldPos = playerPos.copy();
GameMode gameMode = MainWindow.getConnection().getPlayer().getGameMode();
enableGravity = gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR;
enableGravity = gameMode != GameMode.CREATIVE && gameMode != GameMode.SPECTATOR;
handleGravity(deltaTime);
cameraMovement.loop();
playerMovement.loop(deltaTime);
@ -65,7 +64,6 @@ public class PlayerController {
playerVelocity.zero();
return;
}
BlockModelLoader modelLoader = MainWindow.getRenderer().getModelLoader();
collisionHandler.handleCollisions();
}
@ -89,7 +87,7 @@ public class PlayerController {
if (!enableGravity) {
return;
}
// a rather accurate model for the real world, but minecraft probably does it differently
// a rather accurate model for the real world, but minecraft does it differently
playerVelocity.y -= gravity * deltaTime;
}

View File

@ -58,12 +58,12 @@ public class PlayerMovement {
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
if (!MainWindow.getPlayerController().isEnableGravity()) {
playerPos.add(0, cameraSpeed * deltaTime, 0);
playerPos.add(0, -cameraSpeed * deltaTime, 0);
}
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
if (!MainWindow.getPlayerController().isEnableGravity()) {
playerPos.add(0, -cameraSpeed * deltaTime, 0);
playerPos.add(0, cameraSpeed * deltaTime, 0);
}
if (MainWindow.getPlayerController().isOnGround()) {
MainWindow.getPlayerController().jump();