package openmods.geometry; import com.google.common.base.Objects; import net.minecraft.util.Vec3; public class Matrix3d { public double m00; public double m01; public double m02; public double m10; public double m11; public double m12; public double m20; public double m21; public double m22; public Matrix3d() {} public Matrix3d(Matrix3d m) { copy(m); } public Matrix3d copy(Matrix3d src) { return copy(src, this); } public Matrix3d(double m00, double m10, double m20, double m01, double m11, double m21, double m02, double m12, double m22) { this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m20 = m20; this.m21 = m21; this.m22 = m22; } public Matrix3d copy() { return new Matrix3d(this); } public static Matrix3d copy(Matrix3d src, Matrix3d dest) { dest.m00 = src.m00; dest.m10 = src.m10; dest.m20 = src.m20; dest.m01 = src.m01; dest.m11 = src.m11; dest.m21 = src.m21; dest.m02 = src.m02; dest.m12 = src.m12; dest.m22 = src.m22; return dest; } public Matrix3d add(Matrix3d m) { return add(this, m, this); } public static Matrix3d add(Matrix3d left, Matrix3d right) { return add(left, right, new Matrix3d()); } public static Matrix3d add(Matrix3d left, Matrix3d right, Matrix3d dest) { dest.m00 = left.m00 + right.m00; dest.m01 = left.m01 + right.m01; dest.m02 = left.m02 + right.m02; dest.m10 = left.m10 + right.m10; dest.m11 = left.m11 + right.m11; dest.m12 = left.m12 + right.m12; dest.m20 = left.m20 + right.m20; dest.m21 = left.m21 + right.m21; dest.m22 = left.m22 + right.m22; return dest; } public Matrix3d sub(Matrix3d m) { return sub(this, m, this); } public static Matrix3d sub(Matrix3d left, Matrix3d right) { return sub(left, right, new Matrix3d()); } public static Matrix3d sub(Matrix3d left, Matrix3d right, Matrix3d dest) { if (dest == null) dest = new Matrix3d(); dest.m00 = left.m00 - right.m00; dest.m01 = left.m01 - right.m01; dest.m02 = left.m02 - right.m02; dest.m10 = left.m10 - right.m10; dest.m11 = left.m11 - right.m11; dest.m12 = left.m12 - right.m12; dest.m20 = left.m20 - right.m20; dest.m21 = left.m21 - right.m21; dest.m22 = left.m22 - right.m22; return dest; } public Matrix3d mulLeft(Matrix3d v) { return mul(v, this, this); } public Matrix3d mulRight(Matrix3d v) { return mul(this, v, this); } public static Matrix3d mul(Matrix3d left, Matrix3d right) { return mul(left, right, new Matrix3d()); } public static Matrix3d mul(Matrix3d left, Matrix3d right, Matrix3d dest) { final double m00 = left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02; final double m01 = left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02; final double m02 = left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02; final double m10 = left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12; final double m11 = left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12; final double m12 = left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12; final double m20 = left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22; final double m21 = left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22; final double m22 = left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22; dest.m00 = m00; dest.m01 = m01; dest.m02 = m02; dest.m10 = m10; dest.m11 = m11; dest.m12 = m12; dest.m20 = m20; dest.m21 = m21; dest.m22 = m22; return dest; } public double transformX(double x, double y, double z) { return m00 * x + m10 * y + m20 * z; } public double transformY(double x, double y, double z) { return m01 * x + m11 * y + m21 * z; } public double transformZ(double x, double y, double z) { return m02 * x + m12 * y + m22 * z; } public Vec3 transform(Vec3 vec) { final double tx = transformX(vec.xCoord, vec.yCoord, vec.zCoord); final double ty = transformY(vec.xCoord, vec.yCoord, vec.zCoord); final double tz = transformZ(vec.xCoord, vec.yCoord, vec.zCoord); return Vec3.createVectorHelper(tx, ty, tz); } public Matrix3d transpose() { return transpose(this, this); } public Matrix3d transpose(Matrix3d dest) { return transpose(this, dest); } public static Matrix3d transpose(Matrix3d src, Matrix3d dest) { final double m00 = src.m00; final double m01 = src.m10; final double m02 = src.m20; final double m10 = src.m01; final double m11 = src.m11; final double m12 = src.m21; final double m20 = src.m02; final double m21 = src.m12; final double m22 = src.m22; dest.m00 = m00; dest.m01 = m01; dest.m02 = m02; dest.m10 = m10; dest.m11 = m11; dest.m12 = m12; dest.m20 = m20; dest.m21 = m21; dest.m22 = m22; return dest; } public double determinant() { return m00 * (m11 * m22 - m12 * m21) + m01 * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20); } @Override public String toString() { return "[" + m00 + ' ' + m10 + ' ' + m20 + ';' + m01 + ' ' + m11 + ' ' + m21 + ';' + m02 + ' ' + m12 + ' ' + m22 + ']'; } public Matrix3d invertCopy() { return invert(this, new Matrix3d()); } public Matrix3d invertInplace() { return invert(this, this); } public static Matrix3d invert(Matrix3d src, Matrix3d dest) { final double determinant = src.determinant(); if (determinant == 0) throw new ArithmeticException("Can't invert matrix " + src); final double determinant_inv = 1f / determinant; final double t00 = src.m11 * src.m22 - src.m12 * src.m21; final double t01 = -src.m10 * src.m22 + src.m12 * src.m20; final double t02 = src.m10 * src.m21 - src.m11 * src.m20; final double t10 = -src.m01 * src.m22 + src.m02 * src.m21; final double t11 = src.m00 * src.m22 - src.m02 * src.m20; final double t12 = -src.m00 * src.m21 + src.m01 * src.m20; final double t20 = src.m01 * src.m12 - src.m02 * src.m11; final double t21 = -src.m00 * src.m12 + src.m02 * src.m10; final double t22 = src.m00 * src.m11 - src.m01 * src.m10; dest.m00 = t00 * determinant_inv; dest.m11 = t11 * determinant_inv; dest.m22 = t22 * determinant_inv; dest.m01 = t10 * determinant_inv; dest.m10 = t01 * determinant_inv; dest.m20 = t02 * determinant_inv; dest.m02 = t20 * determinant_inv; dest.m12 = t21 * determinant_inv; dest.m21 = t12 * determinant_inv; return dest; } public Matrix3d negateCopy() { return negate(new Matrix3d()); } public Matrix3d negateInplace() { return negate(this); } public Matrix3d negate(Matrix3d dest) { return negate(this, dest); } public static Matrix3d negate(Matrix3d src, Matrix3d dest) { dest.m00 = -src.m00; dest.m01 = -src.m02; dest.m02 = -src.m01; dest.m10 = -src.m10; dest.m11 = -src.m12; dest.m12 = -src.m11; dest.m20 = -src.m20; dest.m21 = -src.m22; dest.m22 = -src.m21; return dest; } public Matrix3d setIdentity() { return setIdentity(this); } public static Matrix3d setIdentity(Matrix3d m) { m.m00 = 1.0; m.m01 = 0.0; m.m02 = 0.0; m.m10 = 0.0; m.m11 = 1.0; m.m12 = 0.0; m.m20 = 0.0; m.m21 = 0.0; m.m22 = 1.0; return m; } public Matrix3d setZero() { return setZero(this); } public static Matrix3d setZero(Matrix3d m) { m.m00 = 0.0; m.m01 = 0.0; m.m02 = 0.0; m.m10 = 0.0; m.m11 = 0.0; m.m12 = 0.0; m.m20 = 0.0; m.m21 = 0.0; m.m22 = 0.0; return m; } @Override public int hashCode() { return Objects.hashCode(m00, m01, m02, m10, m11, m12, m20, m21, m22); } @Override public boolean equals(Object obj) { if (obj instanceof Matrix3d) { final Matrix3d o = (Matrix3d)obj; return m00 == o.m00 && m01 == o.m01 && m02 == o.m02 && m10 == o.m10 && m11 == o.m11 && m12 == o.m12 && m20 == o.m20 && m21 == o.m21 && m22 == o.m22; } return false; } }