Advertisement
Guest User

Untitled

a guest
Jul 15th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.12 KB | None | 0 0
  1. //
  2. // Created by mtesseract on 7/5/19.
  3. //
  4.  
  5. #ifndef MACH_TRANSFORM_HPP
  6. #define MACH_TRANSFORM_HPP
  7.  
  8. #include <math/linalg/LinAlgTypes.hpp>
  9. #include <math/linalg/Matrix/RotationMatrix.hpp>
  10. #include <math/linalg/Matrix/ScaleMatrix.hpp>
  11. #include <math/linalg/Matrix/MatrixUtils.hpp>
  12. #include <auxiliary/Properties.hpp>
  13.  
  14.  
  15. namespace mach {
  16.     template<typename T>
  17.     class Transform {
  18.         Matrix4<T> m_local_transform;
  19.  
  20.         Vector3<T> m_local_position;
  21.         Quaternion<T> m_local_rotation;
  22.         Vector3<T> m_local_scale;
  23.  
  24.         Matrix4<T> m_world_transform;
  25.  
  26.         Vector3<T> m_world_position;
  27.         Quaternion<T> m_world_rotation;
  28.         Vector3<T> m_world_scale;
  29.  
  30.         bool m_changed;
  31.  
  32.         std::vector<std::weak_ptr<Transform>> m_children;
  33.         std::shared_ptr<Transform> m_parent;
  34.  
  35.         void notify_children() {
  36.             for (int i = m_children.size() - 1; i >= 0; --i) {
  37.                 auto child = m_children[i].lock();
  38.                 child->mark_changed();
  39.             }
  40.         }
  41.  
  42.         void update_transform() {
  43.             m_local_transform = math::compose_trs(m_local_position, m_local_rotation, m_local_scale);
  44.             if (m_parent) {
  45.                 m_world_transform = m_parent->get_mat() * m_local_transform;
  46.             } else {
  47.                 m_world_transform = m_local_transform;
  48.             }
  49.             update_world_vars();
  50.             notify_children();
  51.             m_changed = false;
  52.         }
  53.  
  54.         //To be used in conjunction with the world pos/rot/scale setters
  55.         Matrix4<T> create_local_transform(const Matrix4<T> &p_world_transform) {
  56.             if (m_parent) {
  57.                 return m_local_transform = m_parent->get_mat().inverse() * p_world_transform;
  58.             } else {
  59.                 return m_local_transform = p_world_transform;
  60.             }
  61.         }
  62.  
  63.         void update_world_vars() {
  64.             math::decompose_trs(m_world_transform, &m_world_position, &m_world_rotation, &m_world_scale);
  65.         }
  66.  
  67.         void update_local_vars() {
  68.             math::decompose_trs(m_local_transform, &m_local_position, &m_local_rotation, &m_local_scale);
  69.         }
  70.  
  71.         void add_child(std::weak_ptr<Transform> p_child) {
  72.             auto it = std::find(m_children.begin(), m_children.end(),
  73.                                 p_child); //This line will not work for some reason
  74.             if (it == m_children.end()) {
  75.                 m_children.push_back(p_child);
  76.                 p_child.lock()->m_parent = this; //This line will not work
  77.             }
  78.         }
  79.  
  80.         void check_mat() {
  81.             if (m_changed) {
  82.                 update_transform();
  83.             }
  84.         }
  85.  
  86.         void mark_changed() {
  87.             m_changed = true;
  88.             notify_children();
  89.         }
  90.  
  91.     public:
  92.  
  93.         Transform(const Vector3<T> &p_position = Vector3<T>::zero(),
  94.                   const Quaternion<T> &p_rotation = Quaternion<T>::identity(),
  95.                   const Vector3<T> &p_scale = Vector3<T>::one()) :
  96.                 m_local_position(p_position),
  97.                 m_local_rotation(p_rotation),
  98.                 m_local_scale(p_scale),
  99.                 m_local_transform(Matrix4<T>::identity()),
  100.                 m_world_position(Vector3<T>::zero()),
  101.                 m_world_rotation(Quaternion<T>::identity()),
  102.                 m_world_scale(Vector3<T>::one()),
  103.                 m_world_transform(Matrix4<T>::identity()),
  104.                 m_changed(true),
  105.                 m_parent(nullptr) {
  106.         }
  107.  
  108.         static void add_child(std::shared_ptr<Transform> p_parent, std::weak_ptr<Transform> p_child) {
  109.             if (p_parent && !p_child.expired()) {
  110.                 p_parent->m_children.push_back(p_child);
  111.                 p_child.lock()->m_parent = p_parent;
  112.             }
  113.         }
  114.  
  115.         PROPERTY_READONLY(Quaternion<T>, rotation, get_world_rotation);
  116.         PROPERTY(Vector3<T>, position, get_world_position, set_world_position);
  117.         PROPERTY_READONLY(Vector3<T>, scale, get_world_scale);
  118.         PROPERTY(Quaternion<T>, local_rotation, get_local_rotation, set_local_rotation);
  119.         PROPERTY(Vector3<T>, local_position, get_local_position, set_local_position);
  120.         PROPERTY(Vector3<T>, local_scale, get_local_scale, set_local_scale);
  121.  
  122.         Matrix4<T> get_mat() {
  123.             check_mat();
  124.             return m_local_transform;
  125.         }
  126.  
  127.         void set_world_position(const Vector3<T> &p_position) {
  128.             m_world_position = p_position;
  129.             m_world_transform[3] = Vector4<T>(p_position.x, p_position.y, p_position.z, m_world_transform[3][3]);
  130.             create_local_transform(m_world_transform);
  131.             update_local_vars();
  132.             notify_children();
  133.         };
  134.  
  135.         void set_world_position(const Quaternion<T> &p_rotation) {
  136.             m_world_rotation = p_rotation;
  137.             //m_world_transform[3] = Vector4<T>(p_position.x, p_position.y, p_position.z, m_world_transform[3][3]);
  138.             create_local_transform(m_world_transform);
  139.             update_local_vars();
  140.             notify_children();
  141.         };
  142.  
  143.         Quaternion<T> get_world_rotation() {
  144.             check_mat();
  145.             return m_world_rotation;
  146.         };
  147.  
  148.         Vector3<T> get_world_position() {
  149.             check_mat();
  150.             return m_world_position;
  151.         };
  152.  
  153.         Vector3<T> get_world_scale() {
  154.             check_mat();
  155.             return m_world_scale;
  156.         };
  157.  
  158.         Quaternion<T> get_local_rotation() const {
  159.             return m_local_rotation;
  160.         };
  161.  
  162.         Vector3<T> get_local_position() const {
  163.             return m_local_position;
  164.         };
  165.  
  166.         Vector3<T> get_local_scale() const {
  167.             return m_local_scale;
  168.         };
  169.  
  170.         void set_local_rotation(const Quaternion<T> &p_rotation) {
  171.             mark_changed();
  172.             m_local_rotation = p_rotation;
  173.         };
  174.  
  175.         void set_local_position(const Vector3<T> &p_position) {
  176.             mark_changed();
  177.             m_local_position = p_position;
  178.         };
  179.  
  180.         void set_local_scale(const Vector3<T> &p_scale) {
  181.             mark_changed();
  182.             m_local_scale = p_scale;
  183.         };
  184.     };
  185. }
  186.  
  187. #endif //MACH_TRANSFORM_HPP
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement