Advertisement
microwerx

Matrix Class

Apr 16th, 2018
539
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 49.57 KB | None | 0 0
  1. // SSPHH/Fluxions/Unicornfish/Viperfish/Hatchetfish/Sunfish/KASL/GLUT Extensions
  2. // Copyright (C) 2017 Jonathan Metzgar
  3. // All rights reserved.
  4. //
  5. // This program is free software : you can redistribute it and/or modify
  6. // it under the terms of the GNU Affero General Public License as
  7. // published by the Free Software Foundation, either version 3 of the
  8. // License, or (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
  13. // GNU Affero General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with this program.If not, see <https://www.gnu.org/licenses/>.
  17. //
  18. // For any other type of licensing, please contact me at jmetzgar@outlook.com
  19. #ifndef FLUXIONS_MATRIX4_HPP
  20. #define FLUXIONS_MATRIX4_HPP
  21.  
  22.  
  23. #include <type_traits>
  24. #include <fluxions_gte_math.hpp>
  25. #include <fluxions_gte_vector3.hpp>
  26. #include <fluxions_gte_vector4.hpp>
  27.  
  28.  
  29. namespace Fluxions
  30. {
  31.     using namespace std;
  32.  
  33.     template <typename T>
  34.     class TMatrix4
  35.     {
  36.     public:
  37.         union
  38.         {
  39.             // normal access (column major)
  40.             struct
  41.             {
  42.                 T m11, m21, m31, m41;
  43.                 T m12, m22, m32, m42;
  44.                 T m13, m23, m33, m43;
  45.                 T m14, m24, m34, m44;
  46.             };
  47.            
  48.             // transposed access
  49.             struct
  50.             {
  51.                 T t11, t12, t13, t14;
  52.                 T t21, t22, t23, t24;
  53.                 T t31, t32, t33, t34;
  54.                 T t41, t42, t43, t44;
  55.             };
  56.            
  57.             // 2D array form
  58.             T mm[4][4];
  59.  
  60.             // array form
  61.             T m[16];
  62.             T v[16];
  63.         };
  64.  
  65.         static constexpr size_t size() { return 16; }
  66.         static constexpr size_t numrows() { return 4; }
  67.         static constexpr size_t numcols() { return 4; }
  68.        
  69.         TMatrix4() noexcept
  70.         {
  71.             m11 = 1; m12 = 0; m13 = 0; m14 = 0;
  72.             m21 = 0; m22 = 1; m23 = 0; m24 = 0;
  73.             m31 = 0; m32 = 0; m33 = 1; m34 = 0;
  74.             m41 = 0; m42 = 0; m43 = 0; m44 = 1;
  75.         }
  76.  
  77.         constexpr TMatrix4(const TMatrix4<T> & M) noexcept
  78.         {
  79.             m11 = M.m11; m12 = M.m12; m13 = M.m13; m14 = M.m14;
  80.             m21 = M.m21; m22 = M.m22; m23 = M.m23; m24 = M.m24;
  81.             m31 = M.m31; m32 = M.m32; m33 = M.m33; m34 = M.m34;
  82.             m41 = M.m41; m42 = M.m42; m43 = M.m43; m44 = M.m44;
  83.         }
  84.  
  85.         TMatrix4(TMatrix4<T> && M) noexcept
  86.         {
  87.             m11 = std::move(M.m11); m12 = std::move(M.m12); m13 = std::move(M.m13); m14 = std::move(M.m14);
  88.             m21 = std::move(M.m21); m22 = std::move(M.m22); m23 = std::move(M.m23); m24 = std::move(M.m24);
  89.             m31 = std::move(M.m31); m32 = std::move(M.m32); m33 = std::move(M.m33); m34 = std::move(M.m34);
  90.             m41 = std::move(M.m41); m42 = std::move(M.m42); m43 = std::move(M.m43); m44 = std::move(M.m44);
  91.         }
  92.  
  93.         TMatrix4(const T value) noexcept
  94.         {
  95.             m11 = value; m12 = value; m13 = value; m14 = value;
  96.             m21 = value; m22 = value; m23 = value; m24 = value;
  97.             m31 = value; m32 = value; m33 = value; m34 = value;
  98.             m41 = value; m42 = value; m43 = value; m44 = value;        
  99.         }
  100.  
  101.         TMatrix4(
  102.             const T a11, const T a12, const T a13, const T a14,
  103.             const T a21, const T a22, const T a23, const T a24,
  104.             const T a31, const T a32, const T a33, const T a34,
  105.             const T a41, const T a42, const T a43, const T a44) noexcept
  106.         {
  107.             m11 = a11; m12 = a12; m13 = a13; m14 = a14;
  108.             m21 = a21; m22 = a22; m23 = a23; m24 = a24;
  109.             m31 = a31; m32 = a32; m33 = a33; m34 = a34;
  110.             m41 = a41; m42 = a42; m43 = a43; m44 = a44;
  111.         }
  112.  
  113.         TMatrix4(const T M[numrows()][numcols()]) noexcept
  114.         {
  115.             const T *_v = M[0];
  116.             for (auto i = 0; i < size(); i++)
  117.             {
  118.                 v[i] = _v[i];
  119.             }
  120.         }
  121.  
  122.         TMatrix4(const T M[size()]) noexcept
  123.         {
  124.             const T *_v = M;
  125.             for (auto i = 0; i < size(); i++)
  126.             {
  127.                 v[i] = _v[i];
  128.             }
  129.         }
  130.  
  131.         constexpr auto operator = (const TMatrix4<T> & M) noexcept
  132.         {
  133.             m11 = M.m11; m12 = M.m12; m13 = M.m13; m14 = M.m14;
  134.             m21 = M.m21; m22 = M.m22; m23 = M.m23; m24 = M.m24;
  135.             m31 = M.m31; m32 = M.m32; m33 = M.m33; m34 = M.m34;
  136.             m41 = M.m41; m42 = M.m42; m43 = M.m43; m44 = M.m44;
  137.             return *this;
  138.         }
  139.  
  140.         template <typename U> constexpr auto operator = (const TMatrix4<U> & M) noexcept
  141.         {
  142.             m11 = static_cast<T>(M.m11); m12 = static_cast<T>(M.m12); m13 = static_cast<T>(M.m13); m14 = static_cast<T>(M.m14);
  143.             m21 = static_cast<T>(M.m21); m22 = static_cast<T>(M.m22); m23 = static_cast<T>(M.m23); m24 = static_cast<T>(M.m24);
  144.             m31 = static_cast<T>(M.m31); m32 = static_cast<T>(M.m32); m33 = static_cast<T>(M.m33); m34 = static_cast<T>(M.m34);
  145.             m41 = static_cast<T>(M.m41); m42 = static_cast<T>(M.m42); m43 = static_cast<T>(M.m43); m44 = static_cast<T>(M.m44);
  146.             return *this;
  147.         }
  148.  
  149.         //template <typename U> constexpr TMatrix4<T> & operator = (const enable_if_t<is_arithmetic_v<U>, U> value) noexcept
  150.         template <typename U> constexpr TMatrix4<T> & operator = (const U value) noexcept
  151.         {
  152.             m11 = static_cast<T>(value); m12 = static_cast<T>(value); m13 = static_cast<T>(value); m14 = static_cast<T>(value);
  153.             m21 = static_cast<T>(value); m22 = static_cast<T>(value); m23 = static_cast<T>(value); m24 = static_cast<T>(value);
  154.             m31 = static_cast<T>(value); m32 = static_cast<T>(value); m33 = static_cast<T>(value); m34 = static_cast<T>(value);
  155.             m41 = static_cast<T>(value); m42 = static_cast<T>(value); m43 = static_cast<T>(value); m44 = static_cast<T>(value);
  156.             return *this;
  157.         }
  158.  
  159.         template <typename U> constexpr operator TMatrix4<U>() const noexcept {
  160.             return TMatrix4<U>(
  161.                 static_cast<U>(m11), static_cast<U>(m12), static_cast<U>(m13), static_cast<U>(m14),
  162.                 static_cast<U>(m21), static_cast<U>(m22), static_cast<U>(m23), static_cast<U>(m24),
  163.                 static_cast<U>(m31), static_cast<U>(m32), static_cast<U>(m33), static_cast<U>(m34),
  164.                 static_cast<U>(m41), static_cast<U>(m42), static_cast<U>(m43), static_cast<U>(m44)
  165.                 );
  166.         }
  167.  
  168.         constexpr TVector4<T> row1() const noexcept { return TVector4<T>(m11, m12, m13, m14); }
  169.         constexpr TVector4<T> row2() const noexcept { return TVector4<T>(m21, m22, m23, m24); }
  170.         constexpr TVector4<T> row3() const noexcept { return TVector4<T>(m31, m32, m33, m34); }
  171.         constexpr TVector4<T> row4() const noexcept { return TVector4<T>(m41, m42, m43, m44); }
  172.         constexpr TVector4<T> col1() const noexcept { return TVector4<T>(m11, m21, m31, m41); }
  173.         constexpr TVector4<T> col2() const noexcept { return TVector4<T>(m12, m22, m32, m42); }
  174.         constexpr TVector4<T> col3() const noexcept { return TVector4<T>(m13, m23, m33, m43); }
  175.         constexpr TVector4<T> col4() const noexcept { return TVector4<T>(m14, m24, m34, m44); }
  176.  
  177.         // col(i) returns the ith column of the matrix (i = 1 is column 1)
  178.         constexpr TVector4<T> col(int i) const noexcept {
  179.             switch (i) {
  180.             case 1: return col1();
  181.             case 2: return col2();
  182.             case 3: return col3();
  183.             case 4: return col4();
  184.             }
  185.             return TVector4<T>();
  186.         }
  187.  
  188.         // row(i) returns the ith row of the matrix (i = 1 is row 1)
  189.         constexpr TVector4<T> row(int i) const noexcept {
  190.             switch (i) {
  191.             case 1: return row1();
  192.             case 2: return row2();
  193.             case 3: return row3();
  194.             case 4: return row4();
  195.             }
  196.             return TVector4<T>();
  197.         }
  198.  
  199.         template <typename U> static constexpr auto compAdd(const TMatrix4<T> & m1, const TMatrix4<U> & m2) noexcept
  200.         {
  201.             return TMatrix4<common_type_t<T, U>>(
  202.                 m1.m11 + m2.m11, m1.m12 + m2.m12, m1.m13 + m2.m13, m1.m14 + m2.m14,
  203.                 m1.m21 + m2.m21, m1.m22 + m2.m22, m1.m23 + m2.m23, m1.m24 + m2.m24,
  204.                 m1.m31 + m2.m31, m1.m32 + m2.m32, m1.m33 + m2.m33, m1.m34 + m2.m34,
  205.                 m1.m41 + m2.m41, m1.m42 + m2.m42, m1.m43 + m2.m43, m1.m44 + m2.m44
  206.                 );
  207.         }
  208.  
  209.         template <typename U> static constexpr auto compSub(const TMatrix4<T> & m1, const TMatrix4<U> & m2) noexcept
  210.         {
  211.             return TMatrix4<common_type_t<T, U>>(
  212.                 m1.m11 - m2.m11, m1.m12 - m2.m12, m1.m13 - m2.m13, m1.m14 - m2.m14,
  213.                 m1.m21 - m2.m21, m1.m22 - m2.m22, m1.m23 - m2.m23, m1.m24 - m2.m24,
  214.                 m1.m31 - m2.m31, m1.m32 - m2.m32, m1.m33 - m2.m33, m1.m34 - m2.m34,
  215.                 m1.m41 - m2.m41, m1.m42 - m2.m42, m1.m43 - m2.m43, m1.m44 - m2.m44
  216.                 );
  217.         }
  218.  
  219.         template <typename U> static constexpr auto compMult(const TMatrix4<T> & m1, const TMatrix4<U> & m2) noexcept
  220.         {
  221.             return TMatrix4<common_type_t<T, U>>(
  222.                 m1.m11 * m2.m11, m1.m12 * m2.m12, m1.m13 * m2.m13, m1.m14 * m2.m14,
  223.                 m1.m21 * m2.m21, m1.m22 * m2.m22, m1.m23 * m2.m23, m1.m24 * m2.m24,
  224.                 m1.m31 * m2.m31, m1.m32 * m2.m32, m1.m33 * m2.m33, m1.m34 * m2.m34,
  225.                 m1.m41 * m2.m41, m1.m42 * m2.m42, m1.m43 * m2.m43, m1.m44 * m2.m44
  226.                 );
  227.         }
  228.  
  229.         template <typename U> static constexpr auto compDiv(const TMatrix4<T> & m1, const TMatrix4<U> & m2) noexcept
  230.         {
  231.             return TMatrix4<common_type_t<T, U>>(
  232.                 m1.m11 / m2.m11, m1.m12 / m2.m12, m1.m13 / m2.m13, m1.m14 / m2.m14,
  233.                 m1.m21 / m2.m21, m1.m22 / m2.m22, m1.m23 / m2.m23, m1.m24 / m2.m24,
  234.                 m1.m31 / m2.m31, m1.m32 / m2.m32, m1.m33 / m2.m33, m1.m34 / m2.m34,
  235.                 m1.m41 / m2.m41, m1.m42 / m2.m42, m1.m43 / m2.m43, m1.m44 / m2.m44
  236.                 );
  237.         }
  238.  
  239.         template <typename U> static constexpr auto multiply(const TMatrix4<T> & m1, const TMatrix4<U> & m2) noexcept
  240.         {
  241.             return TMatrix4<common_type_t<T, U>>(
  242.                 (m1.m14*m2.m41 + m1.m13*m2.m31 + m1.m12*m2.m21 + m1.m11*m2.m11),
  243.                 (m1.m14*m2.m42 + m1.m13*m2.m32 + m1.m12*m2.m22 + m1.m11*m2.m12),
  244.                 (m1.m14*m2.m43 + m1.m13*m2.m33 + m1.m12*m2.m23 + m1.m11*m2.m13),
  245.                 (m1.m14*m2.m44 + m1.m13*m2.m34 + m1.m12*m2.m24 + m1.m11*m2.m14),
  246.  
  247.                 (m1.m24*m2.m41 + m1.m23*m2.m31 + m1.m22*m2.m21 + m1.m21*m2.m11),
  248.                 (m1.m24*m2.m42 + m1.m23*m2.m32 + m1.m22*m2.m22 + m1.m21*m2.m12),
  249.                 (m1.m24*m2.m43 + m1.m23*m2.m33 + m1.m22*m2.m23 + m1.m21*m2.m13),
  250.                 (m1.m24*m2.m44 + m1.m23*m2.m34 + m1.m22*m2.m24 + m1.m21*m2.m14),
  251.  
  252.                 (m1.m34*m2.m41 + m1.m33*m2.m31 + m1.m32*m2.m21 + m1.m31*m2.m11),
  253.                 (m1.m34*m2.m42 + m1.m33*m2.m32 + m1.m32*m2.m22 + m1.m31*m2.m12),
  254.                 (m1.m34*m2.m43 + m1.m33*m2.m33 + m1.m32*m2.m23 + m1.m31*m2.m13),
  255.                 (m1.m34*m2.m44 + m1.m33*m2.m34 + m1.m32*m2.m24 + m1.m31*m2.m14),
  256.  
  257.                 (m1.m44*m2.m41 + m1.m43*m2.m31 + m1.m42*m2.m21 + m1.m41*m2.m11),
  258.                 (m1.m44*m2.m42 + m1.m43*m2.m32 + m1.m42*m2.m22 + m1.m41*m2.m12),
  259.                 (m1.m44*m2.m43 + m1.m43*m2.m33 + m1.m42*m2.m23 + m1.m41*m2.m13),
  260.                 (m1.m44*m2.m44 + m1.m43*m2.m34 + m1.m42*m2.m24 + m1.m41*m2.m14));
  261.         }
  262.  
  263.         constexpr auto LoadIdentity() noexcept
  264.         {
  265.             return *this = MakeIdentity();
  266.         }
  267.  
  268.         constexpr auto operator - () noexcept
  269.         {
  270.             return TMatrix4<T>(
  271.                 -m11, -m12, -m13, -m14,
  272.                 -m21, -m22, -m23, -m24,
  273.                 -m31, -m32, -m33, -m34,
  274.                 -m41, -m42, -m43, -m44
  275.                 );
  276.         }
  277.  
  278.         template <typename U> constexpr auto operator()(std::function<U(T x)> Func) noexcept
  279.         {
  280.             return TMatrix4<common_type_t<T, U>>(
  281.                 Func(m11), Func(m12), Func(m13), Func(m14),
  282.                 Func(m21), Func(m22), Func(m23), Func(m24),
  283.                 Func(m31), Func(m32), Func(m33), Func(m34),
  284.                 Func(m41), Func(m42), Func(m43), Func(m44)
  285.                 );
  286.         }
  287.  
  288.         template <typename U> constexpr auto MultMatrix(const TMatrix4<U> & M) noexcept
  289.         {
  290.             return *this = multiply(*this, M);
  291.         }
  292.  
  293.         template <typename U> constexpr auto operator *= (const TMatrix4<U> & M) noexcept
  294.         {
  295.             return *this = multiply(*this, M);
  296.         }
  297.  
  298.         template <typename U> constexpr auto operator += (const TMatrix4<U> & M) noexcept
  299.         {
  300.             m11 += M.m11; m12 += M.m12; m13 += M.m13; m14 += M.m14;
  301.             m21 += M.m21; m22 += M.m22; m23 += M.m23; m24 += M.m24;
  302.             m31 += M.m31; m32 += M.m32; m33 += M.m33; m34 += M.m34;
  303.             m41 += M.m41; m42 += M.m42; m43 += M.m43; m44 += M.m44;
  304.             return *this;
  305.         }
  306.  
  307.         template <typename U> constexpr auto operator -= (const TMatrix4<U> & M) noexcept
  308.         {
  309.             m11 -= M.m11; m12 -= M.m12; m13 -= M.m13; m14 -= M.m14;
  310.             m21 -= M.m21; m22 -= M.m22; m23 -= M.m23; m24 -= M.m24;
  311.             m31 -= M.m31; m32 -= M.m32; m33 -= M.m33; m34 -= M.m34;
  312.             m41 -= M.m41; m42 -= M.m42; m43 -= M.m43; m44 -= M.m44;
  313.             return *this;
  314.         }
  315.  
  316.         //template <typename U> const TMatrix4<T> operator * (const TMatrix4<U> & M) const;
  317.         //template <typename U> const TMatrix4<T> operator + (const TMatrix4<U> & M) const;
  318.         //template <typename U> const TMatrix4<T> operator - (const TMatrix4<U> & M) const;
  319.        
  320.         template <typename U> constexpr auto operator += (const U c) noexcept
  321.         {
  322.             m11 += c; m12 += c; m13 += c; m14 += c;
  323.             m21 += c; m22 += c; m23 += c; m24 += c;
  324.             m31 += c; m32 += c; m33 += c; m34 += c;
  325.             m41 += c; m42 += c; m43 += c; m44 += c;
  326.             return *this;
  327.         }
  328.  
  329.         template <typename U> constexpr auto operator -= (const U c) noexcept
  330.         {
  331.             m11 -= c; m12 -= c; m13 -= c; m14 -= c;
  332.             m21 -= c; m22 -= c; m23 -= c; m24 -= c;
  333.             m31 -= c; m32 -= c; m33 -= c; m34 -= c;
  334.             m41 -= c; m42 -= c; m43 -= c; m44 -= c;
  335.             return *this;
  336.         }
  337.  
  338.         template <typename U> constexpr auto operator *= (const U c) noexcept
  339.         {
  340.             m11 *= c; m12 *= c; m13 *= c; m14 *= c;
  341.             m21 *= c; m22 *= c; m23 *= c; m24 *= c;
  342.             m31 *= c; m32 *= c; m33 *= c; m34 *= c;
  343.             m41 *= c; m42 *= c; m43 *= c; m44 *= c;
  344.             return *this;
  345.         }
  346.  
  347.         template <typename U> constexpr auto operator /= (const U c) noexcept
  348.         {
  349.             m11 /= c; m12 /= c; m13 /= c; m14 /= c;
  350.             m21 /= c; m22 /= c; m23 /= c; m24 /= c;
  351.             m31 /= c; m32 /= c; m33 /= c; m34 /= c;
  352.             m41 /= c; m42 /= c; m43 /= c; m44 /= c;
  353.             return *this;
  354.         }
  355.  
  356.         template <typename U> constexpr auto Rotate(U angleInDegrees, U x, U y, U z) noexcept
  357.         {
  358.             return *this *= MakeRotation((T)angleInDegrees, (T)x, (T)y, (T)z);
  359.         }
  360.  
  361.         template <typename U> constexpr auto Scale(U x, U y, U z) noexcept
  362.         {
  363.             return *this *= MakeScaling((T)x, (T)y, (T)z);
  364.         }
  365.  
  366.         template <typename U> constexpr auto Translate(U x, U y, U z) noexcept
  367.         {
  368.             return *this *= MakeTranslation((T)x, (T)y, (T)z);
  369.         }
  370.  
  371.         template <typename U> constexpr auto Ortho(U left, U right, U bottom, U top, U near_value, U far_value) noexcept
  372.         {
  373.             return *this *= MakeOrtho((T)left, (T)right, (T)bottom, (T)top, (T)near_value, (T)far_value);
  374.         }
  375.  
  376.         template <typename U> constexpr auto Ortho2D(U left, U right, U bottom, U top) noexcept
  377.         {
  378.             return *this *= MakeOrtho2D((T)left, (T)right, (T)bottom, (T)top);
  379.         }
  380.  
  381.         template <typename U> constexpr auto Frustum(U left, U right, U bottom, U top, U near_value, U far_value) noexcept
  382.         {
  383.             return *this *= MakeFrustum((T)left, (T)right, (T)bottom, (T)top, (T)near_value, (T)far_value);
  384.         }
  385.  
  386.         template <typename U> constexpr auto Perspective(U angleInDegrees, U aspect, U near_value, U far_value) noexcept
  387.         {
  388.             return *this *= MakePerspective((T)angleInDegrees, (T)aspect, (T)near_value, (T)far_value);
  389.         }
  390.  
  391.         template <typename U> constexpr auto PerspectiveX(U angleInDegrees, U aspect, U near_value, U far_value) noexcept
  392.         {
  393.             return *this *= MakePerspectiveX((T)angleInDegrees, (T)aspect, (T)near_value, (T)far_value);
  394.         }
  395.        
  396.         template <typename U> constexpr auto PerspectiveY(U angleInDegrees, U aspect, U near_value, U far_value) noexcept
  397.         {
  398.             return *this *= MakePerspectiveY((T)angleInDegrees, (T)aspect, (T)near_value, (T)far_value);
  399.         }
  400.  
  401.         template <typename U> constexpr auto LookAt(TVector3<U> eye, TVector3<U> center, TVector3<U> up) noexcept
  402.         {
  403.             return *this *= MakeLookAt((TVector3<T>)eye, (TVector3<T>)center, (TVector3<T>)up);
  404.         }
  405.  
  406.         constexpr auto ShadowBias() noexcept
  407.         {
  408.             return *this *= MakeShadowBias();
  409.         }
  410.        
  411.         constexpr auto CubeMatrix(int face) noexcept
  412.         {
  413.             return *this *= MakeCubeMatrix(face);
  414.         }
  415.  
  416.         constexpr auto CubeMatrixPosition(int face, const TVector3<T> & position) noexcept
  417.         {
  418.             return *this *= MakeCubeMatrixPosition(face, position);
  419.         }
  420.  
  421.         constexpr auto AsTranspose() const noexcept
  422.         {
  423.             return TMatrix4<T>(
  424.                 t11, t12, t13, t14,
  425.                 t21, t22, t23, t24,
  426.                 t31, t32, t33, t34,
  427.                 t41, t42, t43, t44
  428.             );
  429.         }
  430.  
  431.         constexpr auto Transpose() noexcept
  432.         {
  433.             return *this = AsTranspose();
  434.         }
  435.  
  436.         constexpr auto AsAdjugate() const noexcept
  437.         {
  438.             T t1 = m32 * m43 - m33 * m42;
  439.             T t2 = m32 * m44 - m34 * m42;
  440.             T t3 = m33 * m44 - m34 * m43;
  441.             T t4 = m22 * m43 - m23 * m42;
  442.             T t5 = m22 * m44 - m24 * m42;
  443.             T t6 = m23 * m44 - m24 * m43;
  444.             T t7 = m22 * m33 - m23 * m32;
  445.             T t8 = m22 * m34 - m24 * m32;
  446.             T t9 = m23 * m34 - m24 * m33;
  447.             T t10 = m31 * m43 - m33 * m41;
  448.             T t11 = m31 * m44 - m34 * m41;
  449.             T t12 = m21 * m43 - m23 * m41;
  450.             T t13 = m21 * m44 - m24 * m41;
  451.             T t14 = m21 * m33 - m23 * m31;
  452.             T t15 = m21 * m34 - m24 * m31;
  453.             T t16 = m31 * m42 - m32 * m41;
  454.             T t17 = m21 * m42 - m22 * m41;
  455.             T t18 = m21 * m32 - m22 * m31;
  456.  
  457.             return TMatrix4<T>(m22 * t3 - m23 * t2 + m24 * t1,
  458.                 -m12 * t3 + m13 * t2 - m14 * t1,
  459.                 m12 * t6 - m13 * t5 + m14 * t4,
  460.                 -m12 * t9 + m13 * t8 - m14 * t7,
  461.                 -m21 * t3 + m23 * t11 - m24 * t10,
  462.                 m11 * t3 - m13 * t11 + m14 * t10,
  463.                 -m11 * t6 + m13 * t13 - m14 * t12,
  464.                 m11 * t9 - m13 * t15 + m14 * t14,
  465.                 m21 * t2 - m22 * t11 + m24 * t16,
  466.                 -m11 * t2 + m12 * t11 - m14 * t16,
  467.                 m11 * t5 - m12 * t13 + m14 * t17,
  468.                 -m11 * t8 + m12 * t15 - m14 * t18,
  469.                 -m21 * t1 + m22 * t10 - m23 * t16,
  470.                 m11 * t1 - m12 * t10 + m13 * t16,
  471.                 -m11 * t4 + m12 * t12 - m13 * t17,
  472.                 m11 * t7 - m12 * t14 + m13 * t18);
  473.         }
  474.        
  475.         constexpr auto Adjugate() noexcept
  476.         {
  477.             return *this = AsAdjugate();
  478.         }
  479.  
  480.         constexpr auto AsQuickInverse() const noexcept
  481.         {
  482.             return TMatrix4<T>(
  483.                 t11, t12, t13, -m14,
  484.                 t21, t22, t23, -m24,
  485.                 t31, t32, t33, -m34,
  486.                 T(0), T(0), T(0), T(1)
  487.                 );
  488.         }
  489.  
  490.         constexpr auto QuickInvert() noexcept
  491.         {
  492.             if (Invertible())
  493.                 return *this = AsQuickInverse();
  494.             return *this = MakeZero();
  495.         }
  496.  
  497.         constexpr auto AsInverse() const noexcept
  498.         {
  499.             T t1 = m32 * m43 - m33 * m42;
  500.             T t2 = m32 * m44 - m34 * m42;
  501.             T t3 = m33 * m44 - m34 * m43;
  502.             T t4 = m22 * t3 - m23 * t2 + m24 * t1;
  503.             T t5 = m31 * m42 - m32 * m41;
  504.             T t6 = m31 * m43 - m33 * m41;
  505.             T t7 = -m21 * t1 + m22 * t6 - m23 * t5;
  506.             T t8 = m31 * m44 - m34 * m41;
  507.             T t9 = m21 * t2 - m22 * t8 + m24 * t5;
  508.             T t10 = -m21 * t3 + m23 * t8 - m24 * t6;
  509.             T t11 = static_cast<T>(1.0 / (m11 * t4 + m12 * t10 + m13 * t9 + m14 * t7));
  510.             T t12 = m22 * m43 - m23 * m42;
  511.             T t13 = m22 * m44 - m24 * m42;
  512.             T t14 = m23 * m44 - m24 * m43;
  513.             T t15 = m22 * m33 - m23 * m32;
  514.             T t16 = m22 * m34 - m24 * m32;
  515.             T t17 = m23 * m34 - m24 * m33;
  516.             T t18 = m21 * m43 - m23 * m41;
  517.             T t19 = m21 * m44 - m24 * m41;
  518.             T t20 = m21 * m33 - m23 * m31;
  519.             T t21 = m21 * m34 - m24 * m31;
  520.             T t22 = m21 * m42 - m22 * m41;
  521.             T t23 = m21 * m32 - m22 * m31;
  522.  
  523.             return TMatrix4<T>(
  524.                 t4 * t11,
  525.                 (-m12 * t3 + m13 * t2 - m14 * t1) * t11,
  526.                 (m12 * t14 - m13 * t13 + m14 * t12) * t11,
  527.                 (-m12 * t17 + m13 * t16 - m14 * t15) * t11,
  528.                 t10 * t11,
  529.                 (m11 * t3 - m13 * t8 + m14 * t6) * t11,
  530.                 (-m11 * t14 + m13 * t19 - m14 * t18) * t11,
  531.                 (m11 * t17 - m13 * t21 + m14 * t20) * t11,
  532.                 t9 * t11,
  533.                 (-m11 * t2 + m12 * t8 - m14 * t5) * t11,
  534.                 (m11 * t13 - m12 * t19 + m14 * t22) * t11,
  535.                 (-m11 * t16 + m12 * t21 - m14 * t23) * t11,
  536.                 t7 * t11,
  537.                 (m11 * t1 - m12 * t6 + m13 * t5) * t11,
  538.                 (-m11 * t12 + m12 * t18 - m13 * t22) * t11,
  539.                 (m11 * t15 - m12 * t20 + m13 * t23) * t11
  540.                 );
  541.         }
  542.  
  543.         constexpr auto Invert() noexcept
  544.         {
  545.             if (Invertible())
  546.                 return *this = AsInverse();
  547.             return *this = MakeZero();
  548.         }
  549.  
  550.         constexpr bool Invertible() const noexcept
  551.         {
  552.             return Determinant() != 0;
  553.         }
  554.  
  555.         constexpr T Determinant() const noexcept
  556.         {
  557.             T t1 = m31 * m42 - m32 * m41;
  558.             T t2 = m31 * m43 - m33 * m41;
  559.             T t3 = m32 * m43 - m33 * m42;
  560.             T t4 = m31 * m44 - m34 * m41;
  561.             T t5 = m32 * m44 - m34 * m42;
  562.             T t6 = m33 * m44 - m34 * m43;
  563.             return
  564.                 m11 * (m22 * t6 - m23 * t5 + m24 * t3) -
  565.                 m12 * (m21 * t6 - m23 * t4 + m24 * t2) +
  566.                 m13 * (m21 * t5 - m22 * t4 + m24 * t1) -
  567.                 m14 * (m21 * t3 - m22 * t2 + m23 * t1);
  568.         }
  569.  
  570.  
  571.         ///////////////////////////////////////////////////////////////
  572.         // S T A T I C   M E M B E R S ////////////////////////////////
  573.         ///////////////////////////////////////////////////////////////
  574.  
  575.         static constexpr auto MakeIdentity() noexcept
  576.         {
  577.             return TMatrix4<T>(
  578.                 1, 0, 0, 0,
  579.                 0, 1, 0, 0,
  580.                 0, 0, 1, 0,
  581.                 0, 0, 0, 1
  582.                 );
  583.         }
  584.  
  585.         static constexpr auto MakeZero() noexcept
  586.         {
  587.             return TMatrix4<T>(
  588.                 0, 0, 0, 0,
  589.                 0, 0, 0, 0,
  590.                 0, 0, 0, 0,
  591.                 0, 0, 0, 0
  592.                 );
  593.         }
  594.  
  595.         static constexpr auto MakeRotation(T angleInDegrees, T x, T y, T z) noexcept
  596.         {
  597.             T angleInRadians = static_cast<T>(angleInDegrees * FX_DEGREES_TO_RADIANS);
  598.             T c = cos(angleInRadians);
  599.             T s = sin(angleInRadians);
  600.             T invLength = (T)(1.0 / sqrt(x*x + y*y + z*z));
  601.             x *= invLength;
  602.             y *= invLength;
  603.             z *= invLength;
  604.  
  605.             return TMatrix4<T>(
  606.                 x * x * (1 - c) + c, x * y * (1 - c) - z * s, x * z * (1 - c) + y * s, 0.0,
  607.                 y * x * (1 - c) + z * s, y * y * (1 - c) + c, y * z * (1 - c) - x * s, 0.0,
  608.                 x * z * (1 - c) - y * s, y * z * (1 - c) + x * s, z * z * (1 - c) + c, 0.0,
  609.                 0.0, 0.0, 0.0, 1.0
  610.                 );
  611.         }
  612.  
  613.         static constexpr auto MakeScaling(T x, T y, T z) noexcept
  614.         {
  615.             return TMatrix4<T>(
  616.                 x, 0, 0, 0,
  617.                 0, y, 0, 0,
  618.                 0, 0, z, 0,
  619.                 0, 0, 0, 1
  620.                 );
  621.         }
  622.  
  623.         static constexpr auto MakeTranslation(T x, T y, T z) noexcept
  624.         {
  625.             return TMatrix4<T>(
  626.                 1, 0, 0, x,
  627.                 0, 1, 0, y,
  628.                 0, 0, 1, z,
  629.                 0, 0, 0, 1
  630.                 );
  631.         }
  632.  
  633.         static constexpr auto MakeOrtho(T left, T right, T bottom, T top, T near_value, T far_value) noexcept
  634.         {
  635.             T tx = -(right + left) / (right - left);
  636.             T ty = -(top + bottom) / (top - bottom);
  637.             T tz = -(far_value + near_value) / (far_value - near_value);
  638.  
  639.             return TMatrix4<double>(
  640.                 2 / (right - left), 0, 0, tx,
  641.                 0, 2 / (top - bottom), 0, ty,
  642.                 0, 0, -2 / (far_value - near_value), tz,
  643.                 0, 0, 0, 1
  644.                 );
  645.         }
  646.  
  647.         static constexpr auto MakeOrtho2D(T left, T right, T bottom, T top) noexcept
  648.         {
  649.             T tx = -(right + left) / (right - left);
  650.             T ty = -(top + bottom) / (top - bottom);
  651.  
  652.             return TMatrix4<T>(
  653.                 2 / (right - left), 0, 0, tx,
  654.                 0, 2 / (top - bottom), 0, ty,
  655.                 0, 0, -1, 0,
  656.                 0, 0, 0, 1
  657.                 );
  658.         }
  659.  
  660.         static constexpr auto MakeFrustum(T left, T right, T bottom, T top, T near_value, T far_value) noexcept
  661.         {
  662.             T A = (right + left) / (right - left);
  663.             T B = (top + bottom) / (top - bottom);
  664.             T C = -(far_value + near_value) / (far_value - near_value);
  665.             T D = -2 * far_value * near_value / (far_value - near_value);
  666.  
  667.             return TMatrix4<T>(
  668.                 2 * near_value / (right - left), 0, A, 0,
  669.                 0, 2 * near_value / (top - bottom), B, 0,
  670.                 0, 0, C, D,
  671.                 0, 0, -1, 0
  672.                 );
  673.         }
  674.  
  675.         static constexpr auto MakePerspective(T angleInDegrees, T aspect, T near_value, T far_value) noexcept
  676.         {
  677.             T f = static_cast<T>(1.0 / std::tan(FX_DEGREES_TO_RADIANS * 0.5 * angleInDegrees));
  678.  
  679.             return TMatrix4<T>(
  680.                 f / aspect, 0, 0, 0,
  681.                 0, f, 0, 0,
  682.                 0, 0, (far_value + near_value) / (near_value - far_value), 2 * far_value * near_value / (near_value - far_value),
  683.                 0, 0, -1, 0
  684.                 );
  685.         }
  686.  
  687.         static constexpr auto MakePerspectiveX(T angleInDegrees, T aspect, T near_value, T far_value) noexcept
  688.         {
  689.             T f = static_cast<T>(1.0 / std::tan(FX_DEGREES_TO_RADIANS * 0.5 * angleInDegrees));
  690.  
  691.             return TMatrix4<T>(
  692.                 f / aspect, 0, 0, 0,
  693.                 0, f, 0, 0,
  694.                 0, 0, (far_value + near_value) / (near_value - far_value), 2 * far_value * near_value / (near_value - far_value),
  695.                 0, 0, -1, 0
  696.                 );
  697.         }
  698.  
  699.         static constexpr auto MakePerspectiveY(T angleInDegrees, T aspect, T near_value, T far_value) noexcept
  700.         {
  701.             T f = static_cast<T>(1.0 / std::tan(FX_DEGREES_TO_RADIANS * 0.5 * angleInDegrees));
  702.  
  703.             return TMatrix4<T>(
  704.                 f, 0, 0, 0,
  705.                 0, f * aspect, 0, 0,
  706.                 0, 0, (far_value + near_value) / (near_value - far_value), 2 * far_value * near_value / (near_value - far_value),
  707.                 0, 0, -1, 0
  708.                 );
  709.         }
  710.  
  711.         static constexpr auto MakeLookAt(TVector3<T> eye, TVector3<T> center, TVector3<T> up) noexcept
  712.         {
  713.             TVector3<T> F = (center - eye).norm();
  714.             TVector3<T> S = F.cross(up).norm();
  715.             TVector3<T> U = S.cross(F).norm();
  716.  
  717.             return TMatrix4<T>::multiply(TMatrix4<T>(
  718.                 S.x, S.y, S.z, 0.0,
  719.                 U.x, U.y, U.z, 0.0,
  720.                 -F.x, -F.y, -F.z, 0.0,
  721.                 0.0, 0.0, 0.0, 1.0),
  722.                 TMatrix4<T>::MakeTranslation(-eye.x, -eye.y, -eye.z));
  723.         }
  724.  
  725.         static constexpr auto MakeShadowBias() noexcept
  726.         {
  727.             return TMatrix4<T>(
  728.                 0.5, 0.0, 0.0, 0.5,
  729.                 0.0, 0.5, 0.0, 0.5,
  730.                 0.0, 0.0, 0.5, 0.5,
  731.                 0.0, 0.0, 0.0, 1.0
  732.                 );
  733.         }
  734.  
  735.         static constexpr auto MakeCubeMatrix(int face) noexcept
  736.         {
  737.             // support GL_TEXTURE_CUBE_MAP_POSITIVE_X, ... constants
  738.             if (face >= 0x8515 && face <= 0x851A) face -= 0x8515;
  739.  
  740.             switch (face)
  741.             {
  742.             case 0: // GL_TEXTURE_CUBE_MAP_POSITIVE_X
  743.                 return TMatrix4<T>::MakeRotation(90.0, 0.0, 1.0, 0.0);
  744.                 break;
  745.             case 1: // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
  746.                 return TMatrix4<T>::MakeRotation(270.0, 0.0, 1.0, 0.0);
  747.                 break;
  748.             case 2: // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
  749.                 return TMatrix4<T>::MakeRotation(270.0, 1.0, 0.0, 0.0);
  750.                 break;
  751.             case 3: // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
  752.                 return TMatrix4<T>::MakeRotation(90.0, 1.0, 0.0, 0.0);
  753.                 break;
  754.             case 4: // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
  755.                 return TMatrix4<T>::MakeIdentity();
  756.                 break;
  757.             case 5: // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
  758.                 return TMatrix4<T>::MakeRotation(180.0, 0.0, 1.0, 0.0);
  759.                 break;
  760.             }
  761.             return TMatrix4<T>::MakeIdentity();
  762.         }
  763.  
  764.         static constexpr TMatrix4<T> MakeCubeMatrixPosition(int face, const TVector3<T> & position) noexcept
  765.         {
  766.             // support GL_TEXTURE_CUBE_MAP_POSITIVE_X, ... constants
  767.             if (face >= 0x8515 && face <= 0x851A) face -= 0x8515;
  768.  
  769.             switch (face)
  770.             {
  771.             case 0: // GL_TEXTURE_CUBE_MAP_POSITIVE_X
  772.                 return TMatrix4<T>::MakeLookAt(position, position + TVector3<T>(1, 0, 0), TVector3<T>(0, -1, 0));
  773.                 break;
  774.             case 1: // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
  775.                 return TMatrix4<T>::MakeLookAt(position, position + TVector3<T>(-1, 0, 0), TVector3<T>(0, -1, 0));
  776.                 break;
  777.             case 2: // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
  778.                 return TMatrix4<T>::MakeLookAt(position, position + TVector3<T>(0, 1, 0), TVector3<T>(0, 0, 1));
  779.                 break;
  780.             case 3: // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
  781.                 return TMatrix4<T>::MakeLookAt(position, position + TVector3<T>(0, -1, 0), TVector3<T>(0, 0, -1));
  782.                 break;
  783.             case 4: // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
  784.                 return TMatrix4<T>::MakeLookAt(position, position + TVector3<T>(0, 0, 1), TVector3<T>(0, -1, 0));
  785.                 break;
  786.             case 5: // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
  787.                 return TMatrix4<T>::MakeLookAt(position, position + TVector3<T>(0, 0, -1), TVector3<T>(0, -1, 0));
  788.                 break;
  789.             }
  790.             return TMatrix4<T>::MakeIdentity();
  791.         }
  792.  
  793.     };
  794.    
  795.     //////////////////////////////////////////////////////////////////
  796.     // I M P L E M E N T A T I O N ///////////////////////////////////
  797.     //////////////////////////////////////////////////////////////////
  798.     //template <typename T>
  799.     //TMatrix4<T>::TMatrix4()
  800.     //{
  801.     //  m11 = 1; m12 = 0; m13 = 0; m14 = 0;
  802.     //  m21 = 0; m22 = 1; m23 = 0; m24 = 0;
  803.     //  m31 = 0; m32 = 0; m33 = 1; m34 = 0;
  804.     //  m41 = 0; m42 = 0; m43 = 0; m44 = 1;
  805.     //}
  806.     //
  807.     //template <typename T>
  808.     //TMatrix4<T>::TMatrix4(
  809.     //  const T a11, const T a12, const T a13, const T a14,
  810.     //  const T a21, const T a22, const T a23, const T a24,
  811.     //  const T a31, const T a32, const T a33, const T a34,
  812.     //  const T a41, const T a42, const T a43, const T a44
  813.     //  )
  814.     //{
  815.     //  m11 = a11; m12 = a12; m13 = a13; m14 = a14;
  816.     //  m21 = a21; m22 = a22; m23 = a23; m24 = a24;
  817.     //  m31 = a31; m32 = a32; m33 = a33; m34 = a34;
  818.     //  m41 = a41; m42 = a42; m43 = a43; m44 = a44;
  819.     //}
  820.  
  821.     //template <typename T>
  822.     //TMatrix4<T>::TMatrix4(const TMatrix4<T> & M)
  823.     //{
  824.     //  m11 = M.m11; m12 = M.m12; m13 = M.m13; m14 = M.m14;
  825.     //  m21 = M.m21; m22 = M.m22; m23 = M.m23; m24 = M.m24;
  826.     //  m31 = M.m31; m32 = M.m32; m33 = M.m33; m34 = M.m34;
  827.     //  m41 = M.m41; m42 = M.m42; m43 = M.m43; m44 = M.m44;
  828.     //}
  829.     //
  830.     //template <typename T>
  831.     //TMatrix4<T>::TMatrix4(const T M[4][4])
  832.     //{
  833.     //  for (int i = 0; i < 4; i++)
  834.     //  {
  835.     //      for (int j = 0; j < 4; j++)
  836.     //      {
  837.     //          mm[i][j] = M[j][i];
  838.     //      }
  839.     //  }
  840.     //}
  841.     //
  842.     //template <typename T>
  843.     //TMatrix4<T>::TMatrix4(const T M[16])
  844.     //{
  845.     //  for (int i = 0; i < 16; i++)
  846.     //  {
  847.     //      m[i] = M[i];
  848.     //  }
  849.     //}
  850.     //
  851.     //template <typename T>
  852.     //template <typename U>
  853.     //const TMatrix4<T> & TMatrix4<T>::operator = (const TMatrix4<U> & M)
  854.     //{
  855.     //  m11 = T(M.m11); m12 = T(M.m12); m13 = T(M.m13); m14 = T(M.m14);
  856.     //  m21 = T(M.m21); m22 = T(M.m22); m23 = T(M.m23); m24 = T(M.m24);
  857.     //  m31 = T(M.m31); m32 = T(M.m32); m33 = T(M.m33); m34 = T(M.m34);
  858.     //  m41 = T(M.m41); m42 = T(M.m42); m43 = T(M.m43); m44 = T(M.m44);
  859.     //  return *this;
  860.     //}
  861.  
  862.     //
  863.     //template <typename T>
  864.     //const TMatrix4<T> & TMatrix4<T>::LoadIdentity()
  865.     //{
  866.     //  m11 = 1; m12 = 0; m13 = 0; m14 = 0;
  867.     //  m21 = 0; m22 = 1; m23 = 0; m24 = 0;
  868.     //  m31 = 0; m32 = 0; m33 = 1; m34 = 0;
  869.     //  m41 = 0; m42 = 0; m43 = 0; m44 = 1;
  870.  
  871.     //  return *this;
  872.     //}
  873.  
  874.     //template <typename T>
  875.     //template <typename U>
  876.     //const TMatrix4<T> TMatrix4<T>::multiply(const TMatrix4<U> &M) const
  877.     //{
  878.     //  return TMatrix4<T>(
  879.     //      (T)(m14*M.m41 + m13*M.m31 + m12*M.m21 + m11*M.m11),
  880.     //      (T)(m14*M.m42 + m13*M.m32 + m12*M.m22 + m11*M.m12),
  881.     //      (T)(m14*M.m43 + m13*M.m33 + m12*M.m23 + m11*M.m13),
  882.     //      (T)(m14*M.m44 + m13*M.m34 + m12*M.m24 + m11*M.m14),
  883.  
  884.     //      (T)(m24*M.m41 + m23*M.m31 + m22*M.m21 + m21*M.m11),
  885.     //      (T)(m24*M.m42 + m23*M.m32 + m22*M.m22 + m21*M.m12),
  886.     //      (T)(m24*M.m43 + m23*M.m33 + m22*M.m23 + m21*M.m13),
  887.     //      (T)(m24*M.m44 + m23*M.m34 + m22*M.m24 + m21*M.m14),
  888.  
  889.     //      (T)(m34*M.m41 + m33*M.m31 + m32*M.m21 + m31*M.m11),
  890.     //      (T)(m34*M.m42 + m33*M.m32 + m32*M.m22 + m31*M.m12),
  891.     //      (T)(m34*M.m43 + m33*M.m33 + m32*M.m23 + m31*M.m13),
  892.     //      (T)(m34*M.m44 + m33*M.m34 + m32*M.m24 + m31*M.m14),
  893.  
  894.     //      (T)(m44*M.m41 + m43*M.m31 + m42*M.m21 + m41*M.m11),
  895.     //      (T)(m44*M.m42 + m43*M.m32 + m42*M.m22 + m41*M.m12),
  896.     //      (T)(m44*M.m43 + m43*M.m33 + m42*M.m23 + m41*M.m13),
  897.     //      (T)(m44*M.m44 + m43*M.m34 + m42*M.m24 + m41*M.m14));
  898.     //}
  899.  
  900.     //template <typename T>
  901.     //template <typename U>
  902.     //const TMatrix4<T> TMatrix4<T>::compMult(const TMatrix4<U> &m) const
  903.     //{
  904.     //  return TMatrix4<T>(
  905.     //      m11 * m.m11, m12 * m.m12, m13 * m.m13, m14 * m.m14,
  906.     //      m21 * m.m21, m22 * m.m22, m23 * m.m23, m24 * m.m24,
  907.     //      m31 * m.m31, m32 * m.m32, m33 * m.m33, m34 * m.m34,
  908.     //      m41 * m.m41, m42 * m.m42, m43 * m.m43, m44 * m.m44
  909.     //      );
  910.     //}
  911.  
  912.     //template<typename T>
  913.     //template<typename U>
  914.     //inline TMatrix4<T> TMatrix4<T>::multiply(TMatrix4<T> m1, TMatrix4<U> m2)
  915.     //{
  916.     //  return TMatrix4<T>(
  917.     //      (T)(m1.m14*m2.m41 + m1.m13*m2.m31 + m1.m12*m2.m21 + m1.m11*m2.m11),
  918.     //      (T)(m1.m14*m2.m42 + m1.m13*m2.m32 + m1.m12*m2.m22 + m1.m11*m2.m12),
  919.     //      (T)(m1.m14*m2.m43 + m1.m13*m2.m33 + m1.m12*m2.m23 + m1.m11*m2.m13),
  920.     //      (T)(m1.m14*m2.m44 + m1.m13*m2.m34 + m1.m12*m2.m24 + m1.m11*m2.m14),
  921.  
  922.     //      (T)(m1.m24*m2.m41 + m1.m23*m2.m31 + m1.m22*m2.m21 + m1.m21*m2.m11),
  923.     //      (T)(m1.m24*m2.m42 + m1.m23*m2.m32 + m1.m22*m2.m22 + m1.m21*m2.m12),
  924.     //      (T)(m1.m24*m2.m43 + m1.m23*m2.m33 + m1.m22*m2.m23 + m1.m21*m2.m13),
  925.     //      (T)(m1.m24*m2.m44 + m1.m23*m2.m34 + m1.m22*m2.m24 + m1.m21*m2.m14),
  926.  
  927.     //      (T)(m1.m34*m2.m41 + m1.m33*m2.m31 + m1.m32*m2.m21 + m1.m31*m2.m11),
  928.     //      (T)(m1.m34*m2.m42 + m1.m33*m2.m32 + m1.m32*m2.m22 + m1.m31*m2.m12),
  929.     //      (T)(m1.m34*m2.m43 + m1.m33*m2.m33 + m1.m32*m2.m23 + m1.m31*m2.m13),
  930.     //      (T)(m1.m34*m2.m44 + m1.m33*m2.m34 + m1.m32*m2.m24 + m1.m31*m2.m14),
  931.  
  932.     //      (T)(m1.m44*m2.m41 + m1.m43*m2.m31 + m1.m42*m2.m21 + m1.m41*m2.m11),
  933.     //      (T)(m1.m44*m2.m42 + m1.m43*m2.m32 + m1.m42*m2.m22 + m1.m41*m2.m12),
  934.     //      (T)(m1.m44*m2.m43 + m1.m43*m2.m33 + m1.m42*m2.m23 + m1.m41*m2.m13),
  935.     //      (T)(m1.m44*m2.m44 + m1.m43*m2.m34 + m1.m42*m2.m24 + m1.m41*m2.m14));
  936.     //}
  937.     //
  938.     //template <typename T>
  939.     //template <typename U>
  940.     //const TMatrix4<T> & TMatrix4<T>::MultMatrix(const TMatrix4<U> & M)
  941.     //{
  942.     //  return *this = multiply(M);
  943.     //}
  944.     //
  945.     //template <typename T>
  946.     //template <typename U>
  947.     //const TMatrix4<T> & TMatrix4<T>::operator *= (const TMatrix4<U> & M)
  948.     //{
  949.     //  return *this = multiply(M);
  950.     //}
  951.     //
  952.     //template <typename T>
  953.     //template <typename U>
  954.     //const TMatrix4<T> & TMatrix4<T>::operator += (const TMatrix4<U> & M)
  955.     //{
  956.     //  m11 += M.m11; m12 += M.m12; m13 += M.m13; m14 += M.m14;
  957.     //  m21 += M.m21; m22 += M.m22; m23 += M.m23; m24 += M.m24;
  958.     //  m31 += M.m31; m32 += M.m32; m33 += M.m33; m34 += M.m34;
  959.     //  m41 += M.m41; m42 += M.m42; m43 += M.m43; m44 += M.m44;
  960.     //  return *this;
  961.     //}
  962.     //
  963.     //template <typename T>
  964.     //template <typename U>
  965.     //const TMatrix4<T> & TMatrix4<T>::operator -= (const TMatrix4<U> & M)
  966.     //{
  967.     //  m11 -= M.m11; m12 -= M.m12; m13 -= M.m13; m14 -= M.m14;
  968.     //  m21 -= M.m21; m22 -= M.m22; m23 -= M.m23; m24 -= M.m24;
  969.     //  m31 -= M.m31; m32 -= M.m32; m33 -= M.m33; m34 -= M.m34;
  970.     //  m41 -= M.m41; m42 -= M.m42; m43 -= M.m43; m44 -= M.m44;
  971.     //  return *this;
  972.     //}
  973.  
  974.     //template <typename T>
  975.     //template <typename U>
  976.     //const TMatrix4<T> TMatrix4<T>::operator * (const TMatrix4<U> & M) const
  977.     //{
  978.     //  return multiply(M);
  979.     //}
  980.     //
  981.     //template <typename T>
  982.     //template <typename U>
  983.     //const TMatrix4<T> TMatrix4<T>::operator + (const TMatrix4<U> & M) const
  984.     //{
  985.     //  return TMatrix4<T>(
  986.     //      m11 + M.m11, m12 + M.m12, m13 + M.m13, m14 + M.m14,
  987.     //      m21 + M.m21, m22 + M.m22, m23 + M.m23, m24 + M.m24,
  988.     //      m31 + M.m31, m32 + M.m32, m33 + M.m33, m34 + M.m34,
  989.     //      m41 + M.m41, m42 + M.m42, m43 + M.m43, m44 + M.m44
  990.     //  );
  991.     //}
  992.     //
  993.     //template <typename T>
  994.     //template <typename U>
  995.     //const TMatrix4<T> TMatrix4<T>::operator - (const TMatrix4<U> & M) const
  996.     //{
  997.     //  return TMatrix4<T>(
  998.     //      m11 - M.m11, m12 - M.m12, m13 - M.m13, m14 - M.m14,
  999.     //      m21 - M.m21, m22 - M.m22, m23 - M.m23, m24 - M.m24,
  1000.     //      m31 - M.m31, m32 - M.m32, m33 - M.m33, m34 - M.m34,
  1001.     //      m41 - M.m41, m42 - M.m42, m43 - M.m43, m44 - M.m44
  1002.     //      );
  1003.     //}
  1004.     //
  1005.     //template <typename T>
  1006.     //template <typename U>
  1007.     //const TMatrix4<T> & TMatrix4<T>::operator *= (const U X)
  1008.     //{
  1009.     //  for (int i = 0; i < 16; i++)
  1010.     //      m[i] *= X;
  1011.     //  return *this;
  1012.     //}
  1013.     //
  1014.     //template <typename T>
  1015.     //template <typename U>
  1016.     //const TMatrix4<T> & TMatrix4<T>::operator /= (const U X)
  1017.     //{
  1018.     //  for (int i = 0; i < 16; i++)
  1019.     //      m[i] /= X;
  1020.     //  return *this;
  1021.     //}
  1022.  
  1023.  
  1024.     //template <typename T>
  1025.     //const TMatrix4<T> & TMatrix4<T>::Rotate(double angleInDegrees, double X, double y, double z)
  1026.     //{
  1027.     //  return MultMatrix(TMatrix4<double>::MakeRotation(angleInDegrees, X, y, z));
  1028.     //}
  1029.  
  1030.  
  1031.     //template <typename T>
  1032.     //const TMatrix4<T> & TMatrix4<T>::Scale(double X, double y, double z)
  1033.     //{
  1034.     //  return MultMatrix(TMatrix4<double>::MakeScaling(X, y, z));
  1035.     //}
  1036.     //
  1037.  
  1038.     //template <typename T>
  1039.     //const TMatrix4<T> & TMatrix4<T>::Translate(double X, double y, double z)
  1040.     //{
  1041.     //  return MultMatrix(TMatrix4<double>::MakeTranslation(X, y, z));
  1042.     //}
  1043.     //
  1044.  
  1045.     //template <typename T>
  1046.     //const TMatrix4<T> & TMatrix4<T>::Ortho(double left, double right, double bottom, double top, double near_value, double far_value)
  1047.     //{
  1048.     //  return MultMatrix(TMatrix4<double>::MakeOrtho(left, right, bottom, top, near_value, far_value));
  1049.     //}
  1050.     //
  1051.  
  1052.     //template <typename T>
  1053.     //const TMatrix4<T> &  TMatrix4<T>::Ortho2D(double left, double right, double bottom, double top)
  1054.     //{
  1055.     //  return MultMatrix(TMatrix4<double>::MakeOrtho2D(left, right, bottom, top));
  1056.     //}
  1057.     //
  1058.  
  1059.     //template <typename T>
  1060.     //const TMatrix4<T> & TMatrix4<T>::Frustum(double left, double right, double bottom, double top, double near_value, double far_value)
  1061.     //{
  1062.     //  return MultMatrix(TMatrix4<double>::MakeFrustum(left, right, bottom, top, near_value, far_value));
  1063.     //}
  1064.     //
  1065.  
  1066.     //template <typename T>
  1067.     //const TMatrix4<T> & TMatrix4<T>::Perspective(double angleInDegrees, double aspect, double near_value, double far_value)
  1068.     //{
  1069.     //  return MultMatrix(TMatrix4<double>::MakePerspective(angleInDegrees, aspect, near_value, far_value));
  1070.     //}
  1071.  
  1072.  
  1073.     //template <typename T>
  1074.     //const TMatrix4<T> & TMatrix4<T>::PerspectiveX(double angleInDegrees, double aspect, double near_value, double far_value)
  1075.     //{
  1076.     //  return MultMatrix(TMatrix4<double>::MakePerspectiveX(angleInDegrees, aspect, near_value, far_value));
  1077.     //}
  1078.  
  1079.     //template <typename T>
  1080.     //const TMatrix4<T> & TMatrix4<T>::PerspectiveY(double angleInDegrees, double aspect, double near_value, double far_value)
  1081.     //{
  1082.     //  return MultMatrix(TMatrix4<double>::MakePerspectiveY(angleInDegrees, aspect, near_value, far_value));
  1083.     //}
  1084.  
  1085.     //template <typename T>
  1086.     //const TMatrix4<T> &TMatrix4<T>::LookAt(TVector3<double> eye, TVector3<double> center, TVector3<double> up)
  1087.     //{
  1088.     //  return MultMatrix(TMatrix4<double>::MakeLookAt(eye, center, up));
  1089.     //}
  1090.  
  1091.     //template <typename T>
  1092.     //const TMatrix4<T> & TMatrix4<T>::ShadowBias()
  1093.     //{
  1094.     //  return MultMatrix(TMatrix4<double>::MakeShadowBias());
  1095.     //}
  1096.  
  1097.  
  1098.     //template <typename T>
  1099.     //const TMatrix4<T> &TMatrix4<T>::CubeMatrix(int face)
  1100.     //{
  1101.     //  return MultMatrix(TMatrix4<double>::MakeCubeMatrix(face));
  1102.     //}
  1103.  
  1104.  
  1105.     //template <typename T>
  1106.     //inline TMatrix4<T> & TMatrix4<T>::Transpose()
  1107.     //{
  1108.     //  return *this = AsTranspose();
  1109.     //}
  1110.  
  1111.     //template <typename T>
  1112.     //TMatrix4<T> TMatrix4<T>::AsTranspose() const
  1113.     //{
  1114.     //  return TMatrix4<T>(
  1115.     //      t11, t12, t13, t14,
  1116.     //      t21, t22, t23, t24,
  1117.     //      t31, t32, t33, t34,
  1118.     //      t41, t42, t43, t44
  1119.     //  );
  1120.     //}
  1121.  
  1122.     //template <typename T>
  1123.     //T TMatrix4<T>::Determinant() const
  1124.     //{
  1125.     //  T t1 = m31 * m42 - m32 * m41;
  1126.     //  T t2 = m31 * m43 - m33 * m41;
  1127.     //  T t3 = m32 * m43 - m33 * m42;
  1128.     //  T t4 = m31 * m44 - m34 * m41;
  1129.     //  T t5 = m32 * m44 - m34 * m42;
  1130.     //  T t6 = m33 * m44 - m34 * m43;
  1131.     //  return
  1132.     //      m11 * (m22 * t6 - m23 * t5 + m24 * t3) -
  1133.     //      m12 * (m21 * t6 - m23 * t4 + m24 * t2) +
  1134.     //      m13 * (m21 * t5 - m22 * t4 + m24 * t1) -
  1135.     //      m14 * (m21 * t3 - m22 * t2 + m23 * t1);
  1136.     //}
  1137.  
  1138.     //template <typename T>
  1139.     //TMatrix4<T> TMatrix4<T>::AsAdjugate() const
  1140.     //{
  1141.     //  T t1 = m32 * m43 - m33 * m42;
  1142.     //  T t2 = m32 * m44 - m34 * m42;
  1143.     //  T t3 = m33 * m44 - m34 * m43;
  1144.     //  T t4 = m22 * m43 - m23 * m42;
  1145.     //  T t5 = m22 * m44 - m24 * m42;
  1146.     //  T t6 = m23 * m44 - m24 * m43;
  1147.     //  T t7 = m22 * m33 - m23 * m32;
  1148.     //  T t8 = m22 * m34 - m24 * m32;
  1149.     //  T t9 = m23 * m34 - m24 * m33;
  1150.     //  T t10 = m31 * m43 - m33 * m41;
  1151.     //  T t11 = m31 * m44 - m34 * m41;
  1152.     //  T t12 = m21 * m43 - m23 * m41;
  1153.     //  T t13 = m21 * m44 - m24 * m41;
  1154.     //  T t14 = m21 * m33 - m23 * m31;
  1155.     //  T t15 = m21 * m34 - m24 * m31;
  1156.     //  T t16 = m31 * m42 - m32 * m41;
  1157.     //  T t17 = m21 * m42 - m22 * m41;
  1158.     //  T t18 = m21 * m32 - m22 * m31;
  1159.  
  1160.     //  return TMatrix4<T>(m22 * t3 - m23 * t2 + m24 * t1,
  1161.     //      -m12 * t3 + m13 * t2 - m14 * t1,
  1162.     //      m12 * t6 - m13 * t5 + m14 * t4,
  1163.     //      -m12 * t9 + m13 * t8 - m14 * t7,
  1164.     //      -m21 * t3 + m23 * t11 - m24 * t10,
  1165.     //      m11 * t3 - m13 * t11 + m14 * t10,
  1166.     //      -m11 * t6 + m13 * t13 - m14 * t12,
  1167.     //      m11 * t9 - m13 * t15 + m14 * t14,
  1168.     //      m21 * t2 - m22 * t11 + m24 * t16,
  1169.     //      -m11 * t2 + m12 * t11 - m14 * t16,
  1170.     //      m11 * t5 - m12 * t13 + m14 * t17,
  1171.     //      -m11 * t8 + m12 * t15 - m14 * t18,
  1172.     //      -m21 * t1 + m22 * t10 - m23 * t16,
  1173.     //      m11 * t1 - m12 * t10 + m13 * t16,
  1174.     //      -m11 * t4 + m12 * t12 - m13 * t17,
  1175.     //      m11 * t7 - m12 * t14 + m13 * t18);
  1176.     //}
  1177.     //
  1178.     //template <typename T>
  1179.     //TMatrix4<T> & TMatrix4<T>::Adjugate()
  1180.     //{
  1181.     //  return *this = AsAdjugate();
  1182.     //}
  1183.     //
  1184.     //template <typename T>
  1185.     //bool TMatrix4<T>::Invert()
  1186.     //{
  1187.     //  T det;
  1188.     // 
  1189.     //  det = Determinant();
  1190.     //  if (det == 0)
  1191.     //      return false;
  1192.  
  1193.     //  *this = AsInverse();
  1194.  
  1195.     //  return true;
  1196.     //}
  1197.  
  1198.     ////template <typename T>
  1199.     ////TMatrix4<T> TMatrix4<T>::QuickInverse() const
  1200.     ////{
  1201.     ////    return TMatrix4<T>(
  1202.     ////        t11, t12, t13, -m14,
  1203.     ////        t21, t22, t23, -m24,
  1204.     ////        t31, t32, t33, -m34,
  1205.     ////        T(0), T(0), T(0), T(1)
  1206.     ////        );
  1207.     ////}
  1208.  
  1209.  
  1210.     ////template <typename T>
  1211.     ////void TMatrix4<T>::QuickInvert()
  1212.     ////{
  1213.     ////    *this = QuickInverse();
  1214.     ////}
  1215.  
  1216.  
  1217.     //template <typename T>
  1218.     //TMatrix4<double> TMatrix4<T>::AsInverse() const
  1219.     //{
  1220.     //  double t1 = m32 * m43 - m33 * m42;
  1221.     //  double t2 = m32 * m44 - m34 * m42;
  1222.     //  double t3 = m33 * m44 - m34 * m43;
  1223.     //  double t4 = m22 * t3 - m23 * t2 + m24 * t1;
  1224.     //  double t5 = m31 * m42 - m32 * m41;
  1225.     //  double t6 = m31 * m43 - m33 * m41;
  1226.     //  double t7 = -m21 * t1 + m22 * t6 - m23 * t5;
  1227.     //  double t8 = m31 * m44 - m34 * m41;
  1228.     //  double t9 = m21 * t2 - m22 * t8 + m24 * t5;
  1229.     //  double t10 = -m21 * t3 + m23 * t8 - m24 * t6;
  1230.     //  double t11 = 1.0 / (m11 * t4 + m12 * t10 + m13 * t9 + m14 * t7);
  1231.     //  double t12 = m22 * m43 - m23 * m42;
  1232.     //  double t13 = m22 * m44 - m24 * m42;
  1233.     //  double t14 = m23 * m44 - m24 * m43;
  1234.     //  double t15 = m22 * m33 - m23 * m32;
  1235.     //  double t16 = m22 * m34 - m24 * m32;
  1236.     //  double t17 = m23 * m34 - m24 * m33;
  1237.     //  double t18 = m21 * m43 - m23 * m41;
  1238.     //  double t19 = m21 * m44 - m24 * m41;
  1239.     //  double t20 = m21 * m33 - m23 * m31;
  1240.     //  double t21 = m21 * m34 - m24 * m31;
  1241.     //  double t22 = m21 * m42 - m22 * m41;
  1242.     //  double t23 = m21 * m32 - m22 * m31;
  1243.  
  1244.     //  return TMatrix4<double>(
  1245.     //      t4 * t11,
  1246.     //      (-m12 * t3 + m13 * t2 - m14 * t1) * t11,
  1247.     //      (m12 * t14 - m13 * t13 + m14 * t12) * t11,
  1248.     //      (-m12 * t17 + m13 * t16 - m14 * t15) * t11,
  1249.     //      t10 * t11,
  1250.     //      (m11 * t3 - m13 * t8 + m14 * t6) * t11,
  1251.     //      (-m11 * t14 + m13 * t19 - m14 * t18) * t11,
  1252.     //      (m11 * t17 - m13 * t21 + m14 * t20) * t11,
  1253.     //      t9 * t11,
  1254.     //      (-m11 * t2 + m12 * t8 - m14 * t5) * t11,
  1255.     //      (m11 * t13 - m12 * t19 + m14 * t22) * t11,
  1256.     //      (-m11 * t16 + m12 * t21 - m14 * t23) * t11,
  1257.     //      t7 * t11,
  1258.     //      (m11 * t1 - m12 * t6 + m13 * t5) * t11,
  1259.     //      (-m11 * t12 + m12 * t18 - m13 * t22) * t11,
  1260.     //      (m11 * t15 - m12 * t20 + m13 * t23) * t11
  1261.     //      );
  1262.     //}
  1263.  
  1264.  
  1265.     //template <typename T>
  1266.     //TMatrix4<double> TMatrix4<T>::makeRotation(double angleInDegrees, double X, double y, double z)
  1267.     //{
  1268.     //  double angleInRadians = angleInDegrees * FX_DEGREES_TO_RADIANS;
  1269.     //  double c = cos(angleInRadians);
  1270.     //  double s = sin(angleInRadians);
  1271.     //  double invLength = 1.0 / sqrt(X*X + y*y + z*z);
  1272.     //  X *= invLength;
  1273.     //  y *= invLength;
  1274.     //  z *= invLength;
  1275.  
  1276.     //  return TMatrix4<double>(
  1277.     //      X * X * (1 - c) + c, X * y * (1 - c) - z * s, X * z * (1 - c) + y * s, 0.0,
  1278.     //      y * X * (1 - c) + z * s, y * y * (1 - c) + c, y * z * (1 - c) - X * s, 0.0,
  1279.     //      X * z * (1 - c) - y * s, y * z * (1 - c) + X * s, z * z * (1 - c) + c, 0.0,
  1280.     //      0.0, 0.0, 0.0, 1.0
  1281.     //      );
  1282.     //}
  1283.  
  1284.  
  1285.     //template <typename T>
  1286.     //TMatrix4<double> TMatrix4<T>::makeScale(double X, double y, double z)
  1287.     //{
  1288.     //  return TMatrix4<double>(
  1289.     //      X, 0.0, 0.0, 0.0,
  1290.     //      0.0, y, 1.0, 0.0,
  1291.     //      0.0, 0.0, z, 0.0,
  1292.     //      0.0, 0.0, 0.0, 1.0
  1293.     //      );
  1294.     //}
  1295.  
  1296.  
  1297.     //template <typename T>
  1298.     //TMatrix4<double> TMatrix4<T>::makeTranslation(double X, double y, double z)
  1299.     //{
  1300.     //  return TMatrix4<double>(
  1301.     //      0.0, 0.0, 0.0, X,
  1302.     //      0.0, 0.0, 1.0, y,
  1303.     //      0.0, 0.0, 0.0, z,
  1304.     //      0.0, 0.0, 0.0, 1.0
  1305.     //      );
  1306.     //}
  1307.  
  1308.  
  1309.     //template <typename T>
  1310.     //inline TMatrix4<double> TMatrix4<T>::MakeRotation(double angleInDegrees, double X, double y, double z)
  1311.     //{
  1312.     //  double angleInRadians = angleInDegrees * FX_DEGREES_TO_RADIANS;
  1313.     //  double c = cos(angleInRadians);
  1314.     //  double s = sin(angleInRadians);
  1315.     //  double invLength = 1.0 / sqrt(X*X + y*y + z*z);
  1316.     //  X *= invLength;
  1317.     //  y *= invLength;
  1318.     //  z *= invLength;
  1319.  
  1320.     //  return TMatrix4<double>(
  1321.     //      X * X * (1 - c) + c, X * y * (1 - c) - z * s, X * z * (1 - c) + y * s, 0.0,
  1322.     //      y * X * (1 - c) + z * s, y * y * (1 - c) + c, y * z * (1 - c) - X * s, 0.0,
  1323.     //      X * z * (1 - c) - y * s, y * z * (1 - c) + X * s, z * z * (1 - c) + c, 0.0,
  1324.     //      0.0, 0.0, 0.0, 1.0
  1325.     //      );
  1326.     //}
  1327.  
  1328.     //template <typename T>
  1329.     //inline TMatrix4<double> TMatrix4<T>::MakeScaling(double X, double y, double z)
  1330.     //{
  1331.     //  return TMatrix4<double>(
  1332.     //      X, 0, 0, 0,
  1333.     //      0, y, 0, 0,
  1334.     //      0, 0, z, 0,
  1335.     //      0, 0, 0, 1
  1336.     //      );
  1337.     //}
  1338.  
  1339.     //template <typename T>
  1340.     //inline TMatrix4<double> TMatrix4<T>::MakeTranslation(double X, double y, double z)
  1341.     //{
  1342.     //  return TMatrix4<double>(
  1343.     //      1, 0, 0, X,
  1344.     //      0, 1, 0, y,
  1345.     //      0, 0, 1, z,
  1346.     //      0, 0, 0, 1
  1347.     //      );
  1348.     //}
  1349.  
  1350.     //template <typename T>
  1351.     //inline TMatrix4<double> TMatrix4<T>::MakeOrtho(double left, double right, double bottom, double top, double near_value, double far_value)
  1352.     //{
  1353.     //  double tx = -(right + left) / (right - left);
  1354.     //  double ty = -(top + bottom) / (top - bottom);
  1355.     //  double tz = -(far_value + near_value) / (far_value - near_value);
  1356.  
  1357.     //  return TMatrix4<double>(
  1358.     //      2 / (right - left), 0, 0, tx,
  1359.     //      0, 2 / (top - bottom), 0, ty,
  1360.     //      0, 0, -2 / (far_value - near_value), tz,
  1361.     //      0, 0, 0, 1
  1362.     //      );
  1363.     //}
  1364.  
  1365.     //template <typename T>
  1366.     //inline TMatrix4<double> TMatrix4<T>::MakeOrtho2D(double left, double right, double bottom, double top)
  1367.     //{
  1368.     //  double tx = -(right + left) / (right - left);
  1369.     //  double ty = -(top + bottom) / (top - bottom);
  1370.  
  1371.     //  return TMatrix4<double>(
  1372.     //      2 / (right - left), 0, 0, tx,
  1373.     //      0, 2 / (top - bottom), 0, ty,
  1374.     //      0, 0, -1, 0,
  1375.     //      0, 0, 0, 1
  1376.     //      );
  1377.     //}
  1378.  
  1379.     //template <typename T>
  1380.     //inline TMatrix4<double> TMatrix4<T>::MakeFrustum(double left, double right, double bottom, double top, double near_value, double far_value)
  1381.     //{
  1382.     //  double A = (right + left) / (right - left);
  1383.     //  double B = (top + bottom) / (top - bottom);
  1384.     //  double C = -(far_value + near_value) / (far_value - near_value);
  1385.     //  double D = -2 * far_value * near_value / (far_value - near_value);
  1386.  
  1387.     //  return TMatrix4<double>(
  1388.     //      2 * near_value / (right - left), 0, A, 0,
  1389.     //      0, 2 * near_value / (top - bottom), B, 0,
  1390.     //      0, 0, C, D,
  1391.     //      0, 0, -1, 0
  1392.     //      );
  1393.     //}
  1394.  
  1395.     //template <typename T>
  1396.     //inline TMatrix4<double> TMatrix4<T>::MakePerspective(double angleInDegrees, double aspect, double near_value, double far_value)
  1397.     //{
  1398.     //  double f = 1.0 / std::tan(FX_DEGREES_TO_RADIANS * 0.5 * angleInDegrees);
  1399.  
  1400.     //  return TMatrix4<double>(
  1401.     //      f / aspect, 0, 0, 0,
  1402.     //      0, f, 0, 0,
  1403.     //      0, 0, (far_value + near_value) / (near_value - far_value), 2 * far_value * near_value / (near_value - far_value),
  1404.     //      0, 0, -1, 0
  1405.     //      );
  1406.     //}
  1407.  
  1408.     //template <typename T>
  1409.     //inline TMatrix4<double> TMatrix4<T>::MakePerspectiveX(double angleInDegrees, double aspect, double near_value, double far_value)
  1410.     //{
  1411.     //  double f = 1.0 / std::tan(FX_DEGREES_TO_RADIANS * 0.5 * angleInDegrees);
  1412.  
  1413.     //  return TMatrix4<double>(
  1414.     //      f / aspect, 0, 0, 0,
  1415.     //      0, f, 0, 0,
  1416.     //      0, 0, (far_value + near_value) / (near_value - far_value), 2 * far_value * near_value / (near_value - far_value),
  1417.     //      0, 0, -1, 0
  1418.     //      );
  1419.     //}
  1420.  
  1421.     //template <typename T>
  1422.     //inline TMatrix4<double> TMatrix4<T>::MakePerspectiveY(double angleInDegrees, double aspect, double near_value, double far_value)
  1423.     //{
  1424.     //  double f = 1.0 / std::tan(FX_DEGREES_TO_RADIANS * 0.5 * angleInDegrees);
  1425.  
  1426.     //  return TMatrix4<double>(
  1427.     //      f, 0, 0, 0,
  1428.     //      0, f * aspect, 0, 0,
  1429.     //      0, 0, (far_value + near_value) / (near_value - far_value), 2 * far_value * near_value / (near_value - far_value),
  1430.     //      0, 0, -1, 0
  1431.     //      );
  1432.     //}
  1433.  
  1434.     //template <typename T>
  1435.     //inline TMatrix4<double> TMatrix4<T>::MakeLookAt(TVector3<double> eye, TVector3<double> center, TVector3<double> up)
  1436.     //{
  1437.     //  TVector3<double> F = (center - eye).norm();
  1438.     //  TVector3<double> S = F.cross(up).norm();
  1439.     //  TVector3<double> U = S.cross(F).norm();
  1440.  
  1441.     //  return TMatrix4<double>::multiply(TMatrix4<double>(
  1442.     //      S.X, S.y, S.z, 0.0,
  1443.     //      U.X, U.y, U.z, 0.0,
  1444.     //      -F.X, -F.y, -F.z, 0.0,
  1445.     //      0.0, 0.0, 0.0, 1.0),
  1446.     //      TMatrix4<double>::MakeTranslation(-eye.X, -eye.y, -eye.z));
  1447.     //}
  1448.  
  1449.     //template <typename T>
  1450.     //inline TMatrix4<double> TMatrix4<T>::MakeShadowBias()
  1451.     //{
  1452.     //  return TMatrix4<double>(
  1453.     //      0.5, 0.0, 0.0, 0.5,
  1454.     //      0.0, 0.5, 0.0, 0.5,
  1455.     //      0.0, 0.0, 0.5, 0.5,
  1456.     //      0.0, 0.0, 0.0, 1.0);
  1457.     //}
  1458.  
  1459.  
  1460.     //template <typename T>
  1461.     //inline TMatrix4<double> TMatrix4<T>::MakeCubeMatrix(int face)
  1462.     //{
  1463.     //  // support GL_TEXTURE_CUBE_MAP_POSITIVE_X, ... constants
  1464.     //  if (face >= 0x8515 && face <= 0x851A) face -= 0x8515;
  1465.  
  1466.     //  switch (face)
  1467.     //  {
  1468.     //  case 0: // GL_TEXTURE_CUBE_MAP_POSITIVE_X
  1469.     //      return TMatrix4<double>::MakeRotation(90.0, 0.0, 1.0, 0.0);
  1470.     //      break;
  1471.     //  case 1: // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
  1472.     //      return TMatrix4<double>::MakeRotation(270.0, 0.0, 1.0, 0.0);
  1473.     //      break;
  1474.     //  case 2: // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
  1475.     //      return TMatrix4<double>::MakeRotation(270.0, 1.0, 0.0, 0.0);
  1476.     //      break;
  1477.     //  case 3: // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
  1478.     //      return TMatrix4<double>::MakeRotation(90.0, 1.0, 0.0, 0.0);
  1479.     //      break;
  1480.     //  case 4: // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
  1481.     //      return TMatrix4<double>::MakeIdentity();
  1482.     //      break;
  1483.     //  case 5: // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
  1484.     //      return TMatrix4<double>::MakeRotation(180.0, 0.0, 1.0, 0.0);
  1485.     //      break;
  1486.     //  }
  1487.     //  return TMatrix4<double>::MakeIdentity();
  1488.     //}
  1489.  
  1490.  
  1491.     //template <typename T>
  1492.     //inline TMatrix4<double> TMatrix4<T>::MakeIdentity()
  1493.     //{
  1494.     //  return TMatrix4<double>(
  1495.     //      1.0, 0.0, 0.0, 0.0,
  1496.     //      0.0, 1.0, 0.0, 0.0,
  1497.     //      0.0, 0.0, 1.0, 0.0,
  1498.     //      0.0, 0.0, 0.0, 1.0);
  1499.     //}
  1500.  
  1501.  
  1502.     extern template class TMatrix4<float>;
  1503.     extern template class TMatrix4<double>;
  1504.  
  1505.     using Matrix4f = TMatrix4<float>;
  1506.     using Matrix4d = TMatrix4<double>;
  1507.  
  1508.  
  1509.     template <typename T, typename U>
  1510.     constexpr auto operator * (const TMatrix4<T> & m1, const TMatrix4<U> & m2) noexcept
  1511.     {
  1512.         return TMatrix4<T>::multiply(m1, m2);
  1513.     }
  1514.  
  1515.  
  1516.     template <typename T, typename U>
  1517.     constexpr auto operator * (const TMatrix4<T> & M, const TVector2<U> & V) noexcept
  1518.     {
  1519.         return TVector2<common_type_t<T, U>>(
  1520.             M.m11 * V.x + M.m12 * V.y,
  1521.             M.m21 * V.x + M.m22 * V.y
  1522.             );
  1523.     }
  1524.  
  1525.  
  1526.     template <typename T, typename U>
  1527.     constexpr auto operator * (const TMatrix4<T> & M, const TVector3<U> & V) noexcept
  1528.     {
  1529.         return TVector2<common_type_t<T, U>>(
  1530.             M.m11 * V.x + M.m12 * V.y + M.m13 * V.z,
  1531.             M.m21 * V.x + M.m22 * V.y + M.m23 * V.z,
  1532.             M.m31 * V.x + M.m32 * V.y + M.m33 * V.z
  1533.             );
  1534.     }
  1535.  
  1536.  
  1537.     template <typename T, typename U>
  1538.     constexpr auto operator * (const TMatrix4<T> & M, const TVector4<U> & V) noexcept
  1539.     {
  1540.         return TVector4<common_type_t<T, U>>(
  1541.             M.m11 * V.x + M.m12 * V.y + M.m13 * V.z + M.m14 * V.w,
  1542.             M.m21 * V.x + M.m22 * V.y + M.m23 * V.z + M.m24 * V.w,
  1543.             M.m31 * V.x + M.m32 * V.y + M.m33 * V.z + M.m34 * V.w,
  1544.             M.m41 * V.x + M.m42 * V.y + M.m43 * V.z + M.m44 * V.w
  1545.             );
  1546.     }
  1547. }
  1548.  
  1549. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement