mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2025-01-21 07:41:42 +01:00
Off axis rotation
This commit is contained in:
parent
920095a2de
commit
3c4a709efc
@ -469,12 +469,6 @@ public class ClipboardCommands extends MethodCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.clipboard.rotate")
|
@CommandPermissions("worldedit.clipboard.rotate")
|
||||||
public void rotate(Player player, LocalSession session, Double yRotate, @Optional Double xRotate, @Optional Double zRotate) throws WorldEditException {
|
public void rotate(Player player, LocalSession session, Double yRotate, @Optional Double xRotate, @Optional Double zRotate) throws WorldEditException {
|
||||||
if ((yRotate != null && Math.abs(yRotate % 90) > 0.001) ||
|
|
||||||
xRotate != null && Math.abs(xRotate % 90) > 0.001 ||
|
|
||||||
zRotate != null && Math.abs(zRotate % 90) > 0.001) {
|
|
||||||
player.printDebug("Note: Interpolation is not yet supported, so angles that are multiples of 90 is recommended.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
AffineTransform transform = new AffineTransform();
|
AffineTransform transform = new AffineTransform();
|
||||||
transform = transform.rotateY(-(yRotate != null ? yRotate : 0));
|
transform = transform.rotateY(-(yRotate != null ? yRotate : 0));
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package com.sk89q.worldedit.function.operation;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.function.RegionFunction;
|
||||||
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BackwardsExtentBlockCopy implements Operation {
|
||||||
|
private final Region region;
|
||||||
|
private final Transform transform;
|
||||||
|
private final Extent destination;
|
||||||
|
private final Extent source;
|
||||||
|
private final RegionFunction function;
|
||||||
|
private final Vector origin;
|
||||||
|
|
||||||
|
private Vector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
|
public BackwardsExtentBlockCopy(Extent source, Region region, Extent destination, Vector origin, Transform transform, RegionFunction function) {
|
||||||
|
this.source = source;
|
||||||
|
this.region = region;
|
||||||
|
this.destination = destination;
|
||||||
|
this.transform = transform;
|
||||||
|
this.function = function;
|
||||||
|
this.origin = origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operation resume(RunContext run) throws WorldEditException {
|
||||||
|
CuboidRegion destRegion = transform(this.transform, this.region);
|
||||||
|
Transform inverse = this.transform.inverse();
|
||||||
|
for (Vector pt : destRegion) {
|
||||||
|
Vector copyFrom = transform(inverse, pt);
|
||||||
|
if (region.contains(copyFrom)) {
|
||||||
|
function.apply(pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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() }) {
|
||||||
|
Vector pt = transform(transform, new Vector(x, y, z)).toBlockVector();
|
||||||
|
min = Vector.getMinimum(min, pt);
|
||||||
|
max = Vector.getMaximum(max, pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new CuboidRegion(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector transform(Transform transform, Vector pt) {
|
||||||
|
mutable.mutX(((pt.getBlockX() - origin.getBlockX())));
|
||||||
|
mutable.mutY(((pt.getBlockY() - origin.getBlockY())));
|
||||||
|
mutable.mutZ(((pt.getBlockZ() - origin.getBlockZ())));
|
||||||
|
Vector tmp = transform.apply(mutable);
|
||||||
|
tmp.mutX((tmp.getBlockX() + origin.getBlockX()));
|
||||||
|
tmp.mutY((tmp.getBlockY() + origin.getBlockY()));
|
||||||
|
tmp.mutZ((tmp.getBlockZ() + origin.getBlockZ()));
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addStatusMessages(List<String> messages) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,7 @@ import com.sk89q.worldedit.function.mask.Mask;
|
|||||||
import com.sk89q.worldedit.function.mask.Masks;
|
import com.sk89q.worldedit.function.mask.Masks;
|
||||||
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
||||||
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||||
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
import com.sk89q.worldedit.math.transform.Identity;
|
import com.sk89q.worldedit.math.transform.Identity;
|
||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
@ -253,14 +254,33 @@ public class ForwardExtentCopy implements Operation {
|
|||||||
if (!translation.equals(Vector.ZERO)) {
|
if (!translation.equals(Vector.ZERO)) {
|
||||||
finalDest = new BlockTranslateExtent(finalDest, translation.getBlockX(), translation.getBlockY(), translation.getBlockZ());
|
finalDest = new BlockTranslateExtent(finalDest, translation.getBlockX(), translation.getBlockY(), translation.getBlockZ());
|
||||||
}
|
}
|
||||||
PositionTransformExtent transExt;
|
|
||||||
|
Operation blockCopy = null;
|
||||||
|
PositionTransformExtent transExt = null;
|
||||||
if (!currentTransform.isIdentity()) {
|
if (!currentTransform.isIdentity()) {
|
||||||
|
if (!(currentTransform instanceof AffineTransform) || ((AffineTransform) currentTransform).isOffAxis()) {
|
||||||
|
transExt = new PositionTransformExtent(source, currentTransform.inverse());
|
||||||
|
transExt.setOrigin(from);
|
||||||
|
|
||||||
|
RegionFunction copy = new SimpleBlockCopy(transExt, finalDest);
|
||||||
|
if (sourceMask != Masks.alwaysTrue()) {
|
||||||
|
copy = new RegionMaskingFilter(sourceMask, copy);
|
||||||
|
}
|
||||||
|
if (sourceFunction != null) {
|
||||||
|
copy = new CombinedRegionFunction(copy, sourceFunction);
|
||||||
|
}
|
||||||
|
if (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) {
|
||||||
|
copy = new CombinedRegionFunction(copy, new BiomeCopy(source, finalDest));
|
||||||
|
}
|
||||||
|
blockCopy = new BackwardsExtentBlockCopy(transExt, region, finalDest, from, transform, copy);
|
||||||
|
} else {
|
||||||
transExt = new PositionTransformExtent(finalDest, currentTransform);
|
transExt = new PositionTransformExtent(finalDest, currentTransform);
|
||||||
transExt.setOrigin(from);
|
transExt.setOrigin(from);
|
||||||
finalDest = transExt;
|
finalDest = transExt;
|
||||||
} else {
|
|
||||||
transExt = null;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockCopy == null) {
|
||||||
RegionFunction copy = new SimpleBlockCopy(source, finalDest);
|
RegionFunction copy = new SimpleBlockCopy(source, finalDest);
|
||||||
if (sourceMask != Masks.alwaysTrue()) {
|
if (sourceMask != Masks.alwaysTrue()) {
|
||||||
copy = new RegionMaskingFilter(sourceMask, copy);
|
copy = new RegionMaskingFilter(sourceMask, copy);
|
||||||
@ -271,12 +291,13 @@ public class ForwardExtentCopy implements Operation {
|
|||||||
if (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) {
|
if (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) {
|
||||||
copy = new CombinedRegionFunction(copy, new BiomeCopy(source, finalDest));
|
copy = new CombinedRegionFunction(copy, new BiomeCopy(source, finalDest));
|
||||||
}
|
}
|
||||||
RegionVisitor blockVisitor = new RegionVisitor(region, copy, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
|
blockCopy = new RegionVisitor(region, copy, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
|
||||||
|
}
|
||||||
|
|
||||||
List<? extends Entity> entities = isCopyEntities() ? source.getEntities(region) : new ArrayList<>();
|
List<? extends Entity> entities = isCopyEntities() ? source.getEntities(region) : new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < repetitions; i++) {
|
for (int i = 0; i < repetitions; i++) {
|
||||||
Operations.completeBlindly(blockVisitor);
|
Operations.completeBlindly(blockCopy);
|
||||||
|
|
||||||
if (!entities.isEmpty()) {
|
if (!entities.isEmpty()) {
|
||||||
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
|
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
|
||||||
@ -291,7 +312,7 @@ public class ForwardExtentCopy implements Operation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
affected = blockVisitor.getAffected();
|
affected = region.getArea();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,18 @@ public class AffineTransform implements Transform, Serializable {
|
|||||||
return new double[]{m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23};
|
return new double[]{m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOffAxis() {
|
||||||
|
double[] c = coefficients();
|
||||||
|
for (int i = 0; i < c.length; i++) {
|
||||||
|
if ((i + 1) % 4 != 0) {
|
||||||
|
if (Math.abs(c[i]) != 1 && c[i] != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the determinant of this transform. Can be zero.
|
* Computes the determinant of this transform. Can be zero.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user