| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #ifndef ANKI_SCENE_MOVE_COMPONENT_H
- #define ANKI_SCENE_MOVE_COMPONENT_H
- #include "anki/util/Bitset.h"
- #include "anki/Math.h"
- #include "anki/core/Timestamp.h"
- #include "anki/scene/Common.h"
- namespace anki {
- /// @addtogroup Scene
- /// @{
- /// Interface for movable scene nodes
- class MoveComponent:
- public SceneHierarchicalObject<MoveComponent>,
- public Bitset<U8>
- {
- public:
- typedef SceneHierarchicalObject<MoveComponent> Base;
- enum MoveComponentFlag
- {
- MF_NONE = 0,
- /// Get the parent's world transform
- MF_IGNORE_LOCAL_TRANSFORM = 1 << 1,
- /// If dirty then is marked for update
- MF_MARKED_FOR_UPDATE = 1 << 3,
- };
- /// @name Constructors & destructor
- /// @{
- /// The one and only constructor
- /// @param node The scene node to steal it's allocators
- /// @param flags The flags
- MoveComponent(SceneNode* node, U32 flags = MF_NONE);
- ~MoveComponent();
- /// @}
- /// @name Accessors
- /// @{
- const Transform& getLocalTransform() const
- {
- return lTrf;
- }
- void setLocalTransform(const Transform& x)
- {
- lTrf = x;
- markForUpdate();
- }
- void setLocalOrigin(const Vec3& x)
- {
- lTrf.setOrigin(x);
- markForUpdate();
- }
- void setLocalRotation(const Mat3& x)
- {
- lTrf.setRotation(x);
- markForUpdate();
- }
- void setLocalScale(F32 x)
- {
- lTrf.setScale(x);
- markForUpdate();
- }
- const Transform& getWorldTransform() const
- {
- return wTrf;
- }
- const Transform& getPrevWorldTransform() const
- {
- return prevWTrf;
- }
- Timestamp getTimestamp() const
- {
- return timestamp;
- }
- /// @}
- /// @name Mess with the local transform
- /// @{
- void rotateLocalX(F32 angDegrees)
- {
- lTrf.getRotation().rotateXAxis(angDegrees);
- markForUpdate();
- }
- void rotateLocalY(F32 angDegrees)
- {
- lTrf.getRotation().rotateYAxis(angDegrees);
- markForUpdate();
- }
- void rotateLocalZ(F32 angDegrees)
- {
- lTrf.getRotation().rotateZAxis(angDegrees);
- markForUpdate();
- }
- void moveLocalX(F32 distance)
- {
- Vec3 x_axis = lTrf.getRotation().getColumn(0);
- lTrf.getOrigin() += x_axis * distance;
- markForUpdate();
- }
- void moveLocalY(F32 distance)
- {
- Vec3 y_axis = lTrf.getRotation().getColumn(1);
- lTrf.getOrigin() += y_axis * distance;
- markForUpdate();
- }
- void moveLocalZ(F32 distance)
- {
- Vec3 z_axis = lTrf.getRotation().getColumn(2);
- lTrf.getOrigin() += z_axis * distance;
- markForUpdate();
- }
- void scale(F32 s)
- {
- lTrf.getScale() *= s;
- markForUpdate();
- }
- /// @}
- /// This is called by the @a update() method only when the object had
- /// actually moved. It's overridable
- virtual void moveUpdate()
- {}
- /// Update self and children world transform recursively, if root node.
- /// Need to call this at every frame.
- /// @note Don't update if child because we start from roots and go to
- /// children and we don't want a child to be updated before the
- /// parent
- void update();
- private:
- /// The transformation in local space
- Transform lTrf = Transform::getIdentity();
- /// The transformation in world space (local combined with parent's
- /// transformation)
- Transform wTrf = Transform::getIdentity();
- /// Keep the previous transformation for checking if it moved
- Transform prevWTrf = Transform::getIdentity();
- /// The frame where it was last moved
- Timestamp timestamp = getGlobTimestamp();
- /// Called every frame. It updates the @a wTrf if @a shouldUpdateWTrf
- /// is true. Then it moves to the children.
- void updateWorldTransform();
- void markForUpdate()
- {
- enableBits(MF_MARKED_FOR_UPDATE);
- }
- };
- /// @}
- } // end namespace anki
- #endif
|