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); }
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); }
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; }
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; }
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); }
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); }
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); }
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; }