Example #1
0
 public Matrix4x4 multiply(double value) {
   if (flagBits == Mathematics.mat_type_Identity) {
     // dummy matrix
     Matrix4x4 new_mat = new Matrix4x4(0);
     new_mat.set_value(0, value);
     new_mat.set_value(5, value);
     new_mat.set_value(10, value);
     new_mat.set_value(15, value);
     return new_mat;
   }
   return new Matrix4x4(
       this.mat4[0] * value,
       this.mat4[1] * value,
       this.mat4[2] * value,
       this.mat4[3] * value,
       this.mat4[4] * value,
       this.mat4[5] * value,
       this.mat4[6] * value,
       this.mat4[7] * value,
       this.mat4[8] * value,
       this.mat4[9] * value,
       this.mat4[10] * value,
       this.mat4[11] * value,
       this.mat4[12] * value,
       this.mat4[13] * value,
       this.mat4[14] * value,
       this.mat4[15] * value);
 }
Example #2
0
 public Matrix4x4 divide(double value) {
   if (flagBits == Mathematics.mat_type_Identity) {
     // dummy matrix
     Matrix4x4 new_mat = new Matrix4x4(0);
     new_mat.set_value(0, 1.0 / value);
     new_mat.set_value(5, 1.0 / value);
     new_mat.set_value(10, 1.0 / value);
     new_mat.set_value(15, 1.0 / value);
     return new_mat;
   }
   return new Matrix4x4(
       this.mat4[0] / value,
       this.mat4[1] / value,
       this.mat4[2] / value,
       this.mat4[3] / value,
       this.mat4[4] / value,
       this.mat4[5] / value,
       this.mat4[6] / value,
       this.mat4[7] / value,
       this.mat4[8] / value,
       this.mat4[9] / value,
       this.mat4[10] / value,
       this.mat4[11] / value,
       this.mat4[12] / value,
       this.mat4[13] / value,
       this.mat4[14] / value,
       this.mat4[15] / value);
 }
Example #3
0
 public Matrix4x4 transposed() {
   Matrix4x4 result = new Matrix4x4(1); // The "1" says to not load the identity.
   for (int row = 0; row < 4; ++row) {
     for (int col = 0; col < 4; ++col) {
       result.set_value(col + row * 4, mat4[4 * row + col]);
     }
   }
   return result;
 }
Example #4
0
  // cpp would have a boolean as input(pointer so output) to check if inversion was successful...
  // returns identity matrix if not invertible...
  public Matrix4x4 inverted() {

    // Handle some of the easy cases first.
    if (flagBits == Mathematics.mat_type_Identity) {
      return new Matrix4x4();
    } else if (flagBits == Mathematics.mat_type_Translation) {
      Matrix4x4 inv = new Matrix4x4();
      inv.mat4[12] = -mat4[12];
      inv.mat4[13] = -mat4[13];
      inv.mat4[14] = -mat4[14];
      inv.flagBits = Mathematics.mat_type_Translation;
      return inv;
    } else if (flagBits == Mathematics.mat_type_Rotation
        || flagBits == (Mathematics.mat_type_Rotation | Mathematics.mat_type_Translation)) {
      return orthonormalInverse();
    }

    double det = matrixDet4(mat4);
    if (det == 0.0f) {
      return new Matrix4x4();
    }
    det = 1.0f / det;

    return new Matrix4x4(
        matrixDet3(mat4, 1, 2, 3, 1, 2, 3) * det,
        -matrixDet3(mat4, 0, 2, 3, 1, 2, 3) * det,
        matrixDet3(mat4, 0, 1, 3, 1, 2, 3) * det,
        -matrixDet3(mat4, 0, 1, 2, 1, 2, 3) * det,
        -matrixDet3(mat4, 1, 2, 3, 0, 2, 3) * det,
        matrixDet3(mat4, 0, 2, 3, 0, 2, 3) * det,
        -matrixDet3(mat4, 0, 1, 3, 0, 2, 3) * det,
        matrixDet3(mat4, 0, 1, 2, 0, 2, 3) * det,
        matrixDet3(mat4, 1, 2, 3, 0, 1, 3) * det,
        -matrixDet3(mat4, 0, 2, 3, 0, 1, 3) * det,
        matrixDet3(mat4, 0, 1, 3, 0, 1, 3) * det,
        -matrixDet3(mat4, 0, 1, 2, 0, 1, 3) * det,
        -matrixDet3(mat4, 1, 2, 3, 0, 1, 2) * det,
        matrixDet3(mat4, 0, 2, 3, 0, 1, 2) * det,
        -matrixDet3(mat4, 0, 1, 3, 0, 1, 2) * det,
        matrixDet3(mat4, 0, 1, 2, 0, 1, 2) * det);
  }
Example #5
0
 public Matrix4x4 subtract(Matrix4x4 other) {
   return new Matrix4x4(
       this.mat4[0] - other.get_value(0),
       this.mat4[1] - other.get_value(1),
       this.mat4[2] - other.get_value(2),
       this.mat4[3] - other.get_value(3),
       this.mat4[4] - other.get_value(4),
       this.mat4[5] - other.get_value(5),
       this.mat4[6] - other.get_value(6),
       this.mat4[7] - other.get_value(7),
       this.mat4[8] - other.get_value(8),
       this.mat4[9] - other.get_value(9),
       this.mat4[10] - other.get_value(10),
       this.mat4[11] - other.get_value(11),
       this.mat4[12] - other.get_value(12),
       this.mat4[13] - other.get_value(13),
       this.mat4[14] - other.get_value(14),
       this.mat4[15] - other.get_value(15));
 }
Example #6
0
 public Matrix4x4 add(Matrix4x4 other) {
   return new Matrix4x4(
       this.mat4[0] + other.get_value(0),
       this.mat4[1] + other.get_value(1),
       this.mat4[2] + other.get_value(2),
       this.mat4[3] + other.get_value(3),
       this.mat4[4] + other.get_value(4),
       this.mat4[5] + other.get_value(5),
       this.mat4[6] + other.get_value(6),
       this.mat4[7] + other.get_value(7),
       this.mat4[8] + other.get_value(8),
       this.mat4[9] + other.get_value(9),
       this.mat4[10] + other.get_value(10),
       this.mat4[11] + other.get_value(11),
       this.mat4[12] + other.get_value(12),
       this.mat4[13] + other.get_value(13),
       this.mat4[14] + other.get_value(14),
       this.mat4[15] + other.get_value(15));
 }
Example #7
0
  // copy constructor
  public Matrix4x4(Matrix4x4 mat) {
    this.mat4[0] = mat.get_value(0);
    this.mat4[1] = mat.get_value(1);
    this.mat4[2] = mat.get_value(2);
    this.mat4[3] = mat.get_value(3);

    this.mat4[4] = mat.get_value(4);
    this.mat4[5] = mat.get_value(5);
    this.mat4[6] = mat.get_value(6);
    this.mat4[7] = mat.get_value(7);

    this.mat4[8] = mat.get_value(8);
    this.mat4[9] = mat.get_value(9);
    this.mat4[10] = mat.get_value(10);
    this.mat4[11] = mat.get_value(11);

    this.mat4[12] = mat.get_value(12);
    this.mat4[13] = mat.get_value(13);
    this.mat4[14] = mat.get_value(14);
    this.mat4[15] = mat.get_value(15);

    flagBits = Mathematics.mat_type_General;
  }
Example #8
0
  public Matrix4x4 multiply(Matrix4x4 other) {
    if (this.flagBits == Mathematics.mat_type_Identity) return new Matrix4x4(other);
    else if (other.getType() == Mathematics.mat_type_Identity) return new Matrix4x4(this);

    return new Matrix4x4(
        // Fisrt Column
        mat4[0] * other.get_value(0)
            + mat4[4] * other.get_value(1)
            + mat4[8] * other.get_value(2)
            + mat4[12] * other.get_value(3),
        mat4[1] * other.get_value(0)
            + mat4[5] * other.get_value(1)
            + mat4[9] * other.get_value(2)
            + mat4[13] * other.get_value(3),
        mat4[2] * other.get_value(0)
            + mat4[6] * other.get_value(1)
            + mat4[10] * other.get_value(2)
            + mat4[14] * other.get_value(3),
        mat4[3] * other.get_value(0)
            + mat4[7] * other.get_value(1)
            + mat4[11] * other.get_value(2)
            + mat4[15] * other.get_value(3),

        // Second Column
        mat4[0] * other.get_value(4)
            + mat4[4] * other.get_value(5)
            + mat4[8] * other.get_value(6)
            + mat4[12] * other.get_value(7),
        mat4[1] * other.get_value(4)
            + mat4[5] * other.get_value(5)
            + mat4[9] * other.get_value(6)
            + mat4[13] * other.get_value(7),
        mat4[2] * other.get_value(4)
            + mat4[6] * other.get_value(5)
            + mat4[10] * other.get_value(6)
            + mat4[14] * other.get_value(7),
        mat4[3] * other.get_value(4)
            + mat4[7] * other.get_value(5)
            + mat4[11] * other.get_value(6)
            + mat4[15] * other.get_value(7),

        // Third Column
        mat4[0] * other.get_value(8)
            + mat4[4] * other.get_value(9)
            + mat4[8] * other.get_value(10)
            + mat4[12] * other.get_value(11),
        mat4[1] * other.get_value(8)
            + mat4[5] * other.get_value(9)
            + mat4[9] * other.get_value(10)
            + mat4[13] * other.get_value(11),
        mat4[2] * other.get_value(8)
            + mat4[6] * other.get_value(9)
            + mat4[10] * other.get_value(10)
            + mat4[14] * other.get_value(11),
        mat4[3] * other.get_value(8)
            + mat4[7] * other.get_value(9)
            + mat4[11] * other.get_value(10)
            + mat4[15] * other.get_value(11),

        // Fourth Column
        mat4[0] * other.get_value(12)
            + mat4[4] * other.get_value(13)
            + mat4[8] * other.get_value(14)
            + mat4[12] * other.get_value(15),
        mat4[1] * other.get_value(12)
            + mat4[5] * other.get_value(13)
            + mat4[9] * other.get_value(14)
            + mat4[13] * other.get_value(15),
        mat4[2] * other.get_value(12)
            + mat4[6] * other.get_value(13)
            + mat4[10] * other.get_value(14)
            + mat4[14] * other.get_value(15),
        mat4[3] * other.get_value(12)
            + mat4[7] * other.get_value(13)
            + mat4[11] * other.get_value(14)
            + mat4[15] * other.get_value(15)
        // is General matrix...
        );
  }
Example #9
0
  public Matrix4x4 lookAt(Vector3 eye, Vector3 center, Vector3 up) {
    Vector3 forward = (center.subtract(eye)).normalized();
    Vector3 side = Vector3.crossProduct(forward, up).normalized();
    Vector3 upVector = Vector3.crossProduct(side, forward);

    Matrix4x4 m = new Matrix4x4(1);

    m.set_value(0, 0, side.x());
    m.set_value(1, 0, side.y());
    m.set_value(2, 0, side.z());
    m.set_value(3, 0, 0.0f);
    m.set_value(0, 1, upVector.x());
    m.set_value(1, 1, upVector.y());
    m.set_value(2, 1, upVector.z());
    m.set_value(3, 1, 0.0f);
    m.set_value(0, 2, -forward.x());
    m.set_value(1, 2, -forward.y());
    m.set_value(2, 2, -forward.z());
    m.set_value(3, 2, 0.0f);
    m.set_value(0, 3, 0.0f);
    m.set_value(1, 3, 0.0f);
    m.set_value(2, 3, 0.0f);
    m.set_value(3, 3, 1.0f);

    Matrix4x4 m2 = this.multiply(m);
    m2.translate(-eye.x(), -eye.y(), -eye.z());
    return m2;
  }
Example #10
0
  public Matrix4x4 perspective(double angle, double aspect, double nearPlane, double farPlane) {
    // Bail out if the projection volume is zero-sized.
    if (nearPlane == farPlane || aspect == 0.0) return this;

    // Construct the projection.
    Matrix4x4 m = new Matrix4x4(1);
    double radians = (angle / 2.0) * Mathematics.M_PI / 180.0;
    double sine = Math.sin(radians);
    if (sine == 0.0) return this;
    double cotan = Math.cos(radians) / sine;
    double clip = farPlane - nearPlane;
    m.set_value(0, 0, cotan / aspect);
    m.set_value(1, 0, 0.0);
    m.set_value(2, 0, 0.0);
    m.set_value(3, 0, 0.0);
    m.set_value(0, 1, 0.0);
    m.set_value(1, 1, cotan);
    m.set_value(2, 1, 0.0);
    m.set_value(3, 1, 0.0);
    m.set_value(0, 2, 0.0);
    m.set_value(1, 2, 0.0);
    m.set_value(2, 2, -(nearPlane + farPlane) / clip);
    m.set_value(3, 2, -(2.0 * nearPlane * farPlane) / clip);
    m.set_value(0, 3, 0.0);
    m.set_value(1, 3, 0.0);
    m.set_value(2, 3, -1.0);
    m.set_value(3, 3, 0.0);

    // Apply the projection.
    return this.multiply(m);
  }
Example #11
0
  public Matrix4x4 frustum(
      double left, double right, double bottom, double top, double nearPlane, double farPlane) {
    // Bail out if the projection volume is zero-sized.
    if (left == right || bottom == top || nearPlane == farPlane) return this;

    // Construct the projection.
    Matrix4x4 m = new Matrix4x4(1);
    double width = right - left;
    double invheight = top - bottom;
    double clip = farPlane - nearPlane;
    m.set_value(0, 0, 2.0 * nearPlane / width);
    m.set_value(1, 0, 0.0);
    m.set_value(2, 0, (left + right) / width);
    m.set_value(3, 0, 0.0);
    m.set_value(0, 1, 0.0);
    m.set_value(1, 1, 2.0 * nearPlane / invheight);
    m.set_value(2, 1, (top + bottom) / invheight);
    m.set_value(3, 1, 0.0);
    m.set_value(0, 2, 0.0);
    m.set_value(1, 2, 0.0);
    m.set_value(2, 2, -(nearPlane + farPlane) / clip);
    m.set_value(3, 2, -2.0 * nearPlane * farPlane / clip);
    m.set_value(0, 3, 0.0);
    m.set_value(1, 3, 0.0);
    m.set_value(2, 3, -1.0);
    m.set_value(3, 3, 0.0);

    // Apply the projection.
    return this.multiply(m);
  }
Example #12
0
  public Matrix4x4 ortho(
      double left, double right, double bottom, double top, double nearPlane, double farPlane) {
    // Bail out if the projection volume is zero-sized.
    if (left == right || bottom == top || nearPlane == farPlane) return this;

    // Construct the projection.
    double width = right - left;
    double invheight = top - bottom;
    double clip = farPlane - nearPlane;

    // Vector class is incomplete and thus functions are missing...
    // A more efficient way of ortho projection...

    /*
    if (clip == 2.0f && (nearPlane + farPlane) == 0.0f) {
        // We can express this projection as a translate and scale
        // which will be more efficient to modify with further
        // transformations than producing a "General" matrix.
        translate(Vector3
            (-(left + right) / width,
             -(top + bottom) / invheight,
             0.0f));
        scale(Vector3
            (2.0f / width,
             2.0f / invheight,
             -1.0f));
        return;
    }
    */

    Matrix4x4 m = new Matrix4x4(1);
    m.set_value(0, 0, 2.0 / width);
    m.set_value(1, 0, 0.0);
    m.set_value(2, 0, 0.0);
    m.set_value(3, 0, -(left + right) / width);
    m.set_value(0, 1, 0.0);
    m.set_value(1, 1, 2.0 / invheight);
    m.set_value(2, 1, 0.0);
    m.set_value(3, 1, -(top + bottom) / invheight);
    m.set_value(0, 2, 0.0);
    m.set_value(1, 2, 0.0);
    m.set_value(2, 2, -2.0 / clip);
    m.set_value(3, 2, -(nearPlane + farPlane) / clip);
    m.set_value(0, 3, 0.0);
    m.set_value(1, 3, 0.0);
    m.set_value(2, 3, 0.0);
    m.set_value(3, 3, 1.0);

    // Apply the projection.
    return this.multiply(m);
  }
Example #13
0
  private Matrix4x4 orthonormalInverse() {
    Matrix4x4 result = new Matrix4x4(1); // The '1' says not to load identity

    result.set_value(0, mat4[0]);
    result.set_value(4, mat4[1]);
    result.set_value(8, mat4[2]);

    result.set_value(1, mat4[4]);
    result.set_value(5, mat4[5]);
    result.set_value(9, mat4[6]);

    result.set_value(2, mat4[8]);
    result.set_value(6, mat4[9]);
    result.set_value(10, mat4[10]);

    result.set_value(3, 0.0);
    result.set_value(7, 0.0);
    result.set_value(11, 0.0);

    // might have wrong values
    result.set_value(
        12,
        -(result.get_value(0) * mat4[12]
            + result.get_value(4) * mat4[13]
            + result.get_value(8) * mat4[14]));
    result.set_value(
        13,
        -(result.get_value(1) * mat4[12]
            + result.get_value(5) * mat4[13]
            + result.get_value(9) * mat4[14]));
    result.set_value(
        14,
        -(result.get_value(2) * mat4[12]
            + result.get_value(6) * mat4[13]
            + result.get_value(10) * mat4[14]));
    result.set_value(15, 1.0);

    return result;
  }
Example #14
0
  public void rotate(double angle, double x, double y, double z) {
    if (angle == 0.0f) return;
    Matrix4x4 m = new Matrix4x4(1); // The "1" says to not load the identity.
    double c, s, ic;
    if (angle == 90.0 || angle == -270.0) {
      s = 1.0;
      c = 0.0;
    } else if (angle == -90.0 || angle == 270.0) {
      s = -1.0;
      c = 0.0;
    } else if (angle == 180.0 || angle == -180.0) {
      s = 0.0;
      c = -1.0;
    } else {
      double a = angle * Mathematics.M_PI / 180.0;
      c = Math.cos(a);
      s = Math.sin(a);
    }
    boolean quick = false;
    if (x == 0.0) {
      if (y == 0.0) {
        if (z != 0.0) {
          // Rotate around the Z axis.
          m.set_to_identity();
          m.mat4[0] = c;
          m.mat4[5] = c;
          if (z < 0.0) {
            m.mat4[4] = s;
            m.mat4[1] = -s;
          } else {
            m.mat4[4] = -s;
            m.mat4[1] = s;
          }
          m.setType(Mathematics.mat_type_General);
          quick = true;
        }
      } else if (z == 0.0) {
        // Rotate around the Y axis.
        m.set_to_identity();
        m.mat4[0] = c;
        m.mat4[10] = c;
        if (y < 0.0) {
          m.mat4[8] = -s;
          m.mat4[2] = s;
        } else {
          m.mat4[8] = s;
          m.mat4[2] = -s;
        }
        m.setType(Mathematics.mat_type_General);
        quick = true;
      }
    } else if (y == 0.0 && z == 0.0) {
      // Rotate around the X axis.
      m.set_to_identity();
      m.mat4[5] = c;
      m.mat4[10] = c;
      if (x < 0.0) {
        m.mat4[9] = s;
        m.mat4[6] = -s;
      } else {
        m.mat4[9] = -s;
        m.mat4[6] = s;
      }
      m.setType(Mathematics.mat_type_General);
      quick = true;
    }
    if (!quick) {
      double len = x * x + y * y + z * z;
      if (!Mathematics.fuzzyIsNull(len - 1.0) && Mathematics.fuzzyIsNull(len)) {
        len = Math.sqrt(len);
        x /= len;
        y /= len;
        z /= len;
      }
      ic = 1.0 - c;
      m.mat4[0] = x * x * ic + c;
      m.mat4[4] = x * y * ic - z * s;
      m.mat4[8] = x * z * ic + y * s;
      m.mat4[12] = 0.0;
      m.mat4[1] = y * x * ic + z * s;
      m.mat4[5] = y * y * ic + c;
      m.mat4[9] = y * z * ic - x * s;
      m.mat4[13] = 0.0;
      m.mat4[2] = x * z * ic - y * s;
      m.mat4[6] = y * z * ic + x * s;
      m.mat4[10] = z * z * ic + c;
      m.mat4[14] = 0.0;
      m.mat4[3] = 0.0;
      m.mat4[7] = 0.0;
      m.mat4[11] = 0.0;
      m.mat4[15] = 1.0;
    }
    int flags = flagBits;

    // cpp style
    // *this *= m;
    // java...
    this.set_array(this.multiply(m).get_array());

    if (flags != Mathematics.mat_type_Identity) flagBits = flags | Mathematics.mat_type_Rotation;
    else flagBits = Mathematics.mat_type_Rotation;
  }