mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
rendering: improve face preparation, fix some bugs in world rendering/handling
This commit is contained in:
parent
1d3b09c856
commit
b41a7b3694
@ -63,6 +63,7 @@ public class BlockPosition {
|
||||
public ChunkLocation getChunkLocation() {
|
||||
int x = getX() / 16;
|
||||
int z = getZ() / 16;
|
||||
//ToDo
|
||||
if (getX() < 0) {
|
||||
x--;
|
||||
}
|
||||
|
@ -18,14 +18,15 @@ import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Collection of 16 chunks nibbles
|
||||
*/
|
||||
public class Chunk {
|
||||
final HashMap<Byte, ChunkNibble> nibbles;
|
||||
final ConcurrentHashMap<Byte, ChunkNibble> nibbles;
|
||||
|
||||
public Chunk(HashMap<Byte, ChunkNibble> chunks) {
|
||||
public Chunk(ConcurrentHashMap<Byte, ChunkNibble> chunks) {
|
||||
this.nibbles = chunks;
|
||||
}
|
||||
|
||||
@ -46,17 +47,17 @@ public class Chunk {
|
||||
|
||||
public void setBlock(int x, int y, int z, Block block) {
|
||||
byte section = (byte) (y / 16);
|
||||
createSection(section);
|
||||
createSectionIfNotExist(section);
|
||||
nibbles.get(section).setBlock(x, y % 16, z, block);
|
||||
}
|
||||
|
||||
public void setBlock(InChunkLocation location, Block block) {
|
||||
byte section = (byte) (location.getY() / 16);
|
||||
createSection(section);
|
||||
createSectionIfNotExist(section);
|
||||
nibbles.get(section).setBlock(location.getChunkNibbleLocation(), block);
|
||||
}
|
||||
|
||||
void createSection(byte section) {
|
||||
void createSectionIfNotExist(byte section) {
|
||||
if (nibbles.get(section) == null) {
|
||||
// nibble was empty before, creating it
|
||||
nibbles.put(section, new ChunkNibble());
|
||||
@ -69,7 +70,7 @@ public class Chunk {
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<Byte, ChunkNibble> getNibbles() {
|
||||
public ConcurrentHashMap<Byte, ChunkNibble> getNibbles() {
|
||||
return nibbles;
|
||||
}
|
||||
}
|
||||
|
@ -14,25 +14,29 @@
|
||||
package de.bixilon.minosoft.game.datatypes.world;
|
||||
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Collection of 16x16x16 blocks
|
||||
*/
|
||||
public class ChunkNibble {
|
||||
final HashMap<ChunkNibbleLocation, Block> blocks;
|
||||
final ConcurrentHashMap<ChunkNibbleLocation, Block> blocks;
|
||||
|
||||
public ChunkNibble(HashMap<ChunkNibbleLocation, Block> blocks) {
|
||||
public ChunkNibble(ConcurrentHashMap<ChunkNibbleLocation, Block> blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public ChunkNibble() {
|
||||
// empty
|
||||
this.blocks = new HashMap<>();
|
||||
this.blocks = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public Block getBlock(ChunkNibbleLocation loc) {
|
||||
if (!blocks.containsKey(loc)) {
|
||||
return null;
|
||||
}
|
||||
return blocks.get(loc);
|
||||
}
|
||||
|
||||
@ -41,14 +45,18 @@ public class ChunkNibble {
|
||||
}
|
||||
|
||||
public void setBlock(int x, int y, int z, Block block) {
|
||||
blocks.put(new ChunkNibbleLocation(x, y, z), block);
|
||||
setBlock(new ChunkNibbleLocation(x, y, z), block);
|
||||
}
|
||||
|
||||
public void setBlock(ChunkNibbleLocation location, Block block) {
|
||||
if (block == null || block.equals(Blocks.nullBlock)) {
|
||||
blocks.remove(location);
|
||||
return;
|
||||
}
|
||||
blocks.put(location, block);
|
||||
}
|
||||
|
||||
public HashMap<ChunkNibbleLocation, Block> getBlocks() {
|
||||
public ConcurrentHashMap<ChunkNibbleLocation, Block> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
|
@ -17,20 +17,20 @@ import de.bixilon.minosoft.game.datatypes.entities.Entity;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks;
|
||||
import de.bixilon.minosoft.game.datatypes.objectLoader.dimensions.Dimension;
|
||||
import de.bixilon.minosoft.render.GameWindow;
|
||||
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Collection of ChunkColumns
|
||||
*/
|
||||
public class World {
|
||||
final HashMap<ChunkLocation, Chunk> chunks = new HashMap<>();
|
||||
final HashMap<Integer, Entity> entities = new HashMap<>();
|
||||
final ConcurrentHashMap<ChunkLocation, Chunk> chunks = new ConcurrentHashMap<>();
|
||||
final ConcurrentHashMap<Integer, Entity> entities = new ConcurrentHashMap<>();
|
||||
final String name;
|
||||
final HashMap<BlockPosition, CompoundTag> blockEntityMeta = new HashMap<>();
|
||||
final ConcurrentHashMap<BlockPosition, CompoundTag> blockEntityMeta = new ConcurrentHashMap<>();
|
||||
boolean hardcore;
|
||||
boolean raining;
|
||||
Dimension dimension; // used for sky color, etc
|
||||
@ -47,7 +47,7 @@ public class World {
|
||||
return chunks.get(loc);
|
||||
}
|
||||
|
||||
public HashMap<ChunkLocation, Chunk> getAllChunks() {
|
||||
public ConcurrentHashMap<ChunkLocation, Chunk> getAllChunks() {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ public class World {
|
||||
public void setBlock(BlockPosition pos, Block block) {
|
||||
if (getChunk(pos.getChunkLocation()) != null) {
|
||||
getChunk(pos.getChunkLocation()).setBlock(pos.getInChunkLocation(), block);
|
||||
GameWindow.getRenderer().prepareChunkNibble(pos.getChunkLocation(), (byte) (pos.getY() / 16), getChunk(pos.getChunkLocation()).getNibbles().get((byte) (pos.getY() / 16)));
|
||||
}
|
||||
// do nothing if chunk is unloaded
|
||||
}
|
||||
@ -76,14 +75,10 @@ public class World {
|
||||
|
||||
public void setChunk(ChunkLocation location, Chunk chunk) {
|
||||
chunks.put(location, chunk);
|
||||
GameWindow.getRenderer().queueChunk(location, chunk);
|
||||
}
|
||||
|
||||
public void setChunks(HashMap<ChunkLocation, Chunk> chunkMap) {
|
||||
for (Map.Entry<ChunkLocation, Chunk> set : chunkMap.entrySet()) {
|
||||
chunks.put(set.getKey(), set.getValue());
|
||||
}
|
||||
GameWindow.getRenderer().queueChunkBulk(chunkMap);
|
||||
chunkMap.forEach(chunks::put);
|
||||
}
|
||||
|
||||
public boolean isHardcore() {
|
||||
@ -135,7 +130,7 @@ public class World {
|
||||
return blockEntityMeta.get(position);
|
||||
}
|
||||
|
||||
public void setBlockEntityData(HashMap<BlockPosition, CompoundTag> blockEntities) {
|
||||
public void setBlockEntityData(ConcurrentHashMap<BlockPosition, CompoundTag> blockEntities) {
|
||||
for (Map.Entry<BlockPosition, CompoundTag> entrySet : blockEntities.entrySet()) {
|
||||
blockEntityMeta.put(entrySet.getKey(), entrySet.getValue());
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ import de.bixilon.minosoft.util.ChunkUtil;
|
||||
import de.bixilon.minosoft.util.Util;
|
||||
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class PacketChunkData implements ClientboundPacket {
|
||||
final HashMap<BlockPosition, CompoundTag> blockEntities = new HashMap<>();
|
||||
final ConcurrentHashMap<BlockPosition, CompoundTag> blockEntities = new ConcurrentHashMap<>();
|
||||
ChunkLocation location;
|
||||
Chunk chunk;
|
||||
CompoundTag heightMap;
|
||||
@ -122,7 +122,7 @@ public class PacketChunkData implements ClientboundPacket {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public HashMap<BlockPosition, CompoundTag> getBlockEntities() {
|
||||
public ConcurrentHashMap<BlockPosition, CompoundTag> getBlockEntities() {
|
||||
return blockEntities;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class PacketMultiBlockChange implements ClientboundPacket {
|
||||
byte pos = buffer.readByte();
|
||||
byte y = buffer.readByte();
|
||||
int blockId = buffer.readVarInt();
|
||||
blocks.put(new InChunkLocation((pos & 0xF0 >>> 4) & 0xF, y, pos & 0xF), buffer.getConnection().getMapping().getBlockById(blockId));
|
||||
blocks.put(new InChunkLocation((pos >>> 4) & 0xF, y, pos & 0xF), buffer.getConnection().getMapping().getBlockById(blockId));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import de.bixilon.minosoft.game.datatypes.scoreboard.ScoreboardScore;
|
||||
import de.bixilon.minosoft.game.datatypes.scoreboard.Team;
|
||||
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
|
||||
import de.bixilon.minosoft.game.datatypes.world.Chunk;
|
||||
import de.bixilon.minosoft.game.datatypes.world.ChunkLocation;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.network.Connection;
|
||||
import de.bixilon.minosoft.protocol.packets.clientbound.login.*;
|
||||
@ -38,10 +39,10 @@ import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusRespo
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketEncryptionResponse;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketKeepAliveResponse;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketResourcePackStatus;
|
||||
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
|
||||
import de.bixilon.minosoft.util.nbt.tag.StringTag;
|
||||
import de.bixilon.minosoft.render.GameWindow;
|
||||
import de.bixilon.minosoft.render.utility.Vec3;
|
||||
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
|
||||
import de.bixilon.minosoft.util.nbt.tag.StringTag;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.math.BigInteger;
|
||||
@ -172,6 +173,7 @@ public class PacketHandler {
|
||||
|
||||
public void handle(PacketChunkBulk pkg) {
|
||||
connection.getPlayer().getWorld().setChunks(pkg.getChunkMap());
|
||||
GameWindow.getRenderer().queueChunkBulk(pkg.getChunkMap());
|
||||
}
|
||||
|
||||
public void handle(PacketUpdateHealth pkg) {
|
||||
@ -288,7 +290,10 @@ public class PacketHandler {
|
||||
}
|
||||
|
||||
public void handle(PacketBlockChange pkg) {
|
||||
connection.getPlayer().getWorld().setBlock(pkg.getPosition(), pkg.getBlock());
|
||||
ChunkLocation chunkLocation = pkg.getPosition().getChunkLocation();
|
||||
Chunk chunk = connection.getPlayer().getWorld().getChunk(chunkLocation);
|
||||
chunk.setBlock(pkg.getPosition().getInChunkLocation(), pkg.getBlock());
|
||||
GameWindow.getRenderer().queueChunk(chunkLocation, chunk); // ToDo: only recalculate the changed nibbles
|
||||
}
|
||||
|
||||
public void handle(PacketMultiBlockChange pkg) {
|
||||
@ -298,6 +303,7 @@ public class PacketHandler {
|
||||
return;
|
||||
}
|
||||
chunk.setBlocks(pkg.getBlocks());
|
||||
GameWindow.getRenderer().queueChunk(pkg.getLocation(), chunk); // ToDo: only recalculate the changed nibbles
|
||||
}
|
||||
|
||||
public void handle(PacketRespawn pkg) {
|
||||
@ -328,6 +334,7 @@ public class PacketHandler {
|
||||
public void handle(PacketChunkData pkg) {
|
||||
connection.getPlayer().getWorld().setChunk(pkg.getLocation(), pkg.getChunk());
|
||||
connection.getPlayer().getWorld().setBlockEntityData(pkg.getBlockEntities());
|
||||
GameWindow.getRenderer().queueChunk(pkg.getLocation(), pkg.getChunk());
|
||||
}
|
||||
|
||||
public void handle(PacketEntityEffect pkg) {
|
||||
|
@ -22,8 +22,10 @@ import javafx.util.Pair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
@ -33,6 +35,11 @@ public class WorldRenderer {
|
||||
|
||||
private LinkedBlockingQueue<Pair<ChunkLocation, Chunk>> queuedChunks;
|
||||
|
||||
public int getCountOfFaces() {
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
faces.forEach((chunkLocation, nibbleMap) -> nibbleMap.forEach((height, faceMap) -> faceMap.forEach(((nibbleLocation, faces) -> faces.forEach((face -> count.incrementAndGet()))))));
|
||||
return count.get();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
queuedChunks = new LinkedBlockingQueue<>();
|
||||
@ -44,7 +51,8 @@ public class WorldRenderer {
|
||||
while (true) {
|
||||
try {
|
||||
Pair<ChunkLocation, Chunk> current = queuedChunks.take();
|
||||
prepareChunk(current.getKey(), current.getValue());
|
||||
prepareChunk(current.getKey(), current.getValue(), true);
|
||||
//Log.verbose(String.format("Count of faces: %d", getCountOfFaces()));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -62,52 +70,113 @@ public class WorldRenderer {
|
||||
queuedChunks.add(new Pair<>(location, chunk));
|
||||
}
|
||||
|
||||
public void prepareChunk(ChunkLocation location, Chunk chunk) {
|
||||
public void prepareChunk(ChunkLocation location, Chunk chunk, boolean checkEdges) {
|
||||
// clear or create current chunk
|
||||
faces.put(location, new ConcurrentHashMap<>());
|
||||
chunk.getNibbles().forEach(((height, chunkNibble) -> prepareChunkNibble(location, height, chunkNibble)));
|
||||
ConcurrentHashMap<Byte, ConcurrentHashMap<ChunkNibbleLocation, HashSet<Face>>> chunkFaces = new ConcurrentHashMap<>();
|
||||
chunk.getNibbles().forEach(((height, chunkNibble) -> chunkFaces.put(height, getFacesForChunkNibble(location, height, chunkNibble))));
|
||||
faces.put(location, chunkFaces);
|
||||
if (!checkEdges) {
|
||||
return;
|
||||
}
|
||||
//ToDo
|
||||
|
||||
}
|
||||
|
||||
public void prepareChunkNibble(ChunkLocation chunkLocation, byte height, ChunkNibble nibble) {
|
||||
public ConcurrentHashMap<ChunkNibbleLocation, HashSet<Face>> getFacesForChunkNibble(ChunkLocation chunkLocation, byte sectionHeight, ChunkNibble nibble) {
|
||||
ConcurrentHashMap<ChunkLocation, Chunk> world = GameWindow.getConnection().getPlayer().getWorld().getAllChunks();
|
||||
// clear or create current chunk nibble
|
||||
ConcurrentHashMap<ChunkNibbleLocation, HashSet<Face>> nibbleMap = new ConcurrentHashMap<>();
|
||||
faces.get(chunkLocation).put(height, nibbleMap);
|
||||
HashMap<ChunkNibbleLocation, Block> nibbleBlocks = nibble.getBlocks();
|
||||
nibbleBlocks.forEach((location, block) -> {
|
||||
ConcurrentHashMap<ChunkNibbleLocation, Block> nibbleBlocks = nibble.getBlocks();
|
||||
for (Map.Entry<ChunkNibbleLocation, Block> entry : nibbleBlocks.entrySet()) {
|
||||
ChunkNibbleLocation location = entry.getKey();
|
||||
Block block = entry.getValue();
|
||||
HashSet<FaceOrientation> facesToDraw = new HashSet<>();
|
||||
|
||||
for (FaceOrientation orientation : FaceOrientation.values()) {
|
||||
if ((location.getX() == 0 && orientation == FaceOrientation.WEST) || (location.getX() == 15 && orientation == FaceOrientation.EAST)) {
|
||||
facesToDraw.add(orientation);
|
||||
continue;
|
||||
Block dependedBlock = switch (orientation) {
|
||||
case DOWN -> {
|
||||
if (location.getY() == 0) {
|
||||
// need to check upper section (nibble)
|
||||
if (sectionHeight == 0) {
|
||||
// y = 0, there can't be any blocks below me
|
||||
yield null;
|
||||
}
|
||||
if ((location.getY() == 0 && orientation == FaceOrientation.DOWN) || (location.getY() == 15 && orientation == FaceOrientation.UP)) {
|
||||
facesToDraw.add(orientation);
|
||||
continue;
|
||||
// check if block over us is a full block
|
||||
byte bottomSection = (byte) (sectionHeight - 1);
|
||||
if (!world.get(chunkLocation).getNibbles().containsKey(bottomSection)) {
|
||||
yield null;
|
||||
}
|
||||
if ((location.getZ() == 0 && orientation == FaceOrientation.NORTH) || (location.getZ() == 15 && orientation == FaceOrientation.SOUTH)) {
|
||||
facesToDraw.add(orientation);
|
||||
continue;
|
||||
yield world.get(chunkLocation).getNibbles().get(bottomSection).getBlock(location.getX(), 15, location.getZ());
|
||||
}
|
||||
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() - 1, location.getZ()));
|
||||
}
|
||||
case UP -> {
|
||||
if (location.getY() == 15) {
|
||||
// need to check upper section (nibble)
|
||||
if (sectionHeight == 15) {
|
||||
// y = 255, there can't be any blocks above me
|
||||
yield null;
|
||||
}
|
||||
// check if block over us is a full block
|
||||
byte upperSection = (byte) (sectionHeight + 1);
|
||||
if (!world.get(chunkLocation).getNibbles().containsKey(upperSection)) {
|
||||
yield null;
|
||||
}
|
||||
yield world.get(chunkLocation).getNibbles().get(upperSection).getBlock(location.getX(), 0, location.getZ());
|
||||
}
|
||||
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() + 1, location.getZ()));
|
||||
}
|
||||
case WEST -> {
|
||||
if (location.getX() == 0) {
|
||||
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() - 1, chunkLocation.getZ()), sectionHeight);
|
||||
if (otherChunkNibble != null) {
|
||||
yield otherChunkNibble.getBlock(15, location.getY(), location.getZ());
|
||||
}
|
||||
}
|
||||
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() - 1, location.getY(), location.getZ()));
|
||||
}
|
||||
case EAST -> {
|
||||
if (location.getX() == 15) {
|
||||
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX() + 1, chunkLocation.getZ()), sectionHeight);
|
||||
if (otherChunkNibble != null) {
|
||||
yield otherChunkNibble.getBlock(0, location.getY(), location.getZ());
|
||||
}
|
||||
}
|
||||
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX() + 1, location.getY(), location.getZ()));
|
||||
}
|
||||
case NORTH -> {
|
||||
if (location.getZ() == 0) {
|
||||
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() - 1), sectionHeight);
|
||||
if (otherChunkNibble != null) {
|
||||
yield otherChunkNibble.getBlock(location.getX(), location.getY(), 15);
|
||||
}
|
||||
}
|
||||
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() - 1));
|
||||
}
|
||||
case SOUTH -> {
|
||||
if (location.getZ() == 15) {
|
||||
ChunkNibble otherChunkNibble = getChunkNibbleOfWorld(world, new ChunkLocation(chunkLocation.getX(), chunkLocation.getZ() + 1), sectionHeight);
|
||||
if (otherChunkNibble != null) {
|
||||
yield otherChunkNibble.getBlock(location.getX(), location.getY(), 0);
|
||||
}
|
||||
}
|
||||
yield nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() + 1));
|
||||
}
|
||||
//BlockPosition neighbourPos = location.add(faceDir[orientation.ordinal()]);
|
||||
boolean isNeighbourFull = switch (orientation) {
|
||||
case DOWN -> assetsLoader.getBlockModelLoader().isFull(nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() - 1, location.getZ())));
|
||||
case UP -> assetsLoader.getBlockModelLoader().isFull(nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY() + 1, location.getZ())));
|
||||
case WEST -> assetsLoader.getBlockModelLoader().isFull(nibbleBlocks.get(new ChunkNibbleLocation(location.getX() - 1, location.getY(), location.getZ())));
|
||||
case EAST -> assetsLoader.getBlockModelLoader().isFull(nibbleBlocks.get(new ChunkNibbleLocation(location.getX() + 1, location.getY(), location.getZ())));
|
||||
case NORTH -> assetsLoader.getBlockModelLoader().isFull(nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() - 1)));
|
||||
case SOUTH -> assetsLoader.getBlockModelLoader().isFull(nibbleBlocks.get(new ChunkNibbleLocation(location.getX(), location.getY(), location.getZ() + 1)));
|
||||
};
|
||||
if (!isNeighbourFull) {
|
||||
if (dependedBlock == null || !assetsLoader.getBlockModelLoader().isFull(dependedBlock)) {
|
||||
facesToDraw.add(orientation);
|
||||
}
|
||||
|
||||
}
|
||||
if (facesToDraw.size() > 0) {
|
||||
nibbleMap.put(location, assetsLoader.getBlockModelLoader().prepare(block, facesToDraw));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
return nibbleMap;
|
||||
}
|
||||
|
||||
public void prepareChunkNibble(ChunkLocation chunkLocation, byte sectionHeight, ChunkNibble nibble) {
|
||||
faces.get(chunkLocation).put(sectionHeight, getFacesForChunkNibble(chunkLocation, sectionHeight, nibble));
|
||||
}
|
||||
|
||||
|
||||
@ -122,4 +191,11 @@ public class WorldRenderer {
|
||||
public AssetsLoader getAssetsLoader() {
|
||||
return assetsLoader;
|
||||
}
|
||||
|
||||
private ChunkNibble getChunkNibbleOfWorld(ConcurrentHashMap<ChunkLocation, Chunk> world, ChunkLocation location, byte sectionHeight) {
|
||||
if (world.containsKey(location) && world.get(location).getNibbles().containsKey(sectionHeight)) {
|
||||
return world.get(location).getNibbles().get(sectionHeight);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class ChunkUtil {
|
||||
public static Chunk readChunkPacket(InByteBuffer buffer, short sectionBitMask, short addBitMask, boolean groundUpContinuous, boolean containsSkyLight) {
|
||||
@ -51,11 +51,11 @@ public final class ChunkUtil {
|
||||
|
||||
//parse data
|
||||
int arrayPos = 0;
|
||||
HashMap<Byte, ChunkNibble> nibbleMap = new HashMap<>();
|
||||
ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>();
|
||||
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column
|
||||
if (BitByte.isBitSet(sectionBitMask, c)) {
|
||||
|
||||
HashMap<ChunkNibbleLocation, Block> blockMap = new HashMap<>();
|
||||
ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>();
|
||||
|
||||
for (int nibbleY = 0; nibbleY < 16; nibbleY++) {
|
||||
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) {
|
||||
@ -115,12 +115,12 @@ public final class ChunkUtil {
|
||||
}
|
||||
|
||||
int arrayPos = 0;
|
||||
HashMap<Byte, ChunkNibble> nibbleMap = new HashMap<>();
|
||||
ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>();
|
||||
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column
|
||||
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
||||
continue;
|
||||
}
|
||||
HashMap<ChunkNibbleLocation, Block> blockMap = new HashMap<>();
|
||||
ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>();
|
||||
|
||||
for (int nibbleY = 0; nibbleY < 16; nibbleY++) {
|
||||
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) {
|
||||
@ -141,7 +141,7 @@ public final class ChunkUtil {
|
||||
return new Chunk(nibbleMap);
|
||||
}
|
||||
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
|
||||
HashMap<Byte, ChunkNibble> nibbleMap = new HashMap<>();
|
||||
ConcurrentHashMap<Byte, ChunkNibble> nibbleMap = new ConcurrentHashMap<>();
|
||||
for (byte c = 0; c < 16; c++) { // max sections per chunks in chunk column
|
||||
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
||||
continue;
|
||||
@ -155,7 +155,7 @@ public final class ChunkUtil {
|
||||
|
||||
long[] data = buffer.readLongArray(buffer.readVarInt());
|
||||
|
||||
HashMap<ChunkNibbleLocation, Block> blockMap = new HashMap<>();
|
||||
ConcurrentHashMap<ChunkNibbleLocation, Block> blockMap = new ConcurrentHashMap<>();
|
||||
for (int nibbleY = 0; nibbleY < 16; nibbleY++) {
|
||||
for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) {
|
||||
for (int nibbleX = 0; nibbleX < 16; nibbleX++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user