00001
00002
00003
00004 #define WIN32_LEAN_AND_MEAN
00005 #include <windows.h>
00006
00007
00008
00009
00010
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
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
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
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
00202 Point->Pos = Point->origin;
00203
00204 if (Point->PathType <= 0)
00205 continue;
00206
00207
00208 TrackList[TrackCount].Type = Point->PathType;
00209 pointnum = 0;
00210
00211
00212 do
00213 {
00214
00215 track_pt = &TrackList[TrackCount].PointList[pointnum];
00216
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
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
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
00287
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
00364
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))
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
00469
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