Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

VideoMinimap.h

Go to the documentation of this file.
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 //using Core::Array::Array2dVec3UInt8;
00017 //using Core::Array::Element::Vec3Int32;
00018 //using Core::Trec::Thread;
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     /* TODO: AddThread code: counts from end of list back to zero, so that
00081        Push will properly assign decay values.
00082        This isn't terribly efficient and can be done better by doing
00083        decay calculations here too.
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     // convenience functions
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     // internal marking functions:
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         // incorrect, but doable for now:
00269         //int c = p.count;
00270         SetPoint(p.x, p.y, color);
00271         //if (c == 1)
00272         //else
00273         //{
00274         //    SetPoint(p.x, p.y, Vec3Int32(
00275         //        (ccolor.X() * (c-1) + color.X()) / 256,
00276         //        (ccolor.Y() * (c-1) + color.Y()) / 256,
00277         //        (ccolor.Z() * (c-1) + color.Z()) / 256));
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 //            Core::Array::ArrayCreate<Array2dVec3UInt8>(100, 100, 0, 0);
00353             mThreadSet->GetImageByShotID(shotID); //-- TODO
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         // Obtain our 'im' stored as 'imageHandle'
00371         Array2dVec3UInt8* ar = (Array2dVec3UInt8 *) oglIm->imageHandle;
00372 
00373         // Set oglIm dimensions to our 'im' dimensions
00374         oglIm->w = ar->CW();
00375         oglIm->h = ar->CH();
00376         oglIm->changed = 0;
00377         return (void *) ar->CPB(0, 0); // Pointer to the image pixels
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         // TODO: hack, hard coded coords, fix later!
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         // init shot to minimap table:
00420         ILOG_DEBUG("initializing map...");
00421 
00422         mMapFunction = map;
00423 
00424         int width = map->GetWidth();
00425         int height = map->GetHeight();
00426 
00427         //int counts[width][height];
00428         Core::Array::Array2dScalarInt32* counts =
00429             Core::Array::ArrayCreate<Core::Array::Array2dScalarInt32>(width, height, 0, 0);
00430 
00431         int x, y;
00432 
00433         // clear counters:
00434         for (x=0;x<width;x++)
00435             for (y=0;y<height;y++)
00436                 //counts[x][y] = 0;
00437                 counts->SetValue(0, x, y);
00438 
00439         // map shot -> x,y and count nr of shots per x,y pos
00440         for (int i = 0; i < map->GetNrShots(); i++)
00441         {
00442             map->ShotToXY(i, &x, &y);
00443             //counts[x][y] = counts[x][y] + 1;
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         // update map so that every shot knows how many other shots share x,y
00453         for (int i = 0; i < map->GetNrShots(); i++)
00454         {
00455             //mCoordMap[i].count = counts[mCoordMap[i].x][mCoordMap[i].y];
00456             mCoordMap[i].count = counts->Val(mCoordMap[i].x, mCoordMap[i].y);
00457         }
00458         ILOG_DEBUG("map initialized.");
00459 
00460 
00461         // init visualization:
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     // map:
00476     std::map <int, MapCoordPos> mCoordMap;
00477     std::vector<ShotTrail*> mTrails;
00478     MapFunction *mMapFunction;
00479 
00480     // visualization:
00481     OGLIMAGE *mOglIm;
00482     OGLVIEW *mView;
00483 
00484     Window *mParentWindow;
00485 
00486     OglGui::WindowView2D*   mPreviewWindow;
00487 
00488     // hack to get images for showing in preview window:
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

Generated on Fri Mar 19 09:31:55 2010 for ImpalaSrc by  doxygen 1.5.1