Compare commits
8 Commits
master
...
vertical-s
Author | SHA1 | Date | |
---|---|---|---|
2dcf7b7af0 | |||
0f0b8b7087 | |||
e1ca1fe8b0 | |||
6954d46af4 | |||
a1f25a794e | |||
fbabe7b117 | |||
5e456a1326 | |||
99ee5c6978 |
180
src/main/java/net/knarcraft/stargate/SimpleVectorOperation.java
Normal file
180
src/main/java/net/knarcraft/stargate/SimpleVectorOperation.java
Normal file
@ -0,0 +1,180 @@
|
||||
package net.knarcraft.stargate;
|
||||
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.BlockVector;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A class for performing rotational operations on vectors
|
||||
*
|
||||
* @author Kristian Knarvik
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
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
|
||||
*
|
||||
* @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 opening 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 an operation from the real space to the vector space
|
||||
*
|
||||
* @param vector <p>The vector to perform the operation on</p>
|
||||
* @return vector <p>A new vector with the operation applied</p>
|
||||
*/
|
||||
public Vector performToAbstractSpaceOperation(@NotNull Vector vector) {
|
||||
Vector clone = vector.clone();
|
||||
clone.rotateAroundAxis(rotationAxes.get(facing), rotationAngles.get(facing));
|
||||
if (flipZAxis) {
|
||||
clone.setZ(-clone.getZ());
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an operation from the vector space to the real space
|
||||
*
|
||||
* @param vector <p>The vector to perform the inverse operation on</p>
|
||||
* @return vector <p>A new vector with the operation applied</p>
|
||||
*/
|
||||
public Vector performToRealSpaceOperation(@NotNull Vector vector) {
|
||||
Vector clone = vector.clone();
|
||||
if (flipZAxis) {
|
||||
clone.setZ(-clone.getZ());
|
||||
}
|
||||
return clone.rotateAroundAxis(rotationAxes.get(facing), -rotationAngles.get(facing));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an operation from the vector space to the real space
|
||||
*
|
||||
* @param vector <p>The vector to perform the inverse operation on</p>
|
||||
* @return vector <p>A new vector with the operation applied</p>
|
||||
*/
|
||||
public BlockVector performToRealSpaceOperation(@NotNull BlockVector vector) {
|
||||
return performToRealSpaceOperation((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;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* This stores a block location as a vector relative to a position
|
||||
*
|
||||
@ -65,6 +67,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)
|
||||
*
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.knarcraft.stargate.portal;
|
||||
|
||||
import net.knarcraft.stargate.SimpleVectorOperation;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
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.PortalStructure;
|
||||
import net.knarcraft.stargate.portal.property.gate.Gate;
|
||||
import net.knarcraft.stargate.utility.DirectionHelper;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -23,6 +25,7 @@ public class Portal {
|
||||
private final String cleanName;
|
||||
private final String network;
|
||||
private final String cleanNetwork;
|
||||
private final SimpleVectorOperation vectorOperation;
|
||||
|
||||
private final PortalOwner portalOwner;
|
||||
private boolean isRegistered;
|
||||
@ -59,6 +62,7 @@ public class Portal {
|
||||
this.portalActivator = portalOpener.getPortalActivator();
|
||||
this.cleanName = cleanString(name);
|
||||
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>
|
||||
*/
|
||||
public BlockLocation getBlockAt(RelativeBlockVector vector) {
|
||||
return getTopLeft().getRelativeLocation(vector, getYaw());
|
||||
return (BlockLocation) getTopLeft().clone().add(vectorOperation.performToRealSpaceOperation(vector.toVector()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user