Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
transform.h
1#ifndef OE_SCENE_TRANSFORM_H
2#define OE_SCENE_TRANSFORM_H
3
4#include <glm/mat4x4.hpp>
5#include <glm/vec3.hpp>
6
7#include <glm/gtx/quaternion.hpp>
8
9#include <concepts>
10#include "../util/angle.h"
11
12namespace oe::scene
13{
17 template<class V>
18 concept Vector3Type = requires(V v)
19 {
20 {v.x} -> std::convertible_to<float>;
21 {v.y} -> std::convertible_to<float>;
22 {v.z} -> std::convertible_to<float>;
23 };
24
28 template<class V>
29 concept Vector4Type = requires(V v)
30 {
31 {v.x} -> std::convertible_to<float>;
32 {v.y} -> std::convertible_to<float>;
33 {v.z} -> std::convertible_to<float>;
34 {v.w} -> std::convertible_to<float>;
35 };
36
37 template<class T>
38 struct IsPosition : std::false_type {};
39
40 template<class S>
41 struct IsScale : std::false_type {};
42
43 template<class R>
44 struct IsRotation : std::false_type {};
45
46 // Abstract compile time concepts to allow generic types to be used in Transform
47 template<class T>
48 concept TranslationType = IsPosition<T>::value == true && Vector3Type<T>;
49
50 template<class R>
51 concept RotationType = IsRotation<R>::value == true && Vector4Type<R>;
52
53 template<class S>
54 concept ScaleType = IsScale<S>::value == true && Vector3Type<S>;
55
56 // Default specializations to allow glm types
57 template<>struct IsPosition<glm::vec3> : std::true_type {};
58 template<>struct IsRotation<glm::quat> : std::true_type {};
59 template<>struct IsScale<glm::vec3> : std::true_type {};
60
65 {
66 public:
77 const glm::vec3& translation = glm::vec3(0.f),
78 const glm::quat& rotation = glm::quat(1.f, 0.f, 0.f, 0.f),
79 const glm::vec3& scale = glm::vec3(1.f),
80 const glm::vec3& skew = glm::vec3(0.f),
81 const glm::vec4& perspective = glm::vec4(glm::vec3(0.f), 1.f)
82 ):
83 _translation(translation),
84 _rotation(rotation),
85 _scale(scale),
86 _skew(skew),
87 _perspective(perspective)
88 {}
89
95 Transform(const glm::mat4& model)
96 {
97 loadFromModel(model);
98 }
99
105 const glm::vec3& getTranslation() const noexcept
106 {
107 return _translation;
108 }
109
115 const glm::vec3& getPosition() const noexcept
116 {
117 return _translation;
118 }
119
125 const glm::quat& getRotation() const noexcept
126 {
127 return _rotation;
128 }
129
135 const glm::quat& getOrientation() const noexcept
136 {
137 return _rotation;
138 }
139
145 const glm::vec3& getScale() const noexcept
146 {
147 return _scale;
148 }
149
155 const glm::vec3& getSkew() const noexcept
156 {
157 return _skew;
158 }
159
165 const glm::vec4& getPerspective() const noexcept
166 {
167 return _perspective;
168 }
169
177 void setTranslation(const float x, const float y, const float z) noexcept
178 {
179 _translation.x = x;
180 _translation.y = y;
181 _translation.z = z;
182
183 _is_dirty = true;
184 }
185
194 void setPosition(const float x, const float y, const float z) noexcept
195 {
196 setTranslation(x, y, z);
197 }
198
205 void setPosition(const glm::vec3& position) noexcept
206 {
207 setTranslation(position);
208 }
209
217 void setRotation(const lit::Angle& x, const lit::Angle& y, const lit::Angle& z) noexcept
218 {
219 _rotation = glm::quat(glm::vec3(x.getRadians(), y.getRadians(), z.getRadians()));
220
221 _is_dirty = true;
222 }
223
229 void setRotation(const glm::quat& rotation) noexcept
230 {
231 _rotation = rotation;
232
233 _is_dirty = true;
234 }
235
244 void setOrientation(const lit::Angle& x, const lit::Angle& y, const lit::Angle& z) noexcept
245 {
246 setRotation(x, y, z);
247 }
248
255 void setOrientation(const glm::quat& rotation) noexcept
256 {
257 setRotation(rotation);
258 }
259
267 void setScale(const float x, const float y, const float z) noexcept
268 {
269 _scale.x = x;
270 _scale.y = y;
271 _scale.z = z;
272
273 _is_dirty = true;
274 }
275
281 void relativeTranslate(const glm::vec3& translation) noexcept
282 {
283 _translation += translation;
284 _is_dirty = true;
285 }
286
294 void relativeTranslate(const float x, const float y, const float z) noexcept
295 {
296 relativeTranslate(glm::vec3(x, y, z));
297 _is_dirty = true;
298 }
299
305 void loadFromModel(const glm::mat4& model) noexcept;
306
312 void relativeMove(const glm::vec3& translation) noexcept
313 {
314 relativeTranslate(translation);
315 _is_dirty = true;
316 }
317
323 void relativeRotate(const glm::quat& quaternion) noexcept
324 {
325 _rotation = quaternion * _rotation;
326 _is_dirty = true;
327 }
328
338 void relativeRotate(const float x, const float y, const float z) noexcept
339 {
340 relativeRotate(glm::quat(glm::radians(glm::vec3(x, y, z))));
341 _is_dirty = true;
342 }
343
351 void relativeRotate(const lit::Angle& x, const lit::Angle& y, const lit::Angle& z) noexcept
352 {
353 relativeRotate(glm::quat(glm::vec3(x.getRadians(), y.getRadians(), z.getRadians())));
354 _is_dirty = true;
355 }
356
362 void relativeScale(const glm::vec3& scale) noexcept
363 {
364 _scale *= scale;
365 _is_dirty = true;
366 }
367
373 void setSkew(const glm::vec3& skew) noexcept
374 {
375 _skew = skew;
376
377 _is_dirty = true;
378 }
379
385 void setPerspective(const glm::vec4& perspective) noexcept
386 {
387 _perspective = perspective;
388
389 _is_dirty = true;
390 }
391
398 void interpolateWith(const float ratio, const Transform& target) noexcept
399 {
400 _translation = glm::mix(_translation, target._translation, ratio);
401 _rotation = glm::slerp(_rotation, target._rotation, ratio);
402 _scale = glm::mix(_scale, target._scale, ratio);
403 _skew = glm::mix(_skew, target._skew, ratio);
404 _perspective = glm::mix(_perspective, target._perspective, ratio);
405
406 _is_dirty = true;
407 }
408
414 void fillFrom(const Transform& transform) noexcept
415 {
416 _translation = transform._translation;
417 _rotation = transform._rotation;
418 _scale = transform._scale;
419 _skew = transform._skew;
420 _perspective = transform._perspective;
421
422 _is_dirty = true;
423 }
424
430 template<TranslationType T>
431 void setTranslation(const T& translation) noexcept
432 {
433 _translation.x = translation.x;
434 _translation.y = translation.y;
435 _translation.z = translation.z;
436
437 _is_dirty = true;
438 }
439
445 template<RotationType R>
446 void setRotation(const R& rotation) noexcept
447 {
448 _rotation.x = rotation.x;
449 _rotation.y = rotation.y;
450 _rotation.z = rotation.z;
451 _rotation.w = rotation.w;
452
453 _is_dirty = true;
454 }
455
461 template<ScaleType S>
462 void setScale(const S& scale) noexcept
463 {
464 _scale.x = scale.x;
465 _scale.y = scale.y;
466 _scale.z = scale.z;
467
468 _is_dirty = true;
469 }
470
478 template<TranslationType T>
479 void getTranslationAs(T& result) const noexcept
480 {
481 result.x = _translation.x;
482 result.y = _translation.y;
483 result.z = _translation.z;
484 }
485
493 template<RotationType R>
494 void getRotationAs(R& result) const noexcept
495 {
496 result.x = _rotation.x;
497 result.y = _rotation.y;
498 result.z = _rotation.z;
499 result.w = _rotation.w;
500 }
501
509 template<ScaleType S>
510 void getScaleAs(S& result) const noexcept
511 {
512 result.x = _scale.x;
513 result.y = _scale.y;
514 result.z = _scale.z;
515 }
516
521 glm::mat4 getModelMatrix() const noexcept;
522
528 inline bool isDirty() const noexcept
529 {
530 return _is_dirty;
531 }
532
533 protected:
538 void forceDirty(const bool is_dirty) const noexcept
539 {
540 _is_dirty = is_dirty;
541 }
542
543 private:
544 glm::vec3 _translation;
545 glm::quat _rotation;
546 glm::vec3 _scale;
547 glm::vec3 _skew;
548 glm::vec4 _perspective;
549
550 mutable bool _is_dirty = true;
551 };
552}
553#endif
Manage local Translation / Rotation / Scale of an entity in the world.
Definition transform.h:65
void relativeRotate(const lit::Angle &x, const lit::Angle &y, const lit::Angle &z) noexcept
Relatively rotate the transform using a lit::Angle triad.
Definition transform.h:351
void setPerspective(const glm::vec4 &perspective) noexcept
Set perspective effect of the transform.
Definition transform.h:385
void relativeMove(const glm::vec3 &translation) noexcept
Move the transform relative to current translation.
Definition transform.h:312
void setOrientation(const glm::quat &rotation) noexcept
Set orientation of the transform using a quaternion.
Definition transform.h:255
void setRotation(const lit::Angle &x, const lit::Angle &y, const lit::Angle &z) noexcept
Rotate the transform from Euler angles.
Definition transform.h:217
void setPosition(const float x, const float y, const float z) noexcept
Translate to the specified position.
Definition transform.h:194
const glm::vec3 & getSkew() const noexcept
Get Skew component value of the transform.
Definition transform.h:155
void interpolateWith(const float ratio, const Transform &target) noexcept
Interpolate this transform with another one.
Definition transform.h:398
void loadFromModel(const glm::mat4 &model) noexcept
Fill the transform from a model matrix.
void setScale(const float x, const float y, const float z) noexcept
Set scaling.
Definition transform.h:267
const glm::vec3 & getTranslation() const noexcept
Get Translation component value of the transform.
Definition transform.h:105
const glm::vec3 & getScale() const noexcept
Get Scaling component value of the transform.
Definition transform.h:145
void setScale(const S &scale) noexcept
Set scale vector from a generic type.
Definition transform.h:462
void getRotationAs(R &result) const noexcept
Get rotation quaternion and fill in generic type.
Definition transform.h:494
void setRotation(const glm::quat &rotation) noexcept
Rotate the transform using a quaternion.
Definition transform.h:229
void relativeScale(const glm::vec3 &scale) noexcept
Multiply current scale by the new one.
Definition transform.h:362
void setPosition(const glm::vec3 &position) noexcept
Translate to the specified position.
Definition transform.h:205
void relativeRotate(const float x, const float y, const float z) noexcept
Rotate the transform from Euler angles (component wise)
Definition transform.h:338
Transform(const glm::vec3 &translation=glm::vec3(0.f), const glm::quat &rotation=glm::quat(1.f, 0.f, 0.f, 0.f), const glm::vec3 &scale=glm::vec3(1.f), const glm::vec3 &skew=glm::vec3(0.f), const glm::vec4 &perspective=glm::vec4(glm::vec3(0.f), 1.f))
Generate Transform from its translation, rotation, scale values.
Definition transform.h:76
void setOrientation(const lit::Angle &x, const lit::Angle &y, const lit::Angle &z) noexcept
Set orientation of transform using lit::Angle triad.
Definition transform.h:244
const glm::vec3 & getPosition() const noexcept
Get Translation component value of the transform.
Definition transform.h:115
const glm::vec4 & getPerspective() const noexcept
get Perspective component value of the transform
Definition transform.h:165
const glm::quat & getRotation() const noexcept
Get Rotation component value of the transform.
Definition transform.h:125
void forceDirty(const bool is_dirty) const noexcept
Set custom dirty status.
Definition transform.h:538
void fillFrom(const Transform &transform) noexcept
Fill current values from another transform.
Definition transform.h:414
bool isDirty() const noexcept
Check if something modified this transform.
Definition transform.h:528
Transform(const glm::mat4 &model)
Generate Transform from a model matrix.
Definition transform.h:95
void setTranslation(const T &translation) noexcept
Translate to the specified position.
Definition transform.h:431
void getScaleAs(S &result) const noexcept
Get scale vector and fill in generic type.
Definition transform.h:510
const glm::quat & getOrientation() const noexcept
Get orientation of the transform.
Definition transform.h:135
void relativeRotate(const glm::quat &quaternion) noexcept
Rotate the transform relative to current rotation.
Definition transform.h:323
void getTranslationAs(T &result) const noexcept
Get translation vector and fill in generic type.
Definition transform.h:479
void setRotation(const R &rotation) noexcept
Get rotation quaternion from a generic type.
Definition transform.h:446
void setTranslation(const float x, const float y, const float z) noexcept
Translate to the specified position, filled component wise.
Definition transform.h:177
void relativeTranslate(const glm::vec3 &translation) noexcept
Translate the transform from current position.
Definition transform.h:281
void relativeTranslate(const float x, const float y, const float z) noexcept
relative translate the transform from current position, component wise
Definition transform.h:294
void setSkew(const glm::vec3 &skew) noexcept
Set skew of the transform.
Definition transform.h:373
glm::mat4 getModelMatrix() const noexcept
Generate a Model matrix from the transform.
Definition transform.h:51
Definition transform.h:54
Definition transform.h:48
Represent a generic vector of 3 floats.
Definition transform.h:18
Represent a generic vector of 4 floats.
Definition transform.h:29
Scene related management (Render-agnostic Geometry, Manger, etc...)
Definition debug.h:19
Wrapper and helper to abstract conversions between degree and radian angles.
Definition angle.h:19
Definition transform.h:38
Definition transform.h:44
Definition transform.h:41