|
|
|||
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 ////////////////////////////////////////////////////////////
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|