1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Math/BsMatrix4.h"
7#include "Math/BsVector3.h"
8#include "Math/BsQuaternion.h"
9#include "Reflection/BsRTTIType.h"
10
11namespace bs
12{
13 /** @addtogroup Scene
14 * @{
15 */
16
17 /**
18 * Contains information about 3D object's position, rotation and scale, and provides methods to manipulate it.
19 */
20 class BS_CORE_EXPORT Transform : public IReflectable
21 {
22 public:
23 Transform() = default;
24 Transform(const Vector3& position, const Quaternion& rotation, const Vector3& scale);
25
26 /** Sets the local position of the object. */
27 void setPosition(const Vector3& position) { mPosition = position; }
28
29 /** Gets the local position of the object. */
30 const Vector3& getPosition() const { return mPosition; }
31
32 /** Shorthand for getPosition(). */
33 const Vector3& pos() const { return mPosition; }
34
35 /** Sets the local rotation of the object. */
36 void setRotation(const Quaternion& rotation) { mRotation = rotation; }
37
38 /** Gets the local rotation of the object. */
39 const Quaternion& getRotation() const { return mRotation; }
40
41 /** Shorthand for getRotation(). */
42 const Quaternion& rot() const { return mRotation; }
43
44 /** Sets the local scale of the object. */
45 void setScale(const Vector3& scale) { mScale = scale; }
46
47 /** Gets the local scale of the object. */
48 const Vector3& getScale() const { return mScale; }
49
50 /** Shorthand for getScale(). */
51 const Vector3& scl() const { return mScale; }
52
53 /**
54 * Converts the provided world position to a space relative to the provided parent, and sets it as the current
55 * transform's position.
56 */
57 void setWorldPosition(const Vector3& position, const Transform& parent);
58
59 /**
60 * Converts the provided world rotation to a space relative to the provided parent, and sets it as the current
61 * transform's rotation.
62 */
63 void setWorldRotation(const Quaternion& rotation, const Transform& parent);
64
65 /**
66 * Converts the provided world scale to a space relative to the provided parent, and sets it as the current
67 * transform's scale.
68 */
69 void setWorldScale(const Vector3& scale, const Transform& parent);
70
71 /** Builds the transform matrix from current translation, rotation and scale properties. */
72 Matrix4 getMatrix() const;
73
74 /** Builds the inverse transform matrix from current translation, rotation and scale properties. */
75 Matrix4 getInvMatrix() const;
76
77 /**
78 * Makes the current transform relative to the provided transform. In another words, converts from a world
79 * coordinate system to one local to the provided transform.
80 */
81 void makeLocal(const Transform& parent);
82
83 /**
84 * Makes the current transform absolute. In another words, converts from a local coordinate system relative to
85 * the provided transform, to a world coordinate system.
86 */
87 void makeWorld(const Transform& parent);
88
89 /**
90 * Orients the object so it is looking at the provided @p location (world space) where @p up is used for
91 * determining the location of the object's Y axis.
92 */
93 void lookAt(const Vector3& location, const Vector3& up = Vector3::UNIT_Y);
94
95 /** Moves the object's position by the vector offset provided along world axes. */
96 void move(const Vector3& vec);
97
98 /** Moves the object's position by the vector offset provided along it's own axes (relative to orientation). */
99 void moveRelative(const Vector3& vec);
100
101 /**
102 * Gets the negative Z (forward) axis of the object.
103 *
104 * @return Forward axis of the object.
105 */
106 Vector3 getForward() const { return getRotation().rotate(-Vector3::UNIT_Z); }
107
108 /**
109 * Gets the Y (up) axis of the object.
110 *
111 * @return Up axis of the object.
112 */
113 Vector3 getUp() const { return getRotation().rotate(Vector3::UNIT_Y); }
114
115 /**
116 * Gets the X (right) axis of the object.
117 *
118 * @return Right axis of the object.
119 */
120 Vector3 getRight() const { return getRotation().rotate(Vector3::UNIT_X); }
121
122 /**
123 * Rotates the game object so it's forward axis faces the provided direction.
124 *
125 * @param[in] forwardDir The forward direction to face.
126 *
127 * @note Local forward axis is considered to be negative Z.
128 */
129 void setForward(const Vector3& forwardDir);
130
131 /** Rotate the object around an arbitrary axis. */
132 void rotate(const Vector3& axis, const Radian& angle);
133
134 /** Rotate the object around an arbitrary axis using a Quaternion. */
135 void rotate(const Quaternion& q);
136
137 /**
138 * Rotates around local Z axis.
139 *
140 * @param[in] angle Angle to rotate by.
141 */
142 void roll(const Radian& angle);
143
144 /**
145 * Rotates around Y axis.
146 *
147 * @param[in] angle Angle to rotate by.
148 */
149 void yaw(const Radian& angle);
150
151 /**
152 * Rotates around X axis
153 *
154 * @param[in] angle Angle to rotate by.
155 */
156 void pitch(const Radian& angle);
157
158 /** Enumerates all the fields in the type and executes the specified processor action for each field. */
159 template<class P>
160 void rttiEnumFields(P p)
161 {
162 p(mPosition);
163 p(mRotation);
164 p(mScale);
165 }
166
167 static Transform IDENTITY;
168 private:
169 Vector3 mPosition = Vector3::ZERO;
170 Quaternion mRotation = Quaternion::IDENTITY;
171 Vector3 mScale = Vector3::ONE;
172
173 /************************************************************************/
174 /* RTTI */
175 /************************************************************************/
176 public:
177 friend class TransformRTTI;
178 static RTTITypeBase* getRTTIStatic();
179 RTTITypeBase* getRTTI() const override;
180 };
181
182 /** @} */
183}
184