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:
Jesse Boyd 2017-09-05 21:50:12 +10:00
parent cc7719e0e4
commit fb444ad5c4
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
9 changed files with 125 additions and 57 deletions

View File

@ -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!");

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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;
}

View File

@ -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() }) {