/*############################################################################## ## Author: Shaun Reed ## ## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ## ## About: Transform3D class to represent object position in 3D space ## ## From following tutorials at trentreed.net ## ## ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ##############################################################################*/ #ifndef QTK_TRANSFORM3D_H #define QTK_TRANSFORM3D_H #include #include #include #ifndef QT_NO_DEBUG_STREAM #include #endif #include "qtkapi.h" namespace Qtk { /** * Transform3D class to represent and modify object position in 3D space. */ class QTKAPI Transform3D { public: /************************************************************************* * Constructors, Destructors ************************************************************************/ inline Transform3D() : m_dirty(true), mScale(1.0f, 1.0f, 1.0f), mTranslation(0.0f, 0.0f, 0.0f) {} /************************************************************************* * Public Methods ************************************************************************/ /** * @param dt Translation from last to current position. */ void translate(const QVector3D & dt); /** * @param dx X translation from last to current position. * @param dy Y translation from last to current position. * @param dz Z translation from last to current position. */ inline void translate(float dx, float dy, float dz) { translate(QVector3D(dx, dy, dz)); } /** * Scale the object size. * * @param ds Scalar vector to apply to the transform. */ void scale(const QVector3D & ds); /** * Scale the object size. * * @param dx Amount to scale on the X axis. * @param dy Amount to scale on the Y axis. * @param dz Amount to scale on the Z axis. */ inline void scale(float dx, float dy, float dz) { scale(QVector3D(dx, dy, dz)); } /** * Scale the object size. * * @param factor Scalar to apply to all axis of the object. */ inline void scale(float factor) { scale(QVector3D(factor, factor, factor)); } /** * @param ds 3D vector to add to scale axis. */ void grow(const QVector3D & ds); /** * @param dx Amount to grow X axis. * @param dy Amount to grow Y axis. * @param dz Amount to grow Z axis. */ inline void grow(float dx, float dy, float dz) { grow(QVector3D(dx, dy, dz)); } /** * @param factor Amount to grow all axis equally. */ inline void grow(float factor) { grow(QVector3D(factor, factor, factor)); } /** * @param dr Rotation to apply to the transform. */ void rotate(const QQuaternion & dr); /** * @param angle Angle to rotate. * @param axis Axis to rotate apply the rotation on. */ inline void rotate(float angle, const QVector3D & axis) { rotate(QQuaternion::fromAxisAndAngle(axis, angle)); } /** * Apply rotation upon an axis represented by the 3D vector (x, y, z) * * @param angle Angle to rotate. * @param ax X axis to apply the rotation on. * @param ay Y axis to apply the rotation on. * @param az Z axis to apply the rotation on. */ inline void rotate(float angle, float ax, float ay, float az) { rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle)); } /************************************************************************* * Setters ************************************************************************/ /** * @param t Position to move the transform to. */ void setTranslation(const QVector3D & t); /** * @param x X position to set transform. * @param y Y position to set transform. * @param z Z position to set transform. */ inline void setTranslation(float x, float y, float z) { setTranslation(QVector3D(x, y, z)); } /** * @param s Scale to set for this transform. */ void setScale(const QVector3D & s); /** * @param x X axis scale to set for this transform. * @param y Y axis scale to set for this transform. * @param z Z axis scale to set for this transform. */ inline void setScale(float x, float y, float z) { setScale(QVector3D(x, y, z)); } /** * @param k Scale to set for all axis on this transform. */ inline void setScale(float k) { setScale(QVector3D(k, k, k)); } /** * @param r Rotation to set for this transform. */ void setRotation(const QQuaternion & r); /** * @param angle Angle to set for rotation. * @param axis Axis to set rotation for. */ inline void setRotation(float angle, const QVector3D & axis) { setRotation(QQuaternion::fromAxisAndAngle(axis, angle)); } /** * Sets a rotation upon an axis represented by the 3D vector (x, y, z) * * @param angle Angle to set rotation. * @param ax X axis to set angle for. * @param ay Y axis to set angle for. * @param az Z axis to set angle for. */ inline void setRotation(float angle, float ax, float ay, float az) { setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle)); } /************************************************************************* * Getters ************************************************************************/ /** * @return Translation for this transform. */ [[nodiscard]] inline const QVector3D & getTranslation() const { return mTranslation; } /** * @return Scale for this transform. */ [[nodiscard]] inline const QVector3D & getScale() const { return mScale; } /** * @return Rotation for this transform. */ [[nodiscard]] inline const QQuaternion & getRotation() const { return mRotation; } /** * @return Model to world matrix for this transform. * transformation * rotation * scale = ModelToWorld */ const QMatrix4x4 & toMatrix(); /** * @return Forward vector for this transform. */ [[nodiscard]] QVector3D getForward() const; /** * @return Up vector for this transform. */ [[nodiscard]] QVector3D getUp() const; /** * @return Right vector for this transform. */ [[nodiscard]] QVector3D getRight() const; /************************************************************************* * Public Members ************************************************************************/ static const QVector3D LocalForward, LocalUp, LocalRight; private: /************************************************************************* * Private Members ************************************************************************/ QVector3D mTranslation; QQuaternion mRotation; QVector3D mScale; QMatrix4x4 mWorld; bool m_dirty; #ifndef QT_NO_DATASTREAM friend QDataStream & operator<<( QDataStream & out, const Transform3D & transform); friend QDataStream & operator>>( QDataStream & in, Transform3D & transform); #endif }; #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const Transform3D & transform); #endif #ifndef QT_NO_DATASTREAM QDataStream & operator<<(QDataStream & out, const Transform3D & transform); QDataStream & operator>>(QDataStream & in, Transform3D & transform); #endif } // namespace Qtk Q_DECLARE_TYPEINFO(Qtk::Transform3D, Q_MOVABLE_TYPE); #endif // QTK_TRANSFORM3D_H