Current Progress #3

This commit is contained in:
IronApollo
2019-01-09 02:13:44 -05:00
parent d4157b7e0e
commit 842b1307c7
221 changed files with 3173 additions and 3041 deletions

View File

@ -1,10 +1,21 @@
package com.sk89q.worldedit.math;
import com.boydti.fawe.util.MathMan;
import com.google.common.collect.ComparisonChain;
import com.sk89q.worldedit.math.transform.AffineTransform;
import static com.google.common.base.Preconditions.checkArgument;
import java.io.IOException;
import java.io.Serializable;
import java.util.Comparator;
public class MutableBlockVector extends BlockVector3 implements Serializable {
/**
* A mutable rendition of WorldEdit's BlockVector3 class.
* This class should ONLY be used locally for efficient vector manipulation.
*/
public class MutableBlockVector implements Serializable {
private transient int x, y, z;
private static ThreadLocal<MutableBlockVector> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector>() {
@ -23,26 +34,50 @@ public class MutableBlockVector extends BlockVector3 implements Serializable {
}
public MutableBlockVector(int x, int y, int z) {
super(0, 0, 0);
this.x = x;
this.y = y;
this.z = z;
}
public MutableBlockVector() {
super(0, 0, 0);
this(0, 0, 0);
}
public static final MutableBlockVector ZERO = new MutableBlockVector(0, 0, 0);
public static final MutableBlockVector UNIT_X = new MutableBlockVector(1, 0, 0);
public static final MutableBlockVector UNIT_Y = new MutableBlockVector(0, 1, 0);
public static final MutableBlockVector UNIT_Z = new MutableBlockVector(0, 0, 1);
public static final MutableBlockVector ONE = new MutableBlockVector(1, 1, 1);
// thread-safe initialization idiom
private static final class YzxOrderComparator {
private static final Comparator<MutableBlockVector> YZX_ORDER = (a, b) -> {
return ComparisonChain.start()
.compare(a.y, b.y)
.compare(a.z, b.z)
.compare(a.x, b.x)
.result();
};
}
/**
* Returns a comparator that sorts vectors first by Y, then Z, then X.
*
* <p>
* Useful for sorting by chunk block storage order.
*/
public static Comparator<MutableBlockVector> sortByCoordsYzx() {
return YzxOrderComparator.YZX_ORDER;
}
public MutableBlockVector setComponents(BlockVector3 other) {
return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ());
}
// @Override
public MutableBlockVector setComponents(double x, double y, double z) {
return this.setComponents((int) x, (int) y, (int) z);
}
// @Override
public MutableBlockVector setComponents(int x, int y, int z) {
this.mutX(x);
this.mutY(y);
@ -50,64 +85,534 @@ public class MutableBlockVector extends BlockVector3 implements Serializable {
return this;
}
// @Override
public final void mutX(double x) {
this.x = MathMan.roundInt(x);
}
// @Override
public final void mutY(double y) {
this.y = MathMan.roundInt(y);
}
// @Override
public final void mutZ(double z) {
this.z = MathMan.roundInt(z);
}
// @Override
public final void mutX(int x) {
this.x = x;
}
// @Override
public final void mutY(int y) {
this.y = y;
}
// @Override
public final void mutZ(int z) {
this.z = z;
}
@Override
public final int getX() {
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getX() {
return x;
}
@Override
public final int getY() {
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getBlockX() {
return x;
}
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public int getY() {
return y;
}
@Override
public final int getZ() {
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public int getBlockY() {
return y;
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getZ() {
return z;
}
@Override
public int getBlockX() {
return this.x;
}
@Override
public int getBlockY() {
return this.y;
}
@Override
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getBlockZ() {
return this.z;
return z;
}
/**
* Add another vector to this vector.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector add(MutableBlockVector other) {
return add(other.x, other.y, other.z);
}
/**
* Add another vector to this vector.
*
* @param x the value to add
* @param y the value to add
* @param z the value to add
* @return a new vector
*/
public MutableBlockVector add(int x, int y, int z) {
this.x += x;
this.y += y;
this.z += z;
return this;
}
/**
* Add a list of vectors to this vector and return the
* result as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableBlockVector add(MutableBlockVector... others) {
for (MutableBlockVector other : others) {
x += other.x;
y += other.y;
z += other.z;
}
return this;
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector subtract(MutableBlockVector other) {
return subtract(other.x, other.y, other.z);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param x the value to subtract
* @param y the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public MutableBlockVector subtract(int x, int y, int z) {
this.x -= x;
this.y -= y;
this.z -= z;
return this;
}
/**
* Subtract a list of vectors from this vector and return the result
* as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableBlockVector subtract(MutableBlockVector... others) {
for (MutableBlockVector other : others) {
x -= other.x;
y -= other.y;
z -= other.z;
}
return this;
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector multiply(MutableBlockVector other) {
return multiply(other.x, other.y, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param y the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public MutableBlockVector multiply(int x, int y, int z) {
this.x *= x;
this.y *= y;
this.z *= z;
return this;
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableBlockVector multiply(MutableBlockVector... others) {
for (MutableBlockVector other : others) {
x *= other.x;
y *= other.y;
z *= other.z;
}
return this;
}
/**
* Perform scalar multiplication and return a new vector.
*
* @param n the value to multiply
* @return a new vector
*/
public MutableBlockVector multiply(int n) {
return multiply(n, n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector divide(MutableBlockVector other) {
return divide(other.x, other.y, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param y the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public MutableBlockVector divide(int x, int y, int z) {
this.x /= x;
this.y /= y;
this.z /= z;
return this;
}
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public MutableBlockVector divide(int n) {
return divide(n, n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public int lengthSq() {
return x * x + y * y + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(MutableBlockVector other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public int distanceSq(MutableBlockVector other) {
int dx = other.x - x;
int dy = other.y - y;
int dz = other.z - z;
return dx * dx + dy * dy + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public MutableBlockVector normalize() {
double len = length();
x /= len;
y /= len;
z /= len;
return this;
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(MutableBlockVector other) {
return x * other.x + y * other.y + z * other.z;
}
/**
* Gets the cross product of this and another vector.
*
* @param other the other vector
* @return the cross product of this and the other vector
*/
public MutableBlockVector cross(MutableBlockVector other) {
x = y * other.z - z * other.y;
y = z * other.x - x * other.z;
z = x * other.y - y * other.x;
return this;
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(MutableBlockVector min, MutableBlockVector max) {
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
}
/**
* Clamp the Y component.
*
* @param min the minimum value
* @param max the maximum value
* @return a new vector
*/
public MutableBlockVector clampY(int min, int max) {
checkArgument(min <= max, "minimum cannot be greater than maximum");
if (y < min) {
y = min;
}
if (y > max) {
y = max;
}
return this;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public MutableBlockVector floor() {
// already floored, kept for feature parity with Vector3
return this;
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public MutableBlockVector ceil() {
// already raised, kept for feature parity with Vector3
return this;
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public MutableBlockVector round() {
// already rounded, kept for feature parity with Vector3
return this;
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public MutableBlockVector abs() {
x = Math.abs(x);
y = Math.abs(y);
z = Math.abs(z);
return this;
}
/**
* Perform a 2D transformation on this vector and return a new one.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public MutableBlockVector transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
this.x = (int) Math.floor(x2 + aboutX + translateX);
this.z = (int) Math.floor(z2 + aboutZ + translateZ);
return this;
}
/**
* Get this vector's pitch as used within the game.
*
* @return pitch in radians
*/
public double toPitch() {
double x = getX();
double z = getZ();
if (x == 0 && z == 0) {
return getY() > 0 ? -90 : 90;
} else {
double x2 = x * x;
double z2 = z * z;
double xz = Math.sqrt(x2 + z2);
return Math.toDegrees(Math.atan(-getY() / xz));
}
}
/**
* Get this vector's yaw as used within the game.
*
* @return yaw in radians
*/
public double toYaw() {
double x = getX();
double z = getZ();
double t = Math.atan2(-x, z);
double tau = 2 * Math.PI;
return Math.toDegrees(((t + tau) % tau));
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public MutableBlockVector getMinimum(MutableBlockVector v2) {
x = Math.min(x, v2.x);
y = Math.min(y, v2.y);
z = Math.min(z, v2.z);
return this;
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public MutableBlockVector getMaximum(MutableBlockVector v2) {
x = Math.max(x, v2.x);
y = Math.max(y, v2.y);
z = Math.max(z, v2.z);
return this;
}
/**
* Creates a 2D vector by dropping the Y component from this vector.
*
* @return a new {@link BlockVector2}
*/
public BlockVector2 toBlockVector2() {
return new BlockVector2(x, z);
}
public Vector3 toVector3() {
return new Vector3(x, y, z);
}
public BlockVector3 toBlockVector3() {
return new BlockVector3(x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MutableBlockVector)) {
return false;
}
MutableBlockVector other = (MutableBlockVector) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Integer.hashCode(x);
hash = 31 * hash + Integer.hashCode(y);
hash = 31 * hash + Integer.hashCode(z);
return hash;
}
@Override
public String toString() {
return "Mutable (" + x + ", " + y + ", " + z + ")";
}
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {

View File

@ -2,8 +2,16 @@ package com.sk89q.worldedit.math;
import java.io.IOException;
import java.io.Serializable;
import java.util.Comparator;
public final class MutableBlockVector2D extends BlockVector2 implements Serializable {
import com.google.common.collect.ComparisonChain;
import com.sk89q.worldedit.math.transform.AffineTransform;
/**
* A mutable rendition of WorldEdit's BlockVector2 class.
* This class should ONLY be used locally for efficient vector manipulation.
*/
public final class MutableBlockVector2D implements Serializable {
private static ThreadLocal<MutableBlockVector2D> MUTABLE_CACHE = new ThreadLocal<MutableBlockVector2D>() {
@Override
protected MutableBlockVector2D initialValue() {
@ -18,29 +26,505 @@ public final class MutableBlockVector2D extends BlockVector2 implements Serializ
private transient int x, z;
public MutableBlockVector2D() {
super(0, 0);
this.x = 0;
this.z = 0;
this(0, 0);
}
public static final MutableBlockVector2D ZERO = new MutableBlockVector2D(0, 0);
public static final MutableBlockVector2D UNIT_X = new MutableBlockVector2D(1, 0);
public static final MutableBlockVector2D UNIT_Z = new MutableBlockVector2D(0, 1);
public static final MutableBlockVector2D ONE = new MutableBlockVector2D(1, 1);
/**
* A comparator for MutableBlockVector2Ds that orders the vectors by rows, with x as the
* column and z as the row.
*
* For example, if x is the horizontal axis and z is the vertical axis, it
* sorts like so:
*
* <pre>
* 0123
* 4567
* 90ab
* cdef
* </pre>
*/
public static final Comparator<MutableBlockVector2D> COMPARING_GRID_ARRANGEMENT = (a, b) -> {
return ComparisonChain.start()
.compare(a.getBlockZ(), b.getBlockZ())
.compare(a.getBlockX(), b.getBlockX())
.result();
};
/**
* Construct an instance.
*
* @param vector
*/
public MutableBlockVector2D(BlockVector2 vector) {
this(vector.getBlockX(), vector.getBlockZ());
}
// @Override
/**
* Construct an instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public MutableBlockVector2D(double x, double z) {
this((int) Math.floor(x), (int) Math.floor(z));
}
/**
* Construct an instance.
*
* @param x the X coordinate
* @param z the Z coordinate
*/
public MutableBlockVector2D(int x, int z) {
this.x = x;
this.z = z;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getX() {
return x;
}
// @Override
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public int getBlockX() {
return x;
}
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getZ() {
return z;
}
@Override
public int getBlockX() {
return x;
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public int getBlockZ() {
return z;
}
/**
* Add another vector to this vector.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector2D add(MutableBlockVector2D other) {
return add(other.x, other.z);
}
/**
* Add another vector to this vector.
*
* @param x the value to add
* @param z the value to add
* @return a new vector
*/
public MutableBlockVector2D add(int x, int z) {
this.x += x;
this.z += z;
return this;
}
/**
* Add a list of vectors to this vector.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableBlockVector2D add(MutableBlockVector2D... others) {
for (MutableBlockVector2D other : others) {
x += other.x;
x += other.z;
}
return this;
}
/**
* Subtract another vector from this vector.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector2D subtract(MutableBlockVector2D other) {
return subtract(other.x, other.z);
}
/**
* Subtract another vector from this vector.
*
* @param x the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public MutableBlockVector2D subtract(int x, int z) {
this.x -= x;
this.z -= z;
return this;
}
/**
* Subtract a list of vectors from this vector.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableBlockVector2D subtract(MutableBlockVector2D... others) {
for (MutableBlockVector2D other : others) {
x -= other.x;
z -= other.z;
}
return this;
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector2D multiply(MutableBlockVector2D other) {
return multiply(other.x, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public MutableBlockVector2D multiply(int x, int z) {
this.x *= x;
this.z *= z;
return this;
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableBlockVector2D multiply(MutableBlockVector2D... others) {
for (MutableBlockVector2D other : others) {
x *= other.x;
z *= other.z;
}
return this;
}
/**
* Perform scalar multiplication.
*
* @param n the value to multiply
* @return a new vector
*/
public MutableBlockVector2D multiply(int n) {
return multiply(n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public MutableBlockVector2D divide(MutableBlockVector2D other) {
return divide(other.x, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public MutableBlockVector2D divide(int x, int z) {
this.x /= x;
this.z /= z;
return this;
}
/**
* Perform scalar division.
*
* @param n the value to divide by
* @return a new vector
*/
public MutableBlockVector2D divide(int n) {
return divide(n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public int lengthSq() {
return x * x + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(MutableBlockVector2D other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public int distanceSq(MutableBlockVector2D other) {
int dx = other.x - x;
int dz = other.z - z;
return dx * dx + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length.
*
* @return a new vector
*/
public MutableBlockVector2D normalize() {
double len = length();
this.x /= len;
this.z /= len;
return this;
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public int dot(MutableBlockVector2D other) {
return x * other.x + z * other.z;
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(MutableBlockVector2D min, MutableBlockVector2D max) {
return x >= min.x && x <= max.x
&& z >= min.z && z <= max.z;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public MutableBlockVector2D floor() {
// already floored, kept for feature parity with Vector2
return this;
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public MutableBlockVector2D ceil() {
// already raised, kept for feature parity with Vector2
return this;
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public MutableBlockVector2D round() {
// already rounded, kept for feature parity with Vector2
return this;
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public MutableBlockVector2D abs() {
x = Math.abs(x);
z = Math.abs(z);
return this;
}
/**
* Perform a 2D transformation on this vector.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public MutableBlockVector2D transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
this.x = (int) Math.floor(x2 + aboutX + translateX);
this.z = (int) Math.floor(z2 + aboutZ + translateZ);
return this;
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public MutableBlockVector2D getMinimum(MutableBlockVector2D v2) {
x = Math.min(x, v2.x);
z = Math.min(z, v2.z);
return this;
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public MutableBlockVector2D getMaximum(MutableBlockVector2D v2) {
x = Math.max(x, v2.x);
z = Math.max(z, v2.z);
return this;
}
/**
* Creates a 2D vector from this vector.
*
* @return a new vector
*/
public Vector2 toVector2() {
return new Vector2(x, z);
}
/**
* Creates a 3D vector by adding a zero Y component to this vector.
*
* @return a new vector
*/
public Vector3 toVector3() {
return toVector3(0);
}
/**
* Creates a 3D vector by adding the specified Y component to this vector.
*
* @param y the Y component
* @return a new vector
*/
public Vector3 toVector3(double y) {
return new Vector3(x, y, z);
}
/**
* Creates a 3D vector by adding a zero Y component to this vector.
*
* @return a new vector
*/
public BlockVector3 toBlockVector3() {
return toBlockVector3(0);
}
/**
* Creates a 3D vector by adding the specified Y component to this vector.
*
* @param y the Y component
* @return a new vector
*/
public BlockVector3 toBlockVector3(int y) {
return new BlockVector3(x, y, z);
}
/**
* Creates a 2D vector from this vector.
*
* @return a new vector
*/
public BlockVector2 toBlockVector2() {
return new BlockVector2(x, z);
}
@Override
public int getBlockZ() {
return z;
public boolean equals(Object obj) {
if (!(obj instanceof MutableBlockVector2D)) {
return false;
}
MutableBlockVector2D other = (MutableBlockVector2D) obj;
return other.x == this.x && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Integer.hashCode(x);
hash = 31 * hash + Integer.hashCode(z);
return hash;
}
@Override
public String toString() {
return "Mutable (" + x + ", " + z + ")";
}
public MutableBlockVector2D setComponents(int x, int z) {

View File

@ -1,10 +1,18 @@
package com.sk89q.worldedit.math;
import com.boydti.fawe.util.MathMan;
import com.sk89q.worldedit.math.transform.AffineTransform;
import static com.google.common.base.Preconditions.checkArgument;
import java.io.IOException;
import java.io.Serializable;
public class MutableVector extends Vector3 implements Serializable {
/**
* A mutable rendition of WorldEdit's Vector3 class.
* This class should ONLY be used locally for efficient vector manipulation.
*/
public class MutableVector implements Serializable {
private transient double x, y, z;
private static ThreadLocal<MutableVector> MUTABLE_CACHE = new ThreadLocal<MutableVector>() {
@ -14,7 +22,7 @@ public class MutableVector extends Vector3 implements Serializable {
}
};
public static MutableVector get(int x, int y, int z) {
public static MutableVector get(double x, double y, double z) {
return MUTABLE_CACHE.get().setComponents(x, y, z);
}
@ -23,26 +31,27 @@ public class MutableVector extends Vector3 implements Serializable {
}
public MutableVector(double x, double y, double z) {
super(0, 0, 0);
this.x = x;
this.y = y;
this.z = z;
}
public MutableVector() {
super(0, 0, 0);
this(0, 0, 0);
}
public MutableVector setComponents(BlockVector3 other) {
return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ());
public MutableVector setComponents(Vector3 other) {
return setComponents(other.getX(), other.getY(), other.getZ());
}
public MutableVector setComponents(MutableVector mutable) {
return setComponents(mutable.getX(), mutable.getY(), mutable.getZ());
}
// @Override
public MutableVector setComponents(int x, int y, int z) {
return this.setComponents((double) x, (double) y, (double) z);
}
// @Override
public MutableVector setComponents(double x, double y, double z) {
this.mutX(x);
this.mutY(y);
@ -50,50 +59,513 @@ public class MutableVector extends Vector3 implements Serializable {
return this;
}
// @Override
public final void mutX(double x) {
this.x = y;
}
// @Override
public final void mutY(double y) {
this.y =y;
this.y = y;
}
// @Override
public final void mutZ(double z) {
this.z = y;
}
// @Override
public final void mutX(int x) {
this.x = (double)x;
}
// @Override
public final void mutY(int y) {
this.y = (double)y;
}
// @Override
public final void mutZ(int z) {
this.z = (double)z;
}
@Override
public final double getX() {
return x;
}
@Override
public final double getY() {
return y;
}
@Override
public final double getZ() {
return z;
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public MutableVector add(MutableVector other) {
return add(other.x, other.y, other.z);
}
/**
* Add another vector to this vector and return the result as a new vector.
*
* @param x the value to add
* @param y the value to add
* @param z the value to add
* @return a new vector
*/
public MutableVector add(double x, double y, double z) {
this.x += x;
this.y += y;
this.z += z;
return this;
}
/**
* Add a list of vectors to this vector and return the
* result as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableVector add(MutableVector... others) {
for (MutableVector other : others) {
x += other.x;
y += other.y;
z += other.z;
}
return this;
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public MutableVector subtract(MutableVector other) {
return subtract(other.x, other.y, other.z);
}
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param x the value to subtract
* @param y the value to subtract
* @param z the value to subtract
* @return a new vector
*/
public MutableVector subtract(double x, double y, double z) {
this.x -= x;
this.y -= y;
this.z -= z;
return this;
}
/**
* Subtract a list of vectors from this vector and return the result
* as a new vector.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableVector subtract(MutableVector... others) {
for (MutableVector other : others) {
x -= other.x;
y -= other.y;
z -= other.z;
}
return this;
}
/**
* Multiply this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public MutableVector multiply(MutableVector other) {
return multiply(other.x, other.y, other.z);
}
/**
* Multiply this vector by another vector on each component.
*
* @param x the value to multiply
* @param y the value to multiply
* @param z the value to multiply
* @return a new vector
*/
public MutableVector multiply(double x, double y, double z) {
this.x *= x;
this.y *= y;
this.z *= z;
return this;
}
/**
* Multiply this vector by zero or more vectors on each component.
*
* @param others an array of vectors
* @return a new vector
*/
public MutableVector multiply(MutableVector... others) {
for (MutableVector other : others) {
x *= other.x;
y *= other.y;
z *= other.z;
}
return this;
}
/**
* Perform scalar multiplication and return a new vector.
*
* @param n the value to multiply
* @return a new vector
*/
public MutableVector multiply(double n) {
return multiply(n, n, n);
}
/**
* Divide this vector by another vector on each component.
*
* @param other the other vector
* @return a new vector
*/
public MutableVector divide(MutableVector other) {
return divide(other.x, other.y, other.z);
}
/**
* Divide this vector by another vector on each component.
*
* @param x the value to divide by
* @param y the value to divide by
* @param z the value to divide by
* @return a new vector
*/
public MutableVector divide(double x, double y, double z) {
this.x /= x;
this.y /= y;
this.z /= z;
return this;
}
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public MutableVector divide(double n) {
return divide(n, n, n);
}
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(lengthSq());
}
/**
* Get the length, squared, of the vector.
*
* @return length, squared
*/
public double lengthSq() {
return x * x + y * y + z * z;
}
/**
* Get the distance between this vector and another vector.
*
* @param other the other vector
* @return distance
*/
public double distance(Vector3 other) {
return Math.sqrt(distanceSq(other));
}
/**
* Get the distance between this vector and another vector, squared.
*
* @param other the other vector
* @return distance
*/
public double distanceSq(Vector3 other) {
double dx = other.getX() - x;
double dy = other.getY() - y;
double dz = other.getZ() - z;
return dx * dx + dy * dy + dz * dz;
}
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public MutableVector normalize() {
return divide(length());
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(MutableVector other) {
return x * other.x + y * other.y + z * other.z;
}
/**
* Gets the cross product of this and another vector.
*
* @param other the other vector
* @return the cross product of this and the other vector
*/
public Vector3 cross(MutableVector other) {
return new Vector3(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
);
}
/**
* Checks to see if a vector is contained with another.
*
* @param min the minimum point (X, Y, and Z are the lowest)
* @param max the maximum point (X, Y, and Z are the lowest)
* @return true if the vector is contained
*/
public boolean containedWithin(MutableVector min, MutableVector max) {
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
}
/**
* Clamp the Y component.
*
* @param min the minimum value
* @param max the maximum value
* @return a new vector
*/
public MutableVector clampY(int min, int max) {
checkArgument(min <= max, "minimum cannot be greater than maximum");
if (y < min) {
y = min;
}
if (y > max) {
y = max;
}
return this;
}
/**
* Floors the values of all components.
*
* @return a new vector
*/
public MutableVector floor() {
x = Math.floor(x);
y = Math.floor(y);
z = Math.floor(z);
return this;
}
/**
* Rounds all components up.
*
* @return a new vector
*/
public MutableVector ceil() {
x = Math.ceil(x);
y = Math.ceil(y);
z = Math.ceil(z);
return this;
}
/**
* Rounds all components to the closest integer.
*
* <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
*
* @return a new vector
*/
public MutableVector round() {
x = Math.floor(x + 0.5);
y = Math.floor(y + 0.5);
z = Math.floor(z + 0.5);
return this;
}
/**
* Returns a vector with the absolute values of the components of
* this vector.
*
* @return a new vector
*/
public MutableVector abs() {
x = Math.abs(x);
y = Math.abs(y);
z = Math.abs(z);
return this;
}
/**
* Perform a 2D transformation on this vector and return a new one.
*
* @param angle in degrees
* @param aboutX about which x coordinate to rotate
* @param aboutZ about which z coordinate to rotate
* @param translateX what to add after rotation
* @param translateZ what to add after rotation
* @return a new vector
* @see AffineTransform another method to transform vectors
*/
public MutableVector transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
angle = Math.toRadians(angle);
double x = this.x - aboutX;
double z = this.z - aboutZ;
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x2 = x * cos - z * sin;
double z2 = x * sin + z * cos;
this.x = x2 + aboutX + translateX;
this.z = z2 + aboutZ + translateZ;
return this;
}
/**
* Get this vector's pitch as used within the game.
*
* @return pitch in radians
*/
public double toPitch() {
double x = getX();
double z = getZ();
if (x == 0 && z == 0) {
return getY() > 0 ? -90 : 90;
} else {
double x2 = x * x;
double z2 = z * z;
double xz = Math.sqrt(x2 + z2);
return Math.toDegrees(Math.atan(-getY() / xz));
}
}
/**
* Get this vector's yaw as used within the game.
*
* @return yaw in radians
*/
public double toYaw() {
double x = getX();
double z = getZ();
double t = Math.atan2(-x, z);
double tau = 2 * Math.PI;
return Math.toDegrees(((t + tau) % tau));
}
/**
* Gets the minimum components of two vectors.
*
* @param v2 the second vector
* @return minimum
*/
public MutableVector getMinimum(MutableVector v2) {
x = Math.min(x, v2.x);
y = Math.min(y, v2.y);
z = Math.min(z, v2.z);
return this;
}
/**
* Gets the maximum components of two vectors.
*
* @param v2 the second vector
* @return maximum
*/
public MutableVector getMaximum(MutableVector v2) {
x = Math.max(x, v2.x);
y = Math.max(y, v2.y);
z = Math.max(z, v2.z);
return this;
}
/**
* Create a new {@code BlockVector} using the given components.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
* @return a new {@code BlockVector}
*/
public static BlockVector3 toBlockPoint(double x, double y, double z) {
return new BlockVector3(x, y, z);
}
/**
* Create a new {@code BlockVector} from this vector.
*
* @return a new {@code BlockVector}
*/
public BlockVector3 toBlockPoint() {
return toBlockPoint(x, y, z);
}
/**
* Creates a 2D vector by dropping the Y component from this vector.
*
* @return a new {@link Vector2}
*/
public Vector2 toVector2() {
return new Vector2(x, z);
}
public Vector3 toVector3() {
return new Vector3(x, y, z);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MutableVector)) {
return false;
}
MutableVector other = (MutableVector) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + Double.hashCode(x);
hash = 31 * hash + Double.hashCode(y);
hash = 31 * hash + Double.hashCode(z);
return hash;
}
@Override
public String toString() {
return "Mutable (" + x + ", " + y + ", " + z + ")";
}
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
stream.writeDouble(x);

View File

@ -3,15 +3,10 @@ package com.sk89q.worldedit.math.convolution;
import com.boydti.fawe.object.visitor.Fast2DIterator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
<<<<<<< HEAD
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.blocks.BaseBlock;
=======
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.Regions;
@ -74,16 +69,15 @@ public class HeightMap {
invalid = new boolean[data.length];
if (layers) {
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
int bx = min.getBlockX();
int bz = min.getBlockZ();
Iterable<Vector2D> flat = Regions.asFlatRegion(region).asFlatRegion();
Iterator<Vector2D> iter = new Fast2DIterator(flat, session).iterator();
Iterable<BlockVector2> flat = Regions.asFlatRegion(region).asFlatRegion();
Iterator<BlockVector2> iter = new Fast2DIterator(flat, session).iterator();
int layer = 0;
MutableBlockVector mutable = new MutableBlockVector();
while (iter.hasNext()) {
Vector2D pos = iter.next();
BlockVector2 pos = iter.next();
int x = pos.getBlockX();
int z = pos.getBlockZ();
layer = session.getNearestSurfaceLayer(x, z, (layer + 7) >> 3, 0, maxY);
@ -186,7 +180,7 @@ public class HeightMap {
// Depending on growing or shrinking we need to start at the bottom or top
if (newHeight > curHeight) {
// Set the top block of the column to be the same type (this might go wrong with rounding)
<<<<<<< HEAD
//<<<<<<< HEAD
BlockStateHolder existing = session.getBlock(xr, curBlock, zr);
// Skip water/lava
@ -206,33 +200,33 @@ public class HeightMap {
} else {
existing = PropertyGroup.LEVEL.set(existing, 15);
session.setBlock(xr, newBlock, zr, existing);
=======
BlockState existing = session.getBlock(new BlockVector3(xr, curHeight, zr));
// Skip water/lava
if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.LAVA) {
session.setBlock(new BlockVector3(xr, newHeight, zr), existing);
++blocksChanged;
// Grow -- start from 1 below top replacing airblocks
for (int y = newHeight - 1 - originY; y >= 0; --y) {
int copyFrom = (int) (y * scale);
session.setBlock(new BlockVector3(xr, originY + y, zr), session.getBlock(new BlockVector3(xr, originY + copyFrom, zr)));
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
//=======
// BlockState existing = session.getBlock(new BlockVector3(xr, curHeight, zr));
//
// // Skip water/lava
// if (existing.getBlockType() != BlockTypes.WATER && existing.getBlockType() != BlockTypes.LAVA) {
// session.setBlock(new BlockVector3(xr, newHeight, zr), existing);
// ++blocksChanged;
//
// // Grow -- start from 1 below top replacing airblocks
// for (int y = newHeight - 1 - originY; y >= 0; --y) {
// int copyFrom = (int) (y * scale);
// session.setBlock(new BlockVector3(xr, originY + y, zr), session.getBlock(new BlockVector3(xr, originY + copyFrom, zr)));
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
++blocksChanged;
}
}
} else if (curHeight > newHeight) {
<<<<<<< HEAD
//<<<<<<< HEAD
// Fill rest with air
for (int y = newBlock + 1; y <= ((curHeight + 15) >> 4); ++y) {
session.setBlock(xr, y, zr, fillerAir);
=======
// Shrink -- start from bottom
for (int y = 0; y < newHeight - originY; ++y) {
int copyFrom = (int) (y * scale);
session.setBlock(new BlockVector3(xr, originY + y, zr), session.getBlock(new BlockVector3(xr, originY + copyFrom, zr)));
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
//=======
// // Shrink -- start from bottom
// for (int y = 0; y < newHeight - originY; ++y) {
// int copyFrom = (int) (y * scale);
// session.setBlock(new BlockVector3(xr, originY + y, zr), session.getBlock(new BlockVector3(xr, originY + copyFrom, zr)));
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
++blocksChanged;
}
// Set the top block of the column to be the same type
@ -256,7 +250,7 @@ public class HeightMap {
public int apply(int[] data) throws MaxChangedBlocksException {
checkNotNull(data);
Vector minY = region.getMinimumPoint();
BlockVector3 minY = region.getMinimumPoint();
int originX = minY.getBlockX();
int originY = minY.getBlockY();
int originZ = minY.getBlockZ();
@ -300,20 +294,12 @@ public class HeightMap {
} else if (curHeight > newHeight) {
// Set the top block of the column to be the same type
// (this could otherwise go wrong with rounding)
<<<<<<< HEAD
session.setBlock(xr, newHeight, zr, session.getBlock(xr, curHeight, zr));
=======
session.setBlock(new BlockVector3(xr, newHeight, zr), session.getBlock(new BlockVector3(xr, curHeight, zr)));
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
++blocksChanged;
// Fill rest with air
for (int y = newHeight + 1; y <= curHeight; ++y) {
<<<<<<< HEAD
session.setBlock(xr, y, zr, fillerAir);
=======
session.setBlock(new BlockVector3(xr, y, zr), fillerAir);
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
++blocksChanged;
}
}

View File

@ -21,13 +21,9 @@
package com.sk89q.worldedit.math.interpolation;
<<<<<<< HEAD
import com.sk89q.worldedit.Vector;
=======
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.Vector3;
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
import java.util.List;

View File

@ -21,13 +21,9 @@
package com.sk89q.worldedit.math.interpolation;
<<<<<<< HEAD
import com.sk89q.worldedit.Vector;
=======
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.Vector3;
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
import java.util.List;
import java.util.Map.Entry;

View File

@ -19,13 +19,9 @@
package com.sk89q.worldedit.math.transform;
<<<<<<< HEAD
import com.sk89q.worldedit.Vector;
=======
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.Vector3;
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
import java.util.ArrayList;
import java.util.Arrays;

View File

@ -1,11 +1,11 @@
package com.sk89q.worldedit.math.transform;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
public class RoundedTransform implements Transform{
private final Transform transform;
private MutableBlockVector mutable = new MutableBlockVector();
// private MutableBlockVector mutable = new MutableBlockVector();
public RoundedTransform(Transform transform) {
this.transform = transform;
@ -17,12 +17,12 @@ public class RoundedTransform implements Transform{
}
@Override
public Vector apply(Vector input) {
Vector val = transform.apply(input);
mutable.mutX((int) Math.floor(val.getX() + 0.5));
mutable.mutY((int) Math.floor(val.getY() + 0.5));
mutable.mutZ((int) Math.floor(val.getZ() + 0.5));
return mutable;
public Vector3 apply(Vector3 input) {
Vector3 val = transform.apply(input);
// mutable.mutX((int) Math.floor(val.getX() + 0.5));
// mutable.mutY((int) Math.floor(val.getY() + 0.5));
// mutable.mutZ((int) Math.floor(val.getZ() + 0.5));
return new Vector3(Math.floor(val.getX() + 0.5), Math.floor(val.getY() + 0.5), Math.floor(val.getY() + 0.5));
}
@Override