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 if (msg == oglMouseWheelUp)
00486 {
00487
00488
00489
00490
00491 float xd = (x / (float)W()) - 0.5f;
00492 float yd = (y / (float)H()) - 0.5f;
00493 float x = mPtDocX / W()-0.5f;
00494 float y = mPtDocY / H()-0.5f;
00495 x -= xd/mScale;
00496 y -= yd/mScale;
00497 int jumpX=mPtDocX, jumpY=mPtDocY;
00498 mPtDocX = (int)((x+0.5f) * W());
00499 mPtDocY = (int)((y+0.5f) * H());
00500 jumpX -= mPtDocX;
00501 jumpY -= mPtDocY;
00502 Scale(mScale * (1.1f));
00503 jumpX = (float)jumpX / 1.1f;
00504 jumpY = (float)jumpY / 1.1f;
00505 mPtDocX += jumpX;
00506 mPtDocY += jumpY;
00507 }
00508 if (msg == oglMouseWheelDown)
00509 {
00510 float xd = (x / (float)W()) - 0.5f;
00511 float yd = (y / (float)H()) - 0.5f;
00512 float x = mPtDocX / W()-0.5f;
00513 float y = mPtDocY / H()-0.5f;
00514 x -= xd/mScale;
00515 y -= yd/mScale;
00516 int jumpX=mPtDocX, jumpY=mPtDocY;
00517 mPtDocX = (int)((x+0.5f) * W());
00518 mPtDocY = (int)((y+0.5f) * H());
00519 jumpX -= mPtDocX;
00520 jumpY -= mPtDocY;
00521 Scale(mScale * (0.9f));
00522 jumpX = (float)jumpX / 0.9f;
00523 jumpY = (float)jumpY / 0.9f;
00524 mPtDocX += jumpX;
00525 mPtDocY += jumpY;
00526 }
00527
00528 if (msg == oglMouseDown && btn == oglRightButton)
00529 {
00530 isDragging = true;
00531 markDocX = mPtDocX;
00532 markDocY = mPtDocY;
00533 markX = x;
00534 markY = y;
00535 }
00536 if (msg == oglMouseMove && isDragging)
00537 {
00538 if (state & oglShift)
00539 Scale(mScale * (1.f+((x - lastX)/50.f)));
00540 else
00541 {
00542 mPtDocX = markDocX + (x - markX)/mScale;
00543 mPtDocY = markDocY + (y - markY)/mScale;
00544 }
00545 }
00546 if (msg == oglMouseUp)
00547 isDragging = false;
00548
00549 HandleWindowMouse(msg, btn, state, x, y);
00550 lastX = x;
00551 }
00552
00553 virtual void KeyboardFunc(int c, int state)
00554 {
00555 if (c == 's')
00556 oglSys.SetAlwaysDraw(mOglWnd, mStarted = !mStarted);
00557 if (c == 'M')
00558 oglSys.SetAllMouseMotion(mOglWnd, mAllMouseMotion=!mAllMouseMotion);
00559 if (c == 'a')
00560 mAnimation = !mAnimation;
00561 if (c == 'c')
00562 printf("Hits %d Misses %d\n", mCacheHits, mCacheMisses);
00563 Window::KeyboardFunc(c, state);
00564 }
00565
00566 private:
00567
00568 void Init(int w, int h)
00569 {
00570
00571 mDetailImageI = 0;
00572 mOglImageCache = 0;
00573 mGetOglImageByIdI = 0;
00574 mCacheHits = mCacheMisses = 0;
00575
00576 mOldW = w;
00577 mOldH = h;
00578 mPtDocX = w/2;
00579 mPtDocY = h/2;
00580 mScale = 1.f;
00581 mMinX = mMinY = 1000000;
00582 mMaxX = mMaxY = -1000000;
00583 mMaxVisibleImages = 200;
00584
00585 mMinimumScale = 0.25f;
00586 mShowViewAtScale = 16;
00587
00588 mStarted = false;
00589 mAnimation = true;
00590
00591 mMouseMoveOnDisplay = false;
00592 mAllMouseMotion = true;
00593 oglSys.SetAllMouseMotion(mOglWnd, mAllMouseMotion);
00594 oglSys.AllowPicking(mOglWnd, 1, 1);
00595 oglSys.AllowDeleteView(mOglWnd, 1);
00596 }
00597
00598 ULONG mColors[8];
00599
00600 bool mStarted;
00601 bool mAnimation;
00602
00603 bool mAllMouseMotion;
00604
00605 bool mMouseMoveOnDisplay;
00606
00607 int mNrOfPoints;
00608 int mMaxVisibleImages;
00609 int mMouseMsg, mMouseBtn, mMouseState, mMouseX, mMouseY;
00610
00611 int mOldW, mOldH;
00612
00613 float mPtDocX, mPtDocY;
00614
00615 float mMinX, mMaxX;
00616 float mMinY, mMaxY;
00617
00618 float mScale;
00619 float mMinimumScale;
00620 float mShowViewAtScale;
00621
00622 int mCacheHits, mCacheMisses;
00623
00624 SetImageInterface* mDetailImageI;
00625 OglImageCache* mOglImageCache;
00626 GetOglImageByIdInterface* mGetOglImageByIdI;
00627 };
00628
00629 }
00630 #endif