1 ////////////////////////////////////////////////////////////
\r
3 // SFGE - Simple and Fast Multimedia Library
\r
4 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
\r
6 // This software is provided 'as-is', without any express or implied warranty.
\r
7 // In no event will the authors be held liable for any damages arising from the use of this software.
\r
9 // Permission is granted to anyone to use this software for any purpose,
\r
10 // including commercial applications, and to alter it and redistribute it freely,
\r
11 // subject to the following restrictions:
\r
13 // 1. The origin of this software must not be misrepresented;
\r
14 // you must not claim that you wrote the original software.
\r
15 // If you use this software in a product, an acknowledgment
\r
16 // in the product documentation would be appreciated but is not required.
\r
18 // 2. Altered source versions must be plainly marked as such,
\r
19 // and must not be misrepresented as being the original software.
\r
21 // 3. This notice may not be removed or altered from any source distribution.
\r
23 ////////////////////////////////////////////////////////////
\r
26 ////////////////////////////////////////////////////////////
\r
27 /// Default constructor (builds an identity matrix)
\r
28 ////////////////////////////////////////////////////////////
\r
29 inline Matrix3::Matrix3()
\r
31 myData[0] = 1.f; myData[4] = 0.f; myData[8] = 0.f; myData[12] = 0.f;
\r
32 myData[1] = 0.f; myData[5] = 1.f; myData[9] = 0.f; myData[13] = 0.f;
\r
33 myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
\r
34 myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
\r
38 ////////////////////////////////////////////////////////////
\r
39 /// Construct a matrix from its 9 elements
\r
40 ////////////////////////////////////////////////////////////
\r
41 inline Matrix3::Matrix3(float a00, float a01, float a02,
\r
42 float a10, float a11, float a12,
\r
43 float a20, float a21, float a22)
\r
45 myData[0] = a00; myData[4] = a01; myData[8] = 0.f; myData[12] = a02;
\r
46 myData[1] = a10; myData[5] = a11; myData[9] = 0.f; myData[13] = a12;
\r
47 myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
\r
48 myData[3] = a20; myData[7] = a21; myData[11] = 0.f; myData[15] = a22;
\r
52 ////////////////////////////////////////////////////////////
\r
53 /// Build a matrix from a set of transformations
\r
54 ////////////////////////////////////////////////////////////
\r
55 inline void Matrix3::SetFromTransformations(const Vector2f& Center, const Vector2f& Translation, float Rotation, const Vector2f& Scale)
\r
57 float Angle = Rotation * 3.141592654f / 180.f;
\r
58 float Cos = static_cast<float>(cos(Angle));
\r
59 float Sin = static_cast<float>(sin(Angle));
\r
60 float SxCos = Scale.x * Cos;
\r
61 float SyCos = Scale.y * Cos;
\r
62 float SxSin = Scale.x * Sin;
\r
63 float SySin = Scale.y * Sin;
\r
64 float Tx = -Center.x * SxCos - Center.y * SySin + Translation.x;
\r
65 float Ty = Center.x * SxSin - Center.y * SyCos + Translation.y;
\r
67 myData[0] = SxCos; myData[4] = SySin; myData[8] = 0.f; myData[12] = Tx;
\r
68 myData[1] = -SxSin; myData[5] = SyCos; myData[9] = 0.f; myData[13] = Ty;
\r
69 myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
\r
70 myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
\r
74 ////////////////////////////////////////////////////////////
\r
75 /// Transform a point by the matrix
\r
76 ////////////////////////////////////////////////////////////
\r
77 inline Vector2f Matrix3::Transform(const Vector2f& Point) const
\r
79 return Vector2f(myData[0] * Point.x + myData[4] * Point.y + myData[12],
\r
80 myData[1] * Point.x + myData[5] * Point.y + myData[13]);
\r
84 ////////////////////////////////////////////////////////////
\r
85 /// Return the inverse of the matrix
\r
86 ////////////////////////////////////////////////////////////
\r
87 inline Matrix3 Matrix3::GetInverse() const
\r
89 // Compute the determinant
\r
90 float Det = myData[0] * (myData[15] * myData[5] - myData[7] * myData[13]) -
\r
91 myData[1] * (myData[15] * myData[4] - myData[7] * myData[12]) +
\r
92 myData[3] * (myData[13] * myData[4] - myData[5] * myData[12]);
\r
94 // Compute the inverse if determinant is not zero
\r
95 if ((Det < -1E-7f) || (Det > 1E-7f))
\r
97 return Matrix3( (myData[15] * myData[5] - myData[7] * myData[13]) / Det,
\r
98 -(myData[15] * myData[4] - myData[7] * myData[12]) / Det,
\r
99 (myData[13] * myData[4] - myData[5] * myData[12]) / Det,
\r
100 -(myData[15] * myData[1] - myData[3] * myData[13]) / Det,
\r
101 (myData[15] * myData[0] - myData[3] * myData[12]) / Det,
\r
102 -(myData[13] * myData[0] - myData[1] * myData[12]) / Det,
\r
103 (myData[7] * myData[1] - myData[3] * myData[5]) / Det,
\r
104 -(myData[7] * myData[0] - myData[3] * myData[4]) / Det,
\r
105 (myData[5] * myData[0] - myData[1] * myData[4]) / Det);
\r
114 ////////////////////////////////////////////////////////////
\r
115 /// Return the elements of the matrix as a 4x4,
\r
116 /// in an array of 16 floats
\r
117 ////////////////////////////////////////////////////////////
\r
118 inline const float* Matrix3::Get4x4Elements() const
\r
124 ////////////////////////////////////////////////////////////
\r
125 /// Operator () overloads to access the matrix elements
\r
126 ////////////////////////////////////////////////////////////
\r
127 inline float Matrix3::operator ()(unsigned int Row, unsigned int Col) const
\r
129 switch (Row + Col * 3)
\r
131 case 0 : return myData[0];
\r
132 case 1 : return myData[1];
\r
133 case 2 : return myData[3];
\r
134 case 3 : return myData[4];
\r
135 case 4 : return myData[5];
\r
136 case 5 : return myData[7];
\r
137 case 6 : return myData[12];
\r
138 case 7 : return myData[13];
\r
139 case 8 : return myData[15];
\r
141 default : return myData[0];
\r
144 inline float& Matrix3::operator ()(unsigned int Row, unsigned int Col)
\r
146 switch (Row + Col * 3)
\r
148 case 0 : return myData[0];
\r
149 case 1 : return myData[1];
\r
150 case 2 : return myData[3];
\r
151 case 3 : return myData[4];
\r
152 case 4 : return myData[5];
\r
153 case 5 : return myData[7];
\r
154 case 6 : return myData[12];
\r
155 case 7 : return myData[13];
\r
156 case 8 : return myData[15];
\r
158 default : return myData[0];
\r
163 ////////////////////////////////////////////////////////////
\r
164 /// Operator * overload to multiply two matrices
\r
165 ////////////////////////////////////////////////////////////
\r
166 inline Matrix3 Matrix3::operator *(const Matrix3& Mat) const
\r
168 return Matrix3(myData[0] * Mat.myData[0] + myData[4] * Mat.myData[1] + myData[12] * Mat.myData[3],
\r
169 myData[0] * Mat.myData[4] + myData[4] * Mat.myData[5] + myData[12] * Mat.myData[7],
\r
170 myData[0] * Mat.myData[12] + myData[4] * Mat.myData[13] + myData[12] * Mat.myData[15],
\r
171 myData[1] * Mat.myData[0] + myData[5] * Mat.myData[1] + myData[13] * Mat.myData[3],
\r
172 myData[1] * Mat.myData[4] + myData[5] * Mat.myData[5] + myData[13] * Mat.myData[7],
\r
173 myData[1] * Mat.myData[12] + myData[5] * Mat.myData[13] + myData[13] * Mat.myData[15],
\r
174 myData[3] * Mat.myData[0] + myData[7] * Mat.myData[1] + myData[15] * Mat.myData[3],
\r
175 myData[3] * Mat.myData[4] + myData[7] * Mat.myData[5] + myData[15] * Mat.myData[7],
\r
176 myData[3] * Mat.myData[12] + myData[7] * Mat.myData[13] + myData[15] * Mat.myData[15]);
\r
180 ////////////////////////////////////////////////////////////
\r
181 /// Operator *= overload to multiply-assign two matrices
\r
182 ////////////////////////////////////////////////////////////
\r
183 inline Matrix3& Matrix3::operator *=(const Matrix3& Mat)
\r
185 return *this = *this * Mat;
\r