00001
00002 #ifndef OglGui_ViewerPointCloud_h
00003 #define OglGui_ViewerPointCloud_h
00004
00005 #ifndef OglGui_Window_h
00006 #include "OglGui/Window.h"
00007 #endif
00008
00009 #ifndef OglGui_ViewerPoint_h
00010 #include "OglGui/ViewerPoint.h"
00011 #endif
00012
00013 #ifndef OglGui_SetImageInterface_h
00014 #include "OglGui/SetImageInterface.h"
00015 #endif
00016
00017 #ifndef OglGui_GetOglImageByIdInterface_h
00018 #include "OglGui/GetOglImageByIdInterface.h"
00019 #endif
00020
00021 #ifndef OglGui_OglImageCache_h
00022 #include "OglGui/OglImageCache.h"
00023 #endif
00024
00025 namespace OglGui {
00026
00027 class ViewerPointCloud : public Window
00028 {
00029 public:
00030 static const int cMaxPoints = 10000;
00031
00032 ViewerPointCloud(int x, int y, int w, int h) :
00033 Window(x, y, w, h)
00034 {
00035 Init(w,h);
00036 }
00037
00038 ViewerPointCloud(Window* parent, int x, int y, int w, int h) :
00039 Window(parent, x, y, w, h)
00040 {
00041 Init(w,h);
00042 }
00043
00044 void DetailImageInterface(SetImageInterface* si)
00045 {
00046 mDetailImageI = si;
00047 }
00048
00049 void SetOglImageCache(OglImageCache* oglImageCache)
00050 {
00051 mOglImageCache = oglImageCache;
00052 }
00053
00054 void SetGetOglImageByIdInterface(GetOglImageByIdInterface* i)
00055 {
00056 mGetOglImageByIdI = i;
00057 }
00058
00059 OGLIMAGE* LoadViewImage(ViewerPoint* vp)
00060 {
00061 if (!vp || !mGetOglImageByIdI)
00062 return 0;
00063
00064 OGLIMAGE* im = 0;
00065 long long id = vp->GetId();
00066 if (mOglImageCache)
00067 {
00068 im = mOglImageCache->GetImage(id);
00069 im ? mCacheHits++ : mCacheMisses++;
00070 }
00071
00072 if (!im && (im = mGetOglImageByIdI->GetOglImageById(id)))
00073 if (mOglImageCache)
00074 mOglImageCache->Add(im, id);
00075 return im;
00076 }
00077
00078 OGLIMAGE* LoadViewImage(OGLVIEW* oglView)
00079 {
00080 if (!oglView || !(oglView->SysData2 == (void*) ViewerPoint::cMagicNr))
00081 return 0;
00082 ViewerPoint* vp = (ViewerPoint*) oglView->SysData1;
00083 return LoadViewImage(vp);
00084 }
00085
00086 int NrOfPoints() { return mNrOfPoints; }
00087 float PtDocX() { return mPtDocX; }
00088 float PtDocY() { return mPtDocY; }
00089 float MinX() { return mMinX; }
00090 float MinY() { return mMinY; }
00091 float MaxX() { return mMaxX; }
00092 float MaxY() { return mMaxY; }
00093 void MaxVisibleImages(int m) { mMaxVisibleImages = m; }
00094 int MaxVisibleImages() { return mMaxVisibleImages; }
00095 void Scale(float s) { mScale=(s>mMinimumScale) ? s:mMinimumScale;}
00096 float Scale() { return mScale; }
00097 void MinimumScale(float s) { mMinimumScale = s; }
00098 float MinimumScale() { return mMinimumScale; }
00099
00100 void ScaleThreshold(float s) { mShowViewAtScale = s; }
00101 float ScaleThreshold() { return mShowViewAtScale; }
00102
00103 void SetPtDocXY(float x, float y)
00104 {
00105 mPtDocX = x;
00106 mPtDocY = y;
00107 }
00108
00109 void GetMinMax(float& minX, float& minY, float& maxX, float& maxY)
00110 {
00111 minX = mMinX;
00112 minY = mMinY;
00113 maxX = mMaxX;
00114 maxY = mMaxY;
00115 }
00116
00117 void Point2Wnd(float& x, float& y)
00118 {
00119 float hW = W()/2.f, hH = H()/2.f;
00120 x = hW + mScale * (x-hW+mPtDocX);
00121 y = hH + mScale * (y-hH+mPtDocY);
00122 }
00123
00124 void Wnd2Point(float&x, float& y)
00125 {
00126 float hW = W()/2.f, hH = H()/2.f;
00127 x = (x - hW)/mScale + hW - mPtDocX;
00128 y = (y - hH)/mScale + hH - mPtDocY;
00129 }
00130
00131 static LIST *FindViewNodeOnOfTagged(OGLWND *oglWnd, int x, int y,
00132 int onTags, int offTags)
00133 {
00134 LIST *obj;
00135 OGLVIEW *view;
00136
00137 ForAllElementsBackward(obj, oglWnd->lastObject)
00138 {
00139 view = (OGLVIEW *) obj->info;
00140 if (((view->tags & onTags)==onTags) && !(view->tags&offTags))
00141 if( viewSys.PointInView( view, x, y ) )
00142 return obj;
00143 }
00144 return NULL;
00145 }
00146
00147
00148 static OGLVIEW* FindViewOnOfTagged(HOGLWND oglWnd, int x, int y,
00149 int onTags, int offTags)
00150 {
00151 LIST *obj = FindViewNodeOnOfTagged(oglWnd, x, y, onTags, offTags);
00152 return obj ? (OGLVIEW*) obj->info : NULL;
00153 }
00154
00155 void BorderColorTagged(int tags, bool isSet, ULONG col)
00156 {
00157 LIST *obj, *objList = mOglWnd->objectList;
00158 ForAllElements(obj, objList)
00159 {
00160 OGLVIEW* view = (OGLVIEW*) obj->info;
00161 bool hasTags = (view->tags & tags) == tags;
00162
00163 if ((isSet && hasTags) || (!isSet && !hasTags))
00164 view->borderCol = col;
00165 }
00166 }
00167
00168 void TagBorderColor(ULONG col, int tag, bool mode)
00169 {
00170 LIST *obj, *objList = mOglWnd->objectList;
00171 ForAllElements(obj, objList)
00172 {
00173 OGLVIEW* view = (OGLVIEW*) obj->info;
00174 if (view->borderCol == col)
00175 viewSys.SetTagsTo(view, tag, mode);
00176 }
00177 }
00178
00179 void TagBorderColorOnOff(ULONG col, int onTag, int offTag)
00180 {
00181 LIST *obj, *objList = mOglWnd->objectList;
00182 ForAllElements(obj, objList)
00183 {
00184 OGLVIEW* view = (OGLVIEW*) obj->info;
00185 if (view->borderCol == col)
00186 {
00187 viewSys.SetTagsTo(view, onTag, true);
00188 viewSys.SetTagsTo(view, offTag, false);
00189 }
00190 }
00191 }
00192
00193 void HandleDragging()
00194 {
00195 float w = W();
00196 float h = H();
00197 float hW = W()/2.f, hH = H()/2.f;
00198 float offX = hW - mPtDocX;
00199 float offY = hH - mPtDocY;
00200
00201 LIST *obj, *objList = mOglWnd->objectList;
00202 ForAllElements(obj, objList)
00203 {
00204 OGLVIEW* view = (OGLVIEW*) obj->info;
00205 if (!(view->SysData2 == (void*)ViewerPoint::cMagicNr))
00206 continue;
00207 ViewerPoint* vp = (ViewerPoint*) view->SysData1;
00208
00209 if (view->tags & selectedTag)
00210 vp->PointXY((view->x + view->w/2.f - hW)/mScale + offX,
00211 (view->y + view->h/2.f - hH)/mScale + offY);
00212 }
00213 }
00214
00215 void HandleMouseOver(int x, int y)
00216 {
00217 OGLVIEW* view = FindViewOnOfTagged(mOglWnd, x, y, 0, ignoreTag);
00218 OGLIMAGE* im = viewSys.GetImage(view);
00219 if (!im)
00220 im = LoadViewImage(view);
00221 mDetailImageI->SetImage(im);
00222 ReleaseOglImage(im);
00223 }
00224
00225
00226
00227 void DrawPointsEx(float trX, float trY, float offX, float offY,
00228 float ptSize, float scaleX, float scaleY,
00229 int wndW, int wndH)
00230 {
00231 LIST *obj, *objList = mOglWnd->objectList;
00232 ULONG selCol = mOglWnd->selectCol;
00233
00234 glPushMatrix();
00235 ptSize = (ptSize < 1.f) ? 1.f : ptSize;
00236 glPointSize(ptSize);
00237 glTranslatef(trX, trY, 0.f);
00238 glScalef(scaleX, scaleY, 1.f);
00239
00240 glBegin(GL_POINTS);
00241 ForAllElements(obj, objList)
00242 {
00243 OGLVIEW* view = (OGLVIEW*) obj->info;
00244 if ((view->tags & ignoreTag) ||
00245 !(view->SysData2 == (void*)ViewerPoint::cMagicNr))
00246 continue;
00247 bool selected = (view->tags & selectedTag) != 0;
00248 ViewerPoint* vp = (ViewerPoint*) view->SysData1;
00249 float x = vp->PointX() + offX;
00250 float y = vp->PointY() + offY;
00251 ULONG borderCol = view->borderCol;
00252 SetColor(selected ? selCol : borderCol);
00253 glVertex2f(x, y);
00254 if (selected && ptSize >= 3.f)
00255 {
00256 glEnd();
00257 glPointSize(ptSize-2);
00258 glBegin(GL_POINTS);
00259 UCHAR r, g, b;
00260 COLOR2RGB(borderCol, r, g, b);
00261 glColor3ub(r, g, b);
00262 glVertex2f(x, y);
00263 glEnd();
00264 glPointSize(ptSize);
00265 glBegin(GL_POINTS);
00266 }
00267 }
00268 glEnd();
00269 glPopMatrix();
00270 }
00271
00272 void
00273 DrawAsPoints(float trX, float trY, float offX, float offY, float ptSize)
00274 {
00275 ULONG selCol = mOglWnd->selectCol;
00276 int wndW = W(), wndH = H();
00277 float hW = wndW/2.f, hH = wndH/2.f;
00278 int vW = (mScale > 1.f) ? mScale : 1;
00279 int vH = (mScale > 1.f) ? mScale : 1;
00280 float hVW = vW/2.f, hVH = vH/2.f;
00281 float minHWPlusPtDocX = -hW+mPtDocX;
00282 float minHHPlusPtDocY = -hH+mPtDocY;
00283
00284 mMinX = mMinY = 1000000;
00285 mMaxX = mMaxY = -1000000;
00286 mNrOfPoints = 0;
00287 glPushMatrix();
00288 ptSize = (ptSize < 1.f) ? 1.f : ptSize;
00289 glPointSize(ptSize);
00290 glTranslatef(trX, trY, 0.f);
00291 glScalef(mScale, mScale, 1.f);
00292
00293 glBegin(GL_POINTS);
00294 LIST *obj, *objList = mOglWnd->objectList;
00295 ForAllElements(obj, objList)
00296 {
00297 OGLVIEW* view = (OGLVIEW*) obj->info;
00298 if (!(view->SysData2 == (void*) ViewerPoint::cMagicNr))
00299 continue;
00300 ViewerPoint* vp = (ViewerPoint*) view->SysData1;
00301 mNrOfPoints++;
00302 view->tags &= ~visibleTag;
00303 if (view->tags & ignoreTag)
00304 continue;
00305 if (mAnimation && mStarted)
00306 vp->AnimatePoint();
00307 if (mOglImageCache)
00308 viewSys.SetImage(view,0);
00309 float x = vp->PointX(), y = vp->PointY();
00310 float wndX = hW + mScale * (x+minHWPlusPtDocX);
00311 float wndY = hH + mScale * (y+minHHPlusPtDocY);
00312 view->w = vW;
00313 view->h = vH;
00314 int vX = view->x = wndX - hVW;
00315 int vY = view->y = wndY - hVH;
00316
00317 if (x<mMinX) mMinX = x;
00318 if (x>mMaxX) mMaxX = x;
00319 if (y<mMinY) mMinY = y;
00320 if (y>mMaxY) mMaxY = y;
00321
00322 if (vX+vW<0 || vY+vH<0 || vX > wndW || vY > wndH)
00323 continue;
00324
00325 bool selected = (view->tags & selectedTag) != 0;
00326 ULONG borderCol = view->borderCol;
00327 SetColor(selected ? selCol : borderCol);
00328
00329 glVertex2f(x+offX, y+offY);
00330 if (selected && ptSize >= 3.f)
00331 {
00332 glEnd();
00333 glPointSize(ptSize-2);
00334 glBegin(GL_POINTS);
00335 UCHAR r, g, b;
00336 COLOR2RGB(borderCol, r, g, b);
00337 glColor3ub(r, g, b);
00338 glVertex2f(x+offX, y+offY);
00339 glEnd();
00340 glPointSize(ptSize);
00341 glBegin(GL_POINTS);
00342 }
00343 }
00344 glEnd();
00345 glPopMatrix();
00346 }
00347
00348 void HandleViewDisplay(int w, int h)
00349 {
00350 float hW = w/2.f, hH = h/2.f;
00351 float minHWPlusPtDocX = -hW+mPtDocX;
00352 float minHHPlusPtDocY = -hH+mPtDocY;
00353 int nrVisible = 0;
00354
00355 mMinX = mMinY = 1000000;
00356 mMaxX = mMaxY = -1000000;
00357 mNrOfPoints = 0;
00358 LIST *obj, *objList = mOglWnd->objectList;
00359 ForAllElements(obj, objList)
00360 {
00361 OGLVIEW* view = (OGLVIEW*) obj->info;
00362 if (!(view->SysData2 == (void*) ViewerPoint::cMagicNr))
00363 continue;
00364 ViewerPoint* vp = (ViewerPoint*) view->SysData1;
00365 mNrOfPoints++;
00366 if (view->tags & ignoreTag)
00367 continue;
00368 if (mAnimation && mStarted)
00369 vp->AnimatePoint();
00370
00371 float x = vp->PointX(), y = vp->PointY();
00372 float wndX = hW + mScale * (x+minHWPlusPtDocX);
00373 float wndY = hH + mScale * (y+minHHPlusPtDocY);
00374 int zW = mScale;
00375 if(view->im && view->im->w && view->im->h)
00376 zW *= view->im->w/(float)view->im->h;
00377 int vW = view->w = zW;
00378 int vH = view->h = mScale;
00379 int vX = view->x = wndX - vW/2.f;
00380 int vY = view->y = wndY - vH/2.f;
00381
00382 if (x<mMinX) mMinX = x;
00383 if (x>mMaxX) mMaxX = x;
00384 if (y<mMinY) mMinY = y;
00385 if (y>mMaxY) mMaxY = y;
00386
00387 if (vX+vW > 0 && vX < w && vY+vH > 0 && vY < h)
00388 {
00389 view->tags |= visibleTag;
00390 if (++nrVisible > mMaxVisibleImages && mOglImageCache)
00391 {
00392 viewSys.SetImage(view, 0);
00393 continue;
00394 }
00395 if (view->im || (view->im = LoadViewImage(vp)))
00396 {
00397 view->zoomX = vW / (float) view->im->w;
00398 view->zoomY = vH / (float) view->im->h;
00399 }
00400 }
00401 else
00402 {
00403 view->tags &= ~visibleTag;
00404 if (view->im && mOglImageCache)
00405 viewSys.SetImage(view,0);
00406 }
00407 }
00408 }
00409
00410
00411 void HandleMouseMoveOnDisplay()
00412 {
00413 if (mMouseMsg==oglMouseMove && !mMouseState)
00414 if (mAllMouseMotion && mDetailImageI)
00415 HandleMouseOver(mMouseX, mMouseY);
00416
00417 trickFindInvisibleView = 1;
00418 Window::MouseFunc(mMouseMsg, mMouseBtn, mMouseState, mMouseX, mMouseY);
00419 trickFindInvisibleView = 0;
00420 mMouseMoveOnDisplay = false;
00421 if (mOglWnd->dragging)
00422 HandleDragging();
00423 }
00424
00425 virtual void DisplayFunc()
00426 {
00427 OGC myOGC;
00428 ULONG ptColor = oglRED;
00429 int w = mOglWnd->width;
00430 int h = mOglWnd->height;
00431
00432 if (mMouseMoveOnDisplay)
00433 HandleMouseMoveOnDisplay();
00434
00435 OGCSave(&myOGC);
00436
00437 if (mScale < mShowViewAtScale)
00438 DrawAsPoints(w/2.f, h/2.f, mPtDocX-w/2.f, mPtDocY-h/2.f, mScale);
00439 else
00440 HandleViewDisplay(w, h);
00441 Window::DisplayFunc();
00442
00443 SetSolidLineColor(0xff00ffff);
00444 DrawLine(w/2-8, h/2, w/2+9, h/2);
00445 DrawLine(w/2, h/2-8, w/2, h/2+9);
00446 OGCRestore(&myOGC);
00447 }
00448
00449 virtual void ReshapeFunc(int w, int h)
00450 {
00451 float diffX = mPtDocX - (mOldW/2.f);
00452 float diffY = mPtDocY - (mOldH/2.f);
00453
00454 mPtDocX = diffX + w/2.f;
00455 mPtDocY = diffY + h/2.f;
00456 mOldW = w;
00457 mOldH = h;
00458 }
00459
00460 void HandleWindowMouse(int msg, int btn, int state, int x, int y)
00461 {
00462 if (msg != oglMouseMove)
00463 {
00464 trickFindInvisibleView = 1;
00465 Window::MouseFunc(msg, btn, state, x, y);
00466 trickFindInvisibleView = 0;
00467 }
00468 else
00469 {
00470 mMouseMoveOnDisplay = true;
00471 mMouseMsg = msg;
00472 mMouseBtn = btn;
00473 mMouseState = state;
00474 mMouseX = x;
00475 mMouseY = y;
00476 }
00477 }
00478
00479 virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00480 {
00481 static bool isDragging = false;
00482 static float markX, markY, markDocX, markDocY;
00483 static int lastX;
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 if (msg == oglMouseWheelUp)
00532 Scale(mScale * (1.1f));
00533 if (msg == oglMouseWheelDown)
00534 Scale(mScale * (0.9f));
00535
00536 if (msg == oglMouseDown && btn == oglRightButton)
00537 {
00538 isDragging = true;
00539 markDocX = mPtDocX;
00540 markDocY = mPtDocY;
00541 markX = x;
00542 markY = y;
00543 }
00544 if (msg == oglMouseMove && isDragging)
00545 {
00546 if (state & oglShift)
00547 Scale(mScale * (1.f+((x - lastX)/50.f)));
00548 else
00549 {
00550 mPtDocX = markDocX + (x - markX)/mScale;
00551 mPtDocY = markDocY + (y - markY)/mScale;
00552 }
00553 }
00554 if (msg == oglMouseUp)
00555 isDragging = false;
00556
00557 HandleWindowMouse(msg, btn, state, x, y);
00558 lastX = x;
00559 }
00560
00561 virtual void KeyboardFunc(int c, int state)
00562 {
00563 if (c == 's')
00564 oglSys.SetAlwaysDraw(mOglWnd, mStarted = !mStarted);
00565 if (c == 'M')
00566 oglSys.SetAllMouseMotion(mOglWnd, mAllMouseMotion=!mAllMouseMotion);
00567 if (c == 'a')
00568 mAnimation = !mAnimation;
00569 if (c == 'c')
00570 printf("Hits %d Misses %d\n", mCacheHits, mCacheMisses);
00571 Window::KeyboardFunc(c, state);
00572 }
00573
00574 private:
00575
00576 void Init(int w, int h)
00577 {
00578
00579 mDetailImageI = 0;
00580 mOglImageCache = 0;
00581 mGetOglImageByIdI = 0;
00582 mCacheHits = mCacheMisses = 0;
00583
00584 mOldW = w;
00585 mOldH = h;
00586 mPtDocX = w/2;
00587 mPtDocY = h/2;
00588 mScale = 1.f;
00589 mMinX = mMinY = 1000000;
00590 mMaxX = mMaxY = -1000000;
00591 mMaxVisibleImages = 200;
00592
00593 mMinimumScale = 0.25f;
00594 mShowViewAtScale = 16;
00595
00596 mStarted = false;
00597 mAnimation = true;
00598
00599 mMouseMoveOnDisplay = false;
00600 mAllMouseMotion = true;
00601 oglSys.SetAllMouseMotion(mOglWnd, mAllMouseMotion);
00602 oglSys.AllowPicking(mOglWnd, 1, 1);
00603 oglSys.AllowDeleteView(mOglWnd, 1);
00604 }
00605
00606 ULONG mColors[8];
00607
00608 bool mStarted;
00609 bool mAnimation;
00610
00611 bool mAllMouseMotion;
00612
00613 bool mMouseMoveOnDisplay;
00614
00615 int mNrOfPoints;
00616 int mMaxVisibleImages;
00617 int mMouseMsg, mMouseBtn, mMouseState, mMouseX, mMouseY;
00618
00619 int mOldW, mOldH;
00620
00621 float mPtDocX, mPtDocY;
00622
00623 float mMinX, mMaxX;
00624 float mMinY, mMaxY;
00625
00626 float mScale;
00627 float mMinimumScale;
00628 float mShowViewAtScale;
00629
00630 int mCacheHits, mCacheMisses;
00631
00632 SetImageInterface* mDetailImageI;
00633 OglImageCache* mOglImageCache;
00634 GetOglImageByIdInterface* mGetOglImageByIdI;
00635 };
00636
00637 }
00638 #endif