public static Matrix4f createViewMatrix(Vector3f AtVec, Vector3f EyeVec, Vector3f UpVec) { Matrix4f viewMatrix = Matrix4f.identity(); viewMatrix = lookAt(AtVec, EyeVec, UpVec); return(viewMatrix); }
public Matrix4f(Matrix4f matrix) { this._cols[0] = matrix._cols[0]; this._cols[1] = matrix._cols[1]; this._cols[2] = matrix._cols[2]; this._cols[3] = matrix._cols[3]; }
public static Matrix4f createProjectionMatrix(float FovY, float aspectRatio, float zNear, float zFar) { Matrix4f projectionMatrix = new Matrix4f(1); projectionMatrix = perspective(Trigonometric.toRadians(FovY), aspectRatio, zNear, zFar); return(projectionMatrix); }
public static Matrix3f createNormalMatrix(Matrix4f viewMatrix, Matrix4f modelMatrix) { Matrix3f result; result = MatrixTransforms.Transpose(MatrixTransforms.Inverse(viewMatrix * modelMatrix)).toMatrix3(); return(result); }
/// <summary> /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle. /// </summary> /// <param name="m">The m.</param> /// <param name="angle">The angle.</param> /// <param name="v">The v.</param> /// <returns></returns> public static Matrix4f rotate(Matrix4f m, float angle, Vector3f v) { float c = Trigonometric.Cos(angle); float s = Trigonometric.Sin(angle); Vector3f axis = Geometric.Normalize(v); Vector3f temp = (1.0f - c) * axis; Matrix4f rotate = Matrix4f.identity(); rotate[0, 0] = c + temp[0] * axis[0]; rotate[0, 1] = 0 + temp[0] * axis[1] + s * axis[2]; rotate[0, 2] = 0 + temp[0] * axis[2] - s * axis[1]; rotate[1, 0] = 0 + temp[1] * axis[0] - s * axis[2]; rotate[1, 1] = c + temp[1] * axis[1]; rotate[1, 2] = 0 + temp[1] * axis[2] + s * axis[0]; rotate[2, 0] = 0 + temp[2] * axis[0] + s * axis[1]; rotate[2, 1] = 0 + temp[2] * axis[1] - s * axis[0]; rotate[2, 2] = c + temp[2] * axis[2]; Matrix4f result = Matrix4f.identity(); result[0] = m[0] * rotate[0][0] + m[1] * rotate[0][1] + m[2] * rotate[0][2]; result[1] = m[0] * rotate[1][0] + m[1] * rotate[1][1] + m[2] * rotate[1][2]; result[2] = m[0] * rotate[2][0] + m[1] * rotate[2][1] + m[2] * rotate[2][2]; result[3] = m[3]; return(result); }
/// <summary> /// Multiplies the <paramref name="lhs"/> matrix by the <paramref name="rhs"/> matrix. /// </summary> /// <param name="lhs">The LHS matrix.</param> /// <param name="rhs">The RHS matrix.</param> /// <returns>The product of <paramref name="lhs"/> and <paramref name="rhs"/>.</returns> public static Matrix4f operator *(Matrix4f lhs, Matrix4f rhs) { Matrix4f tempM = new Matrix4f(0); tempM[0][0] = (lhs[0][0] * rhs[0][0]) + (lhs[0][1] * rhs[1][0]) + (lhs[0][2] * rhs[2][0]) + (lhs[0][3] * rhs[3][0]); tempM[1][0] = (lhs[1][0] * rhs[0][0]) + (lhs[1][1] * rhs[1][0]) + (lhs[1][2] * rhs[2][0]) + (lhs[1][3] * rhs[3][0]); tempM[2][0] = (lhs[2][0] * rhs[0][0]) + (lhs[2][1] * rhs[1][0]) + (lhs[2][2] * rhs[2][0]) + (lhs[2][3] * rhs[3][0]); tempM[3][0] = (lhs[3][0] * rhs[0][0]) + (lhs[3][1] * rhs[1][0]) + (lhs[3][2] * rhs[2][0]) + (lhs[3][3] * rhs[3][0]); tempM[0][1] = (lhs[0][0] * rhs[0][1]) + (lhs[0][1] * rhs[1][1]) + (lhs[0][2] * rhs[2][1]) + (lhs[0][3] * rhs[3][1]); tempM[1][1] = (lhs[1][0] * rhs[0][1]) + (lhs[1][1] * rhs[1][1]) + (lhs[1][2] * rhs[2][1]) + (lhs[1][3] * rhs[3][1]); tempM[2][1] = (lhs[2][0] * rhs[0][1]) + (lhs[2][1] * rhs[1][1]) + (lhs[2][2] * rhs[2][1]) + (lhs[2][3] * rhs[3][1]); tempM[3][1] = (lhs[3][0] * rhs[0][1]) + (lhs[3][1] * rhs[1][1]) + (lhs[3][2] * rhs[2][1]) + (lhs[3][3] * rhs[3][1]); tempM[0][2] = (lhs[0][0] * rhs[0][2]) + (lhs[0][1] * rhs[1][2]) + (lhs[0][2] * rhs[2][2]) + (lhs[0][3] * rhs[3][2]); tempM[1][2] = (lhs[1][0] * rhs[0][2]) + (lhs[1][1] * rhs[1][2]) + (lhs[1][2] * rhs[2][2]) + (lhs[1][3] * rhs[3][2]); tempM[2][2] = (lhs[2][0] * rhs[0][2]) + (lhs[2][1] * rhs[1][2]) + (lhs[2][2] * rhs[2][2]) + (lhs[2][3] * rhs[3][2]); tempM[3][2] = (lhs[3][0] * rhs[0][2]) + (lhs[3][1] * rhs[1][2]) + (lhs[3][2] * rhs[2][2]) + (lhs[3][3] * rhs[3][2]); tempM[0][3] = (lhs[0][0] * rhs[0][3]) + (lhs[0][1] * rhs[1][3]) + (lhs[0][2] * rhs[2][3]) + (lhs[0][3] * rhs[3][3]); tempM[1][3] = (lhs[1][0] * rhs[0][3]) + (lhs[1][1] * rhs[1][3]) + (lhs[1][2] * rhs[2][3]) + (lhs[1][3] * rhs[3][3]); tempM[2][3] = (lhs[2][0] * rhs[0][3]) + (lhs[2][1] * rhs[1][3]) + (lhs[2][2] * rhs[2][3]) + (lhs[2][3] * rhs[3][3]); tempM[3][3] = (lhs[3][0] * rhs[0][3]) + (lhs[3][1] * rhs[1][3]) + (lhs[3][2] * rhs[2][3]) + (lhs[3][3] * rhs[3][3]); return(tempM); }
/// <summary> /// Applies a translation transformation to matrix <paramref name="m"/> by vector <paramref name="v"/>. /// </summary> /// <param name="m">The matrix to transform.</param> /// <param name="v">The vector to translate by.</param> /// <returns><paramref name="m"/> translated by <paramref name="v"/>.</returns> public static Matrix4f translate(Matrix4f m, Vector3f v) { Matrix4f result = m; result[3] = (m[0] * v[0]) + (m[1] * v[1]) + (m[2] * v[2]) + m[3]; result[3][3] = 1.0f; return(result); }
public static Matrix4f Inverse(Matrix4f m) { float Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; float Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; float Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; float Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; float Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; float Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; float Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; float Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; float Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; float Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; float Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; float Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; float Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; float Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; float Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; float Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; float Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; float Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; Vector4f Fac0 = new Vector4f(Coef00, Coef00, Coef02, Coef03); Vector4f Fac1 = new Vector4f(Coef04, Coef04, Coef06, Coef07); Vector4f Fac2 = new Vector4f(Coef08, Coef08, Coef10, Coef11); Vector4f Fac3 = new Vector4f(Coef12, Coef12, Coef14, Coef15); Vector4f Fac4 = new Vector4f(Coef16, Coef16, Coef18, Coef19); Vector4f Fac5 = new Vector4f(Coef20, Coef20, Coef22, Coef23); Vector4f Vec0 = new Vector4f(m[1][0], m[0][0], m[0][0], m[0][0]); Vector4f Vec1 = new Vector4f(m[1][1], m[0][1], m[0][1], m[0][1]); Vector4f Vec2 = new Vector4f(m[1][2], m[0][2], m[0][2], m[0][2]); Vector4f Vec3 = new Vector4f(m[1][3], m[0][3], m[0][3], m[0][3]); Vector4f Inv0 = new Vector4f(Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2); Vector4f Inv1 = new Vector4f(Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4); Vector4f Inv2 = new Vector4f(Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5); Vector4f Inv3 = new Vector4f(Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5); Vector4f SignA = new Vector4f(+1, -1, +1, -1); Vector4f SignB = new Vector4f(-1, +1, -1, +1); Matrix4f inverse = new Matrix4f(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB); Vector4f Row0 = new Vector4f(inverse[0][0], inverse[1][0], inverse[2][0], inverse[3][0]); Vector4f Dot0 = new Vector4f(m[0] * Row0); float Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w); float OneOverDeterminant = (1f) / Dot1; return(inverse * OneOverDeterminant); }
/// <summary> /// Applies a scale transformation to matrix <paramref name="m"/> by vector <paramref name="v"/>. /// </summary> /// <param name="m">The matrix to transform.</param> /// <param name="v">The vector to scale by.</param> /// <returns><paramref name="m"/> scaled by <paramref name="v"/>.</returns> public static Matrix4f scale(Matrix4f m, Vector3f v) { Matrix4f result = m; result[0] = m[0] * v[0]; result[1] = m[1] * v[1]; result[2] = m[2] * v[2]; result[3] = m[3]; return(result); }
public static Matrix4f createModelMatrix(Vector3f translation, Vector3f rotate, Vector3f scale) { Matrix4f modelMatrix = Matrix4f.identity(); modelMatrix = translate(modelMatrix, translation); modelMatrix = MatrixMath.rotate(modelMatrix, Trigonometric.toRadians(rotate.x), new Vector3f(1, 0, 0)); modelMatrix = MatrixMath.rotate(modelMatrix, Trigonometric.toRadians(rotate.y), new Vector3f(0, 1, 0)); modelMatrix = MatrixMath.rotate(modelMatrix, Trigonometric.toRadians(rotate.z), new Vector3f(0, 0, 1)); modelMatrix = MatrixMath.scale(modelMatrix, scale); return(modelMatrix); }
/// <summary> /// Creates a matrix for projecting two-dimensional coordinates onto the screen. /// </summary> /// <param name="left">The left.</param> /// <param name="right">The right.</param> /// <param name="bottom">The bottom.</param> /// <param name="top">The top.</param> /// <returns></returns> public static Matrix4f ortho(float left, float right, float bottom, float top) { var result = new Matrix4f(1); result[0, 0] = (2f) / (right - left); result[1, 1] = (2f) / (top - bottom); result[2, 2] = -(1f); result[3, 0] = -(right + left) / (right - left); result[3, 1] = -(top + bottom) / (top - bottom); return(result); }
/// <summary> /// Creates a frustrum projection matrix. /// </summary> /// <param name="left">The left.</param> /// <param name="right">The right.</param> /// <param name="bottom">The bottom.</param> /// <param name="top">The top.</param> /// <param name="nearVal">The near val.</param> /// <param name="farVal">The far val.</param> /// <returns></returns> public static Matrix4f frustum(float left, float right, float bottom, float top, float nearVal, float farVal) { var result = new Matrix4f(1); result[0, 0] = (2.0f * nearVal) / (right - left); result[1, 1] = (2.0f * nearVal) / (top - bottom); result[2, 0] = (right + left) / (right - left); result[2, 1] = (top + bottom) / (top - bottom); result[2, 2] = -(farVal + nearVal) / (farVal - nearVal); result[2, 3] = -1.0f; result[3, 2] = -(2.0f * farVal * nearVal) / (farVal - nearVal); return(result); }
/// <summary> /// Creates a perspective transformation matrix. /// </summary> /// <param name="fovy">The field of view angle, in radians.</param> /// <param name="aspect">The aspect ratio.</param> /// <param name="zNear">The near depth clipping plane.</param> /// <param name="zFar">The far depth clipping plane.</param> /// <returns>A <see cref="mat4"/> that contains the projection matrix for the perspective transformation.</returns> public static Matrix4f perspective(float fovy, float aspect, float zNear, float zFar) { var tanHalfFovy = (float)Math.Tan(fovy / 2.0f); Matrix4f result = new Matrix4f(1.0f); result[0, 0] = 1.0f / (aspect * tanHalfFovy); result[1, 1] = 1.0f / (tanHalfFovy); result[2, 2] = -(zFar + zNear) / (zFar - zNear); result[2, 3] = -1.0f; result[3, 2] = -(2.0f * zFar * zNear) / (zFar - zNear); return(result); }
/// <summary> /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. /// </summary> /// <param name="obj">The object.</param> /// <param name="model">The model.</param> /// <param name="proj">The proj.</param> /// <param name="viewport">The viewport.</param> /// <returns></returns> public static Vector3f project(Vector3f obj, Matrix4f model, Matrix4f proj, Vector4f viewport) { Vector4f tmp = new Vector4f(obj, (1f)); tmp = model * tmp; tmp = proj * tmp; tmp /= tmp.w; tmp = tmp * 0.5f + 0.5f; tmp[0] = tmp[0] * viewport[2] + viewport[0]; tmp[1] = tmp[1] * viewport[3] + viewport[1]; return(new Vector3f(tmp.x, tmp.y, tmp.z)); }
public static Matrix4f Transpose(Matrix4f m) { Vector4f[] vec = new Vector4f[4]; vec[0] = new Vector4f(m[0]); vec[1] = new Vector4f(m[1]); vec[2] = new Vector4f(m[2]); vec[3] = new Vector4f(m[3]); for (int i = 0; i < vec.Length; i++) { for (int j = 0; j < vec.Length; j++) { m[i][j] = vec[j][i]; } } return(m); }
/// <summary> /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. /// </summary> /// <param name="win">The win.</param> /// <param name="model">The model.</param> /// <param name="proj">The proj.</param> /// <param name="viewport">The viewport.</param> /// <returns></returns> public static Vector3f unProject(Vector3f win, Matrix4f model, Matrix4f proj, Vector4f viewport) { Matrix4f Inverse = MatrixTransforms.Inverse(proj * model); Vector4f tmp = new Vector4f(win, (1f)); tmp.x = (tmp.x - (viewport[0])) / (viewport[2]); tmp.y = (tmp.y - (viewport[1])) / (viewport[3]); tmp = tmp * (2f) - (1f); Vector4f obj = Inverse * tmp; obj /= obj.w; return(new Vector3f(obj)); }
/// <summary> /// Creates a matrix for a symmetric perspective-view frustum with far plane /// at infinite for graphics hardware that doesn't support depth clamping. /// </summary> /// <param name="fovy">The fovy.</param> /// <param name="aspect">The aspect.</param> /// <param name="zNear">The z near.</param> /// <returns></returns> public static Matrix4f tweakedInfinitePerspective(float fovy, float aspect, float zNear) { float range = Trigonometric.Tan(fovy / (2)) * zNear; float left = -range * aspect; float right = range * aspect; float bottom = -range; float top = range; Matrix4f Result = new Matrix4f((0f)); Result[0, 0] = ((2) * zNear) / (right - left); Result[1, 1] = ((2) * zNear) / (top - bottom); Result[2, 2] = (0.0001f) - (1f); Result[2, 3] = (-1); Result[3, 2] = -((0.0001f) - (2)) * zNear; return(Result); }
/// <summary> /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite. /// </summary> /// <param name="fovy">The fovy.</param> /// <param name="aspect">The aspect.</param> /// <param name="zNear">The z near.</param> /// <returns></returns> public static Matrix4f infinitePerspective(float fovy, float aspect, float zNear) { float range = Trigonometric.Tan(fovy / (2f)) * zNear; float left = -range * aspect; float right = range * aspect; float bottom = -range; float top = range; var result = new Matrix4f(0); result[0, 0] = ((2f) * zNear) / (right - left); result[1, 1] = ((2f) * zNear) / (top - bottom); result[2, 2] = -(1f); result[2, 3] = -(1f); result[3, 2] = -(2f) * zNear; return(result); }
/// <summary> /// Builds a perspective projection matrix based on a field of view. /// </summary> /// <param name="fov">The fov (in radians).</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="zNear">The z near.</param> /// <param name="zFar">The z far.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public static Matrix4f perspectiveFov(float fov, float width, float height, float zNear, float zFar) { if (width <= 0 || height <= 0 || fov <= 0) { throw new ArgumentOutOfRangeException(); } var rad = fov; var h = Trigonometric.Cos((0.5f) * rad) / Trigonometric.Sin((0.5f) * rad); var w = h * height / width; var result = new Matrix4f(0); result[0, 0] = w; result[1, 1] = h; result[2, 2] = -(zFar + zNear) / (zFar - zNear); result[2, 3] = -(1f); result[3, 2] = -((2f) * zFar * zNear) / (zFar - zNear); return(result); }
/// <summary> /// Define a picking region. /// </summary> /// <param name="center">The center.</param> /// <param name="delta">The delta.</param> /// <param name="viewport">The viewport.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public static Matrix4f pickMatrix(Vector2f center, Vector2f delta, Vector4f viewport) { if (delta.x <= 0 || delta.y <= 0) { throw new ArgumentOutOfRangeException(); } var Result = new Matrix4f(1.0f); if (!(delta.x > (0f) && delta.y > (0f))) { return(Result); // Error } Vector3f Temp = new Vector3f( ((viewport[2]) - (2f) * (center.x - (viewport[0]))) / delta.x, ((viewport[3]) - (2f) * (center.y - (viewport[1]))) / delta.y, (0f)); // Translate and scale the picked region to the entire window Result = translate(Result, Temp); return(scale(Result, new Vector3f((viewport[2]) / delta.x, (viewport[3]) / delta.y, (1)))); }
/// <summary> /// Build a look at view matrix. /// </summary> /// <param name="eye">The eye.</param> /// <param name="center">The center.</param> /// <param name="up">Up.</param> /// <returns></returns> public static Matrix4f lookAt(Vector3f eye, Vector3f center, Vector3f up) { Vector3f f = new Vector3f(Geometric.Normalize(center - eye)); Vector3f s = new Vector3f(Geometric.Normalize(Geometric.cross(f, up))); Vector3f u = new Vector3f(Geometric.cross(s, f)); Matrix4f Result = new Matrix4f(1); Result[0, 0] = s.x; Result[1, 0] = s.y; Result[2, 0] = s.z; Result[0, 1] = u.x; Result[1, 1] = u.y; Result[2, 1] = u.z; Result[0, 2] = -f.x; Result[1, 2] = -f.y; Result[2, 2] = -f.z; Result[3, 0] = -Geometric.Dot(s, eye); Result[3, 1] = -Geometric.Dot(u, eye); Result[3, 2] = Geometric.Dot(f, eye); return(Result); }
public static Matrix4f rotate(float angle, Vector3f v) { return(rotate(Matrix4f.identity(), angle, v)); }