Updated the Matrix3 class and documentation (internal stuff)

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1507 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
LaurentGom 2010-04-10 11:29:44 +00:00
parent a00a9c1cc2
commit 1e6161c750
5 changed files with 109 additions and 160 deletions

View File

@ -37,21 +37,33 @@
namespace sf namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Utility class to manipulate 3x3 matrices representing /// \brief Utility class to manipulate 3x3 matrices of floats
/// 2D transformations ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SFML_API Matrix3 class SFML_API Matrix3
{ {
public : public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Default constructor (builds an identity matrix) /// \brief Default constructor
///
/// This constructor creates an identity matrix.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Matrix3(); Matrix3();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Construct a matrix from its 9 elements /// \brief Construct a matrix from its 9 elements
///
/// \param a00 Element (0, 0) of the matrix
/// \param a01 Element (0, 1) of the matrix
/// \param a02 Element (0, 2) of the matrix
/// \param a10 Element (1, 0) of the matrix
/// \param a11 Element (1, 1) of the matrix
/// \param a12 Element (1, 2) of the matrix
/// \param a20 Element (2, 0) of the matrix
/// \param a21 Element (2, 1) of the matrix
/// \param a22 Element (2, 2) of the matrix
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Matrix3(float a00, float a01, float a02, Matrix3(float a00, float a01, float a02,
@ -59,30 +71,9 @@ public :
float a20, float a21, float a22); float a20, float a21, float a22);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Build a matrix from a set of transformations /// \brief Transform a point by the matrix
/// ///
/// \param origin : Origin for the transformations /// \param point Point to transform
/// \param translation : Translation offset
/// \param rotation : Rotation angle in degrees
/// \param scale : Scaling factors
///
////////////////////////////////////////////////////////////
void SetFromTransformations(const Vector2f& origin, const Vector2f& translation, float rotation, const Vector2f& scale);
////////////////////////////////////////////////////////////
/// Build a matrix from a projection
///
/// \param center : Center of the view
/// \param size : Size of the view
/// \param rotation : Angle of rotation of the view rectangle, in degrees
///
////////////////////////////////////////////////////////////
void SetFromProjection(const Vector2f& center, const Vector2f& size, float rotation);
////////////////////////////////////////////////////////////
/// Transform a point by the matrix
///
/// \param point : Point to transform
/// ///
/// \return Transformed point /// \return Transformed point
/// ///
@ -90,16 +81,22 @@ public :
Vector2f Transform(const Vector2f& point) const; Vector2f Transform(const Vector2f& point) const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Return the inverse of the matrix /// \brief Return the inverse of the matrix
/// ///
/// \return A new matrix which is the inverse of this /// If the inverse cannot be computed, the identity matrix
/// is returned.
///
/// \return A new matrix which is the inverse of self
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Matrix3 GetInverse() const; Matrix3 GetInverse() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Return the elements of the matrix as a 4x4, /// \brief Return the elements of the matrix
/// in an array of 16 floats ///
/// This function returns an array of 16 floats containing
/// the corresponding 4x4 matrix, so that it is directly
/// compatible with OpenGL functions.
/// ///
/// \return Pointer to the 4x4 matrix elements /// \return Pointer to the 4x4 matrix elements
/// ///
@ -107,41 +104,48 @@ public :
const float* Get4x4Elements() const; const float* Get4x4Elements() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Operator () overloads to access the matrix elements /// \brief Overload of binary operator *
/// ///
/// \param row : Element row (0 based) /// \param right Right operand of the multiplication
/// \param column : Element column (0 based)
/// ///
/// \return Matrix element (Row, Col) /// \return New matrix which is the result of self * \a right
///
////////////////////////////////////////////////////////////
float operator ()(unsigned int row, unsigned int column) const;
float& operator ()(unsigned int row, unsigned int column);
////////////////////////////////////////////////////////////
/// Operator * overload to multiply two matrices
///
/// \param right : Matrix to multiply
///
/// \return this * right
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Matrix3 operator *(const Matrix3& right) const; Matrix3 operator *(const Matrix3& right) const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Operator *= overload to multiply-assign two matrices /// \brief Build a matrix from a set of transformations
/// ///
/// \param right : Matrix to multiply /// \param origin Origin for the transformations
/// \param translation Translation offset
/// \param rotation Rotation angle in degrees
/// \param scale Scaling factors
/// ///
/// \return this * right /// \return New Matrix3 containing the transformations
///
/// \see Projection
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Matrix3& operator *=(const Matrix3& right); static Matrix3 Transformation(const Vector2f& origin, const Vector2f& translation, float rotation, const Vector2f& scale);
////////////////////////////////////////////////////////////
/// \brief Build a 2D project matrix
///
/// \param center Center of the view
/// \param size Size of the view
/// \param rotation Angle of rotation of the view, in degrees
///
/// \return New Matrix3 containing the projection
///
/// \see Transformation
///
////////////////////////////////////////////////////////////
static Matrix3 Projection(const Vector2f& center, const Vector2f& size, float rotation);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Static member data // Static member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static const Matrix3 Identity; ///< Identity matrix static const Matrix3 Identity; ///< The identity matrix
private : private :
@ -157,3 +161,15 @@ private :
#endif // SFML_MATRIX3_HPP #endif // SFML_MATRIX3_HPP
////////////////////////////////////////////////////////////
/// \class sf::Matrix3
///
/// Matrix3 is only meant for internal use, its interface is
/// limited and its implementation is optimized for OpenGL
/// rendering.
///
/// This type is not used at all in the public API of SFML.
///
////////////////////////////////////////////////////////////

View File

@ -23,8 +23,6 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Default constructor (builds an identity matrix)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
inline Matrix3::Matrix3() inline Matrix3::Matrix3()
{ {
@ -35,8 +33,6 @@ inline Matrix3::Matrix3()
} }
////////////////////////////////////////////////////////////
/// Construct a matrix from its 9 elements
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
inline Matrix3::Matrix3(float a00, float a01, float a02, inline Matrix3::Matrix3(float a00, float a01, float a02,
float a10, float a11, float a12, float a10, float a11, float a12,
@ -49,58 +45,6 @@ inline Matrix3::Matrix3(float a00, float a01, float a02,
} }
////////////////////////////////////////////////////////////
/// Build a matrix from a set of transformations
////////////////////////////////////////////////////////////
inline void Matrix3::SetFromTransformations(const Vector2f& origin, const Vector2f& translation, float rotation, const Vector2f& scale)
{
// Combine the transformations
float angle = rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(cos(angle));
float sine = static_cast<float>(sin(angle));
float sxCos = scale.x * cosine;
float syCos = scale.y * cosine;
float sxSin = scale.x * sine;
float sySin = scale.y * sine;
float tx = -origin.x * sxCos - origin.y * sySin + translation.x;
float ty = origin.x * sxSin - origin.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 Vector2f& center, const Vector2f& size, float rotation)
{
// Rotation components
float angle = rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(cos(angle));
float sine = static_cast<float>(sin(angle));
float tx = -center.x * cosine - center.y * sine + center.x;
float ty = center.x * sine - center.y * cosine + center.y;
// Projection components
float a = 2.f / size.x;
float b = -2.f / size.y;
float c = -a * center.x;
float d = -b * center.y;
// Rebuild the projection matrix
myData[0] = a * cosine; myData[4] = a * sine; myData[8] = 0.f; myData[12] = a * tx + c;
myData[1] = -b * sine; myData[5] = b * cosine; myData[9] = 0.f; myData[13] = b * ty + 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 inline Vector2f Matrix3::Transform(const Vector2f& point) const
{ {
@ -109,8 +53,6 @@ inline Vector2f Matrix3::Transform(const Vector2f& point) const
} }
////////////////////////////////////////////////////////////
/// Return the inverse of the matrix
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
inline Matrix3 Matrix3::GetInverse() const inline Matrix3 Matrix3::GetInverse() const
{ {
@ -139,9 +81,6 @@ inline Matrix3 Matrix3::GetInverse() const
} }
////////////////////////////////////////////////////////////
/// Return the elements of the matrix as a 4x4,
/// in an array of 16 floats
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
inline const float* Matrix3::Get4x4Elements() const inline const float* Matrix3::Get4x4Elements() const
{ {
@ -149,47 +88,6 @@ inline const float* Matrix3::Get4x4Elements() const
} }
////////////////////////////////////////////////////////////
/// Operator () overloads to access the matrix elements
////////////////////////////////////////////////////////////
inline float Matrix3::operator ()(unsigned int row, unsigned int column) const
{
switch (row + column * 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 column)
{
switch (row + column * 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& right) const inline Matrix3 Matrix3::operator *(const Matrix3& right) const
{ {
@ -206,9 +104,44 @@ inline Matrix3 Matrix3::operator *(const Matrix3& right) const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Operator *= overload to multiply-assign two matrices inline Matrix3 Matrix3::Transformation(const Vector2f& origin, const Vector2f& translation, float rotation, const Vector2f& scale)
////////////////////////////////////////////////////////////
inline Matrix3& Matrix3::operator *=(const Matrix3& right)
{ {
return *this = *this * right; // Combine the transformations
float angle = rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(cos(angle));
float sine = static_cast<float>(sin(angle));
float sxCos = scale.x * cosine;
float syCos = scale.y * cosine;
float sxSin = scale.x * sine;
float sySin = scale.y * sine;
float tx = -origin.x * sxCos - origin.y * sySin + translation.x;
float ty = origin.x * sxSin - origin.y * syCos + translation.y;
// Construct the matrix
return Matrix3( sxCos, sySin, tx,
-sxSin, syCos, ty,
0.f, 0.f, 1.f);
}
////////////////////////////////////////////////////////////
inline Matrix3 Matrix3::Projection(const Vector2f& center, const Vector2f& size, float rotation)
{
// Rotation components
float angle = rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(cos(angle));
float sine = static_cast<float>(sin(angle));
float tx = -center.x * cosine - center.y * sine + center.x;
float ty = center.x * sine - center.y * cosine + center.y;
// Projection components
float a = 2.f / size.x;
float b = -2.f / size.y;
float c = -a * center.x;
float d = -b * center.y;
// Rebuild the projection matrix
return Matrix3( a * cosine, a * sine, a * tx + c,
-b * sine, b * cosine, b * ty + d,
0.f, 0.f, 1.f);
} }

View File

@ -339,7 +339,7 @@ const Matrix3& Drawable::GetMatrix() const
// First recompute it if needed // First recompute it if needed
if (!myMatrixUpdated) if (!myMatrixUpdated)
{ {
myMatrix.SetFromTransformations(myOrigin, myPosition, myRotation, myScale); myMatrix = Matrix3::Transformation(myOrigin, myPosition, myRotation, myScale);
myMatrixUpdated = true; myMatrixUpdated = true;
} }

View File

@ -137,7 +137,7 @@ void Renderer::SetModelView(const Matrix3& matrix)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Renderer::ApplyModelView(const Matrix3& matrix) void Renderer::ApplyModelView(const Matrix3& matrix)
{ {
myStates->modelView *= matrix; myStates->modelView = myStates->modelView * matrix;
} }

View File

@ -199,7 +199,7 @@ const Matrix3& View::GetMatrix() const
// Recompute the matrix if needed // Recompute the matrix if needed
if (!myMatrixUpdated) if (!myMatrixUpdated)
{ {
myMatrix.SetFromProjection(myCenter, mySize, myRotation); myMatrix = Matrix3::Projection(myCenter, mySize, myRotation);
myMatrixUpdated = true; myMatrixUpdated = true;
} }