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
sphere_generic.cpp
Go to the documentation of this file.
1 #include "sphere.h"
2 #include "ani_texture.h"
3 #include "vegastrike.h"
4 #include "config_xml.h"
5 #include "vs_globals.h"
6 #include "vsfilesystem.h"
7 #include "xml_support.h"
8 #ifndef M_PI
9 #define M_PI (3.1415926536F)
10 #endif
11 #include "gfx/camera.h"
12 
13 extern Texture * createTexture( const char *filename,
14  int stage = 0,
15  enum FILTER f1 = MIPMAP,
18  unsigned char c = GFXFALSE,
19  int i = 65536 );
20 extern Texture * createTexture( char const *ccc,
21  char const *cc,
22  int k = 0,
23  enum FILTER f1 = MIPMAP,
26  float f = 1,
27  int j = 0,
28  unsigned char c = GFXFALSE,
29  int i = 65536 );
30 extern AnimatedTexture * createAnimatedTexture( char const *c, int i, enum FILTER f );
31 
33 int pixelscalesize = 30;
34 
35 float SphereMesh::GetT( float rho, float rho_min, float rho_max ) const
36 {
37  return 1-(rho-rho_min)/(rho_max-rho_min);
38 }
39 
40 float SphereMesh::GetS( float theta, float theta_min, float theta_max ) const
41 {
42  return 1-(theta-theta_min)/(theta_max-theta_min);
43 }
44 
45 float CityLights::GetT( float rho, float rho_min, float rho_max ) const
46 {
47  return wrapy*SphereMesh::GetT( rho, rho_min, rho_max );
48 }
49 
50 float CityLights::GetS( float theta, float theta_min, float theta_max ) const
51 {
52  return wrapx*SphereMesh::GetS( theta, theta_min, theta_max );
53 }
54 
55 string truncateByPipe( string &input )
56 {
57  string::size_type i = input.find( "|" );
58  string ret = input;
59  if (i != string::npos) {
60  ret = input.substr( 0, i );
61  input = input.substr( i+1 );
62  } else {
63  input = "";
64  }
65  return ret;
66 }
67 
68 void SphereMesh::InitSphere( float radius,
69  int stacks,
70  int slices,
71  const char *texture,
72  const std::string &technique,
73  const char *alpha,
74  bool Insideout,
75  const BLENDFUNC a,
76  const BLENDFUNC b,
77  bool envMapping,
78  float rho_min,
79  float rho_max,
80  float theta_min,
81  float theta_max,
82  FILTER mipmap,
83  bool reverse_normals,
84  bool subclass )
85 {
86  setConvex( true );
87  int numspheres = (stacks+slices)/8;
88  if (numspheres < 1)
89  numspheres = 1;
90  Mesh *oldmesh;
91  char ab[3];
92  ab[2] = '\0';
93  ab[1] = b+'0';
94  ab[0] = a+'0';
95  hash_name = string( "@@Sphere" )+"#"+texture+"#"+technique+"#"+XMLSupport::tostring( stacks )+"#"+XMLSupport::tostring( slices )+ab+"#"
96  +XMLSupport::tostring( rho_min )+"#"+XMLSupport::tostring( rho_max );
97  if ( LoadExistant( hash_name, Vector( radius, radius, radius ), 0 ) ) {
98  return;
99  } else {}
100  this->orig = AllocNewMeshesEachInSizeofMeshSpace( numspheres ); //FIXME::RISKY::MIGHT HAVE...
101  //... DIFFERENT SIZES!! DON"T YOU DARE ADD XTRA VARS TO SphereMesh calsshave to!
102  oldmesh = this->orig;
103  numlods = numspheres;
104  meshHashTable.Put( hash_name, oldmesh );
105  radialSize = radius; //MAKE SURE FRUSTUM CLIPPING IS DONE CORRECTLY!!!!!
108  vector< MeshDrawContext > *odq = NULL;
109  for (int l = 0; l < numspheres; l++) {
110  draw_queue = new vector< MeshDrawContext >[NUM_ZBUF_SEQ+1];
111  if (subclass || rho_max != M_PI || rho_min != 0.0 || theta_min != 0.0 || theta_max != 2*M_PI)
112  odq = draw_queue;
113  vlist = NULL;
114  if (subclass) {
115  if (stacks > 12) {
116  stacks -= 4;
117  slices -= 4;
118  } else {
119  stacks -= 2;
120  slices -= 2;
121  }
122  float drho, dtheta;
123  float x, y, z;
124  float s, t, ds, dt;
125  int i, j, imin, imax;
126  float nsign = Insideout ? -1.0 : 1.0;
127  float normalscale = reverse_normals ? -1.0 : 1.0;
128  int fir = 0; //Insideout?1:0;
129  int sec = 1; //Insideout?0:1;
130  /* Code below adapted from gluSphere */
131  drho = (rho_max-rho_min)/(float) stacks;
132  dtheta = (theta_max-theta_min)/(float) slices;
133  ds = 1.0/slices;
134  dt = 1.0/stacks;
135  t = 1.0; /* because loop now runs from 0 */
136  imin = 0;
137  imax = stacks;
138  int numQuadstrips = stacks;
139  //numQuadstrips = 0;
140  int *QSOffsets = new int[numQuadstrips];
141  //draw intermediate stacks as quad strips
142  int numvertex = stacks*(slices+1)*2;
143  GFXVertex *vertexlist = new GFXVertex[numvertex];
144  GFXVertex *vl = vertexlist;
145  enum POLYTYPE *modes = new enum POLYTYPE[numQuadstrips];
146  float rhol[2];
147  float thetal[2];
148 #define g_rho( i ) (rhol[(i)&1])
149 #define g_theta( i ) (thetal[(i)&1])
150  g_rho( 0 ) = rho_min;
151  for (i = imin; i < imax; i++) {
152  GFXVertex *vertexlist = vl+(i*(slices+1)*2);
153  g_rho( i+1 ) = (i+1)*drho+rho_min;
154  s = 0.0;
155  g_theta( 0 ) = 0;
156  for (j = 0; j <= slices; j++) {
157  g_theta( j+1 ) = (j+1)*dtheta;
158  x = -sin( g_theta( j ) )*sin( g_rho( i ) );
159  y = cos( g_theta( j ) )*sin( g_rho( i ) );
160  z = nsign*cos( g_rho( i ) );
161  vertexlist[j*2+fir].i = x*normalscale;
162  vertexlist[j*2+fir].k = -y*normalscale;
163  vertexlist[j*2+fir].j = z*normalscale;
164  vertexlist[j*2+fir].s = GetS( g_theta( j ), theta_min, theta_max ); //1-s;//insideout?1-s:s;
165  vertexlist[j*2+fir].t = GetT( g_rho( i ), rho_min, rho_max ); //t;
166  vertexlist[j*2+fir].x = x*radius;
167  vertexlist[j*2+fir].z = -y*radius;
168  vertexlist[j*2+fir].y = z*radius;
169  x = -sin( g_theta( j ) )*sin( g_rho( i+1 ) );
170  y = cos( g_theta( j ) )*sin( g_rho( i+1 ) );
171  z = nsign*cos( g_rho( i+1 ) );
172  vertexlist[j*2+sec].i = x*normalscale;
173  vertexlist[j*2+sec].k = -y*normalscale;
174  vertexlist[j*2+sec].j = z*normalscale; //double negative
175  vertexlist[j*2+sec].s = GetS( g_theta( j ), theta_min, theta_max ); //1-s;//insideout?1-s:s;
176  vertexlist[j*2+sec].t = GetT( g_rho( i+1 ), rho_min, rho_max ); //t - dt;
177  vertexlist[j*2+sec].x = x*radius;
178  vertexlist[j*2+sec].z = -y*radius;
179  vertexlist[j*2+sec].y = z*radius;
180  s += ds;
181  }
182  t -= dt;
183  QSOffsets[i] = (slices+1)*2;
184  modes[i] = GFXQUADSTRIP;
185  }
186 #undef g_rho
187 #undef g_theta
188  vlist = new GFXVertexList( modes, numvertex, vertexlist, numQuadstrips, QSOffsets );
189  delete[] vertexlist;
190  delete[] modes;
191  delete[] QSOffsets;
192  } else {
193  vlist = new GFXSphereVertexList( radius, stacks > slices ? stacks : slices, Insideout, reverse_normals );
194  }
195  SetBlendMode( a, b );
196  string inputtex = texture;
197  unsigned int count = 0;
198  if ( Decal.empty() )
199  Decal.push_back( NULL );
200  while ( inputtex.length() ) {
201  string thistex = truncateByPipe( inputtex );
202  while (Decal.size() <= count)
203  Decal.push_back( NULL );
204  if (thistex.find( ".ani" ) != string::npos) {
205  Decal[count] = createAnimatedTexture( thistex.c_str(), 0, mipmap );
206  } else {
207  if (alpha) {
208  Decal[count] =
209  createTexture( thistex.c_str(), alpha, 0, mipmap, TEXTURE2D, TEXTURE_2D, 1, 0,
210  (Insideout || g_game.use_planet_textures) ? GFXTRUE : GFXFALSE );
211  } else {
212  Decal[count] =
214  thistex.c_str(), 0, mipmap, TEXTURE2D, TEXTURE_2D,
215  (Insideout || g_game.use_planet_textures) ? GFXTRUE : GFXFALSE );
216  }
217  }
218  count++;
219  }
220  Insideout ? setEnvMap( GFXFALSE ) : setEnvMap( envMapping );
221  if (Insideout)
222  draw_sequence = 0;
223  Mesh *oldorig = orig;
224  refcount = 1;
225  orig = NULL;
226  if (l >= 1) {
227  lodsize = (numspheres+1-l)*pixelscalesize;
228  if (l == 1)
229  lodsize *= 2;
230  else if (l == 2)
231  lodsize *= 1.75;
232  else if (l == 3)
233  lodsize *= 1.5;
234  }
235  initTechnique( technique );
236  oldmesh[l] = *this;
237  refcount = 0;
238  orig = oldorig;
239  lodsize = FLT_MAX;
240  }
241  draw_queue = odq;
242 }
243 
244 void SphereMesh::Draw( float lod, bool centered, const Matrix &m )
245 {
246  if (centered) {
247  Matrix m1( m );
248  m1.p = QVector( _Universe->AccessCamera()->GetPosition().Transform( m1 ) );
249  Mesh::Draw( lod, m1 );
250  } else {
251  Mesh::Draw( lod, m );
252  }
253 }
254 
255 void SphereMesh::RestoreCullFace( int whichdrawqueue )
256 {
257  //always right
258 }
259 
260 float CityLights::wrapx = 1;
261 float CityLights::wrapy = 1;
262 
264  int stacks,
265  int slices,
266  const char *texture,
267  int zzwrapx,
268  int zzwrapy,
269  bool insideout,
270  const BLENDFUNC a,
271  const BLENDFUNC b,
272  bool envMap,
273  float rho_min,
274  float rho_max,
275  float theta_min,
276  float theta_max,
277  bool reversed_normals ) : SphereMesh()
278 {
279  setConvex( true );
280  wrapx = zzwrapx;
281  wrapy = zzwrapy;
282  FILTER filter =
283  (FILTER) XMLSupport::parse_int( vs_config->getVariable( "graphics", "CityLightFilter",
284  XMLSupport::tostring( ( (int) TRILINEAR ) ) ) );
285  InitSphere( radius,
286  stacks,
287  slices,
288  texture,
289  "",
290  NULL,
291  insideout,
292  a,
293  b,
294  envMap,
295  rho_min,
296  rho_max,
297  theta_min,
298  theta_max,
299  filter,
300  reversed_normals,
301  zzwrapx != 1 || zzwrapy != 1 );
302 }
303