chore: renamed LocationQuaternion2 to LocationQuaternion

This commit is contained in:
Laureηt 2022-05-16 21:04:44 +02:00
parent 8f26f077e7
commit c3f7956cf3
No known key found for this signature in database
GPG key ID: D88C6B294FD40994
7 changed files with 113 additions and 194 deletions

View file

@ -18,8 +18,8 @@ import org.bukkit.inventory.ItemStack;
public class Camera extends JavaPlugin implements Listener { public class Camera extends JavaPlugin implements Listener {
public static ArrayList<LocationQuaternion2> curve = new ArrayList<>(); public static ArrayList<LocationQuaternion> curve = new ArrayList<>();
public static ArrayList<LocationQuaternion2> controlPoints = new ArrayList<>(); public static ArrayList<LocationQuaternion> controlPoints = new ArrayList<>();
public static Logger logger; public static Logger logger;
public static Plugin plugin; public static Plugin plugin;
private static float dt = 0.01f; private static float dt = 0.01f;
@ -64,7 +64,7 @@ public class Camera extends JavaPlugin implements Listener {
if (nControlPoints <= 4) { if (nControlPoints <= 4) {
for (float t = 0; t < 1; t += dt) { for (float t = 0; t < 1; t += dt) {
ArrayList<LocationQuaternion2> P = new ArrayList<>(controlPoints); ArrayList<LocationQuaternion> P = new ArrayList<>(controlPoints);
int N = P.size(); int N = P.size();
for (int k = N - 1; k > 0; k--) { for (int k = N - 1; k > 0; k--) {
@ -82,7 +82,7 @@ public class Camera extends JavaPlugin implements Listener {
int nBezier = (nControlPoints - 1) / 3; int nBezier = (nControlPoints - 1) / 3;
for (int iBezier = 0; iBezier < nBezier; iBezier++) { for (int iBezier = 0; iBezier < nBezier; iBezier++) {
for (float t = 0; t < 1; t += dt) { for (float t = 0; t < 1; t += dt) {
ArrayList<LocationQuaternion2> P = new ArrayList<>(); ArrayList<LocationQuaternion> P = new ArrayList<>();
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
P.add(controlPoints.get(3 * iBezier + k).clone()); P.add(controlPoints.get(3 * iBezier + k).clone());
} }
@ -105,7 +105,7 @@ public class Camera extends JavaPlugin implements Listener {
Bukkit.broadcastMessage(msg); Bukkit.broadcastMessage(msg);
} }
public static String prettyLocation(LocationQuaternion2 point) { public static String prettyLocation(LocationQuaternion point) {
point.updateEulerAngles(); point.updateEulerAngles();
return String.format("X=%05.2f, Y=%05.2f, Z=%05.2f, P=%05.2f, Y=%05.2f", 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.getX(), point.getY(), point.getZ(),

View file

@ -11,7 +11,7 @@ import java.util.Iterator;
public class ExecuteTraveling implements CommandExecutor { public class ExecuteTraveling implements CommandExecutor {
private static int taskID = -1; private static int taskID = -1;
private static Iterator<LocationQuaternion2> curveIterator; private static Iterator<LocationQuaternion> curveIterator;
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
@ -33,7 +33,7 @@ public class ExecuteTraveling implements CommandExecutor {
public void run() { public void run() {
// Teleport to next point // Teleport to next point
if (curveIterator.hasNext()) { if (curveIterator.hasNext()) {
LocationQuaternion2 loc = curveIterator.next(); LocationQuaternion loc = curveIterator.next();
Camera.broadlog(Camera.prettyLocation(loc)); Camera.broadlog(Camera.prettyLocation(loc));
player.teleport(loc); player.teleport(loc);
return; return;

View file

@ -9,7 +9,7 @@ import org.bukkit.entity.Player;
public class ListPoints implements CommandExecutor { public class ListPoints implements CommandExecutor {
private static ListIterator<LocationQuaternion2> points; private static ListIterator<LocationQuaternion> points;
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

View file

@ -11,6 +11,7 @@ public class LocationQuaternion extends Location {
private float roll = 0; private float roll = 0;
private static final float deg2grad = (float) Math.PI / 180.0f; private static final float deg2grad = (float) Math.PI / 180.0f;
private static final float grad2deg = 1 / deg2grad;
// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Source_code // https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Source_code
public LocationQuaternion(Location location) { public LocationQuaternion(Location location) {
@ -18,8 +19,8 @@ public class LocationQuaternion extends Location {
location.getX(), location.getX(),
location.getY(), location.getY(),
location.getZ(), location.getZ(),
location.getYaw() * deg2grad, location.getYaw(),
location.getPitch() * deg2grad); location.getPitch());
this.updateQuaternionAngles(); this.updateQuaternionAngles();
} }
@ -28,54 +29,105 @@ public class LocationQuaternion extends Location {
// roll (x-axis rotation) // roll (x-axis rotation)
double sinr_cosp = 2 * (qw * qx + qy * qz); double sinr_cosp = 2 * (qw * qx + qy * qz);
double cosr_cosp = 1 - 2 * (qx * qx + qy * qy); double cosr_cosp = 1 - 2 * (qx * qx + qy * qy);
this.roll = (float) Math.atan2(sinr_cosp, cosr_cosp); roll = (float) Math.atan2(sinr_cosp, cosr_cosp) * grad2deg;
// pitch (y-axis rotation) // pitch (y-axis rotation)
double pitch;
double sinp = 2 * (qw * qy - qz * qx); double sinp = 2 * (qw * qy - qz * qx);
if (Math.abs(sinp) >= 1) { if (Math.abs(sinp) >= 1) {
this.setPitch((float) Math.copySign(Math.PI / 2, sinp)); // use 90 degrees if out of range pitch = Math.copySign(Math.PI / 2, sinp); // use 90 degrees if out of range
} else { } else {
this.setPitch((float) Math.asin(sinp)); pitch = Math.asin(sinp);
} }
setPitch((float) pitch * grad2deg);
// yaw (z-axis rotation) // yaw (z-axis rotation)
double siny_cosp = 2 * (qw * qz + qx * qy); double siny_cosp = 2 * (qw * qz + qx * qy);
double cosy_cosp = 1 - 2 * (qy * qy + qz * qz); double cosy_cosp = 1 - 2 * (qy * qy + qz * qz);
this.setYaw((float) Math.atan2(siny_cosp, cosy_cosp)); double yaw = Math.atan2(siny_cosp, cosy_cosp);
setYaw((float) yaw * grad2deg);
} }
public void updateQuaternionAngles() { public void updateQuaternionAngles() {
double cy = Math.cos(getYaw() * 0.5); float yaw = getYaw() * deg2grad;
double sy = Math.sin(getYaw() * 0.5); float pitch = getPitch() * deg2grad;
double cp = Math.cos(getPitch() * 0.5);
double sp = Math.sin(getPitch() * 0.5);
double cr = Math.cos(getRoll() * 0.5);
double sr = Math.sin(getRoll() * 0.5);
this.qw = cr * cp * cy + sr * sp * sy; double cy = Math.cos(yaw * 0.5);
this.qx = sr * cp * cy - cr * sp * sy; double sy = Math.sin(yaw * 0.5);
this.qy = cr * sp * cy + sr * cp * sy; double cp = Math.cos(pitch * 0.5);
this.qz = cr * cp * sy - sr * sp * cy; double sp = Math.sin(pitch * 0.5);
double cr = Math.cos(roll * 0.5);
double sr = Math.sin(roll * 0.5);
qw = cr * cp * cy + sr * sp * sy;
qx = sr * cp * cy - cr * sp * sy;
qy = cr * sp * cy + sr * cp * sy;
qz = cr * cp * sy - sr * sp * cy;
} }
public double dot(LocationQuaternion loc) { public LocationQuaternion patchYaw(LocationQuaternion previousLocation) {
return this.qw * loc.qw + this.qx * loc.qx + this.qy * loc.qy + this.qz * loc.qz; float A = previousLocation.getYaw();
float B = getYaw();
float b = B % 360;
int wholePart = 360 * (int) (A / 360);
float minDist = -1;
float sol = 0;
for (int i = -1; i < 2; i++) {
float val = wholePart + b + i * 360;
float dist = Math.abs(val - A);
if (minDist == -1 || dist < minDist) {
sol = val;
minDist = dist;
}
}
setYaw(sol);
updateQuaternionAngles();
return this;
}
public LocationQuaternion add(LocationQuaternion loc) {
super.add(loc);
qw += loc.qw;
qx += loc.qx;
qy += loc.qy;
qz += loc.qz;
updateEulerAngles();
return this;
}
public LocationQuaternion subtract(LocationQuaternion loc) {
super.subtract(loc);
qw -= loc.qw;
qx -= loc.qx;
qy -= loc.qy;
qz -= loc.qz;
updateEulerAngles();
return this;
}
public LocationQuaternion multiply(double m) {
super.multiply(m);
qw *= m;
qx += m;
qy += m;
qz += m;
updateEulerAngles();
return this;
} }
@Override @Override
public LocationQuaternion clone() { public LocationQuaternion clone() {
LocationQuaternion cloned = (LocationQuaternion) super.clone(); LocationQuaternion cloned = new LocationQuaternion(this);
cloned.roll = this.roll;
cloned.qw = this.qw;
cloned.qx = this.qx;
cloned.qy = this.qy;
cloned.qz = this.qz;
return cloned; return cloned;
} }
public float getRoll() {
return this.roll;
}
} }

View file

@ -1,133 +0,0 @@
package com.tocard.cam;
import org.bukkit.Location;
public class LocationQuaternion2 extends Location {
private double qw;
private double qx;
private double qy;
private double qz;
private float roll = 0;
private static final float deg2grad = (float) Math.PI / 180.0f;
private static final float grad2deg = 1 / deg2grad;
// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Source_code
public LocationQuaternion2(Location location) {
super(location.getWorld(),
location.getX(),
location.getY(),
location.getZ(),
location.getYaw(),
location.getPitch());
this.updateQuaternionAngles();
}
public void updateEulerAngles() {
// roll (x-axis rotation)
double sinr_cosp = 2 * (qw * qx + qy * qz);
double cosr_cosp = 1 - 2 * (qx * qx + qy * qy);
roll = (float) Math.atan2(sinr_cosp, cosr_cosp) * grad2deg;
// pitch (y-axis rotation)
double pitch;
double sinp = 2 * (qw * qy - qz * qx);
if (Math.abs(sinp) >= 1) {
pitch = Math.copySign(Math.PI / 2, sinp); // use 90 degrees if out of range
} else {
pitch = Math.asin(sinp);
}
setPitch((float) pitch * grad2deg);
// yaw (z-axis rotation)
double siny_cosp = 2 * (qw * qz + qx * qy);
double cosy_cosp = 1 - 2 * (qy * qy + qz * qz);
double yaw = Math.atan2(siny_cosp, cosy_cosp);
setYaw((float) yaw * grad2deg);
}
public void updateQuaternionAngles() {
float yaw = getYaw() * deg2grad;
float pitch = getPitch() * deg2grad;
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);
qw = cr * cp * cy + sr * sp * sy;
qx = sr * cp * cy - cr * sp * sy;
qy = cr * sp * cy + sr * cp * sy;
qz = cr * cp * sy - sr * sp * cy;
}
public LocationQuaternion2 patchYaw(LocationQuaternion2 previousLocation) {
float A = previousLocation.getYaw();
float B = getYaw();
float b = B % 360;
int wholePart = 360 * (int) (A / 360);
float minDist = -1;
float sol = 0;
for (int i = -1; i < 2; i++) {
float val = wholePart + b + i * 360;
float dist = Math.abs(val - A);
if (minDist == -1 || dist < minDist) {
sol = val;
minDist = dist;
}
}
setYaw(sol);
updateQuaternionAngles();
return this;
}
public LocationQuaternion2 add(LocationQuaternion2 loc) {
super.add(loc);
qw += loc.qw;
qx += loc.qx;
qy += loc.qy;
qz += loc.qz;
updateEulerAngles();
return this;
}
public LocationQuaternion2 subtract(LocationQuaternion2 loc) {
super.subtract(loc);
qw -= loc.qw;
qx -= loc.qx;
qy -= loc.qy;
qz -= loc.qz;
updateEulerAngles();
return this;
}
public LocationQuaternion2 multiply(double m) {
super.multiply(m);
qw *= m;
qx += m;
qy += m;
qz += m;
updateEulerAngles();
return this;
}
@Override
public LocationQuaternion2 clone() {
LocationQuaternion2 cloned = new LocationQuaternion2(this);
return cloned;
}
}

View file

@ -16,13 +16,13 @@ public class NewPoint implements CommandExecutor {
Player player = (Player) sender; Player player = (Player) sender;
switch (args[0]) { switch (args[0]) {
case "add": case "add":
add(args, new LocationQuaternion2(player.getLocation()), player.getWorld()); add(args, new LocationQuaternion(player.getLocation()), player.getWorld());
break; break;
case "rm": case "rm":
rm(args, null, null); rm(args, null, null);
break; break;
case "set": case "set":
set(args, new LocationQuaternion2(player.getLocation()), player.getWorld()); set(args, new LocationQuaternion(player.getLocation()), player.getWorld());
break; break;
default: default:
break; break;
@ -38,34 +38,34 @@ public class NewPoint implements CommandExecutor {
return true; return true;
} }
public static void addPoint(LocationQuaternion2 point, World world) { public static void addPoint(LocationQuaternion point, World world) {
Camera.controlPoints.add(point); Camera.controlPoints.add(point);
ShowCurve.add(point, world); ShowCurve.add(point, world);
Camera.broadlog("Point added: " + Camera.prettyLocation(point)); Camera.broadlog("Point added: " + Camera.prettyLocation(point));
} }
public static void setPoint(int index, LocationQuaternion2 point, World world) { public static void setPoint(int index, LocationQuaternion point, World world) {
Camera.controlPoints.set(index, point); Camera.controlPoints.set(index, point);
ShowCurve.set(index, point, world); ShowCurve.set(index, point, world);
Camera.broadlog("Point n°" + index + " set: " + Camera.prettyLocation(point)); Camera.broadlog("Point n°" + index + " set: " + Camera.prettyLocation(point));
} }
public static void rmPoint(int index) { public static void rmPoint(int index) {
LocationQuaternion2 location = Camera.controlPoints.remove(index); LocationQuaternion location = Camera.controlPoints.remove(index);
ShowCurve.rm(index); ShowCurve.rm(index);
Camera.broadlog("Point deleted: " + Camera.prettyLocation(location)); Camera.broadlog("Point deleted: " + Camera.prettyLocation(location));
} }
public static void add(String[] args, LocationQuaternion2 location, World world) { public static void add(String[] args, LocationQuaternion location, World world) {
int n = Camera.controlPoints.size(); int n = Camera.controlPoints.size();
if (n < 4) { if (n < 4) {
addPoint(location, world); addPoint(location, world);
} else { } else {
LocationQuaternion2 P2 = Camera.controlPoints.get(n - 2); LocationQuaternion P2 = Camera.controlPoints.get(n - 2);
LocationQuaternion2 P3 = Camera.controlPoints.get(n - 1); LocationQuaternion P3 = Camera.controlPoints.get(n - 1);
LocationQuaternion2 P4 = P3.clone().multiply(2).subtract(P2); LocationQuaternion P4 = P3.clone().multiply(2).subtract(P2);
LocationQuaternion2 P5 = location.clone().add(P4).multiply(0.5); LocationQuaternion P5 = location.clone().add(P4).multiply(0.5);
addPoint(P4, world); addPoint(P4, world);
addPoint(P5, world); addPoint(P5, world);
@ -74,7 +74,7 @@ public class NewPoint implements CommandExecutor {
} }
@Deprecated @Deprecated
public static void ins(String[] args, LocationQuaternion2 location, World world) { public static void ins(String[] args, LocationQuaternion location, World world) {
int index = Integer.parseInt(args[1]); int index = Integer.parseInt(args[1]);
Camera.controlPoints.add(index, location); Camera.controlPoints.add(index, location);
Camera.broadlog("Point added: " + Camera.prettyLocation(location)); Camera.broadlog("Point added: " + Camera.prettyLocation(location));
@ -106,7 +106,7 @@ public class NewPoint implements CommandExecutor {
} }
public static void set(String[] args, LocationQuaternion2 location, World world) { public static void set(String[] args, LocationQuaternion location, World world) {
int n = Camera.controlPoints.size(); int n = Camera.controlPoints.size();
int index = Integer.parseInt(args[1]); int index = Integer.parseInt(args[1]);
@ -118,7 +118,7 @@ public class NewPoint implements CommandExecutor {
switch (index % 3) { switch (index % 3) {
case 0: case 0:
// Anchor point // Anchor point
LocationQuaternion2 shift = location.clone().subtract(Camera.controlPoints.get(index)); LocationQuaternion shift = location.clone().subtract(Camera.controlPoints.get(index));
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
try { try {
setPoint(index + i - 1, Camera.controlPoints.get(index + i - 1).clone().add(shift), world); 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 // Control point after an anchor
if (index - 2 >= 0) { if (index - 2 >= 0) {
// Get anchor-location direction // Get anchor-location direction
LocationQuaternion2 anchor = Camera.controlPoints.get(index - 1); LocationQuaternion anchor = Camera.controlPoints.get(index - 1);
double currentDistance = anchor.distance(location); double currentDistance = anchor.distance(location);
LocationQuaternion2 currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance); LocationQuaternion currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance);
// Get anchor-corresponding distance // Get anchor-corresponding distance
LocationQuaternion2 correspondingControl = Camera.controlPoints.get(index - 2); LocationQuaternion correspondingControl = Camera.controlPoints.get(index - 2);
double correspondingDistance = anchor.distance(correspondingControl); double correspondingDistance = anchor.distance(correspondingControl);
// Keep correcponding at the same distance // Keep correcponding at the same distance
@ -150,12 +150,12 @@ public class NewPoint implements CommandExecutor {
// Control point before an anchor // Control point before an anchor
if (index + 2 < n) { if (index + 2 < n) {
// Get anchor-location direction // Get anchor-location direction
LocationQuaternion2 anchor = Camera.controlPoints.get(index + 1); LocationQuaternion anchor = Camera.controlPoints.get(index + 1);
double currentDistance = anchor.distance(location); double currentDistance = anchor.distance(location);
LocationQuaternion2 currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance); LocationQuaternion currentVect = anchor.clone().subtract(location).multiply(1 / currentDistance);
// Get anchor-corresponding distance // Get anchor-corresponding distance
LocationQuaternion2 correspondingControl = Camera.controlPoints.get(index + 2); LocationQuaternion correspondingControl = Camera.controlPoints.get(index + 2);
double correspondingDistance = anchor.distance(correspondingControl); double correspondingDistance = anchor.distance(correspondingControl);
// Keep correcponding at the same distance // Keep correcponding at the same distance

View file

@ -61,7 +61,7 @@ public class ShowCurve implements CommandExecutor {
@Override @Override
public void run() { public void run() {
// Get curve iterator // Get curve iterator
Iterator<LocationQuaternion2> curveIterator = Camera.curve.iterator(); Iterator<LocationQuaternion> curveIterator = Camera.curve.iterator();
// Draw path // Draw path
while (curveIterator.hasNext()) { while (curveIterator.hasNext()) {
@ -101,7 +101,7 @@ public class ShowCurve implements CommandExecutor {
return true; return true;
} }
public static void add(LocationQuaternion2 point, World world) { public static void add(LocationQuaternion point, World world) {
ArmorStand as = world.spawn(point, ArmorStand.class); ArmorStand as = world.spawn(point, ArmorStand.class);
as.setGravity(false); as.setGravity(false);
as.setVisible(false); as.setVisible(false);
@ -120,7 +120,7 @@ public class ShowCurve implements CommandExecutor {
} }
@Deprecated @Deprecated
public static void insert(int index, LocationQuaternion2 point, World world) { public static void insert(int index, LocationQuaternion point, World world) {
ArmorStand as = world.spawn(point, ArmorStand.class); ArmorStand as = world.spawn(point, ArmorStand.class);
as.setGravity(false); as.setGravity(false);
as.setVisible(false); as.setVisible(false);
@ -135,7 +135,7 @@ public class ShowCurve implements CommandExecutor {
controlPointsArmorStands.add(index, as); controlPointsArmorStands.add(index, as);
} }
public static void set(int index, LocationQuaternion2 point, World world) { public static void set(int index, LocationQuaternion point, World world) {
controlPointsArmorStands.get(index).setHeadPose(new EulerAngle(point.getPitch() / 180 * Math.PI, 0, 0)); controlPointsArmorStands.get(index).setHeadPose(new EulerAngle(point.getPitch() / 180 * Math.PI, 0, 0));
controlPointsArmorStands.get(index).teleport(point); controlPointsArmorStands.get(index).teleport(point);
} }