Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
animation.cpp
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2001-2002 Daniel Horn
4  *
5  * http://vegastrike.sourceforge.net/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include "cmd/unit_generic.h"
23 #include "animation.h"
24 #include "aux_texture.h"
25 #include "camera.h"
26 #include "lin_time.h"
27 #include <stack>
28 #include "vsfilesystem.h"
29 #include "vs_globals.h"
30 #include "point_to_cam.h"
31 #include "config_xml.h"
32 #include "xml_support.h"
33 #include "sprite.h"
34 #include <algorithm>
35 #include "../gldrv/gl_globals.h"
36 using std::vector;
37 using std::stack;
38 
39 static vector< Animation* >far_animationdrawqueue;
41 {
42  return !far_animationdrawqueue.empty();
43 }
44 
45 static vector < Animation* >animationdrawqueue;
47 {
48  return !animationdrawqueue.empty();
49 }
50 
51 
52 static const unsigned char ani_up = 0x01;
53 static const unsigned char ani_close = 0x02;
54 static const unsigned char ani_alpha = 0x04;
55 static const unsigned char ani_repeat = 0x08;
57 {
58  VSCONSTRUCT2( 'a' )
59  height = 0.001F;
60  width = 0.001F;
61 }
62 void Animation::SetFaceCam( bool face )
63 {
64  if (face)
65  options |= ani_up;
66  else
67  options &= (~ani_up);
68 }
69 
70 using namespace VSFileSystem;
71 
73  bool Rep,
74  float priority,
75  enum FILTER ismipmapped,
76  bool camorient,
77  bool appear_near_by_radius,
78  const GFXColor &c ) : mycolor( c )
79 {}
80 
81 Animation::Animation( const char *FileName,
82  bool Rep,
83  float priority,
84  enum FILTER ismipmapped,
85  bool camorient,
86  bool appear_near_by_radius,
87  const GFXColor &c ) : mycolor( c )
88 {
89  Identity( local_transformation );
90  VSCONSTRUCT2( 'a' )
91  //repeat = Rep;
92  options = 0;
93  if (Rep)
94  options |= ani_repeat;
95  if (camorient)
96  options |= ani_up;
97  if (appear_near_by_radius)
98  options |= ani_close;
99  SetLoop( Rep ); //setup AnimatedTexture's loop flag - NOTE: Load() will leave it like this unless a force(No)Loop option is present
100  SetLoopInterp( Rep ); //Default interpolation method == looping method
101  VSFile f;
102  VSError err = f.OpenReadOnly( FileName, AnimFile );
103  if (err > Ok) {
104  //load success already set false
105  } else {
106  f.Fscanf( "%f %f", &width, &height );
107  if (width > 0)
108  options |= ani_alpha;
109  width = fabs( width*0.5F );
110  height = height*0.5F;
111  Load( f, 0, ismipmapped );
112  f.Close();
113  }
114  //VSFileSystem::ResetCurrentPath();
115 }
117 {
118  vector< Animation* >::iterator i;
119  while ( ( i =
120  std::find( far_animationdrawqueue.begin(), far_animationdrawqueue.end(),
121  this ) ) != far_animationdrawqueue.end() )
122  far_animationdrawqueue.erase( i );
123  while ( ( i = std::find( animationdrawqueue.begin(), animationdrawqueue.end(), this ) ) != animationdrawqueue.end() )
124  animationdrawqueue.erase( i );
126 }
128 {
129  local_transformation.p = p;
130 }
131 void Animation::SetOrientation( const Vector &p, const Vector &q, const Vector &r )
132 {
133  VectorAndPositionToMatrix( local_transformation, p, q, r, local_transformation.p );
134 }
136 {
137  return local_transformation.p;
138 }
139 void Animation::SetDimensions( float wid, float hei )
140 {
141  width = wid;
142  height = hei;
143 }
144 void Animation::GetDimensions( float &wid, float &hei )
145 {
146  wid = width;
147  hei = height;
148 }
149 
151 {
153  GFXDisable( LIGHTING );
154  GFXEnable( TEXTURE0 );
155  GFXDisable( TEXTURE1 );
158 }
160 {
161  return AnimationsLeftInQueue();
162 }
163 void Animation::ProcessFarDrawQueue( float farval )
164 {
165  //set farshit
167  GFXDisable( LIGHTING );
168  GFXEnable( TEXTURE0 );
169  GFXDisable( TEXTURE1 );
170 
172 }
174 {
175  return AnimationsLeftInFarQueue();
176 }
177 void Animation::ProcessDrawQueue( std::vector< Animation* > &animationdrawqueue, float limit )
178 {
179  if (g_game.use_animations == 0 && g_game.use_textures == 0)
180  return;
181  unsigned char alphamaps = ani_alpha;
182  int i, j; //NOT UNSIGNED
183  for (i = animationdrawqueue.size()-1; i >= 0; i--) {
184  GFXColorf( animationdrawqueue[i]->mycolor ); //fixme, should we need this? we get som egreenie explosions
185  Matrix result;
186  if ( alphamaps != (animationdrawqueue[i]->options&ani_alpha) ) {
187  alphamaps = (animationdrawqueue[i]->options&ani_alpha);
188  GFXBlendMode( (alphamaps != 0) ? SRCALPHA : ONE, (alphamaps != 0) ? INVSRCALPHA : ONE );
189  }
190  QVector campos = _Universe->AccessCamera()->GetPosition();
191  animationdrawqueue[i]->CalculateOrientation( result );
192  if ( (limit
193  <= -FLT_MAX) || (animationdrawqueue[i]->Position()-campos).Magnitude()-animationdrawqueue[i]->height > limit ) {
194  //other way was inconsistent about what was far and what was not--need to use the same test for putting to far queueu and drawing it--otherwise graphical glitches
195  GFXFogMode( FOG_OFF );
196  animationdrawqueue[i]->DrawNow( result );
197  animationdrawqueue[i] = 0; //Flag for deletion: gets called multiple times with decreasing values, and eventually is called with limit=-FLT_MAX.
198  }
199  }
200  //Delete flagged ones
201  i = 0;
202  while (i < static_cast<int>(animationdrawqueue.size()) && animationdrawqueue[i])
203  ++i;
204  j = i;
205  while ( i < static_cast<int>(animationdrawqueue.size()) ) {
206  while (i < static_cast<int>(animationdrawqueue.size()) && !animationdrawqueue[i])
207  ++i;
208  while (i < static_cast<int>(animationdrawqueue.size()) && animationdrawqueue[i])
209  animationdrawqueue[j++] = animationdrawqueue[i++];
210  }
211  if( j >= 0 )
212  animationdrawqueue.resize( j );
213 }
215 {
216  Vector camp, camq, camr;
217  QVector pos( Position() );
218  float hei = height;
219  float wid = width;
220  static float HaloOffset = XMLSupport::parse_float( vs_config->getVariable( "graphics", "HaloOffset", ".1" ) );
221  bool retval =
223  camp,
224  camq,
225  camr,
226  wid,
227  hei,
228  (options&ani_close) ? HaloOffset : 0,
229  false,
230  (options&ani_up) ? NULL : &local_transformation );
231 
232  /*
233  * Camera* TempCam = _Universe->AccessCamera();
234  * TempCam->GetPQR(camp,camq,camr);
235  * if (!camup){
236  * Vector q1 (local_transformation[1],local_transformation[5],local_transformation[9]);
237  * Vector p1 ((q1.Dot(camq))*camq);
238  * camq = (q1.Dot(camp))*camp+p1;
239  * Vector posit;
240  * TempCam->GetPosition (posit);
241  * camr.i = -local_transformation[12]+posit.i;
242  * camr.j = -local_transformation[13]+posit.j;
243  * camr.k = -local_transformation[14]+posit.k;
244  * Normalize (camr);
245  * ScaledCrossProduct (camq,camr,camp);
246  * ScaledCrossProduct (camr,camp,camq);
247  * //if the vectors are linearly dependant we're phucked :) fun fun fun
248  * }
249  */
250  VectorAndPositionToMatrix( result, camp, camq, camr, pos );
251  return retval;
252 }
253 void Animation::DrawNow( const Matrix &final_orientation )
254 {
255 // if (g_game.use_animations == 0 && g_game.use_textures == 0)
256 // {
257 // }
258 // else if ( !Done() || (options&ani_repeat) )
259 // { //chuck_starchaser simplifying...
260  if ( (g_game.use_animations || g_game.use_textures) && (!Done() || (options&ani_repeat)) )
261  {
262  GFXLoadMatrixModel( final_orientation );
263  size_t lyr;
264  size_t numlayers = numLayers();
265  bool multitex = (numlayers > 1);
266  size_t numpasses = numPasses();
267  float ms = mintcoord.i, Ms = maxtcoord.i;
268  float mt = mintcoord.j, Mt = maxtcoord.j;
269  BLENDFUNC src, dst;
270  GFXGetBlendMode( src, dst );
271  for (lyr = 0; (lyr < gl_options.Multitexture) || (lyr < numlayers); lyr++) {
272  GFXToggleTexture( (lyr < numlayers), lyr );
273  if (lyr < numlayers)
274  GFXTextureCoordGenMode( lyr, NO_GEN, NULL, NULL );
275  }
276  for (size_t pass = 0; pass < numpasses; pass++) {
277  if ( SetupPass( pass, 0, src, dst ) ) {
278  MakeActive( 0, pass );
280  GFXBegin( GFXQUAD );
281  if (!multitex)
282  GFXTexCoord2f( ms, Mt );
283  else
284  GFXTexCoord4f( ms, Mt, ms, Mt );
285  GFXVertex3f( -width, -height, 0.0f ); //lower left
286  if (!multitex)
287  GFXTexCoord2f( Ms, Mt );
288  else
289  GFXTexCoord4f( Ms, Mt, Ms, Mt );
290  GFXVertex3f( width, -height, 0.0f ); //upper left
291  if (!multitex)
292  GFXTexCoord2f( Ms, mt );
293  else
294  GFXTexCoord4f( Ms, mt, Ms, mt );
295  GFXVertex3f( width, height, 0.0f ); //upper right
296  if (!multitex)
297  GFXTexCoord2f( ms, mt );
298  else
299  GFXTexCoord4f( ms, mt, ms, mt );
300  GFXVertex3f( -width, height, 0.0f ); //lower right
301  GFXEnd();
302  }
303  }
304  for (lyr = 0; lyr < numlayers; lyr++)
305  GFXToggleTexture( false, lyr );
306  SetupPass( -1, 0, src, dst );
307  }
308 }
310 {
311  if (!spr)
312  return;
313  if (g_game.use_animations != 0 || g_game.use_textures != 0) {
314  //unsigned char alphamaps=ani_alpha;
316  if (options&ani_alpha)
318  else
319  GFXBlendMode( ONE, ZERO );
320  size_t lyr;
321  size_t numlayers = numLayers();
322  bool multitex = (numlayers > 1);
323  size_t numpasses = numPasses();
324  float ms = mintcoord.i, Ms = maxtcoord.i;
325  float mt = mintcoord.j, Mt = maxtcoord.j;
326  GFXDisable( CULLFACE );
327  Vector ll, lr, ur, ul;
328  spr->DrawHere( ll, lr, ur, ul );
329  BLENDFUNC src, dst;
330  GFXGetBlendMode( src, dst );
331  for (lyr = 0; (lyr < gl_options.Multitexture) || (lyr < numlayers); lyr++) {
332  GFXToggleTexture( (lyr < numlayers), lyr );
333  if (lyr < numlayers) GFXTextureCoordGenMode( lyr, NO_GEN, NULL, NULL );
334  }
335  for (size_t pass = 0; pass < numpasses; pass++)
336  if ( SetupPass( pass, 0, src, dst ) ) {
337  MakeActive( 0, pass );
339  GFXBegin( GFXQUAD );
340  if (!multitex) GFXTexCoord2f( ms, Mt );
341 
342  else GFXTexCoord4f( ms, Mt, ms, Mt );
343  GFXVertexf( ll );
344  if (!multitex) GFXTexCoord2f( Ms, Mt );
345 
346  else GFXTexCoord4f( Ms, Mt, Ms, Mt );
347  GFXVertexf( lr );
348  if (!multitex) GFXTexCoord2f( Ms, mt );
349 
350  else GFXTexCoord4f( Ms, mt, Ms, mt );
351  GFXVertexf( ur );
352  if (!multitex) GFXTexCoord2f( ms, mt );
353 
354  else GFXTexCoord4f( ms, mt, ms, mt );
355  GFXVertexf( ul );
356  GFXEnd();
357  }
358  SetupPass( -1, 0, src, dst );
359  for (lyr = 0; lyr < numlayers; lyr++)
360  GFXToggleTexture( false, lyr );
361  GFXEnable( CULLFACE );
362  GFXPopBlendMode();
363  }
364 }
365 void Animation::DrawNoTransform( bool cross, bool blendoption )
366 {
367  bool doitagain = false;
368  if (g_game.use_animations == 0 && g_game.use_textures == 0) {} else if ( !Done() || (options&ani_repeat) ) {
369  size_t lyr;
370  size_t numlayers = numLayers();
371  bool multitex = (numlayers > 1);
372  size_t numpasses = numPasses();
373  float ms = mintcoord.i, Ms = maxtcoord.i;
374  float mt = mintcoord.j, Mt = maxtcoord.j;
375  if (blendoption) {
376  if (options&ani_alpha) {
379  } else {
380  GFXBlendMode( ONE, ONE );
381  }
382  }
383  BLENDFUNC src, dst;
384  GFXGetBlendMode( src, dst );
385  for (lyr = 0; (lyr < gl_options.Multitexture) || (lyr < numlayers); lyr++) {
386  GFXToggleTexture( (lyr < numlayers), lyr );
387  if (lyr < numlayers) GFXTextureCoordGenMode( lyr, NO_GEN, NULL, NULL );
388  }
389  for (size_t pass = 0; pass < numpasses; pass++)
390  if ( SetupPass( pass, 0, src, dst ) ) {
391  MakeActive( 0, pass );
393  GFXBegin( GFXQUAD );
394  if (!multitex) GFXTexCoord2f( ms, Mt );
395 
396  else GFXTexCoord4f( ms, Mt, ms, Mt );
397  GFXVertex3f( -width, -height, 0.0f ); //lower left
398  if (!multitex) GFXTexCoord2f( Ms, Mt );
399 
400  else GFXTexCoord4f( Ms, Mt, Ms, Mt );
401  GFXVertex3f( width, -height, 0.0f ); //upper left
402  if (!multitex) GFXTexCoord2f( Ms, mt );
403 
404  else GFXTexCoord4f( Ms, mt, Ms, mt );
405  GFXVertex3f( width, height, 0.0f ); //upper right
406  if (!multitex) GFXTexCoord2f( ms, mt );
407 
408  else GFXTexCoord4f( ms, mt, ms, mt );
409  GFXVertex3f( -width, height, 0.0f ); //lower right
410  if (cross) {
411  if (!multitex) GFXTexCoord2f( ms, Mt );
412 
413  else GFXTexCoord4f( ms, Mt, ms, Mt );
414  GFXVertex3f( -width, 0.0f, -height ); //lower left
415  if (!multitex) GFXTexCoord2f( Ms, Mt );
416 
417  else GFXTexCoord4f( Ms, Mt, Ms, Mt );
418  GFXVertex3f( width, 0.0f, -height ); //upper left
419  if (!multitex) GFXTexCoord2f( Ms, mt );
420 
421  else GFXTexCoord4f( Ms, mt, Ms, mt );
422  GFXVertex3f( width, 0.0f, height ); //upper right
423  if (!multitex) GFXTexCoord2f( ms, mt );
424 
425  else GFXTexCoord4f( ms, mt, ms, mt );
426  GFXVertex3f( -width, 0.0f, height ); //lower right
427  if (!multitex) GFXTexCoord2f( ms, Mt );
428 
429  else GFXTexCoord4f( ms, Mt, ms, Mt );
430  GFXVertex3f( 0.0f, -height, -height ); //lower left
431  if (!multitex) GFXTexCoord2f( Ms, Mt );
432 
433  else GFXTexCoord4f( Ms, Mt, Ms, Mt );
434  GFXVertex3f( 0.0f, height, -height ); //upper left
435  if (!multitex) GFXTexCoord2f( Ms, mt );
436 
437  else GFXTexCoord4f( Ms, mt, Ms, mt );
438  GFXVertex3f( 0.0f, height, height ); //upper right
439  if (!multitex) GFXTexCoord2f( ms, mt );
440 
441  else GFXTexCoord4f( ms, mt, ms, mt );
442  GFXVertex3f( 0.0f, -height, height ); //lower right
443  }
444  GFXEnd();
445  }
446  SetupPass( -1, 0, src, dst );
447  for (lyr = 0; lyr < numlayers; lyr++)
448  GFXToggleTexture( false, lyr );
449  if (blendoption)
450  if (options&ani_alpha)
452  }
453 }
455 {
456  if (g_game.use_animations != 0 || g_game.use_textures != 0) {
457  Vector camp, camq, camr;
458  QVector pos( Position() );
459  float hei = height;
460  float wid = width;
461  static float HaloOffset = XMLSupport::parse_float( vs_config->getVariable( "graphics", "HaloOffset", ".1" ) );
462 
463 
464  //Why do all this if we can use ::CalculateOrientation?
465  //-- well one reason is that the code change broke it :-/ Until suns display properly or we switch to ogre we should keep it as it was (problem was, flare wouldn't display--- or would display behind the sun)
467  _Universe->AccessCamera()->GetR().k );
468  static float too_far_dist = XMLSupport::parse_float( vs_config->getVariable( "graphics", "anim_far_percent", ".8" ) );
469  if ( ( /*R.Dot*/ ( Position()
470  -_Universe->AccessCamera()->GetPosition() ).Magnitude()+HaloOffset
471  *(height > width ? height : width) ) < too_far_dist*g_game.zfar )
472  //if (::CalculateOrientation (pos,camp,camq,camr,wid,hei,(options&ani_close)?HaloOffset:0,false)) {ss
473  animationdrawqueue.push_back( this );
474  else
475  far_animationdrawqueue.push_back( this );
476  }
477 }
478