Fillwave  10.0.0
Moveable.h
1 #pragma once
2 
3 /*
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2018 Filip Wasil and Fillwave community members
7  *
8  * Permission is hereby granted, free of charge, to any person
9  * obtaining a copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
12  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <flw/cmn/scene/Moveable.h>
25 
26 #include <flw/cmn/Observable.h>
27 #include <flw/cmn/Easing.h>
28 #include <flw/cmn/Containers.h>
29 #include <flw/cmn/Aliases.h>
30 
31 #include <vector>
32 #include <functional>
33 #include <algorithm>
34 
35 #include <flw/Math.h>
36 
37 namespace flw {
38 
43 class Moveable : public Observable {
44 public:
45  Moveable(
46  glm::vec3 translation = glm::vec3(0.0)
47  , glm::quat rotation = glm::quat(1.0, 0.0, 0.0, 0.0)
48  , unsigned int callbacks = 1);
49 
50  ~Moveable() override;
51 
52  Moveable &operator=(const Moveable&);
53 
54  Moveable(const Moveable&);
55 
56  Moveable& operator= (Moveable &&);
57 
58  Moveable (Moveable&&);
59 
60  void moveTo(glm::vec3 coordinates);
61 
62  void moveToX(float distance);
63 
64  void moveToY(float distance);
65 
66  void moveToZ(float distance);
67 
68  void moveBy(glm::vec3 coordinates);
69 
70  void moveByX(float distance);
71 
72  void moveByY(float distance);
73 
74  void moveByZ(float distance);
75 
76  void moveInDirection(glm::vec3 direction);
77 
78  glm::vec3 getTranslation();
79 
80  void scaleTo(float scale);
81 
82  void scaleTo(glm::vec3 scale);
83 
84  void scaleToX(float scale);
85 
86  void scaleToY(float scale);
87 
88  void scaleToZ(float scale);
89 
90  glm::vec3 getScale();
91 
92  void rotateTo(glm::quat rotation);
93 
94  void rotateTo(const glm::vec3 &axis, float angle);
95 
96  void rotateBy(const glm::vec3 &axis, float angle);
97 
98  void rotateByX(float angle);
99 
100  void rotateByY(float angle);
101 
102  void rotateByZ(float angle);
103 
104  glm::quat getRotation();
105 
106  void updateMatrixCache();
107 
108  bool isRefresh() const;
109 
110  void setRefresh(bool state);
111 
112  /* Parent */
113  glm::mat4 getParentMMC() const;
114 
115  glm::quat getParentRotation() const;
116 
117  void waitInTime(float deltaTime);
118 
119  void moveBy(float deltaTime, const glm::vec3& deltaMove, Callback<float(float)> ease = LinearInterpolation);
120 
121  void moveTo(float durationInSeconds, const glm::vec3& endTranslation, Callback<float(float)> ease);
122 
123  void scaleBy(float deltaTime, const glm::vec3& aScale, Callback<float(float)> ease = LinearInterpolation);
124 
125  void scaleTo(float deltaTime, const glm::vec3& aScale, Callback<float(float)> ease = LinearInterpolation);
126 
127  void rotateBy(float deltaTime, const float aAngle, const glm::vec3& aAxis, Callback<float(float)> ease = LinearInterpolation);
128 
129  void rotateTo(float deltaTime, const float aAngle, const glm::vec3& aAxis, Callback<float(float)> ease = LinearInterpolation);
130 
131  void loop(int loops);
132 
133  void stop();
134 
135  bool isMoving();
136 
137  float stepInTime(float delta);
138 
139  void attachTimeCallback(float deltaTime, Callback<float(float)> aAction);
140 
141  template <typename ...ARGS>
142  void attachTimeCallback(float deltaTime, Callback<float(float, ARGS...)> aAction, ARGS&&... args) {
143  mTimeCallbacks.push_back([this, deltaTime, aAction, args...](float aDeltaTime) {
144  if (mCallbackTimePassed == 0.0f) {
145  aAction(0.0f, std::forward<ARGS...>(args...));
146  }
147  mCallbackTimePassed += aDeltaTime;
148  aAction(mCallbackTimePassed/deltaTime >= 1.0f ? 1.0f : mCallbackTimePassed/deltaTime, args...);
149  if (mCallbackTimePassed < deltaTime) {
150  return 0.0f;
151  }
152  float timeLeft = mCallbackTimePassed - deltaTime;
153  mCallbackTimePassed = 0;
154  return timeLeft;
155  });
156  }
157 
158 protected:
159  glm::fvec3 mTranslation;
160  glm::quat mRotation;
161  glm::vec3 mScale;
162 
163  /* Parent */
164  glm::quat mParentRotation;
165 
166  /* MMC - Model Matrix Cache */
167  glm::mat4 mMMC;
168  glm::mat4 mParentMMC;
169 
170  /* Refresh flag */
171  bool mRefresh;
172 
173  float mCallbackTimePassed;
174 
175  private:
176  unsigned int mCurrentCallbackIdx;
177  unsigned int mCallbackLoops;
178  vec<Callback<float(float)>> mTimeCallbacks;
179 
180  struct {
181  glm::vec3 mTranslation;
182  glm::vec3 mScale;
183  glm::quat mRotation;
184  } mBase;
185 };
186 
187 template <class M>
188 bool isMoveablesRefresh(const std::vector<M>& moveables) {
189  for (auto &it : moveables) {
190  if (it->isRefresh()) {
191  return true;
192  }
193  }
194  return false;
195 }
196 
197 template <class M>
198 void resetMoveablesRefresh(const std::vector<M>& data) {
199  for (auto &it : data) {
200  it->setRefresh(false);
201  }
202 }
203 
204 } /* flw */
Definition: Aliases.h:30
Base for every object which has a 3D position.
Definition: Moveable.h:43
Implementation of Observable pattern.
Definition: Observable.h:34