Skip to content

Instantly share code, notes, and snippets.

@hnOsmium0001
Last active July 11, 2023 16:39
Show Gist options
  • Select an option

  • Save hnOsmium0001/fdc93d21e9f9e4b806d8a5bedd249ed8 to your computer and use it in GitHub Desktop.

Select an option

Save hnOsmium0001/fdc93d21e9f9e4b806d8a5bedd249ed8 to your computer and use it in GitHub Desktop.
Extension to AxisAlignedBB, adding functions such as rotation
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import javax.vecmath.Matrix4d;
import javax.vecmath.Vector3d;
import java.io.Serializable;
/**
* Extends the functionality of {@link AxisAlignedBB} without adding extra properties.
*/
public class ExtendedAABB extends AxisAlignedBB implements Serializable {
public static ExtendedAABB of(Vec3i vec) {
return new ExtendedAABB(vec, vec);
}
public static ExtendedAABB of(Vec3d vec) {
return new ExtendedAABB(vec, vec);
}
public static ExtendedAABB of(Vector3d vec) {
return new ExtendedAABB(vec, vec);
}
public static ExtendedAABB from(AxisAlignedBB source) {
return new ExtendedAABB(source.minX, source.minY, source.minZ, source.maxX, source.maxY, source.maxZ);
}
public static CompoundNBT toNBT(ExtendedAABB source) {
CompoundNBT tag = new CompoundNBT();
toNBT(source, tag);
return tag;
}
public static void toNBT(ExtendedAABB source, CompoundNBT tag) {
tag.putDouble("minX", source.minX);
tag.putDouble("minY", source.minY);
tag.putDouble("minZ", source.minZ);
tag.putDouble("maxX", source.maxX);
tag.putDouble("maxY", source.maxY);
tag.putDouble("maxZ", source.maxZ);
}
public static ExtendedAABB fromNBT(CompoundNBT tag) {
return new ExtendedAABB(
tag.getDouble("minX"),
tag.getDouble("minY"),
tag.getDouble("minZ"),
tag.getDouble("maxX"),
tag.getDouble("maxY"),
tag.getDouble("maxZ")
);
}
public ExtendedAABB(double x1, double y1, double z1, double x2, double y2, double z2) {
super(x1, y1, z1, x2, y2, z2);
}
public ExtendedAABB(Vec3i min, Vec3i max) {
this(min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ());
}
public ExtendedAABB(Vec3d min, Vec3d max) {
super(min, max);
}
public ExtendedAABB(Vector3d min, Vector3d max) {
this(min.x, min.y, min.z, max.x, max.y, max.z);
}
/**
* Rotate the current ExtendedAABB on three different axis and return a new one if any of the parameters are nonzero.
* <p>
* When called, it will rotate the current ExtendedAABB on all three axis by a given degree one at a time, as <b><a
* href="https://en.wikipedia.org/wiki/Right-hand_rule#Electromagnetics">Right Hand Law in electromagnetism</a></b>:
* <i>The direction of a positive rotation is the direction of your fingers when your thumb is pointing towards the positive direction of the axis.</i>
* <p>
* Equivalent to apply the method {@link #rotate(Axis, int)} three times on all X, Y, and Z axis.
*
* <h3>Example:</h3>
* Given the current AABB describes an half box where the empty side is pointing {@link Direction#UP up}<sup>1</sup>, a rotation of
* x=90 will make the empty side pointing to the {@link Direction#SOUTH south}<sup>2</sup>.
* <p>
* <hr/>
* <sup>1. {@link AxisDirection#POSITIVE positive} direction of {@link Axis#Y y axis}</sup>
* <sup>2. {@link AxisDirection#POSITIVE positive} direction of {@link Axis#Z z axis}</sup>
*
* @param x The angle to rotate on x-axis, in degrees
* @param y The angle to rotate on y-axis, in degrees
* @param z The angle to rotate on z-axis, in degrees
* @return A new, rotated ExtendedAABB
*/
public ExtendedAABB rotate(int x, int y, int z) {
Matrix4d rotationMat = TransformationUtils.combineTransformations(
TransformationUtils.getRotationMatrix(Axis.X, x),
TransformationUtils.getRotationMatrix(Axis.Y, y),
TransformationUtils.getRotationMatrix(Axis.Z, z));
return this.transformSelf(rotationMat, true);
}
/**
* Rotate the ExtendedAABB on the given axis at a given angle.
* <p>
* See {@link #rotate(int, int, int)} for more information and examples.
*
* @param axis The axis to rotate around
* @param angle The angle to rotate, in degrees.
* @return A new, rotated ExtendedAABB
* @see #rotate(int, int, int)
*/
public ExtendedAABB rotate(Axis axis, int angle) {
if (angle == 0) {
return this;
}
return this.transformSelf(TransformationUtils.getRotationMatrix(axis, angle), true);
}
private ExtendedAABB transformSelf(Matrix4d transformation, boolean centralize) {
ExtendedAABB source = this;
if (centralize) {
source = this.offset(-0.5d, -0.5d, -0.5d);
}
Vector3d min = new Vector3d(source.minX, source.minY, source.minZ);
Vector3d max = new Vector3d(source.maxX, source.maxY, source.maxZ);
transformation.transform(min);
transformation.transform(max);
if (centralize) {
min.setX(min.x + 0.5d);
min.setY(min.y + 0.5d);
min.setZ(min.z + 0.5d);
max.setX(max.x + 0.5d);
max.setY(max.y + 0.5d);
max.setZ(max.z + 0.5d);
}
return new ExtendedAABB(min, max);
}
// =========================================================================//
// Override the return types of parent methods to make chain calling easier //
// =========================================================================//
@Override
public ExtendedAABB contract(double x, double y, double z) {
return from(super.contract(x, y, z));
}
@Override
public ExtendedAABB expand(double x, double y, double z) {
return from(super.expand(x, y, z));
}
@Override
public ExtendedAABB grow(double x, double y, double z) {
return from(super.grow(x, y, z));
}
@Override
public ExtendedAABB grow(double value) {
return from(super.grow(value));
}
@Override
public ExtendedAABB intersect(AxisAlignedBB other) {
return from(super.intersect(other));
}
@Override
public ExtendedAABB union(AxisAlignedBB other) {
return from(super.union(other));
}
@Override
public ExtendedAABB offset(double x, double y, double z) {
return from(super.offset(x, y, z));
}
@Override
public ExtendedAABB offset(BlockPos pos) {
return from(super.offset(pos));
}
@Override
public ExtendedAABB offset(Vec3d vec) {
return from(super.offset(vec));
}
@Override
public ExtendedAABB shrink(double value) {
return from(super.shrink(value));
}
}
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.Vec3i;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Matrix4d;
public class TransformationUtils {
public static Matrix4d createIdentityMatrix4d() {
Matrix4d identity = new Matrix4d();
identity.setIdentity();
return identity;
}
public static Matrix4d combineTransformations(Matrix4d... transformations) {
Matrix4d result = createIdentityMatrix4d();
for (Matrix4d transformation : transformations) {
result.mul(transformation);
}
return result;
}
public static Matrix4d getTranslationMatrix(double dx, double dy, double dz) {
Matrix4d translation = createIdentityMatrix4d();
// [ 1 0 0 dx ]
// | 0 1 0 dy |
// | 0 0 1 dz |
// [ 0 0 0 1 ]
translation.setM03(dx);
translation.setM13(dy);
translation.setM23(dz);
return translation;
}
public static Matrix4d getRotationMatrix(int x, int y, int z) {
return combineTransformations(getRotationMatrix(Axis.X, x), getRotationMatrix(Axis.Y, y), getRotationMatrix(Axis.Z, z));
}
public static Matrix4d getRotationMatrix(double rx, double ry, double rz) {
return combineTransformations(getRotationMatrix(Axis.X, rx), getRotationMatrix(Axis.Y, ry), getRotationMatrix(Axis.Z, rz));
}
public static Matrix4d getRotationMatrix(Axis axis, int degrees) {
return getRotationMatrix(axis, Math.toRadians(degrees));
}
public static Matrix4d getRotationMatrix(Axis axis, double radians) {
Matrix4d rotation = new Matrix4d();
Vec3i direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).getDirectionVec();
// Rotation matrix calculation is done in Matrix4d#set(AxisAngle4d), the object is just used
// to pass in parameters
rotation.set(new AxisAngle4d(direction.getX(), direction.getY(), direction.getZ(), radians));
return rotation;
}
public static Matrix4d getScalingMatrix(double scale) {
return getScalingMatrix(scale, scale, scale);
}
public static Matrix4d getScalingMatrix(double xs, double ys, double zs) {
Matrix4d scaling = createIdentityMatrix4d();
// [ xs 0 0 0 ]
// | 0 ys 0 0 |
// | 0 0 zs 0 |
// [ 0 0 0 1 ]
scaling.setM00(xs);
scaling.setM11(ys);
scaling.setM22(zs);
return scaling;
}
}
@CSX8600
Copy link
Copy Markdown

CSX8600 commented Jul 11, 2023

Bro. Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment