Some fixes to the erode brush

This commit is contained in:
Jesse Boyd 2017-02-20 01:50:05 +11:00
parent 3ce80033e5
commit 32808dfc81
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
6 changed files with 68 additions and 57 deletions

View File

@ -28,7 +28,7 @@ ext {
date = git.head().date.format("yy.MM.dd")
revision = "-${git.head().abbreviatedId}"
parents = git.head().parentIds;
index = -71; // Offset to mach CI
index = -72; // Offset to mach CI
int major, minor, patch;
major = minor = patch = 0;
for (;parents != null && !parents.isEmpty();index++) {

View File

@ -114,7 +114,7 @@ public enum BBC {
BRUSH_COPY("Copy brush equipped (%s0). Left click the base of an object to copy, right click to paste. Increase the brush radius if necessary.", "WorldEdit.Brush"),
BRUSH_COMMAND("Command brush equipped (%s0)", "WorldEdit.Brush"),
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2).", "WorldEdit.Brush"),
BRUSH_SMOOTH("Smooth brush equipped (%s0 x %s1 using %s2. Note: Use the blend brush if you want to smooth overhangs or caves.).", "WorldEdit.Brush"),
BRUSH_SPHERE("Sphere brush shape equipped (%s0).", "WorldEdit.Brush"),
BRUSH_LINE("Line brush shape equipped (%s0).", "WorldEdit.Brush"),
BRUSH_SPLINE("Line brush shape equipped (%s0). Right click an end to add a shape", "WorldEdit.Brush"),
@ -122,7 +122,7 @@ public enum BBC {
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"),
BRUSH_BLEND_BALL("Blend ball brush equipped (%s0).", "WorldEdit.Brush"),
BRUSH_ERODE("Erode brush equipped (%s0).", "WorldEdit.Brush"),
BRUSH_ERODE("Erode brush equipped (%s0). Right click to erode, left click to pull.", "WorldEdit.Brush"),
BRUSH_RECURSIVE("Recursive brush equipped (%s0).", "WorldEdit.Brush"),
BRUSH_PASTE_NONE("Nothing to paste", "WorldEdit.Brush"),
BRUSH_SIZE("Brush size set", "WorldEdit.Brush"),

View File

@ -6,14 +6,12 @@ import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
import com.boydti.fawe.object.clipboard.FaweClipboard;
import com.boydti.fawe.object.clipboard.OffsetFaweClipboard;
import com.google.common.collect.Maps;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.function.pattern.Pattern;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.Map;
import java.util.Arrays;
public class ErodeBrush implements DoubleActionBrush {
@ -25,18 +23,18 @@ public class ErodeBrush implements DoubleActionBrush {
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
switch (action) {
case PRIMARY: {
int erodeFaces = this.rand.nextInt(5) + 1;
int erodeRec = this.rand.nextInt(4) + 1;
int fillFaces = (int)(this.rand.nextDouble() * this.rand.nextDouble() * 5) + 1;
int fillRec = this.rand.nextInt(3) + 1;
int erodeFaces = 2;
int erodeRec = 1;
int fillFaces = 5;
int fillRec = 1;
this.erosion(editSession, erodeFaces, erodeRec, fillFaces, fillRec, position, size);
break;
}
case SECONDARY: {
int erodeFaces = (int)(this.rand.nextDouble() * this.rand.nextDouble() * 5) + 1;
int erodeRec = this.rand.nextInt(3) + 1;
int fillFaces = this.rand.nextInt(5) + 1;
int fillRec = this.rand.nextInt(4) + 1;
int erodeFaces = 6;
int erodeRec = 0;
int fillFaces = 1;
int fillRec = 1;
this.erosion(editSession, erodeFaces, erodeRec, fillFaces, fillRec, position, size);
break;
}
@ -45,20 +43,20 @@ public class ErodeBrush implements DoubleActionBrush {
protected void erosion(final EditSession es, int erodeFaces, int erodeRec, int fillFaces, int fillRec, Vector target, double size) {
int brushSize = (int) size + 1;
int brushSizeSquared = (int) size * (int) size;
int brushSizeSquared = (int) (size * size);
int dimension = brushSize * 2 + 1;
FaweClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension + 2, dimension + 2, dimension + 2), brushSize + 1);
FaweClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension + 2, dimension + 2, dimension + 2), brushSize + 1);
FaweClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
FaweClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
final int bx = target.getBlockX();
final int by = target.getBlockY();
final int bz = target.getBlockZ();
for (int x = -brushSize - 1; x <= brushSize + 1; x++) {
for (int x = -brushSize; x <= brushSize; x++) {
int x0 = x + bx;
for (int y = -brushSize - 1; y <= brushSize + 1; y++) {
for (int y = -brushSize; y <= brushSize; y++) {
int y0 = y + by;
for (int z = -brushSize - 1; z <= brushSize + 1; z++) {
for (int z = -brushSize; z <= brushSize; z++) {
int z0 = z + bz;
BaseBlock state = es.getBlock(x0, y0, z0);
buffer1.setBlock(x, y, z, state);
@ -88,12 +86,15 @@ public class ErodeBrush implements DoubleActionBrush {
}
private void fillIteration(int brushSize, int brushSizeSquared, int fillFaces, FaweClipboard current, FaweClipboard target) {
Map<BaseBlock, Integer> frequency = Maps.newHashMap();
int[] frequency = null;
for (int x = -brushSize; x <= brushSize; x++) {
for (int y = -brushSize; y <= brushSize; y++) {
int x2 = x * x;
for (int z = -brushSize; z <= brushSize; z++) {
int x2y2 = x2 + z * z;
for (int y = -brushSize; y <= brushSize; y++) {
int cube = x2y2 + y * y;
target.setBlock(x, y, z, current.getBlock(x, y, z));
if (x * x + y * y + z * z >= brushSizeSquared) {
if (cube >= brushSizeSquared) {
continue;
}
BaseBlock state = current.getBlock(x, y, z);
@ -103,26 +104,24 @@ public class ErodeBrush implements DoubleActionBrush {
int total = 0;
int highest = 1;
BaseBlock highestState = state;
frequency.clear();
if (frequency == null) {
frequency = new int[4096];
} else {
Arrays.fill(frequency, 0);
}
for (Vector offs : FACES_TO_CHECK) {
BaseBlock next = current.getBlock(x + offs.getBlockX(), y + offs.getBlockY(), z + offs.getBlockZ());
if (FaweCache.isLiquidOrGas(next.getId())) {
continue;
}
total++;
Integer count = frequency.get(next);
if (count == null) {
count = 1;
} else {
count++;
}
if (count > highest) {
int count = ++frequency[next.getType()];
if (count >= highest) {
highest = count;
highestState = next;
}
frequency.put(next, count);
}
if (total > fillFaces) {
if (total >= fillFaces) {
target.setBlock(x, y, z, highestState);
}
}
@ -131,13 +130,15 @@ public class ErodeBrush implements DoubleActionBrush {
}
private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, FaweClipboard current, FaweClipboard target) {
Int2ObjectOpenHashMap<Integer> frequency = new Int2ObjectOpenHashMap<>();
int[] frequency = null;
for (int x = -brushSize; x <= brushSize; x++) {
for (int y = -brushSize; y <= brushSize; y++) {
int x2 = x * x;
for (int z = -brushSize; z <= brushSize; z++) {
int x2y2 = x2 + z * z;
for (int y = -brushSize; y <= brushSize; y++) {
int cube = x2y2 + y * y;
target.setBlock(x, y, z, current.getBlock(x, y, z));
if (x * x + y * y + z * z >= brushSizeSquared) {
if (cube >= brushSizeSquared) {
continue;
}
BaseBlock state = current.getBlock(x, y, z);
@ -146,31 +147,26 @@ public class ErodeBrush implements DoubleActionBrush {
}
int total = 0;
int highest = 1;
int highestState = FaweCache.getCombined(state);
frequency.clear();
int highestState = state.getType();
if (frequency == null) {
frequency = new int[4096];
} else {
Arrays.fill(frequency, 0);
}
for (Vector offs : FACES_TO_CHECK) {
BaseBlock next = current.getBlock(x + offs.getBlockX(), y + offs.getBlockY(), z + offs.getBlockZ());
if (!FaweCache.isLiquidOrGas(next.getId())) {
continue;
}
total++;
Integer count = frequency.get(next.getType());
if (count == null) {
count = 1;
} else {
count++;
}
int count = ++frequency[next.getType()];
if (count > highest) {
highest = count;
int combined = FaweCache.getCombined(next);
highestState = combined;
frequency.put(combined, count);
} else {
frequency.put(FaweCache.getCombined(next), count);
highestState = next.getType();
}
}
if (total > erodeFaces) {
target.setBlock(x, y, z, FaweCache.CACHE_BLOCK[highestState]);
if (total >= erodeFaces) {
target.setBlock(x, y, z, FaweCache.CACHE_BLOCK[highestState << 4]);
}
}
}

View File

@ -64,6 +64,22 @@ public class MathMan {
return (((long)x) << 32) | (y & 0xffffffffL);
}
public static final long tripleWorldCoord(int x, int y, int z) {
return y + (((long) x & 0x3FFFFFF) << 8) + (((long) z & 0x3FFFFFF) << 34);
}
public static final long untripleWorldCoordX(long triple) {
return (((triple >> 8) & 0x3FFFFFF) << 38) >> 38;
}
public static final long untripleWorldCoordY(long triple) {
return triple & 0xFF;
}
public static final long untripleWorldCoordZ(long triple) {
return (((triple >> 34) & 0x3FFFFFF) << 38) >> 38;
}
public static final short tripleBlockCoord(int x, int y, int z) {
return (short) ((x & 15) << 12 | (z & 15) << 8 | y);
}

View File

@ -185,8 +185,6 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
private int changes = 0;
private BlockBag blockBag;
private MutableBlockVector mutable = new MutableBlockVector();
private final int maxY;
public static final UUID CONSOLE = UUID.fromString("1-1-3-3-7");
@ -1943,6 +1941,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
final com.sk89q.worldedit.function.pattern.Pattern pattern = replacement != null ? new BlockPattern(replacement) : new BlockPattern(new BaseBlock(BlockID.AIR));
final BlockReplace remove = new BlockReplace(EditSession.this, pattern) {
private MutableBlockVector mutable = new MutableBlockVector();
@Override
// Only copy what's necessary
public boolean apply(Vector position) throws WorldEditException {

View File

@ -96,7 +96,7 @@ public class BrushCommands {
}
@Command(
aliases = { "blendball", "bb" },
aliases = { "blendball", "bb", "blend" },
usage = "[radius]",
desc = "Choose the blend ball brush",
help = "Chooses the blend ball brush",