mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 18:05:51 -04:00
new block rendering system wip2
This commit is contained in:
parent
c3faa0e9e3
commit
76cef9baeb
6
pom.xml
6
pom.xml
@ -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>
|
@ -81,7 +81,7 @@ public class WorldRenderer {
|
||||
}
|
||||
}
|
||||
synchronized (faces) {
|
||||
faces.put(position, modelLoader.getBlockDescription(block).prepare(adjacentBlocks));
|
||||
faces.put(position, modelLoader.prepare(block, adjacentBlocks));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -71,8 +71,10 @@ 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
|
||||
controller.onGround = true;
|
||||
|
||||
if (deltaY < 0) {
|
||||
controller.onGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void zAxisCollision() {
|
||||
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user