SFML/include/SFML/Graphics/Matrix3.inl
laurentgom b86c4627ab Added functions and overloads to sf::Rect
Slightly changed the sf::View interface


git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1138 4e206d99-4929-0410-ac5d-dfc041789085
2009-06-13 21:13:43 +00:00

208 lines
8.8 KiB
C++

////////////////////////////////////////////////////////////
//
// SFGE - Simple and Fast Game Engine
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Default constructor (builds an identity matrix)
////////////////////////////////////////////////////////////
inline Matrix3::Matrix3()
{
myData[0] = 1.f; myData[4] = 0.f; myData[8] = 0.f; myData[12] = 0.f;
myData[1] = 0.f; myData[5] = 1.f; myData[9] = 0.f; myData[13] = 0.f;
myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
}
////////////////////////////////////////////////////////////
/// Construct a matrix from its 9 elements
////////////////////////////////////////////////////////////
inline Matrix3::Matrix3(float a00, float a01, float a02,
float a10, float a11, float a12,
float a20, float a21, float a22)
{
myData[0] = a00; myData[4] = a01; myData[8] = 0.f; myData[12] = a02;
myData[1] = a10; myData[5] = a11; myData[9] = 0.f; myData[13] = a12;
myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
myData[3] = a20; myData[7] = a21; myData[11] = 0.f; myData[15] = a22;
}
////////////////////////////////////////////////////////////
/// Build a matrix from a set of transformations
////////////////////////////////////////////////////////////
inline void Matrix3::SetFromTransformations(const Vector2f& Center, const Vector2f& Translation, float Rotation, const Vector2f& Scale)
{
// Combine the transformations
float Angle = Rotation * 3.141592654f / 180.f;
float Cos = static_cast<float>(cos(Angle));
float Sin = static_cast<float>(sin(Angle));
float SxCos = Scale.x * Cos;
float SyCos = Scale.y * Cos;
float SxSin = Scale.x * Sin;
float SySin = Scale.y * Sin;
float Tx = -Center.x * SxCos - Center.y * SySin + Translation.x;
float Ty = Center.x * SxSin - Center.y * SyCos + Translation.y;
// Rebuild the matrix
myData[0] = SxCos; myData[4] = SySin; myData[8] = 0.f; myData[12] = Tx;
myData[1] = -SxSin; myData[5] = SyCos; myData[9] = 0.f; myData[13] = Ty;
myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
}
////////////////////////////////////////////////////////////
/// Build a matrix from a projection
////////////////////////////////////////////////////////////
inline void Matrix3::SetFromProjection(const FloatRect& Rectangle)
{
// Projection components
float A = 2.f / Rectangle.GetSize().x;
float B = -2.f / Rectangle.GetSize().y;
float C = -(Rectangle.Left + Rectangle.Right) / Rectangle.GetSize().x;
float D = (Rectangle.Bottom + Rectangle.Top) / Rectangle.GetSize().y;
// Rebuild the projection matrix
myData[0] = A; myData[4] = 0.f; myData[8] = 0.f; myData[12] = C;
myData[1] = 0.f; myData[5] = B; myData[9] = 0.f; myData[13] = D;
myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
}
////////////////////////////////////////////////////////////
/// Transform a point by the matrix
////////////////////////////////////////////////////////////
inline Vector2f Matrix3::Transform(const Vector2f& Point) const
{
return Vector2f(myData[0] * Point.x + myData[4] * Point.y + myData[12],
myData[1] * Point.x + myData[5] * Point.y + myData[13]);
}
////////////////////////////////////////////////////////////
/// Return the inverse of the matrix
////////////////////////////////////////////////////////////
inline Matrix3 Matrix3::GetInverse() const
{
// Compute the determinant
float Det = myData[0] * (myData[15] * myData[5] - myData[7] * myData[13]) -
myData[1] * (myData[15] * myData[4] - myData[7] * myData[12]) +
myData[3] * (myData[13] * myData[4] - myData[5] * myData[12]);
// Compute the inverse if determinant is not zero
if ((Det < -1E-7f) || (Det > 1E-7f))
{
return Matrix3( (myData[15] * myData[5] - myData[7] * myData[13]) / Det,
-(myData[15] * myData[4] - myData[7] * myData[12]) / Det,
(myData[13] * myData[4] - myData[5] * myData[12]) / Det,
-(myData[15] * myData[1] - myData[3] * myData[13]) / Det,
(myData[15] * myData[0] - myData[3] * myData[12]) / Det,
-(myData[13] * myData[0] - myData[1] * myData[12]) / Det,
(myData[7] * myData[1] - myData[3] * myData[5]) / Det,
-(myData[7] * myData[0] - myData[3] * myData[4]) / Det,
(myData[5] * myData[0] - myData[1] * myData[4]) / Det);
}
else
{
return Identity;
}
}
////////////////////////////////////////////////////////////
/// Return the elements of the matrix as a 4x4,
/// in an array of 16 floats
////////////////////////////////////////////////////////////
inline const float* Matrix3::Get4x4Elements() const
{
return myData;
}
////////////////////////////////////////////////////////////
/// Operator () overloads to access the matrix elements
////////////////////////////////////////////////////////////
inline float Matrix3::operator ()(unsigned int Row, unsigned int Col) const
{
switch (Row + Col * 3)
{
case 0 : return myData[0];
case 1 : return myData[1];
case 2 : return myData[3];
case 3 : return myData[4];
case 4 : return myData[5];
case 5 : return myData[7];
case 6 : return myData[12];
case 7 : return myData[13];
case 8 : return myData[15];
default : return myData[0];
}
}
inline float& Matrix3::operator ()(unsigned int Row, unsigned int Col)
{
switch (Row + Col * 3)
{
case 0 : return myData[0];
case 1 : return myData[1];
case 2 : return myData[3];
case 3 : return myData[4];
case 4 : return myData[5];
case 5 : return myData[7];
case 6 : return myData[12];
case 7 : return myData[13];
case 8 : return myData[15];
default : return myData[0];
}
}
////////////////////////////////////////////////////////////
/// Operator * overload to multiply two matrices
////////////////////////////////////////////////////////////
inline Matrix3 Matrix3::operator *(const Matrix3& Mat) const
{
return Matrix3(myData[0] * Mat.myData[0] + myData[4] * Mat.myData[1] + myData[12] * Mat.myData[3],
myData[0] * Mat.myData[4] + myData[4] * Mat.myData[5] + myData[12] * Mat.myData[7],
myData[0] * Mat.myData[12] + myData[4] * Mat.myData[13] + myData[12] * Mat.myData[15],
myData[1] * Mat.myData[0] + myData[5] * Mat.myData[1] + myData[13] * Mat.myData[3],
myData[1] * Mat.myData[4] + myData[5] * Mat.myData[5] + myData[13] * Mat.myData[7],
myData[1] * Mat.myData[12] + myData[5] * Mat.myData[13] + myData[13] * Mat.myData[15],
myData[3] * Mat.myData[0] + myData[7] * Mat.myData[1] + myData[15] * Mat.myData[3],
myData[3] * Mat.myData[4] + myData[7] * Mat.myData[5] + myData[15] * Mat.myData[7],
myData[3] * Mat.myData[12] + myData[7] * Mat.myData[13] + myData[15] * Mat.myData[15]);
}
////////////////////////////////////////////////////////////
/// Operator *= overload to multiply-assign two matrices
////////////////////////////////////////////////////////////
inline Matrix3& Matrix3::operator *=(const Matrix3& Mat)
{
return *this = *this * Mat;
}