Advertisement
Guest User

Transform.cpp

a guest
Apr 6th, 2020
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.45 KB | None | 0 0
  1. #include "World/Transform.h"
  2. #include <3rd Party\imgui\imgui.h>
  3.  
  4. Vector3 Transform::Position() const
  5. {
  6.     if (m_HashChanged)
  7.     {
  8.         UpdateTransform();
  9.     }
  10.  
  11.     return m_WorldPosition;
  12. }
  13.  
  14. void Transform::SetPosition(const Vector3& worldPosition)
  15. {
  16.     if (!m_Parent)
  17.     {
  18.         SetLocalPosition(worldPosition);
  19.     }
  20.     else
  21.     {
  22.         // Transform the world position relative to the parents space
  23.         SetLocalPosition(Matrix4::Inverse(m_Parent->World()).Transform(worldPosition));
  24.     }
  25. }
  26.  
  27. Quaternion Transform::Rotation() const
  28. {
  29.     if (m_HashChanged)
  30.     {
  31.         UpdateTransform();
  32.     }
  33.  
  34.     return m_WorldRotation;
  35. }
  36.  
  37. void Transform::SetRotation(const Quaternion& worldRotation)
  38. {
  39.     if (!m_Parent)
  40.     {
  41.         SetLocalRotation(worldRotation);
  42.     }
  43.     else
  44.     {
  45.         // Transform the world position relative to the parents space
  46.         SetLocalRotation(Quaternion::Inverse(m_Parent->Rotation()) * worldRotation);
  47.     }
  48. }
  49.  
  50. void Transform::SetRotation(const Vector3& worldRotation)
  51. {
  52.     if (!m_Parent)
  53.     {
  54.         SetLocalRotation(worldRotation);
  55.     }
  56.     else
  57.     {
  58.         // Transform world rotation into local space of heirarchy, just uses the quat version.
  59.         SetLocalRotation(Quaternion::Inverse(m_Parent->Rotation()) * Quaternion::Euler(worldRotation));
  60.     }
  61. }
  62.  
  63. Vector3 Transform::Scale() const
  64. {
  65.     if (m_HashChanged)
  66.     {
  67.         UpdateTransform();
  68.     }
  69.    
  70.     return m_WorldScale;
  71. }
  72.  
  73. void Transform::SetScale(const Vector3& scale)
  74. {
  75.     if (!m_Parent)
  76.     {
  77.         SetLocalScale(scale);
  78.     }
  79.     else
  80.     {
  81.         SetLocalScale(scale / m_Parent->Scale());
  82.     }
  83. }
  84.  
  85. Vector3 Transform::Right() const
  86. {
  87.     return m_LocalRotation * Vector3::Right;
  88. }
  89.  
  90. Vector3 Transform::Up() const
  91. {
  92.     return m_LocalRotation * Vector3::Up;
  93. }
  94.  
  95. Vector3 Transform::Forward() const
  96. {
  97.     return m_LocalRotation * Vector3::Forward;
  98. }
  99.  
  100. Matrix4 Transform::World() const
  101. {
  102.     if (m_HashChanged)
  103.     {
  104.         // Got to update immediatly
  105.         UpdateTransform();
  106.     }
  107.  
  108.     return m_World;
  109. }
  110.  
  111. Matrix4 Transform::WorldToLocalMatrix() const
  112. {
  113.     return Matrix4::Inverse(World());
  114. }
  115.  
  116. Vector3 Transform::LocalPosition() const
  117. {
  118.     return m_LocalPosition;
  119. }
  120.  
  121. void Transform::SetLocalPosition(const Vector3& position)
  122. {
  123.     HasChanged();
  124.     m_LocalPosition = position;
  125. }
  126.  
  127. Quaternion Transform::LocalRotation() const
  128. {
  129.     return m_LocalRotation;
  130. }
  131.  
  132. void Transform::SetLocalRotation(const Quaternion& quat)
  133. {
  134.     HasChanged();
  135.     m_Euler = Quaternion::ToEuler(quat);
  136.     m_LocalRotation = Quaternion::Normalize(quat);
  137. }
  138.  
  139. void Transform::SetLocalRotation(const Vector3& euler)
  140. {
  141.     HasChanged();
  142.     m_Euler = euler;
  143.     m_LocalRotation = Quaternion::Normalize(Quaternion::Euler(euler));
  144. }
  145.  
  146. Vector3 Transform::LocalScale() const
  147. {
  148.     return m_LocalScale;
  149. }
  150.  
  151. void Transform::SetLocalScale(const Vector3& scale)
  152. {
  153.     HasChanged();
  154.     m_LocalScale = scale;
  155. }
  156.  
  157. Transform* Transform::Parent() const
  158. {
  159.     return m_Parent;
  160. }
  161.  
  162. void Transform::SetParent(Transform* parent)
  163. {
  164.     if (parent)
  165.     {
  166.         // Set parent and add as child to parent.
  167.         m_Parent = parent;
  168.         m_Parent->m_Children.push_back(parent);
  169.     }
  170. }
  171.  
  172. Transform* Transform::GetChild(Uint32 index)
  173. {
  174.     if (index >= m_Children.size()) { return nullptr; }
  175.     return m_Children[index];
  176. }
  177.  
  178. void Transform::DetatchChildren()
  179. {
  180.     HasChanged();
  181.     m_Children.clear();
  182. }
  183.  
  184. Uint32 Transform::ChildCount()
  185. {
  186.     return (Uint32)m_Children.size();
  187. }
  188.  
  189. void Transform::Translate(const Vector3& translation, Space space)
  190. {
  191.     HasChanged();
  192.  
  193.     // Add parent to this!
  194.     if (space == Space::Self)
  195.     {
  196.         // Moves relative to objects coordinates
  197.         m_LocalPosition += m_LocalRotation * translation;
  198.     }
  199.     else if (space == Space::World)
  200.     {
  201.         if (!m_Parent)
  202.         {
  203.             m_LocalPosition += translation;
  204.         }
  205.         else
  206.         {
  207.             // Transform the translation into local space relative ot the parent hierarchy
  208.             // Then transform using it.
  209.             m_LocalPosition += Matrix4::Inverse(m_Parent->World()).Transform(translation);
  210.         }
  211.     }
  212. }
  213.  
  214. // My quat multiplcation seems to be backward to everyone elses???
  215. void Transform::Rotate(const Quaternion& quat, Space space)
  216. {
  217.     HasChanged();
  218.  
  219.     if (space == Space::Self)
  220.     {
  221.         m_LocalRotation = Quaternion::Normalize(quat * m_LocalRotation);
  222.     }
  223.     else if (space == Space::World)
  224.     {
  225.         if (!m_Parent)
  226.         {
  227.             m_LocalRotation = Quaternion::Normalize(m_LocalRotation * quat);
  228.         }
  229.         else
  230.         {
  231.             Quaternion worldRotation = m_Parent->Rotation();
  232.             m_LocalRotation = Quaternion::Normalize(m_LocalRotation * (Quaternion::Inverse(worldRotation) * quat));
  233.         }
  234.     }
  235. }
  236.  
  237. void Transform::Rotate(const Vector3& euler, Space space)
  238. {
  239.     Rotate(Quaternion::Euler(euler), space);
  240. }
  241.  
  242. void Transform::LookAt(const Transform target, Vector3 worldUp)
  243. {
  244.     Rotate(Quaternion::LookRotation(target.Position(), worldUp), Space::World);
  245. }
  246.  
  247. void Transform::OnGui()
  248. {
  249.     if (ImGui::CollapsingHeader("Transform: "))
  250.     {
  251.         ImGui::Spacing();
  252.         // Position
  253.         ImGui::Text("Position");
  254.         if (ImGui::DragFloat3("##Position", (float*)&m_LocalPosition, 0.01f, -FLT_MAX, FLT_MAX))
  255.         {
  256.             HasChanged();
  257.         }
  258.  
  259.         // Rotation
  260.         ImGui::Text("Rotation");
  261.         if (ImGui::DragFloat3("##Rotation", (float*)&m_Euler, 1.0f, -FLT_MAX, FLT_MAX))
  262.         {
  263.             SetLocalRotation(m_Euler);
  264.         }
  265.  
  266.         // Scale
  267.         ImGui::Checkbox("Uniform Scale: ", &m_UniformScale);
  268.         ImGui::Text("Scale");
  269.         if (m_UniformScale)
  270.         {
  271.             if (ImGui::DragFloat("##Scale", (float*)&m_LocalScale, 1, -FLT_MAX, FLT_MAX))
  272.             {
  273.                 m_LocalScale.y = m_LocalScale.x;
  274.                 m_LocalScale.z = m_LocalScale.x;
  275.                 HasChanged();
  276.             }
  277.         }
  278.         else
  279.         {
  280.             if (ImGui::DragFloat3("##Scale", (float*)&m_LocalScale, 0.1f, -FLT_MAX, FLT_MAX)) { HasChanged(); }
  281.         }
  282.     }
  283. }
  284.  
  285. void Transform::HasChanged() const
  286. {
  287.     if (m_HashChanged) { return; }
  288.     m_HashChanged = true;
  289.  
  290.     // Update all the children to reflect our change!
  291.     for (size_t i = 0; i < m_Children.size(); i++)
  292.     {
  293.         m_Children[i]->HasChanged();
  294.     }
  295. }
  296.  
  297. void Transform::UpdateTransform() const
  298. {
  299.     if (!m_Parent)
  300.     {
  301.         // Its just the exact same thing
  302.         m_World = Matrix4::Scale(m_LocalScale) * Matrix4::Rotate(m_LocalRotation) * Matrix4::Translation(m_LocalPosition);
  303.         m_WorldPosition = m_LocalPosition;
  304.         m_WorldRotation = m_LocalRotation;
  305.         m_WorldScale    = m_LocalScale;
  306.     }
  307.     else
  308.     {
  309.         // Get local relative to parent, then construct matrix.
  310.         m_WorldPosition = m_Parent->World().Transform(m_LocalPosition);
  311.         m_WorldRotation = m_Parent->Rotation() * m_LocalRotation;
  312.         m_WorldScale    = m_Parent->Scale() * m_LocalScale;
  313.  
  314.         m_World = Matrix4::Scale(m_WorldScale) * Matrix4::Rotate(m_WorldRotation) * Matrix4::Translation(m_WorldPosition);
  315.     }
  316.  
  317.     m_HashChanged = false;
  318. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement