base mod created
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
293
build/tmp/recompileMc/sources/net/minecraft/util/math/Vec3d.java
Normal file
293
build/tmp/recompileMc/sources/net/minecraft/util/math/Vec3d.java
Normal 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));
|
||||
}
|
||||
}
|
||||
150
build/tmp/recompileMc/sources/net/minecraft/util/math/Vec3i.java
Normal file
150
build/tmp/recompileMc/sources/net/minecraft/util/math/Vec3i.java
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.util.math;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
Reference in New Issue
Block a user