diff --git a/include/SFML/Graphics/Matrix3.hpp b/include/SFML/Graphics/Matrix3.hpp index 25ad90b44..7c486a266 100644 --- a/include/SFML/Graphics/Matrix3.hpp +++ b/include/SFML/Graphics/Matrix3.hpp @@ -37,21 +37,33 @@ namespace sf { //////////////////////////////////////////////////////////// -/// Utility class to manipulate 3x3 matrices representing -/// 2D transformations +/// \brief Utility class to manipulate 3x3 matrices of floats +/// //////////////////////////////////////////////////////////// class SFML_API Matrix3 { public : //////////////////////////////////////////////////////////// - /// Default constructor (builds an identity matrix) + /// \brief Default constructor + /// + /// This constructor creates an identity matrix. /// //////////////////////////////////////////////////////////// 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, @@ -59,30 +71,9 @@ public : 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 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 + /// \param point Point to transform /// /// \return Transformed point /// @@ -90,16 +81,22 @@ public : 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; //////////////////////////////////////////////////////////// - /// Return the elements of the matrix as a 4x4, - /// in an array of 16 floats + /// \brief Return the elements of the matrix + /// + /// 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 /// @@ -107,41 +104,48 @@ public : const float* Get4x4Elements() const; //////////////////////////////////////////////////////////// - /// Operator () overloads to access the matrix elements + /// \brief Overload of binary operator * /// - /// \param row : Element row (0 based) - /// \param column : Element column (0 based) + /// \param right Right operand of the multiplication /// - /// \return Matrix element (Row, Col) - /// - //////////////////////////////////////////////////////////// - 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 + /// \return New matrix which is the result of self * \a right /// //////////////////////////////////////////////////////////// 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 const Matrix3 Identity; ///< Identity matrix + static const Matrix3 Identity; ///< The identity matrix private : @@ -157,3 +161,15 @@ private : #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. +/// +//////////////////////////////////////////////////////////// diff --git a/include/SFML/Graphics/Matrix3.inl b/include/SFML/Graphics/Matrix3.inl index ed1f60086..1b5c83e9b 100644 --- a/include/SFML/Graphics/Matrix3.inl +++ b/include/SFML/Graphics/Matrix3.inl @@ -23,8 +23,6 @@ //////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////// -/// Default constructor (builds an identity matrix) //////////////////////////////////////////////////////////// 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, 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(cos(angle)); - float sine = static_cast(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(cos(angle)); - float sine = static_cast(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 { @@ -109,8 +53,6 @@ inline Vector2f Matrix3::Transform(const Vector2f& point) const } -//////////////////////////////////////////////////////////// -/// Return the inverse of the matrix //////////////////////////////////////////////////////////// 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 { @@ -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 { @@ -206,9 +104,44 @@ inline Matrix3 Matrix3::operator *(const Matrix3& right) const //////////////////////////////////////////////////////////// -/// Operator *= overload to multiply-assign two matrices -//////////////////////////////////////////////////////////// -inline Matrix3& Matrix3::operator *=(const Matrix3& right) +inline Matrix3 Matrix3::Transformation(const Vector2f& origin, const Vector2f& translation, float rotation, const Vector2f& scale) { - return *this = *this * right; + // Combine the transformations + float angle = rotation * 3.141592654f / 180.f; + float cosine = static_cast(cos(angle)); + float sine = static_cast(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(cos(angle)); + float sine = static_cast(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); } diff --git a/src/SFML/Graphics/Drawable.cpp b/src/SFML/Graphics/Drawable.cpp index 5be00a80f..9c3849060 100644 --- a/src/SFML/Graphics/Drawable.cpp +++ b/src/SFML/Graphics/Drawable.cpp @@ -339,7 +339,7 @@ const Matrix3& Drawable::GetMatrix() const // First recompute it if needed if (!myMatrixUpdated) { - myMatrix.SetFromTransformations(myOrigin, myPosition, myRotation, myScale); + myMatrix = Matrix3::Transformation(myOrigin, myPosition, myRotation, myScale); myMatrixUpdated = true; } diff --git a/src/SFML/Graphics/Renderer.cpp b/src/SFML/Graphics/Renderer.cpp index bddf9e031..a8480f60e 100644 --- a/src/SFML/Graphics/Renderer.cpp +++ b/src/SFML/Graphics/Renderer.cpp @@ -137,7 +137,7 @@ void Renderer::SetModelView(const Matrix3& matrix) //////////////////////////////////////////////////////////// void Renderer::ApplyModelView(const Matrix3& matrix) { - myStates->modelView *= matrix; + myStates->modelView = myStates->modelView * matrix; } diff --git a/src/SFML/Graphics/View.cpp b/src/SFML/Graphics/View.cpp index bd3e416c2..a14a43ff4 100644 --- a/src/SFML/Graphics/View.cpp +++ b/src/SFML/Graphics/View.cpp @@ -199,7 +199,7 @@ const Matrix3& View::GetMatrix() const // Recompute the matrix if needed if (!myMatrixUpdated) { - myMatrix.SetFromProjection(myCenter, mySize, myRotation); + myMatrix = Matrix3::Projection(myCenter, mySize, myRotation); myMatrixUpdated = true; }