Matrix3.inl
00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00025 
00027 inline Matrix3::Matrix3()
00028 {
00029     myData[0] = 1.f; myData[4] = 0.f; myData[8]  = 0.f; myData[12] = 0.f;
00030     myData[1] = 0.f; myData[5] = 1.f; myData[9]  = 0.f; myData[13] = 0.f;
00031     myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
00032     myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
00033 }
00034 
00035 
00037 inline Matrix3::Matrix3(float a00, float a01, float a02,
00038                         float a10, float a11, float a12,
00039                         float a20, float a21, float a22)
00040 {
00041     myData[0] = a00; myData[4] = a01; myData[8]  = 0.f; myData[12] = a02;
00042     myData[1] = a10; myData[5] = a11; myData[9]  = 0.f; myData[13] = a12;
00043     myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
00044     myData[3] = a20; myData[7] = a21; myData[11] = 0.f; myData[15] = a22;
00045 }
00046 
00047 
00049 inline Vector2f Matrix3::Transform(const Vector2f& point) const
00050 {
00051     return Vector2f(myData[0] * point.x + myData[4] * point.y + myData[12],
00052                     myData[1] * point.x + myData[5] * point.y + myData[13]);
00053 }
00054 
00055 
00057 inline Matrix3 Matrix3::GetInverse() const
00058 {
00059     // Compute the determinant
00060     float det = myData[0] * (myData[15] * myData[5] - myData[7] * myData[13]) -
00061                 myData[1] * (myData[15] * myData[4] - myData[7] * myData[12]) +
00062                 myData[3] * (myData[13] * myData[4] - myData[5] * myData[12]);
00063 
00064     // Compute the inverse if determinant is not zero
00065     if (det != 0.f) // don't use an epsilon because the determinant may *really* be tiny
00066     {
00067         return Matrix3( (myData[15] * myData[5] - myData[7] * myData[13]) / det,
00068                        -(myData[15] * myData[4] - myData[7] * myData[12]) / det,
00069                         (myData[13] * myData[4] - myData[5] * myData[12]) / det,
00070                        -(myData[15] * myData[1] - myData[3] * myData[13]) / det,
00071                         (myData[15] * myData[0] - myData[3] * myData[12]) / det,
00072                        -(myData[13] * myData[0] - myData[1] * myData[12]) / det,
00073                         (myData[7]  * myData[1] - myData[3] * myData[5])  / det,
00074                        -(myData[7]  * myData[0] - myData[3] * myData[4])  / det,
00075                         (myData[5]  * myData[0] - myData[1] * myData[4])  / det);
00076     }
00077     else
00078     {
00079         return Identity;
00080     }
00081 }
00082 
00083 
00085 inline const float* Matrix3::Get4x4Elements() const
00086 {
00087     return myData;
00088 }
00089 
00090 
00092 inline Matrix3 Matrix3::operator *(const Matrix3& right) const
00093 {
00094     return Matrix3(myData[0] * right.myData[0]  + myData[4] * right.myData[1]  + myData[12] * right.myData[3],
00095                    myData[0] * right.myData[4]  + myData[4] * right.myData[5]  + myData[12] * right.myData[7],
00096                    myData[0] * right.myData[12] + myData[4] * right.myData[13] + myData[12] * right.myData[15],
00097                    myData[1] * right.myData[0]  + myData[5] * right.myData[1]  + myData[13] * right.myData[3],
00098                    myData[1] * right.myData[4]  + myData[5] * right.myData[5]  + myData[13] * right.myData[7],
00099                    myData[1] * right.myData[12] + myData[5] * right.myData[13] + myData[13] * right.myData[15],
00100                    myData[3] * right.myData[0]  + myData[7] * right.myData[1]  + myData[15] * right.myData[3],
00101                    myData[3] * right.myData[4]  + myData[7] * right.myData[5]  + myData[15] * right.myData[7],
00102                    myData[3] * right.myData[12] + myData[7] * right.myData[13] + myData[15] * right.myData[15]);
00103 }
00104 
00105 
00107 inline Matrix3 Matrix3::Transformation(const Vector2f& origin, const Vector2f& translation, float rotation, const Vector2f& scale)
00108 {
00109     // Combine the transformations
00110     float angle  = -rotation * 3.141592654f / 180.f;
00111     float cosine = static_cast<float>(std::cos(angle));
00112     float sine   = static_cast<float>(std::sin(angle));
00113     float sxCos  = scale.x * cosine;
00114     float syCos  = scale.y * cosine;
00115     float sxSin  = scale.x * sine;
00116     float sySin  = scale.y * sine;
00117     float tx     = -origin.x * sxCos - origin.y * sySin + translation.x;
00118     float ty     =  origin.x * sxSin - origin.y * syCos + translation.y;
00119 
00120     // Construct the matrix
00121     return Matrix3( sxCos, sySin, tx,
00122                    -sxSin, syCos, ty,
00123                     0.f,   0.f,   1.f);
00124 }
00125 
00126 
00128 inline Matrix3 Matrix3::Projection(const Vector2f& center, const Vector2f& size, float rotation)
00129 {
00130     // Rotation components
00131     float angle  = rotation * 3.141592654f / 180.f;
00132     float cosine = static_cast<float>(std::cos(angle));
00133     float sine   = static_cast<float>(std::sin(angle));
00134     float tx     = -center.x * cosine - center.y * sine + center.x;
00135     float ty     =  center.x * sine - center.y * cosine + center.y;
00136 
00137     // Projection components
00138     float a =  2.f / size.x;
00139     float b = -2.f / size.y;
00140     float c = -a * center.x;
00141     float d = -b * center.y;
00142 
00143     // Rebuild the projection matrix
00144     return Matrix3( a * cosine, a * sine,   a * tx + c,
00145                    -b * sine,   b * cosine, b * ty + d,
00146                     0.f,        0.f,        1.f);
00147 }