RioEngine  0.1
My first attempt to create a 3D WYSIWYG Game Engine
cactioninterval.cpp
Go to the documentation of this file.
1 //--------------------------------------------------------------- @License begins
2 // cocos2d for iPhone: http://www.cocos2d-iphone.org
3 // -> This file was ported to C++ by Leopoldo Lomas Flores just for fun.
4 // I suggest you get the official C++ version of this file from:
5 // http://www.cocos2d-x.org/
6 //
7 // Copyright (c) 2008-2011 Ricardo Quesada
8 // Copyright (c) 2011 Zynga Inc.
9 // Copyright (c) 2013-2014 Cocos2D Authors
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //--------------------------------------------------------------- @License ends
29 
30 #include "cengine/cgameobject.h"
32 
33 // --------------------------------------------- CActionInterval implementation
34 
36  initWithDuration(duration);
37 }
38 
39 //-----------------------------------------------------------------------------
40 
41 void CActionInterval::initWithDuration(float duration) {
42  m_duration = duration;
43 
44  // prevent division by 0
45  // This comparison could be in step:, but it might decrease the performance
46  // by 3% in heavy based action games.
47  if ( m_duration == 0 )
48  m_duration = FLT_EPSILON;
49  m_elapsed = 0;
50  m_firstTick = true;
51 }
52 
53 //-----------------------------------------------------------------------------
54 
57 
58  m_elapsed = 0.0f;
59  m_firstTick = true;
60 
61  emit(onActionStart(this));
62 }
63 
64 //-----------------------------------------------------------------------------
65 
67  return (m_elapsed >= m_duration);
68 }
69 
70 //-----------------------------------------------------------------------------
71 
72 void CActionInterval::step(float dt) {
73  if (m_firstTick) {
74  m_firstTick = false;
75  m_elapsed = 0;
76  } else
77  m_elapsed += dt;
78 
79  update(std::max<float>(0, std::min<float>(1, m_elapsed / std::max<float>(m_duration, FLT_EPSILON))));
80 
81  if(isDone()) {
82  emit onActionDone(this);
83  }
84 }
85 
86 //-----------------------------------------------------------------------------
87 
89  LOG("CActionInterval::reverse() not implemented");
90  return NULL;
91 }
92 
93 // -------------------------------------------------- CDelayTime implementation
94 
95 CDelayTime::CDelayTime(float duration) : CActionInterval(duration) {
96 }
97 
98 // ----------------------------------------------------- CMoveTo implementation
99 
100 CMoveTo::CMoveTo(float duration, btVector3 &position) : CActionInterval(duration) {
101  m_endPosition = position;
102 }
103 
104 //-----------------------------------------------------------------------------
105 
108 
111 }
112 
113 void CMoveTo::update(float t) {
114  btVector3 new_position = btVector3(m_startPosition.x() + m_delta.x() * t,
115  m_startPosition.y() + m_delta.y() * t,
116  m_startPosition.z() + m_delta.z() * t);
117 
118  m_target->transform().setLocalPosition(new_position);
119 }
120 
121 // ----------------------------------------------------- CMoveBy implementation
122 
123 CMoveBy::CMoveBy(float duration, btVector3 &position) {
124  initWithDuration(duration);
125  m_delta = position;
126 }
127 
128 //-----------------------------------------------------------------------------
129 
131  btVector3 d_tmp = m_delta;
132  CMoveTo::startWithTarget(target);
133  m_delta = d_tmp;
134 }
135 
136 //-----------------------------------------------------------------------------
137 
139  return new CMoveBy(m_duration, m_delta * -1.0f);
140 }
141 
142 // --------------------------------------------------- CRotateTo implementation
143 
144 CRotateTo::CRotateTo(float duration, btVector3 &angle) {
145  initWithDuration(duration, angle);
146 }
147 
148 //-----------------------------------------------------------------------------
149 
150 void CRotateTo::initWithDuration(float duration, btVector3& angle) {
152  m_dstAngle = angle;
153 }
154 
155 //-----------------------------------------------------------------------------
156 
159  m_startAngle = target->transform().localRotation();
160 
161  m_diffAngle = btVector3( m_dstAngle.y() - m_startAngle.y(),
162  m_dstAngle.x() - m_startAngle.x(),
163  m_dstAngle.z() - m_startAngle.z() );
164 }
165 
166 //-----------------------------------------------------------------------------
167 
168 void CRotateTo::update(float t) {
169  float heading_diff = m_diffAngle.y() * t;
170  float pitch_diff = m_diffAngle.x() * t;
171  float bank_diff = m_diffAngle.z() * t;
172 
173  btQuaternion y_rot = btQuaternion(btVector3(1, 0, 0), DEGTORAD(heading_diff));
174  btQuaternion x_rot = btQuaternion(btVector3(0, 1, 0), DEGTORAD(pitch_diff));
175  btQuaternion z_rot = btQuaternion(btVector3(0, 0, 1), DEGTORAD(bank_diff));
176 
177  btQuaternion final_rot = m_startAngle;
178 
179  final_rot = final_rot * y_rot;
180  final_rot = x_rot * final_rot;
181  final_rot = final_rot * z_rot;
182 
183  m_target->transform().setLocalRotation(final_rot);
184 }
185 
186 // --------------------------------------------------- CRotateBy implementation
187 
188 CRotateBy::CRotateBy(float duration, btVector3 &angle) {
189  initWithDuration(duration, angle);
190 }
191 
192 //-----------------------------------------------------------------------------
193 
194 void CRotateBy::initWithDuration(float duration, btVector3& angle) {
196  m_dstAngle = angle;
197 }
198 
199 //-----------------------------------------------------------------------------
200 
203  m_startAngle = target->transform().localRotation();
204 }
205 
206 //-----------------------------------------------------------------------------
207 
208 void CRotateBy::update(float t) {
209  float heading_diff = m_dstAngle.y() * t;
210  float pitch_diff = m_dstAngle.x() * t;
211  float bank_diff = m_dstAngle.z() * t;
212 
213  btQuaternion y_rot = btQuaternion(btVector3(1, 0, 0), DEGTORAD(heading_diff));
214  btQuaternion x_rot = btQuaternion(btVector3(0, 1, 0), DEGTORAD(pitch_diff));
215  btQuaternion z_rot = btQuaternion(btVector3(0 ,0, 1), DEGTORAD(bank_diff));
216 
217  btQuaternion final_rot = m_startAngle;
218 
219  final_rot = final_rot * y_rot;
220  final_rot = x_rot * final_rot;
221  final_rot = final_rot * z_rot;
222 
223  m_target->transform().setLocalRotation(final_rot);
224 }
225 
226 // ---------------------------------------------------- CScaleTo implementation
227 
228 CScaleTo::CScaleTo(float duration, float sx, float sy, float sz) {
229  initWithDuration(duration, sx, sy, sz);
230 }
231 
232 //-----------------------------------------------------------------------------
233 
234 CScaleTo::CScaleTo(float duration, btVector3 &scale) {
235  initWithDuration(duration, scale.x(), scale.y(), scale.z());
236 }
237 
238 //-----------------------------------------------------------------------------
239 
240 void CScaleTo::initWithDuration(float duration, float sx, float sy, float sz) {
242  m_endScale = btVector3(sx, sy, sz);
243 }
244 
245 //-----------------------------------------------------------------------------
246 
249  m_startScale = target->transform().localScale();
251 }
252 
253 //-----------------------------------------------------------------------------
254 
255 void CScaleTo::update(float t) {
257 }
258 
259 // ---------------------------------------------------- CScaleBy implementation
260 
261 CScaleBy::CScaleBy(float duration, float sx, float sy, float sz) :
262  CScaleTo(duration, sx, sy, sz)
263 {}
264 
265 //-----------------------------------------------------------------------------
266 
267 CScaleBy::CScaleBy(float duration, btVector3 &scale) :
268  CScaleTo(duration, scale)
269 {}
270 
271 //-----------------------------------------------------------------------------
272 
275 
276  float dx = m_startScale.x() * m_endScale.x() - m_startScale.x();
277  float dy = m_startScale.y() * m_endScale.y() - m_startScale.y();
278  float dz = m_startScale.z() * m_endScale.z() - m_startScale.z();
279 
280  m_deltaScale = btVector3(dx, dy, dz);
281 }
282 
283 //-----------------------------------------------------------------------------
284 
286  return new CScaleBy(m_duration,/*1*/ m_endScale); // TODO verify this
287 }
288 
289 // --------------------------------------------------- CSequence implementation
290 
292  va_list params;
293  va_start(params,action);
294 
295  CFiniteTimeAction* now, *prev_old = NULL;
296  CFiniteTimeAction* prev = action;
297  while ( action ) {
298  now = va_arg(params,CFiniteTimeAction*);
299  if ( now ) {
300  prev_old = prev;
301  prev = new CSequence();
302  prev->autorelease();
303  ((CSequence*)prev)->initHavingActions(prev_old, now);
304  } else {
305  break;
306  }
307  }
308  va_end(params);
309  return prev;
310 }
311 
312 //-----------------------------------------------------------------------------
313 
315  m_actions[0] = NULL;
316  m_actions[1] = NULL;
317 }
318 
319 //-----------------------------------------------------------------------------
320 
322  RE_ASSERT(firstAction && secondAction);
323  RE_ASSERT(firstAction != m_actions[0] && firstAction != m_actions[1]);
324  RE_ASSERT(secondAction != m_actions[0] && secondAction != m_actions[1]);
325 
326  float d = firstAction->getDuration() + secondAction->getDuration();
327 
328  initWithDuration(d);
329 
330  SAFE_RELEASE(m_actions[0]);
331  SAFE_RELEASE(m_actions[1]);
332 
333  m_actions[0] = static_cast<CFiniteTimeAction*>(firstAction->retain());
334  m_actions[1] = static_cast<CFiniteTimeAction*>(secondAction->retain());
335 
336  return this;
337 }
338 
339 //-----------------------------------------------------------------------------
340 
343  m_split = m_actions[0]->getDuration() / std::max(m_duration, FLT_EPSILON);
344  m_last = -1;
345 }
346 
347 //-----------------------------------------------------------------------------
348 
349 void CSequence::update(float t) {
350  int found = 0;
351  float new_t = 0.0f;
352 
353  if ( t < m_split ) {
354  // action[0]
355  found = 0;
356  if ( m_split != 0 )
357  new_t = t / m_split;
358  else
359  new_t = 1;
360 
361  } else {
362  // action[1]
363  found = 1;
364  if ( m_split == 1 )
365  new_t = 1;
366  else
367  new_t = (t-m_split) / (1 - m_split );
368  }
369 
370  if ( found==1 ) {
371 
372  if ( m_last == -1 ) {
373  // action[0] was skipped, execute it.
374  m_actions[0]->startWithTarget(m_target);
375  m_actions[0]->update(1.0f);
376  m_actions[0]->stop();
377  } else if ( m_last == 0 )
378  {
379  // switching to action 1. stop action 0.
380  m_actions[0]->update(1.0f);
381  m_actions[0]->stop();
382  }
383  }
384 
385  // New action. Start it.
386  if ( found != m_last )
387  m_actions[found]->startWithTarget(m_target);
388 
389  m_actions[found]->update(new_t);
390  m_last = found;
391 }
392 
393 //-----------------------------------------------------------------------------
394 
396  if ( m_last != -1 ) {
397  m_actions[m_last]->stop();
398  }
399 
401 }
402 
403 //-----------------------------------------------------------------------------
404 
406  CSequence* reversed_sequence = new CSequence();
407  reversed_sequence->initHavingActions(m_actions[1]->reverse(), m_actions[0]->reverse());
408 
409  return reversed_sequence;
410 }
411 
412 //-----------------------------------------------------------------------------
413 
415  SAFE_RELEASE(m_actions[0]);
416  SAFE_RELEASE(m_actions[1]);
417 }
418 
419 // -------------------------------------------------- CCallFuncN implementation
420 
422  initWithDuration(0.0f);
423  m_callbackMethod = callback_method;
424 }
425 
426 //-----------------------------------------------------------------------------
427 
430 }
431 
432 //-----------------------------------------------------------------------------
433 
434 void CCallFuncN::update(float) {
435  m_callbackMethod();
436 }
virtual void startWithTarget(CGameObject *target)
btVector3 m_delta
#define LOG
Definition: macro.h:43
virtual void startWithTarget(CGameObject *target)
btQuaternion localRotation() const
Definition: transform.cpp:132
virtual void initWithDuration(float duration, btVector3 &angle)
virtual void update(float t)
Definition: caction.cpp:68
virtual CActionInterval * reverse()
btVector3 m_startPosition
float getDuration() const
Definition: caction.cpp:78
virtual void startWithTarget(CGameObject *target)
virtual void initWithDuration(float duration, float sx, float sy, float sz)
virtual void stop()
Definition: caction.cpp:57
void setLocalScale(float x, float y, float z)
Definition: transform.cpp:180
virtual void startWithTarget(CGameObject *target)
virtual void update(float t)
void onActionStart(CAction *action)
const btVector3 & localPosition(UnitType unit_type=WORLD) const
Definition: transform.cpp:105
btVector3 m_endPosition
virtual void update(float t)
virtual void update(float)
void setLocalRotation(float w, float x, float y, float z)
Definition: transform.cpp:209
CGameObject * m_target
Definition: caction.h:95
float m_duration
Definition: caction.h:128
CScaleBy(float duration, float sx, float sy, float sz)
CSequence * initHavingActions(CFiniteTimeAction *firstAction, CFiniteTimeAction *secondAction)
virtual void startWithTarget(CGameObject *target)
Definition: caction.cpp:45
virtual void initWithDuration(float duration)
virtual void update(float)
virtual void startWithTarget(CGameObject *target)
virtual CActionInterval * reverse()
btVector3 m_endScale
virtual void startWithTarget(CGameObject *target)
#define SAFE_RELEASE(x)
Definition: cobject.h:36
CObject * autorelease()
Definition: cobject.cpp:87
btVector3 localScale() const
Definition: transform.cpp:123
virtual void startWithTarget(CGameObject *target)
virtual void update(float t)
virtual void startWithTarget(CGameObject *target)
btVector3 m_deltaScale
#define RE_ASSERT
Definition: macro.h:57
void onActionDone(CAction *action)
#define DEGTORAD(x)
Definition: macro.h:52
virtual void initWithDuration(float duration, btVector3 &angle)
virtual bool isDone()
virtual CActionInterval * reverse()
virtual void stop()
static CFiniteTimeAction * actions(CFiniteTimeAction *action,...)
void setLocalPosition(float x, float y, float z)
Definition: transform.cpp:165
virtual CActionInterval * reverse()
virtual void step(float dt)
Transform & transform()
Definition: clnode.cpp:69
CObject * retain()
Definition: cobject.cpp:66
virtual void update(float t)
btVector3 m_startScale
virtual void startWithTarget(CGameObject *target)