mirror of https://github.com/webbukkit/dynmap.git
Start chunk and biome rework - common chunk section class
This commit is contained in:
parent
12fce4c5ae
commit
be43072cd1
|
@ -0,0 +1,205 @@
|
|||
package org.dynmap.common.chunk;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.dynmap.common.BiomeMap;
|
||||
import org.dynmap.renderer.DynmapBlockState;
|
||||
|
||||
// Generic section: represents 16 x 16 x 16 grid of blocks
|
||||
public class DynmapChunkSection {
|
||||
public final BiomeAccess biomes; // Access for biome data
|
||||
public final BlockStateAccess blocks; // Access for block states
|
||||
public final LightingAccess sky; // Access for sky light data
|
||||
public final LightingAccess emitted; // Access for emitted light data
|
||||
public final boolean isEmpty; // if true, section is all air with default sky and emitted light
|
||||
|
||||
// Block state access interface
|
||||
public interface BlockStateAccess {
|
||||
public DynmapBlockState getBlock(int x, int y, int z);
|
||||
}
|
||||
private static class BlockStateAccess3D implements BlockStateAccess {
|
||||
private final DynmapBlockState blocks[];
|
||||
BlockStateAccess3D(DynmapBlockState[][][] bs) { // (16 x 16 x 16) X, Y, Z
|
||||
blocks = new DynmapBlockState[4096];
|
||||
Arrays.fill(blocks, DynmapBlockState.AIR); // Initialize to AIR
|
||||
for (int x = 0; (x < 16) && (x < bs.length); x++) {
|
||||
for (int y = 0; (y < 16) && (y < bs[x].length); y++) {
|
||||
for (int z = 0; (z < 16) && (z < bs[x][y].length); z++) {
|
||||
blocks[(256 * y) + (16 * z) + x] = bs[x][y][z];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public final DynmapBlockState getBlock(int x, int y, int z) {
|
||||
return blocks[(256 * y) + (16 * z) + x];
|
||||
}
|
||||
}
|
||||
private static class BlockStateAccessSingle implements BlockStateAccess {
|
||||
private final DynmapBlockState block;
|
||||
BlockStateAccessSingle(DynmapBlockState bs) {
|
||||
block = bs;
|
||||
}
|
||||
public final DynmapBlockState getBlock(int x, int y, int z) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
// Biome access interface
|
||||
public interface BiomeAccess {
|
||||
public BiomeMap getBiome(int x, int y, int z);
|
||||
}
|
||||
// For classic 2D biome map
|
||||
private static class BiomeAccess2D implements BiomeAccess {
|
||||
private final BiomeMap biomes[]; // (16 * Z) + X
|
||||
BiomeAccess2D(BiomeMap[][] b) { // Grid is 16 x 16 (X, Z)
|
||||
biomes = new BiomeMap[256];
|
||||
Arrays.fill(biomes, BiomeMap.NULL); // Initialize to null
|
||||
for (int x = 0; (x < 16) && (x < b.length); x++) {
|
||||
for (int z = 0; (z < 16) && (z < b[x].length); z++) {
|
||||
biomes[(z << 4) + x] = b[x][z];
|
||||
}
|
||||
}
|
||||
}
|
||||
public final BiomeMap getBiome(int x, int y, int z) {
|
||||
return biomes[((z & 0xF) << 4) + (x & 0xF)];
|
||||
}
|
||||
}
|
||||
// For 3D biome map
|
||||
private static class BiomeAccess3D implements BiomeAccess {
|
||||
private final BiomeMap biomes[]; // (16 * (Y >> 2)) + (4 * (Z >> 2)) + (X >> 2)
|
||||
BiomeAccess3D(BiomeMap[][][] b) { // Grid is 4 x 4 x 4 (X, Y, Z)
|
||||
biomes = new BiomeMap[64];
|
||||
Arrays.fill(biomes, BiomeMap.NULL); // Initialize to null
|
||||
for (int x = 0; (x < 4) && (x < b.length); x++) {
|
||||
for (int y = 0; (y < 4) && (y < b[x].length); y++) {
|
||||
for (int z = 0; (z < 4) && (z < b[x][y].length); z++) {
|
||||
biomes[((y & 0xC) << 2) | (z & 0xC) | ((x & 0xC) >> 2)] = b[x][y][z];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public final BiomeMap getBiome(int x, int y, int z) {
|
||||
return biomes[ ((y & 0xC) << 2) | (z & 0xC) | ((x & 0xC) >> 2) ];
|
||||
}
|
||||
}
|
||||
// For single biome map
|
||||
private static class BiomeAccessSingle implements BiomeAccess {
|
||||
private final BiomeMap biome;
|
||||
BiomeAccessSingle(BiomeMap b) {
|
||||
biome = b;
|
||||
}
|
||||
public final BiomeMap getBiome(int x, int y, int z) {
|
||||
return biome;
|
||||
}
|
||||
}
|
||||
// Lighting access interface
|
||||
public interface LightingAccess {
|
||||
public int getLight(int x, int y, int z);
|
||||
}
|
||||
private static class LightingAccess3D implements LightingAccess {
|
||||
private final long[] light; // Nibble array (16 * y) * z (nibble at 4 << x)
|
||||
|
||||
// Construct using nibble array (same as lighting format in NBT fields) (128*Y + 8*Z + X/2) (oddX high, evenX low)
|
||||
LightingAccess3D(byte[] lig) {
|
||||
light = new long[256];
|
||||
if (lig != null) {
|
||||
for (int off = 0; (off < lig.length) && (off < 2048); off++) {
|
||||
light[off >> 3] |= (0xFFL & (long)lig[off]) << (8 * (off & 0x7));
|
||||
}
|
||||
}
|
||||
}
|
||||
public final int getLight(int x, int y, int z) {
|
||||
return (int)(light[(16 * (y & 0xF)) + (z & 0xF)] >> (4 * (x & 0xF)) & 0xFL);
|
||||
}
|
||||
}
|
||||
private static class LightingAccessSingle implements LightingAccess {
|
||||
private final int light;
|
||||
LightingAccessSingle(int lig) {
|
||||
light = lig & 0xF;
|
||||
}
|
||||
public final int getLight(int x, int y, int z) {
|
||||
return light;
|
||||
}
|
||||
}
|
||||
private DynmapChunkSection(BlockStateAccess blks, BiomeAccess bio, LightingAccess skyac, LightingAccess emitac, boolean empty) {
|
||||
blocks = blks;
|
||||
biomes = bio;
|
||||
sky = skyac;
|
||||
emitted = emitac;
|
||||
isEmpty = empty;
|
||||
}
|
||||
private static BiomeAccess defaultBiome = new BiomeAccessSingle(BiomeMap.NULL);
|
||||
private static BlockStateAccess defaultBlockState = new BlockStateAccessSingle(DynmapBlockState.AIR);
|
||||
private static LightingAccess defaultSky = new LightingAccessSingle(15);
|
||||
private static LightingAccess defaultEmit = new LightingAccessSingle(0);
|
||||
// Factory for building section
|
||||
public static class Builder {
|
||||
private BiomeAccess ba;
|
||||
private BlockStateAccess bs;
|
||||
private LightingAccess sk;
|
||||
private LightingAccess em;
|
||||
private boolean empty;
|
||||
// Initialize builder with empty state
|
||||
public Builder() {
|
||||
reset();
|
||||
}
|
||||
// Reset builder to default state
|
||||
public void reset() {
|
||||
ba = defaultBiome;
|
||||
bs = defaultBlockState;
|
||||
sk = defaultSky;
|
||||
em = defaultEmit;
|
||||
empty = true;
|
||||
}
|
||||
// Set sky lighting to single value
|
||||
public Builder singleSkyLight(int val) {
|
||||
sk = new LightingAccessSingle(val);
|
||||
return this;
|
||||
}
|
||||
// Set sky lighting to given nibble array (YZX order)
|
||||
public Builder skyLight(byte[] data) {
|
||||
sk = new LightingAccess3D(data);
|
||||
return this;
|
||||
}
|
||||
// Set emitted lighting to single value
|
||||
public Builder singleEmittedLight(int val) {
|
||||
em = new LightingAccessSingle(val);
|
||||
return this;
|
||||
}
|
||||
// Set emitted lighting to given nibble array (YZX order)
|
||||
public Builder emittedLight(byte[] data) {
|
||||
em = new LightingAccess3D(data);
|
||||
return this;
|
||||
}
|
||||
// Set bipme to single value
|
||||
public Builder singleBiome(BiomeMap bio) {
|
||||
ba = new BiomeAccessSingle(bio);
|
||||
return this;
|
||||
}
|
||||
// Set bipme to 2D array of values (bio[x][z] = 16 x 16)
|
||||
public Builder xzBiome(BiomeMap bio[][]) {
|
||||
ba = new BiomeAccess2D(bio);
|
||||
return this;
|
||||
}
|
||||
// Set bipme to 3D array of values (bio[x][y][z] = 4 x 4 x 4)
|
||||
public Builder xyzBiome(BiomeMap bio[][][]) {
|
||||
ba = new BiomeAccess3D(bio);
|
||||
return this;
|
||||
}
|
||||
// Set block state to single value
|
||||
public Builder singleBlockState(DynmapBlockState block) {
|
||||
bs = new BlockStateAccessSingle(block);
|
||||
empty = block.isAir();
|
||||
return this;
|
||||
}
|
||||
// Set block state to 3D array (blocks[x][y][z])
|
||||
public Builder xyzBlockState(DynmapBlockState blocks[][][]) {
|
||||
bs = new BlockStateAccess3D(blocks);
|
||||
empty = false;
|
||||
return this;
|
||||
}
|
||||
// Build section based on current builder state
|
||||
public DynmapChunkSection build() {
|
||||
return new DynmapChunkSection(bs, ba, sk, em, empty);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue