Turn 'sf::Transform' into a 'constexpr' class
This commit is contained in:
parent
63ce7e4e92
commit
dbeef66693
@ -31,16 +31,17 @@
|
|||||||
#include <SFML/Graphics/Export.hpp>
|
#include <SFML/Graphics/Export.hpp>
|
||||||
#include <SFML/Graphics/Rect.hpp>
|
#include <SFML/Graphics/Rect.hpp>
|
||||||
#include <SFML/System/Vector2.hpp>
|
#include <SFML/System/Vector2.hpp>
|
||||||
#include <SFML/System/Angle.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
|
class Angle;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Define a 3x3 transform matrix
|
/// \brief Define a 3x3 transform matrix
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
class SFML_GRAPHICS_API Transform
|
class Transform
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ public:
|
|||||||
/// Creates an identity transform (a transform that does nothing).
|
/// Creates an identity transform (a transform that does nothing).
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform();
|
constexpr Transform();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Construct a transform from a 3x3 matrix
|
/// \brief Construct a transform from a 3x3 matrix
|
||||||
@ -66,7 +67,7 @@ public:
|
|||||||
/// \param a22 Element (2, 2) of the matrix
|
/// \param a22 Element (2, 2) of the matrix
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform(float a00, float a01, float a02,
|
constexpr Transform(float a00, float a01, float a02,
|
||||||
float a10, float a11, float a12,
|
float a10, float a11, float a12,
|
||||||
float a20, float a21, float a22);
|
float a20, float a21, float a22);
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ public:
|
|||||||
/// \return Pointer to a 4x4 matrix
|
/// \return Pointer to a 4x4 matrix
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
const float* getMatrix() const;
|
constexpr const float* getMatrix() const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Return the inverse of the transform
|
/// \brief Return the inverse of the transform
|
||||||
@ -96,7 +97,7 @@ public:
|
|||||||
/// \return A new transform which is the inverse of self
|
/// \return A new transform which is the inverse of self
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform getInverse() const;
|
constexpr Transform getInverse() const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Transform a 2D point
|
/// \brief Transform a 2D point
|
||||||
@ -112,7 +113,7 @@ public:
|
|||||||
/// \return Transformed point
|
/// \return Transformed point
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Vector2f transformPoint(const Vector2f& point) const;
|
constexpr Vector2f transformPoint(const Vector2f& point) const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Transform a rectangle
|
/// \brief Transform a rectangle
|
||||||
@ -128,7 +129,7 @@ public:
|
|||||||
/// \return Transformed rectangle
|
/// \return Transformed rectangle
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
FloatRect transformRect(const FloatRect& rectangle) const;
|
constexpr FloatRect transformRect(const FloatRect& rectangle) const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Combine the current transform with another one
|
/// \brief Combine the current transform with another one
|
||||||
@ -148,7 +149,7 @@ public:
|
|||||||
/// \return Reference to *this
|
/// \return Reference to *this
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& combine(const Transform& transform);
|
constexpr Transform& combine(const Transform& transform);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Combine the current transform with a translation
|
/// \brief Combine the current transform with a translation
|
||||||
@ -167,7 +168,7 @@ public:
|
|||||||
/// \see rotate, scale
|
/// \see rotate, scale
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& translate(const Vector2f& offset);
|
constexpr Transform& translate(const Vector2f& offset);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Combine the current transform with a rotation
|
/// \brief Combine the current transform with a rotation
|
||||||
@ -186,7 +187,7 @@ public:
|
|||||||
/// \see translate, scale
|
/// \see translate, scale
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& rotate(Angle angle);
|
SFML_GRAPHICS_API Transform& rotate(Angle angle);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Combine the current transform with a rotation
|
/// \brief Combine the current transform with a rotation
|
||||||
@ -211,7 +212,7 @@ public:
|
|||||||
/// \see translate, scale
|
/// \see translate, scale
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& rotate(Angle angle, const Vector2f& center);
|
SFML_GRAPHICS_API Transform& rotate(Angle angle, const Vector2f& center);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Combine the current transform with a scaling
|
/// \brief Combine the current transform with a scaling
|
||||||
@ -230,7 +231,7 @@ public:
|
|||||||
/// \see translate, rotate
|
/// \see translate, rotate
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& scale(const Vector2f& factors);
|
constexpr Transform& scale(const Vector2f& factors);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Combine the current transform with a scaling
|
/// \brief Combine the current transform with a scaling
|
||||||
@ -255,7 +256,7 @@ public:
|
|||||||
/// \see translate, rotate
|
/// \see translate, rotate
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& scale(const Vector2f& factors, const Vector2f& center);
|
constexpr Transform& scale(const Vector2f& factors, const Vector2f& center);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Static member data
|
// Static member data
|
||||||
@ -282,7 +283,7 @@ private:
|
|||||||
/// \return New combined transform
|
/// \return New combined transform
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFML_GRAPHICS_API Transform operator *(const Transform& left, const Transform& right);
|
constexpr Transform operator *(const Transform& left, const Transform& right);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \relates sf::Transform
|
/// \relates sf::Transform
|
||||||
@ -296,7 +297,7 @@ SFML_GRAPHICS_API Transform operator *(const Transform& left, const Transform& r
|
|||||||
/// \return The combined transform
|
/// \return The combined transform
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFML_GRAPHICS_API Transform& operator *=(Transform& left, const Transform& right);
|
constexpr Transform& operator *=(Transform& left, const Transform& right);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \relates sf::Transform
|
/// \relates sf::Transform
|
||||||
@ -310,7 +311,7 @@ SFML_GRAPHICS_API Transform& operator *=(Transform& left, const Transform& right
|
|||||||
/// \return New transformed point
|
/// \return New transformed point
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFML_GRAPHICS_API Vector2f operator *(const Transform& left, const Vector2f& right);
|
constexpr Vector2f operator *(const Transform& left, const Vector2f& right);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \relates sf::Transform
|
/// \relates sf::Transform
|
||||||
@ -325,7 +326,7 @@ SFML_GRAPHICS_API Vector2f operator *(const Transform& left, const Vector2f& rig
|
|||||||
/// \return true if the transforms are equal, false otherwise
|
/// \return true if the transforms are equal, false otherwise
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFML_GRAPHICS_API bool operator ==(const Transform& left, const Transform& right);
|
[[nodiscard]] constexpr bool operator ==(const Transform& left, const Transform& right);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \relates sf::Transform
|
/// \relates sf::Transform
|
||||||
@ -339,7 +340,9 @@ SFML_GRAPHICS_API bool operator ==(const Transform& left, const Transform& right
|
|||||||
/// \return true if the transforms are not equal, false otherwise
|
/// \return true if the transforms are not equal, false otherwise
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFML_GRAPHICS_API bool operator !=(const Transform& left, const Transform& right);
|
[[nodiscard]] constexpr bool operator !=(const Transform& left, const Transform& right);
|
||||||
|
|
||||||
|
#include <SFML/Graphics/Transform.inl>
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
||||||
|
222
include/SFML/Graphics/Transform.inl
Normal file
222
include/SFML/Graphics/Transform.inl
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2022 Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform::Transform()
|
||||||
|
// Identity matrix
|
||||||
|
: m_matrix{1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 1.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 1.f, 0.f,
|
||||||
|
0.f, 0.f, 0.f, 1.f}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform::Transform(float a00, float a01, float a02,
|
||||||
|
float a10, float a11, float a12,
|
||||||
|
float a20, float a21, float a22)
|
||||||
|
: m_matrix{a00, a10, 0.f, a20,
|
||||||
|
a01, a11, 0.f, a21,
|
||||||
|
0.f, 0.f, 1.f, 0.f,
|
||||||
|
a02, a12, 0.f, a22}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr const float* Transform::getMatrix() const
|
||||||
|
{
|
||||||
|
return m_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform Transform::getInverse() const
|
||||||
|
{
|
||||||
|
// Compute the determinant
|
||||||
|
float det = m_matrix[0] * (m_matrix[15] * m_matrix[5] - m_matrix[7] * m_matrix[13]) -
|
||||||
|
m_matrix[1] * (m_matrix[15] * m_matrix[4] - m_matrix[7] * m_matrix[12]) +
|
||||||
|
m_matrix[3] * (m_matrix[13] * m_matrix[4] - m_matrix[5] * m_matrix[12]);
|
||||||
|
|
||||||
|
// Compute the inverse if the determinant is not zero
|
||||||
|
// (don't use an epsilon because the determinant may *really* be tiny)
|
||||||
|
if (det != 0.f)
|
||||||
|
{
|
||||||
|
return Transform( (m_matrix[15] * m_matrix[5] - m_matrix[7] * m_matrix[13]) / det,
|
||||||
|
-(m_matrix[15] * m_matrix[4] - m_matrix[7] * m_matrix[12]) / det,
|
||||||
|
(m_matrix[13] * m_matrix[4] - m_matrix[5] * m_matrix[12]) / det,
|
||||||
|
-(m_matrix[15] * m_matrix[1] - m_matrix[3] * m_matrix[13]) / det,
|
||||||
|
(m_matrix[15] * m_matrix[0] - m_matrix[3] * m_matrix[12]) / det,
|
||||||
|
-(m_matrix[13] * m_matrix[0] - m_matrix[1] * m_matrix[12]) / det,
|
||||||
|
(m_matrix[7] * m_matrix[1] - m_matrix[3] * m_matrix[5]) / det,
|
||||||
|
-(m_matrix[7] * m_matrix[0] - m_matrix[3] * m_matrix[4]) / det,
|
||||||
|
(m_matrix[5] * m_matrix[0] - m_matrix[1] * m_matrix[4]) / det);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Vector2f Transform::transformPoint(const Vector2f& point) const
|
||||||
|
{
|
||||||
|
return Vector2f(m_matrix[0] * point.x + m_matrix[4] * point.y + m_matrix[12],
|
||||||
|
m_matrix[1] * point.x + m_matrix[5] * point.y + m_matrix[13]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr FloatRect Transform::transformRect(const FloatRect& rectangle) const
|
||||||
|
{
|
||||||
|
// Transform the 4 corners of the rectangle
|
||||||
|
const Vector2f points[] =
|
||||||
|
{
|
||||||
|
transformPoint({rectangle.left, rectangle.top}),
|
||||||
|
transformPoint({rectangle.left, rectangle.top + rectangle.height}),
|
||||||
|
transformPoint({rectangle.left + rectangle.width, rectangle.top}),
|
||||||
|
transformPoint({rectangle.left + rectangle.width, rectangle.top + rectangle.height})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compute the bounding rectangle of the transformed points
|
||||||
|
float left = points[0].x;
|
||||||
|
float top = points[0].y;
|
||||||
|
float right = points[0].x;
|
||||||
|
float bottom = points[0].y;
|
||||||
|
for (int i = 1; i < 4; ++i)
|
||||||
|
{
|
||||||
|
if (points[i].x < left) left = points[i].x;
|
||||||
|
else if (points[i].x > right) right = points[i].x;
|
||||||
|
if (points[i].y < top) top = points[i].y;
|
||||||
|
else if (points[i].y > bottom) bottom = points[i].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FloatRect({left, top}, {right - left, bottom - top});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform& Transform::combine(const Transform& transform)
|
||||||
|
{
|
||||||
|
const float* a = m_matrix;
|
||||||
|
const float* b = transform.m_matrix;
|
||||||
|
|
||||||
|
*this = Transform(a[0] * b[0] + a[4] * b[1] + a[12] * b[3],
|
||||||
|
a[0] * b[4] + a[4] * b[5] + a[12] * b[7],
|
||||||
|
a[0] * b[12] + a[4] * b[13] + a[12] * b[15],
|
||||||
|
a[1] * b[0] + a[5] * b[1] + a[13] * b[3],
|
||||||
|
a[1] * b[4] + a[5] * b[5] + a[13] * b[7],
|
||||||
|
a[1] * b[12] + a[5] * b[13] + a[13] * b[15],
|
||||||
|
a[3] * b[0] + a[7] * b[1] + a[15] * b[3],
|
||||||
|
a[3] * b[4] + a[7] * b[5] + a[15] * b[7],
|
||||||
|
a[3] * b[12] + a[7] * b[13] + a[15] * b[15]);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform& Transform::translate(const Vector2f& offset)
|
||||||
|
{
|
||||||
|
Transform translation(1, 0, offset.x,
|
||||||
|
0, 1, offset.y,
|
||||||
|
0, 0, 1);
|
||||||
|
|
||||||
|
return combine(translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform& Transform::scale(const Vector2f& factors)
|
||||||
|
{
|
||||||
|
Transform scaling(factors.x, 0, 0,
|
||||||
|
0, factors.y, 0,
|
||||||
|
0, 0, 1);
|
||||||
|
|
||||||
|
return combine(scaling);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform& Transform::scale(const Vector2f& factors, const Vector2f& center)
|
||||||
|
{
|
||||||
|
Transform scaling(factors.x, 0, center.x * (1 - factors.x),
|
||||||
|
0, factors.y, center.y * (1 - factors.y),
|
||||||
|
0, 0, 1);
|
||||||
|
|
||||||
|
return combine(scaling);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform operator *(const Transform& left, const Transform& right)
|
||||||
|
{
|
||||||
|
return Transform(left).combine(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Transform& operator *=(Transform& left, const Transform& right)
|
||||||
|
{
|
||||||
|
return left.combine(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr Vector2f operator *(const Transform& left, const Vector2f& right)
|
||||||
|
{
|
||||||
|
return left.transformPoint(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr bool operator ==(const Transform& left, const Transform& right)
|
||||||
|
{
|
||||||
|
const float* a = left.getMatrix();
|
||||||
|
const float* b = right.getMatrix();
|
||||||
|
|
||||||
|
return ((a[0] == b[0]) && (a[1] == b[1]) && (a[3] == b[3]) &&
|
||||||
|
(a[4] == b[4]) && (a[5] == b[5]) && (a[7] == b[7]) &&
|
||||||
|
(a[12] == b[12]) && (a[13] == b[13]) && (a[15] == b[15]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
constexpr bool operator !=(const Transform& left, const Transform& right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Static member data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Note: the 'inline' keyword here is technically not required, but VS2019 fails
|
||||||
|
// to compile with a bogus "multiple definition" error if not explicitly used.
|
||||||
|
|
||||||
|
inline constexpr Transform Transform::Identity;
|
@ -30,6 +30,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Graphics/Export.hpp>
|
#include <SFML/Graphics/Export.hpp>
|
||||||
#include <SFML/Graphics/Transform.hpp>
|
#include <SFML/Graphics/Transform.hpp>
|
||||||
|
#include <SFML/System/Angle.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <SFML/Graphics/Export.hpp>
|
#include <SFML/Graphics/Export.hpp>
|
||||||
#include <SFML/Graphics/Rect.hpp>
|
#include <SFML/Graphics/Rect.hpp>
|
||||||
#include <SFML/Graphics/Transform.hpp>
|
#include <SFML/Graphics/Transform.hpp>
|
||||||
|
#include <SFML/System/Angle.hpp>
|
||||||
#include <SFML/System/Vector2.hpp>
|
#include <SFML/System/Vector2.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ set(SRC
|
|||||||
${SRCROOT}/TextureSaver.hpp
|
${SRCROOT}/TextureSaver.hpp
|
||||||
${SRCROOT}/Transform.cpp
|
${SRCROOT}/Transform.cpp
|
||||||
${INCROOT}/Transform.hpp
|
${INCROOT}/Transform.hpp
|
||||||
|
${INCROOT}/Transform.inl
|
||||||
${SRCROOT}/Transformable.cpp
|
${SRCROOT}/Transformable.cpp
|
||||||
${INCROOT}/Transformable.hpp
|
${INCROOT}/Transformable.hpp
|
||||||
${SRCROOT}/View.cpp
|
${SRCROOT}/View.cpp
|
||||||
|
@ -26,142 +26,12 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Graphics/Transform.hpp>
|
#include <SFML/Graphics/Transform.hpp>
|
||||||
|
#include <SFML/System/Angle.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
const Transform Transform::Identity;
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform::Transform()
|
|
||||||
{
|
|
||||||
// Identity matrix
|
|
||||||
m_matrix[0] = 1.f; m_matrix[4] = 0.f; m_matrix[8] = 0.f; m_matrix[12] = 0.f;
|
|
||||||
m_matrix[1] = 0.f; m_matrix[5] = 1.f; m_matrix[9] = 0.f; m_matrix[13] = 0.f;
|
|
||||||
m_matrix[2] = 0.f; m_matrix[6] = 0.f; m_matrix[10] = 1.f; m_matrix[14] = 0.f;
|
|
||||||
m_matrix[3] = 0.f; m_matrix[7] = 0.f; m_matrix[11] = 0.f; m_matrix[15] = 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform::Transform(float a00, float a01, float a02,
|
|
||||||
float a10, float a11, float a12,
|
|
||||||
float a20, float a21, float a22)
|
|
||||||
{
|
|
||||||
m_matrix[0] = a00; m_matrix[4] = a01; m_matrix[8] = 0.f; m_matrix[12] = a02;
|
|
||||||
m_matrix[1] = a10; m_matrix[5] = a11; m_matrix[9] = 0.f; m_matrix[13] = a12;
|
|
||||||
m_matrix[2] = 0.f; m_matrix[6] = 0.f; m_matrix[10] = 1.f; m_matrix[14] = 0.f;
|
|
||||||
m_matrix[3] = a20; m_matrix[7] = a21; m_matrix[11] = 0.f; m_matrix[15] = a22;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
const float* Transform::getMatrix() const
|
|
||||||
{
|
|
||||||
return m_matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform Transform::getInverse() const
|
|
||||||
{
|
|
||||||
// Compute the determinant
|
|
||||||
float det = m_matrix[0] * (m_matrix[15] * m_matrix[5] - m_matrix[7] * m_matrix[13]) -
|
|
||||||
m_matrix[1] * (m_matrix[15] * m_matrix[4] - m_matrix[7] * m_matrix[12]) +
|
|
||||||
m_matrix[3] * (m_matrix[13] * m_matrix[4] - m_matrix[5] * m_matrix[12]);
|
|
||||||
|
|
||||||
// Compute the inverse if the determinant is not zero
|
|
||||||
// (don't use an epsilon because the determinant may *really* be tiny)
|
|
||||||
if (det != 0.f)
|
|
||||||
{
|
|
||||||
return Transform( (m_matrix[15] * m_matrix[5] - m_matrix[7] * m_matrix[13]) / det,
|
|
||||||
-(m_matrix[15] * m_matrix[4] - m_matrix[7] * m_matrix[12]) / det,
|
|
||||||
(m_matrix[13] * m_matrix[4] - m_matrix[5] * m_matrix[12]) / det,
|
|
||||||
-(m_matrix[15] * m_matrix[1] - m_matrix[3] * m_matrix[13]) / det,
|
|
||||||
(m_matrix[15] * m_matrix[0] - m_matrix[3] * m_matrix[12]) / det,
|
|
||||||
-(m_matrix[13] * m_matrix[0] - m_matrix[1] * m_matrix[12]) / det,
|
|
||||||
(m_matrix[7] * m_matrix[1] - m_matrix[3] * m_matrix[5]) / det,
|
|
||||||
-(m_matrix[7] * m_matrix[0] - m_matrix[3] * m_matrix[4]) / det,
|
|
||||||
(m_matrix[5] * m_matrix[0] - m_matrix[1] * m_matrix[4]) / det);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Identity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Vector2f Transform::transformPoint(const Vector2f& point) const
|
|
||||||
{
|
|
||||||
return Vector2f(m_matrix[0] * point.x + m_matrix[4] * point.y + m_matrix[12],
|
|
||||||
m_matrix[1] * point.x + m_matrix[5] * point.y + m_matrix[13]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
FloatRect Transform::transformRect(const FloatRect& rectangle) const
|
|
||||||
{
|
|
||||||
// Transform the 4 corners of the rectangle
|
|
||||||
const Vector2f points[] =
|
|
||||||
{
|
|
||||||
transformPoint({rectangle.left, rectangle.top}),
|
|
||||||
transformPoint({rectangle.left, rectangle.top + rectangle.height}),
|
|
||||||
transformPoint({rectangle.left + rectangle.width, rectangle.top}),
|
|
||||||
transformPoint({rectangle.left + rectangle.width, rectangle.top + rectangle.height})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute the bounding rectangle of the transformed points
|
|
||||||
float left = points[0].x;
|
|
||||||
float top = points[0].y;
|
|
||||||
float right = points[0].x;
|
|
||||||
float bottom = points[0].y;
|
|
||||||
for (int i = 1; i < 4; ++i)
|
|
||||||
{
|
|
||||||
if (points[i].x < left) left = points[i].x;
|
|
||||||
else if (points[i].x > right) right = points[i].x;
|
|
||||||
if (points[i].y < top) top = points[i].y;
|
|
||||||
else if (points[i].y > bottom) bottom = points[i].y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FloatRect({left, top}, {right - left, bottom - top});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform& Transform::combine(const Transform& transform)
|
|
||||||
{
|
|
||||||
const float* a = m_matrix;
|
|
||||||
const float* b = transform.m_matrix;
|
|
||||||
|
|
||||||
*this = Transform(a[0] * b[0] + a[4] * b[1] + a[12] * b[3],
|
|
||||||
a[0] * b[4] + a[4] * b[5] + a[12] * b[7],
|
|
||||||
a[0] * b[12] + a[4] * b[13] + a[12] * b[15],
|
|
||||||
a[1] * b[0] + a[5] * b[1] + a[13] * b[3],
|
|
||||||
a[1] * b[4] + a[5] * b[5] + a[13] * b[7],
|
|
||||||
a[1] * b[12] + a[5] * b[13] + a[13] * b[15],
|
|
||||||
a[3] * b[0] + a[7] * b[1] + a[15] * b[3],
|
|
||||||
a[3] * b[4] + a[7] * b[5] + a[15] * b[7],
|
|
||||||
a[3] * b[12] + a[7] * b[13] + a[15] * b[15]);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform& Transform::translate(const Vector2f& offset)
|
|
||||||
{
|
|
||||||
Transform translation(1, 0, offset.x,
|
|
||||||
0, 1, offset.y,
|
|
||||||
0, 0, 1);
|
|
||||||
|
|
||||||
return combine(translation);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Transform& Transform::rotate(Angle angle)
|
Transform& Transform::rotate(Angle angle)
|
||||||
{
|
{
|
||||||
@ -191,66 +61,4 @@ Transform& Transform::rotate(Angle angle, const Vector2f& center)
|
|||||||
return combine(rotation);
|
return combine(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform& Transform::scale(const Vector2f& factors)
|
|
||||||
{
|
|
||||||
Transform scaling(factors.x, 0, 0,
|
|
||||||
0, factors.y, 0,
|
|
||||||
0, 0, 1);
|
|
||||||
|
|
||||||
return combine(scaling);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform& Transform::scale(const Vector2f& factors, const Vector2f& center)
|
|
||||||
{
|
|
||||||
Transform scaling(factors.x, 0, center.x * (1 - factors.x),
|
|
||||||
0, factors.y, center.y * (1 - factors.y),
|
|
||||||
0, 0, 1);
|
|
||||||
|
|
||||||
return combine(scaling);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform operator *(const Transform& left, const Transform& right)
|
|
||||||
{
|
|
||||||
return Transform(left).combine(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Transform& operator *=(Transform& left, const Transform& right)
|
|
||||||
{
|
|
||||||
return left.combine(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Vector2f operator *(const Transform& left, const Vector2f& right)
|
|
||||||
{
|
|
||||||
return left.transformPoint(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool operator ==(const Transform& left, const Transform& right)
|
|
||||||
{
|
|
||||||
const float* a = left.getMatrix();
|
|
||||||
const float* b = right.getMatrix();
|
|
||||||
|
|
||||||
return ((a[0] == b[0]) && (a[1] == b[1]) && (a[3] == b[3]) &&
|
|
||||||
(a[4] == b[4]) && (a[5] == b[5]) && (a[7] == b[7]) &&
|
|
||||||
(a[12] == b[12]) && (a[13] == b[13]) && (a[15] == b[15]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool operator !=(const Transform& left, const Transform& right)
|
|
||||||
{
|
|
||||||
return !(left == right);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <SFML/Graphics/Transform.hpp>
|
#include <SFML/Graphics/Transform.hpp>
|
||||||
|
#include <SFML/System/Angle.hpp>
|
||||||
#include "GraphicsUtil.hpp"
|
#include "GraphicsUtil.hpp"
|
||||||
#include "SystemUtil.hpp"
|
#include "SystemUtil.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
Loading…
Reference in New Issue
Block a user