replace magic chunk numbers with constants

This commit is contained in:
Bixilon 2020-09-30 19:04:54 +02:00
parent ae139f0ca0
commit 340a154ca9
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 100 additions and 130 deletions

View File

@ -73,7 +73,7 @@ public class Block {
out.append("rotation="); out.append("rotation=");
out.append(getRotation()); out.append(getRotation());
} }
if (properties.size() > 0) { if (!properties.isEmpty()) {
if (out.length() > 0) { if (out.length() > 0) {
out.append(", "); out.append(", ");
} else { } else {
@ -91,7 +91,7 @@ public class Block {
@Override @Override
public int hashCode() { public int hashCode() {
int ret = mod.hashCode() * identifier.hashCode() * rotation.hashCode(); int ret = mod.hashCode() * identifier.hashCode() * rotation.hashCode();
if (properties.size() > 0) { if (!properties.isEmpty()) {
ret *= properties.hashCode(); ret *= properties.hashCode();
} }
return ret; return ret;

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.game.datatypes.world; package de.bixilon.minosoft.game.datatypes.world;
import de.bixilon.minosoft.render.blockModels.Face.RenderConstants;
import de.bixilon.minosoft.render.utility.Vec3; import de.bixilon.minosoft.render.utility.Vec3;
public class BlockPosition { public class BlockPosition {
@ -21,7 +22,6 @@ public class BlockPosition {
final int z; final int z;
public BlockPosition(int x, int y, int z) { public BlockPosition(int x, int y, int z) {
// y min -2048, max 2047
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -34,9 +34,9 @@ public class BlockPosition {
} }
public BlockPosition(ChunkLocation chunkLocation, Byte height, ChunkNibbleLocation nibbleLocation) { public BlockPosition(ChunkLocation chunkLocation, Byte height, ChunkNibbleLocation nibbleLocation) {
this.x = chunkLocation.getX() * 16 + nibbleLocation.getX(); this.x = chunkLocation.getX() * RenderConstants.SECTION_WIDTH + nibbleLocation.getX();
this.y = height * 16 + nibbleLocation.getY(); this.y = height * RenderConstants.SECTION_HEIGHT + nibbleLocation.getY();
this.z = chunkLocation.getZ() * 16 + nibbleLocation.getZ(); this.z = chunkLocation.getZ() * RenderConstants.SECTION_WIDTH + nibbleLocation.getZ();
} }
public int getX() { public int getX() {
@ -61,8 +61,8 @@ public class BlockPosition {
} }
public ChunkLocation getChunkLocation() { public ChunkLocation getChunkLocation() {
int x = getX() / 16; int x = getX() / RenderConstants.SECTION_WIDTH;
int z = getZ() / 16; int z = getZ() / RenderConstants.SECTION_WIDTH;
//ToDo //ToDo
if (getX() < 0) { if (getX() < 0) {
x--; x--;
@ -84,13 +84,13 @@ public class BlockPosition {
} }
public InChunkLocation getInChunkLocation() { public InChunkLocation getInChunkLocation() {
int x = getX() % 16; int x = getX() % RenderConstants.SECTION_WIDTH;
if (x < 0) { if (x < 0) {
x = 16 + x; x += RenderConstants.SECTION_WIDTH;
} }
int z = getZ() % 16; int z = getZ() % RenderConstants.SECTION_WIDTH;
if (z < 0) { if (z < 0) {
z = 16 + z; z += RenderConstants.SECTION_WIDTH;
} }
return new InChunkLocation(x, getY(), z); return new InChunkLocation(x, getY(), z);
} }

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.game.datatypes.world; package de.bixilon.minosoft.game.datatypes.world;
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block; import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks; import de.bixilon.minosoft.render.blockModels.Face.RenderConstants;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -31,14 +31,8 @@ public class Chunk {
} }
public Block getBlock(int x, int y, int z) { public Block getBlock(int x, int y, int z) {
if (x > 15 || y > 255 || z > 15 || x < 0 || y < 0 || z < 0) { byte section = (byte) (y / RenderConstants.SECTION_HEIGHT);
throw new IllegalArgumentException(String.format("Invalid chunk location %s %s %s", x, y, z)); return nibbles.get(section).getBlock(x, y % RenderConstants.SECTION_HEIGHT, z);
}
byte section = (byte) (y / 16);
if (nibbles.get(section) == null) {
return Blocks.nullBlock;
}
return nibbles.get(section).getBlock(x, y % 16, z);
} }
public Block getBlock(InChunkLocation location) { public Block getBlock(InChunkLocation location) {
@ -46,20 +40,19 @@ public class Chunk {
} }
public void setBlock(int x, int y, int z, Block block) { public void setBlock(int x, int y, int z, Block block) {
byte section = (byte) (y / 16); byte section = (byte) (y / RenderConstants.SECTION_HEIGHT);
createSectionIfNotExist(section); createSectionIfNotExist(section);
nibbles.get(section).setBlock(x, y % 16, z, block); nibbles.get(section).setBlock(x, y % RenderConstants.SECTION_HEIGHT, z, block);
} }
public void setBlock(InChunkLocation location, Block block) { public void setBlock(InChunkLocation location, Block block) {
byte section = (byte) (location.getY() / 16); byte section = (byte) (location.getY() / RenderConstants.SECTION_HEIGHT);
createSectionIfNotExist(section); createSectionIfNotExist(section);
nibbles.get(section).setBlock(location.getChunkNibbleLocation(), block); nibbles.get(section).setBlock(location.getChunkNibbleLocation(), block);
} }
void createSectionIfNotExist(byte section) { void createSectionIfNotExist(byte section) {
if (nibbles.get(section) == null) { if (nibbles.get(section) == null) {
// nibble was empty before, creating it
nibbles.put(section, new ChunkNibble()); nibbles.put(section, new ChunkNibble());
} }
} }

View File

@ -13,21 +13,14 @@
package de.bixilon.minosoft.game.datatypes.world; package de.bixilon.minosoft.game.datatypes.world;
/** import de.bixilon.minosoft.render.blockModels.Face.RenderConstants;
* Chunk X, Y and Z location (max 16x16x16)
*/
public class InChunkLocation { public class InChunkLocation {
final int x; final int x;
final int y; final int y;
final int z; final int z;
public InChunkLocation(int x, int y, int z) { public InChunkLocation(int x, int y, int z) {
// x 0 - 16
// y 0 - 255
// z 0 - 16
if (x > 15 || y > 255 || z > 15 || x < 0 || y < 0 || z < 0) {
throw new IllegalArgumentException(String.format("Invalid chunk location %s %s %s", x, y, z));
}
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -55,7 +48,7 @@ public class InChunkLocation {
} }
public ChunkNibbleLocation getChunkNibbleLocation() { public ChunkNibbleLocation getChunkNibbleLocation() {
return new ChunkNibbleLocation(getX(), getY() % 16, getZ()); return new ChunkNibbleLocation(getX(), getY() % RenderConstants.SECTION_HEIGHT, getZ());
} }
@Override @Override

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.game.datatypes.world.*;
import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.render.blockModels.Face.Face; import de.bixilon.minosoft.render.blockModels.Face.Face;
import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation; import de.bixilon.minosoft.render.blockModels.Face.FaceOrientation;
import de.bixilon.minosoft.render.blockModels.Face.RenderConstants;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -102,9 +103,9 @@ public class WorldRenderer {
for (FaceOrientation orientation : FaceOrientation.values()) { for (FaceOrientation orientation : FaceOrientation.values()) {
Block dependedBlock = switch (orientation) { Block dependedBlock = switch (orientation) {
case DOWN -> { case DOWN -> {
if (location.getY() == 0) { if (location.getY() == RenderConstants.SECTIONS_MIN_Y) {
// need to check upper section (nibble) // need to check upper section (nibble)
if (sectionHeight == 0) { if (sectionHeight == RenderConstants.SECTIONS_MIN_Y) {
// y = 0, there can't be any blocks below me // y = 0, there can't be any blocks below me
yield null; yield null;
} }
@ -113,14 +114,14 @@ public class WorldRenderer {
if (!world.get(chunkLocation).getNibbles().containsKey(bottomSection)) { if (!world.get(chunkLocation).getNibbles().containsKey(bottomSection)) {
yield null; yield null;
} }
yield world.get(chunkLocation).getNibbles().get(bottomSection).getBlock(location.getX(), 15, location.getZ()); yield world.get(chunkLocation).getNibbles().get(bottomSection).getBlock(location.getX(), RenderConstants.SECTIONS_MAX_Y, location.getZ());
} }
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() - 1, location.getZ())); yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() - 1, location.getZ()));
} }
case UP -> { case UP -> {
if (location.getY() == 15) { if (location.getY() == RenderConstants.SECTIONS_MAX_Y) {
// need to check upper section (nibble) // need to check upper section (nibble)
if (sectionHeight == 15) { if (sectionHeight == RenderConstants.SECTIONS_MAX_Y) {
// y = 255, there can't be any blocks above me // y = 255, there can't be any blocks above me
yield null; yield null;
} }
@ -129,42 +130,42 @@ public class WorldRenderer {
if (!world.get(chunkLocation).getNibbles().containsKey(upperSection)) { if (!world.get(chunkLocation).getNibbles().containsKey(upperSection)) {
yield null; yield null;
} }
yield world.get(chunkLocation).getNibbles().get(upperSection).getBlock(location.getX(), 0, location.getZ()); yield world.get(chunkLocation).getNibbles().get(upperSection).getBlock(location.getX(), RenderConstants.SECTIONS_MIN_Y, location.getZ());
} }
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() + 1, location.getZ())); yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() + 1, location.getZ()));
} }
case WEST -> { case WEST -> {
if (location.getX() == 0) { if (location.getX() == RenderConstants.SECTIONS_MIN_X) {
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() - 1, chunkLocation.getZ()), sectionHeight); ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() - 1, chunkLocation.getZ()), sectionHeight);
if (otherChunkNibble != null) { if (otherChunkNibble != null) {
yield otherChunkNibble.getBlock(15, location.getY(), location.getZ()); yield otherChunkNibble.getBlock(RenderConstants.SECTIONS_MAX_X, location.getY(), location.getZ());
} }
} }
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() - 1, location.getY(), location.getZ())); yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() - 1, location.getY(), location.getZ()));
} }
case EAST -> { case EAST -> {
if (location.getX() == 15) { if (location.getX() == RenderConstants.SECTIONS_MIN_X) {
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() + 1, chunkLocation.getZ()), sectionHeight); ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() + 1, chunkLocation.getZ()), sectionHeight);
if (otherChunkNibble != null) { if (otherChunkNibble != null) {
yield otherChunkNibble.getBlock(0, location.getY(), location.getZ()); yield otherChunkNibble.getBlock(RenderConstants.SECTIONS_MAX_X, location.getY(), location.getZ());
} }
} }
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() + 1, location.getY(), location.getZ())); yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() + 1, location.getY(), location.getZ()));
} }
case NORTH -> { case NORTH -> {
if (location.getZ() == 0) { if (location.getZ() == RenderConstants.SECTIONS_MIN_Z) {
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() - 1), sectionHeight); ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() - 1), sectionHeight);
if (otherChunkNibble != null) { if (otherChunkNibble != null) {
yield otherChunkNibble.getBlock(location.getX(), location.getY(), 15); yield otherChunkNibble.getBlock(location.getX(), location.getY(), RenderConstants.SECTIONS_MAX_Z);
} }
} }
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() - 1)); yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() - 1));
} }
case SOUTH -> { case SOUTH -> {
if (location.getZ() == 15) { if (location.getZ() == RenderConstants.SECTIONS_MAX_Z) {
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() + 1), sectionHeight); ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() + 1), sectionHeight);
if (otherChunkNibble != null) { if (otherChunkNibble != null) {
yield otherChunkNibble.getBlock(location.getX(), location.getY(), 0); yield otherChunkNibble.getBlock(location.getX(), location.getY(), RenderConstants.SECTIONS_MIN_Z);
} }
} }
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() + 1)); yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() + 1));
@ -174,7 +175,7 @@ public class WorldRenderer {
facesToDraw.add(orientation); facesToDraw.add(orientation);
} }
} }
if (facesToDraw.size() > 0) { if (!facesToDraw.isEmpty()) {
nibbleMap.put(location, assetsLoader.getBlockModelLoader().prepare(block, facesToDraw)); nibbleMap.put(location, assetsLoader.getBlockModelLoader().prepare(block, facesToDraw));
} }
@ -190,54 +191,30 @@ public class WorldRenderer {
for (FaceOrientation orientation : FaceOrientation.values()) { for (FaceOrientation orientation : FaceOrientation.values()) {
Block dependedBlock = switch (orientation) { Block dependedBlock = switch (orientation) {
case DOWN -> { case DOWN -> {
if (position.getY() == 0) { if (position.getY() == RenderConstants.CHUNK_MIN_Y) {
facesToDraw.add(orientation); facesToDraw.add(orientation);
yield null; yield null;
} }
yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY() - 1, position.getZ())); yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY() - 1, position.getZ()));
} }
case UP -> { case UP -> {
if (position.getY() == 255) { if (position.getY() == RenderConstants.CHUNK_MAX_Y) {
facesToDraw.add(orientation); facesToDraw.add(orientation);
yield null; yield null;
} }
yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY() + 1, position.getZ())); yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY() + 1, position.getZ()));
} }
case NORTH -> { case NORTH -> GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY(), position.getZ() - 1));
if (position.getY() == 255) { case SOUTH -> GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY(), position.getZ() + 1));
facesToDraw.add(orientation); case WEST -> GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX() - 1, position.getY(), position.getZ()));
yield null; case EAST -> GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX() + 1, position.getY(), position.getZ()));
}
yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY(), position.getZ() - 1));
}
case SOUTH -> {
if (position.getY() == 255) {
facesToDraw.add(orientation);
yield null;
}
yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX(), position.getY(), position.getZ() + 1));
}
case WEST -> {
if (position.getY() == 255) {
facesToDraw.add(orientation);
yield null;
}
yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX() - 1, position.getY(), position.getZ()));
}
case EAST -> {
if (position.getY() == 255) {
facesToDraw.add(orientation);
yield null;
}
yield GameWindow.getConnection().getPlayer().getWorld().getBlock(new BlockPosition(position.getX() + 1, position.getY(), position.getZ()));
}
}; };
if (dependedBlock == null || !assetsLoader.getBlockModelLoader().isFull(dependedBlock)) { if (dependedBlock == null || !assetsLoader.getBlockModelLoader().isFull(dependedBlock)) {
facesToDraw.add(orientation); facesToDraw.add(orientation);
} }
} }
} }
ConcurrentHashMap<ChunkNibbleLocation, HashSet<Face>> nibbleMap = faces.get(position.getChunkLocation()).get((byte) (position.getY() / 16)); ConcurrentHashMap<ChunkNibbleLocation, HashSet<Face>> nibbleMap = faces.get(position.getChunkLocation()).get((byte) (position.getY() / RenderConstants.SECTION_HEIGHT));
if (facesToDraw.size() == 0) { if (facesToDraw.size() == 0) {
// remove all faces // remove all faces
nibbleMap.remove(position.getInChunkLocation().getChunkNibbleLocation()); nibbleMap.remove(position.getInChunkLocation().getChunkNibbleLocation());
@ -248,11 +225,11 @@ public class WorldRenderer {
if (trustEdges) { if (trustEdges) {
return; return;
} }
if (position.getY() != 0) { if (position.getY() != RenderConstants.CHUNK_MIN_Y) {
// bottom // bottom
prepareBlock(new BlockPosition(position.getX(), position.getY() - 1, position.getZ()), true); prepareBlock(new BlockPosition(position.getX(), position.getY() - 1, position.getZ()), true);
} }
if (position.getY() != 255) { if (position.getY() != RenderConstants.CHUNK_MAX_Y) {
// bottom // bottom
prepareBlock(new BlockPosition(position.getX(), position.getY() + 1, position.getZ()), true); prepareBlock(new BlockPosition(position.getX(), position.getY() + 1, position.getZ()), true);
} }

View File

@ -14,13 +14,24 @@
package de.bixilon.minosoft.render.blockModels.Face; package de.bixilon.minosoft.render.blockModels.Face;
public class RenderConstants { public class RenderConstants {
public static final int TEXTURE_PACK_RES = 16; public static final int TEXTURE_PACK_RESOLUTION = 16;
public static final int BLOCK_RESOLUTION = 16;
public static final int texturePackRes = 16; public static final byte SECTION_HEIGHT = 16;
public static final byte SECTION_WIDTH = 16;
public static final byte SECTIONS_PER_CHUNK = 16;
public static final int blockRes = 16; public static final byte SECTIONS_MIN_X = 0;
public static final byte SECTIONS_MIN_Y = 0;
public static final byte SECTIONS_MIN_Z = 0;
public static final byte SECTIONS_MAX_X = SECTION_WIDTH - 1;
public static final byte SECTIONS_MAX_Y = SECTION_HEIGHT - 1;
public static final byte SECTIONS_MAX_Z = SECTION_WIDTH - 1;
public static final int[][] faceDir = new int[][]{ public static final byte CHUNK_MIN_Y = 0;
public static final int CHUNK_MAX_Y = SECTION_HEIGHT * SECTIONS_PER_CHUNK - 1;
public static final int[][] FACE_DIRECTIONS = new int[][]{
{1, 0, 0}, {1, 0, 0},
{-1, 0, 0}, {-1, 0, 0},
{0, 1, 0}, {0, 1, 0},

View File

@ -17,27 +17,23 @@ import com.google.gson.JsonArray;
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block; import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition; import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.render.blockModels.Face.Axis; import de.bixilon.minosoft.render.blockModels.Face.Axis;
import de.bixilon.minosoft.render.blockModels.Face.RenderConstants;
import static de.bixilon.minosoft.render.blockModels.Face.RenderConstants.blockRes;
import static org.lwjgl.opengl.GL11.glVertex3f; import static org.lwjgl.opengl.GL11.glVertex3f;
public class SubBlockPosition { public class SubBlockPosition {
public float x;
public float y;
public float z;
private static final SubBlockPosition middlePos = new SubBlockPosition(8, 8, 8); private static final SubBlockPosition middlePos = new SubBlockPosition(8, 8, 8);
private static final SubBlockRotation westRotator = new SubBlockRotation(middlePos, Axis.Y, 90); private static final SubBlockRotation westRotator = new SubBlockRotation(middlePos, Axis.Y, 90);
private static final SubBlockRotation eastRotator = new SubBlockRotation(middlePos, Axis.Y, 270); private static final SubBlockRotation eastRotator = new SubBlockRotation(middlePos, Axis.Y, 270);
private static final SubBlockRotation southRotator = new SubBlockRotation(middlePos, Axis.Y, 180); private static final SubBlockRotation southRotator = new SubBlockRotation(middlePos, Axis.Y, 180);
private static final SubBlockRotation xAxisRotator = new SubBlockRotation(middlePos, Axis.Z, 90); private static final SubBlockRotation xAxisRotator = new SubBlockRotation(middlePos, Axis.Z, 90);
private static final SubBlockRotation zAxisRotator = new SubBlockRotation(middlePos, Axis.X, 90); private static final SubBlockRotation zAxisRotator = new SubBlockRotation(middlePos, Axis.X, 90);
private static final SubBlockRotation downRotator = new SubBlockRotation(middlePos, Axis.X, 90); private static final SubBlockRotation downRotator = new SubBlockRotation(middlePos, Axis.X, 90);
private static final SubBlockRotation downAltRotator = new SubBlockRotation(middlePos, Axis.X, 180); private static final SubBlockRotation downAltRotator = new SubBlockRotation(middlePos, Axis.X, 180);
private static final SubBlockRotation upRotator = new SubBlockRotation(middlePos, Axis.X, -90); private static final SubBlockRotation upRotator = new SubBlockRotation(middlePos, Axis.X, -90);
public float x;
public float y;
public float z;
public SubBlockPosition(JsonArray json) { public SubBlockPosition(JsonArray json) {
@ -67,10 +63,9 @@ public class SubBlockPosition {
} }
public void draw(BlockPosition pos) { public void draw(BlockPosition pos) {
glVertex3f( glVertex3f(pos.getX() + x / RenderConstants.BLOCK_RESOLUTION,
pos.getX() + x / blockRes, pos.getY() + y / RenderConstants.BLOCK_RESOLUTION,
pos.getY() + y / blockRes, pos.getZ() + z / RenderConstants.BLOCK_RESOLUTION);
pos.getZ() + z / blockRes);
} }
public SubBlockPosition rotated(Block block) { public SubBlockPosition rotated(Block block) {

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.render.texture;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import de.bixilon.minosoft.render.GameWindow; import de.bixilon.minosoft.render.GameWindow;
import static de.bixilon.minosoft.render.blockModels.Face.RenderConstants.texturePackRes; import static de.bixilon.minosoft.render.blockModels.Face.RenderConstants.TEXTURE_PACK_RESOLUTION;
import static org.lwjgl.opengl.GL11.glTexCoord2f; import static org.lwjgl.opengl.GL11.glTexCoord2f;
public class InFaceUV { public class InFaceUV {
@ -38,11 +38,11 @@ public class InFaceUV {
public void prepare(float texture) { public void prepare(float texture) {
realU1 = texture + u1 * GameWindow.getRenderer().getAssetsLoader().getTextureLoader().getStep() realU1 = texture + u1 * GameWindow.getRenderer().getAssetsLoader().getTextureLoader().getStep()
/ texturePackRes; / TEXTURE_PACK_RESOLUTION;
realU2 = texture + u2 * GameWindow.getRenderer().getAssetsLoader().getTextureLoader().getStep() realU2 = texture + u2 * GameWindow.getRenderer().getAssetsLoader().getTextureLoader().getStep()
/ texturePackRes; / TEXTURE_PACK_RESOLUTION;
realV1 = (float) v1 / texturePackRes; realV1 = (float) v1 / TEXTURE_PACK_RESOLUTION;
realV2 = (float) v2 / texturePackRes; realV2 = (float) v2 / TEXTURE_PACK_RESOLUTION;
} }
public void draw(int i) { public void draw(int i) {

View File

@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import static de.bixilon.minosoft.render.blockModels.Face.RenderConstants.TEXTURE_PACK_RES; import static de.bixilon.minosoft.render.blockModels.Face.RenderConstants.TEXTURE_PACK_RESOLUTION;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL30.glGenerateMipmap; import static org.lwjgl.opengl.GL30.glGenerateMipmap;
@ -36,7 +36,7 @@ public class TextureLoader {
private int textureID; private int textureID;
private float step; private float step;
private int totalTextures = 0; private int totalTextures = 0;
private HashMap<String, HashMap<String, BufferedImage>> images; private final HashMap<String, HashMap<String, BufferedImage>> images;
public TextureLoader(HashMap<String, HashSet<String>> textures, HashMap<String, HashMap<String, float[]>> tints) { public TextureLoader(HashMap<String, HashSet<String>> textures, HashMap<String, HashMap<String, float[]>> tints) {
textureCoordinates = new HashMap<>(); textureCoordinates = new HashMap<>();
@ -99,20 +99,20 @@ public class TextureLoader {
// greatly improves performance in opengl // greatly improves performance in opengl
// TEXTURE_PACK_RESxTEXTURE_PACK_RES textures only // TEXTURE_PACK_RESxTEXTURE_PACK_RES textures only
int imageLength = 1; int imageLength = 1;
while (totalTextures * TEXTURE_PACK_RES > imageLength) { while (totalTextures * TEXTURE_PACK_RESOLUTION > imageLength) {
imageLength *= 2; //figure out the right length for the image imageLength *= 2; //figure out the right length for the image
} }
BufferedImage totalImage = new BufferedImage(imageLength, TEXTURE_PACK_RES, BufferedImage totalImage = new BufferedImage(imageLength, TEXTURE_PACK_RESOLUTION,
BufferedImage.TYPE_4BYTE_ABGR); BufferedImage.TYPE_4BYTE_ABGR);
int currentPos = 0; int currentPos = 0;
for (Map.Entry<String, HashMap<String, BufferedImage>> mod : images.entrySet()) { for (Map.Entry<String, HashMap<String, BufferedImage>> mod : images.entrySet()) {
HashMap<String, Integer> modMap = new HashMap<>(); HashMap<String, Integer> modMap = new HashMap<>();
for (Map.Entry<String, BufferedImage> texture : mod.getValue().entrySet()) { for (Map.Entry<String, BufferedImage> texture : mod.getValue().entrySet()) {
for (int y = 0; y < TEXTURE_PACK_RES; y++) { for (int y = 0; y < TEXTURE_PACK_RESOLUTION; y++) {
for (int xPixel = 0; xPixel < TEXTURE_PACK_RES; xPixel++) { for (int xPixel = 0; xPixel < TEXTURE_PACK_RESOLUTION; xPixel++) {
int rgb = texture.getValue().getRGB(xPixel, y); int rgb = texture.getValue().getRGB(xPixel, y);
totalImage.setRGB(currentPos * TEXTURE_PACK_RES + xPixel, y, rgb); totalImage.setRGB(currentPos * TEXTURE_PACK_RESOLUTION + xPixel, y, rgb);
} }
} }
modMap.put(texture.getKey(), currentPos++); modMap.put(texture.getKey(), currentPos++);
@ -126,7 +126,7 @@ public class TextureLoader {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
step = (float) 1 / (float) imageLength * TEXTURE_PACK_RES; step = (float) 1 / (float) imageLength * TEXTURE_PACK_RESOLUTION;
} }
private int bindTexture(ByteBuffer buf, int width, int height) { private int bindTexture(ByteBuffer buf, int width, int height) {

View File

@ -22,6 +22,7 @@ import de.bixilon.minosoft.game.datatypes.world.palette.Palette;
import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer; import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition; import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.render.blockModels.Face.RenderConstants;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -34,7 +35,7 @@ public final class ChunkUtil {
} }
//chunk //chunk
byte sections = BitByte.getBitCount(sectionBitMask); byte sections = BitByte.getBitCount(sectionBitMask);
int totalBytes = 4096 * sections; // 16 * 16 * 16 * sections; Section Width * Section Height * Section Width * sections int totalBytes = RenderConstants.SECTION_HEIGHT * RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH * sections;
int halfBytes = totalBytes / 2; // half bytes int halfBytes = totalBytes / 2; // half bytes
byte[] blockTypes = buffer.readBytes(totalBytes); byte[] blockTypes = buffer.readBytes(totalBytes);
@ -44,22 +45,22 @@ public final class ChunkUtil {
if (containsSkyLight) { if (containsSkyLight) {
skyLight = buffer.readBytes(halfBytes); skyLight = buffer.readBytes(halfBytes);
} }
byte[] addBlockTypes = buffer.readBytes(Integer.bitCount(addBitMask) * 2048); // 16 * 16 * 16 * addBlocks / 2 byte[] addBlockTypes = buffer.readBytes(Integer.bitCount(addBitMask) * RenderConstants.SECTION_HEIGHT * RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH / 2); // 16 * 16 * 16 * addBlocks / 2
if (groundUpContinuous) { if (groundUpContinuous) {
byte[] biomes = buffer.readBytes(256); byte[] biomes = buffer.readBytes(RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH);
} }
//parse data //parse data
int arrayPos = 0; int arrayPos = 0;
ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>(); ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>();
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column for (byte c = 0; c < RenderConstants.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
if (BitByte.isBitSet(sectionBitMask, c)) { if (BitByte.isBitSet(sectionBitMask, c)) {
ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>(); ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>();
for (int nibbleY = 0; nibbleY < 16; nibbleY++) { for (int nibbleY = 0; nibbleY < RenderConstants.SECTION_HEIGHT; nibbleY++) {
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) { for (int nibbleZ = 0; nibbleZ < RenderConstants.SECTION_WIDTH; nibbleZ++) {
for (int nibbleX = 0; nibbleX < 16; nibbleX++) { for (int nibbleX = 0; nibbleX < RenderConstants.SECTION_WIDTH; nibbleX++) {
short singeBlockId = (short) (blockTypes[arrayPos] & 0xFF); short singeBlockId = (short) (blockTypes[arrayPos] & 0xFF);
byte singleMeta; byte singleMeta;
@ -99,7 +100,7 @@ public final class ChunkUtil {
return null; return null;
} }
byte sections = BitByte.getBitCount(sectionBitMask); byte sections = BitByte.getBitCount(sectionBitMask);
int totalBlocks = 4096 * sections; // 16 * 16 * 16 * sections; Section Width * Section Height * Section Width * sections int totalBlocks = RenderConstants.SECTION_HEIGHT * RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH * sections;
int halfBytes = totalBlocks / 2; // half bytes int halfBytes = totalBlocks / 2; // half bytes
short[] blockData = buffer.readLEShorts(totalBlocks); // blocks >>> 4, data & 0xF short[] blockData = buffer.readLEShorts(totalBlocks); // blocks >>> 4, data & 0xF
@ -111,20 +112,20 @@ public final class ChunkUtil {
} }
if (groundUpContinuous) { if (groundUpContinuous) {
byte[] biomes = buffer.readBytes(256); byte[] biomes = buffer.readBytes(RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH);
} }
int arrayPos = 0; int arrayPos = 0;
ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>(); ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>();
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column for (byte c = 0; c < RenderConstants.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
if (!BitByte.isBitSet(sectionBitMask, c)) { if (!BitByte.isBitSet(sectionBitMask, c)) {
continue; continue;
} }
ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>(); ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>();
for (int nibbleY = 0; nibbleY < 16; nibbleY++) { for (int nibbleY = 0; nibbleY < RenderConstants.SECTION_HEIGHT; nibbleY++) {
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) { for (int nibbleZ = 0; nibbleZ < RenderConstants.SECTION_WIDTH; nibbleZ++) {
for (int nibbleX = 0; nibbleX < 16; nibbleX++) { for (int nibbleX = 0; nibbleX < RenderConstants.SECTION_WIDTH; nibbleX++) {
int blockId = blockData[arrayPos] & 0xFFFF; int blockId = blockData[arrayPos] & 0xFFFF;
Block block = buffer.getConnection().getMapping().getBlockById(blockId); Block block = buffer.getConnection().getMapping().getBlockById(blockId);
if (block.equals(Blocks.nullBlock)) { if (block.equals(Blocks.nullBlock)) {
@ -142,7 +143,7 @@ public final class ChunkUtil {
} }
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712 // really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>(); ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>();
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column for (byte c = 0; c < RenderConstants.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
if (!BitByte.isBitSet(sectionBitMask, c)) { if (!BitByte.isBitSet(sectionBitMask, c)) {
continue; continue;
} }
@ -156,9 +157,9 @@ public final class ChunkUtil {
long[] data = buffer.readLongArray(buffer.readVarInt()); long[] data = buffer.readLongArray(buffer.readVarInt());
ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>(); ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>();
for (int nibbleY = 0; nibbleY < 16; nibbleY++) { for (int nibbleY = 0; nibbleY < RenderConstants.SECTION_HEIGHT; nibbleY++) {
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) { for (int nibbleZ = 0; nibbleZ < RenderConstants.SECTION_WIDTH; nibbleZ++) {
for (int nibbleX = 0; nibbleX < 16; nibbleX++) { for (int nibbleX = 0; nibbleX < RenderConstants.SECTION_WIDTH; nibbleX++) {
int blockNumber = (((nibbleY * 16) + nibbleZ) * 16) + nibbleX; int blockNumber = (((nibbleY * 16) + nibbleZ) * 16) + nibbleX;
int startLong = (blockNumber * palette.getBitsPerBlock()) / 64; int startLong = (blockNumber * palette.getBitsPerBlock()) / 64;
@ -203,7 +204,7 @@ public final class ChunkUtil {
nibbleMap.put(c, new ChunkNibble(blockMap)); nibbleMap.put(c, new ChunkNibble(blockMap));
} }
if (buffer.getProtocolId() < 552) { if (buffer.getProtocolId() < 552) {
byte[] biomes = buffer.readBytes(256); byte[] biomes = buffer.readBytes(RenderConstants.SECTION_WIDTH * RenderConstants.SECTION_WIDTH);
} }
return new Chunk(nibbleMap); return new Chunk(nibbleMap);
} }