Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

MoonImage.cpp

Go to the documentation of this file.
00001 /*
00002  * MoonImage.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00037 /*
00038  *
00039  * There are 17 textures representing the phases of the moon.  All are
00040  *   128x128 in size, in RAW/ACT format in the \Art folder:
00041  *
00042  *     moon0000.RAW   Full
00043  *     moon0001.RAW   Waxing Gibbous
00044  *     moon0002.RAW   Waxing Gibbous
00045  *     moon0003.RAW   Waxing Gibbous
00046  *     moon0004.RAW   First Quarter
00047  *     moon0005.RAW   Waxing Crescent
00048  *     moon0006.RAW   Waxing Crescent
00049  *     moon0007.RAW   New -> Waxing
00050  *     moon0008.RAW   New
00051  *     moon0009.RAW   Waning -> New
00052  *     moon0010.RAW   Waning Crescent
00053  *     moon0011.RAW   Waning Crescent
00054  *     moon0012.RAW   Waning Crescent
00055  *     moon0013.RAW   Third Quarter
00056  *     moon0014.RAW   Waning Gibbous
00057  *     moon0015.RAW   Waning Gibbous
00058  *     moon0016.RAW   Waning Gibbous
00059  */
00060 
00061 #include "../Include/Sky.h"
00062 #include "../Ssg/ssgLocal.h"
00063 #include "../Include/Utility.h"
00064 #include "../Include/Ui.h"
00065 #include "../Include/Globals.h"
00066 
00067 #include <plib/ssgAux.h>
00068 
00069 
00070 static int moonimage_predraw (ssgEntity *e)
00071 {
00072   ssgLeaf *f = (ssgLeaf*) e;
00073   if (f->hasState()) {
00074     ssgSimpleState* state = (ssgSimpleState*) f->getState();
00075     state->apply ();
00076   }
00077 
00078   glPushAttrib (GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
00079   glDisable (GL_DEPTH_TEST);
00080   glDisable (GL_FOG);
00081 
00082   return true;
00083 }
00084 
00085 
00086 static int moonimage_postdraw (ssgEntity *e)
00087 {
00088   glPopAttrib ();
00089   return true;
00090 }
00091 
00092 
00093 #define N_PHASES  17
00094 
00096 
00097 CMoonImage::CMoonImage (double size)
00098 {
00099   // Instantiate SSG entities
00100   top = new ssgTransform;
00101   top->setName ("Moon");
00102 
00103   // Load textures
00104   for (int i=0; i<N_PHASES; i++) {
00105     // Construct moon texture RAW, ACT and OPA filenames
00106     char base[64];
00107     sprintf (base, "MOON%04d", i);
00108 
00109     char rawFilename[64];
00110     char actFilename[64];
00111     char opaFilename[64];
00112     sprintf (rawFilename, "ART\\MOON%04d.RAW", i);
00113     sprintf (actFilename, "ART\\MOON%04d.ACT", i);
00114     sprintf (opaFilename, "ART\\MOON%04d.OPA", i);
00115 
00116     // Load the textures, non-mipmapped
00117     texlist[i] = new CRawImage (128, 128, rawFilename, actFilename, opaFilename);
00118     if (texlist[i] == NULL) {
00119       globals->logWarning->Write ("CMoonImage : Could not open texture %s", rawFilename);
00120     }
00121   }
00122 
00123   // Create leaf node for the orb
00124   ssgVertexArray *va = new ssgVertexArray (4);
00125   ssgColourArray *ca = new ssgColourArray (1);
00126   ssgNormalArray *na = new ssgNormalArray (1);
00127   ssgTexCoordArray *ta = new ssgTexCoordArray (4);
00128 
00129   sgVec3 v;
00130   sgSetVec3 (v,  size, size, 0);
00131   va->add (v);
00132   sgSetVec3 (v,  size, -size, 0);
00133   va->add (v);
00134   sgSetVec3 (v, -size, -size, 0);
00135   va->add (v);
00136   sgSetVec3 (v, -size, size, 0);
00137   va->add (v);
00138 
00139   sgVec3 n;
00140   sgSetVec3 (n, 0.0, 1.0, 0.0);
00141   na->add (n);
00142 
00143   sgVec4 c;
00144   sgSetVec4 (c, 1.0, 1.0, 1.0, 1.0);
00145   ca->add (c);
00146 
00147   sgVec2 t;
00148   sgSetVec2 (t, 0.0, 0.0);
00149   ta->add (t);
00150   sgSetVec2 (t, 0.0, 1.0);
00151   ta->add (t);
00152   sgSetVec2 (t, 1.0, 1.0);
00153   ta->add (t);
00154   sgSetVec2 (t, 1.0, 0.0);
00155   ta->add (t);
00156 
00157 //  orb = new ssgVtxTable (GL_TRIANGLE_STRIP, va, na, ta, ca);
00158   orb = new ssgVtxTable (GL_POLYGON, va, na, ta, ca);
00159   orb->setName ("Orb");
00160   orb->setCallback (SSG_CALLBACK_PREDRAW, moonimage_predraw);
00161   orb->setCallback (SSG_CALLBACK_POSTDRAW, moonimage_postdraw);
00162 
00163   // Create state for the orb
00164   ssgSimpleState *state = new ssgSimpleState ();
00165   state->setShadeModel (GL_SMOOTH);
00166   state->disable (GL_LIGHTING);
00167 //  state->disable (GL_CULL_FACE);
00168   state->enable (GL_CULL_FACE);
00169   state->enable (GL_TEXTURE_2D);
00170   state->enable (GL_COLOR_MATERIAL);
00171   state->enable (GL_BLEND);
00172   state->disable (GL_ALPHA_TEST);
00173   state->setColourMaterial (GL_AMBIENT_AND_DIFFUSE);
00174   state->setMaterial (GL_EMISSION, 0, 0, 0, 1);
00175   state->setMaterial (GL_SPECULAR, 0, 0, 0, 1);
00176   state->setAlphaClamp (0.01);
00177   phase = -1;
00178   orb->setState (state);
00179 
00180   // Add the cutout to the top-level transform
00181   top->addKid (orb);
00182 
00183 //  FILE* f = fopen ("moonimage.txt", "w");
00184 //  top->print (f);
00185 //  fclose (f);
00186 }
00187 
00188 CMoonImage::~CMoonImage (void)
00189 {
00190   // Delete moon texture images
00191   for (int i=0; i<N_PHASES; i++) {
00192     if (texlist[i] != NULL) delete texlist[i];
00193   }
00194 
00195   // Delete top-level SSG entity
00196   delete top;
00197 }
00198 
00199 
00200 ssgEntity*    CMoonImage::GetSSGEntity (void)
00201 {
00202   return top;
00203 }
00204 
00205 
00206 // Repaint the moon image based on its relative angle in radians:
00207 //    0  =   Transit (highest point in the sky)
00208 //   PI/2 =  Rise/set
00209 //    PI  =  Nadir
00210 //
00211 // Age is number of days into current lunation (0.0 = new moon, ~14.5 = full moon)
00212 //
00213 // Moon lighting algorithm adapted from SimGear 0.3.3
00214 
00215 void CMoonImage::Repaint (double angle, float age)
00216 {
00217   // Select appropriate phase based on lunar phase age.
00218   // ??? Is this correct or was another bug fixed to prevent the crash ???
00219   // Only change the texture
00220   //   if it is not already the current moon texture.  SSG will crash
00221   //   if the same texture is re-set as the actual texture.
00222   int new_phase = (int)(((LUNATION_DAYS - age) / LUNATION_DAYS) * N_PHASES + 0.5) + (N_PHASES / 2);
00223   while (new_phase < 0) { new_phase += N_PHASES; }
00224   while (new_phase >= N_PHASES) { new_phase -= N_PHASES; }
00225   if (new_phase != phase && (texlist[new_phase] != NULL)) {
00226     ssgSimpleState* state = (ssgSimpleState*) orb->getState();
00227 
00228     // Free old phase texture from video memory
00229     texlist[phase]->FreeTexture ();
00230 
00231     // Assign new phase texture
00232     GLint t = texlist[new_phase]->GetTexture(true);
00233     state->setTexture (t);
00234     state->force ();
00235 
00236     phase = new_phase;
00237   }
00238 
00239   // x_10 = moon_angle^10
00240   double x_2 = angle * angle;
00241   double x_10 = x_2 * x_2 * x_2 * x_2 * x_2;
00242 
00243   // Calculate ambient light caused by moon; clamped between 0.3 and 1.0
00245   float ambient = (float)(0.4 * pow (1.1, -x_10 / 30.0));
00246   if (ambient < 0.3) ambient = 0.3;
00247   if (ambient > 1.0) ambient = 1.0;
00248 
00249   // Compute moon colouring
00250   sgVec4 colour;
00251   sgSetVec4 (colour,
00252     (ambient * 6.0) - 1.0,
00253     (ambient * 11.0) - 3.0,
00254     (ambient * 12.0) - 3.6,
00255     0.5);
00256 
00257   // For testing, force colour to pure white
00258   sgSetVec4 (colour, 1.0, 1.0, 1.0, 1.0);
00259 
00260   // Clamp colour components to maximum 1.0
00261   if (colour[0] > 1.0) colour[0] = 1.0;
00262   if (colour[1] > 1.0) colour[1] = 1.0;
00263   if (colour[2] > 1.0) colour[2] = 1.0;
00264 
00265   // Update colour of moon leaf node
00266 //  ssgVtxTable *vt = (ssgVtxTable*) orb_cutout->getKid(0);
00267   ssgVtxTable *vt = (ssgVtxTable*) top->getKid (0);
00268   float *ptr = vt->getColours()->get(0);
00269 //  float *ptr = orb->getColours()->get(0);
00270   sgCopyVec4 (ptr, colour);
00271 
00272   // DEBUG
00273 //  char debug[80];
00274 //  sprintf (debug, "age=%7.3f   phase=%d", age, phase);
00275 //  DrawNoticeToUser (debug, 1);
00276 }
00277 
00278 
00279 //
00280 // Update the position of the moon image in the sky
00281 //
00282 void CMoonImage::Reposition (sgVec3 p, double theta, double lst, double lat,
00283                double ra, double dec, double spin,
00284                double distance)
00285 {
00286   sgMat4 LST, LAT, RA, DEC, D, E, SCALE;
00287   sgVec3 axis;
00288   sgVec3 v;
00289 
00295   sgMakeIdentMat4 (SCALE);
00296   if (theta > (SGD_PI / 4)) {
00297     sgMat4 I;
00298     sgMakeIdentMat4 (I);
00299     float scale = 1.0 + fabs ((theta - (SGD_PI/4)) / (SGD_PI/4));
00300     sgScaleMat4 (SCALE, I, scale);
00301 
00302     // DEBUG
00303 //    char debug[80];
00304 //    sprintf (debug, "moon scale =%7.3f", scale);
00305 //    DrawNoticeToUser (debug, 1);
00306   }
00307 
00308   // Rotation matrix for latitude
00309   sgSetVec3 (axis, -1, 0, 0);
00310   sgMakeRotMat4 (LAT, 90-lat, axis);
00311 
00312   // Rotation matrix for local sidereal time, converted from h to deg
00313   sgSetVec3 (axis, 0, 0, -1);
00314   sgMakeRotMat4 (LST, (lst * 15), axis);
00315 
00316   // Rotation matrix for right ascension
00317   sgSetVec3 (axis, 0, 0, 1);
00318   sgMakeRotMat4 (RA, RadToDeg (ra), axis);
00319 
00320   // Rotation matrix for declination
00321   sgSetVec3 (axis, 1, 0, 0);
00322   sgMakeRotMat4 (DEC, 90 - RadToDeg (dec), axis);
00323 
00324   // Translate sun distance
00325   sgSetVec3 (v, 0, 0, distance);
00326   sgMakeTransMat4 (D, v);
00327 
00329   sgSetVec3 (axis, 0, 0, 1);
00330   sgMakeRotMat4 (E, 0, axis);
00331 
00332   // Combine all transforms
00333   sgMat4 T;
00334   sgMakeIdentMat4 (T);
00335   sgPreMultMat4 (T, LAT);
00336   sgPreMultMat4 (T, LST);
00337   sgPreMultMat4 (T, RA);
00338   sgPreMultMat4 (T, DEC);
00339   sgPreMultMat4 (T, D);
00340   sgPreMultMat4 (T, E);
00341   
00342   top->setTransform (T);
00343 }
SourceForge.net Logo Documentation generated by doxygen