MoveComponent.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/scene/Common.h>
  7. #include <anki/scene/SceneComponent.h>
  8. #include <anki/util/Bitset.h>
  9. #include <anki/util/Enum.h>
  10. #include <anki/Math.h>
  11. namespace anki
  12. {
  13. /// @addtogroup scene
  14. /// @{
  15. enum class MoveComponentFlag : U8
  16. {
  17. NONE = 0,
  18. /// Get the parent's world transform
  19. IGNORE_LOCAL_TRANSFORM = 1 << 1,
  20. /// Ignore parent's transform
  21. IGNORE_PARENT_TRANSFORM = 1 << 2,
  22. /// If dirty then is marked for update
  23. MARKED_FOR_UPDATE = 1 << 3,
  24. };
  25. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(MoveComponentFlag, inline)
  26. /// Interface for movable scene nodes
  27. class MoveComponent : public SceneComponent, public Bitset<MoveComponentFlag>
  28. {
  29. public:
  30. using Flag = MoveComponentFlag;
  31. static Bool classof(const SceneComponent& c)
  32. {
  33. return c.getType() == Type::MOVE;
  34. }
  35. /// The one and only constructor
  36. /// @param node The scene node to steal it's allocators
  37. /// @param flags The flags
  38. MoveComponent(SceneNode* node, Flag flags = Flag::NONE);
  39. ~MoveComponent();
  40. const Transform& getLocalTransform() const
  41. {
  42. return m_ltrf;
  43. }
  44. void setLocalTransform(const Transform& x)
  45. {
  46. m_ltrf = x;
  47. markForUpdate();
  48. }
  49. void setLocalOrigin(const Vec4& x)
  50. {
  51. m_ltrf.setOrigin(x);
  52. markForUpdate();
  53. }
  54. const Vec4& getLocalOrigin() const
  55. {
  56. return m_ltrf.getOrigin();
  57. }
  58. void setLocalRotation(const Mat3x4& x)
  59. {
  60. m_ltrf.setRotation(x);
  61. markForUpdate();
  62. }
  63. const Mat3x4& getLocalRotation() const
  64. {
  65. return m_ltrf.getRotation();
  66. }
  67. void setLocalScale(F32 x)
  68. {
  69. m_ltrf.setScale(x);
  70. markForUpdate();
  71. }
  72. F32 getLocalScale() const
  73. {
  74. return m_ltrf.getScale();
  75. }
  76. const Transform& getWorldTransform() const
  77. {
  78. return m_wtrf;
  79. }
  80. const Transform& getPreviousWorldTransform() const
  81. {
  82. return m_prevWTrf;
  83. }
  84. /// Called when there is an update in the world transformation.
  85. virtual ANKI_USE_RESULT Error onMoveComponentUpdate(
  86. SceneNode& node, F32 prevTime, F32 crntTime)
  87. {
  88. return ErrorCode::NONE;
  89. }
  90. /// @name SceneComponent overrides
  91. /// @{
  92. /// Update self and children world transform recursively, if root node.
  93. /// Need to call this at every frame.
  94. /// @note Don't update if child because we start from roots and go to
  95. /// children and we don't want a child to be updated before the
  96. /// parent
  97. ANKI_USE_RESULT Error update(SceneNode&, F32, F32, Bool& updated) override;
  98. ANKI_USE_RESULT Error onUpdate(
  99. SceneNode& node, F32 prevTime, F32 crntTime) final
  100. {
  101. return onMoveComponentUpdate(node, prevTime, crntTime);
  102. }
  103. /// @}
  104. /// @name Mess with the local transform
  105. /// @{
  106. void rotateLocalX(F32 angDegrees)
  107. {
  108. m_ltrf.getRotation().rotateXAxis(angDegrees);
  109. markForUpdate();
  110. }
  111. void rotateLocalY(F32 angDegrees)
  112. {
  113. m_ltrf.getRotation().rotateYAxis(angDegrees);
  114. markForUpdate();
  115. }
  116. void rotateLocalZ(F32 angDegrees)
  117. {
  118. m_ltrf.getRotation().rotateZAxis(angDegrees);
  119. markForUpdate();
  120. }
  121. void moveLocalX(F32 distance)
  122. {
  123. Vec3 x_axis = m_ltrf.getRotation().getColumn(0);
  124. m_ltrf.getOrigin() += Vec4(x_axis, 0.0) * distance;
  125. markForUpdate();
  126. }
  127. void moveLocalY(F32 distance)
  128. {
  129. Vec3 y_axis = m_ltrf.getRotation().getColumn(1);
  130. m_ltrf.getOrigin() += Vec4(y_axis, 0.0) * distance;
  131. markForUpdate();
  132. }
  133. void moveLocalZ(F32 distance)
  134. {
  135. Vec3 z_axis = m_ltrf.getRotation().getColumn(2);
  136. m_ltrf.getOrigin() += Vec4(z_axis, 0.0) * distance;
  137. markForUpdate();
  138. }
  139. void scale(F32 s)
  140. {
  141. m_ltrf.getScale() *= s;
  142. markForUpdate();
  143. }
  144. /// @}
  145. private:
  146. /// The transformation in local space
  147. Transform m_ltrf = Transform::getIdentity();
  148. /// The transformation in world space (local combined with parent's
  149. /// transformation)
  150. Transform m_wtrf = Transform::getIdentity();
  151. /// Keep the previous transformation for checking if it moved
  152. Transform m_prevWTrf = Transform::getIdentity();
  153. void markForUpdate()
  154. {
  155. enableBits(Flag::MARKED_FOR_UPDATE);
  156. }
  157. /// Called every frame. It updates the @a m_wtrf if @a shouldUpdateWTrf
  158. /// is true. Then it moves to the children.
  159. Bool updateWorldTransform(SceneNode& node);
  160. };
  161. /// @}
  162. } // end namespace anki