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

PathPt.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*    FILE: PathPt.c                                                                                                            */
00003 /****************************************************************************/
00004 #define WIN32_LEAN_AND_MEAN
00005 #include        <windows.h>
00006 
00007 // PathPt kind of does a naughty thing.  It digs directly into the world, to get the entities needed
00008 // to make a path.  This is ok, UNTIL the game stuff gets put into a dll.  Then we'll need to make
00009 // an interface to all the genesis API's needed to access the world.  ALSO, NOTE that this stuff will
00010 // still only happen on the server side...
00011 
00012 #include        <math.h>
00013 #include        <stdlib.h>
00014 #include        <assert.h>
00015 
00016 #include        "PathPt.h"
00017 #include    "_Bot.h"
00018 #include        "Track.h"
00019 
00020 static  geBoolean PathPoint_Frame2(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime);
00021 static  geBoolean PathPoint_Frame3(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime);
00022 
00023 static  geBitmap        *PathPointTexture;
00024 
00025 #define SetRGB(t,rv,gv,bv) ((t).r = (float)(rv), (t).g = (float)(gv), (t).b = (float)(bv))
00026 
00027 static  void    DrawLine3d(
00028         geWorld *                       World,
00029         const geXForm3d *       M, 
00030         const geVec3d *         p1,
00031         const geVec3d *         p2,
00032         int r, int g, int b,
00033         int r1, int g1, int b1
00034         )
00035 {
00036         GE_LVertex      v[4];
00037         int                     i;
00038         geVec3d         perp;
00039         geVec3d         in;
00040 
00041         v[0].u = 0.0f;
00042         v[0].v = 0.0f;
00043         v[1].u = 1.0f;
00044         v[1].v = 0.0f;
00045         v[2].u = 1.0f;
00046         v[2].v = 1.0f;
00047         v[3].u = 0.0f;
00048         v[3].v = 1.0f;
00049 
00050         for     (i = 0; i < 4; i++)
00051         {
00052                 v[i].r = (geFloat)r;
00053                 v[i].g = (geFloat)g;
00054                 v[i].b = (geFloat)b;
00055                 v[i].a = 255.0f;
00056         }
00057 
00058         geVec3d_Subtract(p1, p2, &perp);
00059         geXForm3d_GetIn(M, &in);
00060         geVec3d_CrossProduct(&perp, &in, &perp);
00061         geVec3d_Normalize(&perp);
00062 //      geVec3d_Scale(&perp, 4.0f / 2.0f, &perp);
00063         geVec3d_Scale(&perp, 2.0f / 2.0f, &perp);
00064 
00065         v[0].X = p2->X - perp.X;
00066         v[0].Y = p2->Y - perp.Y;
00067         v[0].Z = p2->Z - perp.Z;
00068         v[1].X = p2->X + perp.X;
00069         v[1].Y = p2->Y + perp.Y;
00070         v[1].Z = p2->Z + perp.Z;
00071         v[2].X = p1->X + perp.X;
00072         v[2].Y = p1->Y + perp.Y;
00073         v[2].Z = p1->Z + perp.Z;
00074         v[3].X = p1->X - perp.X;
00075         v[3].Y = p1->Y - perp.Y;
00076         v[3].Z = p1->Z - perp.Z;
00077 
00078         SetRGB(v[0], r1, g1, b1);
00079         SetRGB(v[1], r1, g1, b1);
00080         SetRGB(v[2], r, g, b);
00081         SetRGB(v[3], r, g, b);
00082 
00083         geWorld_AddPolyOnce(World,
00084                                                 v,
00085                                                 4,
00086                                                 NULL,
00087                                                 GE_GOURAUD_POLY,
00088                                                 GE_RENDER_DO_NOT_OCCLUDE_OTHERS,
00089                                                 1.0f);
00090 }
00091 
00092 geBoolean PathPt_Reset(geWorld *World)
00093 {
00094         if      (!World)
00095                 return GE_TRUE;
00096 
00097         memset(TrackList,0,sizeof(TrackList[0])*MAX_TRACKS);
00098         TrackCount = 0;
00099 
00100         return GE_TRUE;
00101 }
00102 
00103 static geBoolean PathPoint_SetTexture(geWorld *World, geVFile *MainFS)
00104 {
00105         geEntity_EntitySet      *Set;
00106         geBitmap                        *ABitmap;
00107 
00108         ABitmap = NULL;
00109 
00110         if      (World == NULL)
00111                 return GE_TRUE;
00112 
00113         Set = geWorld_GetEntitySet(World, "PathPoint");
00114         if      (Set == NULL)
00115                 return GE_TRUE;
00116 
00117         PathPointTexture = geBitmap_CreateFromFileName(MainFS, "Bmp\\Corona.Bmp");
00118 
00119         if (!PathPointTexture)
00120         {
00121                 goto ExitWithError;
00122         }
00123 
00124         ABitmap = geBitmap_CreateFromFileName(MainFS, "Bmp\\Corona.Bmp");
00125 
00126         if (!ABitmap)
00127         {
00128                 goto ExitWithError;
00129         }
00130 
00131         if (!geBitmap_SetAlpha(PathPointTexture, ABitmap))
00132         {
00133                 goto ExitWithError;
00134         }
00135 
00136         geBitmap_Destroy(&ABitmap);
00137         ABitmap = NULL;
00138 
00139         if (!geWorld_AddBitmap(World, PathPointTexture))
00140         {
00141                 goto ExitWithError;
00142         }
00143 
00144         return GE_TRUE;
00145 
00146         // Error clean up
00147         ExitWithError:
00148         {
00149                 if (PathPointTexture)
00150                 {
00151                         geBitmap_Destroy(&PathPointTexture);
00152                         PathPointTexture = NULL;
00153                 }
00154 
00155                 if (ABitmap)
00156                 {
00157                         geBitmap_Destroy(&ABitmap);
00158                         ABitmap = NULL;
00159                 }
00160 
00161                 return GE_FALSE;
00162         }
00163 }
00164 
00165 
00166 geBoolean PathPt_Startup(geWorld *World, geVFile *Fs)
00167 {
00168         void                            *ClassData;
00169         geEntity_EntitySet      *ClassSet;
00170         geEntity                        *Entity;
00171         PathPoint                       *Point;
00172         
00173         int pointnum=0;
00174         TrackPt *track_pt;
00175 
00176         if      (!World)
00177                 return GE_TRUE;
00178 
00179         PathPt_Reset(World);
00180 
00181         // Look for the class name in the world
00182         ClassSet = geWorld_GetEntitySet(World, "PathPoint");
00183 
00184     if (!ClassSet)
00185         return GE_TRUE;
00186 
00187         Entity = NULL;
00188 
00189         while (1)
00190         {
00191                 Entity = geEntity_EntitySetGetNextEntity(ClassSet, Entity);
00192 
00193                 if (!Entity)
00194                         break;
00195 
00196                 ClassData = geEntity_GetUserData(Entity);
00197                 Point = (PathPoint*)ClassData;
00198 
00199                 assert(Point);
00200 
00201                 // initialize translated position
00202                 Point->Pos = Point->origin;
00203 
00204                 if (Point->PathType <= 0)
00205                         continue;
00206 
00207                 //save off header info
00208                 TrackList[TrackCount].Type = Point->PathType;
00209         pointnum = 0;
00210 
00211                 //move through points setting up the list
00212                 do
00213                 {
00214                         //save off point info
00215                         track_pt = &TrackList[TrackCount].PointList[pointnum];
00216                         // initialize translated position
00217                         Point->Pos = Point->origin;
00218                         track_pt->Pos = &Point->Pos;
00219                         if (Point->WatchPoint)
00220                                 track_pt->WatchPos = &Point->WatchPoint->origin;
00221 
00222                         track_pt->Action = Point->ActionType;
00223                         track_pt->Time = Point->Time;
00224             track_pt->ActionDir = Point->Direction;
00225                         track_pt->Dist = Point->Dist;
00226                         track_pt->VelocityScale = Point->VelocityScale;
00227 
00228                         // automatic setup for doors
00229                         if (TrackList[TrackCount].Type == TRACK_TYPE_TRAVERSE_DOOR)
00230                                 {
00231                                 if (pointnum == 0)
00232                                         {
00233                                         track_pt->ActionDir = 1;
00234                                         track_pt->Action = POINT_TYPE_WAIT_POINT_VISIBLE;
00235                                         track_pt->WatchPos = &Point->Next->origin;
00236                                         }
00237                                 else
00238                                 if (pointnum == 1)
00239                                         {
00240                                         track_pt->ActionDir = -1;
00241                                         track_pt->Action = POINT_TYPE_WAIT_POINT_VISIBLE;
00242                                         track_pt->WatchPos = (track_pt-1)->Pos;
00243                                         }
00244                                 }
00245 
00246                         pointnum++;
00247                         TrackList[TrackCount].PointCount = pointnum;
00248 
00249             assert(pointnum < MAX_TRACK_POINTS);
00250 
00251                         Point = Point->Next;
00252 
00253                         // Found a type
00254                         if (Point && Point->PathType >= 0)
00255                                 {
00256                                 track_pt = &TrackList[TrackCount].PointList[pointnum];
00257                                 SET(track_pt->Flags, BIT(0));
00258                                 }
00259 
00260                 }while(Point && Point != (PathPoint*)ClassData);
00261 
00262                 TrackCount++;
00263                 assert(TrackCount < MAX_TRACKS);
00264         }
00265 
00266         Entity = NULL;
00267 
00268         {
00269                 void Track_LinkTracks(geWorld *World);
00270                 Track_LinkTracks(World);
00271         }
00272 
00273         if (Fs)
00274         {
00275                 if (!PathPoint_SetTexture(World, Fs))
00276                         return GE_FALSE;
00277         }
00278 
00279         return GE_TRUE;
00280 }
00281 
00282 geBoolean PathPt_Shutdown(void)
00283 {
00284         if (PathPointTexture)
00285         {
00286                 // NOTE - We really should remove it from the world, but when the world is destroyed
00287                 // it removes all leftover bitmaps, so we are free to just let that happen...
00288                 geBitmap_Destroy(&PathPointTexture);
00289                 PathPointTexture = NULL;
00290         }
00291 
00292         return GE_TRUE;
00293 }
00294 
00295 geBoolean PathPt_Frame(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime)
00296 {
00297         geEntity_EntitySet *    Set;
00298         geEntity *                              Entity;
00299 
00300         PathPoint *     P;
00301         geVec3d         Pos;
00302         geVec3d Center;
00303         extern geBoolean PathLight;
00304         extern geBoolean MultiPathLight;
00305 
00306         if      (!World)
00307                 return GE_TRUE;
00308  
00309         Set = geWorld_GetEntitySet(World, "PathPoint");
00310 
00311         if      (Set == NULL)
00312                 return GE_TRUE;
00313 
00314         Entity = NULL;
00315 
00316         while   (1)
00317         {
00318                 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00319 
00320                 if (!Entity)
00321                         break;
00322 
00323                 P = geEntity_GetUserData(Entity);
00324 
00325                 if      (P->MoveWithModel)
00326                 {
00327                         geXForm3d       XForm;
00328 
00329                         geWorld_GetModelXForm(World, P->MoveWithModel, &XForm);
00330 
00331                         Pos = P->origin;
00332 
00333                         geWorld_GetModelRotationalCenter(World, P->MoveWithModel, &Center);
00334                         geVec3d_Subtract(&Pos, &Center, &Pos);
00335                         geXForm3d_Transform(&XForm, &Pos, &Pos);
00336                         geVec3d_Add(&Pos, &Center, &P->Pos);
00337                 }
00338         }
00339 
00340         if (XForm)
00341         {
00342                 if (PathLight)
00343                         PathPoint_Frame2(World, XForm, DeltaTime);
00344                 if (MultiPathLight)
00345                         PathPoint_Frame3(World, XForm, DeltaTime);
00346         }
00347 
00348 
00349         return GE_TRUE;
00350 }
00351 
00352 static  geBoolean PathPoint_Frame2(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime)
00353 {
00354         GE_Collision                    Collision;
00355         int                                             i;
00356         geBoolean       Visible;
00357         geFloat         DistanceToCorona;
00358         geVec3d         Delta;
00359 
00360         if      (!World)
00361                 return GE_TRUE;
00362  
00363         // Now walk the track list, drawing lines to connect them all.  Draw red
00364         // lines to things that are being watched.
00365 
00366         for     (i = 0; i < TrackCount; i++)
00367         {
00368                 int             j;
00369                 Track * T;
00370 
00371                 T = &TrackList[i];
00372                 assert(T->PointCount > 0);
00373 
00374                 for     (j = 0; j < T->PointCount; j++)
00375                 {
00376                         GE_LVertex      Vert;
00377                         float Radius;
00378 
00379                         DistanceToCorona = geVec3d_Length(&Delta);
00380 
00381                         if      (!geWorld_Collision(World,
00382                                                                         NULL,
00383                                                                         NULL,
00384                                                                         T->PointList[j].Pos,
00385                                                                         &XForm->Translation,
00386                                                                         GE_CONTENTS_CANNOT_OCCUPY,
00387                                                                         GE_COLLIDE_MODELS,
00388                                                                         0xffffffff, NULL, NULL, 
00389                                                                         &Collision) &&
00390                                  (DistanceToCorona < 2000.0f))//C->MaxVisibleDistance))
00391                                 {
00392                                 Visible = GE_TRUE;
00393                                 }
00394                         else
00395                                 {
00396                                 Visible = GE_FALSE;
00397                                 }
00398 
00399                         
00400                         if (Visible)
00401                                 {
00402                                 Vert.X = T->PointList[j].Pos->X;
00403                                 Vert.Y = T->PointList[j].Pos->Y;
00404                                 Vert.Z = T->PointList[j].Pos->Z;
00405 
00406                                 if (j != 0 && TEST(T->PointList[j].Flags, BIT(0)))
00407                                         {
00408                                         Vert.g = 0.0f;
00409                                         Vert.b = 0.0f;
00410                                         Radius = 5.0f;
00411                                         }
00412                                 else
00413                                         {
00414                                         Vert.g = 255.0f;
00415                                         Vert.b = 255.0f;
00416                                         Radius = 1.0f;
00417                                         }
00418 
00419                                 Vert.r = 255.0f;
00420                                 Vert.a = 255.0f;
00421                                 Vert.u = Vert.v = 0.0f;
00422 
00423                                 geWorld_AddPolyOnce(World,
00424                                                                         &Vert,
00425                                                                         1,
00426                                                                         PathPointTexture,
00427                                                                         GE_TEXTURED_POINT,
00428                                                                         GE_RENDER_DO_NOT_OCCLUDE_OTHERS | GE_RENDER_DO_NOT_OCCLUDE_SELF,
00429                                                                         Radius);
00430                                 }
00431 
00432 
00433                         if (j < T->PointCount - 1)
00434                                 {
00435                                 DrawLine3d(World,
00436                                                    XForm, 
00437                                                    T->PointList[j].Pos,
00438                                                    T->PointList[j + 1].Pos,
00439                                                    255, 255, 255,
00440                                                    0, 255, 0);
00441                                 }
00442 
00443                         if      (T->PointList[j].WatchPos)
00444                                 {
00445                                 DrawLine3d(World,
00446                                                    XForm, 
00447                                                    T->PointList[j].Pos,
00448                                                    T->PointList[j].WatchPos,
00449                                                    255, 255, 255,
00450                                                    255, 0, 0);
00451                                 }
00452                 }
00453         }
00454 
00455         return GE_TRUE;
00456 }
00457 
00458 
00459 static  geBoolean PathPoint_Frame3(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime)
00460 {
00461         int     i,v;
00462 
00463         geVec3d *sp, *ep, *ep2, *sp2;
00464 
00465         if      (!World)
00466                 return GE_TRUE;
00467  
00468         // Now walk the track list, drawing lines to connect them all.  Draw red
00469         // lines to things that are being watched.
00470 
00471         for     (i = 0; i < TrackCount; i++)
00472             {
00473                 Track * T;
00474 
00475                 T = &TrackList[i];
00476                 assert(T->PointCount > 0);
00477 
00478                 sp = T->PointList[0].Pos;
00479                 ep = T->PointList[T->PointCount - 1].Pos;
00480 
00481         for (v = 0; T->Vis[v]; v++)
00482             {
00483                         sp2 = T->Vis[v]->PointList[0].Pos;
00484                         ep2 = T->Vis[v]->PointList[T->Vis[v]->PointCount - 1].Pos;
00485 
00486                         switch(T->VisFlag[v])
00487                                 {
00488                                 case 1:
00489                                         DrawLine3d(World,
00490                                                            XForm, 
00491                                                            sp,
00492                                                            sp2,
00493                                                            255, 255, 255,
00494                                                            0, 0, 255);
00495                                         break;
00496                                 case 2:
00497                                         DrawLine3d(World,
00498                                                            XForm, 
00499                                                            sp,
00500                                                            ep2,
00501                                                            255, 255, 255,
00502                                                            0, 0, 255);
00503                                         break;
00504                                 case 3:
00505                                         DrawLine3d(World,
00506                                                            XForm, 
00507                                                            ep,
00508                                                            ep2,
00509                                                            255, 255, 255,
00510                                                            0, 0, 255);
00511                                         break;
00512                                 case 4:
00513                                         DrawLine3d(World,
00514                                                            XForm, 
00515                                                            ep,
00516                                                            sp2,
00517                                                            255, 255, 255,
00518                                                            0, 0, 255);
00519                                         break;
00520                                 }
00521             }
00522         }
00523 
00524         return GE_TRUE;
00525 }
00526 

Generated on Tue Sep 30 12:36:05 2003 for GTestAndEngine by doxygen 1.3.2