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()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user