Fixlighting now also calculates heightmaps

Fixes #386 and #438 seems fixed, but that might be something else that fixed?
This commit is contained in:
dordsor21 2020-09-14 14:19:23 +01:00
parent 0685881f64
commit d6c9a887ac
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
24 changed files with 295 additions and 41 deletions

View File

@ -5,6 +5,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14; import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14;
@ -38,6 +39,7 @@ import net.minecraft.server.v1_14_R1.DataPaletteLinear;
import net.minecraft.server.v1_14_R1.Entity; import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityTypes; import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.EnumSkyBlock; import net.minecraft.server.v1_14_R1.EnumSkyBlock;
import net.minecraft.server.v1_14_R1.HeightMap;
import net.minecraft.server.v1_14_R1.IBlockData; import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.LightEngine; import net.minecraft.server.v1_14_R1.LightEngine;
import net.minecraft.server.v1_14_R1.NBTTagCompound; import net.minecraft.server.v1_14_R1.NBTTagCompound;
@ -187,6 +189,12 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
SectionPosition.b(BlockPosition.d(l))); SectionPosition.b(BlockPosition.d(l)));
} }
@Override public int[] getHeightMap(HeightMapType type) {
long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a();
BitArray bitArray = new BitArray(9, 256, longArray);
return bitArray.toRaw(new int[256]);
}
@Override @Override
public CompoundTag getEntity(UUID uuid) { public CompoundTag getEntity(UUID uuid) {
Entity entity = world.getEntity(uuid); Entity entity = world.getEntity(uuid);
@ -402,6 +410,13 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
} }
} }
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
BitArray bitArray = new BitArray(9, 256);
bitArray.fromRaw(entry.getValue());
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
}
boolean lightUpdate = false; boolean lightUpdate = false;
// Lighting // Lighting

View File

@ -5,6 +5,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2; import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
@ -15,7 +16,6 @@ import com.google.common.base.Suppliers;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
@ -39,6 +39,7 @@ import net.minecraft.server.v1_15_R1.DataPaletteLinear;
import net.minecraft.server.v1_15_R1.Entity; import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.EntityTypes; import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.EnumSkyBlock; import net.minecraft.server.v1_15_R1.EnumSkyBlock;
import net.minecraft.server.v1_15_R1.HeightMap;
import net.minecraft.server.v1_15_R1.IBlockData; import net.minecraft.server.v1_15_R1.IBlockData;
import net.minecraft.server.v1_15_R1.LightEngine; import net.minecraft.server.v1_15_R1.LightEngine;
import net.minecraft.server.v1_15_R1.NBTTagCompound; import net.minecraft.server.v1_15_R1.NBTTagCompound;
@ -177,6 +178,12 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
} }
@Override public int[] getHeightMap(HeightMapType type) {
long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a();
BitArray bitArray = new BitArray(9, 256, longArray);
return bitArray.toRaw(new int[256]);
}
@Override @Override
public CompoundTag getEntity(UUID uuid) { public CompoundTag getEntity(UUID uuid) {
Entity entity = world.getEntity(uuid); Entity entity = world.getEntity(uuid);
@ -391,6 +398,13 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
} }
} }
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
BitArray bitArray = new BitArray(9, 256);
bitArray.fromRaw(entry.getValue());
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
}
boolean lightUpdate = false; boolean lightUpdate = false;
// Lighting // Lighting

View File

@ -238,7 +238,7 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
if (num_palette == 1) { if (num_palette == 1) {
for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0; for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0;
} else { } else {
final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates);
bitArray.fromRaw(blocksCopy); bitArray.fromRaw(blocksCopy);
} }

View File

@ -5,11 +5,13 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1; import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.AdaptedMap; import com.boydti.fawe.object.collection.AdaptedMap;
import com.boydti.fawe.object.collection.BitArray;
import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.object.collection.BitArrayUnstretched;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -143,6 +145,12 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
} }
@Override public int[] getHeightMap(HeightMapType type) {
long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a();
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray);
return bitArray.toRaw(new int[256]);
}
@Override @Override
public CompoundTag getEntity(UUID uuid) { public CompoundTag getEntity(UUID uuid) {
Entity entity = world.getEntity(uuid); Entity entity = world.getEntity(uuid);
@ -359,6 +367,13 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
} }
} }
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
bitArray.fromRaw(entry.getValue());
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
}
boolean lightUpdate = false; boolean lightUpdate = false;
// Lighting // Lighting
@ -567,7 +582,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
final int bitsPerEntry = (int) BukkitAdapter_1_16_1.fieldBitsPerEntry.get(bits); final int bitsPerEntry = (int) BukkitAdapter_1_16_1.fieldBitsPerEntry.get(bits);
final long[] blockStates = bits.a(); final long[] blockStates = bits.a();
new BitArrayUnstretched(bitsPerEntry, blockStates).toRaw(data); new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data);
int num_palette; int num_palette;
if (palette instanceof DataPaletteLinear) { if (palette instanceof DataPaletteLinear) {

View File

@ -253,7 +253,7 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
if (num_palette == 1) { if (num_palette == 1) {
for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0; for (int i = 0; i < blockBitArrayEnd; i++) blockStates[i] = 0;
} else { } else {
final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates);
bitArray.fromRaw(blocksCopy); bitArray.fromRaw(blocksCopy);
} }

View File

@ -5,11 +5,13 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.blocks.CharBlocks; import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks; import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.beta.implementation.queue.QueueHandler; import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock; import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2; import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.AdaptedMap; import com.boydti.fawe.object.collection.AdaptedMap;
import com.boydti.fawe.object.collection.BitArray;
import com.boydti.fawe.object.collection.BitArrayUnstretched; import com.boydti.fawe.object.collection.BitArrayUnstretched;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -143,6 +145,12 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l))); return blockLight[layer].a(SectionPosition.b(BlockPosition.b(l)), SectionPosition.b(BlockPosition.c(l)), SectionPosition.b(BlockPosition.d(l)));
} }
@Override public int[] getHeightMap(HeightMapType type) {
long[] longArray = getChunk().heightMap.get(HeightMap.Type.valueOf(type.name())).a();
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray);
return bitArray.toRaw(new int[256]);
}
@Override @Override
public CompoundTag getEntity(UUID uuid) { public CompoundTag getEntity(UUID uuid) {
Entity entity = world.getEntity(uuid); Entity entity = world.getEntity(uuid);
@ -359,6 +367,13 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
} }
} }
Map<HeightMapType, int[]> heightMaps = set.getHeightMaps();
for (Map.Entry<HeightMapType, int[]> entry : heightMaps.entrySet()) {
BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256);
bitArray.fromRaw(entry.getValue());
nmsChunk.heightMap.get(HeightMap.Type.valueOf(entry.getKey().name())).a(bitArray.getData());
}
boolean lightUpdate = false; boolean lightUpdate = false;
// Lighting // Lighting
@ -567,7 +582,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
final int bitsPerEntry = (int) BukkitAdapter_1_16_2.fieldBitsPerEntry.get(bits); final int bitsPerEntry = (int) BukkitAdapter_1_16_2.fieldBitsPerEntry.get(bits);
final long[] blockStates = bits.a(); final long[] blockStates = bits.a();
new BitArrayUnstretched(bitsPerEntry, blockStates).toRaw(data); new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data);
int num_palette; int num_palette;
if (palette instanceof DataPaletteLinear) { if (palette instanceof DataPaletteLinear) {

View File

@ -373,7 +373,7 @@ public class FaweAPI {
} }
} }
NMSRelighter relighter = new NMSRelighter(queue); NMSRelighter relighter = new NMSRelighter(queue, Settings.IMP.LIGHTING.DO_HEIGHTMAPS);
for (int x = minX; x <= maxX; x++) { for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) { for (int z = minZ; z <= maxZ; z++) {
relighter.addChunk(x, z, null, 65535); relighter.addChunk(x, z, null, 65535);

View File

@ -375,7 +375,7 @@ public enum FaweCache implements Trimable {
blockStates[0] = 0; blockStates[0] = 0;
blockBitArrayEnd = 1; blockBitArrayEnd = 1;
} else { } else {
BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, blockStates); BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates);
bitArray.fromRaw(blocksCopy); bitArray.fromRaw(blocksCopy);
} }

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.InputExtent; import com.sk89q.worldedit.extent.InputExtent;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
@ -29,6 +30,9 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput {
@Override @Override
int getEmmittedLight(int x, int y, int z); int getEmmittedLight(int x, int y, int z);
@Override
int[] getHeightMap(HeightMapType type);
default void optimize() { default void optimize() {
} }

View File

@ -1,11 +1,14 @@
package com.boydti.fawe.beta; package com.boydti.fawe.beta;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.OutputExtent; import com.sk89q.worldedit.extent.OutputExtent;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -34,6 +37,9 @@ public interface IChunkSet extends IBlocks, OutputExtent {
@Override @Override
void setSkyLight(int x, int y, int z, int value); void setSkyLight(int x, int y, int z, int value);
@Override
void setHeightMap(HeightMapType type, int[] heightMap);
void setLightLayer(int layer, char[] toSet); void setLightLayer(int layer, char[] toSet);
void setSkyLightLayer(int layer, char[] toSet); void setSkyLightLayer(int layer, char[] toSet);
@ -76,6 +82,10 @@ public interface IChunkSet extends IBlocks, OutputExtent {
return -1; return -1;
} }
default Map<HeightMapType, int[]> getHeightMaps() {
return new HashMap<>();
}
@Override @Override
IChunkSet reset(); IChunkSet reset();

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.beta.implementation.blocks;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.object.collection.MemBlockSet; import com.boydti.fawe.object.collection.MemBlockSet;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -71,6 +72,8 @@ public class BitSetBlocks implements IChunkSet {
@Override public void setSkyLight(int x, int y, int z, int value) {} @Override public void setSkyLight(int x, int y, int z, int value) {}
@Override public void setHeightMap(HeightMapType type, int[] heightMap) {}
@Override public void setLightLayer(int layer, char[] toSet) {} @Override public void setLightLayer(int layer, char[] toSet) {}
@Override public void setSkyLightLayer(int layer, char[] toSet) {} @Override public void setSkyLightLayer(int layer, char[] toSet) {}

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.beta.implementation.blocks;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.beta.implementation.queue.Pool; import com.boydti.fawe.beta.implementation.queue.Pool;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.BlockVector3ChunkMap; import com.boydti.fawe.object.collection.BlockVector3ChunkMap;
@ -14,6 +15,7 @@ import org.jetbrains.annotations.Range;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -32,6 +34,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
public BlockVector3ChunkMap<CompoundTag> tiles; public BlockVector3ChunkMap<CompoundTag> tiles;
public HashSet<CompoundTag> entities; public HashSet<CompoundTag> entities;
public HashSet<UUID> entityRemoves; public HashSet<UUID> entityRemoves;
public Map<HeightMapType, int[]> heightMaps;
private boolean fastMode = false; private boolean fastMode = false;
private int bitMask = -1; private int bitMask = -1;
@ -73,6 +76,11 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
return entityRemoves == null ? Collections.emptySet() : entityRemoves; return entityRemoves == null ? Collections.emptySet() : entityRemoves;
} }
@Override
public Map<HeightMapType, int[]> getHeightMaps() {
return heightMaps == null ? new HashMap<>() : heightMaps;
}
@Override @Override
public boolean setBiome(int x, int y, int z, BiomeType biome) { public boolean setBiome(int x, int y, int z, BiomeType biome) {
if (biomes == null) { if (biomes == null) {
@ -138,6 +146,13 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
skyLight[y >> 4][index] = (char) value; skyLight[y >> 4][index] = (char) value;
} }
@Override public void setHeightMap(HeightMapType type, int[] heightMap) {
if (heightMaps == null) {
heightMaps = new HashMap<>();
}
heightMaps.put(type, heightMap);
}
@Override public void setLightLayer(int layer, char[] toSet) { @Override public void setLightLayer(int layer, char[] toSet) {
if (light == null) { if (light == null) {
light = new char[16][]; light = new char[16][];

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IBlocks; import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
@ -50,6 +51,10 @@ public class FallbackChunkGet implements IChunkGet {
return extent.getSkyLight(bx + x, y, bz + z); return extent.getSkyLight(bx + x, y, bz + z);
} }
@Override public int[] getHeightMap(HeightMapType type) {
return extent.getHeightMap(type);
}
@Override public int getEmmittedLight(int x, int y, int z) { @Override public int getEmmittedLight(int x, int y, int z) {
return extent.getEmmittedLight(bx + x, y, bz + z); return extent.getEmmittedLight(bx + x, y, bz + z);
} }

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.FaweCache
import com.boydti.fawe.beta.IBlocks import com.boydti.fawe.beta.IBlocks
import com.boydti.fawe.beta.IChunkGet import com.boydti.fawe.beta.IChunkGet
import com.boydti.fawe.beta.IChunkSet import com.boydti.fawe.beta.IChunkSet
import com.boydti.fawe.beta.implementation.lighting.HeightMapType
import com.sk89q.jnbt.CompoundTag import com.sk89q.jnbt.CompoundTag
import com.sk89q.worldedit.math.BlockVector3 import com.sk89q.worldedit.math.BlockVector3
import com.sk89q.worldedit.world.biome.BiomeType import com.sk89q.worldedit.world.biome.BiomeType
@ -72,6 +73,10 @@ object NullChunkGet : IChunkGet {
return 15 return 15
} }
override fun getHeightMap(type: HeightMapType?): IntArray {
return IntArray(256)
}
override fun reset(): IBlocks? { override fun reset(): IBlocks? {
return null return null
} }

View File

@ -8,6 +8,7 @@ import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueChunk; import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.beta.implementation.queue.Pool; import com.boydti.fawe.beta.implementation.queue.Pool;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
@ -192,6 +193,10 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
chunk.chunkSet.setSkyLightLayer(layer, toSet); chunk.chunkSet.setSkyLightLayer(layer, toSet);
} }
@Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) {
chunk.chunkSet.setHeightMap(type, heightMap);
}
@Override @Override
public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) { public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) {
return chunk.chunkExisting.getBiomeType(x, y, z); return chunk.chunkExisting.getBiomeType(x, y, z);
@ -245,8 +250,12 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
public int getOpacity(ChunkHolder chunk, int x, int y, int z) { public int getOpacity(ChunkHolder chunk, int x, int y, int z) {
return chunk.chunkExisting.getOpacity(x, y, z); return chunk.chunkExisting.getOpacity(x, y, z);
} }
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
return chunk.chunkExisting.getHeightMap(type);
}
}; };
private static final IBlockDelegate GET = new IBlockDelegate() { private static final IBlockDelegate GET = new IBlockDelegate() {
@Override @Override
public IChunkGet get(ChunkHolder chunk) { public IChunkGet get(ChunkHolder chunk) {
@ -318,6 +327,12 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
chunk.setSkyLightLayer(layer, toSet); chunk.setSkyLightLayer(layer, toSet);
} }
@Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) {
chunk.getOrCreateSet();
chunk.delegate = BOTH;
chunk.setHeightMap(type, heightMap);
}
@Override @Override
public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) { public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) {
return chunk.chunkExisting.getBiomeType(x, y, z); return chunk.chunkExisting.getBiomeType(x, y, z);
@ -353,8 +368,12 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
public int getOpacity(ChunkHolder chunk, int x, int y, int z) { public int getOpacity(ChunkHolder chunk, int x, int y, int z) {
return chunk.chunkExisting.getOpacity(x, y, z); return chunk.chunkExisting.getOpacity(x, y, z);
} }
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
return chunk.chunkExisting.getHeightMap(type);
}
}; };
private static final IBlockDelegate SET = new IBlockDelegate() { private static final IBlockDelegate SET = new IBlockDelegate() {
@Override @Override
public IChunkGet get(ChunkHolder chunk) { public IChunkGet get(ChunkHolder chunk) {
@ -409,6 +428,10 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
chunk.chunkSet.setSkyLightLayer(layer, toSet); chunk.chunkSet.setSkyLightLayer(layer, toSet);
} }
@Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) {
chunk.chunkSet.setHeightMap(type, heightMap);
}
@Override @Override
public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) { public BiomeType getBiome(ChunkHolder chunk, int x, int y, int z) {
chunk.getOrCreateGet(); chunk.getOrCreateGet();
@ -476,8 +499,14 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
chunk.delegate = BOTH; chunk.delegate = BOTH;
return chunk.getOpacity(x, y, z); return chunk.getOpacity(x, y, z);
} }
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
chunk.getOrCreateGet();
chunk.delegate = BOTH;
return chunk.getHeightMap(type);
}
}; };
private static final IBlockDelegate NULL = new IBlockDelegate() { private static final IBlockDelegate NULL = new IBlockDelegate() {
@Override @Override
public IChunkGet get(ChunkHolder chunk) { public IChunkGet get(ChunkHolder chunk) {
@ -575,6 +604,12 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
chunk.setSkyLightLayer(layer, toSet); chunk.setSkyLightLayer(layer, toSet);
} }
@Override public void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap) {
chunk.getOrCreateSet();
chunk.delegate = SET;
chunk.setHeightMap(type, heightMap);
}
@Override @Override
public int getSkyLight(ChunkHolder chunk, int x, int y, int z) { public int getSkyLight(ChunkHolder chunk, int x, int y, int z) {
chunk.getOrCreateGet(); chunk.getOrCreateGet();
@ -606,6 +641,13 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
chunk.chunkExisting.trim(false); chunk.chunkExisting.trim(false);
return chunk.getOpacity(x, y, z); return chunk.getOpacity(x, y, z);
} }
@Override public int[] getHeightMap(ChunkHolder chunk, HeightMapType type) {
chunk.getOrCreateGet();
chunk.delegate = GET;
chunk.chunkExisting.trim(false);
return chunk.getHeightMap(type);
}
}; };
@Override @Override
@ -791,6 +833,10 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
delegate.setSkyLight(this, x, y, z, value); delegate.setSkyLight(this, x, y, z, value);
} }
@Override public void setHeightMap(HeightMapType type, int[] heightMap) {
delegate.setHeightMap(this, type, heightMap);
}
@Override public void removeSectionLighting(int layer, boolean sky) { @Override public void removeSectionLighting(int layer, boolean sky) {
delegate.removeSectionLighting(this, layer, sky); delegate.removeSectionLighting(this, layer, sky);
} }
@ -834,6 +880,10 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
return delegate.getOpacity(this, x, y, z); return delegate.getOpacity(this, x, y, z);
} }
@Override public int[] getHeightMap(HeightMapType type) {
return delegate.getHeightMap(this, type);
}
public interface IBlockDelegate { public interface IBlockDelegate {
<C extends Future<C>> IChunkGet get(ChunkHolder<C> chunk); <C extends Future<C>> IChunkGet get(ChunkHolder<C> chunk);
IChunkSet set(ChunkHolder chunk); IChunkSet set(ChunkHolder chunk);
@ -860,6 +910,8 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
void setSkyLightLayer(ChunkHolder chunk, int layer, char[] toSet); void setSkyLightLayer(ChunkHolder chunk, int layer, char[] toSet);
void setHeightMap(ChunkHolder chunk, HeightMapType type, int[] heightMap);
int getSkyLight(ChunkHolder chunk, int x, int y, int z); int getSkyLight(ChunkHolder chunk, int x, int y, int z);
int getEmmittedLight(ChunkHolder chunk, int x, int y, int z); int getEmmittedLight(ChunkHolder chunk, int x, int y, int z);
@ -867,5 +919,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
int getBrightness(ChunkHolder chunk, int x, int y, int z); int getBrightness(ChunkHolder chunk, int x, int y, int z);
int getOpacity(ChunkHolder chunk, int x, int y, int z); int getOpacity(ChunkHolder chunk, int x, int y, int z);
int[] getHeightMap(ChunkHolder chunk, HeightMapType type);
} }
} }

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.beta.Filter
import com.boydti.fawe.beta.IChunkSet import com.boydti.fawe.beta.IChunkSet
import com.boydti.fawe.beta.IQueueChunk import com.boydti.fawe.beta.IQueueChunk
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock
import com.boydti.fawe.beta.implementation.lighting.HeightMapType
import com.sk89q.jnbt.CompoundTag import com.sk89q.jnbt.CompoundTag
import com.sk89q.worldedit.math.BlockVector3 import com.sk89q.worldedit.math.BlockVector3
import com.sk89q.worldedit.regions.Region import com.sk89q.worldedit.regions.Region
@ -74,6 +75,10 @@ object NullChunk : IQueueChunk<Nothing> {
return emptyArray() return emptyArray()
} }
override fun getHeightMap(type: HeightMapType?): IntArray {
return IntArray(256)
}
override fun getEmmittedLight(x: Int, y: Int, z: Int): Int { override fun getEmmittedLight(x: Int, y: Int, z: Int): Int {
return 15 return 15
} }
@ -82,6 +87,10 @@ object NullChunk : IQueueChunk<Nothing> {
} }
override fun setHeightMap(type: HeightMapType?, heightMap: IntArray?) {
}
override fun fullySupports3DBiomes(): Boolean { override fun fullySupports3DBiomes(): Boolean {
return false return false
} }

View File

@ -0,0 +1,5 @@
package com.boydti.fawe.beta.implementation.lighting;
public enum HeightMapType {
MOTION_BLOCKING, MOTION_BLOCKING_NO_LEAVES, OCEAN_FLOOR, WORLD_SURFACE
}

View File

@ -5,6 +5,7 @@ import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.chunk.ChunkHolder; import com.boydti.fawe.beta.implementation.chunk.ChunkHolder;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.collection.BitArray;
import com.boydti.fawe.object.collection.BlockVectorSet; import com.boydti.fawe.object.collection.BlockVectorSet;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
@ -14,6 +15,7 @@ import com.sk89q.worldedit.registry.state.EnumProperty;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@ -50,20 +52,24 @@ public class NMSRelighter implements Relighter {
private final Map<Long, RelightSkyEntry> skyToRelight; private final Map<Long, RelightSkyEntry> skyToRelight;
private final Object present = new Object(); private final Object present = new Object();
private final Map<Long, Integer> chunksToSend; private final Map<Long, Integer> chunksToSend;
private final Map<Long, Map<HeightMapType, int[]>> heightMaps;
private final ConcurrentLinkedQueue<RelightSkyEntry> extentdSkyToRelight = new ConcurrentLinkedQueue<>(); private final ConcurrentLinkedQueue<RelightSkyEntry> extentdSkyToRelight = new ConcurrentLinkedQueue<>();
private final Map<Long, long[][][] /* z y x */> lightQueue; private final Map<Long, long[][][] /* z y x */> lightQueue;
private final AtomicBoolean lightLock = new AtomicBoolean(false); private final AtomicBoolean lightLock = new AtomicBoolean(false);
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue; private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
private final int maxY; private final int maxY;
private final boolean calculateHeightMaps;
private boolean removeFirst; private boolean removeFirst;
public NMSRelighter(IQueueExtent<IQueueChunk> queue) { public NMSRelighter(IQueueExtent<IQueueChunk> queue, boolean calculateHeightMaps) {
this.queue = queue; this.queue = queue;
this.skyToRelight = new Long2ObjectOpenHashMap<>(12); this.skyToRelight = new Long2ObjectOpenHashMap<>(12);
this.lightQueue = new Long2ObjectOpenHashMap<>(12); this.lightQueue = new Long2ObjectOpenHashMap<>(12);
this.chunksToSend = new Long2ObjectOpenHashMap<>(12); this.chunksToSend = new Long2ObjectOpenHashMap<>(12);
this.concurrentLightQueue = new ConcurrentHashMap<>(12); this.concurrentLightQueue = new ConcurrentHashMap<>(12);
this.heightMaps = new Long2ObjectOpenHashMap<>(12);
this.maxY = queue.getMaxY(); this.maxY = queue.getMaxY();
this.calculateHeightMaps = calculateHeightMaps;
} }
@Override public boolean isEmpty() { @Override public boolean isEmpty() {
@ -93,7 +99,7 @@ public class NMSRelighter implements Relighter {
if (m2 == null) { if (m2 == null) {
m2 = m1[x] = new long[4]; m2 = m1[x] = new long[4];
} }
long value = m2[y >> 6] |= 1l << y; m2[y >> 6] |= 1L << y;
} }
public void addLightUpdate(int x, int y, int z) { public void addLightUpdate(int x, int y, int z) {
@ -125,11 +131,12 @@ public class NMSRelighter implements Relighter {
extentdSkyToRelight.clear(); extentdSkyToRelight.clear();
skyToRelight.clear(); skyToRelight.clear();
chunksToSend.clear(); chunksToSend.clear();
heightMaps.clear();
lightQueue.clear(); lightQueue.clear();
} }
public boolean addChunk(int cx, int cz, byte[] fix, int bitmask) { public boolean addChunk(int cx, int cz, byte[] fix, int bitmask) {
RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask); RelightSkyEntry toPut = new RelightSkyEntry(cx, cz, fix, bitmask, calculateHeightMaps);
extentdSkyToRelight.add(toPut); extentdSkyToRelight.add(toPut);
return true; return true;
} }
@ -791,6 +798,14 @@ public class NMSRelighter implements Relighter {
int z = MathMan.unpairIntY(pair); int z = MathMan.unpairIntY(pair);
ChunkHolder<?> chunk = (ChunkHolder<?>) queue.getOrCreateChunk(x, z); ChunkHolder<?> chunk = (ChunkHolder<?>) queue.getOrCreateChunk(x, z);
chunk.setBitMask(bitMask); chunk.setBitMask(bitMask);
if (calculateHeightMaps && heightMaps != null) {
Map<HeightMapType, int[]> heightMapList = heightMaps.get(pair);
if (heightMapList != null) {
for (Map.Entry<HeightMapType, int[]> heightMapEntry : heightMapList.entrySet()){
chunk.setHeightMap(heightMapEntry.getKey(), heightMapEntry.getValue());
}
}
}
iter.remove(); iter.remove();
} }
if (Settings.IMP.LIGHTING.ASYNC) { if (Settings.IMP.LIGHTING.ASYNC) {
@ -856,18 +871,33 @@ public class NMSRelighter implements Relighter {
private void fixSkyLighting(List<RelightSkyEntry> sorted) { private void fixSkyLighting(List<RelightSkyEntry> sorted) {
RelightSkyEntry[] chunks = sorted.toArray(new RelightSkyEntry[sorted.size()]); RelightSkyEntry[] chunks = sorted.toArray(new RelightSkyEntry[sorted.size()]);
boolean remove = this.removeFirst; boolean remove = this.removeFirst;
boolean heightMaps = this.calculateHeightMaps;
BlockVectorSet chunkSet = null; BlockVectorSet chunkSet = null;
if (remove) { if (remove || heightMaps) {
chunkSet = new BlockVectorSet();
BlockVectorSet tmpSet = new BlockVectorSet(); BlockVectorSet tmpSet = new BlockVectorSet();
for (RelightSkyEntry chunk : chunks) { if (remove) {
tmpSet.add(chunk.x, 0, chunk.z); chunkSet = new BlockVectorSet();
for (RelightSkyEntry chunk : chunks) {
tmpSet.add(chunk.x, 0, chunk.z);
}
} }
for (RelightSkyEntry chunk : chunks) { for (RelightSkyEntry chunk : chunks) {
int x = chunk.x; if (remove) {
int z = chunk.z; int x = chunk.x;
if (tmpSet.contains(x + 1, 0, z) && tmpSet.contains(x - 1, 0, z) && tmpSet.contains(x, 0, z + 1) && tmpSet.contains(x, 0, z - 1)) { int z = chunk.z;
chunkSet.add(x, 0, z); if (tmpSet.contains(x + 1, 0, z) && tmpSet.contains(x - 1, 0, z) && tmpSet.contains(x, 0, z + 1) && tmpSet
.contains(x, 0, z - 1)) {
chunkSet.add(x, 0, z);
}
}
if (heightMaps) {
long pair = MathMan.pairInt(chunk.x, chunk.z);
this.heightMaps.putIfAbsent(pair, new HashMap<>());
Map<HeightMapType, int[]> heightMapList = this.heightMaps.get(pair);
heightMapList.putIfAbsent(HeightMapType.WORLD_SURFACE, new int[256]);
heightMapList.putIfAbsent(HeightMapType.OCEAN_FLOOR, new int[256]);
heightMapList.putIfAbsent(HeightMapType.MOTION_BLOCKING, new int[256]);
heightMapList.putIfAbsent(HeightMapType.MOTION_BLOCKING_NO_LEAVES, new int[256]);
} }
} }
} }
@ -893,17 +923,42 @@ public class NMSRelighter implements Relighter {
iChunk.removeSectionLighting(y >> 4, true); iChunk.removeSectionLighting(y >> 4, true);
} }
Map<HeightMapType, int[]> heightMapList = null;
if (heightMaps) {
long pair = MathMan.pairInt(chunk.x, chunk.z);
heightMapList = this.heightMaps.get(pair);
}
for (int j = 0; j < 256; j++) { for (int j = 0; j < 256; j++) {
int x = j & 15; int x = j & 15;
int z = j >> 4; int z = j >> 4;
byte value = mask[j]; byte value = mask[j];
BlockMaterial material = iChunk.getBlock(x, y, z).getBlockType().getMaterial(); BlockType type = iChunk.getBlock(x, y, z).getBlockType();
BlockMaterial material = type.getMaterial();
int opacity = material.getLightOpacity(); int opacity = material.getLightOpacity();
int brightness = iChunk.getBrightness(x, y, z); int brightness = iChunk.getBrightness(x, y, z);
boolean solidNeedsLight = (!material.isSolid() || !material.isFullCube()) && material.getLightOpacity() > 0; boolean solidNeedsLight = (!material.isSolid() || !material.isFullCube()) && material.getLightOpacity() > 0;
if (brightness > 1) { if (brightness > 1) {
addLightUpdate(bx + x, y, bz + z); addLightUpdate(bx + x, y, bz + z);
} }
if (heightMaps) {
if (heightMapList.get(HeightMapType.WORLD_SURFACE)[j] == 0 && !material.isAir()) {
// MC Requires y+1
heightMapList.get(HeightMapType.WORLD_SURFACE)[j] = y + 1;
}
if (heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] == 0 && material.isSolid()) {
heightMapList.get(HeightMapType.OCEAN_FLOOR)[j] = y + 1;
}
if (heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] == 0 && (material.isSolid() || material.isLiquid())) {
heightMapList.get(HeightMapType.MOTION_BLOCKING)[j] = y + 1;
}
if (heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] == 0 && (material.isSolid() || material.isLiquid()) && !type
.getId().toLowerCase().contains("leaves")) {
heightMapList.get(HeightMapType.MOTION_BLOCKING_NO_LEAVES)[j] = y + 1;
}
}
switch (value) { switch (value) {
case 0: case 0:
if (opacity > 1) { if (opacity > 1) {
@ -1081,7 +1136,7 @@ public class NMSRelighter implements Relighter {
public int bitmask; public int bitmask;
public boolean smooth; public boolean smooth;
public RelightSkyEntry(int x, int z, byte[] fix, int bitmask) { public RelightSkyEntry(int x, int z, byte[] fix, int bitmask, boolean heightmaps) {
this.x = x; this.x = x;
this.z = z; this.z = z;
byte[] array = new byte[256]; byte[] array = new byte[256];

View File

@ -481,6 +481,8 @@ public class Settings extends Config {
public int MODE = 1; public int MODE = 1;
@Comment({"If existing lighting should be removed before relighting"}) @Comment({"If existing lighting should be removed before relighting"})
public boolean REMOVE_FIRST = true; public boolean REMOVE_FIRST = true;
@Comment({"Calculate and set heightmaps when relighting"})
public boolean DO_HEIGHTMAPS = true;
} }
public void reload(File file) { public void reload(File file) {

View File

@ -6,6 +6,7 @@ import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.boydti.fawe.jnbt.streamer.StreamDelegate; import com.boydti.fawe.jnbt.streamer.StreamDelegate;
import com.boydti.fawe.jnbt.streamer.ValueReader; import com.boydti.fawe.jnbt.streamer.ValueReader;
import com.boydti.fawe.object.collection.BitArray; import com.boydti.fawe.object.collection.BitArray;
@ -443,6 +444,10 @@ public class MCAChunk implements IChunk {
} }
@Override public void setHeightMap(HeightMapType type, int[] heightMap) {
}
@Override public void removeSectionLighting(int layer, boolean sky) {} @Override public void removeSectionLighting(int layer, boolean sky) {}
@Override public void setFullBright(int layer) {} @Override public void setFullBright(int layer) {}
@ -533,6 +538,10 @@ public class MCAChunk implements IChunk {
return 0; return 0;
} }
@Override public int[] getHeightMap(HeightMapType type) {
return new int[256];
}
@Override @Override
public BaseBlock getFullBlock(int x, int y, int z) { public BaseBlock getFullBlock(int x, int y, int z) {
BlockState block = getBlock(x, y, z); BlockState block = getBlock(x, y, z);

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.`object`.clipboard package com.boydti.fawe.`object`.clipboard
import com.boydti.fawe.beta.implementation.lighting.HeightMapType
import com.sk89q.jnbt.CompoundTag import com.sk89q.jnbt.CompoundTag
import com.sk89q.worldedit.WorldEditException import com.sk89q.worldedit.WorldEditException
import com.sk89q.worldedit.entity.Entity import com.sk89q.worldedit.entity.Entity
@ -49,6 +50,10 @@ object EmptyClipboard : Clipboard {
return null return null
} }
override fun getHeightMap(type: HeightMapType?): IntArray {
return IntArray(256)
}
@Throws(WorldEditException::class) @Throws(WorldEditException::class)
override fun <T : BlockStateHolder<T>?> setBlock(position: BlockVector3, block: T): Boolean { override fun <T : BlockStateHolder<T>?> setBlock(position: BlockVector3, block: T): Boolean {
return false return false

View File

@ -11,13 +11,13 @@ public final class BitArrayUnstretched {
private final long mask; private final long mask;
private final int longLen; private final int longLen;
public BitArrayUnstretched(int bitsPerEntry, long[] buffer) { public BitArrayUnstretched(int bitsPerEntry, int arraySize, long[] buffer) {
this.bitsPerEntry = bitsPerEntry; this.bitsPerEntry = bitsPerEntry;
this.mask = (1L << bitsPerEntry) - 1L; this.mask = (1L << bitsPerEntry) - 1L;
this.emptyBitCount = 64 % bitsPerEntry; this.emptyBitCount = 64 % bitsPerEntry;
this.maxSeqLocIndex = 64 - (bitsPerEntry + emptyBitCount); this.maxSeqLocIndex = 64 - (bitsPerEntry + emptyBitCount);
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
this.longLen = MathMan.ceilZero((float) 4096 / blocksPerLong); this.longLen = MathMan.ceilZero((float) arraySize / blocksPerLong);
if (buffer.length < longLen) { if (buffer.length < longLen) {
this.data = new long[longLen]; this.data = new long[longLen];
} else { } else {
@ -25,6 +25,16 @@ public final class BitArrayUnstretched {
} }
} }
public BitArrayUnstretched(int bitsPerEntry, int arraySize) {
this.bitsPerEntry = bitsPerEntry;
this.mask = (1L << bitsPerEntry) - 1L;
this.emptyBitCount = 64 % bitsPerEntry;
this.maxSeqLocIndex = 64 - bitsPerEntry;
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry);
this.longLen = MathMan.ceilZero((float) arraySize / blocksPerLong);
this.data = new long[longLen];
}
public long[] getData() { public long[] getData() {
return data; return data;
} }
@ -61,7 +71,7 @@ public final class BitArrayUnstretched {
long l = 0; long l = 0;
for (int i = 0; i < longLen; i++) { for (int i = 0; i < longLen; i++) {
int lastVal; int lastVal;
for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { for (; localStart <= maxSeqLocIndex && arrI < arr.length; localStart += bitsPerEntry) {
lastVal = arr[arrI++]; lastVal = arr[arrI++];
l |= ((long) lastVal << localStart); l |= ((long) lastVal << localStart);
} }
@ -85,7 +95,7 @@ public final class BitArrayUnstretched {
for (int i = 0; i < longLen; i++) { for (int i = 0; i < longLen; i++) {
long l = data[i]; long l = data[i];
char lastVal; char lastVal;
for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { for (; localStart <= maxSeqLocIndex && arrI < buffer.length; localStart += bitsPerEntry) {
lastVal = (char) (l >>> localStart & this.mask); lastVal = (char) (l >>> localStart & this.mask);
buffer[arrI++] = lastVal; buffer[arrI++] = lastVal;
} }
@ -104,7 +114,7 @@ public final class BitArrayUnstretched {
for (int i = 0; i < longLen; i++) { for (int i = 0; i < longLen; i++) {
long l = data[i]; long l = data[i];
char lastVal; char lastVal;
for (; localStart <= maxSeqLocIndex && arrI < 4096; localStart += bitsPerEntry) { for (; localStart <= maxSeqLocIndex && arrI < buffer.length; localStart += bitsPerEntry) {
lastVal = (char) (l >>> localStart & this.mask); lastVal = (char) (l >>> localStart & this.mask);
buffer[arrI++] = lastVal; buffer[arrI++] = lastVal;
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extent; package com.sk89q.worldedit.extent;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.internal.util.DeprecationUtil; import com.sk89q.worldedit.internal.util.DeprecationUtil;
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
@ -80,8 +81,7 @@ public interface InputExtent {
* @return the biome at the location * @return the biome at the location
* @deprecated Biomes in Minecraft are 3D now, use {@link InputExtent#getBiome(BlockVector3)} * @deprecated Biomes in Minecraft are 3D now, use {@link InputExtent#getBiome(BlockVector3)}
*/ */
@Deprecated @Deprecated default BiomeType getBiome(BlockVector2 position) {
default BiomeType getBiome(BlockVector2 position) {
return getBiomeType(position.getX(), 0, position.getZ()); return getBiomeType(position.getX(), 0, position.getZ());
} }
@ -93,26 +93,22 @@ public interface InputExtent {
* Get the biome at the given location. * Get the biome at the given location.
* *
* <p> * <p>
* If there is no biome available, then the ocean biome should be * If there is no biome available, then the ocean biome should be
* returned. * returned.
* </p> * </p>
* *
* <p> * <p>
* As implementation varies per Minecraft version, this may not exactly get * As implementation varies per Minecraft version, this may not exactly get
* this positions biome. On versions prior to 1.15, this will get the entire * this positions biome. On versions prior to 1.15, this will get the entire
* column. On later versions it will get the 4x4x4 cube's biome. * column. On later versions it will get the 4x4x4 cube's biome.
* </p> * </p>
* *
* @param position the (x, y, z) location to check the biome at * @param position the (x, y, z) location to check the biome at
* @return the biome at the location * @return the biome at the location
* @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility} * @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility}
* for details * for details
*/ */
@NonAbstractForCompatibility( @NonAbstractForCompatibility(delegateName = "getBiome", delegateParams = {BlockVector2.class}) default BiomeType getBiome(BlockVector3 position) {
delegateName = "getBiome",
delegateParams = { BlockVector2.class }
)
default BiomeType getBiome(BlockVector3 position) {
DeprecationUtil.checkDelegatingOverride(getClass()); DeprecationUtil.checkDelegatingOverride(getClass());
return getBiome(position.toBlockVector2()); return getBiome(position.toBlockVector2());
@ -161,4 +157,8 @@ public interface InputExtent {
default int getOpacity(int x, int y, int z) { default int getOpacity(int x, int y, int z) {
return getFullBlock(x, y, z).getMaterial().getLightOpacity(); return getFullBlock(x, y, z).getMaterial().getLightOpacity();
} }
default int[] getHeightMap(HeightMapType type) {
return new int[256];
}
} }

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extent; package com.sk89q.worldedit.extent;
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
@ -158,6 +159,9 @@ public interface OutputExtent {
default void setSkyLight(int x, int y, int z, int value) { default void setSkyLight(int x, int y, int z, int value) {
} }
default void setHeightMap(HeightMapType type, int[] heightMap) {
}
/** /**
* Return an {@link Operation} that should be called to tie up loose ends * Return an {@link Operation} that should be called to tie up loose ends
* (such as to commit changes in a buffer). * (such as to commit changes in a buffer).