00001 #ifndef Impala_Visualization_VideoMinimap_h
00002 #define Impala_Visualization_VideoMinimap_h
00003
00004 #include "OglGui/Window.h"
00005 #include "Basis/ILog.h"
00006 #include "Core/Array/Arrays.h"
00007 #include "Visualization/MapFunction.h"
00008 #include "Core/Trec/Thread.h"
00009 #include "Core/Trec/ThreadSet.h"
00010 #include "Visualization/RotorBrowser/RotorBrowserContext.h"
00011 #include "OglGui/WindowView2D.h"
00012
00013 namespace Impala {
00014 namespace Visualization {
00015
00016
00017
00018
00019
00020 typedef struct
00021 {
00022 int x;
00023 int y;
00024 int count;
00025 } MapCoordPos;
00026
00027 typedef struct
00028 {
00029 int shot;
00030 double decay;
00031 } ShotTrailPoint;
00032
00033 class ShotTrail
00034 {
00035 public:
00036 typedef Core::Array::Element::Vec3Int32 Vec3Int32;
00037 typedef Core::Trec::Thread Thread;
00038
00039 ShotTrail(std::string name, int maxlength, Vec3Int32 color, double decay=0.0)
00040 {
00041 mMaxLength = maxlength;
00042 mDecay = decay;
00043 mBaseColor = color;
00044 mName = name;
00045 }
00046
00047 void Push(int shot)
00048 {
00049 double d = 1.0;
00050 ShotTrailPoint p;
00051 p.shot = shot;
00052 p.decay = d;
00053
00054 mShots.insert(mShots.begin(), p);
00055 int ctr=0;
00056 for (std::vector<ShotTrailPoint>::iterator i = mShots.begin(); i!=mShots.end(); i++)
00057 {
00058 if (ctr>0 && (*i).shot == shot)
00059 {
00060 i=mShots.erase(i);
00061 i--;
00062 }
00063 (*i).decay = d;
00064 d -= mDecay;
00065 ctr++;
00066 if (d <= 0.0 || ctr > mMaxLength)
00067 {
00068 mShots.erase(i, mShots.end());
00069 break;
00070 }
00071 }
00072 }
00073
00074 void
00075 Clear()
00076 {
00077 mShots.clear();
00078 }
00079
00080
00081
00082
00083
00084
00085 void
00086 AddThread(Thread *t, int length)
00087 {
00088 for (int i=length-1;i>=0;i--)
00089 {
00090 int shot = t->GetShot(i);
00091 if (shot == -1)
00092 continue;
00093 Push(shot);
00094 }
00095 }
00096
00097 void
00098 AddThread(Thread *t, int position, int direction, int length)
00099 {
00100 for (int i=length-1; i>=0;i--)
00101 {
00102 int shot = t->GetShotAt(position, direction * i);
00103 if (shot == -1)
00104 continue;
00105 Push(shot);
00106 }
00107 }
00108
00109 void
00110 AddBrowserContext(RotorBrowser::RotorBrowserContext *c, int length, bool bidirectional=false)
00111 {
00112 if (bidirectional)
00113 length = length / 2;
00114
00115 for (int i=length-1; i>=0; i--)
00116 {
00117 int shot = c->GetRelative(i);
00118 if (shot == -1)
00119 continue;
00120 Push(shot);
00121 if (bidirectional)
00122 {
00123 shot = c->GetRelative(-i);
00124 if (shot == -1)
00125 continue;
00126 Push(shot);
00127 }
00128 }
00129 }
00130
00131 std::string
00132 GetName()
00133 {
00134 return mName;
00135 }
00136
00137 int
00138 GetLength()
00139 {
00140 return mShots.size();
00141 }
00142
00143 int
00144 GetShot(int p)
00145 {
00146 return mShots[p].shot;
00147 }
00148
00149
00150 Vec3Int32
00151 GetColor(int p)
00152 {
00153 return DecayColor(mShots[p].decay);
00154 }
00155
00156 private:
00157
00158 Vec3Int32 DecayColor(double dval)
00159 {
00160 return Vec3Int32(
00161 mBaseColor.X() * dval,
00162 mBaseColor.Y() * dval,
00163 mBaseColor.Z() * dval);
00164 }
00165
00166 std::vector<ShotTrailPoint> mShots;
00167 int mMaxLength;
00168 double mDecay;
00169 Vec3Int32 mBaseColor;
00170 std::string mName;
00171 };
00172
00173 class VideoMinimap : public OglGui::Window
00174 {
00175 public:
00176 typedef Core::Array::Array2dVec3UInt8 Array2dVec3UInt8;
00177 typedef Core::Array::Element::Vec3Int32 Vec3Int32;
00178
00179 VideoMinimap(MapFunction *map, OglGui::Window *parent, int width, int height) :
00180 OglGui::Window(parent, width, height, true)
00181 {
00182 Init(map, width, height, parent);
00183 }
00184
00185 VideoMinimap(MapFunction *map, OglGui::Window *parent, int x, int y, int width, int height) :
00186 OglGui::Window(parent, x, y, width, height, true)
00187 {
00188 Init(map, width, height, parent);
00189 }
00190
00191 virtual void
00192 DisplayFunc()
00193 {
00194 static int counter = 1;
00195 static int color = 1;
00196 int w = mOglWnd->width;
00197 int h = mOglWnd->height;
00198 viewSys.SetDimensions(mView, 0, 0, w, h);
00199
00200 if (mView->im)
00201 viewSys.SetZoom(mView, w / (float) mView->im->w,
00202 h / (float) mView->im->h);
00203
00204 DrawMinimap();
00205
00206 Window::DisplayFunc();
00207 }
00208
00209 virtual void MouseFunc(int msg, int but, int state, int x, int y)
00210 {
00211 if (but == 1)
00212 {
00213 ShowPreviewWindow();
00214
00215 y = mOglWnd->height - y;
00216 x = mMapFunction->GetWidth() * x / mOglWnd->width;
00217 y = mMapFunction->GetHeight() * y / mOglWnd->height;
00218 ILOG_USER("Mouse previewing shot " << x <<"," << y <<" == " << mMapFunction->XYToShot(x,y));
00219
00220 UpdatePreviewWindow(mMapFunction->XYToShot(x,y));
00221 }
00222 if (but == 0)
00223 {
00224 HidePreviewWindow();
00225 }
00226 }
00227
00228
00229 void
00230 RegisterTrail(ShotTrail *trail)
00231 {
00232 mTrails.push_back(trail);
00233 }
00234
00235 void
00236 DrawMinimap()
00237 {
00238 Blank();
00239 for (int i=0; i<mTrails.size(); i++)
00240 {
00241 DrawTrail(mTrails[i]);
00242 }
00243 mOglIm->changed = 1;
00244 }
00245
00246 void
00247 DrawTrail(ShotTrail *trail)
00248 {
00249 for (int i=0; i<trail->GetLength();i++)
00250 {
00251 SetPoint(trail->GetShot(i), trail->GetColor(i));
00252 }
00253 }
00254
00255
00256
00257 Vec3Int32 GetPoint(int shot)
00258 {
00259 MapCoordPos p = mCoordMap[shot];
00260 Array2dVec3UInt8* ar =(Array2dVec3UInt8*)mOglIm->imageHandle;
00261 return ar->Value(p.x,p.y);
00262 }
00263 inline void
00264 SetPoint(int shot, Vec3Int32 color)
00265 {
00266 MapCoordPos p = mCoordMap[shot];
00267 Vec3Int32 ccolor = GetPoint(shot);
00268
00269
00270 SetPoint(p.x, p.y, color);
00271
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281 inline void
00282 SetPoint(int x, int y, Vec3Int32 color)
00283 {
00284 if (!mOglIm)
00285 return;
00286 Array2dVec3UInt8* ar =(Array2dVec3UInt8*)mOglIm->imageHandle;
00287
00288 Vec3Int32 ccol = ar->Value(x,y);
00289
00290 ar->SetValue(MergeCol(ccol,color), x, y);
00291 }
00292
00293 inline Vec3Int32 MergeCol(Vec3Int32 ca, Vec3Int32 cb)
00294 {
00295 int r,g,b;
00296 if (ca.X() > cb.X()) r = ca.X(); else r = cb.X();
00297 if (ca.Y() > cb.Y()) g = ca.Y(); else g = cb.Y();
00298 if (ca.Z() > cb.Z()) b = ca.Z(); else b = cb.Z();
00299 return Vec3Int32(r,g,b);
00300 }
00301
00302 void
00303 Blank()
00304 {
00305 if (!mOglIm)
00306 return;
00307 Array2dVec3UInt8* ar =(Array2dVec3UInt8*)mOglIm->imageHandle;
00308 for (int x=0;x<mOglIm->w;x++)
00309 for (int y=0;y<mOglIm->h;y++)
00310 ar->SetValue(Vec3Int32(20,20,20), x, y);
00311 }
00312
00313 void
00314 EnablePreviewWindow(Core::Trec::ThreadSet *t)
00315 {
00316 mThreadSet = t;
00317 InitPreviewWindow();
00318 HidePreviewWindow();
00319 }
00320
00321 void
00322 ShowPreviewWindow()
00323 {
00324 mPreviewWindow->SetVisible(true);
00325 }
00326
00327 void
00328 HidePreviewWindow()
00329 {
00330 mPreviewWindow->SetVisible(false);
00331 }
00332
00333 protected:
00334
00335 OGLIMAGE*
00336 InitOGLIMAGE(int imW, int imH)
00337 {
00338 mOglIm = oglSys.OglImage(GL_RGB, imW, imH);
00339 mOglIm->imDataFunc = MyOglImdataFunc;
00340 mOglIm->onDestroy = MyOglImdataDestroyFunc;
00341 Array2dVec3UInt8* ar =
00342 Core::Array::ArrayCreate<Array2dVec3UInt8>(imW, imH, 0, 0);
00343 mOglIm->imageHandle = ar;
00344 return mOglIm;
00345 }
00346
00347 OGLIMAGE*
00348 CreateImageForShotID(int shotID)
00349 {
00350 OGLIMAGE *im;
00351 Array2dVec3UInt8* ar =
00352
00353 mThreadSet->GetImageByShotID(shotID);
00354 im = oglSys.OglImage(GL_RGB, ar->CW(), ar->CH());
00355 im->imDataFunc = MyOglImdataFunc;
00356 im->onDestroy = MyOglImdataDestroyFunc;
00357 im->imageHandle = ar;
00358 return im;
00359 }
00360
00361 void
00362 DoUpdateDispImage(OGLIMAGE* oglIm)
00363 {
00364 oglIm->changed = 1;
00365 }
00366
00367 static void*
00368 MyOglImdataFunc(OGLIMAGE* oglIm)
00369 {
00370
00371 Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00372
00373
00374 oglIm->w = ar->CW();
00375 oglIm->h = ar->CH();
00376 oglIm->changed = 0;
00377 return (void *) ar->CPB(0, 0);
00378 }
00379
00380 static void
00381 MyOglImdataDestroyFunc(OGLIMAGE* oglIm)
00382 {
00383 if (!oglIm)
00384 return;
00385 Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00386 if (ar)
00387 delete ar;
00388 }
00389
00390
00391 private:
00392
00393 void
00394 UpdatePreviewWindow(int shot)
00395 {
00396 if (shot >= 0) {
00397 OGLIMAGE *i = CreateImageForShotID(shot);
00398 mPreviewWindow->SetImage(i);
00399 oglSys.ReleaseOglImage(i);
00400 }
00401 }
00402
00403 void
00404 InitPreviewWindow()
00405 {
00406 if (mPreviewWindow)
00407 return;
00408
00409
00410 mPreviewWindow = new OglGui::WindowView2D(mParentWindow,
00411 mParentWindow->W() - 420,
00412 mParentWindow->H() - 220,
00413 200,200,0);
00414 }
00415
00416 void
00417 Init(MapFunction *map, int screenwidth, int screenheight, Window *parent)
00418 {
00419
00420 ILOG_DEBUG("initializing map...");
00421
00422 mMapFunction = map;
00423
00424 int width = map->GetWidth();
00425 int height = map->GetHeight();
00426
00427
00428 Core::Array::Array2dScalarInt32* counts =
00429 Core::Array::ArrayCreate<Core::Array::Array2dScalarInt32>(width, height, 0, 0);
00430
00431 int x, y;
00432
00433
00434 for (x=0;x<width;x++)
00435 for (y=0;y<height;y++)
00436
00437 counts->SetValue(0, x, y);
00438
00439
00440 for (int i = 0; i < map->GetNrShots(); i++)
00441 {
00442 map->ShotToXY(i, &x, &y);
00443
00444 counts->SetValue(counts->Val(x, y) + 1, x, y);
00445 MapCoordPos p;
00446 p.x = x;
00447 p.y = y;
00448 p.count = 0;
00449 mCoordMap[i] = p;
00450 }
00451
00452
00453 for (int i = 0; i < map->GetNrShots(); i++)
00454 {
00455
00456 mCoordMap[i].count = counts->Val(mCoordMap[i].x, mCoordMap[i].y);
00457 }
00458 ILOG_DEBUG("map initialized.");
00459
00460
00461
00462 InitOGLIMAGE(width, height);
00463
00464 mView = viewSys.View2D(mOglWnd, mOglIm, 0, 0, screenwidth, screenheight);
00465 viewSys.SetTags(mView, visibleTag);
00466
00467 mParentWindow = parent;
00468 mPreviewWindow = 0;
00469 mThreadSet = 0;
00470
00471 Blank();
00472 }
00473
00474
00475
00476 std::map <int, MapCoordPos> mCoordMap;
00477 std::vector<ShotTrail*> mTrails;
00478 MapFunction *mMapFunction;
00479
00480
00481 OGLIMAGE *mOglIm;
00482 OGLVIEW *mView;
00483
00484 Window *mParentWindow;
00485
00486 OglGui::WindowView2D* mPreviewWindow;
00487
00488
00489 Core::Trec::ThreadSet *mThreadSet;
00490
00491 ILOG_VAR_DEC;
00492 };
00493
00494 ILOG_VAR_INIT(VideoMinimap, Visualization);
00495
00496
00497 }
00498 }
00499
00500 #endif