Adds the SimpleVectorOperation class which is capable of rotating a RelativeBlockVector in 6 directions
This commit is contained in:
parent
05a5fb2160
commit
99ee5c6978
191
src/main/java/net/knarcraft/stargate/SimpleVectorOperation.java
Normal file
191
src/main/java/net/knarcraft/stargate/SimpleVectorOperation.java
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package net.knarcraft.stargate;
|
||||||
|
|
||||||
|
import org.bukkit.Axis;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simpler version of the vector operation class, but with the same functionality
|
||||||
|
*
|
||||||
|
* @author Kristian Knarvik
|
||||||
|
*/
|
||||||
|
public class SimpleVectorOperation {
|
||||||
|
|
||||||
|
private static final Map<BlockFace, Double> rotationAngles = new HashMap<>();
|
||||||
|
private static final Map<BlockFace, Vector> rotationAxes = new HashMap<>();
|
||||||
|
private static final Map<BlockFace, Axis> normalAxes = new HashMap<>();
|
||||||
|
private static final BlockFace defaultDirection = BlockFace.SOUTH;
|
||||||
|
private static final Axis defaultVerticalAxis = Axis.Y;
|
||||||
|
|
||||||
|
private final Axis normalAxis;
|
||||||
|
private boolean flipZAxis = false;
|
||||||
|
private final BlockFace facing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a vector operation to rotate vectors in the direction of a sign face
|
||||||
|
*
|
||||||
|
* <p>Gate structures have their relative location represented by a vector where x = outwards, y = down and
|
||||||
|
* z = right. The vector operation rotates the given vectors so that "outwards" is going the same direction as the
|
||||||
|
* given sign face.</p>
|
||||||
|
*
|
||||||
|
* @param signFace <p>The sign face of a gate's sign</p>
|
||||||
|
*/
|
||||||
|
public SimpleVectorOperation(BlockFace signFace) {
|
||||||
|
if (normalAxes.isEmpty()) {
|
||||||
|
initializeIrisNormalAxes();
|
||||||
|
initializeOperations();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.facing = signFace;
|
||||||
|
this.normalAxis = normalAxes.get(signFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block face of a sign given upon instantiation
|
||||||
|
*
|
||||||
|
* @return <p>The block face of a sign given upon instantiation</p>
|
||||||
|
*/
|
||||||
|
public BlockFace getFacing() {
|
||||||
|
return facing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the normal axis orthogonal to the opening plane
|
||||||
|
*
|
||||||
|
* <p>Said another way, get the axis going directly towards or away from a stargate's entrance.</p>
|
||||||
|
*
|
||||||
|
* @return <p>The normal axis orthogonal to the iris plane</p>
|
||||||
|
*/
|
||||||
|
public Axis getNormalAxis() {
|
||||||
|
return normalAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to flip the Z- axis
|
||||||
|
*
|
||||||
|
* @param flipZAxis <p>Whether to flip the z-axis</p>
|
||||||
|
*/
|
||||||
|
public void setFlipZAxis(boolean flipZAxis) {
|
||||||
|
this.flipZAxis = flipZAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs this vector operation on the given vector
|
||||||
|
*
|
||||||
|
* <p>Inverse operation of doInverse; A vector operation that rotates around the origin, and flips the z-axis.
|
||||||
|
* Does not permute input vector</p>
|
||||||
|
*
|
||||||
|
* @param vector <p>The vector to perform the operation on</p>
|
||||||
|
* @return vector <p>A new vector with the operation applied</p>
|
||||||
|
*/
|
||||||
|
public Vector performOperation(Vector vector) {
|
||||||
|
Vector clone = vector.clone();
|
||||||
|
clone.rotateAroundAxis(rotationAxes.get(facing), rotationAngles.get(facing));
|
||||||
|
if (flipZAxis) {
|
||||||
|
clone.setZ(-clone.getZ());
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the reverse of this vector operation on the given vector
|
||||||
|
*
|
||||||
|
* <p>Inverse operation of doOperation; A vector operation that rotates around
|
||||||
|
* the origin and flips the z-axis. Does not permute input vector</p>
|
||||||
|
*
|
||||||
|
* @param vector <p>The vector to perform the inverse operation on</p>
|
||||||
|
* @return vector <p>A new vector with the inverse operation applied</p>
|
||||||
|
*/
|
||||||
|
public Vector performInverseOperation(Vector vector) {
|
||||||
|
Vector clone = vector.clone();
|
||||||
|
if (flipZAxis) {
|
||||||
|
clone.setZ(-clone.getZ());
|
||||||
|
}
|
||||||
|
return clone.rotateAroundAxis(rotationAxes.get(facing), -rotationAngles.get(facing));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the reverse of this vector operation on the given vector
|
||||||
|
*
|
||||||
|
* <p>Inverse operation of doOperation; A vector operation that rotates around
|
||||||
|
* the origin and flips the z-axis. Does not permute input vector</p>
|
||||||
|
*
|
||||||
|
* @param vector <p>The vector to perform the inverse operation on</p>
|
||||||
|
* @return vector <p>A new vector with the inverse operation applied</p>
|
||||||
|
*/
|
||||||
|
public BlockVector performInverseOperation(BlockVector vector) {
|
||||||
|
return performInverseOperation((Vector) vector).toBlockVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the operations used for rotating to each block-face
|
||||||
|
*/
|
||||||
|
private static void initializeOperations() {
|
||||||
|
Map<Axis, Vector> axisVectors = new HashMap<>();
|
||||||
|
axisVectors.put(Axis.Y, new Vector(0, 1, 0));
|
||||||
|
axisVectors.put(Axis.X, new Vector(1, 0, 0));
|
||||||
|
axisVectors.put(Axis.Z, new Vector(0, 0, 1));
|
||||||
|
|
||||||
|
//Use the cross product to find the correct axis
|
||||||
|
for (BlockFace face : normalAxes.keySet()) {
|
||||||
|
Vector crossProduct = face.getDirection().crossProduct(defaultDirection.getDirection());
|
||||||
|
if (face == defaultDirection || face == defaultDirection.getOppositeFace()) {
|
||||||
|
rotationAxes.put(face, axisVectors.get(defaultVerticalAxis));
|
||||||
|
} else if (Math.abs(crossProduct.getZ()) > 0) {
|
||||||
|
rotationAxes.put(face, axisVectors.get(Axis.Z));
|
||||||
|
} else if (Math.abs(crossProduct.getY()) > 0) {
|
||||||
|
rotationAxes.put(face, axisVectors.get(Axis.Y));
|
||||||
|
} else {
|
||||||
|
rotationAxes.put(face, axisVectors.get(Axis.X));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateRotations();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the required rotations based on the default rotation
|
||||||
|
*/
|
||||||
|
private static void calculateRotations() {
|
||||||
|
double halfRotation = Math.PI;
|
||||||
|
double quarterRotation = halfRotation / 2;
|
||||||
|
|
||||||
|
Vector defaultDirectionVector = defaultDirection.getDirection();
|
||||||
|
boolean defaultDirectionPositive = defaultDirectionVector.getX() + defaultDirectionVector.getY() +
|
||||||
|
defaultDirectionVector.getZ() > 0;
|
||||||
|
|
||||||
|
for (BlockFace blockFace : normalAxes.keySet()) {
|
||||||
|
if (defaultDirection == blockFace) {
|
||||||
|
//The default direction requires no rotation
|
||||||
|
rotationAngles.put(blockFace, 0d);
|
||||||
|
} else if (defaultDirection.getOppositeFace() == blockFace) {
|
||||||
|
//The opposite direction requires a half rotation
|
||||||
|
rotationAngles.put(blockFace, halfRotation);
|
||||||
|
} else {
|
||||||
|
//All the other used directions require a quarter rotation
|
||||||
|
Vector faceDirectionVector = blockFace.getDirection();
|
||||||
|
boolean faceDirectionPositive = faceDirectionVector.getX() + faceDirectionVector.getY() +
|
||||||
|
faceDirectionVector.getZ() > 0;
|
||||||
|
double rotation = defaultDirectionPositive && faceDirectionPositive ? quarterRotation : -quarterRotation;
|
||||||
|
rotationAngles.put(blockFace, rotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the iris normal axes corresponding to each block face
|
||||||
|
*/
|
||||||
|
private static void initializeIrisNormalAxes() {
|
||||||
|
normalAxes.put(BlockFace.EAST, Axis.Z);
|
||||||
|
normalAxes.put(BlockFace.WEST, Axis.Z);
|
||||||
|
normalAxes.put(BlockFace.NORTH, Axis.X);
|
||||||
|
normalAxes.put(BlockFace.SOUTH, Axis.X);
|
||||||
|
normalAxes.put(BlockFace.UP, Axis.Y);
|
||||||
|
normalAxes.put(BlockFace.DOWN, Axis.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package net.knarcraft.stargate.container;
|
package net.knarcraft.stargate.container;
|
||||||
|
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This stores a block location as a vector relative to a position
|
* This stores a block location as a vector relative to a position
|
||||||
*
|
*
|
||||||
@ -70,6 +72,15 @@ public class RelativeBlockVector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a relative vector in the real space representing this relative block vector
|
||||||
|
*
|
||||||
|
* @return <p>A vector representing this relative block vector</p>
|
||||||
|
*/
|
||||||
|
public Vector toVector() {
|
||||||
|
return new Vector(this.right, -this.down, this.out);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a relative block vector which is this inverted (pointing in the opposite direction)
|
* Gets a relative block vector which is this inverted (pointing in the opposite direction)
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.knarcraft.stargate.portal;
|
package net.knarcraft.stargate.portal;
|
||||||
|
|
||||||
|
import net.knarcraft.stargate.SimpleVectorOperation;
|
||||||
import net.knarcraft.stargate.container.BlockLocation;
|
import net.knarcraft.stargate.container.BlockLocation;
|
||||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||||
import net.knarcraft.stargate.portal.property.PortalLocation;
|
import net.knarcraft.stargate.portal.property.PortalLocation;
|
||||||
@ -8,6 +9,7 @@ import net.knarcraft.stargate.portal.property.PortalOptions;
|
|||||||
import net.knarcraft.stargate.portal.property.PortalOwner;
|
import net.knarcraft.stargate.portal.property.PortalOwner;
|
||||||
import net.knarcraft.stargate.portal.property.PortalStructure;
|
import net.knarcraft.stargate.portal.property.PortalStructure;
|
||||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||||
|
import net.knarcraft.stargate.utility.DirectionHelper;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -23,6 +25,7 @@ public class Portal {
|
|||||||
private final String cleanName;
|
private final String cleanName;
|
||||||
private final String network;
|
private final String network;
|
||||||
private final String cleanNetwork;
|
private final String cleanNetwork;
|
||||||
|
private final SimpleVectorOperation vectorOperation;
|
||||||
|
|
||||||
private final PortalOwner portalOwner;
|
private final PortalOwner portalOwner;
|
||||||
private boolean isRegistered;
|
private boolean isRegistered;
|
||||||
@ -59,6 +62,7 @@ public class Portal {
|
|||||||
this.portalActivator = portalOpener.getPortalActivator();
|
this.portalActivator = portalOpener.getPortalActivator();
|
||||||
this.cleanName = cleanString(name);
|
this.cleanName = cleanString(name);
|
||||||
this.cleanNetwork = cleanString(network);
|
this.cleanNetwork = cleanString(network);
|
||||||
|
this.vectorOperation = new SimpleVectorOperation(DirectionHelper.getBlockFaceFromYaw(portalLocation.getYaw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -294,7 +298,7 @@ public class Portal {
|
|||||||
* @return <p>The block at the given relative position</p>
|
* @return <p>The block at the given relative position</p>
|
||||||
*/
|
*/
|
||||||
public BlockLocation getBlockAt(RelativeBlockVector vector) {
|
public BlockLocation getBlockAt(RelativeBlockVector vector) {
|
||||||
return getTopLeft().getRelativeLocation(vector, getYaw());
|
return (BlockLocation) getTopLeft().clone().add(vectorOperation.performOperation(vector.toVector()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user