Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

ssgaWaveSystem2.cpp

Go to the documentation of this file.
00001 
00002 /*
00003      PLIB - A Suite of Portable Game Libraries
00004      Copyright (C) 1998,2002  Steve Baker
00005  
00006      This library is free software; you can redistribute it and/or
00007      modify it under the terms of the GNU Library General Public
00008      License as published by the Free Software Foundation; either
00009      version 2 of the License, or (at your option) any later version.
00010  
00011      This library is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014      Library General Public License for more details.
00015  
00016      You should have received a copy of the GNU Library General Public
00017      License along with this library; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019  
00020      For further information visit http://plib.sourceforge.net
00021 
00022      $Id: ssgaWaveSystem.cxx,v 1.10 2002/09/02 06:05:49 sjbaker Exp $
00023 */
00024 
00025 #include "ssgaWaveSystem2.h"
00026 #include <plib/ssgAux.h>
00027 #include <string.h>
00028 #include <plib/ul.h>
00029 #define G 9.81f
00030 
00031 void ssgaWaveSystem2::set_active() {
00032   active = true;
00033 }
00034 
00035 void ssgaWaveSystem2::updateAnimation ( float tim )
00036 {
00037   if ( ntriangles <= 0 ||
00038        normals    == NULL || colours    == NULL ||
00039        texcoords  == NULL || vertices   == NULL ||
00040        orig_vertices == NULL )
00041     return ;
00042   if (!active) 
00043     return;
00044   active = false;
00045   int i ;
00046  
00047   static ulClock ck ;
00048   ck.update();
00049   double t = ck . getAbsTime   () ;
00050   
00051   time_iterator += t;
00052   if (time_iterator < 0)
00053     time_iterator = 0;
00054 
00055   float adjSpeed   [ SSGA_MAX_WAVETRAIN ] ;
00056   float sinHeading [ SSGA_MAX_WAVETRAIN ] ;
00057   float cosHeading [ SSGA_MAX_WAVETRAIN ] ;
00058   float length     [ SSGA_MAX_WAVETRAIN ] ;
00059   float lambda     [ SSGA_MAX_WAVETRAIN ] ;
00060   float height     [ SSGA_MAX_WAVETRAIN ] ;
00061 
00062   /* Pre-adjust speed's to allow for wind speed. */
00063 
00064   int num_trains = 0 ;
00065   float noi = 0;
00066   for ( i = 0 ; i < SSGA_MAX_WAVETRAIN ; i++)
00067     if ( train [ i ] != NULL )
00068     {
00069       adjSpeed   [num_trains] = train [ i ] -> getSpeed () * G *
00070                                                       t / windSpeed ;
00071       sinHeading [num_trains] = (float) -sin ( train[i]->getHeading () *
00072                                                       SG_DEGREES_TO_RADIANS ) ;
00073       cosHeading [num_trains] = (float) cos ( train[i]->getHeading () *
00074                                                       SG_DEGREES_TO_RADIANS ) ;
00075       length     [num_trains] = train [ i ] -> getLength     () ;
00076       lambda     [num_trains] = train [ i ] -> getLambda     () ;
00077       height     [num_trains] = train [ i ] -> getWaveHeight () ;
00078       num_trains++ ;
00079     }
00080 
00081   for ( i = 0 ; i <= nstrips ; i++ )
00082   {
00083     float fade_i = (i<1) ? 0.05f : (i<5) ? (float)(i-2)/5.0f :
00084                    (i>nstrips-1) ? 0.05f :
00085                    (i>nstrips-5) ? (float)(nstrips-i-2)/5.0f : 1.0f ;
00086 
00087     for ( int j = 0 ; j <= nstacks ; j++ )
00088     {
00089       float fade_j = (j<1) ? 0.05f : (j<5) ? (float)(j-2)/5.0f :
00090                      (j>nstacks-1) ? 0.05f :
00091                      (j>nstacks-5) ? (float)(nstacks-j-2)/5.0f : 1.0f ;
00092 
00093       float edge_fade = fade_i * fade_j ;
00094 
00095       int  idx = i * (nstrips+1) + j ;
00096 
00097       float x0 = orig_vertices [idx][0] + center[0] ;
00098       float y0 = orig_vertices [idx][1] + center[1] ; 
00099       float z0 = vertices [idx][2] ;
00100 
00101       float depth = (gridGetter==NULL) ? 1000000.0f : gridGetter ( x0, y0 ) ;
00102 
00103       float xx = x0 ;
00104       float yy = y0 ;
00105       float zz = center[2] ;
00106 
00107       for ( int t = 0 ; t < num_trains ; t++ )
00108       {
00109         float adjHeight = height [ t ] * edge_fade ;
00110         float adjLength = ( depth < 0.2f ) ? 0.2f :
00111                             ( depth > length[t] ) ? length[t] : depth ;
00112 
00113         float phase = ( x0 * sinHeading[t] + y0 * cosHeading[t] ) / adjLength -
00114                                              adjSpeed[t] - lambda[t] * z0 ;
00115 
00116         float delta = adjHeight * (float) sin ( phase ) ;
00117 
00118         xx += delta * sinHeading [ t ] ;
00119         yy += delta * cosHeading [ t ] ;
00120         zz += adjHeight * (float) -cos ( phase ) ;
00121       }
00122       noi = noiser.getNoise(xx, yy, time_iterator);
00123       sgSetVec3 ( vertices  [idx], xx, yy, zz + noi * roughness ) ; 
00124       noi *= tex_noise;
00125       sgSetVec2 ( texcoords [idx], tu * x0 / size[0] + noi, tv * y0 /size[1] +noi) ;
00126     }
00127   }
00128 
00129   for ( i = 0 ; i < nstrips ; i++ )
00130   {
00131     int i1 =   i   * (nstrips+1) ;
00132     int i2 = (i+1) * (nstrips+1) ;
00133 
00134     for ( int j = 0 ; j < nstacks ; j++ )
00135     {
00136       int idx1 = i1 +   j   ;
00137       int idx2 = i2 +   j   ;
00138       int idx3 = i1 + (j+1) ;
00139 
00140       sgVec3 ab ; sgSubVec3 ( ab, vertices[idx3], vertices[idx1] ) ;
00141       sgVec3 ac ; sgSubVec3 ( ac, vertices[idx2], vertices[idx1] ) ;
00142 
00143       float nx = ab[1] * ac[2] - ab[2] * ac[1] ;
00144       float ny = ab[2] * ac[0] - ab[0] * ac[2] ;
00145       float nz = ab[0] * ac[1] - ab[1] * ac[0] ;
00146 
00147       /* About 10% of execution time is in this instruction!  */
00148       float rlen = 1.0f / (float) sqrt ( nx * nx + ny * ny + nz * nz ) ;
00149 
00150       normals[idx1][0] = nx * rlen ;
00151       normals[idx1][1] = ny * rlen ;
00152       normals[idx1][2] = nz * rlen ;
00153     }
00154   }
00155 
00156   for ( i = 0 ; i < nstrips ; i++ )
00157   {
00158     ssgVtxTable      *vt = (ssgVtxTable *) getKid ( i ) ;
00159     ssgVertexArray   *vv = vt -> getVertices  () ;
00160     ssgNormalArray   *nn = vt -> getNormals   () ;
00161     ssgColourArray   *cc = vt -> getColours   () ;
00162     ssgTexCoordArray *tt = vt -> getTexCoords () ;
00163 
00164     int i1 = (i+1) * (nstrips+1) ;
00165     int i2 =   i   * (nstrips+1) ;
00166 
00167     for ( int j = 0, jj = 0 ; j < nstacks + 1 ; j++, jj += 2, i1++, i2++ )
00168     {
00169       vv -> set ( vertices [i1], jj   ) ; vv -> set ( vertices [i2], jj+1 ) ;
00170       nn -> set ( normals  [i1], jj   ) ; nn -> set ( normals  [i2], jj+1 ) ;
00171       cc -> set ( colours  [i1], jj   ) ; cc -> set ( colours  [i2], jj+1 ) ;
00172       tt -> set ( texcoords[i1], jj   ) ; tt -> set ( texcoords[i2], jj+1 ) ;
00173     }
00174   }
00175 }
00176 
00177 
00178 void ssgaWaveSystem2::copy_from ( ssgaWaveSystem2 *src, int clone_flags )
00179 {
00180   ssgaShape::copy_from ( src, clone_flags ) ;
00181  
00182   setDepthCallback ( src -> getDepthCallback () ) ;
00183   setWindSpeed     ( src -> getWindSpeed     () ) ;
00184   setWindDirn      ( src -> getWindDirn      () ) ;
00185   setEdgeFlatten   ( src -> getEdgeFlatten   () ) ;
00186 } 
00187 
00188 
00189 ssgBase *ssgaWaveSystem2::clone ( int clone_flags )
00190 {
00191   ssgaWaveSystem2 *b = new ssgaWaveSystem2 ( getNumTris() ) ;
00192   b -> copy_from ( this, clone_flags ) ;
00193   return b ;
00194 }
00195 
00196 
00197 ssgaWaveSystem2::ssgaWaveSystem2 ( int np ) : ssgaShape ( np )
00198 {
00199   type=ssgaTypeWaveSystem ();
00200   active = true;
00201   setDepthCallback ( NULL ) ;
00202   setWindSpeed     ( 1.0f ) ;
00203   setWindDirn      ( 0.0f ) ;
00204   setEdgeFlatten   ( 0.0f ) ;
00205 
00206   nstrips = nstacks = 0 ;
00207 
00208   normals   = NULL ;
00209   colours   = NULL ;
00210   texcoords = NULL ;
00211   vertices  = NULL ;
00212   orig_vertices  = NULL ;
00213 
00214   tu = tv = 1.0f ;
00215 
00216   for ( int i = 0 ; i < SSGA_MAX_WAVETRAIN ; i++ )
00217     train [ i ] = NULL ;
00218 
00219   regenerate();
00220 }
00221 
00222 
00223 ssgaWaveSystem2::~ssgaWaveSystem2 (void) {}
00224 
00225 const char *ssgaWaveSystem2::getTypeName(void) { return "ssgaWaveSystem2" ; }
00226 
00227 
00228 void ssgaWaveSystem2::regenerate ()
00229 {
00230   delete[] normals   ;
00231   delete[] colours   ;
00232   delete[] texcoords ;
00233   delete[] vertices  ;
00234   delete[] orig_vertices  ;
00235 
00236   roughness = 0.25f;
00237   tex_noise = (float)1/(float)13;
00238   
00239   normals   = NULL ;
00240   colours   = NULL ;
00241   texcoords = NULL ;
00242   vertices  = NULL ;
00243   orig_vertices  = NULL ;
00244 
00245   nstrips = nstacks = 0 ;
00246 
00247   if ( kidState != NULL ) kidState -> ref () ;
00248   removeAllKids () ;
00249   if ( kidState != NULL ) kidState -> deRef () ;
00250 
00251   if ( ntriangles <= 0 )
00252     return ;
00253 
00254   int gridSize = (int) sqrt ( (float) ntriangles / 2.0f ) ;
00255  
00256   nstacks = gridSize ;
00257   nstrips = gridSize ;
00258 
00259   if ( nstacks < 1 ) nstacks = 1 ;
00260   if ( nstrips < 1 ) nstrips = 1 ;
00261 
00262   normals   = new sgVec3 [ (nstacks+1) * (nstrips+1) ] ;
00263   colours   = new sgVec4 [ (nstacks+1) * (nstrips+1) ] ;
00264   texcoords = new sgVec2 [ (nstacks+1) * (nstrips+1) ] ;
00265   vertices  = new sgVec3 [ (nstacks+1) * (nstrips+1) ] ;
00266   orig_vertices = new sgVec3 [ (nstacks+1) * (nstrips+1) ] ;
00267 
00268   int i;
00269   for ( i = 0 ; i <= nstrips ; i++ )
00270     for ( int j = 0 ; j <= nstacks ; j++ )
00271     {
00272       int idx = i * (nstrips+1) + j ;
00273 
00274       float x = (float) j / (float) nstacks ;
00275       float y = (float) i / (float) nstrips ;
00276 
00277       /*if ( j == 0 ) x = -500.0f ;
00278       if ( j == nstacks ) x = 500.0f ;
00279       if ( i == 0 ) y = -500.0f ;
00280       if ( i == nstacks ) y = 500.0f ;
00281 */
00282       sgSetVec3  ( vertices [idx], (x-0.5f) * size[0],
00283                                    (y-0.5f) * size[1], 0.0f ) ;
00284       sgSetVec3  ( normals  [idx], 0.0f, 0.0f, 1.0f ) ;
00285       sgSetVec2  ( texcoords[idx], x * tu, y * tv ) ;
00286       sgCopyVec4 ( colours  [idx], colour ) ;
00287       sgCopyVec3 ( orig_vertices [ idx ], vertices [idx] ) ;
00288     }
00289 
00290   for ( i = 0 ; i < nstrips ; i++ )
00291   {
00292     ssgVtxTable      *vt = new ssgVtxTable ;
00293     ssgVertexArray   *vv = new ssgVertexArray   ( nstacks * 2 + 2 ) ;
00294     ssgNormalArray   *nn = new ssgNormalArray   ( nstacks * 2 + 2 ) ;
00295     ssgColourArray   *cc = new ssgColourArray   ( nstacks * 2 + 2 ) ;
00296     ssgTexCoordArray *tt = new ssgTexCoordArray ( nstacks * 2 + 2 ) ;
00297 
00298     addKid ( vt ) ;
00299 
00300     vt -> setState    ( getKidState () ) ;
00301     vt -> setCallback ( SSG_CALLBACK_PREDRAW , getKidPreDrawCB  () ) ;
00302     vt -> setCallback ( SSG_CALLBACK_POSTDRAW, getKidPostDrawCB () ) ;
00303 
00304     vt -> setPrimitiveType ( GL_TRIANGLE_STRIP ) ;
00305 
00306     for ( int j = 0 ; j < nstacks + 1 ; j++ )
00307     {
00308       int idx = (i+1) * (nstrips+1) + j ;
00309 
00310       vv -> add ( vertices [ idx ] ) ; nn -> add ( normals  [ idx ] ) ;
00311       cc -> add ( colours  [ idx ] ) ; tt -> add ( texcoords[ idx ] ) ;
00312 
00313       idx = i * (nstrips+1) + j ;
00314 
00315       vv -> add ( vertices [ idx ] ) ; nn -> add ( normals  [ idx ] ) ;
00316       cc -> add ( colours  [ idx ] ) ; tt -> add ( texcoords[ idx ] ) ;
00317     }
00318 
00319     vt -> setVertices  ( vv ) ;
00320     vt -> setNormals   ( nn ) ;
00321     vt -> setColours   ( cc ) ;
00322     vt -> setTexCoords ( tt ) ;
00323 
00324     vt -> recalcBSphere () ;
00325   }
00326   recalcBSphere () ;
00327 }
00328 
00329 
00330 // XXX really need these (and ssgLocal.h is not accessible):
00331 extern int _ssgLoadObject ( FILE *, ssgBase **, int ) ;
00332 extern int _ssgSaveObject ( FILE *, ssgBase * ) ;
00333 
00334 
00335 #define load_field(fp, name) (fread(&(name), 1, sizeof(name), fp) == sizeof(name))
00336 #define save_field(fp, name) (fwrite(&(name), 1, sizeof(name), fp) == sizeof(name))
00337 
00338 
00339 int ssgaWaveSystem2::load ( FILE *fp )
00340 {
00341    return ( load_field ( fp, windSpeed ) &&
00342             load_field ( fp, windHeading ) &&
00343             load_field ( fp, edgeFlatten ) &&
00344             load_field ( fp, tu ) &&
00345             load_field ( fp, tv ) &&
00346             ssgaShape::load ( fp ) ) ;
00347 }
00348 
00349 
00350 
00351 int ssgaWaveSystem2::save ( FILE *fp )
00352 {
00353    return ( save_field ( fp, windSpeed ) &&
00354             save_field ( fp, windHeading ) &&
00355             save_field ( fp, edgeFlatten ) &&
00356             save_field ( fp, tu ) &&
00357             save_field ( fp, tv ) &&
00358             ssgaShape::save ( fp ) ) ;
00359 }
00360 
00361 
00362 

Generated on Sat Jul 12 04:29:21 2003 for glPirates by doxygen 1.3.2