diff --git a/src/main/java/com/tocard/cam/Camera.java b/src/main/java/com/tocard/cam/Camera.java index c9e1afe..db12593 100644 --- a/src/main/java/com/tocard/cam/Camera.java +++ b/src/main/java/com/tocard/cam/Camera.java @@ -18,8 +18,8 @@ import org.bukkit.inventory.ItemStack; public class Camera extends JavaPlugin implements Listener { - public static ArrayList curve; - public static List controlPoints; + public static ArrayList curve; + public static List controlPoints; public static Logger logger; public static Plugin plugin; private static float dt = 0.01f; @@ -56,7 +56,7 @@ public class Camera extends JavaPlugin implements Listener { if (nControlPoints <= 4) { for (float t = 0; t < 1; t += dt) { - ArrayList P = new ArrayList<>(controlPoints); + ArrayList P = new ArrayList<>(controlPoints); int N = P.size(); for (int k = N - 1; k > 0; k--) { @@ -74,7 +74,7 @@ public class Camera extends JavaPlugin implements Listener { int nBezier = (nControlPoints - 1) / 3; for (int iBezier = 0; iBezier < nBezier; iBezier++) { for (float t = 0; t < 1; t += dt) { - ArrayList P = new ArrayList<>(); + ArrayList P = new ArrayList<>(); for (int k = 0; k < 4; k++) { P.add(controlPoints.get(3 * iBezier + k).clone()); } @@ -97,10 +97,11 @@ public class Camera extends JavaPlugin implements Listener { Bukkit.broadcastMessage(msg); } - public static String prettyLocation(Location point) { + public static String prettyLocation(LocationQuaternion point) { + Location loc = point.toLocation(); return String.format("X=%05.2f, Y=%05.2f, Z=%05.2f, P=%05.2f, Y=%05.2f", - point.getX(), point.getY(), point.getZ(), - point.getPitch(), point.getYaw()); + loc.getX(), loc.getY(), loc.getZ(), + loc.getPitch(), loc.getYaw()); } @Override diff --git a/src/main/java/com/tocard/cam/LocationQuaternion.java b/src/main/java/com/tocard/cam/LocationQuaternion.java new file mode 100644 index 0000000..a661612 --- /dev/null +++ b/src/main/java/com/tocard/cam/LocationQuaternion.java @@ -0,0 +1,90 @@ +package com.tocard.cam; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +public class LocationQuaternion { + private double[] coordinates = new double[7]; + + public LocationQuaternion(Location location) { + coordinates[0] = location.getX(); + coordinates[1] = location.getY(); + coordinates[2] = location.getZ(); + + double yaw = location.getYaw(); + double pitch = location.getPitch(); + double roll = 0; + + double cy = Math.cos(yaw * 0.5); + double sy = Math.sin(yaw * 0.5); + double cp = Math.cos(pitch * 0.5); + double sp = Math.sin(pitch * 0.5); + double cr = Math.cos(roll * 0.5); + double sr = Math.sin(roll * 0.5); + + coordinates[3] = cr * cp * cy + sr * sp * sy; + coordinates[4] = sr * cp * cy - cr * sp * sy; + coordinates[5] = cr * sp * cy + sr * cp * sy; + coordinates[6] = cr * cp * sy - sr * sp * cy; + } + + public LocationQuaternion(double[] coords) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] = coords[i]; + } + } + + public LocationQuaternion add(LocationQuaternion lq) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] += lq.coordinates[i]; + } + return this; + } + + public LocationQuaternion add(Location l) { + LocationQuaternion lq = new LocationQuaternion(l); + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] += lq.coordinates[i]; + } + return this; + } + + public LocationQuaternion multiply(double m) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] *= m; + } + return this; + } + + public Location toLocation() { + // roll (x-axis rotation) + // double sinr_cosp = 2 * (coordinates[3] * coordinates[4] + coordinates[5] * + // coordinates[6]); + // double cosr_cosp = 1 - 2 * (coordinates[4] * coordinates[4] + coordinates[5] + // * coordinates[5]); + // double roll = Math.atan2(sinr_cosp, cosr_cosp); + + // pitch (y-axis rotation) + double pitch; + double sinp = 2 * (coordinates[3] * coordinates[5] - coordinates[6] * coordinates[4]); + if (Math.abs(sinp) >= 1) + pitch = Math.signum(sinp) * Math.PI / 2; // use 90 degrees if out of range + else + pitch = Math.asin(sinp); + + // yaw (z-axis rotation) + double siny_cosp = 2 * (coordinates[3] * coordinates[6] + coordinates[4] * coordinates[5]); + double cosy_cosp = 1 - 2 * (coordinates[5] * coordinates[5] + coordinates[6] * coordinates[6]); + double yaw = Math.atan2(siny_cosp, cosy_cosp); + + return new Location( + Bukkit.getWorlds().get(0), + coordinates[0], coordinates[1], coordinates[2], + (float) yaw, (float) pitch); + } + + @Override + public LocationQuaternion clone() { + return new LocationQuaternion(coordinates); + } +} diff --git a/src/main/java/com/tocard/cam/ShowCurve.java b/src/main/java/com/tocard/cam/ShowCurve.java index c821325..23397c0 100644 --- a/src/main/java/com/tocard/cam/ShowCurve.java +++ b/src/main/java/com/tocard/cam/ShowCurve.java @@ -60,12 +60,15 @@ public class ShowCurve implements CommandExecutor { @Override public void run() { // Get curve iterator - Iterator curveIterator = Camera.curve.iterator(); + Iterator curveIterator = Camera.curve.iterator(); // Draw path while (curveIterator.hasNext()) { player.getWorld().spawnParticle(Particle.ELECTRIC_SPARK, - curveIterator.next().clone().add(0, 1.8, 0), 1, + curveIterator.next().clone() + .add(new LocationQuaternion(new double[] { 0, 1.8, 0, 0, 0, 0, 0 })) + .toLocation(), + 1, 0, 0, 0, 0); } @@ -81,7 +84,9 @@ public class ShowCurve implements CommandExecutor { Camera.controlPoints.get(indMin).clone().multiply(1 - t) .add(Camera.controlPoints.get(indMax).clone() .multiply(t)) - .add(0, 1.8, 0), + .add(new LocationQuaternion( + new double[] { 0, 1.8, 0, 0, 0, 0, 0 })) + .toLocation(), 1, 0, 0, 0, 0); } @@ -98,8 +103,8 @@ public class ShowCurve implements CommandExecutor { return true; } - public static void add(Location point, World world) { - ArmorStand as = world.spawn(point, ArmorStand.class); + public static void add(LocationQuaternion point, World world) { + ArmorStand as = world.spawn(point.toLocation(), ArmorStand.class); as.setGravity(false); as.setVisible(false); as.setMarker(true); @@ -116,8 +121,8 @@ public class ShowCurve implements CommandExecutor { } @Deprecated - public static void insert(int index, Location point, World world) { - ArmorStand as = world.spawn(point, ArmorStand.class); + public static void insert(int index, LocationQuaternion point, World world) { + ArmorStand as = world.spawn(point.toLocation(), ArmorStand.class); as.setGravity(false); as.setVisible(false); as.setMarker(true); @@ -130,8 +135,8 @@ public class ShowCurve implements CommandExecutor { controlPointsArmorStands.add(index, as); } - public static void set(int index, Location point, World world) { - controlPointsArmorStands.get(index).teleport(point); + public static void set(int index, LocationQuaternion point, World world) { + controlPointsArmorStands.get(index).teleport(point.toLocation()); } public static void rm(int index) {