Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

electric.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*    FILE: electric.c                                                      */
00003 /*                                                                          */
00004 /*    Copyright (c) 1997, Eclipse Entertainment; All rights reserved.       */
00005 /*                                                                          */
00006 /****************************************************************************/
00007 
00008 #include        <windows.h>
00009 #include        <math.h>
00010 #include        <assert.h>
00011 
00012 #include        "genesis.h"
00013 #include        "ErrorLog.h"
00014 
00015 #include        "Electric.h"
00016 #include        "..\\Procedurals\\gebmutil.h"
00017 
00018 extern  geFloat         EffectScale;
00019 
00020 static  geBitmap                        *Bitmap;
00021 static  geSound_Def *           LoopingDef;
00022 static  geSound_Def *           SingleDef;
00023 static  geSound_System *        SoundSys;
00024 
00025 static geBoolean        Electric_SetWorld(geWorld *World, geVFile *Context);
00026 
00027 typedef struct  Electric_BoltEffect
00028 {
00029         int                     beInitialized;
00030         int                     beNumPoints;
00031         geFloat         beWildness;
00032 
00033         /* For rendering */
00034         geVec3d         beStart;
00035         geVec3d         beEnd;
00036 
00037         /* For generating the geometry */
00038         geVec3d *       beCenterPoints;
00039         geVec3d *       beCurrentPoint;
00040 
00041         geFloat         beBaseColors[3];
00042         geFloat         beCurrentColors[3];
00043         geFloat         beBaseBlue;
00044         int                     beDecayRate;
00045         int                     beDominantColor;
00046 
00047         int                     beWidth;
00048 
00049         geBitmap        *beBitmap;
00050 
00051 }       Electric_BoltEffect;
00052 
00053 Electric_BoltEffect * Electric_BoltEffectCreate(
00054         geBitmap                                *Texture,       /* The texture we map onto the bolt */
00055         geBitmap                                *Texture2,      /* The texture we map onto the bolt */
00056         int                                     NumPolys,       /* Number of polys, must be power of 2 */
00057         int                                             Width,          /* Width in world units of the bolt */
00058         geFloat                                 Wildness);      /* How wild the bolt is (0 to 1 inclusive) */
00059 
00060 void Electric_BoltEffectDestroy(Electric_BoltEffect *Effect);
00061 
00062 void Electric_BoltEffectAnimate(
00063         Electric_BoltEffect *   Effect,
00064         const geVec3d *                 start,          /* Starting point of the bolt */
00065         const geVec3d *                 end);           /* Ending point of the bolt */
00066 
00067 void Electric_BoltEffectRender(
00068         geWorld *                               World,          /* World to render for */
00069         Electric_BoltEffect *   Effect,         /* Bolt to render */
00070         const geXForm3d *               XForm);         /* Transform of our point of view */
00071 
00072 void Electric_BoltEffectSetColorInfo(
00073         Electric_BoltEffect *   Effect,
00074         GE_RGBA *                               BaseColor,              /* Base color of the bolt (2 colors should be the same */
00075         int                                             DominantColor); /* Which color is the one to leave fixed */
00076 
00077 static  int             logBase2(int n)
00078 {
00079         int     i = 0;
00080 
00081         assert(n != 0);
00082 
00083         while   (!(n & 1))
00084         {
00085                 n = n >> 1;
00086                 i++;
00087         }
00088 
00089         assert((n & ~1) == 0);
00090 
00091         return i;
00092 }
00093 
00094 static  geBoolean       IsPowerOf2(int n)
00095 {
00096         if      (n == 0)
00097                 return GE_TRUE;
00098 
00099         while   (!(n & 1))
00100                 n = n >> 1;
00101 
00102         if      (n & ~1)
00103                 return GE_FALSE;
00104 
00105         return GE_TRUE;
00106 }
00107 
00108 Electric_BoltEffect * Electric_BoltEffectCreate(
00109         geBitmap                *Bitmap,
00110         geBitmap                *Bitmap2,
00111         int NumPolys,
00112         int Width,
00113         geFloat Wildness)
00114 {
00115         Electric_BoltEffect *   be;
00116         GE_RGBA                                 color;
00117 
00118         assert(Wildness >= 0.0f && Wildness <= 1.0f);
00119 
00120         /* Asserts power of 2 */
00121         logBase2(NumPolys);
00122 
00123         be = (Electric_BoltEffect *)malloc(sizeof(*be));
00124         if      (!be)
00125                 return be;
00126 
00127         memset(be, 0, sizeof(*be));
00128 
00129         be->beCenterPoints = (geVec3d *)malloc(sizeof(*be->beCenterPoints) * (NumPolys + 1));
00130         if      (!be->beCenterPoints)
00131                 goto fail;
00132 
00133         be->beBitmap    = Bitmap;
00134 //      be->beBitmap2   = Bitmap2;
00135         be->beNumPoints = NumPolys;
00136         be->beWildness  = Wildness;
00137         be->beWidth             = Width;
00138 
00139 //      color.r = 255.0f;
00140 //      color.g = 60.0f;
00141 //      color.b = 60.0f;
00142 //      Electric_BoltEffectSetColorInfo(be, &color, ELECTRIC_BOLT_REDDOMINANT);
00143 
00144 //      color.r = 60.0f;
00145 //      color.g = 255.0f;
00146 //      color.b = 60.0f;
00147 //      Electric_BoltEffectSetColorInfo(be, &color, ELECTRIC_BOLT_GREENDOMINANT);
00148 
00149         color.r = 160.0f;
00150         color.g = 160.0f;
00151         color.b = 255.0f;
00152         Electric_BoltEffectSetColorInfo(be, &color, ELECTRIC_BOLT_BLUEDOMINANT);
00153 
00154         return be;
00155 
00156 fail:
00157         if      (be->beCenterPoints)
00158                 free(be->beCenterPoints);
00159 
00160         return NULL;
00161 }
00162 
00163 void Electric_BoltEffectDestroy(Electric_BoltEffect *Effect)
00164 {
00165         free(Effect->beCenterPoints);
00166         free(Effect);
00167 }
00168 
00169 static  geFloat GaussRand(void)
00170 {
00171         int     i;
00172         int     r;
00173 
00174         r = 0;
00175 
00176         for     (i = 0; i < 6; i++)
00177                 r = r + rand() - rand();
00178 
00179         return (geFloat)r / ((geFloat)RAND_MAX * 6.0f);
00180 }
00181 
00182 static  void    subdivide(
00183         Electric_BoltEffect *   be,
00184         const geVec3d *                 start,
00185         const geVec3d *                 end,
00186         geFloat                                 s,
00187         int                                     n)
00188 {
00189         geVec3d tmp;
00190 
00191         if      (n == 0)
00192         {
00193                 be->beCurrentPoint++;
00194                 *be->beCurrentPoint = *end;
00195                 return;
00196         }
00197         
00198         tmp.X = (end->X + start->X) / 2 + s * GaussRand();
00199         tmp.Y = (end->Y + start->Y) / 2 + s * GaussRand();
00200         tmp.Z = (end->Z + start->Z) / 2 + s * GaussRand();
00201         subdivide(be,  start, &tmp, s / 2, n - 1);
00202         subdivide(be, &tmp,    end, s / 2, n - 1);
00203 }
00204 
00205 #define LIGHTNINGWIDTH 8.0f
00206 
00207 static  void    genLightning(
00208         Electric_BoltEffect *   be,
00209         int                                     RangeLow,
00210         int                                     RangeHigh,
00211         const geVec3d *                 start,
00212         const geVec3d *                 end)
00213 {
00214         geFloat length;
00215         int             seed;
00216 
00217         assert(be);
00218         assert(start);
00219         assert(end);
00220         assert(RangeHigh > RangeLow);
00221         assert(IsPowerOf2(RangeHigh - RangeLow));
00222 
00223         /* Manhattan length is good enough for this */
00224         length = (geFloat)(fabs(start->X - end->X) +
00225                                                 fabs(start->Y - end->Y) +
00226                                                 fabs(start->Z - end->Z));
00227 
00228         seed = rand();
00229 
00230         srand(seed);
00231         be->beCurrentPoint                                      = be->beCenterPoints + RangeLow;
00232         be->beCenterPoints[RangeLow]            = *start;
00233         be->beCenterPoints[RangeHigh]           = *end;
00234 //      be->beCenterPoints[be->beNumPoints] = *end;
00235 //      subdivide(be, start, end, length * be->beWildness, logBase2(be->beNumPoints));
00236         subdivide(be, start, end, length * be->beWildness, logBase2(RangeHigh - RangeLow));
00237 }
00238 
00239 void Electric_BoltEffectSetColorInfo(
00240         Electric_BoltEffect *   Effect,
00241         GE_RGBA *                               BaseColor,
00242         int                                             DominantColor)
00243 {
00244         Effect->beBaseColors[0]         = BaseColor->r;
00245         Effect->beBaseColors[1]         = BaseColor->g;
00246         Effect->beBaseColors[2]         = BaseColor->b;
00247         Effect->beCurrentColors[0]      = BaseColor->r;
00248         Effect->beCurrentColors[1]      = BaseColor->g;
00249         Effect->beCurrentColors[2]      = BaseColor->b;
00250         Effect->beDominantColor         = DominantColor;
00251 }
00252 
00253 void Electric_BoltEffectAnimate(
00254         Electric_BoltEffect *   Effect,
00255         const geVec3d *                 start,
00256         const geVec3d *                 end)
00257 {
00258         int             dominant;
00259         int             nonDominant1;
00260         int             nonDominant2;
00261         geVec3d SubdivideStart;
00262         geVec3d SubdivideEnd;
00263         int             LowIndex;
00264         int             HighIndex;
00265 
00266         Effect->beStart = *start;
00267         Effect->beEnd   = *end;
00268 
00269         dominant = Effect->beDominantColor;
00270         nonDominant1 = (dominant + 1) % 3;
00271         nonDominant2 = (dominant + 2) % 3;
00272         if      (Effect->beBaseColors[nonDominant1] == Effect->beCurrentColors[nonDominant1])
00273         {
00274                 int     DecayRate;
00275                 int     Spike;
00276 
00277                 DecayRate = rand() % (int)(Effect->beBaseColors[dominant] - Effect->beBaseColors[nonDominant1]);
00278                 DecayRate = max(DecayRate, 5);
00279                 Effect->beDecayRate = DecayRate;
00280                 if      (Effect->beBaseColors[nonDominant1] >= 1.0f)
00281                         Spike = rand() % (int)(Effect->beBaseColors[nonDominant1]);
00282                 else
00283                         Spike = 0;
00284                 Effect->beCurrentColors[nonDominant1] -= Spike;
00285                 Effect->beCurrentColors[nonDominant2] -= Spike;
00286         }
00287         else
00288         {
00289                 Effect->beCurrentColors[nonDominant1] += Effect->beDecayRate;
00290                 Effect->beCurrentColors[nonDominant2] += Effect->beDecayRate;
00291                 if      (Effect->beCurrentColors[nonDominant1] > Effect->beBaseColors[nonDominant1])
00292                 {
00293                         Effect->beCurrentColors[nonDominant1] = Effect->beBaseColors[nonDominant1];
00294                         Effect->beCurrentColors[nonDominant2] = Effect->beBaseColors[nonDominant2];
00295                 }
00296         }
00297 
00298         if      (Effect->beInitialized && Effect->beNumPoints > 16)
00299         {
00300                 int             P1;
00301                 int             P2;
00302                 int             P3;
00303                 int             P4;
00304 
00305                 switch  (rand() % 7)
00306                 {
00307                         case    0:
00308                                 genLightning(Effect, 0, Effect->beNumPoints, start, end);
00309                                 return;
00310 
00311                         case    1:
00312                         case    2:
00313                         case    3:
00314                                 P1 = 0;
00315                                 P2 = Effect->beNumPoints / 2;
00316                                 P3 = P2 + Effect->beNumPoints / 4;
00317                                 P4 = Effect->beNumPoints;
00318                                 break;
00319 
00320                         case    4:
00321                         case    5:
00322                         case    6:
00323                                 P1 = 0;
00324                                 P3 = Effect->beNumPoints / 2;
00325                                 P2 = P3 - Effect->beNumPoints / 4;
00326                                 P4 = Effect->beNumPoints;
00327                                 break;
00328                 }
00329                 SubdivideStart = Effect->beCenterPoints[P1];
00330                 SubdivideEnd = Effect->beCenterPoints[P2];
00331                 genLightning(Effect, P1, P2, &SubdivideStart, &SubdivideEnd);
00332                 SubdivideStart = Effect->beCenterPoints[P2];
00333                 SubdivideEnd = Effect->beCenterPoints[P3];
00334                 genLightning(Effect, P2, P3, &SubdivideStart, &SubdivideEnd);
00335                 SubdivideStart = Effect->beCenterPoints[P3];
00336                 SubdivideEnd = Effect->beCenterPoints[P4];
00337                 genLightning(Effect, P3, P4, &SubdivideStart, &SubdivideEnd);
00338         }
00339         else
00340         {
00341                 Effect->beInitialized = 1;
00342                 LowIndex = 0;
00343                 HighIndex = Effect->beNumPoints;
00344                 SubdivideStart = *start;
00345                 SubdivideEnd   = *end;
00346 
00347                 genLightning(Effect, LowIndex, HighIndex, &SubdivideStart, &SubdivideEnd);
00348         }
00349 }
00350 
00351 #if 0
00352 static  void    DrawPoint(geWorld *world, geVec3d *pos, geBitmap *Bitmap, int r, int g, int b)
00353 {
00354         GE_LVertex      vert;
00355 
00356         vert.X = pos->X;
00357         vert.Y = pos->Y;
00358         vert.Z = pos->Z;
00359         vert.r = (geFloat)r;
00360         vert.g = (geFloat)g;
00361         vert.b = (geFloat)b;
00362         vert.a = 255.0f;
00363         vert.u = vert.v = 0.0f;
00364 
00365         GE_WorldAddPolyOnce(world,
00366                                                 &vert,
00367                                                 1,
00368                                                 Bitmap,
00369                                                 GE_TEXTURED_POINT,
00370                                                 GE_FX_TRANSPARENT,
00371                                                 EffectScale);
00372 }
00373 #endif
00374 
00375 #define LIGHTNINGALPHA  160.0f
00376 
00377 void Electric_BoltEffectRender(
00378         geWorld *                               World,
00379         Electric_BoltEffect *   be,
00380         const geXForm3d *               XForm)
00381 {
00382         geVec3d                 perp;
00383         geVec3d                 temp;
00384         geVec3d                 in;
00385         GE_LVertex              verts[4];
00386         int                             i;
00387 
00388         geVec3d_Subtract(&be->beStart, &be->beEnd, &temp);
00389         geXForm3d_GetIn(XForm, &in);
00390 
00391         geVec3d_CrossProduct(&in, &temp, &perp);
00392         geVec3d_Normalize(&perp);
00393 
00394         geVec3d_Scale(&perp, be->beWidth / 2.0f, &perp);
00395 
00396         /*
00397                 We've got the perpendicular to the camera in the
00398                 rough direction of the electric bolt center.  Walk
00399                 the left and right sides, constructing verts, then
00400                 do the drawing.
00401         */
00402         for     (i = 0; i < be->beNumPoints - 1; i++)
00403         {
00404                 geVec3d temp;
00405 
00406                 geVec3d_Subtract(&be->beCenterPoints[i], &perp, &temp);
00407                 verts[0].X = temp.X;
00408                 verts[0].Y = temp.Y;
00409                 verts[0].Z = temp.Z;
00410                 verts[0].u = 0.0f;
00411                 verts[0].v = 0.0f;
00412                 verts[0].r = be->beCurrentColors[0];
00413                 verts[0].g = be->beCurrentColors[1];
00414                 verts[0].b = be->beCurrentColors[2];
00415                 verts[0].a = LIGHTNINGALPHA;
00416 
00417                 geVec3d_Subtract(&be->beCenterPoints[i + 1], &perp, &temp);
00418                 verts[1].X = temp.X;
00419                 verts[1].Y = temp.Y;
00420                 verts[1].Z = temp.Z;
00421                 verts[1].u = 0.0f;
00422                 verts[1].v = 1.0f;
00423                 verts[1].r = be->beCurrentColors[0];
00424                 verts[1].g = be->beCurrentColors[1];
00425                 verts[1].b = be->beCurrentColors[2];
00426                 verts[1].a = LIGHTNINGALPHA;
00427 
00428                 geVec3d_Add(&be->beCenterPoints[i + 1], &perp, &temp);
00429                 verts[2].X = temp.X;
00430                 verts[2].Y = temp.Y;
00431                 verts[2].Z = temp.Z;
00432                 verts[2].u = 1.0f;
00433                 verts[2].v = 1.0f;
00434                 verts[2].r = be->beCurrentColors[0];
00435                 verts[2].g = be->beCurrentColors[1];
00436                 verts[2].b = be->beCurrentColors[2];
00437                 verts[2].a = LIGHTNINGALPHA;
00438 
00439                 geVec3d_Add(&be->beCenterPoints[i], &perp, &temp);
00440                 verts[3].X = temp.X;
00441                 verts[3].Y = temp.Y;
00442                 verts[3].Z = temp.Z;
00443                 verts[3].u = 1.0f;
00444                 verts[3].v = 0.0f;
00445                 verts[3].r = be->beCurrentColors[0];
00446                 verts[3].g = be->beCurrentColors[1];
00447                 verts[3].b = be->beCurrentColors[2];
00448                 verts[3].a = LIGHTNINGALPHA;
00449 
00450                 geWorld_AddPolyOnce(World,
00451                                                         verts,
00452                                                         4,
00453                                                         be->beBitmap,
00454                                                         GE_TEXTURED_POLY,
00455                                                         GE_RENDER_DO_NOT_OCCLUDE_OTHERS,
00456                                                         1.0f);
00457 
00458 //              DrawPoint(World, &be->beCenterPoints[i], be->beTexture, 255, 0, 0);
00459         }
00460 }
00461 
00462 geBoolean Electric_Init(geEngine *Engine, geWorld *World, geVFile * MainFS, geSound_System *SoundSystem)
00463 {
00464         Engine;
00465 
00466         if      (SoundSystem)
00467         {
00468                 geVFile *       File;
00469 
00470                 SoundSys = SoundSystem;
00471                 assert(SoundSys);
00472                 File = geVFile_Open(MainFS, "wav\\loopbzzt.wav", GE_VFILE_OPEN_READONLY);
00473                 if      (!File)
00474                         return GE_FALSE;
00475                 LoopingDef = geSound_LoadSoundDef(SoundSys, File);
00476                 geVFile_Close(File);
00477                 File = geVFile_Open(MainFS, "wav\\onebzzt.wav", GE_VFILE_OPEN_READONLY);
00478                 if      (!File)
00479                         return GE_FALSE;
00480                 
00481                 SingleDef = geSound_LoadSoundDef(SoundSys, File);
00482                 
00483                 geVFile_Close(File);
00484                 if      (!LoopingDef || !SingleDef)
00485                         return GE_FALSE;
00486         }
00487 
00488         if (!Electric_SetWorld(World, MainFS))
00489         {
00490                 // FIXME: Free more stuff
00491                 return GE_FALSE;
00492         }
00493 
00494         return GE_TRUE;
00495 }
00496 
00497 geBoolean Electric_Reset(geWorld *World)
00498 {
00499         geEntity_EntitySet *    Set;
00500         geEntity *                              Entity;
00501 
00502         if      (!World)
00503                 return GE_TRUE;
00504  
00505         Set = geWorld_GetEntitySet(World, "ElectricBolt");
00506         if      (Set == NULL)
00507                 return GE_TRUE;
00508 
00509         Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00510         while   (Entity)
00511         {
00512                 ElectricBolt *          Bolt;
00513 
00514                 Bolt = geEntity_GetUserData(Entity);
00515                 Bolt->LastTime = 0.0f;
00516                 Bolt->LastBoltTime = 0.0f;
00517 
00518                 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00519         }
00520 
00521         return GE_TRUE;
00522 }
00523 
00524 static geBoolean Electric_SetWorld(geWorld *World, geVFile *MainFS)
00525 {
00526         geEntity_EntitySet *    Set;
00527         geEntity *                              Entity;
00528 
00529         assert(World);
00530         assert(MainFS);
00531 
00532         assert(Bitmap == NULL);
00533 
00534         Set = geWorld_GetEntitySet(World, "ElectricBolt");
00535 
00536         if      (Set == NULL)
00537                 return GE_TRUE;
00538 
00539         Bitmap = geBitmapUtil_CreateFromFileAndAlphaNames(MainFS, "Bmp\\Bolt.Bmp", "Bmp\\Bolt.Bmp");
00540 
00541         if (!Bitmap)
00542         {
00543                 geErrorLog_AddString(-1, "Electric_SetWorld:  geBitmapUtil_CreateFromFileAndAlphaNames failed:", "Bmp\\Bolt.Bmp, Bmp\\Bolt.Bmp");
00544                 return GE_FALSE;
00545         }
00546 
00547         if (!geWorld_AddBitmap(World, Bitmap))
00548         {
00549                 geBitmap_Destroy(&Bitmap);
00550                 return GE_FALSE;
00551         }
00552 
00553         Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00554         while   (Entity)
00555         {
00556                 ElectricBolt *  Bolt;
00557 
00558                 Bolt = geEntity_GetUserData(Entity);
00559                 if (Bolt->Terminus == NULL)
00560                         {
00561                                 #define MAX_NAME 100
00562                                 char    EntityName[MAX_NAME];
00563                                 char    s[MAX_NAME + 200];
00564                                 geEntity_GetName(Entity, EntityName, MAX_NAME-1);
00565                                 EntityName[MAX_NAME-1]=0;
00566                                 sprintf(s,"Name='%s' Origin=%f,%f,%f",EntityName,Bolt->origin.X,Bolt->origin.Y,Bolt->origin.Z);
00567                                 geErrorLog_AddString(-1,"Electric_SetWorld:  ElectricBolt entity has no terminius.  ",s);
00568                                 geWorld_RemoveBitmap(World, Bitmap);
00569                                 geBitmap_Destroy(&Bitmap);
00570                                 return GE_FALSE;
00571                         }
00572                 Bolt->Bolt = Electric_BoltEffectCreate(Bitmap,
00573                                                                                            NULL,
00574                                                                                            Bolt->NumPoints,
00575                                                                                            Bolt->Width,
00576                                                                                            Bolt->Wildness);
00577 
00578                 Electric_BoltEffectSetColorInfo(Bolt->Bolt, &Bolt->Color, Bolt->DominantColor);
00579 
00580                 if      (Bolt->Bolt == NULL)
00581                 {
00582                         geWorld_RemoveBitmap(World, Bitmap);
00583                         geBitmap_Destroy(&Bitmap);
00584                         return GE_FALSE;
00585                 }
00586 
00587                 if      (!Bolt->Intermittent && SoundSys)
00588                 {
00589                         Bolt->LoopingSound = geSound_PlaySoundDef(SoundSys,
00590                                                                                                           LoopingDef,
00591                                                                                                           0.0f,
00592                                                                                                           0.0f,
00593                                                                                                           0.0f,
00594                                                                                                           GE_TRUE);
00595                         if      (!Bolt->LoopingSound)
00596                         {
00597                                 geWorld_RemoveBitmap(World, Bitmap);
00598                                 geBitmap_Destroy(&Bitmap);
00599                                 return GE_FALSE;
00600                         }
00601                 }
00602 
00603                 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00604         }
00605 
00606         return GE_TRUE;
00607 }
00608 
00609 geBoolean Electric_Shutdown(void)
00610 {
00611         if (LoopingDef)
00612         {
00613                 geSound_FreeSoundDef(SoundSys, LoopingDef);
00614                 LoopingDef = NULL;
00615         }
00616         
00617         if (SingleDef)
00618         {
00619                 geSound_FreeSoundDef(SoundSys, SingleDef);
00620                 SingleDef = NULL;
00621         }
00622 
00623         if (Bitmap)
00624         {
00625                 //geWorld_RemoveBitmap(World, Bitmap);
00626                 geBitmap_Destroy(&Bitmap);
00627                 Bitmap = NULL;
00628         }
00629 
00630         return GE_TRUE;
00631 }
00632 
00633 static  geFloat frand(geFloat Low, geFloat High)
00634 {
00635         geFloat Range;
00636 
00637         //assert(High > Low);
00638 
00639         Range = High - Low;
00640 
00641         return ((geFloat)(((rand() % 1000) + 1))) / 1000.0f * Range + Low;
00642 }
00643 
00644 #define LIGHTNINGSTROKEDURATION 0.05f
00645 
00646 geBoolean Electric_Frame(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime)
00647 {
00648         geEntity_EntitySet *    Set;
00649         geEntity *                              Entity;
00650  
00651         if      (!World)
00652                 return GE_TRUE;
00653 
00654         Set = geWorld_GetEntitySet(World, "ElectricBolt");
00655         if      (Set == NULL)
00656                 return GE_TRUE;
00657 
00658         Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00659         while   (Entity)
00660         {
00661                 ElectricBolt *  Bolt;
00662                 geFloat                 Volume;
00663                 geFloat                 Pan;
00664                 geFloat                 Frequency;
00665                 geVec3d                 MidPoint;
00666                 int32                   Leaf;
00667 
00668                 Bolt = geEntity_GetUserData(Entity);
00669 
00670                 geVec3d_Subtract(&Bolt->Terminus->origin, &Bolt->origin, &MidPoint);
00671                 geVec3d_AddScaled(&Bolt->origin, &MidPoint, 0.5f, &MidPoint);
00672 
00673                 geWorld_GetLeaf(World, &MidPoint, &Leaf);
00674                 
00675                 if (geWorld_MightSeeLeaf(World, Leaf))
00676                 {
00677                 geSound3D_GetConfig(World,
00678                                                         XForm,
00679                                                         &MidPoint,
00680                                                         600.0f,
00681                                                         2.0f,
00682                                                         &Volume,
00683                                                         &Pan,
00684                                                         &Frequency);
00685 
00686                 Bolt->LastTime += DeltaTime;
00687 
00688                 if      (!Bolt->Intermittent ||
00689                          (Bolt->LastTime - Bolt->LastBoltTime > frand(Bolt->MaxFrequency, Bolt->MinFrequency)))
00690                 {
00691                         Electric_BoltEffectAnimate(Bolt->Bolt,
00692                                                                            &Bolt->origin,
00693                                                                            &Bolt->Terminus->origin);
00694 
00695                         if      (Bolt->Intermittent && SoundSys)
00696                                 geSound_PlaySoundDef(SoundSys, SingleDef, Volume, Pan, Frequency, GE_FALSE);
00697 
00698                         Bolt->LastBoltTime = Bolt->LastTime;
00699                 }
00700 
00701                 if      (!Bolt->Intermittent && SoundSys)
00702                         geSound_ModifySound(SoundSys, Bolt->LoopingSound, Volume, Pan, Frequency);
00703 
00704                 if      (Bolt->LastTime - Bolt->LastBoltTime <= LIGHTNINGSTROKEDURATION)
00705                         Electric_BoltEffectRender(World, Bolt->Bolt, XForm);
00706                 }
00707 
00708                 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00709         }
00710 
00711         return GE_TRUE;
00712 }
00713 

Generated on Tue Sep 30 12:35:40 2003 for GTestAndEngine by doxygen 1.3.2