Optimized pixel block rendering with preloaded block and block data arrays, reduced redundant block lookups, and added hidden block detection logic.

This commit is contained in:
MineTec committed 2026-10-25 21:33:32 +01:00
1 parent 1566419f85
commit 6256c363c9
1 file changed
+34 -6
@@ -5,7 +5,9 @@ import eu.mhsl.minecraft.pixelblocks.utils.Direction;
import eu.mhsl.minecraft.pixelblocks.utils.LocationUtil;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.BlockSupport;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.Rotatable;
@@ -112,6 +114,17 @@ public class PixelBlockWorld {
Location origin = this.getBuildOrigin();
int max = pixelsPerBlock - 1;
Block[][][] blocks = new Block[pixelsPerBlock][pixelsPerBlock][pixelsPerBlock];
BlockData[][][] blockData = new BlockData[pixelsPerBlock][pixelsPerBlock][pixelsPerBlock];
for(int x = 0; x < pixelsPerBlock; x++) {
for(int y = 0; y < pixelsPerBlock; y++) {
for(int z = 0; z < pixelsPerBlock; z++) {
blocks[x][y][z] = this.world.getBlockAt(origin.getBlockX() + x, origin.getBlockY() + y, origin.getBlockZ() + z);
blockData[x][y][z] = blocks[x][y][z].getBlockData();
}
}
}
for(int x = 0; x < pixelsPerBlock; x++) {
for(int y = 0; y < pixelsPerBlock; y++) {
for(int z = 0; z < pixelsPerBlock; z++) {
@@ -128,13 +141,14 @@ public class PixelBlockWorld {
case west -> max - x;
};
Block block = this.world.getBlockAt(origin.getBlockX() + blockX, origin.getBlockY() + y, origin.getBlockZ() + blockZ);
BlockData blockData = block.getBlockData();
if(blockData.getMaterial().isAir()) continue;
BlockData data = blockData[blockX][y][blockZ];
if(data.getMaterial().isAir()) continue;
if(this.isHidden(blockData, blockX, y, blockZ)) continue;
@Nullable Directional directional = blockData instanceof Directional face ? face : null;
@Nullable Rotatable rotatable = blockData instanceof Rotatable rotation ? rotation : null;
pixelData.add(new PixelData(new Vector(x, y, z), blockData, directional, rotatable, block.getState(), (double) 1 / pixelsPerBlock));
Block block = blocks[blockX][y][blockZ];
@Nullable Directional directional = data instanceof Directional face ? face : null;
@Nullable Rotatable rotatable = data instanceof Rotatable rotation ? rotation : null;
pixelData.add(new PixelData(new Vector(x, y, z), data, directional, rotatable, block.getState(), (double) 1 / pixelsPerBlock));
}
}
}
@@ -142,6 +156,20 @@ public class PixelBlockWorld {
return pixelData;
}
private static final BlockFace[] neighbourFaces = {BlockFace.UP, BlockFace.DOWN, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST};
private boolean isHidden(BlockData[][][] blockData, int x, int y, int z) {
for(BlockFace face : neighbourFaces) {
int nx = x + face.getModX(), ny = y + face.getModY(), nz = z + face.getModZ();
if(nx < 0 || ny < 0 || nz < 0 || nx >= pixelsPerBlock || ny >= pixelsPerBlock || nz >= pixelsPerBlock) return false;
// isOccluding() schließt Glas, Laub etc. aus; isFaceSturdy() nicht volle Blöcke wie Stufen, Treppenfronten oder Zäune
BlockData neighbour = blockData[nx][ny][nz];
if(!neighbour.isOccluding() || !neighbour.isFaceSturdy(face.getOppositeFace(), BlockSupport.FULL)) return false;
}
return true;
}
private World loadOrCreatePixelWorld() {
final WorldCreator worldCreator = new WorldCreator(getWorldPathName());