Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:58:14

0001 ////////////////////////////////////////////////////////////
0002 //
0003 // SFML - Simple and Fast Multimedia Library
0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
0005 //
0006 // This software is provided 'as-is', without any express or implied warranty.
0007 // In no event will the authors be held liable for any damages arising from the use of this software.
0008 //
0009 // Permission is granted to anyone to use this software for any purpose,
0010 // including commercial applications, and to alter it and redistribute it freely,
0011 // subject to the following restrictions:
0012 //
0013 // 1. The origin of this software must not be misrepresented;
0014 //    you must not claim that you wrote the original software.
0015 //    If you use this software in a product, an acknowledgment
0016 //    in the product documentation would be appreciated but is not required.
0017 //
0018 // 2. Altered source versions must be plainly marked as such,
0019 //    and must not be misrepresented as being the original software.
0020 //
0021 // 3. This notice may not be removed or altered from any source distribution.
0022 //
0023 ////////////////////////////////////////////////////////////
0024 
0025 #ifndef SFML_TRANSFORMABLE_HPP
0026 #define SFML_TRANSFORMABLE_HPP
0027 
0028 ////////////////////////////////////////////////////////////
0029 // Headers
0030 ////////////////////////////////////////////////////////////
0031 #include <SFML/Graphics/Export.hpp>
0032 #include <SFML/Graphics/Transform.hpp>
0033 
0034 
0035 namespace sf
0036 {
0037 ////////////////////////////////////////////////////////////
0038 /// \brief Decomposed transform defined by a position, a rotation and a scale
0039 ///
0040 ////////////////////////////////////////////////////////////
0041 class SFML_GRAPHICS_API Transformable
0042 {
0043 public:
0044 
0045     ////////////////////////////////////////////////////////////
0046     /// \brief Default constructor
0047     ///
0048     ////////////////////////////////////////////////////////////
0049     Transformable();
0050 
0051     ////////////////////////////////////////////////////////////
0052     /// \brief Virtual destructor
0053     ///
0054     ////////////////////////////////////////////////////////////
0055     virtual ~Transformable();
0056 
0057     ////////////////////////////////////////////////////////////
0058     /// \brief set the position of the object
0059     ///
0060     /// This function completely overwrites the previous position.
0061     /// See the move function to apply an offset based on the previous position instead.
0062     /// The default position of a transformable object is (0, 0).
0063     ///
0064     /// \param x X coordinate of the new position
0065     /// \param y Y coordinate of the new position
0066     ///
0067     /// \see move, getPosition
0068     ///
0069     ////////////////////////////////////////////////////////////
0070     void setPosition(float x, float y);
0071 
0072     ////////////////////////////////////////////////////////////
0073     /// \brief set the position of the object
0074     ///
0075     /// This function completely overwrites the previous position.
0076     /// See the move function to apply an offset based on the previous position instead.
0077     /// The default position of a transformable object is (0, 0).
0078     ///
0079     /// \param position New position
0080     ///
0081     /// \see move, getPosition
0082     ///
0083     ////////////////////////////////////////////////////////////
0084     void setPosition(const Vector2f& position);
0085 
0086     ////////////////////////////////////////////////////////////
0087     /// \brief set the orientation of the object
0088     ///
0089     /// This function completely overwrites the previous rotation.
0090     /// See the rotate function to add an angle based on the previous rotation instead.
0091     /// The default rotation of a transformable object is 0.
0092     ///
0093     /// \param angle New rotation, in degrees
0094     ///
0095     /// \see rotate, getRotation
0096     ///
0097     ////////////////////////////////////////////////////////////
0098     void setRotation(float angle);
0099 
0100     ////////////////////////////////////////////////////////////
0101     /// \brief set the scale factors of the object
0102     ///
0103     /// This function completely overwrites the previous scale.
0104     /// See the scale function to add a factor based on the previous scale instead.
0105     /// The default scale of a transformable object is (1, 1).
0106     ///
0107     /// \param factorX New horizontal scale factor
0108     /// \param factorY New vertical scale factor
0109     ///
0110     /// \see scale, getScale
0111     ///
0112     ////////////////////////////////////////////////////////////
0113     void setScale(float factorX, float factorY);
0114 
0115     ////////////////////////////////////////////////////////////
0116     /// \brief set the scale factors of the object
0117     ///
0118     /// This function completely overwrites the previous scale.
0119     /// See the scale function to add a factor based on the previous scale instead.
0120     /// The default scale of a transformable object is (1, 1).
0121     ///
0122     /// \param factors New scale factors
0123     ///
0124     /// \see scale, getScale
0125     ///
0126     ////////////////////////////////////////////////////////////
0127     void setScale(const Vector2f& factors);
0128 
0129     ////////////////////////////////////////////////////////////
0130     /// \brief set the local origin of the object
0131     ///
0132     /// The origin of an object defines the center point for
0133     /// all transformations (position, scale, rotation).
0134     /// The coordinates of this point must be relative to the
0135     /// top-left corner of the object, and ignore all
0136     /// transformations (position, scale, rotation).
0137     /// The default origin of a transformable object is (0, 0).
0138     ///
0139     /// \param x X coordinate of the new origin
0140     /// \param y Y coordinate of the new origin
0141     ///
0142     /// \see getOrigin
0143     ///
0144     ////////////////////////////////////////////////////////////
0145     void setOrigin(float x, float y);
0146 
0147     ////////////////////////////////////////////////////////////
0148     /// \brief set the local origin of the object
0149     ///
0150     /// The origin of an object defines the center point for
0151     /// all transformations (position, scale, rotation).
0152     /// The coordinates of this point must be relative to the
0153     /// top-left corner of the object, and ignore all
0154     /// transformations (position, scale, rotation).
0155     /// The default origin of a transformable object is (0, 0).
0156     ///
0157     /// \param origin New origin
0158     ///
0159     /// \see getOrigin
0160     ///
0161     ////////////////////////////////////////////////////////////
0162     void setOrigin(const Vector2f& origin);
0163 
0164     ////////////////////////////////////////////////////////////
0165     /// \brief get the position of the object
0166     ///
0167     /// \return Current position
0168     ///
0169     /// \see setPosition
0170     ///
0171     ////////////////////////////////////////////////////////////
0172     const Vector2f& getPosition() const;
0173 
0174     ////////////////////////////////////////////////////////////
0175     /// \brief get the orientation of the object
0176     ///
0177     /// The rotation is always in the range [0, 360].
0178     ///
0179     /// \return Current rotation, in degrees
0180     ///
0181     /// \see setRotation
0182     ///
0183     ////////////////////////////////////////////////////////////
0184     float getRotation() const;
0185 
0186     ////////////////////////////////////////////////////////////
0187     /// \brief get the current scale of the object
0188     ///
0189     /// \return Current scale factors
0190     ///
0191     /// \see setScale
0192     ///
0193     ////////////////////////////////////////////////////////////
0194     const Vector2f& getScale() const;
0195 
0196     ////////////////////////////////////////////////////////////
0197     /// \brief get the local origin of the object
0198     ///
0199     /// \return Current origin
0200     ///
0201     /// \see setOrigin
0202     ///
0203     ////////////////////////////////////////////////////////////
0204     const Vector2f& getOrigin() const;
0205 
0206     ////////////////////////////////////////////////////////////
0207     /// \brief Move the object by a given offset
0208     ///
0209     /// This function adds to the current position of the object,
0210     /// unlike setPosition which overwrites it.
0211     /// Thus, it is equivalent to the following code:
0212     /// \code
0213     /// sf::Vector2f pos = object.getPosition();
0214     /// object.setPosition(pos.x + offsetX, pos.y + offsetY);
0215     /// \endcode
0216     ///
0217     /// \param offsetX X offset
0218     /// \param offsetY Y offset
0219     ///
0220     /// \see setPosition
0221     ///
0222     ////////////////////////////////////////////////////////////
0223     void move(float offsetX, float offsetY);
0224 
0225     ////////////////////////////////////////////////////////////
0226     /// \brief Move the object by a given offset
0227     ///
0228     /// This function adds to the current position of the object,
0229     /// unlike setPosition which overwrites it.
0230     /// Thus, it is equivalent to the following code:
0231     /// \code
0232     /// object.setPosition(object.getPosition() + offset);
0233     /// \endcode
0234     ///
0235     /// \param offset Offset
0236     ///
0237     /// \see setPosition
0238     ///
0239     ////////////////////////////////////////////////////////////
0240     void move(const Vector2f& offset);
0241 
0242     ////////////////////////////////////////////////////////////
0243     /// \brief Rotate the object
0244     ///
0245     /// This function adds to the current rotation of the object,
0246     /// unlike setRotation which overwrites it.
0247     /// Thus, it is equivalent to the following code:
0248     /// \code
0249     /// object.setRotation(object.getRotation() + angle);
0250     /// \endcode
0251     ///
0252     /// \param angle Angle of rotation, in degrees
0253     ///
0254     ////////////////////////////////////////////////////////////
0255     void rotate(float angle);
0256 
0257     ////////////////////////////////////////////////////////////
0258     /// \brief Scale the object
0259     ///
0260     /// This function multiplies the current scale of the object,
0261     /// unlike setScale which overwrites it.
0262     /// Thus, it is equivalent to the following code:
0263     /// \code
0264     /// sf::Vector2f scale = object.getScale();
0265     /// object.setScale(scale.x * factorX, scale.y * factorY);
0266     /// \endcode
0267     ///
0268     /// \param factorX Horizontal scale factor
0269     /// \param factorY Vertical scale factor
0270     ///
0271     /// \see setScale
0272     ///
0273     ////////////////////////////////////////////////////////////
0274     void scale(float factorX, float factorY);
0275 
0276     ////////////////////////////////////////////////////////////
0277     /// \brief Scale the object
0278     ///
0279     /// This function multiplies the current scale of the object,
0280     /// unlike setScale which overwrites it.
0281     /// Thus, it is equivalent to the following code:
0282     /// \code
0283     /// sf::Vector2f scale = object.getScale();
0284     /// object.setScale(scale.x * factor.x, scale.y * factor.y);
0285     /// \endcode
0286     ///
0287     /// \param factor Scale factors
0288     ///
0289     /// \see setScale
0290     ///
0291     ////////////////////////////////////////////////////////////
0292     void scale(const Vector2f& factor);
0293 
0294     ////////////////////////////////////////////////////////////
0295     /// \brief get the combined transform of the object
0296     ///
0297     /// \return Transform combining the position/rotation/scale/origin of the object
0298     ///
0299     /// \see getInverseTransform
0300     ///
0301     ////////////////////////////////////////////////////////////
0302     const Transform& getTransform() const;
0303 
0304     ////////////////////////////////////////////////////////////
0305     /// \brief get the inverse of the combined transform of the object
0306     ///
0307     /// \return Inverse of the combined transformations applied to the object
0308     ///
0309     /// \see getTransform
0310     ///
0311     ////////////////////////////////////////////////////////////
0312     const Transform& getInverseTransform() const;
0313 
0314 private:
0315 
0316     ////////////////////////////////////////////////////////////
0317     // Member data
0318     ////////////////////////////////////////////////////////////
0319     Vector2f          m_origin;                     //!< Origin of translation/rotation/scaling of the object
0320     Vector2f          m_position;                   //!< Position of the object in the 2D world
0321     float             m_rotation;                   //!< Orientation of the object, in degrees
0322     Vector2f          m_scale;                      //!< Scale of the object
0323     mutable Transform m_transform;                  //!< Combined transformation of the object
0324     mutable bool      m_transformNeedUpdate;        //!< Does the transform need to be recomputed?
0325     mutable Transform m_inverseTransform;           //!< Combined transformation of the object
0326     mutable bool      m_inverseTransformNeedUpdate; //!< Does the transform need to be recomputed?
0327 };
0328 
0329 } // namespace sf
0330 
0331 
0332 #endif // SFML_TRANSFORMABLE_HPP
0333 
0334 
0335 ////////////////////////////////////////////////////////////
0336 /// \class sf::Transformable
0337 /// \ingroup graphics
0338 ///
0339 /// This class is provided for convenience, on top of sf::Transform.
0340 ///
0341 /// sf::Transform, as a low-level class, offers a great level of
0342 /// flexibility but it is not always convenient to manage. Indeed,
0343 /// one can easily combine any kind of operation, such as a translation
0344 /// followed by a rotation followed by a scaling, but once the result
0345 /// transform is built, there's no way to go backward and, let's say,
0346 /// change only the rotation without modifying the translation and scaling.
0347 /// The entire transform must be recomputed, which means that you
0348 /// need to retrieve the initial translation and scale factors as
0349 /// well, and combine them the same way you did before updating the
0350 /// rotation. This is a tedious operation, and it requires to store
0351 /// all the individual components of the final transform.
0352 ///
0353 /// That's exactly what sf::Transformable was written for: it hides
0354 /// these variables and the composed transform behind an easy to use
0355 /// interface. You can set or get any of the individual components
0356 /// without worrying about the others. It also provides the composed
0357 /// transform (as a sf::Transform), and keeps it up-to-date.
0358 ///
0359 /// In addition to the position, rotation and scale, sf::Transformable
0360 /// provides an "origin" component, which represents the local origin
0361 /// of the three other components. Let's take an example with a 10x10
0362 /// pixels sprite. By default, the sprite is positioned/rotated/scaled
0363 /// relatively to its top-left corner, because it is the local point
0364 /// (0, 0). But if we change the origin to be (5, 5), the sprite will
0365 /// be positioned/rotated/scaled around its center instead. And if
0366 /// we set the origin to (10, 10), it will be transformed around its
0367 /// bottom-right corner.
0368 ///
0369 /// To keep the sf::Transformable class simple, there's only one
0370 /// origin for all the components. You cannot position the sprite
0371 /// relatively to its top-left corner while rotating it around its
0372 /// center, for example. To do such things, use sf::Transform directly.
0373 ///
0374 /// sf::Transformable can be used as a base class. It is often
0375 /// combined with sf::Drawable -- that's what SFML's sprites,
0376 /// texts and shapes do.
0377 /// \code
0378 /// class MyEntity : public sf::Transformable, public sf::Drawable
0379 /// {
0380 ///     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
0381 ///     {
0382 ///         states.transform *= getTransform();
0383 ///         target.draw(..., states);
0384 ///     }
0385 /// };
0386 ///
0387 /// MyEntity entity;
0388 /// entity.setPosition(10, 20);
0389 /// entity.setRotation(45);
0390 /// window.draw(entity);
0391 /// \endcode
0392 ///
0393 /// It can also be used as a member, if you don't want to use
0394 /// its API directly (because you don't need all its functions,
0395 /// or you have different naming conventions for example).
0396 /// \code
0397 /// class MyEntity
0398 /// {
0399 /// public:
0400 ///     void SetPosition(const MyVector& v)
0401 ///     {
0402 ///         myTransform.setPosition(v.x(), v.y());
0403 ///     }
0404 ///
0405 ///     void Draw(sf::RenderTarget& target) const
0406 ///     {
0407 ///         target.draw(..., myTransform.getTransform());
0408 ///     }
0409 ///
0410 /// private:
0411 ///     sf::Transformable myTransform;
0412 /// };
0413 /// \endcode
0414 ///
0415 /// A note on coordinates and undistorted rendering: \n
0416 /// By default, SFML (or more exactly, OpenGL) may interpolate drawable objects
0417 /// such as sprites or texts when rendering. While this allows transitions
0418 /// like slow movements or rotations to appear smoothly, it can lead to
0419 /// unwanted results in some cases, for example blurred or distorted objects.
0420 /// In order to render a sf::Drawable object pixel-perfectly, make sure
0421 /// the involved coordinates allow a 1:1 mapping of pixels in the window
0422 /// to texels (pixels in the texture). More specifically, this means:
0423 /// * The object's position, origin and scale have no fractional part
0424 /// * The object's and the view's rotation are a multiple of 90 degrees
0425 /// * The view's center and size have no fractional part
0426 ///
0427 /// \see sf::Transform
0428 ///
0429 ////////////////////////////////////////////////////////////