base mod created

This commit is contained in:
Mohammad-Ali Minaie
2018-10-08 09:07:47 -04:00
parent 0a7700c356
commit b86dedad2f
7848 changed files with 584664 additions and 1 deletions

View File

@@ -0,0 +1,636 @@
package net.minecraft.util.math;
import com.google.common.annotations.VisibleForTesting;
import javax.annotation.Nullable;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class AxisAlignedBB
{
/** The minimum X coordinate of this bounding box. Guaranteed to always be less than or equal to {@link #maxX}. */
public final double minX;
/** The minimum Y coordinate of this bounding box. Guaranteed to always be less than or equal to {@link #maxY}. */
public final double minY;
/** The minimum Y coordinate of this bounding box. Guaranteed to always be less than or equal to {@link #maxZ}. */
public final double minZ;
/** The maximum X coordinate of this bounding box. Guaranteed to always be greater than or equal to {@link #minX}. */
public final double maxX;
/** The maximum Y coordinate of this bounding box. Guaranteed to always be greater than or equal to {@link #minY}. */
public final double maxY;
/** The maximum Z coordinate of this bounding box. Guaranteed to always be greater than or equal to {@link #minZ}. */
public final double maxZ;
public AxisAlignedBB(double x1, double y1, double z1, double x2, double y2, double z2)
{
this.minX = Math.min(x1, x2);
this.minY = Math.min(y1, y2);
this.minZ = Math.min(z1, z2);
this.maxX = Math.max(x1, x2);
this.maxY = Math.max(y1, y2);
this.maxZ = Math.max(z1, z2);
}
public AxisAlignedBB(BlockPos pos)
{
this((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)(pos.getX() + 1), (double)(pos.getY() + 1), (double)(pos.getZ() + 1));
}
public AxisAlignedBB(BlockPos pos1, BlockPos pos2)
{
this((double)pos1.getX(), (double)pos1.getY(), (double)pos1.getZ(), (double)pos2.getX(), (double)pos2.getY(), (double)pos2.getZ());
}
@SideOnly(Side.CLIENT)
public AxisAlignedBB(Vec3d min, Vec3d max)
{
this(min.x, min.y, min.z, max.x, max.y, max.z);
}
/**
* Helper method that returns a new {@link AxisAlignedBB} with the given value for {@link #maxY} and all other
* values taken from this bounding box.
*/
public AxisAlignedBB setMaxY(double y2)
{
return new AxisAlignedBB(this.minX, this.minY, this.minZ, this.maxX, y2, this.maxZ);
}
public boolean equals(Object p_equals_1_)
{
if (this == p_equals_1_)
{
return true;
}
else if (!(p_equals_1_ instanceof AxisAlignedBB))
{
return false;
}
else
{
AxisAlignedBB axisalignedbb = (AxisAlignedBB)p_equals_1_;
if (Double.compare(axisalignedbb.minX, this.minX) != 0)
{
return false;
}
else if (Double.compare(axisalignedbb.minY, this.minY) != 0)
{
return false;
}
else if (Double.compare(axisalignedbb.minZ, this.minZ) != 0)
{
return false;
}
else if (Double.compare(axisalignedbb.maxX, this.maxX) != 0)
{
return false;
}
else if (Double.compare(axisalignedbb.maxY, this.maxY) != 0)
{
return false;
}
else
{
return Double.compare(axisalignedbb.maxZ, this.maxZ) == 0;
}
}
}
public int hashCode()
{
long i = Double.doubleToLongBits(this.minX);
int j = (int)(i ^ i >>> 32);
i = Double.doubleToLongBits(this.minY);
j = 31 * j + (int)(i ^ i >>> 32);
i = Double.doubleToLongBits(this.minZ);
j = 31 * j + (int)(i ^ i >>> 32);
i = Double.doubleToLongBits(this.maxX);
j = 31 * j + (int)(i ^ i >>> 32);
i = Double.doubleToLongBits(this.maxY);
j = 31 * j + (int)(i ^ i >>> 32);
i = Double.doubleToLongBits(this.maxZ);
j = 31 * j + (int)(i ^ i >>> 32);
return j;
}
/**
* Creates a new {@link AxisAlignedBB} that has been contracted by the given amount, with positive changes
* decreasing max values and negative changes increasing min values.
* <br/>
* If the amount to contract by is larger than the length of a side, then the side will wrap (still creating a valid
* AABB - see last sample).
*
* <h3>Samples:</h3>
* <table>
* <tr><th>Input</th><th>Result</th></tr>
* <tr><td><pre><code>new AxisAlignedBB(0, 0, 0, 4, 4, 4).contract(2, 2, 2)</code></pre></td><td><pre><samp>box[0.0,
* 0.0, 0.0 -> 2.0, 2.0, 2.0]</samp></pre></td></tr>
* <tr><td><pre><code>new AxisAlignedBB(0, 0, 0, 4, 4, 4).contract(-2, -2, -
* 2)</code></pre></td><td><pre><samp>box[2.0, 2.0, 2.0 -> 4.0, 4.0, 4.0]</samp></pre></td></tr>
* <tr><td><pre><code>new AxisAlignedBB(5, 5, 5, 7, 7, 7).contract(0, 1, -
* 1)</code></pre></td><td><pre><samp>box[5.0, 5.0, 6.0 -> 7.0, 6.0, 7.0]</samp></pre></td></tr>
* <tr><td><pre><code>new AxisAlignedBB(-2, -2, -2, 2, 2, 2).contract(4, -4,
* 0)</code></pre></td><td><pre><samp>box[-8.0, 2.0, -2.0 -> -2.0, 8.0, 2.0]</samp></pre></td></tr>
* </table>
*
* <h3>See Also:</h3>
* <ul>
* <li>{@link #expand(double, double, double)} - like this, except for expanding.</li>
* <li>{@link #grow(double, double, double)} and {@link #grow(double)} - expands in all directions.</li>
* <li>{@link #shrink(double)} - contracts in all directions (like {@link #grow(double)})</li>
* </ul>
*
* @return A new modified bounding box.
*/
public AxisAlignedBB contract(double x, double y, double z)
{
double d0 = this.minX;
double d1 = this.minY;
double d2 = this.minZ;
double d3 = this.maxX;
double d4 = this.maxY;
double d5 = this.maxZ;
if (x < 0.0D)
{
d0 -= x;
}
else if (x > 0.0D)
{
d3 -= x;
}
if (y < 0.0D)
{
d1 -= y;
}
else if (y > 0.0D)
{
d4 -= y;
}
if (z < 0.0D)
{
d2 -= z;
}
else if (z > 0.0D)
{
d5 -= z;
}
return new AxisAlignedBB(d0, d1, d2, d3, d4, d5);
}
/**
* Creates a new {@link AxisAlignedBB} that has been expanded by the given amount, with positive changes increasing
* max values and negative changes decreasing min values.
*
* <h3>Samples:</h3>
* <table>
* <tr><th>Input</th><th>Result</th></tr>
* <tr><td><pre><code>new AxisAlignedBB(0, 0, 0, 1, 1, 1).expand(2, 2, 2)</code></pre></td><td><pre><samp>box[0, 0,
* 0 -> 3, 3, 3]</samp></pre></td><td>
* <tr><td><pre><code>new AxisAlignedBB(0, 0, 0, 1, 1, 1).expand(-2, -2, -2)</code></pre></td><td><pre><samp>box[-2,
* -2, -2 -> 1, 1, 1]</samp></pre></td><td>
* <tr><td><pre><code>new AxisAlignedBB(5, 5, 5, 7, 7, 7).expand(0, 1, -1)</code></pre></td><td><pre><samp>box[5, 5,
* 4, 7, 8, 7]</samp></pre></td><td>
* </table>
*
* <h3>See Also:</h3>
* <ul>
* <li>{@link #contract(double, double, double)} - like this, except for shrinking.</li>
* <li>{@link #grow(double, double, double)} and {@link #grow(double)} - expands in all directions.</li>
* <li>{@link #shrink(double)} - contracts in all directions (like {@link #grow(double)})</li>
* </ul>
*
* @return A modified bounding box that will always be equal or greater in volume to this bounding box.
*/
public AxisAlignedBB expand(double x, double y, double z)
{
double d0 = this.minX;
double d1 = this.minY;
double d2 = this.minZ;
double d3 = this.maxX;
double d4 = this.maxY;
double d5 = this.maxZ;
if (x < 0.0D)
{
d0 += x;
}
else if (x > 0.0D)
{
d3 += x;
}
if (y < 0.0D)
{
d1 += y;
}
else if (y > 0.0D)
{
d4 += y;
}
if (z < 0.0D)
{
d2 += z;
}
else if (z > 0.0D)
{
d5 += z;
}
return new AxisAlignedBB(d0, d1, d2, d3, d4, d5);
}
/**
* Creates a new {@link AxisAlignedBB} that has been contracted by the given amount in both directions. Negative
* values will shrink the AABB instead of expanding it.
* <br/>
* Side lengths will be increased by 2 times the value of the parameters, since both min and max are changed.
* <br/>
* If contracting and the amount to contract by is larger than the length of a side, then the side will wrap (still
* creating a valid AABB - see last ample).
*
* <h3>Samples:</h3>
* <table>
* <tr><th>Input</th><th>Result</th></tr>
* <tr><td><pre><code>new AxisAlignedBB(0, 0, 0, 1, 1, 1).grow(2, 2, 2)</code></pre></td><td><pre><samp>box[-2.0, -
* 2.0, -2.0 -> 3.0, 3.0, 3.0]</samp></pre></td></tr>
* <tr><td><pre><code>new AxisAlignedBB(0, 0, 0, 6, 6, 6).grow(-2, -2, -2)</code></pre></td><td><pre><samp>box[2.0,
* 2.0, 2.0 -> 4.0, 4.0, 4.0]</samp></pre></td></tr>
* <tr><td><pre><code>new AxisAlignedBB(5, 5, 5, 7, 7, 7).grow(0, 1, -1)</code></pre></td><td><pre><samp>box[5.0,
* 4.0, 6.0 -> 7.0, 8.0, 6.0]</samp></pre></td></tr>
* <tr><td><pre><code>new AxisAlignedBB(1, 1, 1, 3, 3, 3).grow(-4, -2, -3)</code></pre></td><td><pre><samp>box[-1.0,
* 1.0, 0.0 -> 5.0, 3.0, 4.0]</samp></pre></td></tr>
* </table>
*
* <h3>See Also:</h3>
* <ul>
* <li>{@link #expand(double, double, double)} - expands in only one direction.</li>
* <li>{@link #contract(double, double, double)} - contracts in only one direction.</li>
* <lu>{@link #grow(double)} - version of this that expands in all directions from one parameter.</li>
* <li>{@link #shrink(double)} - contracts in all directions</li>
* </ul>
*
* @return A modified bounding box.
*/
public AxisAlignedBB grow(double x, double y, double z)
{
double d0 = this.minX - x;
double d1 = this.minY - y;
double d2 = this.minZ - z;
double d3 = this.maxX + x;
double d4 = this.maxY + y;
double d5 = this.maxZ + z;
return new AxisAlignedBB(d0, d1, d2, d3, d4, d5);
}
/**
* Creates a new {@link AxisAlignedBB} that is expanded by the given value in all directions. Equivalent to {@link
* #grow(double, double, double)} with the given value for all 3 params. Negative values will shrink the AABB.
* <br/>
* Side lengths will be increased by 2 times the value of the parameter, since both min and max are changed.
* <br/>
* If contracting and the amount to contract by is larger than the length of a side, then the side will wrap (still
* creating a valid AABB - see samples on {@link #grow(double, double, double)}).
*
* @return A modified AABB.
*/
public AxisAlignedBB grow(double value)
{
return this.grow(value, value, value);
}
public AxisAlignedBB intersect(AxisAlignedBB other)
{
double d0 = Math.max(this.minX, other.minX);
double d1 = Math.max(this.minY, other.minY);
double d2 = Math.max(this.minZ, other.minZ);
double d3 = Math.min(this.maxX, other.maxX);
double d4 = Math.min(this.maxY, other.maxY);
double d5 = Math.min(this.maxZ, other.maxZ);
return new AxisAlignedBB(d0, d1, d2, d3, d4, d5);
}
public AxisAlignedBB union(AxisAlignedBB other)
{
double d0 = Math.min(this.minX, other.minX);
double d1 = Math.min(this.minY, other.minY);
double d2 = Math.min(this.minZ, other.minZ);
double d3 = Math.max(this.maxX, other.maxX);
double d4 = Math.max(this.maxY, other.maxY);
double d5 = Math.max(this.maxZ, other.maxZ);
return new AxisAlignedBB(d0, d1, d2, d3, d4, d5);
}
/**
* Offsets the current bounding box by the specified amount.
*/
public AxisAlignedBB offset(double x, double y, double z)
{
return new AxisAlignedBB(this.minX + x, this.minY + y, this.minZ + z, this.maxX + x, this.maxY + y, this.maxZ + z);
}
public AxisAlignedBB offset(BlockPos pos)
{
return new AxisAlignedBB(this.minX + (double)pos.getX(), this.minY + (double)pos.getY(), this.minZ + (double)pos.getZ(), this.maxX + (double)pos.getX(), this.maxY + (double)pos.getY(), this.maxZ + (double)pos.getZ());
}
public AxisAlignedBB offset(Vec3d vec)
{
return this.offset(vec.x, vec.y, vec.z);
}
/**
* if instance and the argument bounding boxes overlap in the Y and Z dimensions, calculate the offset between them
* in the X dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the
* calculated offset. Otherwise return the calculated offset.
*/
public double calculateXOffset(AxisAlignedBB other, double offsetX)
{
if (other.maxY > this.minY && other.minY < this.maxY && other.maxZ > this.minZ && other.minZ < this.maxZ)
{
if (offsetX > 0.0D && other.maxX <= this.minX)
{
double d1 = this.minX - other.maxX;
if (d1 < offsetX)
{
offsetX = d1;
}
}
else if (offsetX < 0.0D && other.minX >= this.maxX)
{
double d0 = this.maxX - other.minX;
if (d0 > offsetX)
{
offsetX = d0;
}
}
return offsetX;
}
else
{
return offsetX;
}
}
/**
* if instance and the argument bounding boxes overlap in the X and Z dimensions, calculate the offset between them
* in the Y dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the
* calculated offset. Otherwise return the calculated offset.
*/
public double calculateYOffset(AxisAlignedBB other, double offsetY)
{
if (other.maxX > this.minX && other.minX < this.maxX && other.maxZ > this.minZ && other.minZ < this.maxZ)
{
if (offsetY > 0.0D && other.maxY <= this.minY)
{
double d1 = this.minY - other.maxY;
if (d1 < offsetY)
{
offsetY = d1;
}
}
else if (offsetY < 0.0D && other.minY >= this.maxY)
{
double d0 = this.maxY - other.minY;
if (d0 > offsetY)
{
offsetY = d0;
}
}
return offsetY;
}
else
{
return offsetY;
}
}
/**
* if instance and the argument bounding boxes overlap in the Y and X dimensions, calculate the offset between them
* in the Z dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the
* calculated offset. Otherwise return the calculated offset.
*/
public double calculateZOffset(AxisAlignedBB other, double offsetZ)
{
if (other.maxX > this.minX && other.minX < this.maxX && other.maxY > this.minY && other.minY < this.maxY)
{
if (offsetZ > 0.0D && other.maxZ <= this.minZ)
{
double d1 = this.minZ - other.maxZ;
if (d1 < offsetZ)
{
offsetZ = d1;
}
}
else if (offsetZ < 0.0D && other.minZ >= this.maxZ)
{
double d0 = this.maxZ - other.minZ;
if (d0 > offsetZ)
{
offsetZ = d0;
}
}
return offsetZ;
}
else
{
return offsetZ;
}
}
/**
* Checks if the bounding box intersects with another.
*/
public boolean intersects(AxisAlignedBB other)
{
return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ);
}
public boolean intersects(double x1, double y1, double z1, double x2, double y2, double z2)
{
return this.minX < x2 && this.maxX > x1 && this.minY < y2 && this.maxY > y1 && this.minZ < z2 && this.maxZ > z1;
}
@SideOnly(Side.CLIENT)
public boolean intersects(Vec3d min, Vec3d max)
{
return this.intersects(Math.min(min.x, max.x), Math.min(min.y, max.y), Math.min(min.z, max.z), Math.max(min.x, max.x), Math.max(min.y, max.y), Math.max(min.z, max.z));
}
/**
* Returns if the supplied Vec3D is completely inside the bounding box
*/
public boolean contains(Vec3d vec)
{
if (vec.x > this.minX && vec.x < this.maxX)
{
if (vec.y > this.minY && vec.y < this.maxY)
{
return vec.z > this.minZ && vec.z < this.maxZ;
}
else
{
return false;
}
}
else
{
return false;
}
}
/**
* Returns the average length of the edges of the bounding box.
*/
public double getAverageEdgeLength()
{
double d0 = this.maxX - this.minX;
double d1 = this.maxY - this.minY;
double d2 = this.maxZ - this.minZ;
return (d0 + d1 + d2) / 3.0D;
}
/**
* Creates a new {@link AxisAlignedBB} that is expanded by the given value in all directions. Equivalent to {@link
* #grow(double)} with value set to the negative of the value provided here. Passing a negative value to this method
* values will grow the AABB.
* <br/>
* Side lengths will be decreased by 2 times the value of the parameter, since both min and max are changed.
* <br/>
* If contracting and the amount to contract by is larger than the length of a side, then the side will wrap (still
* creating a valid AABB - see samples on {@link #grow(double, double, double)}).
*
* @return A modified AABB.
*/
public AxisAlignedBB shrink(double value)
{
return this.grow(-value);
}
@Nullable
public RayTraceResult calculateIntercept(Vec3d vecA, Vec3d vecB)
{
Vec3d vec3d = this.collideWithXPlane(this.minX, vecA, vecB);
EnumFacing enumfacing = EnumFacing.WEST;
Vec3d vec3d1 = this.collideWithXPlane(this.maxX, vecA, vecB);
if (vec3d1 != null && this.isClosest(vecA, vec3d, vec3d1))
{
vec3d = vec3d1;
enumfacing = EnumFacing.EAST;
}
vec3d1 = this.collideWithYPlane(this.minY, vecA, vecB);
if (vec3d1 != null && this.isClosest(vecA, vec3d, vec3d1))
{
vec3d = vec3d1;
enumfacing = EnumFacing.DOWN;
}
vec3d1 = this.collideWithYPlane(this.maxY, vecA, vecB);
if (vec3d1 != null && this.isClosest(vecA, vec3d, vec3d1))
{
vec3d = vec3d1;
enumfacing = EnumFacing.UP;
}
vec3d1 = this.collideWithZPlane(this.minZ, vecA, vecB);
if (vec3d1 != null && this.isClosest(vecA, vec3d, vec3d1))
{
vec3d = vec3d1;
enumfacing = EnumFacing.NORTH;
}
vec3d1 = this.collideWithZPlane(this.maxZ, vecA, vecB);
if (vec3d1 != null && this.isClosest(vecA, vec3d, vec3d1))
{
vec3d = vec3d1;
enumfacing = EnumFacing.SOUTH;
}
return vec3d == null ? null : new RayTraceResult(vec3d, enumfacing);
}
@VisibleForTesting
boolean isClosest(Vec3d p_186661_1_, @Nullable Vec3d p_186661_2_, Vec3d p_186661_3_)
{
return p_186661_2_ == null || p_186661_1_.squareDistanceTo(p_186661_3_) < p_186661_1_.squareDistanceTo(p_186661_2_);
}
@Nullable
@VisibleForTesting
Vec3d collideWithXPlane(double p_186671_1_, Vec3d p_186671_3_, Vec3d p_186671_4_)
{
Vec3d vec3d = p_186671_3_.getIntermediateWithXValue(p_186671_4_, p_186671_1_);
return vec3d != null && this.intersectsWithYZ(vec3d) ? vec3d : null;
}
@Nullable
@VisibleForTesting
Vec3d collideWithYPlane(double p_186663_1_, Vec3d p_186663_3_, Vec3d p_186663_4_)
{
Vec3d vec3d = p_186663_3_.getIntermediateWithYValue(p_186663_4_, p_186663_1_);
return vec3d != null && this.intersectsWithXZ(vec3d) ? vec3d : null;
}
@Nullable
@VisibleForTesting
Vec3d collideWithZPlane(double p_186665_1_, Vec3d p_186665_3_, Vec3d p_186665_4_)
{
Vec3d vec3d = p_186665_3_.getIntermediateWithZValue(p_186665_4_, p_186665_1_);
return vec3d != null && this.intersectsWithXY(vec3d) ? vec3d : null;
}
@VisibleForTesting
public boolean intersectsWithYZ(Vec3d vec)
{
return vec.y >= this.minY && vec.y <= this.maxY && vec.z >= this.minZ && vec.z <= this.maxZ;
}
@VisibleForTesting
public boolean intersectsWithXZ(Vec3d vec)
{
return vec.x >= this.minX && vec.x <= this.maxX && vec.z >= this.minZ && vec.z <= this.maxZ;
}
@VisibleForTesting
public boolean intersectsWithXY(Vec3d vec)
{
return vec.x >= this.minX && vec.x <= this.maxX && vec.y >= this.minY && vec.y <= this.maxY;
}
public String toString()
{
return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]";
}
@SideOnly(Side.CLIENT)
public boolean hasNaN()
{
return Double.isNaN(this.minX) || Double.isNaN(this.minY) || Double.isNaN(this.minZ) || Double.isNaN(this.maxX) || Double.isNaN(this.maxY) || Double.isNaN(this.maxZ);
}
@SideOnly(Side.CLIENT)
public Vec3d getCenter()
{
return new Vec3d(this.minX + (this.maxX - this.minX) * 0.5D, this.minY + (this.maxY - this.minY) * 0.5D, this.minZ + (this.maxZ - this.minZ) * 0.5D);
}
}

View File

@@ -0,0 +1,664 @@
package net.minecraft.util.math;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import javax.annotation.concurrent.Immutable;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Rotation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Immutable
public class BlockPos extends Vec3i
{
private static final Logger LOGGER = LogManager.getLogger();
/** An immutable block pos with zero as all coordinates. */
public static final BlockPos ORIGIN = new BlockPos(0, 0, 0);
private static final int NUM_X_BITS = 1 + MathHelper.log2(MathHelper.smallestEncompassingPowerOfTwo(30000000));
private static final int NUM_Z_BITS = NUM_X_BITS;
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
private static final int Y_SHIFT = 0 + NUM_Z_BITS;
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
public BlockPos(int x, int y, int z)
{
super(x, y, z);
}
public BlockPos(double x, double y, double z)
{
super(x, y, z);
}
public BlockPos(Entity source)
{
this(source.posX, source.posY, source.posZ);
}
public BlockPos(Vec3d vec)
{
this(vec.x, vec.y, vec.z);
}
public BlockPos(Vec3i source)
{
this(source.getX(), source.getY(), source.getZ());
}
/**
* Add the given coordinates to the coordinates of this BlockPos
*/
public BlockPos add(double x, double y, double z)
{
return x == 0.0D && y == 0.0D && z == 0.0D ? this : new BlockPos((double)this.getX() + x, (double)this.getY() + y, (double)this.getZ() + z);
}
/**
* Add the given coordinates to the coordinates of this BlockPos
*/
public BlockPos add(int x, int y, int z)
{
return x == 0 && y == 0 && z == 0 ? this : new BlockPos(this.getX() + x, this.getY() + y, this.getZ() + z);
}
/**
* Add the given Vector to this BlockPos
*/
public BlockPos add(Vec3i vec)
{
return this.add(vec.getX(), vec.getY(), vec.getZ());
}
/**
* Subtract the given Vector from this BlockPos
*/
public BlockPos subtract(Vec3i vec)
{
return this.add(-vec.getX(), -vec.getY(), -vec.getZ());
}
/**
* Offset this BlockPos 1 block up
*/
public BlockPos up()
{
return this.up(1);
}
/**
* Offset this BlockPos n blocks up
*/
public BlockPos up(int n)
{
return this.offset(EnumFacing.UP, n);
}
/**
* Offset this BlockPos 1 block down
*/
public BlockPos down()
{
return this.down(1);
}
/**
* Offset this BlockPos n blocks down
*/
public BlockPos down(int n)
{
return this.offset(EnumFacing.DOWN, n);
}
/**
* Offset this BlockPos 1 block in northern direction
*/
public BlockPos north()
{
return this.north(1);
}
/**
* Offset this BlockPos n blocks in northern direction
*/
public BlockPos north(int n)
{
return this.offset(EnumFacing.NORTH, n);
}
/**
* Offset this BlockPos 1 block in southern direction
*/
public BlockPos south()
{
return this.south(1);
}
/**
* Offset this BlockPos n blocks in southern direction
*/
public BlockPos south(int n)
{
return this.offset(EnumFacing.SOUTH, n);
}
/**
* Offset this BlockPos 1 block in western direction
*/
public BlockPos west()
{
return this.west(1);
}
/**
* Offset this BlockPos n blocks in western direction
*/
public BlockPos west(int n)
{
return this.offset(EnumFacing.WEST, n);
}
/**
* Offset this BlockPos 1 block in eastern direction
*/
public BlockPos east()
{
return this.east(1);
}
/**
* Offset this BlockPos n blocks in eastern direction
*/
public BlockPos east(int n)
{
return this.offset(EnumFacing.EAST, n);
}
/**
* Offset this BlockPos 1 block in the given direction
*/
public BlockPos offset(EnumFacing facing)
{
return this.offset(facing, 1);
}
/**
* Offsets this BlockPos n blocks in the given direction
*/
public BlockPos offset(EnumFacing facing, int n)
{
return n == 0 ? this : new BlockPos(this.getX() + facing.getFrontOffsetX() * n, this.getY() + facing.getFrontOffsetY() * n, this.getZ() + facing.getFrontOffsetZ() * n);
}
public BlockPos rotate(Rotation rotationIn)
{
switch (rotationIn)
{
case NONE:
default:
return this;
case CLOCKWISE_90:
return new BlockPos(-this.getZ(), this.getY(), this.getX());
case CLOCKWISE_180:
return new BlockPos(-this.getX(), this.getY(), -this.getZ());
case COUNTERCLOCKWISE_90:
return new BlockPos(this.getZ(), this.getY(), -this.getX());
}
}
/**
* Calculate the cross product of this and the given Vector
*/
public BlockPos crossProduct(Vec3i vec)
{
return new BlockPos(this.getY() * vec.getZ() - this.getZ() * vec.getY(), this.getZ() * vec.getX() - this.getX() * vec.getZ(), this.getX() * vec.getY() - this.getY() * vec.getX());
}
/**
* Serialize this BlockPos into a long value
*/
public long toLong()
{
return ((long)this.getX() & X_MASK) << X_SHIFT | ((long)this.getY() & Y_MASK) << Y_SHIFT | ((long)this.getZ() & Z_MASK) << 0;
}
/**
* Create a BlockPos from a serialized long value (created by toLong)
*/
public static BlockPos fromLong(long serialized)
{
int i = (int)(serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS);
int j = (int)(serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS);
int k = (int)(serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS);
return new BlockPos(i, j, k);
}
/**
* Create an Iterable that returns all positions in the box specified by the given corners. There is no requirement
* that one corner is greater than the other; individual coordinates will be swapped as needed.
*
* In situations where it is usable, prefer {@link #getAllInBoxMutable(BlockPos, BlockPos}) instead as it has better
* performance (fewer allocations)
*
* @see #getAllInBox(int, int, int, int, int, int)
* @see #getAllInBoxMutable(BlockPos, BlockPos)
* @see #mutablesBetween(int, int, int, int, int, int)
*
* @param from One corner of the box
* @param to Another corner of the box
*/
public static Iterable<BlockPos> getAllInBox(BlockPos from, BlockPos to)
{
return getAllInBox(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ()), Math.max(from.getX(), to.getX()), Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ()));
}
/**
* Create an Iterable that returns all positions in the box specified by the coordinates. <strong>Coordinates must
* be in order</strong>; e.g. x1 <= x2.
*
* In situations where it is usable, prefer {@link #getAllInBoxMutable(BlockPos, BlockPos}) instead as it has better
* performance (fewer allocations)
*
* @see #getAllInBox(BlockPos, BlockPos)
* @see #getAllInBoxMutable(BlockPos, BlockPos)
* @see #mutablesBetween(int, int, int, int, int, int)
*
* @param x1 The lower x coordinate
* @param y1 The lower y coordinate
* @param z1 The lower z coordinate
* @param x2 The upper x coordinate
* @param y2 The upper y coordinate
* @param z2 The upper z coordinate
*/
public static Iterable<BlockPos> getAllInBox(final int x1, final int y1, final int z1, final int x2, final int y2, final int z2)
{
return new Iterable<BlockPos>()
{
public Iterator<BlockPos> iterator()
{
return new AbstractIterator<BlockPos>()
{
private boolean first = true;
private int lastPosX;
private int lastPosY;
private int lastPosZ;
protected BlockPos computeNext()
{
if (this.first)
{
this.first = false;
this.lastPosX = x1;
this.lastPosY = y1;
this.lastPosZ = z1;
return new BlockPos(x1, y1, z1);
}
else if (this.lastPosX == x2 && this.lastPosY == y2 && this.lastPosZ == z2)
{
return (BlockPos)this.endOfData();
}
else
{
if (this.lastPosX < x2)
{
++this.lastPosX;
}
else if (this.lastPosY < y2)
{
this.lastPosX = x1;
++this.lastPosY;
}
else if (this.lastPosZ < z2)
{
this.lastPosX = x1;
this.lastPosY = y1;
++this.lastPosZ;
}
return new BlockPos(this.lastPosX, this.lastPosY, this.lastPosZ);
}
}
};
}
};
}
/**
* Returns a version of this BlockPos that is guaranteed to be immutable.
*
* <p>When storing a BlockPos given to you for an extended period of time, make sure you
* use this in case the value is changed internally.</p>
*/
public BlockPos toImmutable()
{
return this;
}
/**
* Creates an Iterable that returns all positions in the box specified by the given corners. There is no requirement
* that one corner is greater than the other; individual coordinates will be swapped as needed.
*
* This method uses {@link BlockPos.MutableBlockPos MutableBlockPos} instead of regular BlockPos, which grants
* better performance. However, the resulting BlockPos instances can only be used inside the iteration loop (as
* otherwise the value will change), unless {@link #toImmutable()} is called. This method is ideal for searching
* large areas and only storing a few locations.
*
* @see #getAllInBox(BlockPos, BlockPos)
* @see #getAllInBox(int, int, int, int, int, int)
* @see #getAllInBoxMutable(BlockPos, BlockPos)
* @see #mutablesBetween(int, int, int, int, int, int)
*
* @param from One corner of the box
* @param to Another corner of the box
*/
public static Iterable<BlockPos.MutableBlockPos> getAllInBoxMutable(BlockPos from, BlockPos to)
{
return getAllInBoxMutable(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ()), Math.max(from.getX(), to.getX()), Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ()));
}
/**
* Creates an Iterable that returns all positions in the box specified by the given corners. <strong>Coordinates
* must be in order</strong>; e.g. x1 <= x2.
*
* This method uses {@link BlockPos.MutableBlockPos MutableBlockPos} instead of regular BlockPos, which grants
* better performance. However, the resulting BlockPos instances can only be used inside the iteration loop (as
* otherwise the value will change), unless {@link #toImmutable()} is called. This method is ideal for searching
* large areas and only storing a few locations.
*
* @see #getAllInBox(BlockPos, BlockPos)
* @see #getAllInBox(int, int, int, int, int, int)
* @see #getAllInBoxMutable(BlockPos, BlockPos)
*
* @param x1 The lower x coordinate
* @param y1 The lower y coordinate
* @param z1 The lower z coordinate
* @param x2 The upper x coordinate
* @param y2 The upper y coordinate
* @param z2 The upper z coordinate
*/
public static Iterable<BlockPos.MutableBlockPos> getAllInBoxMutable(final int x1, final int y1, final int z1, final int x2, final int y2, final int z2)
{
return new Iterable<BlockPos.MutableBlockPos>()
{
public Iterator<BlockPos.MutableBlockPos> iterator()
{
return new AbstractIterator<BlockPos.MutableBlockPos>()
{
private BlockPos.MutableBlockPos pos;
protected BlockPos.MutableBlockPos computeNext()
{
if (this.pos == null)
{
this.pos = new BlockPos.MutableBlockPos(x1, y1, z1);
return this.pos;
}
else if (this.pos.x == x2 && this.pos.y == y2 && this.pos.z == z2)
{
return (BlockPos.MutableBlockPos)this.endOfData();
}
else
{
if (this.pos.x < x2)
{
++this.pos.x;
}
else if (this.pos.y < y2)
{
this.pos.x = x1;
++this.pos.y;
}
else if (this.pos.z < z2)
{
this.pos.x = x1;
this.pos.y = y1;
++this.pos.z;
}
return this.pos;
}
}
};
}
};
}
public static class MutableBlockPos extends BlockPos
{
/** Mutable X Coordinate */
protected int x;
/** Mutable Y Coordinate */
protected int y;
/** Mutable Z Coordinate */
protected int z;
public MutableBlockPos()
{
this(0, 0, 0);
}
public MutableBlockPos(BlockPos pos)
{
this(pos.getX(), pos.getY(), pos.getZ());
}
public MutableBlockPos(int x_, int y_, int z_)
{
super(0, 0, 0);
this.x = x_;
this.y = y_;
this.z = z_;
}
/**
* Add the given coordinates to the coordinates of this BlockPos
*/
public BlockPos add(double x, double y, double z)
{
return super.add(x, y, z).toImmutable();
}
/**
* Add the given coordinates to the coordinates of this BlockPos
*/
public BlockPos add(int x, int y, int z)
{
return super.add(x, y, z).toImmutable();
}
/**
* Offsets this BlockPos n blocks in the given direction
*/
public BlockPos offset(EnumFacing facing, int n)
{
return super.offset(facing, n).toImmutable();
}
public BlockPos rotate(Rotation rotationIn)
{
return super.rotate(rotationIn).toImmutable();
}
/**
* Gets the X coordinate.
*/
public int getX()
{
return this.x;
}
/**
* Gets the Y coordinate.
*/
public int getY()
{
return this.y;
}
/**
* Gets the Z coordinate.
*/
public int getZ()
{
return this.z;
}
/**
* None
*/
public BlockPos.MutableBlockPos setPos(int xIn, int yIn, int zIn)
{
this.x = xIn;
this.y = yIn;
this.z = zIn;
return this;
}
public BlockPos.MutableBlockPos setPos(double xIn, double yIn, double zIn)
{
return this.setPos(MathHelper.floor(xIn), MathHelper.floor(yIn), MathHelper.floor(zIn));
}
@SideOnly(Side.CLIENT)
public BlockPos.MutableBlockPos setPos(Entity entityIn)
{
return this.setPos(entityIn.posX, entityIn.posY, entityIn.posZ);
}
public BlockPos.MutableBlockPos setPos(Vec3i vec)
{
return this.setPos(vec.getX(), vec.getY(), vec.getZ());
}
public BlockPos.MutableBlockPos move(EnumFacing facing)
{
return this.move(facing, 1);
}
public BlockPos.MutableBlockPos move(EnumFacing facing, int n)
{
return this.setPos(this.x + facing.getFrontOffsetX() * n, this.y + facing.getFrontOffsetY() * n, this.z + facing.getFrontOffsetZ() * n);
}
public void setY(int yIn)
{
this.y = yIn;
}
/**
* Returns a version of this BlockPos that is guaranteed to be immutable.
*
* <p>When storing a BlockPos given to you for an extended period of time, make sure you
* use this in case the value is changed internally.</p>
*/
public BlockPos toImmutable()
{
return new BlockPos(this);
}
}
public static final class PooledMutableBlockPos extends BlockPos.MutableBlockPos
{
private boolean released;
private static final List<BlockPos.PooledMutableBlockPos> POOL = Lists.<BlockPos.PooledMutableBlockPos>newArrayList();
private PooledMutableBlockPos(int xIn, int yIn, int zIn)
{
super(xIn, yIn, zIn);
}
public static BlockPos.PooledMutableBlockPos retain()
{
return retain(0, 0, 0);
}
public static BlockPos.PooledMutableBlockPos retain(double xIn, double yIn, double zIn)
{
return retain(MathHelper.floor(xIn), MathHelper.floor(yIn), MathHelper.floor(zIn));
}
@SideOnly(Side.CLIENT)
public static BlockPos.PooledMutableBlockPos retain(Vec3i vec)
{
return retain(vec.getX(), vec.getY(), vec.getZ());
}
public static BlockPos.PooledMutableBlockPos retain(int xIn, int yIn, int zIn)
{
synchronized (POOL)
{
if (!POOL.isEmpty())
{
BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = POOL.remove(POOL.size() - 1);
if (blockpos$pooledmutableblockpos != null && blockpos$pooledmutableblockpos.released)
{
blockpos$pooledmutableblockpos.released = false;
blockpos$pooledmutableblockpos.setPos(xIn, yIn, zIn);
return blockpos$pooledmutableblockpos;
}
}
}
return new BlockPos.PooledMutableBlockPos(xIn, yIn, zIn);
}
public void release()
{
synchronized (POOL)
{
if (POOL.size() < 100)
{
POOL.add(this);
}
this.released = true;
}
}
/**
* None
*/
public BlockPos.PooledMutableBlockPos setPos(int xIn, int yIn, int zIn)
{
if (this.released)
{
BlockPos.LOGGER.error("PooledMutableBlockPosition modified after it was released.", new Throwable());
this.released = false;
}
return (BlockPos.PooledMutableBlockPos)super.setPos(xIn, yIn, zIn);
}
@SideOnly(Side.CLIENT)
public BlockPos.PooledMutableBlockPos setPos(Entity entityIn)
{
return (BlockPos.PooledMutableBlockPos)super.setPos(entityIn);
}
public BlockPos.PooledMutableBlockPos setPos(double xIn, double yIn, double zIn)
{
return (BlockPos.PooledMutableBlockPos)super.setPos(xIn, yIn, zIn);
}
public BlockPos.PooledMutableBlockPos setPos(Vec3i vec)
{
return (BlockPos.PooledMutableBlockPos)super.setPos(vec);
}
public BlockPos.PooledMutableBlockPos move(EnumFacing facing)
{
return (BlockPos.PooledMutableBlockPos)super.move(facing);
}
public BlockPos.PooledMutableBlockPos move(EnumFacing facing, int n)
{
return (BlockPos.PooledMutableBlockPos)super.move(facing, n);
}
}
}

View File

@@ -0,0 +1,191 @@
package net.minecraft.util.math;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.UnmodifiableIterator;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import javax.annotation.Nullable;
public class Cartesian
{
/**
* Create the cartesian product. This method returns an Iterable of arrays of type clazz.
*/
public static <T> Iterable<T[]> cartesianProduct(Class<T> clazz, Iterable <? extends Iterable <? extends T >> sets)
{
return new Cartesian.Product(clazz, (Iterable[])toArray(Iterable.class, sets));
}
/**
* Like cartesianProduct(Class, Iterable) but returns an Iterable of Lists instead.
*/
public static <T> Iterable<List<T>> cartesianProduct(Iterable <? extends Iterable <? extends T >> sets)
{
return arraysAsLists(cartesianProduct(Object.class, sets));
}
/**
* Convert an Iterable of Arrays (Object[]) to an Iterable of Lists
*/
private static <T> Iterable<List<T>> arraysAsLists(Iterable<Object[]> arrays)
{
return Iterables.transform(arrays, new Cartesian.GetList());
}
/**
* Create a new Array of type clazz with the contents of the given Iterable
*/
private static <T> T[] toArray(Class <? super T > clazz, Iterable <? extends T > it)
{
List<T> list = Lists.<T>newArrayList();
for (T t : it)
{
list.add(t);
}
return (T[])(list.toArray(createArray(clazz, list.size())));
}
private static <T> T[] createArray(Class <? super T > elementType, int length)
{
return (T[])((Object[])Array.newInstance(elementType, length));
}
static class GetList<T> implements Function<Object[], List<T>>
{
private GetList()
{
}
public List<T> apply(@Nullable Object[] p_apply_1_)
{
return Arrays.<T>asList((T[])p_apply_1_);
}
}
static class Product<T> implements Iterable<T[]>
{
private final Class<T> clazz;
private final Iterable <? extends T > [] iterables;
private Product(Class<T> clazz, Iterable <? extends T > [] iterables)
{
this.clazz = clazz;
this.iterables = iterables;
}
public Iterator<T[]> iterator()
{
return (Iterator<T[]>)(this.iterables.length <= 0 ? Collections.singletonList(Cartesian.createArray(this.clazz, 0)).iterator() : new Cartesian.Product.ProductIterator(this.clazz, this.iterables));
}
static class ProductIterator<T> extends UnmodifiableIterator<T[]>
{
private int index;
private final Iterable <? extends T > [] iterables;
private final Iterator <? extends T > [] iterators;
/** Array used as the result of next() */
private final T[] results;
private ProductIterator(Class<T> clazz, Iterable <? extends T > [] iterables)
{
this.index = -2;
this.iterables = iterables;
this.iterators = (Iterator[])Cartesian.createArray(Iterator.class, this.iterables.length);
for (int i = 0; i < this.iterables.length; ++i)
{
this.iterators[i] = iterables[i].iterator();
}
this.results = (T[])Cartesian.createArray(clazz, this.iterators.length);
}
/**
* Called when no more data is available in this Iterator.
*/
private void endOfData()
{
this.index = -1;
Arrays.fill(this.iterators, (Object)null);
Arrays.fill(this.results, (Object)null);
}
public boolean hasNext()
{
if (this.index == -2)
{
this.index = 0;
for (Iterator <? extends T > iterator1 : this.iterators)
{
if (!iterator1.hasNext())
{
this.endOfData();
break;
}
}
return true;
}
else
{
if (this.index >= this.iterators.length)
{
for (this.index = this.iterators.length - 1; this.index >= 0; --this.index)
{
Iterator <? extends T > iterator = this.iterators[this.index];
if (iterator.hasNext())
{
break;
}
if (this.index == 0)
{
this.endOfData();
break;
}
iterator = this.iterables[this.index].iterator();
this.iterators[this.index] = iterator;
if (!iterator.hasNext())
{
this.endOfData();
break;
}
}
}
return this.index >= 0;
}
}
public T[] next()
{
if (!this.hasNext())
{
throw new NoSuchElementException();
}
else
{
while (this.index < this.iterators.length)
{
this.results[this.index] = this.iterators[this.index].next();
++this.index;
}
return (T[])((Object[])this.results.clone());
}
}
}
}
}

View File

@@ -0,0 +1,109 @@
package net.minecraft.util.math;
import net.minecraft.entity.Entity;
public class ChunkPos
{
/** The X position of this Chunk Coordinate Pair */
public final int x;
/** The Z position of this Chunk Coordinate Pair */
public final int z;
public ChunkPos(int x, int z)
{
this.x = x;
this.z = z;
}
public ChunkPos(BlockPos pos)
{
this.x = pos.getX() >> 4;
this.z = pos.getZ() >> 4;
}
/**
* Converts the chunk coordinate pair to a long
*/
public static long asLong(int x, int z)
{
return (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
}
public int hashCode()
{
int i = 1664525 * this.x + 1013904223;
int j = 1664525 * (this.z ^ -559038737) + 1013904223;
return i ^ j;
}
public boolean equals(Object p_equals_1_)
{
if (this == p_equals_1_)
{
return true;
}
else if (!(p_equals_1_ instanceof ChunkPos))
{
return false;
}
else
{
ChunkPos chunkpos = (ChunkPos)p_equals_1_;
return this.x == chunkpos.x && this.z == chunkpos.z;
}
}
public double getDistanceSq(Entity entityIn)
{
double d0 = (double)(this.x * 16 + 8);
double d1 = (double)(this.z * 16 + 8);
double d2 = d0 - entityIn.posX;
double d3 = d1 - entityIn.posZ;
return d2 * d2 + d3 * d3;
}
/**
* Get the first world X coordinate that belongs to this Chunk
*/
public int getXStart()
{
return this.x << 4;
}
/**
* Get the first world Z coordinate that belongs to this Chunk
*/
public int getZStart()
{
return this.z << 4;
}
/**
* Get the last world X coordinate that belongs to this Chunk
*/
public int getXEnd()
{
return (this.x << 4) + 15;
}
/**
* Get the last world Z coordinate that belongs to this Chunk
*/
public int getZEnd()
{
return (this.z << 4) + 15;
}
/**
* Get the World coordinates of the Block with the given Chunk coordinates relative to this chunk
*/
public BlockPos getBlock(int x, int y, int z)
{
return new BlockPos((this.x << 4) + x, y, (this.z << 4) + z);
}
public String toString()
{
return "[" + this.x + ", " + this.z + "]";
}
}

View File

@@ -0,0 +1,665 @@
package net.minecraft.util.math;
import java.util.Random;
import java.util.UUID;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class MathHelper
{
public static final float SQRT_2 = sqrt(2.0F);
/** A table of sin values computed from 0 (inclusive) to 2*pi (exclusive), with steps of 2*PI / 65536. */
private static final float[] SIN_TABLE = new float[65536];
private static final Random RANDOM = new Random();
/**
* Though it looks like an array, this is really more like a mapping. Key (index of this array) is the upper 5 bits
* of the result of multiplying a 32-bit unsigned integer by the B(2, 5) De Bruijn sequence 0x077CB531. Value
* (value stored in the array) is the unique index (from the right) of the leftmost one-bit in a 32-bit unsigned
* integer that can cause the upper 5 bits to get that value. Used for highly optimized "find the log-base-2 of
* this number" calculations.
*/
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION;
private static final double FRAC_BIAS;
private static final double[] ASINE_TAB;
private static final double[] COS_TAB;
/**
* sin looked up in a table
*/
public static float sin(float value)
{
return SIN_TABLE[(int)(value * 10430.378F) & 65535];
}
/**
* cos looked up in the sin table with the appropriate offset
*/
public static float cos(float value)
{
return SIN_TABLE[(int)(value * 10430.378F + 16384.0F) & 65535];
}
public static float sqrt(float value)
{
return (float)Math.sqrt((double)value);
}
public static float sqrt(double value)
{
return (float)Math.sqrt(value);
}
/**
* Returns the greatest integer less than or equal to the float argument
*/
public static int floor(float value)
{
int i = (int)value;
return value < (float)i ? i - 1 : i;
}
/**
* returns par0 cast as an int, and no greater than Integer.MAX_VALUE-1024
*/
@SideOnly(Side.CLIENT)
public static int fastFloor(double value)
{
return (int)(value + 1024.0D) - 1024;
}
/**
* Returns the greatest integer less than or equal to the double argument
*/
public static int floor(double value)
{
int i = (int)value;
return value < (double)i ? i - 1 : i;
}
/**
* Long version of floor()
*/
public static long lfloor(double value)
{
long i = (long)value;
return value < (double)i ? i - 1L : i;
}
@SideOnly(Side.CLIENT)
public static int absFloor(double value)
{
return (int)(value >= 0.0D ? value : -value + 1.0D);
}
public static float abs(float value)
{
return value >= 0.0F ? value : -value;
}
/**
* Returns the unsigned value of an int.
*/
public static int abs(int value)
{
return value >= 0 ? value : -value;
}
public static int ceil(float value)
{
int i = (int)value;
return value > (float)i ? i + 1 : i;
}
public static int ceil(double value)
{
int i = (int)value;
return value > (double)i ? i + 1 : i;
}
/**
* Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and
* third parameters.
*/
public static int clamp(int num, int min, int max)
{
if (num < min)
{
return min;
}
else
{
return num > max ? max : num;
}
}
/**
* Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and
* third parameters
*/
public static float clamp(float num, float min, float max)
{
if (num < min)
{
return min;
}
else
{
return num > max ? max : num;
}
}
public static double clamp(double num, double min, double max)
{
if (num < min)
{
return min;
}
else
{
return num > max ? max : num;
}
}
public static double clampedLerp(double lowerBnd, double upperBnd, double slide)
{
if (slide < 0.0D)
{
return lowerBnd;
}
else
{
return slide > 1.0D ? upperBnd : lowerBnd + (upperBnd - lowerBnd) * slide;
}
}
/**
* Maximum of the absolute value of two numbers.
*/
public static double absMax(double p_76132_0_, double p_76132_2_)
{
if (p_76132_0_ < 0.0D)
{
p_76132_0_ = -p_76132_0_;
}
if (p_76132_2_ < 0.0D)
{
p_76132_2_ = -p_76132_2_;
}
return p_76132_0_ > p_76132_2_ ? p_76132_0_ : p_76132_2_;
}
/**
* Buckets an integer with specifed bucket sizes.
*/
@SideOnly(Side.CLIENT)
public static int intFloorDiv(int p_76137_0_, int p_76137_1_)
{
return p_76137_0_ < 0 ? -((-p_76137_0_ - 1) / p_76137_1_) - 1 : p_76137_0_ / p_76137_1_;
}
public static int getInt(Random random, int minimum, int maximum)
{
return minimum >= maximum ? minimum : random.nextInt(maximum - minimum + 1) + minimum;
}
public static float nextFloat(Random random, float minimum, float maximum)
{
return minimum >= maximum ? minimum : random.nextFloat() * (maximum - minimum) + minimum;
}
public static double nextDouble(Random random, double minimum, double maximum)
{
return minimum >= maximum ? minimum : random.nextDouble() * (maximum - minimum) + minimum;
}
public static double average(long[] values)
{
long i = 0L;
for (long j : values)
{
i += j;
}
return (double)i / (double)values.length;
}
@SideOnly(Side.CLIENT)
public static boolean epsilonEquals(float p_180185_0_, float p_180185_1_)
{
return abs(p_180185_1_ - p_180185_0_) < 1.0E-5F;
}
@SideOnly(Side.CLIENT)
public static int normalizeAngle(int p_180184_0_, int p_180184_1_)
{
return (p_180184_0_ % p_180184_1_ + p_180184_1_) % p_180184_1_;
}
@SideOnly(Side.CLIENT)
public static float positiveModulo(float numerator, float denominator)
{
return (numerator % denominator + denominator) % denominator;
}
@SideOnly(Side.CLIENT)
public static double positiveModulo(double numerator, double denominator)
{
return (numerator % denominator + denominator) % denominator;
}
/**
* the angle is reduced to an angle between -180 and +180 by mod, and a 360 check
*/
public static float wrapDegrees(float value)
{
value = value % 360.0F;
if (value >= 180.0F)
{
value -= 360.0F;
}
if (value < -180.0F)
{
value += 360.0F;
}
return value;
}
/**
* the angle is reduced to an angle between -180 and +180 by mod, and a 360 check
*/
public static double wrapDegrees(double value)
{
value = value % 360.0D;
if (value >= 180.0D)
{
value -= 360.0D;
}
if (value < -180.0D)
{
value += 360.0D;
}
return value;
}
/**
* Adjust the angle so that his value is in range [-180;180[
*/
public static int wrapDegrees(int angle)
{
angle = angle % 360;
if (angle >= 180)
{
angle -= 360;
}
if (angle < -180)
{
angle += 360;
}
return angle;
}
/**
* parses the string as integer or returns the second parameter if it fails
*/
public static int getInt(String value, int defaultValue)
{
try
{
return Integer.parseInt(value);
}
catch (Throwable var3)
{
return defaultValue;
}
}
/**
* parses the string as integer or returns the second parameter if it fails. this value is capped to par2
*/
public static int getInt(String value, int defaultValue, int max)
{
return Math.max(max, getInt(value, defaultValue));
}
/**
* parses the string as double or returns the second parameter if it fails.
*/
public static double getDouble(String value, double defaultValue)
{
try
{
return Double.parseDouble(value);
}
catch (Throwable var4)
{
return defaultValue;
}
}
public static double getDouble(String value, double defaultValue, double max)
{
return Math.max(max, getDouble(value, defaultValue));
}
/**
* Returns the input value rounded up to the next highest power of two.
*/
public static int smallestEncompassingPowerOfTwo(int value)
{
int i = value - 1;
i = i | i >> 1;
i = i | i >> 2;
i = i | i >> 4;
i = i | i >> 8;
i = i | i >> 16;
return i + 1;
}
/**
* Is the given value a power of two? (1, 2, 4, 8, 16, ...)
*/
private static boolean isPowerOfTwo(int value)
{
return value != 0 && (value & value - 1) == 0;
}
/**
* Uses a B(2, 5) De Bruijn sequence and a lookup table to efficiently calculate the log-base-two of the given
* value. Optimized for cases where the input value is a power-of-two. If the input value is not a power-of-two,
* then subtract 1 from the return value.
*/
public static int log2DeBruijn(int value)
{
value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value);
return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)((long)value * 125613361L >> 27) & 31];
}
/**
* Efficiently calculates the floor of the base-2 log of an integer value. This is effectively the index of the
* highest bit that is set. For example, if the number in binary is 0...100101, this will return 5.
*/
public static int log2(int value)
{
return log2DeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1);
}
/**
* Rounds the first parameter up to the next interval of the second parameter.
*
* For instance, {@code roundUp(1, 4)} returns 4; {@code roundUp(0, 4)} returns 0; and {@code roundUp(4, 4)} returns
* 4.
*/
public static int roundUp(int number, int interval)
{
if (interval == 0)
{
return 0;
}
else if (number == 0)
{
return interval;
}
else
{
if (number < 0)
{
interval *= -1;
}
int i = number % interval;
return i == 0 ? number : number + interval - i;
}
}
public static long getCoordinateRandom(int x, int y, int z)
{
long i = (long)(x * 3129871) ^ (long)z * 116129781L ^ (long)y;
i = i * i * 42317861L + i * 11L;
return i;
}
/**
* Makes an integer color from the given red, green, and blue float values
*/
@SideOnly(Side.CLIENT)
public static int rgb(float rIn, float gIn, float bIn)
{
return rgb(floor(rIn * 255.0F), floor(gIn * 255.0F), floor(bIn * 255.0F));
}
/**
* Makes a single int color with the given red, green, and blue values.
*/
@SideOnly(Side.CLIENT)
public static int rgb(int rIn, int gIn, int bIn)
{
int lvt_3_1_ = (rIn << 8) + gIn;
lvt_3_1_ = (lvt_3_1_ << 8) + bIn;
return lvt_3_1_;
}
@SideOnly(Side.CLIENT)
public static int multiplyColor(int p_180188_0_, int p_180188_1_)
{
int i = (p_180188_0_ & 16711680) >> 16;
int j = (p_180188_1_ & 16711680) >> 16;
int k = (p_180188_0_ & 65280) >> 8;
int l = (p_180188_1_ & 65280) >> 8;
int i1 = (p_180188_0_ & 255) >> 0;
int j1 = (p_180188_1_ & 255) >> 0;
int k1 = (int)((float)i * (float)j / 255.0F);
int l1 = (int)((float)k * (float)l / 255.0F);
int i2 = (int)((float)i1 * (float)j1 / 255.0F);
return p_180188_0_ & -16777216 | k1 << 16 | l1 << 8 | i2;
}
/**
* Gets the decimal portion of the given double. For instance, {@code frac(5.5)} returns {@code .5}.
*/
@SideOnly(Side.CLIENT)
public static double frac(double number)
{
return number - Math.floor(number);
}
@SideOnly(Side.CLIENT)
public static long getPositionRandom(Vec3i pos)
{
return getCoordinateRandom(pos.getX(), pos.getY(), pos.getZ());
}
public static UUID getRandomUUID(Random rand)
{
long i = rand.nextLong() & -61441L | 16384L;
long j = rand.nextLong() & 4611686018427387903L | Long.MIN_VALUE;
return new UUID(i, j);
}
/**
* Generates a random UUID using the shared random
*/
public static UUID getRandomUUID()
{
return getRandomUUID(RANDOM);
}
public static double pct(double p_181160_0_, double p_181160_2_, double p_181160_4_)
{
return (p_181160_0_ - p_181160_2_) / (p_181160_4_ - p_181160_2_);
}
public static double atan2(double p_181159_0_, double p_181159_2_)
{
double d0 = p_181159_2_ * p_181159_2_ + p_181159_0_ * p_181159_0_;
if (Double.isNaN(d0))
{
return Double.NaN;
}
else
{
boolean flag = p_181159_0_ < 0.0D;
if (flag)
{
p_181159_0_ = -p_181159_0_;
}
boolean flag1 = p_181159_2_ < 0.0D;
if (flag1)
{
p_181159_2_ = -p_181159_2_;
}
boolean flag2 = p_181159_0_ > p_181159_2_;
if (flag2)
{
double d1 = p_181159_2_;
p_181159_2_ = p_181159_0_;
p_181159_0_ = d1;
}
double d9 = fastInvSqrt(d0);
p_181159_2_ = p_181159_2_ * d9;
p_181159_0_ = p_181159_0_ * d9;
double d2 = FRAC_BIAS + p_181159_0_;
int i = (int)Double.doubleToRawLongBits(d2);
double d3 = ASINE_TAB[i];
double d4 = COS_TAB[i];
double d5 = d2 - FRAC_BIAS;
double d6 = p_181159_0_ * d4 - p_181159_2_ * d5;
double d7 = (6.0D + d6 * d6) * d6 * 0.16666666666666666D;
double d8 = d3 + d7;
if (flag2)
{
d8 = (Math.PI / 2D) - d8;
}
if (flag1)
{
d8 = Math.PI - d8;
}
if (flag)
{
d8 = -d8;
}
return d8;
}
}
/**
* Computes 1/sqrt(n) using <a href="https://en.wikipedia.org/wiki/Fast_inverse_square_root">the fast inverse square
* root</a> with a constant of 0x5FE6EB50C7B537AA.
*/
public static double fastInvSqrt(double p_181161_0_)
{
double d0 = 0.5D * p_181161_0_;
long i = Double.doubleToRawLongBits(p_181161_0_);
i = 6910469410427058090L - (i >> 1);
p_181161_0_ = Double.longBitsToDouble(i);
p_181161_0_ = p_181161_0_ * (1.5D - d0 * p_181161_0_ * p_181161_0_);
return p_181161_0_;
}
@SideOnly(Side.CLIENT)
public static int hsvToRGB(float hue, float saturation, float value)
{
int i = (int)(hue * 6.0F) % 6;
float f = hue * 6.0F - (float)i;
float f1 = value * (1.0F - saturation);
float f2 = value * (1.0F - f * saturation);
float f3 = value * (1.0F - (1.0F - f) * saturation);
float f4;
float f5;
float f6;
switch (i)
{
case 0:
f4 = value;
f5 = f3;
f6 = f1;
break;
case 1:
f4 = f2;
f5 = value;
f6 = f1;
break;
case 2:
f4 = f1;
f5 = value;
f6 = f3;
break;
case 3:
f4 = f1;
f5 = f2;
f6 = value;
break;
case 4:
f4 = f3;
f5 = f1;
f6 = value;
break;
case 5:
f4 = value;
f5 = f1;
f6 = f2;
break;
default:
throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value);
}
int j = clamp((int)(f4 * 255.0F), 0, 255);
int k = clamp((int)(f5 * 255.0F), 0, 255);
int l = clamp((int)(f6 * 255.0F), 0, 255);
return j << 16 | k << 8 | l;
}
public static int hash(int p_188208_0_)
{
p_188208_0_ = p_188208_0_ ^ p_188208_0_ >>> 16;
p_188208_0_ = p_188208_0_ * -2048144789;
p_188208_0_ = p_188208_0_ ^ p_188208_0_ >>> 13;
p_188208_0_ = p_188208_0_ * -1028477387;
p_188208_0_ = p_188208_0_ ^ p_188208_0_ >>> 16;
return p_188208_0_;
}
static
{
for (int i = 0; i < 65536; ++i)
{
SIN_TABLE[i] = (float)Math.sin((double)i * Math.PI * 2.0D / 65536.0D);
}
MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[] {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
FRAC_BIAS = Double.longBitsToDouble(4805340802404319232L);
ASINE_TAB = new double[257];
COS_TAB = new double[257];
for (int j = 0; j < 257; ++j)
{
double d0 = (double)j / 256.0D;
double d1 = Math.asin(d0);
COS_TAB[j] = Math.cos(d1);
ASINE_TAB[j] = d1;
}
}
}

View File

@@ -0,0 +1,69 @@
package net.minecraft.util.math;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumFacing;
public class RayTraceResult
{
/** Used to determine what sub-segment is hit */
public int subHit = -1;
/** Used to add extra hit info */
public Object hitInfo = null;
private BlockPos blockPos;
/** The type of hit that occured, see {@link RayTraceResult#Type} for possibilities. */
public RayTraceResult.Type typeOfHit;
public EnumFacing sideHit;
/** The vector position of the hit */
public Vec3d hitVec;
/** The hit entity */
public Entity entityHit;
public RayTraceResult(Vec3d hitVecIn, EnumFacing sideHitIn, BlockPos blockPosIn)
{
this(RayTraceResult.Type.BLOCK, hitVecIn, sideHitIn, blockPosIn);
}
public RayTraceResult(Vec3d hitVecIn, EnumFacing sideHitIn)
{
this(RayTraceResult.Type.BLOCK, hitVecIn, sideHitIn, BlockPos.ORIGIN);
}
public RayTraceResult(Entity entityIn)
{
this(entityIn, new Vec3d(entityIn.posX, entityIn.posY, entityIn.posZ));
}
public RayTraceResult(RayTraceResult.Type typeIn, Vec3d hitVecIn, EnumFacing sideHitIn, BlockPos blockPosIn)
{
this.typeOfHit = typeIn;
this.blockPos = blockPosIn;
this.sideHit = sideHitIn;
this.hitVec = new Vec3d(hitVecIn.x, hitVecIn.y, hitVecIn.z);
}
public RayTraceResult(Entity entityHitIn, Vec3d hitVecIn)
{
this.typeOfHit = RayTraceResult.Type.ENTITY;
this.entityHit = entityHitIn;
this.hitVec = hitVecIn;
}
public BlockPos getBlockPos()
{
return this.blockPos;
}
public String toString()
{
return "HitResult{type=" + this.typeOfHit + ", blockpos=" + this.blockPos + ", f=" + this.sideHit + ", pos=" + this.hitVec + ", entity=" + this.entityHit + '}';
}
public static enum Type
{
MISS,
BLOCK,
ENTITY;
}
}

View File

@@ -0,0 +1,72 @@
package net.minecraft.util.math;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagList;
public class Rotations
{
/** Rotation on the X axis */
protected final float x;
/** Rotation on the Y axis */
protected final float y;
/** Rotation on the Z axis */
protected final float z;
public Rotations(float x, float y, float z)
{
this.x = !Float.isInfinite(x) && !Float.isNaN(x) ? x % 360.0F : 0.0F;
this.y = !Float.isInfinite(y) && !Float.isNaN(y) ? y % 360.0F : 0.0F;
this.z = !Float.isInfinite(z) && !Float.isNaN(z) ? z % 360.0F : 0.0F;
}
public Rotations(NBTTagList nbt)
{
this(nbt.getFloatAt(0), nbt.getFloatAt(1), nbt.getFloatAt(2));
}
public NBTTagList writeToNBT()
{
NBTTagList nbttaglist = new NBTTagList();
nbttaglist.appendTag(new NBTTagFloat(this.x));
nbttaglist.appendTag(new NBTTagFloat(this.y));
nbttaglist.appendTag(new NBTTagFloat(this.z));
return nbttaglist;
}
public boolean equals(Object p_equals_1_)
{
if (!(p_equals_1_ instanceof Rotations))
{
return false;
}
else
{
Rotations rotations = (Rotations)p_equals_1_;
return this.x == rotations.x && this.y == rotations.y && this.z == rotations.z;
}
}
/**
* Gets the X axis rotation
*/
public float getX()
{
return this.x;
}
/**
* Gets the Y axis rotation
*/
public float getY()
{
return this.y;
}
/**
* Gets the Z axis rotation
*/
public float getZ()
{
return this.z;
}
}

View File

@@ -0,0 +1,35 @@
package net.minecraft.util.math;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class Vec2f
{
/** An immutable vector with {@code 0.0F} as the x and y components. */
public static final Vec2f ZERO = new Vec2f(0.0F, 0.0F);
/** An immutable vector with {@code 1.0F} as the x and y components. */
public static final Vec2f ONE = new Vec2f(1.0F, 1.0F);
/** An immutable vector with {@code 1.0F} as the x component. */
public static final Vec2f UNIT_X = new Vec2f(1.0F, 0.0F);
/** An immutable vector with {@code -1.0F} as the x component. */
public static final Vec2f NEGATIVE_UNIT_X = new Vec2f(-1.0F, 0.0F);
/** An immutable vector with {@code 1.0F} as the y component. */
public static final Vec2f UNIT_Y = new Vec2f(0.0F, 1.0F);
/** An immutable vector with {@code -1.0F} as the y component. */
public static final Vec2f NEGATIVE_UNIT_Y = new Vec2f(0.0F, -1.0F);
/** An immutable vector with {@link Float#MAX_VALUE} as the x and y components. */
public static final Vec2f MAX = new Vec2f(Float.MAX_VALUE, Float.MAX_VALUE);
/** An immutable vector with {@link Float#MIN_VALUE} as the x and y components. */
public static final Vec2f MIN = new Vec2f(Float.MIN_VALUE, Float.MIN_VALUE);
/** The x component of this vector. */
public final float x;
/** The y component of this vector. */
public final float y;
public Vec2f(float xIn, float yIn)
{
this.x = xIn;
this.y = yIn;
}
}

View File

@@ -0,0 +1,293 @@
package net.minecraft.util.math;
import javax.annotation.Nullable;
public class Vec3d
{
public static final Vec3d ZERO = new Vec3d(0.0D, 0.0D, 0.0D);
/** X coordinate of Vec3D */
public final double x;
/** Y coordinate of Vec3D */
public final double y;
/** Z coordinate of Vec3D */
public final double z;
public Vec3d(double xIn, double yIn, double zIn)
{
if (xIn == -0.0D)
{
xIn = 0.0D;
}
if (yIn == -0.0D)
{
yIn = 0.0D;
}
if (zIn == -0.0D)
{
zIn = 0.0D;
}
this.x = xIn;
this.y = yIn;
this.z = zIn;
}
public Vec3d(Vec3i vector)
{
this((double)vector.getX(), (double)vector.getY(), (double)vector.getZ());
}
/**
* Returns a new vector with the result of the specified vector minus this.
*/
public Vec3d subtractReverse(Vec3d vec)
{
return new Vec3d(vec.x - this.x, vec.y - this.y, vec.z - this.z);
}
/**
* Normalizes the vector to a length of 1 (except if it is the zero vector)
*/
public Vec3d normalize()
{
double d0 = (double)MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
return d0 < 1.0E-4D ? ZERO : new Vec3d(this.x / d0, this.y / d0, this.z / d0);
}
public double dotProduct(Vec3d vec)
{
return this.x * vec.x + this.y * vec.y + this.z * vec.z;
}
/**
* Returns a new vector with the result of this vector x the specified vector.
*/
public Vec3d crossProduct(Vec3d vec)
{
return new Vec3d(this.y * vec.z - this.z * vec.y, this.z * vec.x - this.x * vec.z, this.x * vec.y - this.y * vec.x);
}
public Vec3d subtract(Vec3d vec)
{
return this.subtract(vec.x, vec.y, vec.z);
}
public Vec3d subtract(double x, double y, double z)
{
return this.addVector(-x, -y, -z);
}
public Vec3d add(Vec3d vec)
{
return this.addVector(vec.x, vec.y, vec.z);
}
/**
* Adds the specified x,y,z vector components to this vector and returns the resulting vector. Does not change this
* vector.
*/
public Vec3d addVector(double x, double y, double z)
{
return new Vec3d(this.x + x, this.y + y, this.z + z);
}
/**
* Euclidean distance between this and the specified vector, returned as double.
*/
public double distanceTo(Vec3d vec)
{
double d0 = vec.x - this.x;
double d1 = vec.y - this.y;
double d2 = vec.z - this.z;
return (double)MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
}
/**
* The square of the Euclidean distance between this and the specified vector.
*/
public double squareDistanceTo(Vec3d vec)
{
double d0 = vec.x - this.x;
double d1 = vec.y - this.y;
double d2 = vec.z - this.z;
return d0 * d0 + d1 * d1 + d2 * d2;
}
public double squareDistanceTo(double xIn, double yIn, double zIn)
{
double d0 = xIn - this.x;
double d1 = yIn - this.y;
double d2 = zIn - this.z;
return d0 * d0 + d1 * d1 + d2 * d2;
}
public Vec3d scale(double factor)
{
return new Vec3d(this.x * factor, this.y * factor, this.z * factor);
}
/**
* Returns the length of the vector.
*/
public double lengthVector()
{
return (double)MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
}
public double lengthSquared()
{
return this.x * this.x + this.y * this.y + this.z * this.z;
}
/**
* Returns a new vector with x value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*/
@Nullable
public Vec3d getIntermediateWithXValue(Vec3d vec, double x)
{
double d0 = vec.x - this.x;
double d1 = vec.y - this.y;
double d2 = vec.z - this.z;
if (d0 * d0 < 1.0000000116860974E-7D)
{
return null;
}
else
{
double d3 = (x - this.x) / d0;
return d3 >= 0.0D && d3 <= 1.0D ? new Vec3d(this.x + d0 * d3, this.y + d1 * d3, this.z + d2 * d3) : null;
}
}
/**
* Returns a new vector with y value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*/
@Nullable
public Vec3d getIntermediateWithYValue(Vec3d vec, double y)
{
double d0 = vec.x - this.x;
double d1 = vec.y - this.y;
double d2 = vec.z - this.z;
if (d1 * d1 < 1.0000000116860974E-7D)
{
return null;
}
else
{
double d3 = (y - this.y) / d1;
return d3 >= 0.0D && d3 <= 1.0D ? new Vec3d(this.x + d0 * d3, this.y + d1 * d3, this.z + d2 * d3) : null;
}
}
/**
* Returns a new vector with z value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*/
@Nullable
public Vec3d getIntermediateWithZValue(Vec3d vec, double z)
{
double d0 = vec.x - this.x;
double d1 = vec.y - this.y;
double d2 = vec.z - this.z;
if (d2 * d2 < 1.0000000116860974E-7D)
{
return null;
}
else
{
double d3 = (z - this.z) / d2;
return d3 >= 0.0D && d3 <= 1.0D ? new Vec3d(this.x + d0 * d3, this.y + d1 * d3, this.z + d2 * d3) : null;
}
}
public boolean equals(Object p_equals_1_)
{
if (this == p_equals_1_)
{
return true;
}
else if (!(p_equals_1_ instanceof Vec3d))
{
return false;
}
else
{
Vec3d vec3d = (Vec3d)p_equals_1_;
if (Double.compare(vec3d.x, this.x) != 0)
{
return false;
}
else if (Double.compare(vec3d.y, this.y) != 0)
{
return false;
}
else
{
return Double.compare(vec3d.z, this.z) == 0;
}
}
}
public int hashCode()
{
long j = Double.doubleToLongBits(this.x);
int i = (int)(j ^ j >>> 32);
j = Double.doubleToLongBits(this.y);
i = 31 * i + (int)(j ^ j >>> 32);
j = Double.doubleToLongBits(this.z);
i = 31 * i + (int)(j ^ j >>> 32);
return i;
}
public String toString()
{
return "(" + this.x + ", " + this.y + ", " + this.z + ")";
}
public Vec3d rotatePitch(float pitch)
{
float f = MathHelper.cos(pitch);
float f1 = MathHelper.sin(pitch);
double d0 = this.x;
double d1 = this.y * (double)f + this.z * (double)f1;
double d2 = this.z * (double)f - this.y * (double)f1;
return new Vec3d(d0, d1, d2);
}
public Vec3d rotateYaw(float yaw)
{
float f = MathHelper.cos(yaw);
float f1 = MathHelper.sin(yaw);
double d0 = this.x * (double)f + this.z * (double)f1;
double d1 = this.y;
double d2 = this.z * (double)f - this.x * (double)f1;
return new Vec3d(d0, d1, d2);
}
/**
* returns a Vec3d from given pitch and yaw degrees as Vec2f
*/
public static Vec3d fromPitchYawVector(Vec2f p_189984_0_)
{
return fromPitchYaw(p_189984_0_.x, p_189984_0_.y);
}
/**
* returns a Vec3d from given pitch and yaw degrees
*/
public static Vec3d fromPitchYaw(float p_189986_0_, float p_189986_1_)
{
float f = MathHelper.cos(-p_189986_1_ * 0.017453292F - (float)Math.PI);
float f1 = MathHelper.sin(-p_189986_1_ * 0.017453292F - (float)Math.PI);
float f2 = -MathHelper.cos(-p_189986_0_ * 0.017453292F);
float f3 = MathHelper.sin(-p_189986_0_ * 0.017453292F);
return new Vec3d((double)(f1 * f2), (double)f3, (double)(f * f2));
}
}

View File

@@ -0,0 +1,150 @@
package net.minecraft.util.math;
import com.google.common.base.MoreObjects;
import javax.annotation.concurrent.Immutable;
@Immutable
public class Vec3i implements Comparable<Vec3i>
{
/** An immutable vector with zero as all coordinates. */
public static final Vec3i NULL_VECTOR = new Vec3i(0, 0, 0);
/** X coordinate */
private final int x;
/** Y coordinate */
private final int y;
/** Z coordinate */
private final int z;
public Vec3i(int xIn, int yIn, int zIn)
{
this.x = xIn;
this.y = yIn;
this.z = zIn;
}
public Vec3i(double xIn, double yIn, double zIn)
{
this(MathHelper.floor(xIn), MathHelper.floor(yIn), MathHelper.floor(zIn));
}
public boolean equals(Object p_equals_1_)
{
if (this == p_equals_1_)
{
return true;
}
else if (!(p_equals_1_ instanceof Vec3i))
{
return false;
}
else
{
Vec3i vec3i = (Vec3i)p_equals_1_;
if (this.getX() != vec3i.getX())
{
return false;
}
else if (this.getY() != vec3i.getY())
{
return false;
}
else
{
return this.getZ() == vec3i.getZ();
}
}
}
public int hashCode()
{
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
}
public int compareTo(Vec3i p_compareTo_1_)
{
if (this.getY() == p_compareTo_1_.getY())
{
return this.getZ() == p_compareTo_1_.getZ() ? this.getX() - p_compareTo_1_.getX() : this.getZ() - p_compareTo_1_.getZ();
}
else
{
return this.getY() - p_compareTo_1_.getY();
}
}
/**
* Gets the X coordinate.
*/
public int getX()
{
return this.x;
}
/**
* Gets the Y coordinate.
*/
public int getY()
{
return this.y;
}
/**
* Gets the Z coordinate.
*/
public int getZ()
{
return this.z;
}
/**
* Calculate the cross product of this and the given Vector
*/
public Vec3i crossProduct(Vec3i vec)
{
return new Vec3i(this.getY() * vec.getZ() - this.getZ() * vec.getY(), this.getZ() * vec.getX() - this.getX() * vec.getZ(), this.getX() * vec.getY() - this.getY() * vec.getX());
}
public double getDistance(int xIn, int yIn, int zIn)
{
double d0 = (double)(this.getX() - xIn);
double d1 = (double)(this.getY() - yIn);
double d2 = (double)(this.getZ() - zIn);
return Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
}
/**
* Calculate squared distance to the given coordinates
*/
public double distanceSq(double toX, double toY, double toZ)
{
double d0 = (double)this.getX() - toX;
double d1 = (double)this.getY() - toY;
double d2 = (double)this.getZ() - toZ;
return d0 * d0 + d1 * d1 + d2 * d2;
}
/**
* Compute square of distance from point x, y, z to center of this Block
*/
public double distanceSqToCenter(double xIn, double yIn, double zIn)
{
double d0 = (double)this.getX() + 0.5D - xIn;
double d1 = (double)this.getY() + 0.5D - yIn;
double d2 = (double)this.getZ() + 0.5D - zIn;
return d0 * d0 + d1 * d1 + d2 * d2;
}
/**
* Calculate squared distance to the given Vector
*/
public double distanceSq(Vec3i to)
{
return this.distanceSq((double)to.getX(), (double)to.getY(), (double)to.getZ());
}
public String toString()
{
return MoreObjects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString();
}
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.util.math;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;