/******************************************************************************* Copyright (c) 2009, Charles McGarvey All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #ifndef _MATRIX_HH_ #define _MATRIX_HH_ /** * @file matrix.hh * Matrix classes. */ #include #include "math.hh" namespace dc { /** * 3x3 matrix. */ struct matrix3 { matrix3() {} matrix3(scalar M11, scalar M12, scalar M13, scalar M21, scalar M22, scalar M23, scalar M31, scalar M32, scalar M33) { m11 = M11; m12 = M12; m13 = M13; m21 = M21; m22 = M22; m23 = M23; m31 = M31; m32 = M32; m33 = M33; } matrix3(scalar m[9]) { array[0] = m[0]; array[1] = m[1]; array[2] = m[2]; array[3] = m[3]; array[4] = m[4]; array[5] = m[5]; array[6] = m[6]; array[7] = m[7]; array[8] = m[8]; } const scalar& operator[](int i) const { assert(i >= 0 && i <= 8 && "Index into matrix3 out of bounds."); return array[i]; } scalar& operator[](int i) { assert(i >= 0 && i <= 8 && "Index into matrix3 out of bounds."); return array[i]; } matrix3 operator+(const matrix3& m) const { return matrix3(m11 + m.m11, m12 + m.m12, m13 + m.m13, m21 + m.m21, m22 + m.m22, m23 + m.m23, m31 + m.m31, m32 + m.m32, m33 + m.m33); } matrix3 operator-(const matrix3& m) const { return matrix3(m11 - m.m11, m12 - m.m12, m13 - m.m13, m21 - m.m21, m22 - m.m22, m23 - m.m23, m31 - m.m31, m32 - m.m32, m33 - m.m33); } matrix3 operator*(const matrix3& m) const { return matrix3(m11 * m.m11 + m12 * m.m21 + m13 * m.m31, m11 * m.m12 + m12 * m.m22 + m13 * m.m32, m11 * m.m13 + m12 * m.m23 + m13 * m.m33, m21 * m.m11 + m22 * m.m21 + m23 * m.m31, m21 * m.m12 + m22 * m.m22 + m23 * m.m32, m21 * m.m13 + m22 * m.m23 + m23 * m.m33, m31 * m.m11 + m32 * m.m21 + m33 * m.m31, m31 * m.m12 + m32 * m.m22 + m33 * m.m32, m32 * m.m13 + m32 * m.m23 + m33 * m.m33); } matrix3 operator*(scalar s) const { return matrix3(m11 * s, m12 * s, m13 * s, m21 * s, m22 * s, m23 * s, m31 * s, m32 * s, m33 * s); } matrix3 operator/(scalar s) const { return matrix3(m11 / s, m12 / s, m13 / s, m21 / s, m22 / s, m23 / s, m31 / s, m32 / s, m33 / s); } matrix3& operator+=(const matrix3& m) { m11 += m.m11; m12 += m.m12; m13 += m.m13; m21 += m.m21; m22 += m.m22; m23 += m.m23; m31 += m.m31; m32 += m.m32; m33 += m.m33; return *this; } matrix3& operator-=(const matrix3& m) { m11 -= m.m11; m12 -= m.m12; m13 -= m.m13; m21 -= m.m21; m22 -= m.m22; m23 -= m.m23; m31 -= m.m31; m32 -= m.m32; m33 -= m.m33; return *this; } matrix3& operator*=(const matrix3& m) { return *this = *this * m; } matrix3& operator*=(scalar s) { m11 *= s; m12 *= s; m13 *= s; m21 *= s; m22 *= s; m23 *= s; m31 *= s; m32 *= s; m33 *= s; return *this; } matrix3& operator/=(scalar s) { m11 /= s; m12 /= s; m13 /= s; m21 /= s; m22 /= s; m23 /= s; m31 /= s; m32 /= s; m33 /= s; return *this; } matrix3 operator-() const { return matrix3(-m11, -m12, -m13, -m21, -m22, -m23, -m31, -m32, -m33); } bool operator==(const matrix3& m) const { return equals(m11,m.m11) && equals(m12,m.m12) && equals(m13,m.m13) && equals(m21,m.m21) && equals(m22,m.m22) && equals(m23,m.m23) && equals(m31,m.m31) && equals(m32,m.m32) && equals(m33,m.m33); } bool operator!=(const matrix3& m) const { return !(*this == m); } union { struct { scalar m11, m21, m31; scalar m12, m22, m32; scalar m13, m23, m33; ///< scalars }; scalar array[9]; ///< array }; static matrix3 zero; ///< zero matrix static matrix3 identity; ///< identity matrix }; inline matrix3 operator*(scalar s, const matrix3& m) { return m * s; } inline matrix3 operator/(scalar s, const matrix3& m) { return matrix3(s / m.m11, s / m.m12, s / m.m13, s / m.m21, s / m.m22, s / m.m23, s / m.m31, s / m.m32, s / m.m33); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * 4x4 matrix. */ struct matrix4 { matrix4() {} matrix4(scalar M11, scalar M12, scalar M13, scalar M14, scalar M21, scalar M22, scalar M23, scalar M24, scalar M31, scalar M32, scalar M33, scalar M34, scalar M41, scalar M42, scalar M43, scalar M44) { m11 = M11; m12 = M12; m13 = M13; m14 = M14; m21 = M21; m22 = M22; m23 = M23; m24 = M24; m31 = M31; m32 = M32; m33 = M33; m34 = M34; m41 = M41; m42 = M42; m43 = M43; m44 = M44; } matrix4(scalar m[15]) { array[0] = m[0]; array[1] = m[1]; array[2] = m[2]; array[3] = m[3]; array[4] = m[4]; array[5] = m[5]; array[6] = m[6]; array[7] = m[7]; array[8] = m[8]; array[9] = m[9]; array[10] = m[10]; array[11] = m[11]; array[12] = m[12]; array[13] = m[13]; array[14] = m[14]; array[15] = m[15]; } const scalar& operator[](int i) const { assert(i >= 0 && i <= 15 && "Index into matrix4 out of bounds."); return array[i]; } scalar& operator[](int i) { assert(i >= 0 && i <= 15 && "Index into matrix4 out of bounds."); return array[i]; } matrix4 operator+(const matrix4& m) const { return matrix4(m11 + m.m11, m12 + m.m12, m13 + m.m13, m14 + m.m14, m21 + m.m21, m22 + m.m22, m23 + m.m23, m24 + m.m24, m31 + m.m31, m32 + m.m32, m33 + m.m33, m34 + m.m34, m41 + m.m41, m42 + m.m42, m43 + m.m43, m44 + m.m44); } matrix4 operator-(const matrix4& m) const { return matrix4(m11 - m.m11, m12 - m.m12, m13 - m.m13, m14 - m.m14, m21 - m.m21, m22 - m.m22, m23 - m.m23, m24 - m.m24, m31 - m.m31, m32 - m.m32, m33 - m.m33, m34 - m.m34, m41 - m.m41, m42 - m.m42, m43 - m.m43, m44 - m.m44); } matrix4 operator*(const matrix4& m) const // TODO ?? { return matrix4(m11 * m.m11 + m12 * m.m21 + m13 * m.m31 + m14 * m.m41, m11 * m.m12 + m12 * m.m22 + m13 * m.m32 + m14 * m.m42, m11 * m.m13 + m12 * m.m23 + m13 * m.m33 + m14 * m.m43, m11 * m.m14 + m12 * m.m24 + m13 * m.m34 + m14 * m.m44, m21 * m.m11 + m22 * m.m21 + m23 * m.m31 + m24 * m.m41, m21 * m.m12 + m22 * m.m22 + m23 * m.m32 + m24 * m.m42, m21 * m.m13 + m22 * m.m23 + m23 * m.m33 + m24 * m.m43, m21 * m.m14 + m22 * m.m24 + m23 * m.m34 + m24 * m.m44, m31 * m.m11 + m32 * m.m21 + m33 * m.m31 + m34 * m.m41, m31 * m.m12 + m32 * m.m22 + m33 * m.m32 + m34 * m.m42, m31 * m.m13 + m32 * m.m23 + m33 * m.m33 + m34 * m.m43, m31 * m.m14 + m32 * m.m24 + m33 * m.m34 + m34 * m.m44, m41 * m.m11 + m42 * m.m21 + m43 * m.m31 + m44 * m.m41, m41 * m.m12 + m42 * m.m22 + m43 * m.m32 + m44 * m.m42, m41 * m.m13 + m42 * m.m23 + m43 * m.m33 + m44 * m.m43, m41 * m.m14 + m42 * m.m24 + m43 * m.m34 + m44 * m.m44); } matrix4 operator*(scalar s) const { return matrix4(m11 * s, m12 * s, m13 * s, m14 * s, m21 * s, m22 * s, m23 * s, m24 * s, m31 * s, m32 * s, m33 * s, m34 * s, m41 * s, m42 * s, m43 * s, m44 * s); } matrix4 operator/(scalar s) const { return matrix4(m11 / s, m12 / s, m13 / s, m14 / s, m21 / s, m22 / s, m23 / s, m24 / s, m31 / s, m32 / s, m33 / s, m34 / s, m41 / s, m42 / s, m43 / s, m44 / s); } matrix4& operator+=(const matrix4& m) { m11 += m.m11; m12 += m.m12; m13 += m.m13; m14 += m.m14; m21 += m.m21; m22 += m.m22; m23 += m.m23; m24 += m.m24; m31 += m.m31; m32 += m.m32; m33 += m.m33; m34 += m.m34; m41 += m.m41; m42 += m.m42; m43 += m.m43; m44 += m.m44; return *this; } matrix4& operator-=(const matrix4& m) { m11 -= m.m11; m12 -= m.m12; m13 -= m.m13; m14 -= m.m14; m21 -= m.m21; m22 -= m.m22; m23 -= m.m23; m24 -= m.m24; m31 -= m.m31; m32 -= m.m32; m33 -= m.m33; m34 -= m.m34; m41 -= m.m41; m42 -= m.m42; m43 -= m.m43; m44 -= m.m44; return *this; } matrix4& operator*=(const matrix4& m) { *this = *this * m; return *this; } matrix4& operator*=(scalar s) { m11 *= s; m12 *= s; m13 *= s; m14 *= s; m21 *= s; m22 *= s; m23 *= s; m24 *= s; m31 *= s; m32 *= s; m33 *= s; m34 *= s; m41 *= s; m42 *= s; m43 *= s; m44 *= s; return *this; } matrix4& operator/=(scalar s) { m11 /= s; m12 /= s; m13 /= s; m14 /= s; m21 /= s; m22 /= s; m23 /= s; m24 /= s; m31 /= s; m32 /= s; m33 /= s; m34 /= s; m41 /= s; m42 /= s; m43 /= s; m44 /= s; return *this; } matrix4 operator-() const { return matrix4(-m11, -m12, -m13, -m14, -m21, -m22, -m23, -m24, -m31, -m32, -m33, -m34, -m41, -m42, -m43, -m44); } bool operator==(const matrix4& m) const { return equals(m11,m.m11) && equals(m12,m.m12) && equals(m13,m.m13) && equals(m14,m.m14) && equals(m21,m.m21) && equals(m22,m.m22) && equals(m23,m.m23) && equals(m24,m.m24) && equals(m31,m.m31) && equals(m32,m.m32) && equals(m33,m.m33) && equals(m34,m.m34) && equals(m41,m.m41) && equals(m42,m.m42) && equals(m43,m.m43) && equals(m44,m.m44); } bool operator!=(const matrix4& m) const { return !(*this == m); } union { struct { scalar m11, m21, m31, m41; scalar m12, m22, m32, m42; scalar m13, m23, m33, m43; scalar m14, m24, m34, m44; ///< scalars }; scalar array[16]; ///< array }; static matrix4 zero; ///< zero matrix static matrix4 identity; ///< identity matrix }; inline matrix4 operator*(scalar s, const matrix4& m) { return m * s; } inline matrix4 operator/(scalar s, const matrix4& m) { return matrix4(s / m.m11, s / m.m12, s / m.m13, s / m.m14, s / m.m21, s / m.m22, s / m.m23, s / m.m24, s / m.m31, s / m.m32, s / m.m33, s / m.m34, s / m.m41, s / m.m42, s / m.m43, s / m.m44); } } // namespace dc #endif // _MATRIX_HH_