/* Copyright (c) 2018 Alex Diener This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Alex Diener alex@ludobloom.com */ #ifndef __Matrix4x4x_H__ #define __Matrix4x4x_H__ #include "gamemath/FixedPoint.h" typedef struct Matrix4x4x Matrix4x4x; struct Matrix4x4x { fixed16_16 m[16]; }; #include "gamemath/Matrix3x3x.h" #include "gamemath/Quaternionx.h" #include "gamemath/Vector2x.h" #include "gamemath/Vector3x.h" #include "gamemath/Vector4x.h" #define MATRIX4x4x_IDENTITY ((Matrix4x4x) {{0x10000, 0x00000, 0x00000, 0x00000, \ 0x00000, 0x10000, 0x00000, 0x00000, \ 0x00000, 0x00000, 0x10000, 0x00000, \ 0x00000, 0x00000, 0x00000, 0x10000}}) void Matrix4x4x_loadIdentity(Matrix4x4x * matrix1); // Performs a multiplication of matrix1 with matrix2 and returns the result. Matrix4x4x Matrix4x4x_multiplied(Matrix4x4x matrix1, Matrix4x4x matrix2); // Performs a multiplication of matrix1 with matrix2 and stores the result in matrix1. void Matrix4x4x_multiply(Matrix4x4x * matrix1, Matrix4x4x matrix2); // Performs a multiplication of matrix2 with matrix1 and stores the result in matrix1. void Matrix4x4x_leftMultiply(Matrix4x4x * matrix1, Matrix4x4x matrix2); #define MATRIX4x4x(m0, m4, m8, m12, \ m1, m5, m9, m13, \ m2, m6, m10, m14, \ m3, m7, m11, m15) \ ((Matrix4x4x) {{m0, m1, m2, m3, \ m4, m5, m6, m7, \ m8, m9, m10, m11, \ m12, m13, m14, m15}}) Matrix4x4x Matrix4x4x_fromDirectionVectors(Vector3x right, Vector3x up, Vector3x front); Matrix4x4x Matrix4x4x_fromComponentArray(fixed16_16 * components); Matrix4x4x Matrix4x4x_fromQuaternionx(Quaternionx quaternion); Matrix4x4x Matrix4x4x_fromMatrix3x3x(Matrix3x3x matrix3x3); bool Matrix4x4x_isEqual(Matrix4x4x matrix1, Matrix4x4x matrix2); bool Matrix4x4x_isIdentity(Matrix4x4x matrix); // Returns a new matrix that can be multiplied with another to transform it as specified. Matrix4x4x Matrix4x4x_translationMatrix(Vector3x offset); Matrix4x4x Matrix4x4x_scaleMatrix(Vector3x scale); Matrix4x4x Matrix4x4x_rotationMatrix(struct Vector3x axis, fixed16_16 radians); Matrix4x4x Matrix4x4x_shearXMatrix(fixed16_16 y, fixed16_16 z); Matrix4x4x Matrix4x4x_shearYMatrix(fixed16_16 x, fixed16_16 z); Matrix4x4x Matrix4x4x_shearZMatrix(fixed16_16 x, fixed16_16 y); Matrix4x4x Matrix4x4x_perspectiveMatrix(fixed16_16 fovYDegrees, fixed16_16 aspect, fixed16_16 zNear, fixed16_16 zFar); Matrix4x4x Matrix4x4x_orthoMatrix(fixed16_16 left, fixed16_16 right, fixed16_16 bottom, fixed16_16 top, fixed16_16 zNear, fixed16_16 zFar); // Convenience functions to multiply matrix by a constructed transformation and store the result in matrix. // To multiply in the other order, construct the transformation yourself and call Matrix_leftMultiply(). void Matrix4x4x_translate(Matrix4x4x * matrix1, Vector3x offset); void Matrix4x4x_scale(Matrix4x4x * matrix, Vector3x scale); void Matrix4x4x_rotate(Matrix4x4x * matrix, struct Vector3x axis, fixed16_16 radians); void Matrix4x4x_shearX(Matrix4x4x * matrix, fixed16_16 y, fixed16_16 z); void Matrix4x4x_shearY(Matrix4x4x * matrix, fixed16_16 x, fixed16_16 z); void Matrix4x4x_shearZ(Matrix4x4x * matrix, fixed16_16 x, fixed16_16 y); void Matrix4x4x_applyPerspective(Matrix4x4x * matrix, fixed16_16 fovYDegrees, fixed16_16 aspect, fixed16_16 zNear, fixed16_16 zFar); void Matrix4x4x_applyOrtho(Matrix4x4x * matrix, fixed16_16 left, fixed16_16 right, fixed16_16 bottom, fixed16_16 top, fixed16_16 zNear, fixed16_16 zFar); // Convenience functions to multiply matrix by a constructed transformation and return the result. // To multiply in the other order, construct the transformation yourself and call Matrix_multiplied() with the target matrix as the second parameter. Matrix4x4x Matrix4x4x_translated(Matrix4x4x matrix1, Vector3x offset); Matrix4x4x Matrix4x4x_scaled(Matrix4x4x matrix, Vector3x scale); Matrix4x4x Matrix4x4x_rotated(Matrix4x4x matrix, struct Vector3x axis, fixed16_16 radians); Matrix4x4x Matrix4x4x_shearedX(Matrix4x4x matrix, fixed16_16 y, fixed16_16 z); Matrix4x4x Matrix4x4x_shearedY(Matrix4x4x matrix, fixed16_16 x, fixed16_16 z); Matrix4x4x Matrix4x4x_shearedZ(Matrix4x4x matrix, fixed16_16 x, fixed16_16 y); Matrix4x4x Matrix4x4x_perspective(Matrix4x4x matrix, fixed16_16 fovYDegrees, fixed16_16 aspect, fixed16_16 zNear, fixed16_16 zFar); Matrix4x4x Matrix4x4x_ortho(Matrix4x4x matrix, fixed16_16 left, fixed16_16 right, fixed16_16 bottom, fixed16_16 top, fixed16_16 zNear, fixed16_16 zFar); Matrix4x4x Matrix4x4x_transposed(Matrix4x4x matrix); void Matrix4x4x_transpose(Matrix4x4x * matrix); fixed16_16 Matrix4x4x_determinant(Matrix4x4x matrix); Matrix4x4x Matrix4x4x_inverted(Matrix4x4x matrix); void Matrix4x4x_invert(Matrix4x4x * matrix); Matrix4x4x Matrix4x4x_interpolated(Matrix4x4x left, Matrix4x4x right, fixed16_16 value); void Matrix4x4x_interpolate(Matrix4x4x * left, Matrix4x4x right, fixed16_16 value); // Normalizes a scaled matrix's direction vectors, undoing the scale transformation while preserving rotation. // May produce incorrect results for extreme scale factors or unconventional matrices. Matrix4x4x Matrix4x4x_normalized(Matrix4x4x matrix); void Matrix4x4x_normalize(Matrix4x4x * matrix); Vector2x Matrix4x4x_multiplyVector2x(Matrix4x4x matrix, Vector2x vector); Vector3x Matrix4x4x_multiplyVector3x(Matrix4x4x matrix, Vector3x vector); Vector4x Matrix4x4x_multiplyVector4x(Matrix4x4x matrix, Vector4x vector); // Performs a vector multiplication treating this as a 3x3 matrix. Despite the name, scale will still be applied as well as rotation. Vector2x Matrix4x4x_multiplyVector2x_rotationOnly(Matrix4x4x matrix, Vector2x vector); Vector3x Matrix4x4x_multiplyVector3x_rotationOnly(Matrix4x4x matrix, Vector3x vector); #endif