Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CinemaTrack.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2009 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 #include "precompiled.h"
20 #include <string>
21 #include <sstream>
22 #include "lib/ogl.h"
23 #include "CinemaTrack.h"
24 #include "ps/Game.h"
25 #include "GameView.h"
26 #include "maths/MathUtil.h"
27 #include "Camera.h"
28 #include "ps/CStr.h"
29 #include "maths/Vector3D.h"
30 #include "maths/Vector4D.h"
31 #include "maths/Quaternion.h"
32 
33 CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline)
34  : CCinemaData(data), TNSpline(spline), m_TimeElapsed(0.f)
35 {
36  m_TimeElapsed = 0;
37  BuildSpline();
38 
39  //Set distortion mode and style
40  switch(data.m_Mode)
41  {
42  case CCinemaPath::EM_IN:
44  break;
47  break;
50  break;
53  break;
54  default:
55  debug_printf(L"Cinematic mode not found for %d ", data.m_Mode);
56  break;
57  }
58 
59  switch (data.m_Style)
60  {
63  break;
66  break;
69  break;
72  break;
75  break;
76  default:
77  debug_printf(L"Cinematic mode not found for %d !", data.m_Style);
78  break;
79  }
80  //UpdateDuration();
81 
82 }
83 
84 void CCinemaPath::DrawSpline(const CVector4D& RGBA, int smoothness, bool lines) const
85 {
86  if (NodeCount < 2 || DistModePtr == NULL)
87  return;
88  if ( NodeCount == 2 && lines )
89  smoothness = 2;
90 
91  float start = MaxDistance / smoothness;
92  float time=0;
93 
94 #if CONFIG2_GLES
95 #warning TODO: do something about CCinemaPath on GLES
96 #else
97 
98  glColor4f( RGBA.X, RGBA.Y, RGBA.Z, RGBA.W );
99  if ( lines )
100  {
101  glLineWidth(1.8f);
102  glEnable(GL_LINE_SMOOTH);
103  glBegin(GL_LINE_STRIP);
104 
105  for (int i=0; i<=smoothness; ++i)
106  {
107  //Find distorted time
108  time = start*i / MaxDistance;
109  CVector3D tmp = GetPosition(time);
110  glVertex3f( tmp.X, tmp.Y, tmp.Z );
111  }
112  glEnd();
113  glDisable(GL_LINE_SMOOTH);
114  glLineWidth(1.0f);
115  }
116  else
117  {
118  smoothness /= 2;
119  start = MaxDistance / smoothness;
120  glEnable(GL_POINT_SMOOTH);
121  glPointSize(3.0f);
122  glBegin(GL_POINTS);
123 
124  for (int i=0; i<=smoothness; ++i)
125  {
126  //Find distorted time
127  time = (this->*DistModePtr)(start*i / MaxDistance);
128  CVector3D tmp = GetPosition(time);
129  glVertex3f( tmp.X, tmp.Y, tmp.Z );
130  }
131  glColor3f(1.0f, 1.0f, 0.0f); //yellow
132 
133  for ( size_t i=0; i<Node.size(); ++i )
134  glVertex3f(Node[i].Position.X, Node[i].Position.Y, Node[i].Position.Z);
135 
136  glEnd();
137  glPointSize(1.0f);
138  glDisable(GL_POINT_SMOOTH);
139  }
140 
141 #endif
142 }
143 
144 void CCinemaPath::MoveToPointAt(float t, float nodet, const CVector3D& startRotation)
145 {
146  CCamera *Cam = g_Game->GetView()->GetCamera();
147  t = (this->*DistModePtr)(t);
148 
149  CVector3D nodeRotation = Node[m_CurrentNode + 1].Rotation;
150  CQuaternion start, end;
151  start.FromEulerAngles(DEGTORAD(startRotation.X), DEGTORAD(startRotation.Y), DEGTORAD(startRotation.Z));
152  end.FromEulerAngles(DEGTORAD(nodeRotation.X), DEGTORAD(nodeRotation.Y), DEGTORAD(nodeRotation.Z));
153  start.Slerp(start, end, nodet);
154  CVector3D pos = GetPosition(t);
155  CQuaternion quat;
156 
157  Cam->m_Orientation.SetIdentity();
158  Cam->m_Orientation.Rotate(start);
159  Cam->m_Orientation.Translate(pos);
160  Cam->UpdateFrustum();
161 }
162 
163 //Distortion mode functions
164 float CCinemaPath::EaseIn(float t) const
165 {
166  return (this->*DistStylePtr)(t);
167 }
168 float CCinemaPath::EaseOut(float t) const
169 {
170  return 1.0f - EaseIn(1.0f-t);
171 }
172 float CCinemaPath::EaseInOut(float t) const
173 {
174  if (t < m_Switch)
175  return EaseIn(1.0f/m_Switch * t) * m_Switch;
176  return EaseOut(1.0f/m_Switch * (t-m_Switch)) * m_Switch + m_Switch;
177 }
178 float CCinemaPath::EaseOutIn(float t) const
179 {
180  if (t < m_Switch)
181  return EaseOut(1.0f/m_Switch * t) * m_Switch;
182  return EaseIn(1.0f/m_Switch * (t-m_Switch)) * m_Switch + m_Switch;
183 }
184 
185 
186 //Distortion style functions
187 float CCinemaPath::EaseDefault(float t) const
188 {
189  return t;
190 }
191 float CCinemaPath::EaseGrowth(float t) const
192 {
193  return pow(t, m_Growth);
194 }
195 
196 float CCinemaPath::EaseExpo(float t) const
197 {
198  if(t == 0)
199  return t;
200  return powf(m_Growth, 10*(t-1.0f));
201 }
202 float CCinemaPath::EaseCircle(float t) const
203 {
204  t = -(sqrt(1.0f - t*t) - 1.0f);
205  if(m_GrowthCount > 1.0f)
206  {
207  m_GrowthCount--;
208  return (this->*DistStylePtr)(t);
209  }
210  return t;
211 }
212 
213 float CCinemaPath::EaseSine(float t) const
214 {
215  t = 1.0f - cos(t * (float)M_PI/2);
216  if(m_GrowthCount > 1.0f)
217  {
218  m_GrowthCount--;
219  return (this->*DistStylePtr)(t);
220  }
221  return t;
222 }
223 
225 {
226  if ( m_TimeElapsed <= GetDuration() && m_TimeElapsed >= 0.0f )
227  {
228  //Find current node and past "node time"
229  float previousTime = 0.0f, cumulation = 0.0f;
230  //Ignore the last node, since it is a blank (node time values are shifted down one from interface)
231  for ( size_t i = 0; i < Node.size() - 1; ++i )
232  {
233  cumulation += Node[i].Distance;
234  if ( m_TimeElapsed <= cumulation )
235  {
236  m_PreviousNodeTime = previousTime;
237  m_PreviousRotation = Node[i].Rotation;
238  m_CurrentNode = i; //We're moving toward this next node, so use its rotation
239  return true;
240  }
241  else
242  previousTime += Node[i].Distance;
243  }
244  }
245  return false;
246 }
247 
248 bool CCinemaPath::Play(const float deltaRealTime)
249 {
250  m_TimeElapsed += m_Timescale * deltaRealTime;
251 
252  if (!Validate())
253  {
254  m_TimeElapsed = 0.0f;
255  return false;
256  }
257 
259  return true;
260 }
261 
262 
263 CCinemaManager::CCinemaManager() : m_DrawCurrentSpline(false), m_Active(true), m_ValidCurrent(false)
264 {
265  m_CurrentPath = m_Paths.end();
266 }
267 
268 void CCinemaManager::AddPath(CCinemaPath path, const CStrW& name)
269 {
270  ENSURE( m_Paths.find( name ) == m_Paths.end() );
271  m_Paths[name] = path;
272 }
273 
274 void CCinemaManager::QueuePath(const CStrW& name, bool queue )
275 {
276  if (!m_PathQueue.empty() && queue == false)
277  {
278  return;
279  }
280  else
281  {
282  ENSURE(HasTrack(name));
283  m_PathQueue.push_back(m_Paths[name]);
284  }
285 }
286 
287 void CCinemaManager::OverridePath(const CStrW& name)
288 {
289  m_PathQueue.clear();
290  ENSURE(HasTrack(name));
291  m_PathQueue.push_back( m_Paths[name] );
292 }
293 
294 void CCinemaManager::SetAllPaths( const std::map<CStrW, CCinemaPath>& paths)
295 {
296  CStrW name;
297  m_Paths = paths;
298 }
299 void CCinemaManager::SetCurrentPath(const CStrW& name, bool current, bool drawLines)
300 {
301  if ( !HasTrack(name) )
302  m_ValidCurrent = false;
303  else
304  m_ValidCurrent = true;
305 
306  m_CurrentPath = m_Paths.find(name);
307  m_DrawCurrentSpline = current;
308  m_DrawLines = drawLines;
309  DrawSpline();
310 }
311 
312 bool CCinemaManager::HasTrack(const CStrW& name) const
313 {
314  return m_Paths.find(name) != m_Paths.end();
315 }
316 
318 {
320  return;
321  static const int smoothness = 200;
322 
323  m_CurrentPath->second.DrawSpline(CVector4D(0.f, 0.f, 1.f, 1.f), smoothness, m_DrawLines);
324 }
325 
327 {
328  ENSURE(m_CurrentPath != m_Paths.end());
329  StopPlaying();
330 
331  m_CurrentPath->second.m_TimeElapsed = time;
332  if ( !m_CurrentPath->second.Validate() )
333  return;
334 
335  m_CurrentPath->second.MoveToPointAt(m_CurrentPath->second.m_TimeElapsed /
336  m_CurrentPath->second.GetDuration(), m_CurrentPath->second.GetNodeFraction(),
337  m_CurrentPath->second.m_PreviousRotation );
338 }
339 
340 bool CCinemaManager::Update(const float deltaRealTime)
341 {
342  if (!m_PathQueue.front().Play(deltaRealTime))
343  {
344  m_PathQueue.pop_front();
345  return false;
346  }
347  return true;
348 }
#define M_PI
Definition: wposix.h:64
void Translate(float x, float y, float z)
Definition: Matrix3D.cpp:172
float m_Timescale
Definition: CinemaTrack.h:52
float EaseOutIn(float t) const
float EaseCircle(float t) const
void FromEulerAngles(float x, float y, float z)
Definition: Quaternion.cpp:96
float m_Switch
Definition: CinemaTrack.h:49
float m_Growth
Definition: CinemaTrack.h:48
std::map< CStrW, CCinemaPath > m_Paths
Definition: CinemaTrack.h:161
bool Play(const float deltaRealTime)
Returns false if finished.
CVector3D GetPosition(float time) const
Definition: NUSpline.cpp:96
bool HasTrack(const CStrW &name) const
void QueuePath(const CStrW &name, bool queue)
float MaxDistance
Definition: NUSpline.h:50
float EaseGrowth(float t) const
void BuildSpline()
Definition: NUSpline.h:79
bool m_DrawCurrentSpline
Definition: CinemaTrack.h:159
float(CCinemaPath::* DistStylePtr)(float ratio) const
Definition: CinemaTrack.h:87
Definition: wnuma.cpp:46
void SetCurrentPath(const CStrW &name, bool current, bool lines)
void DrawSpline() const
void SetAllPaths(const std::map< CStrW, CCinemaPath > &tracks)
void MoveToPointAt(float t, float nodet, const CVector3D &)
void Rotate(const CQuaternion &quat)
Definition: Matrix3D.cpp:354
float Y
Definition: Vector4D.h:128
float EaseDefault(float t) const
int NodeCount
Definition: NUSpline.h:51
float EaseSine(float t) const
size_t m_CurrentNode
Definition: CinemaTrack.h:108
std::list< CCinemaPath > m_PathQueue
Definition: CinemaTrack.h:162
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
CVector3D m_PreviousRotation
Definition: CinemaTrack.h:109
float GetNodeFraction() const
Definition: CinemaTrack.h:100
float Z
Definition: Vector4D.h:128
bool Update(const float deltaRealTime)
float EaseOut(float t) const
float X
Definition: Vector3D.h:31
float EaseInOut(float t) const
float Y
Definition: Vector3D.h:31
void DrawSpline(const CVector4D &RGBA, int smoothness, bool lines) const
Definition: CinemaTrack.cpp:84
Definition: Camera.h:39
void SetIdentity()
Definition: Matrix3D.cpp:30
CCamera * GetCamera()
Definition: GameView.cpp:390
CGame * g_Game
Globally accessible pointer to the CGame object.
Definition: Game.cpp:56
std::map< CStrW, CCinemaPath >::iterator m_CurrentPath
Definition: CinemaTrack.h:160
float m_PreviousNodeTime
Definition: CinemaTrack.h:106
float(CCinemaPath::* DistModePtr)(float ratio) const
Definition: CinemaTrack.h:88
void UpdateFrustum(const CBoundingBoxAligned &scissor=CBoundingBoxAligned(CVector3D(-1.0f,-1.0f,-1.0f), CVector3D(1.0f, 1.0f, 1.0f)))
Definition: Camera.cpp:83
CGameView * GetView()
Get the pointer to the game view object.
Definition: Game.h:128
float W
Definition: Vector4D.h:128
void AddPath(CCinemaPath path, const CStrW &name)
void StopPlaying()
Definition: CinemaTrack.h:145
CMatrix3D m_Orientation
Definition: Camera.h:112
float Z
Definition: Vector3D.h:31
float EaseIn(float t) const
void OverridePath(const CStrW &name)
#define DEGTORAD(a)
Definition: MathUtil.h:21
void MoveToPointAt(float time)
float GetDuration() const
Definition: CinemaTrack.h:98
void Slerp(const CQuaternion &from, const CQuaternion &to, float ratio)
Definition: Quaternion.cpp:198
float m_GrowthCount
Definition: CinemaTrack.h:47
float m_TimeElapsed
Definition: CinemaTrack.h:105
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
Definition: debug.cpp:142
bool Validate()
float X
Definition: Vector4D.h:128
float EaseExpo(float t) const