From ceec170be9dcb47f36ba30a335704e8b5cd77e33 Mon Sep 17 00:00:00 2001 From: sk89q Date: Thu, 10 Jul 2014 15:49:34 -0700 Subject: [PATCH] Change Location to store pitch/yaw rather than a directional vector. --- .../sk89q/worldedit/bukkit/BukkitAdapter.java | 8 +- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 23 ++-- .../sk89q/worldedit/forge/ForgePlayer.java | 9 +- .../com/sk89q/worldedit/util/Location.java | 106 +++++++++++++++--- .../com/sk89q/worldedit/util/Vectors.java | 65 ----------- 5 files changed, 110 insertions(+), 101 deletions(-) delete mode 100644 src/main/java/com/sk89q/worldedit/util/Vectors.java diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java index 3fba70a8e..f949510f1 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java @@ -22,7 +22,6 @@ package com.sk89q.worldedit.bukkit; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.Vectors; import com.sk89q.worldedit.world.World; import org.bukkit.Bukkit; @@ -76,8 +75,11 @@ final class BukkitAdapter { public static Location adapt(org.bukkit.Location location) { checkNotNull(location); Vector position = BukkitUtil.toVector(location); - Vector direction = Vectors.fromEulerDeg(location.getYaw(), location.getPitch()); - return new com.sk89q.worldedit.util.Location(adapt(location.getWorld()), position, direction); + return new com.sk89q.worldedit.util.Location( + adapt(location.getWorld()), + position, + (float) Math.toRadians(location.getYaw()), + (float) Math.toRadians(location.getPitch())); } /** diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 1fcaf1c1d..22a659abf 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -19,23 +19,21 @@ package com.sk89q.worldedit.bukkit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseBlock; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.util.Vectors; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - import com.sk89q.util.StringUtil; import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.internal.cui.CUIEvent; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; public class BukkitPlayer extends LocalPlayer { private Player player; @@ -180,7 +178,10 @@ public class BukkitPlayer extends LocalPlayer { public com.sk89q.worldedit.util.Location getLocation() { Location nativeLocation = player.getLocation(); Vector position = BukkitUtil.toVector(nativeLocation); - Vector direction = Vectors.fromEulerDeg(nativeLocation.getYaw(), nativeLocation.getPitch()); - return new com.sk89q.worldedit.util.Location(getWorld(), position, direction); + return new com.sk89q.worldedit.util.Location( + getWorld(), + position, + (float) Math.toRadians(nativeLocation.getYaw()), + (float) Math.toRadians(nativeLocation.getPitch())); } } diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java index 6a07c1ff8..d1ce05924 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -21,7 +21,6 @@ package com.sk89q.worldedit.forge; import com.sk89q.util.StringUtil; import com.sk89q.worldedit.LocalPlayer; -import com.sk89q.worldedit.ServerInterface; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; import com.sk89q.worldedit.entity.BaseEntity; @@ -29,7 +28,6 @@ import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.Vectors; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.network.packet.Packet250CustomPayload; @@ -59,8 +57,11 @@ public class ForgePlayer extends LocalPlayer { @Override public Location getLocation() { Vector position = new Vector(this.player.posX, this.player.posY, this.player.posZ); - Vector direction = Vectors.fromEulerDeg(this.player.cameraYaw, this.player.cameraPitch); - return new Location(ForgeWorldEdit.inst.getWorld(this.player.worldObj), position, direction); + return new Location( + ForgeWorldEdit.inst.getWorld(this.player.worldObj), + position, + (float) Math.toRadians(this.player.cameraYaw), + (float) Math.toRadians(this.player.cameraPitch)); } public WorldVector getPosition() { diff --git a/src/main/java/com/sk89q/worldedit/util/Location.java b/src/main/java/com/sk89q/worldedit/util/Location.java index d6ee8c468..0bc45e592 100644 --- a/src/main/java/com/sk89q/worldedit/util/Location.java +++ b/src/main/java/com/sk89q/worldedit/util/Location.java @@ -38,7 +38,8 @@ public class Location { private final Extent extent; private final Vector position; - private final Vector direction; + private final float pitch; + private final float yaw; /** * Create a new instance in the given extent at 0, 0, 0 with a @@ -88,6 +89,21 @@ public class Location { this(extent, new Vector(x, y, z), direction); } + /** + * Create a new instance in the given extent with the given coordinates + * and the given direction vector. + * + * @param extent the extent + * @param x the X coordinate + * @param y the Y coordinate + * @param z the Z coordinate + * @param yaw the yaw, in radians + * @param pitch the pitch, in radians + */ + public Location(Extent extent, double x, double y, double z, float yaw, float pitch) { + this(extent, new Vector(x, y, z), yaw, pitch); + } + /** * Create a new instance in the given extent with the given position vector * and the given direction vector. @@ -97,12 +113,26 @@ public class Location { * @param direction the direction vector */ public Location(Extent extent, Vector position, Vector direction) { + this(extent, position, 0, 0); + this.setDirection(direction); + } + + /** + * Create a new instance in the given extent with the given position vector + * and the given direction vector. + * + * @param extent the extent + * @param position the position vector + * @param yaw the yaw, in radians + * @param pitch the pitch, in radians + */ + public Location(Extent extent, Vector position, float yaw, float pitch) { checkNotNull(extent); checkNotNull(position); - checkNotNull(direction); this.extent = extent; this.position = position; - this.direction = direction; + this.pitch = pitch; + this.yaw = yaw; } /** @@ -125,15 +155,36 @@ public class Location { } /** - * Get the direction. - *

- * The direction vector may be a null vector. It may or may not - * be a unit vector. + * Get the yaw in radians. * - * @return the direction + * @return the yaw in radians + */ + public float getYaw() { + return yaw; + } + + /** + * Get the pitch in radians. + * + * @return the pitch in radians + */ + public float getPitch() { + return pitch; + } + + /** + * Get the direction vector. + * + * @return the direction vector */ public Vector getDirection() { - return direction; + double yaw = this.getYaw(); + double pitch = this.getPitch(); + double xz = Math.cos(pitch); + return new Vector( + -xz * Math.sin(yaw), + -Math.sin(pitch), + xz * Math.cos(yaw)); } /** @@ -143,7 +194,24 @@ public class Location { * @return the new instance */ public Location setDirection(Vector direction) { - return new Location(extent, position, direction); + double x = direction.getX(); + double z = direction.getZ(); + + if (x == 0 && z == 0) { + float pitch = direction.getY() > 0 ? -90 : 90; + return new Location(extent, position, 0, pitch); + } else { + double t = Math.atan2(-x, z); + double x2 = x * x; + double z2 = z * z; + double xz = Math.sqrt(x2 + z2); + double _2pi = 2 * Math.PI; + + float pitch = (float) Math.atan(-direction.getY() / xz); + float yaw = (float) ((t + _2pi) % _2pi); + + return new Location(extent, position, yaw, pitch); + } } /** @@ -181,7 +249,7 @@ public class Location { * @return a new immutable instance */ public Location setX(double x) { - return new Location(extent, position.setX(x), direction); + return new Location(extent, position.setX(x), yaw, pitch); } /** @@ -192,7 +260,7 @@ public class Location { * @return a new immutable instance */ public Location setX(int x) { - return new Location(extent, position.setX(x), direction); + return new Location(extent, position.setX(x), yaw, pitch); } /** @@ -221,7 +289,7 @@ public class Location { * @return a new immutable instance */ public Location setY(double y) { - return new Location(extent, position.setY(y), direction); + return new Location(extent, position.setY(y), yaw, pitch); } /** @@ -232,7 +300,7 @@ public class Location { * @return a new immutable instance */ public Location setY(int y) { - return new Location(extent, position.setY(y), direction); + return new Location(extent, position.setY(y), yaw, pitch); } /** @@ -261,7 +329,7 @@ public class Location { * @return a new immutable instance */ public Location setZ(double z) { - return new Location(extent, position.setZ(z), direction); + return new Location(extent, position.setZ(z), yaw, pitch); } /** @@ -272,7 +340,7 @@ public class Location { * @return a new immutable instance */ public Location setZ(int z) { - return new Location(extent, position.setZ(z), direction); + return new Location(extent, position.setZ(z), yaw, pitch); } @Override @@ -282,7 +350,8 @@ public class Location { Location location = (Location) o; - if (!direction.equals(location.direction)) return false; + if (Double.doubleToLongBits(pitch) != Double.doubleToLongBits(location.pitch)) return false; + if (Double.doubleToLongBits(yaw) != Double.doubleToLongBits(location.yaw)) return false; if (!position.equals(location.position)) return false; if (!extent.equals(location.extent)) return false; @@ -293,7 +362,8 @@ public class Location { public int hashCode() { int result = extent.hashCode(); result = 31 * result + position.hashCode(); - result = 31 * result + direction.hashCode(); + result = 31 * result + Float.floatToIntBits(this.pitch); + result = 31 * result + Float.floatToIntBits(this.yaw); return result; } diff --git a/src/main/java/com/sk89q/worldedit/util/Vectors.java b/src/main/java/com/sk89q/worldedit/util/Vectors.java deleted file mode 100644 index 277bf9c3d..000000000 --- a/src/main/java/com/sk89q/worldedit/util/Vectors.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util; - -import com.sk89q.worldedit.Vector; - -/** - * Utility methods for {@link Vector}s. - */ -public final class Vectors { - - private Vectors() { - } - - /** - * Create a new {@link Vector} using Euler angles specified in degrees, - * but with no roll. - * - * @param yaw the yaw - * @param pitch the pitch - * @return a new {@link Vector} - */ - public static Vector fromEulerDeg(double yaw, double pitch) { - final double yawRadians = Math.toRadians(yaw); - final double pitchRadians = Math.toRadians(pitch); - return fromEulerRad(yawRadians, pitchRadians); - } - - /** - * Create a new {@link Vector} using Euler angles specified in radians, - * but with no roll. - * - * @param yaw the yaw - * @param pitch the pitch - * @return a new {@link Vector} - */ - public static Vector fromEulerRad(double yaw, double pitch) { - final double y = -Math.sin(pitch); - - final double h = Math.cos(pitch); - - final double x = -h * Math.sin(yaw); - final double z = h * Math.cos(yaw); - - return new Vector(x, y, z); - } - -}