From a36a5be8fba7e02475aedfa220b6cde74a77b6e5 Mon Sep 17 00:00:00 2001 From: gdamms Date: Mon, 16 May 2022 18:22:40 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20a=20moiti=C3=A9=20les=20rotation=20baybl?= =?UTF-8?q?ed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Laureηt --- src/main/java/com/tocard/cam/Camera.java | 18 ++-- .../java/com/tocard/cam/ExecuteTraveling.java | 6 +- src/main/java/com/tocard/cam/ListPoints.java | 2 +- .../com/tocard/cam/LocationQuaternion.java | 57 +++++++++++- .../com/tocard/cam/LocationQuaternion2.java | 89 +++++++++++++++++++ src/main/java/com/tocard/cam/NewPoint.java | 40 ++++----- src/main/java/com/tocard/cam/ShowCurve.java | 16 ++-- 7 files changed, 190 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/tocard/cam/LocationQuaternion2.java diff --git a/src/main/java/com/tocard/cam/Camera.java b/src/main/java/com/tocard/cam/Camera.java index db12593..4b9d089 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; @@ -46,7 +46,15 @@ public class Camera extends JavaPlugin implements Listener { getServer().getPluginManager().registerEvents(this, this); } + public static void reverseQuaternions() { + for (int i = 1; i < controlPoints.size(); i++) { + controlPoints.get(i).invertQuaternion(controlPoints.get(i - 1)); + } + } + public static void compute() { + reverseQuaternions(); + int nControlPoints = controlPoints.size(); curve = new ArrayList<>(); @@ -56,7 +64,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 +82,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,7 +105,7 @@ public class Camera extends JavaPlugin implements Listener { Bukkit.broadcastMessage(msg); } - public static String prettyLocation(LocationQuaternion point) { + public static String prettyLocation(LocationQuaternion2 point) { Location loc = point.toLocation(); return String.format("X=%05.2f, Y=%05.2f, Z=%05.2f, P=%05.2f, Y=%05.2f", loc.getX(), loc.getY(), loc.getZ(), diff --git a/src/main/java/com/tocard/cam/ExecuteTraveling.java b/src/main/java/com/tocard/cam/ExecuteTraveling.java index 6c132e2..f2b8d9e 100644 --- a/src/main/java/com/tocard/cam/ExecuteTraveling.java +++ b/src/main/java/com/tocard/cam/ExecuteTraveling.java @@ -11,7 +11,7 @@ import java.util.Iterator; public class ExecuteTraveling implements CommandExecutor { private static int taskID = -1; - private static Iterator curveIterator; + private static Iterator curveIterator; @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { @@ -33,14 +33,14 @@ public class ExecuteTraveling implements CommandExecutor { public void run() { // Teleport to next point if (curveIterator.hasNext()) { - player.teleport(curveIterator.next()); + player.teleport(curveIterator.next().toLocation()); return; } // Regenerate traveling and begin if (ClosePath.closed) { curveIterator = Camera.curve.iterator(); - player.teleport(curveIterator.next()); + player.teleport(curveIterator.next().toLocation()); return; } diff --git a/src/main/java/com/tocard/cam/ListPoints.java b/src/main/java/com/tocard/cam/ListPoints.java index 6e6b267..69541a0 100644 --- a/src/main/java/com/tocard/cam/ListPoints.java +++ b/src/main/java/com/tocard/cam/ListPoints.java @@ -9,7 +9,7 @@ import org.bukkit.entity.Player; public class ListPoints implements CommandExecutor { - private static ListIterator points; + private static ListIterator points; @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { diff --git a/src/main/java/com/tocard/cam/LocationQuaternion.java b/src/main/java/com/tocard/cam/LocationQuaternion.java index a661612..6140241 100644 --- a/src/main/java/com/tocard/cam/LocationQuaternion.java +++ b/src/main/java/com/tocard/cam/LocationQuaternion.java @@ -11,8 +11,8 @@ public class LocationQuaternion { coordinates[1] = location.getY(); coordinates[2] = location.getZ(); - double yaw = location.getYaw(); - double pitch = location.getPitch(); + double yaw = location.getYaw() * Math.PI / 180; + double pitch = location.getPitch() * Math.PI / 180; double roll = 0; double cy = Math.cos(yaw * 0.5); @@ -41,6 +41,13 @@ public class LocationQuaternion { return this; } + public LocationQuaternion subtract(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++) { @@ -56,6 +63,11 @@ public class LocationQuaternion { return this; } + public double distance(LocationQuaternion loc) { + return Math.sqrt( + coordinates[0] * coordinates[0] + coordinates[1] * coordinates[1] + coordinates[2] * coordinates[2]); + } + public Location toLocation() { // roll (x-axis rotation) // double sinr_cosp = 2 * (coordinates[3] * coordinates[4] + coordinates[5] * @@ -80,7 +92,46 @@ public class LocationQuaternion { return new Location( Bukkit.getWorlds().get(0), coordinates[0], coordinates[1], coordinates[2], - (float) yaw, (float) pitch); + (float) (yaw * 180 / Math.PI), (float) (pitch * 180 / Math.PI)); + } + + public Location toLocation(double previousYaw) { + Location loc = toLocation(); + + double A = previousYaw; + double B = loc.getYaw(); + double b = B % 360; + int wholePart = 360 * (int) (A / 360); + + double minDist = -1; + double sol = 0; + for (int i = -1; i < 2; i++) { + double val = wholePart + b + i * 360; + double dist = Math.abs(val - A); + if (minDist == -1 || dist < minDist) { + sol = val; + minDist = dist; + } + } + Camera.broadlog("From " + coordinates[3] + " to " + sol); + loc.setYaw((float) sol); + return loc; + } + + public double dot(LocationQuaternion loc) { + double sum = 0; + for (int i = 3; i < 7; i++) { + sum += coordinates[i] + loc.coordinates[i]; + } + return sum; + } + + public LocationQuaternion invertQuaternion(LocationQuaternion previousLocationQuaternion) { + if (dot(previousLocationQuaternion) < 0) + for (int i = 3; i < 7; i++) { + coordinates[i] *= -1; + } + return this; } @Override diff --git a/src/main/java/com/tocard/cam/LocationQuaternion2.java b/src/main/java/com/tocard/cam/LocationQuaternion2.java new file mode 100644 index 0000000..01d9771 --- /dev/null +++ b/src/main/java/com/tocard/cam/LocationQuaternion2.java @@ -0,0 +1,89 @@ +package com.tocard.cam; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +public class LocationQuaternion2 { + public double[] coordinates = new double[5]; + + public LocationQuaternion2(Location location) { + coordinates[0] = location.getX(); + coordinates[1] = location.getY(); + coordinates[2] = location.getZ(); + coordinates[3] = location.getYaw(); + coordinates[4] = location.getPitch(); + } + + public LocationQuaternion2(double[] coords) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] = coords[i]; + } + } + + public LocationQuaternion2 add(LocationQuaternion2 lq) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] += lq.coordinates[i]; + } + return this; + } + + public LocationQuaternion2 subtract(LocationQuaternion2 lq) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] -= lq.coordinates[i]; + } + return this; + } + + public LocationQuaternion2 add(Location l) { + LocationQuaternion2 lq = new LocationQuaternion2(l); + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] += lq.coordinates[i]; + } + return this; + } + + public LocationQuaternion2 multiply(double m) { + for (int i = 0; i < coordinates.length; i++) { + coordinates[i] *= m; + } + return this; + } + + public double distance(LocationQuaternion2 loc) { + return Math.sqrt( + coordinates[0] * coordinates[0] + coordinates[1] * coordinates[1] + coordinates[2] * coordinates[2]); + } + + public Location toLocation() { + return new Location( + Bukkit.getWorlds().get(0), + coordinates[0], coordinates[1], coordinates[2], + (float) (coordinates[3]), (float) (coordinates[4])); + } + + public LocationQuaternion2 invertQuaternion(LocationQuaternion2 previousLocationQuaternion) { + double A = previousLocationQuaternion.coordinates[3]; + double B = coordinates[3]; + double b = B % 360; + int wholePart = 360 * (int) (A / 360); + + double minDist = -1; + double sol = 0; + for (int i = -1; i < 2; i++) { + double val = wholePart + b + i * 360; + double dist = Math.abs(val - A); + if (minDist == -1 || dist < minDist) { + sol = val; + minDist = dist; + } + } + Camera.broadlog("From " + coordinates[3] + " to " + sol); + coordinates[3] = sol; + return this; + } + + @Override + public LocationQuaternion2 clone() { + return new LocationQuaternion2(coordinates); + } +} diff --git a/src/main/java/com/tocard/cam/NewPoint.java b/src/main/java/com/tocard/cam/NewPoint.java index 45e6deb..fe3f035 100644 --- a/src/main/java/com/tocard/cam/NewPoint.java +++ b/src/main/java/com/tocard/cam/NewPoint.java @@ -16,13 +16,13 @@ public class NewPoint implements CommandExecutor { Player player = (Player) sender; switch (args[0]) { case "add": - add(args, player.getLocation(), player.getWorld()); + add(args, new LocationQuaternion2(player.getLocation()), player.getWorld()); break; case "rm": - rm(args, player.getLocation(), player.getWorld()); + rm(args, null, null); break; case "set": - set(args, player.getLocation(), player.getWorld()); + set(args, new LocationQuaternion2(player.getLocation()), player.getWorld()); break; default: break; @@ -38,34 +38,34 @@ public class NewPoint implements CommandExecutor { return true; } - public static void addPoint(Location point, World world) { + public static void addPoint(LocationQuaternion2 point, World world) { Camera.controlPoints.add(point); ShowCurve.add(point, world); Camera.broadlog("Point added: " + Camera.prettyLocation(point)); } - public static void setPoint(int index, Location point, World world) { + public static void setPoint(int index, LocationQuaternion2 point, World world) { Camera.controlPoints.set(index, point); ShowCurve.set(index, point, world); Camera.broadlog("Point n°" + index + " set: " + Camera.prettyLocation(point)); } public static void rmPoint(int index) { - Location location = Camera.controlPoints.remove(index); + LocationQuaternion2 location = Camera.controlPoints.remove(index); ShowCurve.rm(index); Camera.broadlog("Point deleted: " + Camera.prettyLocation(location)); } - public static void add(String[] args, Location location, World world) { + public static void add(String[] args, LocationQuaternion2 location, World world) { int n = Camera.controlPoints.size(); if (n < 4) { addPoint(location, world); } else { - Location P2 = Camera.controlPoints.get(n - 2); - Location P3 = Camera.controlPoints.get(n - 1); - Location P4 = P3.clone().multiply(2).subtract(P2); - Location P5 = location.clone().add(P4).multiply(0.5); + LocationQuaternion2 P2 = Camera.controlPoints.get(n - 2); + LocationQuaternion2 P3 = Camera.controlPoints.get(n - 1); + LocationQuaternion2 P4 = P3.clone().multiply(2).subtract(P2); + LocationQuaternion2 P5 = location.clone().add(P4).multiply(0.5); addPoint(P4, world); addPoint(P5, world); @@ -74,7 +74,7 @@ public class NewPoint implements CommandExecutor { } @Deprecated - public static void ins(String[] args, Location location, World world) { + public static void ins(String[] args, LocationQuaternion2 location, World world) { int index = Integer.parseInt(args[1]); Camera.controlPoints.add(index, location); Camera.broadlog("Point added: " + Camera.prettyLocation(location)); @@ -106,7 +106,7 @@ public class NewPoint implements CommandExecutor { } - public static void set(String[] args, Location location, World world) { + public static void set(String[] args, LocationQuaternion2 location, World world) { int n = Camera.controlPoints.size(); int index = Integer.parseInt(args[1]); @@ -118,7 +118,7 @@ public class NewPoint implements CommandExecutor { switch (index % 3) { case 0: // Anchor point - Location shift = location.clone().subtract(Camera.controlPoints.get(index)); + LocationQuaternion2 shift = location.clone().subtract(Camera.controlPoints.get(index)); for (int i = 0; i < 3; i++) { try { setPoint(index + i - 1, Camera.controlPoints.get(index + i - 1).clone().add(shift), world); @@ -131,12 +131,12 @@ public class NewPoint implements CommandExecutor { // Control point after an anchor if (index - 2 >= 0) { // Get anchor-location direction - Location anchor = Camera.controlPoints.get(index - 1); + LocationQuaternion2 anchor = Camera.controlPoints.get(index - 1); double currentDistance = anchor.distance(location); - Location currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance); + LocationQuaternion2 currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance); // Get anchor-corresponding distance - Location correspondingControl = Camera.controlPoints.get(index - 2); + LocationQuaternion2 correspondingControl = Camera.controlPoints.get(index - 2); double correspondingDistance = anchor.distance(correspondingControl); // Keep correcponding at the same distance @@ -150,12 +150,12 @@ public class NewPoint implements CommandExecutor { // Control point before an anchor if (index + 2 < n) { // Get anchor-location direction - Location anchor = Camera.controlPoints.get(index + 1); + LocationQuaternion2 anchor = Camera.controlPoints.get(index + 1); double currentDistance = anchor.distance(location); - Location currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance); + LocationQuaternion2 currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance); // Get anchor-corresponding distance - Location correspondingControl = Camera.controlPoints.get(index + 2); + LocationQuaternion2 correspondingControl = Camera.controlPoints.get(index + 2); double correspondingDistance = anchor.distance(correspondingControl); // Keep correcponding at the same distance diff --git a/src/main/java/com/tocard/cam/ShowCurve.java b/src/main/java/com/tocard/cam/ShowCurve.java index 23397c0..3ad51c9 100644 --- a/src/main/java/com/tocard/cam/ShowCurve.java +++ b/src/main/java/com/tocard/cam/ShowCurve.java @@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.EulerAngle; import org.bukkit.Bukkit; import java.util.ArrayList; @@ -60,13 +61,13 @@ 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(new LocationQuaternion(new double[] { 0, 1.8, 0, 0, 0, 0, 0 })) + .add(new LocationQuaternion2(new double[] { 0, 1.8, 0, 0, 0, 0, 0 })) .toLocation(), 1, 0, 0, 0, 0); @@ -84,7 +85,7 @@ public class ShowCurve implements CommandExecutor { Camera.controlPoints.get(indMin).clone().multiply(1 - t) .add(Camera.controlPoints.get(indMax).clone() .multiply(t)) - .add(new LocationQuaternion( + .add(new LocationQuaternion2( new double[] { 0, 1.8, 0, 0, 0, 0, 0 })) .toLocation(), 1, @@ -103,7 +104,7 @@ public class ShowCurve implements CommandExecutor { return true; } - public static void add(LocationQuaternion point, World world) { + public static void add(LocationQuaternion2 point, World world) { ArmorStand as = world.spawn(point.toLocation(), ArmorStand.class); as.setGravity(false); as.setVisible(false); @@ -117,11 +118,12 @@ public class ShowCurve implements CommandExecutor { else as.getEquipment().setHelmet(cameraHeadControl); } + as.setHeadPose(new EulerAngle(point.coordinates[4] / 180 * Math.PI, 0, 0)); controlPointsArmorStands.add(as); } @Deprecated - public static void insert(int index, LocationQuaternion point, World world) { + public static void insert(int index, LocationQuaternion2 point, World world) { ArmorStand as = world.spawn(point.toLocation(), ArmorStand.class); as.setGravity(false); as.setVisible(false); @@ -132,10 +134,12 @@ public class ShowCurve implements CommandExecutor { as.getEquipment().setHelmet(cameraHeadAnchor); else as.getEquipment().setHelmet(cameraHeadControl); + as.setHeadPose(new EulerAngle(point.coordinates[4] / 180 * Math.PI, 0, 0)); controlPointsArmorStands.add(index, as); } - public static void set(int index, LocationQuaternion point, World world) { + public static void set(int index, LocationQuaternion2 point, World world) { + controlPointsArmorStands.get(index).setHeadPose(new EulerAngle(point.coordinates[4] / 180 * Math.PI, 0, 0)); controlPointsArmorStands.get(index).teleport(point.toLocation()); }