Various minor
Fix skull rotation Fix off axis rotation issues after reloading disk clipboard Fix image loading removing alpha Add masking support to 2 cfi blockBiomeColor
This commit is contained in:
parent
cc7719e0e4
commit
fb444ad5c4
@ -460,6 +460,43 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
this.biomePriority = ((value * 65536) / 100) - 32768;
|
||||
}
|
||||
|
||||
public void setBlockAndBiomeColor(BufferedImage img, Mask mask, BufferedImage imgMask, boolean whiteOnly) {
|
||||
if (mask == null && imgMask == null) {
|
||||
setBlockAndBiomeColor(img);
|
||||
return;
|
||||
}
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
TextureUtil textureUtil = getTextureUtil();
|
||||
int index = 0;
|
||||
int widthIndex = img.getWidth() - 1;
|
||||
int heightIndex = img.getHeight() - 1;
|
||||
int maxIndex = biomes.length - 1;
|
||||
|
||||
int[] buffer = new int[2];
|
||||
for (int z = 0; z < img.getHeight(); z++) {
|
||||
mutable.mutZ(z);
|
||||
for (int x = 0; x < img.getWidth(); x++, index++) {
|
||||
if (mask != null) {
|
||||
mutable.mutX(z);
|
||||
mutable.mutY(heights[index] & 0xFF);
|
||||
if (!mask.test(mutable)) continue;
|
||||
}
|
||||
if (imgMask != null) {
|
||||
int height = imgMask.getRGB(x, z) & 0xFF;
|
||||
if (height != 255 && (height <= 0 || !whiteOnly || PseudoRandom.random.nextInt(256) > height)) continue;
|
||||
}
|
||||
int color = img.getRGB(x, z);
|
||||
if (textureUtil.getIsBlockCloserThanBiome(buffer, color, biomePriority)) {
|
||||
char combined = (char) buffer[0];
|
||||
main[index] = combined;
|
||||
floor[index] = combined;
|
||||
}
|
||||
biomes[index] = (byte) buffer[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlockAndBiomeColor(BufferedImage img) {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
|
@ -11,7 +11,6 @@ import java.awt.image.Raster;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashSet;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class ScalableHeightMap implements com.boydti.fawe.object.brush.heightmap.HeightMap {
|
||||
public int size2;
|
||||
@ -91,7 +90,7 @@ public class ScalableHeightMap implements com.boydti.fawe.object.brush.heightmap
|
||||
}
|
||||
|
||||
public static ScalableHeightMap fromPNG(InputStream stream) throws IOException {
|
||||
BufferedImage heightFile = MainUtil.toRGB(ImageIO.read(stream));
|
||||
BufferedImage heightFile = MainUtil.readImage(stream);
|
||||
int width = heightFile.getWidth();
|
||||
int length = heightFile.getHeight();
|
||||
Raster data = heightFile.getData();
|
||||
|
@ -163,12 +163,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
|
||||
public BlockArrayClipboard toClipboard() {
|
||||
try {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(width - 1, height - 1, length - 1)) {
|
||||
@Override
|
||||
public boolean contains(Vector position) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(width - 1, height - 1, length - 1));
|
||||
int ox = mbb.getShort(8);
|
||||
int oy = mbb.getShort(10);
|
||||
int oz = mbb.getShort(12);
|
||||
|
@ -52,7 +52,6 @@ import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@CommandDeclaration(
|
||||
command = "cfi",
|
||||
@ -327,12 +326,24 @@ public class CreateFromImage extends Command {
|
||||
}
|
||||
case "blockbiomecolor":
|
||||
case "setblockandbiomecolor": {
|
||||
if (argList.size() != 2) {
|
||||
if (argList.size() < 2) {
|
||||
C.COMMAND_SYNTAX.send(player, "/2 cfi " + argList.get(0) + " <url>");
|
||||
return;
|
||||
}
|
||||
BufferedImage image = getImage(argList.get(1), fp);
|
||||
generator.setBlockAndBiomeColor(image);
|
||||
BufferedImage imgMask = null;
|
||||
Mask mask = null;
|
||||
boolean whiteOnly = true;
|
||||
if (argList.size() > 2) {
|
||||
String arg2 = argList.get(2);
|
||||
if (arg2.startsWith("http") || arg2.startsWith("file://")) {
|
||||
imgMask = getImage(arg2, fp);
|
||||
} else {
|
||||
mask = we.getMaskFactory().parseFromInput(argList.get(1), context);
|
||||
}
|
||||
whiteOnly = argList.size() < 4 || Boolean.parseBoolean(argList.get(3));
|
||||
}
|
||||
generator.setBlockAndBiomeColor(image, mask, imgMask, whiteOnly);
|
||||
player.sendMessage("Set color, what's next?");
|
||||
return;
|
||||
}
|
||||
@ -619,7 +630,7 @@ public class CreateFromImage extends Command {
|
||||
if (arg.startsWith("http")) {
|
||||
URL url = new URL(arg);
|
||||
fp.sendMessage(BBC.getPrefix() + "Downloading image... (3)");
|
||||
BufferedImage img = MainUtil.toRGB(ImageIO.read(url));
|
||||
BufferedImage img = MainUtil.readImage(url);
|
||||
if (img == null) {
|
||||
throw new IOException("Failed to read " + url + ", please try again later");
|
||||
}
|
||||
@ -628,7 +639,7 @@ public class CreateFromImage extends Command {
|
||||
if (arg.startsWith("file://")) {
|
||||
arg = arg.substring(7);
|
||||
File file = MainUtil.getFile(MainUtil.getFile(Fawe.imp().getDirectory(), com.boydti.fawe.config.Settings.IMP.PATHS.HEIGHTMAP), arg);
|
||||
return MainUtil.toRGB(ImageIO.read(file));
|
||||
return MainUtil.readImage(file);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
@ -69,6 +70,7 @@ import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import net.jpountz.lz4.LZ4Compressor;
|
||||
@ -601,6 +603,25 @@ public class MainUtil {
|
||||
return destFile;
|
||||
}
|
||||
|
||||
public static BufferedImage readImage(InputStream in) throws IOException {
|
||||
try (DataInputStream dis = new DataInputStream(new BufferedInputStream(in, 1024))) {
|
||||
dis.mark(1024);
|
||||
boolean jpeg = dis.readInt() == 0xffd8ffe0;
|
||||
dis.reset();
|
||||
BufferedImage img = ImageIO.read(dis);
|
||||
if (jpeg) img = toRGB(img);
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
||||
public static BufferedImage readImage(URL url) throws IOException {
|
||||
return readImage(url.openStream());
|
||||
}
|
||||
|
||||
public static BufferedImage readImage(File file) throws IOException {
|
||||
return readImage(new FileInputStream(file));
|
||||
}
|
||||
|
||||
public static BufferedImage toRGB(BufferedImage src) {
|
||||
if (src == null) return src;
|
||||
BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_BGR);
|
||||
|
@ -90,6 +90,7 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
||||
offsetColor = color;
|
||||
}
|
||||
BaseBlock res = super.getNearestBlock(offsetColor);
|
||||
if (res == null) return null;
|
||||
int newColor = getColor(res);
|
||||
{
|
||||
byte dr = (byte) (((color >> 16) & 0xFF) - ((newColor >> 16) & 0xFF));
|
||||
|
@ -59,7 +59,6 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
|
||||
import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL;
|
||||
@ -129,7 +128,7 @@ public class GenerationCommands extends MethodCommands {
|
||||
throw new IOException("Only i.imgur.com or empcraft.com/ui links are allowed!");
|
||||
}
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
BufferedImage image = MainUtil.toRGB(ImageIO.read(url));
|
||||
BufferedImage image = MainUtil.readImage(url);
|
||||
MutableBlockVector pos1 = new MutableBlockVector(player.getPosition());
|
||||
MutableBlockVector pos2 = new MutableBlockVector(pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1));
|
||||
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
||||
|
@ -2,14 +2,19 @@ package com.sk89q.worldedit.extent.transform;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.helper.MCDirections;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||
import com.sk89q.worldedit.world.registry.State;
|
||||
@ -75,26 +80,26 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag != null) {
|
||||
newBlock = new BaseBlock(newBlock.getId(), newBlock.getData(), tag);
|
||||
// if (tag.containsKey("Rot")) {
|
||||
// int rot = tag.asInt("Rot");
|
||||
//
|
||||
// Direction direction = MCDirections.fromRotation(rot);
|
||||
//
|
||||
// if (direction != null) {
|
||||
// Vector applyAbsolute = transform.apply(direction.toVector());
|
||||
// Vector applyOrigin = transform.apply(Vector.ZERO);
|
||||
// applyAbsolute.x -= applyOrigin.x;
|
||||
// applyAbsolute.y -= applyOrigin.y;
|
||||
// applyAbsolute.z -= applyOrigin.z;
|
||||
//
|
||||
// Direction newDirection = Direction.findClosest(applyAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
//
|
||||
// if (newDirection != null) {
|
||||
// Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
// values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (tag.containsKey("Rot")) {
|
||||
int rot = tag.asInt("Rot");
|
||||
|
||||
Direction direction = MCDirections.fromRotation(rot);
|
||||
|
||||
if (direction != null) {
|
||||
Vector applyAbsolute = transform.apply(direction.toVector());
|
||||
Vector applyOrigin = transform.apply(Vector.ZERO);
|
||||
applyAbsolute.mutX(applyAbsolute.getBlockX() - applyOrigin.getBlockX());
|
||||
applyAbsolute.mutY(applyAbsolute.getBlockY() - applyOrigin.getBlockY());
|
||||
applyAbsolute.mutZ(applyAbsolute.getBlockZ() - applyOrigin.getBlockZ());
|
||||
|
||||
Direction newDirection = Direction.findClosest(applyAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
|
||||
if (newDirection != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newBlock;
|
||||
}
|
||||
@ -104,26 +109,26 @@ public class BlockTransformExtent extends ResettableExtent {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag != null) {
|
||||
newBlock = new BaseBlock(newBlock.getId(), newBlock.getData(), tag);
|
||||
// if (tag.containsKey("Rot")) {
|
||||
// int rot = tag.asInt("Rot");
|
||||
//
|
||||
// Direction direction = MCDirections.fromRotation(rot);
|
||||
//
|
||||
// if (direction != null) {
|
||||
// Vector applyAbsolute = transformInverse.apply(direction.toVector());
|
||||
// Vector applyOrigin = transformInverse.apply(Vector.ZERO);
|
||||
// applyAbsolute.x -= applyOrigin.x;
|
||||
// applyAbsolute.y -= applyOrigin.y;
|
||||
// applyAbsolute.z -= applyOrigin.z;
|
||||
//
|
||||
// Direction newDirection = Direction.findClosest(applyAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
//
|
||||
// if (newDirection != null) {
|
||||
// Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
// values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (tag.containsKey("Rot")) {
|
||||
int rot = tag.asInt("Rot");
|
||||
|
||||
Direction direction = MCDirections.fromRotation(rot);
|
||||
|
||||
if (direction != null) {
|
||||
Vector applyAbsolute = transformInverse.apply(direction.toVector());
|
||||
Vector applyOrigin = transformInverse.apply(Vector.ZERO);
|
||||
applyAbsolute.mutX(applyAbsolute.getBlockX() - applyOrigin.getBlockX());
|
||||
applyAbsolute.mutY(applyAbsolute.getBlockY() - applyOrigin.getBlockY());
|
||||
applyAbsolute.mutZ(applyAbsolute.getBlockZ() - applyOrigin.getBlockZ());
|
||||
|
||||
Direction newDirection = Direction.findClosest(applyAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
|
||||
if (newDirection != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newBlock;
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ public class BackwardsExtentBlockCopy implements Operation {
|
||||
private CuboidRegion transform(Transform transform, Region region) {
|
||||
Vector min = new MutableBlockVector(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
Vector max = new MutableBlockVector(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
Vector pos1 = region.getMinimumPoint().subtract(1, 1, 1);
|
||||
Vector pos2 = region.getMaximumPoint().add(1, 1, 1);
|
||||
Vector pos1 = region.getMinimumPoint();
|
||||
Vector pos2 = region.getMaximumPoint();
|
||||
for (int x : new int[] { pos1.getBlockX(), pos2.getBlockX() }) {
|
||||
for (int y : new int[] { pos1.getBlockY(), pos2.getBlockY() }) {
|
||||
for (int z : new int[] { pos1.getBlockZ(), pos2.getBlockZ() }) {
|
||||
|
Loading…
Reference in New Issue
Block a user