RavEngine
Loading...
Searching...
No Matches
Transform.hpp
1#pragma once
2//
3// Transform.h
4// RavEngine_Static
5//
6// Copyright © 2020 Ravbug.
7//
8
9#include "Atomic.hpp"
10#include "mathtypes.hpp"
11#include "ComponentHandle.hpp"
12#include "Queryable.hpp"
13#include "Common3D.hpp"
15#include "DataStructures.hpp"
16#include "ComponentWithOwner.hpp"
17#include "Arch.hpp"
18
19namespace RavEngine {
20 struct Transform : public ComponentWithOwner, public Queryable<Transform> {
21 protected:
22 mutable matrix4 matrix; // defined as the world space transform of the PARENT
23 UnorderedVector<ComponentHandle<Transform>> children; //non-owning
24 quaternion rotation;
25 ComponentHandle<Transform> parent; //non-owning
26 vector3 position, scale;
27 mutable bool isDirty : 1 = true; // used for when the transform hierarchy has been changed
28 mutable bool isTickDirty : 1 = true; // used for when this transform has been updated in the current tick and needs updating in the world's render data
29
30 // sanity checking for optimal struct padding
31#if RVE_64_BIT
32 static_assert(sizeof(matrix) >= sizeof(children), "Invalid struct order");
33 static_assert(sizeof(children) >= sizeof(rotation), "Invalid struct order");
34 static_assert(sizeof(rotation) >= sizeof(position), "Invalid struct order");
35 static_assert(sizeof(parent) >= sizeof(position), "Invalid struct order");
36#endif
37
38 friend class World;
39
40 inline void MarkAsDirty() const{
41 isDirty = true;
42 isTickDirty = true;
43 }
44
45 inline void ClearTickDirty() {
46 isTickDirty = false;
47 }
48
49 inline void UpdateChildren()
50 {
51 MarkAsDirty();
52 if (children.size() > 0) [[unlikely]] {
53 constexpr auto update = [](Transform* transform, auto&& updatefn) -> void {
54 transform->MarkAsDirty();
55 auto newParentMatrix = transform->GetWorldMatrix();
56 for (auto& child : transform->children) {
57 auto component = child.get();
58 component->matrix = newParentMatrix;
59
60 updatefn(component, updatefn);
61 }
62 };
63 update(this, update);
64 }
65 }
66
67 public:
68 inline bool getTickDirty() const{
69 return isTickDirty;
70 }
71
72 Transform(Entity owner, const vector3& inpos, const quaternion& inrot, const vector3& inscale) : ComponentWithOwner(owner), matrix(1){
76 }
77 Transform(Entity owner) : Transform(owner, vector3(0, 0, 0), quaternion(1.0, 0.0, 0.0, 0.0), vector3(1, 1, 1)) {}
78
79 MOVE_NO_COPY(Transform);
80
84 Transform& WorldTranslateDelta(const vector3&);
85
89
91 Transform& LocalScaleDelta(const vector3&);
92
93 Transform& SetLocalScale(const decimalType& scale){ SetLocalScale(vector3(scale,scale,scale)); return *this;}
94
95 vector3 Forward() const;
96 vector3 Right() const;
97 vector3 Up() const;
98
99 vector3 WorldForward() const;
100 vector3 WorldRight() const;
101 vector3 WorldUp() const;
102
103 inline bool HasParent() const{
104 return parent.IsValid();
105 }
106
107 vector3 GetLocalPosition() const;
108 vector3 GetWorldPosition() const;
109
110 quaternion GetLocalRotation() const;
111 quaternion GetWorldRotation() const;
112
113 vector3 GetLocalScale() const;
114
116
117 matrix4 GetMatrix() const;
118
124 return matrix * GenerateLocalMatrix();
125 }
126
127 matrix4 GetParentSpaceMatrix() const {
128 return matrix;
129 }
130
135 Transform& AddChild(ComponentHandle<Transform> child);
136
141 Transform& RemoveChild(ComponentHandle<Transform> child);
142
143 const decltype(children)& GetChildren() const{
144 return children;
145 }
146
147 // destroy everything parented to this
148 void Destroy(){
149 for(auto& child : children){
150 child.GetOwner().Destroy();
151 }
152 }
153};
154
160 return glm::translate(matrix4(1), (vector3)position) * glm::toMat4((quaternion)rotation) * glm::scale(matrix4(1), (vector3)scale);
161 }
162
167 return (quaternion)rotation * vector3_forward;
168 }
169
173 inline vector3 Transform::Up() const{
174 return (quaternion)rotation * vector3_up;
175 }
176
180 inline vector3 Transform::Right() const{
181 return (quaternion)rotation * vector3_right;
182 }
183
184 inline vector3 Transform::WorldForward() const{
185 return GetWorldRotation() * vector3_forward;
186 }
187
188 inline vector3 Transform::WorldRight() const{
189 return GetWorldRotation() * vector3_right;
190 }
191
192 inline vector3 Transform::WorldUp() const{
193 return GetWorldRotation() * vector3_up;
194 }
195
201 //set position value
202 position += delta;
203 UpdateChildren();
204 return *this;
205 }
206
207 inline Transform& Transform::WorldTranslateDelta(const vector3& delta){
208 SetWorldPosition(GetWorldPosition() + delta);
209 return *this;
210 }
211
217 //set position value
218 position = newPos;
219 UpdateChildren();
220 return *this;
221 }
222
228 if (!HasParent()) {
230 }
231 else {
232 //get the world position
233 auto worldpos = GetWorldPosition();
234 //get the displacement to the new world coords from the current local position
235 auto displacement = newPos - worldpos;
236 //update the local pos to that displacement
238 }
239 return *this;
240 }
241
247 rotation = newRot;
248 UpdateChildren();
249 return *this;
250 }
251
257 // sum two quaternions by multiplying them
258 rotation *= delta;
259 UpdateChildren();
260 return *this;
261 }
262
268 if (!HasParent()) {
270 }
271 else {
272 //get world rotation
273 auto worldRot = GetWorldRotation();
274 //get the relative world offset
276 //apply the rotation
278 }
279 return *this;
280 }
281
287 scale = newScale;
288 UpdateChildren();
289 return *this;
290 }
291
292 inline Transform& Transform::LocalScaleDelta(const vector3& delta) {
293 scale += delta;
294 UpdateChildren();
295 return *this;
296 }
297
298 inline vector3 Transform::GetLocalPosition() const
299 {
300 return position;
301 }
302
303 inline quaternion Transform::GetLocalRotation() const
304 {
305 return rotation;
306 }
307
308 inline vector3 Transform::GetLocalScale() const
309 {
310 return scale;
311 }
312
313
319 return matrix;
320 }
321
322 inline vector3 Transform::GetWorldPosition() const
323 {
324 if (!HasParent()) {
325 return GetLocalPosition();
326 }
327
328 return GetParentSpaceMatrix() * vector4(GetLocalPosition(),1);
329 }
330
331 inline quaternion Transform::GetWorldRotation() const
332 {
333 if (!HasParent()) {
334 return GetLocalRotation();
335 }
336
337 auto finalMatrix = GetParentSpaceMatrix() * glm::toMat4(GetLocalRotation());
338
339 return glm::quat_cast(finalMatrix);
340 }
341}
Definition ComponentWithOwner.hpp:6
Definition World.hpp:181
Definition concurrentqueue.h:747
GLM_FUNC_QUALIFIER mat< C, R, T, Q > inverse(mat< C, R, T, Q > const &m)
Definition func_matrix.inl:388
GLM_FUNC_DECL mat< 4, 4, T, Q > translate(mat< 4, 4, T, Q > const &m, vec< 3, T, Q > const &v)
Definition matrix_transform.inl:10
GLM_FUNC_DECL mat< 4, 4, T, Q > scale(mat< 4, 4, T, Q > const &m, vec< 3, T, Q > const &v)
Definition matrix_transform.inl:78
GLM_FUNC_DECL qua< T, Q > quat_cast(mat< 3, 3, T, Q > const &x)
Definition quaternion.inl:75
GLM_FUNC_DECL mat< 4, 4, T, Q > toMat4(qua< T, Q > const &x)
Definition quaternion.hpp:120
GLM_FUNC_DECL qua< T, Q > rotation(vec< 3, T, Q > const &orig, vec< 3, T, Q > const &dest)
Definition quaternion.inl:122
Definition Animation.hpp:6
Definition Entity.hpp:11
Definition Queryable.hpp:21
Definition Transform.hpp:20
Transform & SetWorldPosition(const vector3 &)
Definition Transform.hpp:227
vector3 Up() const
Definition Transform.hpp:173
Transform & AddChild(ComponentHandle< Transform > child)
Definition Transform.cpp:10
Transform & SetLocalRotation(const quaternion &)
Definition Transform.hpp:246
matrix4 GetWorldMatrix() const
Definition Transform.hpp:123
Transform & LocalRotateDelta(const quaternion &)
Definition Transform.hpp:256
matrix4 GenerateLocalMatrix() const
Definition Transform.hpp:159
Transform & LocalTranslateDelta(const vector3 &)
Definition Transform.hpp:200
Transform & RemoveChild(ComponentHandle< Transform > child)
Definition Transform.cpp:25
Transform & SetLocalScale(const vector3 &)
Definition Transform.hpp:286
vector3 Forward() const
Definition Transform.hpp:166
Transform & SetLocalPosition(const vector3 &)
Definition Transform.hpp:216
Transform & SetWorldRotation(const quaternion &)
Definition Transform.hpp:267
matrix4 GetMatrix() const
Definition Transform.hpp:318
vector3 Right() const
Definition Transform.hpp:180
Definition qualifier.hpp:36
Definition type_quat.hpp:20
Definition qualifier.hpp:35