Added support for axis rotations.

This commit is contained in:
Matthew Miller 2018-11-17 12:00:19 +10:00
parent 24800a662a
commit 2dc9321da6
2 changed files with 59 additions and 7 deletions

View File

@ -30,6 +30,7 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.registry.state.BooleanProperty; import com.sk89q.worldedit.registry.state.BooleanProperty;
import com.sk89q.worldedit.registry.state.DirectionalProperty; import com.sk89q.worldedit.registry.state.DirectionalProperty;
import com.sk89q.worldedit.registry.state.EnumProperty;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
@ -49,8 +50,6 @@ import javax.annotation.Nullable;
*/ */
public class BlockTransformExtent extends AbstractDelegateExtent { public class BlockTransformExtent extends AbstractDelegateExtent {
private static final double RIGHT_ANGLE = Math.toRadians(90);
private final Transform transform; private final Transform transform;
/** /**
@ -129,15 +128,48 @@ public class BlockTransformExtent extends AbstractDelegateExtent {
List<? extends Property> properties = block.getBlockType().getProperties(); List<? extends Property> properties = block.getBlockType().getProperties();
for (Property property : properties) { for (Property<?> property : properties) {
if (property instanceof DirectionalProperty) { if (property instanceof DirectionalProperty) {
Direction value = (Direction) block.getState(property); Direction value = (Direction) block.getState(property);
if (value != null) { if (value != null) {
Vector3 newValue = getNewStateValue((DirectionalProperty) property, transform, value.toVector()); Vector3 newValue = getNewStateValue((List<Direction>) property.getValues(), transform, value.toVector());
if (newValue != null) { if (newValue != null) {
changedBlock = (T) changedBlock.with(property, Direction.findClosest(newValue, Direction.Flag.ALL)); changedBlock = (T) changedBlock.with(property, Direction.findClosest(newValue, Direction.Flag.ALL));
} }
} }
} else if (property instanceof EnumProperty) {
if (property.getName().equals("axis")) {
// We have an axis - this is something we can do the rotations to :sunglasses:
Direction value = null;
switch ((String) block.getState(property)) {
case "x":
value = Direction.EAST;
break;
case "y":
value = Direction.UP;
break;
case "z":
value = Direction.NORTH;
break;
}
if (value != null) {
Vector3 newValue = getNewStateValue(Direction.valuesOf(Direction.Flag.UPRIGHT | Direction.Flag.CARDINAL), transform, value.toVector());
if (newValue != null) {
String axis = null;
Direction newDir = Direction.findClosest(newValue, Direction.Flag.UPRIGHT | Direction.Flag.CARDINAL);
if (newDir == Direction.NORTH || newDir == Direction.SOUTH) {
axis = "z";
} else if (newDir == Direction.EAST || newDir == Direction.WEST) {
axis = "x";
} else if (newDir == Direction.UP || newDir == Direction.DOWN) {
axis = "y";
}
if (axis != null) {
changedBlock = (T) changedBlock.with(property, axis);
}
}
}
}
} }
} }
@ -166,19 +198,19 @@ public class BlockTransformExtent extends AbstractDelegateExtent {
/** /**
* Get the new value with the transformed direction. * Get the new value with the transformed direction.
* *
* @param state the state * @param allowedStates the allowed states
* @param transform the transform * @param transform the transform
* @param oldDirection the old direction to transform * @param oldDirection the old direction to transform
* @return a new state or null if none could be found * @return a new state or null if none could be found
*/ */
@Nullable @Nullable
private static Vector3 getNewStateValue(DirectionalProperty state, Transform transform, Vector3 oldDirection) { private static Vector3 getNewStateValue(List<Direction> allowedStates, Transform transform, Vector3 oldDirection) {
Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize(); Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize();
Vector3 newValue = null; Vector3 newValue = null;
double closest = -2; double closest = -2;
boolean found = false; boolean found = false;
for (Direction v : state.getValues()) { for (Direction v : allowedStates) {
double dot = v.toVector().normalize().dot(newDirection); double dot = v.toVector().normalize().dot(newDirection);
if (dot >= closest) { if (dot >= closest) {
closest = dot; closest = dot;

View File

@ -22,6 +22,9 @@ package com.sk89q.worldedit.util;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
@ -150,6 +153,23 @@ public enum Direction {
return closest; return closest;
} }
/**
* Gets all directions with the given flags.
*
* @param flags The flags
* @return The directions that fit the flags
*/
public static List<Direction> valuesOf(int flags) {
List<Direction> directions = new ArrayList<>();
for (Direction direction : values()) {
if ((~flags & direction.flags) == 0) {
directions.add(direction);
}
}
return directions;
}
/** /**
* Flags to use with {@link #findClosest(Vector3, int)}. * Flags to use with {@link #findClosest(Vector3, int)}.
*/ */