*More off axis rotation changes

Fix off axis rotation for certain angles
- Math error when calculating the inverse affine transform
Add -a flag to copyPaste brush (rotates based on view)
This commit is contained in:
Jesse Boyd 2017-08-24 22:11:03 +10:00
parent 70e1e00e23
commit d14b267cfd
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
12 changed files with 47 additions and 25 deletions

View File

@ -24,18 +24,20 @@ import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Location;
public class CopyPastaBrush implements Brush, ResettableTool {
private final LocalSession session;
private final boolean randomRotate;
private final Player player;
public boolean autoRotate, randomRotate;
public CopyPastaBrush(Player player, LocalSession session, boolean randomRotate) {
public CopyPastaBrush(Player player, LocalSession session, boolean randomRotate, boolean autoRotate) {
session.setClipboard(null);
this.player = player;
this.session = session;
this.randomRotate = randomRotate;
this.autoRotate = autoRotate;
}
@Override
@ -65,7 +67,7 @@ public class CopyPastaBrush implements Brush, ResettableTool {
public boolean test(Vector vector) {
if (super.test(vector) && vector.getBlockY() >= minY) {
BaseBlock block = editSession.getLazyBlock(vector);
if (block != EditSession.nullBlock) {
if (block.getId() != 0) {
builder.add(vector, EditSession.nullBlock, block);
return true;
}
@ -87,19 +89,33 @@ public class CopyPastaBrush implements Brush, ResettableTool {
BBC.COMMAND_COPY.send(fp, blocks);
return;
} else {
AffineTransform transform = null;
if (randomRotate) {
if (transform == null) transform = new AffineTransform();
int rotate = 90 * PseudoRandom.random.nextInt(4);
clipboard.setTransform(rotate != 0 ? new AffineTransform().rotateY(rotate) : new AffineTransform());
transform = transform.rotateY(rotate);
}
if (autoRotate) {
if (transform == null) transform = new AffineTransform();
Location loc = editSession.getPlayer().getPlayer().getLocation();
float yaw = loc.getYaw();
float pitch = loc.getPitch();
transform = transform.rotateY((-yaw) % 360);
transform = transform.rotateX(pitch - 90);
}
if (transform != null && !transform.isIdentity()) {
clipboard.setTransform(transform);
}
Clipboard faweClip = clipboard.getClipboard();
Region region = faweClip.getRegion();
Vector centerOffset = region.getCenter().subtract(faweClip.getOrigin());
Operation operation = clipboard
.createPaste(editSession, editSession.getWorld().getWorldData())
.createPaste(editSession, editSession.getWorldData())
.to(position.add(0, 1, 0))
.ignoreAirBlocks(true)
.build();
Operations.completeLegacy(operation);
editSession.flushQueue();
}
}
}

View File

@ -29,7 +29,7 @@ public class PopulateSchem implements Brush {
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {
new MaskTraverser(mask).reset(editSession);
SchemGen gen = new SchemGen(mask, editSession, editSession.getWorldData(), clipboards, randomRotate);
CuboidRegion cuboid = new CuboidRegion(position.subtract(size, size, size), position.add(size, size, size));
CuboidRegion cuboid = new CuboidRegion(editSession.getWorld(), position.subtract(size, size, size), position.add(size, size, size));
try {
editSession.addSchems(cuboid, mask, editSession.getWorldData(), clipboards, rarity, randomRotate);
} catch (WorldEditException e) {

View File

@ -7,6 +7,7 @@ import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.function.pattern.Pattern;
public class SpikeBrush implements Brush {
@Override
public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException {

View File

@ -47,7 +47,7 @@ public class StencilBrush extends HeightBrush {
int cutoff = onlyWhite ? maxY : 0;
final SolidBlockMask solid = new SolidBlockMask(editSession);
final AdjacentAnyMask adjacent = new AdjacentAnyMask(Masks.negate(solid));
RegionMask region = new RegionMask(new CuboidRegion(position.subtract(size, size, size), position.add(size, size, size)));
RegionMask region = new RegionMask(new CuboidRegion(editSession.getWorld(), position.subtract(size, size, size), position.add(size, size, size)));
RecursiveVisitor visitor = new RecursiveVisitor(new Mask() {
@Override
public boolean test(Vector vector) {

View File

@ -3,7 +3,6 @@ package com.boydti.fawe.object.brush.heightmap;
import com.boydti.fawe.object.IntegerPair;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
@ -79,7 +78,7 @@ public class ScalableHeightMap implements com.boydti.fawe.object.brush.heightmap
for (int y = minY; y <= maxY; y++) {
pos.mutY(y);
BaseBlock block = clipboard.getBlock(pos);
if (block != EditSession.nullBlock) {
if (block.getId() != 0) {
highestY = y + 1;
}
}

View File

@ -114,7 +114,7 @@ public class PNGWriter implements ClipboardWriter {
mutableTop.mutY(y + 1);
mutableRight.mutY(y);
mutableLeft.mutY(y);
if (clipboard.getBlock(mutableTop) != EditSession.nullBlock && clipboard.getBlock(mutableRight) != EditSession.nullBlock && clipboard.getBlock(mutableLeft) != EditSession.nullBlock) {
if (clipboard.getBlock(mutableTop).getId() != 0 && clipboard.getBlock(mutableRight) != EditSession.nullBlock && clipboard.getBlock(mutableLeft).getId() != 0 ) {
continue;
}
double cpy = cpy2 - dpxi[y - y0];

View File

@ -1430,13 +1430,13 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
int freeSpot = startCheckY;
for (int y = startCheckY; y <= endY; y++) {
if (y < startPerformY) {
if (getLazyBlock(x, y, z) != EditSession.nullBlock) {
if (getLazyBlock(x, y, z).getId() != 0) {
freeSpot = y + 1;
}
continue;
}
BaseBlock block = getLazyBlock(x, y, z);
if (block != EditSession.nullBlock) {
if (block.getId() != 0) {
if (freeSpot != y) {
setBlock(x, freeSpot, z, block);
setBlock(x, y, z, replace);
@ -2217,11 +2217,11 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
return makeCylinder(pos, block, radiusX, radiusZ, height, 0, filled);
}
public int makeHollowCylinder(Vector pos, final Pattern block, double radiusX, double radiusZ, int height, int thickness) {
public int makeHollowCylinder(Vector pos, final Pattern block, double radiusX, double radiusZ, int height, double thickness) {
return makeCylinder(pos, block, radiusX, radiusZ, height, thickness, false);
}
private int makeCylinder(Vector pos, final Pattern block, double radiusX, double radiusZ, int height, int thickness, final boolean filled) {
private int makeCylinder(Vector pos, final Pattern block, double radiusX, double radiusZ, int height, double thickness, final boolean filled) {
radiusX += 0.5;
radiusZ += 0.5;

View File

@ -783,17 +783,19 @@ public class BrushCommands extends MethodCommands {
help = "Left click the base of an object to copy.\n" +
"Right click to paste\n" +
"The -r flag Will apply random rotation on paste\n" +
"The -a flag Will apply auto view based rotation on paste\n" +
"Note: Works well with the clipboard scroll action\n" +
"Video: https://www.youtube.com/watch?v=RPZIaTbqoZw",
min = 0,
max = 1
)
@CommandPermissions("worldedit.brush.copy")
public BrushSettings copy(Player player, LocalSession session, @Optional("5") double radius, @Switch('r') boolean rotate, CommandContext context) throws WorldEditException {
public BrushSettings copy(Player player, LocalSession session, @Optional("5") double radius, @Switch('r') boolean randomRotate, @Switch('a') boolean autoRotate, CommandContext context) throws WorldEditException {
worldEdit.checkMaxBrushRadius(radius);
player.print(BBC.getPrefix() + BBC.BRUSH_COPY.f(radius));
return get(context)
.setBrush(new CopyPastaBrush(player, session, rotate))
.setBrush(new CopyPastaBrush(player, session, randomRotate, autoRotate))
.setSize(radius);
}

View File

@ -184,7 +184,7 @@ public class GenerationCommands extends MethodCommands {
)
@CommandPermissions("worldedit.generation.cylinder")
@Logging(PLACEMENT)
public void hcyl(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, Vector2D radius, @Optional("1") int height, @Range(min = 1) @Optional("1") int thickness, CommandContext context) throws WorldEditException, ParameterException {
public void hcyl(FawePlayer fp, Player player, LocalSession session, EditSession editSession, Pattern pattern, Vector2D radius, @Optional("1") int height, @Range(min = 1) @Optional("1") double thickness, CommandContext context) throws WorldEditException, ParameterException {
double max = MathMan.max(radius.getBlockX(), radius.getBlockZ());
worldEdit.checkMaxRadius(max);
fp.checkConfirmationRadius(getArguments(context), (int) max);

View File

@ -25,6 +25,7 @@ import com.boydti.fawe.object.extent.BlockTranslateExtent;
import com.boydti.fawe.object.extent.PositionTransformExtent;
import com.boydti.fawe.object.function.block.BiomeCopy;
import com.boydti.fawe.object.function.block.SimpleBlockCopy;
import com.boydti.fawe.util.MaskTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
@ -249,8 +250,10 @@ public class ForwardExtentCopy implements Operation {
} else {
queue = null;
}
Extent finalDest = destination;
Vector translation = to.subtract(from);
if (!translation.equals(Vector.ZERO)) {
finalDest = new BlockTranslateExtent(finalDest, translation.getBlockX(), translation.getBlockY(), translation.getBlockZ());
}
@ -264,6 +267,7 @@ public class ForwardExtentCopy implements Operation {
RegionFunction copy = new SimpleBlockCopy(transExt, finalDest);
if (sourceMask != Masks.alwaysTrue()) {
new MaskTraverser(sourceMask).reset(transExt);
copy = new RegionMaskingFilter(sourceMask, copy);
}
if (sourceFunction != null) {

View File

@ -150,7 +150,7 @@ public class AffineTransform implements Transform, Serializable {
*
* @return the determinant of the transform.
*/
private double determinant() {
public double determinant() {
return m00 * (m11 * m22 - m12 * m21) - m01 * (m10 * m22 - m20 * m12)
+ m02 * (m10 * m21 - m20 * m11);
}
@ -163,17 +163,17 @@ public class AffineTransform implements Transform, Serializable {
double det = this.determinant();
return new AffineTransform(
(m11 * m22 - m21 * m12) / det,
(m21 * m01 - m01 * m22) / det,
(m02 * m21 - m22 * m01) / det,
(m01 * m12 - m11 * m02) / det,
(m01 * (m22 * m13 - m12 * m23) + m02 * (m11 * m23 - m21 * m13)
- m03 * (m11 * m22 - m21 * m12)) / det,
(m20 * m12 - m10 * m22) / det,
(m12 * m20 - m22 * m10) / det,
(m00 * m22 - m20 * m02) / det,
(m10 * m02 - m00 * m12) / det,
(m02 * m10 - m12 * m00) / det,
(m00 * (m12 * m23 - m22 * m13) - m02 * (m10 * m23 - m20 * m13)
+ m03 * (m10 * m22 - m20 * m12)) / det,
(m10 * m21 - m20 * m11) / det,
(m20 * m01 - m00 * m21) / det,
(m01 * m20 - m21 * m00) / det,
(m00 * m11 - m10 * m01) / det,
(m00 * (m21 * m13 - m11 * m23) + m01 * (m10 * m23 - m20 * m13)
- m03 * (m10 * m21 - m20 * m11)) / det);

View File

@ -137,8 +137,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
if (pos1 == null || pos2 == null) {
return;
}
pos1 = pos1.clampY(0, world == null ? 255 : world.getMaxY());
pos2 = pos2.clampY(0, world == null ? 255 : world.getMaxY());
pos1 = pos1.clampY(world == null ? Integer.MIN_VALUE : 0, world == null ? Integer.MAX_VALUE : world.getMaxY());
pos2 = pos2.clampY(world == null ? Integer.MIN_VALUE : 0, world == null ? Integer.MAX_VALUE : world.getMaxY());
Vector min = getMinimumPoint();
Vector max = getMaximumPoint();
minX = min.getBlockX();