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
atmosphere.cpp
Go to the documentation of this file.
1 #include "cmd/atmosphere.h"
2 #include "gfx/mesh.h"
3 #include "gfx/matrix.h"
4 #include "gfx/vec.h"
5 #include "gfxlib_struct.h"
6 #include "gfx/sphere.h"
7 #include "cmd/planet.h"
8 #include "star_system.h"
9 #include "cmd/collection.h"
10 #include "cmd/unit_generic.h"
11 
12 Atmosphere::SunBox::~SunBox()
13 {
14  if (sunbox)
15  delete sunbox;
16 }
17 
18 void Atmosphere::setArray( float c0[4], const GFXColor &c1 )
19 {
20  c0[0] = c1.r;
21  c0[1] = c1.g;
22  c0[2] = c1.b;
23  c0[3] = c1.a;
24 }
25 
26 void Atmosphere::setArray1( float c0[3], const GFXColor &c1 )
27 {
28  c0[0] = c1.r;
29  c0[1] = c1.g;
30  c0[2] = c1.b;
31 }
32 
33 Atmosphere::Atmosphere( const Parameters &params ) : user_params( params )
34  , divisions( 64 )
35 {
36  dome = new SphereMesh( params.radius, divisions, divisions, "white.bmp", "", NULL, true, ONE, ZERO, false, 0, M_PI/2 );
37 }
38 
40 {
41  for (size_t a = 0; a < sunboxes.size(); ++a)
42  delete sunboxes[a];
43 }
44 
46 {
47  return user_params;
48 }
49 
51 {
52  user_params = params;
53 }
54 
55 void Atmosphere::Update( const QVector &position, const Matrix &tmatrix )
56 {
57  Planet *currPlanet;
59  for (size_t a = 0; a < sunboxes.size(); ++a)
60  delete sunboxes[a];
61  sunboxes.clear();
62  QVector localDir;
63  float rho1 = 0.0;
64  Unit *primary;
65  for (un_iter iter = system->getUnitList().createIterator(); (primary=*iter)!=NULL; ++iter)
66  if ( primary->isUnit() == PLANETPTR && (currPlanet = (GamePlanet*) primary)->hasLights() ) {
67  /* for now just assume all planets with lights are really bright */
68  QVector direction = (currPlanet->Position()-position);
69  direction.Normalize();
70  double rho = direction*InvTransformNormal( tmatrix, QVector( 0, 1, 0 ) );
71  if (rho > 0) {
72  /* above the horizon */
73  QVector localDirection = InvTransformNormal( tmatrix, direction );
74 
75  /* bad */
76  localDir = localDirection;
77  rho1 = rho;
78 
79  /* need a function for the sunbox size. for now, say it takes up a quarter
80  * of the screen */
81  /* drop the z value and find the theta */
82  QVector lprime = localDirection;
83  lprime.k = 0;
84  lprime.Normalize();
85  //float theta = atan2(lprime.i,lprime.j);
86  //float size = .125;
87  sunboxes.push_back( new SunBox( NULL ) );
88  break;
89  }
90  }
91  if ( !sunboxes.empty() ) {
92  float rho = acos( rho1 )/(PI/2);
93  float radius = user_params.radius;
94  /* index 0 is the top color, index 1 is the bottom color */
95  GFXLight light0 = GFXLight();
96  light0.SetProperties( AMBIENT, rho*user_params.high_ambient_color[0]+(1-rho)*user_params.low_ambient_color[0] );
97  light0.SetProperties( DIFFUSE, rho*user_params.high_color[0]+(1-rho)*user_params.low_color[0] );
98  light0.SetProperties( ATTENUATE, 0.5*GFXColor( 1, 0.25/radius, 0 ) );
99  light0.SetProperties( POSITION, GFXColor( 0, 1.1*radius, 0, 1 ) );
100 
101  /* do a linear interpolation between this and the next one */
102 
103  GFXLight light1 = GFXLight();
104  light1.SetProperties( AMBIENT, (1-rho)*user_params.high_ambient_color[1]+rho*user_params.low_ambient_color[1] );
105  light1.SetProperties( DIFFUSE, (1-rho)*user_params.high_color[1]+rho*user_params.low_color[1] );
106  light1.SetProperties( ATTENUATE, 0.5*GFXColor( 1, 0.75/radius, 0 ) );
107  light1.SetProperties( POSITION, GFXColor( 0, -1.1*radius, 0, 1 ) );
108 
109  /* Note!! make sure that this light never goes too far around the sphere */
110  GFXLight light2 = light1; /* -80 degree declination from sun position */
111  Matrix m;
112  QVector r;
113  ScaledCrossProduct( QVector( 0, 1, 0 ), localDir, r );
114  Rotate( m, r.Cast(), -80*(PI/180) );
115  r = Transform( m, QVector( 0, 0, 1 ) );
116  float sradius = 1.1*radius;
117  light2.SetProperties( POSITION, GFXColor( sradius*r.i, sradius*r.j, sradius*r.k, 1 ) );
118 
119  GFXCreateLight( l0, light0, true );
120  GFXCreateLight( l1, light1, true );
121  GFXEnableLight( l0 );
122  GFXEnableLight( l1 );
123  }
124 }
125 
126 static std::vector< Atmosphere* >draw_queue;
127 void Atmosphere::SetMatricesAndDraw( const QVector &pos, const Matrix mat )
128 {
129  CopyMatrix( tmatrix, mat );
130  position = pos;
131  draw_queue.push_back( this );
132 }
133 
135 {
136  GFXEnable( LIGHTING );
137  GFXDisable( TEXTURE1 );
138  GFXDisable( TEXTURE0 );
140  while ( !draw_queue.empty() ) {
141  draw_queue.back()->Draw();
142  draw_queue.pop_back();
143  }
144 }
145 
147 {
148  GFXDisable( TEXTURE1 );
149  Matrix rot( 1, 0, 0,
150  0, 0, -1,
151  0, 1, 0,
152  QVector( 0, 0, 0 ) );
153  Matrix rot1;
154  MultMatrix( rot1, tmatrix, rot );
155  CopyMatrix( rot1, tmatrix );
156 
157  Vector tmp( rot1.getR() );
158  Vector tmp2( rot1.getQ() );
159 
160  rot1.r[6] = -tmp.i;
161  rot1.r[7] = -tmp.j;
162  rot1.r[8] = -tmp.k;
163 
164  rot1.r[3] = -tmp2.i;
165  rot1.r[4] = -tmp2.j;
166  rot1.r[5] = -tmp2.k;
167 
168  GFXMaterial a = {
169  0, 0, 0, 0,
170  1, 1, 1, 1,
171  0, 0, 0, 0,
172  0, 0, 0, 0,
173  0
174  };
175  dome->SetMaterial( a );
176  GFXLoadMatrixModel( rot1 );
177  Update( position, rot1 );
178 
180  dome->DrawNow( 100000, GFXFALSE, rot1 );
181  GFXDisableLight( l0 );
182  GFXDisableLight( l1 );
183  GFXDeleteLight( l0 );
184  GFXDeleteLight( l1 );
185 }
186 
188 {
189  abort();
190 }
191