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

Carousel3D.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 // Author: Richard van Balen
00003 #ifndef OglGui_Carousel3D_h
00004 #define OglGui_Carousel3D_h
00005 
00006 #include <vector>
00007 
00008 /*
00009 #ifndef OglGui_time_included
00010 #include <time.h>
00011 #define OglGui_time_included
00012 #endif
00013 */
00014 
00015 #ifndef OglGui_Carousel3DListener_h
00016 #include "OglGui/Carousel3DListener.h"
00017 #endif
00018 
00019 #ifndef OglGui_ChangingToView_h
00020 #include "OglGui/ChangingToView.h"
00021 #endif
00022 
00023 namespace OglGui {
00024 
00025 class Carousel3D :  public Window,
00026                     public ChangingToViewListener
00027 {
00028 public:
00029     Carousel3D(int x, int y, int w, int h) :
00030         Window(x, y, w, h, false)
00031     {
00032         Init(w,h);
00033     }
00034 
00035     Carousel3D(Window* parent, int x, int y, int w, int h) :
00036         Window(parent, x, y, w, h, false)
00037     {
00038         Init(w,h);
00039     }
00040 
00041     void SetCarousel3DListener(Carousel3DListener* l, void *userData)
00042     {
00043         mListener = l;
00044         mListenerData = userData;
00045     }
00046 
00047     virtual void OnChangingToViewDestiny(ChangingToView* v, void *userData)
00048     {
00049         int idx = (int)(long long) userData;
00050         if (mListener)
00051             mListener->OnChangingToViewDestination(this, idx, mListenerData);
00052     }
00053 
00054     float   CenterX()                       { return mCenterX; }
00055     float   CenterY()                       { return mCenterY; }
00056     float   CenterZ()                       { return mCenterZ; }
00057     float   Radius()                        { return mRadius; }
00058 
00059     void    Friction(double f)              { mFriction = f; }
00060     double  Friction()                      { return mFriction; }
00061 
00062     OGLVIEW3D* AddView(strconst str)
00063     {
00064         OGLVIEW3D* v = view3DSys.View3D(mOglWnd, 0, 0, 0, 0, 1, 1, 1);
00065         if (v)
00066         {
00067             //view3DSys.SetTags(v, FlexViewTags);
00068             mOglViews.push_back(v);
00069             mTitles.push_back(str);
00070         }
00071         return v;
00072     }
00073 
00074     void
00075     AddCaptureView(strconst str, int x, int y, int w, int h, bool capture=true)
00076     {
00077         OGLVIEW3D* v = AddView(str);
00078         view3DSys.SetRotation(v, 180, 0, 0);
00079         view3DSys.SetTexFilter(v, 0, GL_LINEAR);
00080         view3DSys.SetTexFilter(v, 1, GL_LINEAR);
00081         OGLIMAGE* oglIm = MyOglImage(4, 10, 10);
00082         oglIm->noTexScaling = 1;
00083         v->im = oglIm;
00084 
00085         ChangingToView* chToView = new ChangingToView(v);
00086         int idx = mTitles.size()-1;
00087         chToView->SetChangingToViewListener(this, (void *) idx);
00088         mChangingToViews.push_back(chToView);
00089 
00090         if (capture)
00091             OglImCapture(v->im, x, y, w, h);
00092     }
00093 
00094     ChangingToView* ChToView(int idx)
00095     {
00096         if (idx < 0 || idx >= mChangingToViews.size())
00097             return 0;
00098         return mChangingToViews[idx];
00099     }
00100 
00101     int IndexOf(strconst str)
00102     {
00103         for (int i=0; i<mTitles.size(); i++)
00104         {
00105             if (str == mTitles[i])
00106                 return i;
00107         }
00108         return -1;
00109     }
00110 
00111     int IndexOf(OGLVIEW3D* v)
00112     {
00113         for (int i=0; i<mOglViews.size(); i++)
00114         {
00115             if (v == mOglViews[i])
00116                 return i;
00117         }
00118         return -1;
00119     }
00120 
00121     void TitledCapture(strconst str, int x, int y, int w, int h)
00122     {
00123         int idx = IndexOf(str);
00124         if (idx == -1)
00125             AddCaptureView(str, x, y, w, h);
00126         else
00127         {
00128             OglImCapture(mOglViews[idx]->im, x, y, w, h);
00129             CheckOglImageChanged(mOglViews[idx]->im);
00130             for (int i=0; i<mOglViews.size(); i++)
00131             {
00132                 OGLVIEW3D*  oglV3D  = mOglViews[i];
00133                 OGLIMAGE*   im      = oglV3D->im; 
00134                 oglV3D->w = (w/(float)h);
00135                 oglV3D->h = 1;
00136                 float tW = im->noTexScaling ? im->texW : im->w;
00137                 float tH = im->noTexScaling ? im->texH : im->h;
00138                 float zX = (oglV3D->w)*(tW/im->w);
00139                 float zY = (oglV3D->h)*(tH/im->h);
00140                 view3DSys.SetZoom(oglV3D,zX,zY);
00141             }
00142         }
00143     }
00144 
00145     void Clamp360(float& f)
00146     {
00147         while (f < 0)
00148             f += 360;
00149         while (f - 360 > 0)
00150             f -= 360;
00151     }
00152 
00153     void RotateTo(float deg, int ms=500)
00154     {
00155         Clamp360(mCenterRotY);
00156         Clamp360(deg);
00157 
00158         float diff    = deg - mCenterRotY;
00159         float absDiff = fabs(diff);
00160 
00161         if ((mCenterRotY == deg) || absDiff <= 0.2 || absDiff >= 359.8)
00162         {
00163             mCenterRotY     = deg;
00164             mIsRotatingTo   = false;
00165             return;
00166         }
00167         if (absDiff > 180)
00168             deg += (diff > 0 ? -360 : 360);
00169 
00170         mRotateTo           = deg;
00171         mRotateToStart      = mCenterRotY;
00172         //mRotateToDuration   = ms;
00173         mRotateToDuration   = ms/1000.0;
00174         //mRotateToStartTime  = clock();
00175         mRotateToStartTime  = OglClock();
00176         mIsRotatingTo       = true;
00177     }
00178 
00179     void RotateToSpike(int idx, int ms=500)
00180     {
00181         float spikes  = 360.f / mOglViews.size();
00182         RotateTo(-idx * spikes, ms);
00183         UpdateScene();
00184     }
00185 
00186     void RotateToNearest(int ms=500)
00187     {
00188         Clamp360(mCenterRotY);
00189         int     nrOfViews = mOglViews.size();
00190         float   spikes    = 360.f / nrOfViews;
00191         float   n         = floor(0.5f + mCenterRotY / spikes);
00192         int     s         = abs(n-nrOfViews);
00193         RotateToSpike(s);
00194     }
00195 
00196     void HandleRotateTo()
00197     {
00198         if (!mIsRotatingTo)
00199             return;
00200 
00201         //float timePassed = clock() - mRotateToStartTime;
00202         double timePassed = OglClock() - mRotateToStartTime;
00203         if (timePassed > mRotateToDuration)
00204         {
00205             mCenterRotY   = mRotateTo;
00206             mIsRotatingTo = false;
00207             return;
00208         }
00209         double factor = timePassed/mRotateToDuration;
00210         mCenterRotY  = mRotateToStart + factor * (mRotateTo-mRotateToStart);
00211         UpdateScene();
00212     }
00213 
00214         virtual void DisplayFunc()
00215         {
00216         if (!mShowCarousel)
00217             return;
00218 
00219         OGC myOGC;
00220         OGCSave(&myOGC);
00221 
00222                 view3DSys.View3DCameraTransform(mOglWnd);
00223 
00224         int nrOfViews = mOglViews.size();
00225 
00226         mRadius  = (nrOfViews*mOglViews[0]->w) / OGL_PI_2;
00227         mCenterZ = -mRadius - 1.5;
00228                 glTranslatef(mCenterX, mCenterY, mCenterZ);
00229                 glRotatef(mCenterRotY, 0.0f, 1.0f, 0.0f);       // Rotate Y
00230 
00231                 for (int i=0; i<nrOfViews; i++)
00232                 {
00233                         glPushMatrix();
00234                         glRotatef( i * 360.f/nrOfViews, 0.0f, 1.0f, 0.0f );
00235             glTranslatef(0, 0, mRadius);
00236                     view3DSys.DrawView(mOglViews[i]);
00237                         glColor3f( 1.0f, 1.0f, 0.0f );
00238                         oglSys.Printf3D(mTxtFontBase, -0.5, 0.5, 0.1, 0.08, 0.08, 0.01,
00239                             "%s", mTitles[i].c_str());
00240                         glPopMatrix();
00241                 }
00242         OGCRestore( &myOGC );
00243         glLoadName(0);
00244 
00245         HandleRotateTo();
00246 
00247 //SetAlwaysDraw(mFlowing || mIsRotatingTo);
00248         if (!mFlowing)
00249             return;
00250 
00251         //float   t    = (clock() - mFlowDragStartTime)/1000.f;
00252         float   t    = (OglClock() - mFlowDragStartTime);
00253         float   endT = fabs(mFlowSpeed / mFriction);
00254         if (t >= endT)
00255         {
00256             t = endT;
00257             mFlowing = false;
00258             //SetAlwaysDraw(mFlowing = false);
00259             UpdateScene();
00260             RotateToNearest();
00261         }
00262         float d = mFlowSpeed*t + (0.5 * (mFlowSpeed>0?1:-1)*mFriction * (t*t));
00263         mCenterRotY = mFlowStartRotY + d;
00264         }
00265 
00266     virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00267     {
00268         Window::MouseFunc(msg, btn, state, x, y);
00269 
00270         if (msg == oglMouseDown && btn == oglLeftButton)
00271         {
00272             if (mDragged = ((mFlowing||mIsRotatingTo) ? true : false))
00273                 SetAlwaysDraw(mFlowing = mIsRotatingTo = false);
00274             //mFlowDragStartTime  = clock();
00275             mFlowDragStartTime  = OglClock();
00276             mDragStarted        = true;
00277             mFlowDragDiff       = 0;
00278             mFlowDragStartX     = x;
00279             mFlowDragLastX      = x;
00280             mFlowStartRotY      = mCenterRotY;
00281         }
00282         if (msg == oglMouseMove && mDragStarted)
00283         {
00284             mFlowDragDiff  = mFlowDragLastX - x;
00285             mCenterRotY   -= mFlowDragDiff / 10.f;
00286             mFlowDragLastX = x;
00287             if (fabs(mFlowStartRotY - mCenterRotY) > mDragPixThreshold)
00288                 mDragged = true;
00289         }
00290         if (msg == oglMouseUp && btn == oglLeftButton)
00291         {
00292             OGLVIEW3D*    v;
00293             if (!mDragged && mListener && (v = view3DSys.FindView(mOglWnd,x,y)))
00294                 mListener->OnCarousel3D(this, IndexOf(v), mListenerData);
00295             if (mDragged)
00296             {
00297                 //double t = (clock() - mFlowDragStartTime) / (CLOCKS_PER_SEC*1.);
00298                 double t = (OglClock() - mFlowDragStartTime);
00299                 if (t<0.1) t = 0.1;
00300                 mFlowSpeed = ((x-mFlowDragStartX)/10.f) / t;
00301                 if (abs(mFlowDragDiff) < 5)
00302                     mFlowSpeed = 0;
00303                 SetAlwaysDraw(mFlowing = (fabs(mFlowSpeed) > 30));
00304                 mFlowStartRotY     = mCenterRotY;
00305                 //mFlowDragStartTime = clock();
00306                 mFlowDragStartTime = OglClock();
00307             }
00308             mDragStarted = mDragged = false;
00309         }
00310     }
00311 
00312     virtual void InitFunc()
00313         {
00314                 OGLWND* oglWnd = oglSys.GetTopOGLWND( mOglWnd );
00315         void*   font;
00316 
00317 #ifdef OGL_USING_GLUT
00318                 mTxtFontBase = oglSys.Create3DFont( mOglWnd, font, 1, 0.6f, NULL );
00319 #else
00320                 font = (void*) CreateFont(
00321                         -12, 0, 0, 0, FW_NORMAL, 0, 0, 0,
00322                         ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
00323                         ANTIALIASED_QUALITY, VARIABLE_PITCH | FF_DONTCARE, "Verdana" );
00324                 // Transform MsWindows fonts to OpenGL fontBases
00325                 mTxtFontBase = oglSys.Create3DFont( mOglWnd, font, 1, 0.6f, NULL );
00326                 // MsWindows font no longer needed
00327                 DeleteObject( (HFONT) font );
00328 #endif
00329                 Window::InitFunc();
00330         }
00331 
00332 protected:
00333 
00334     void ReadPixels(OGLIMAGE* oglIm, int x, int y, int w, int h)
00335     {
00336         if (oglIm->imData)
00337             free(oglIm->imData);
00338 
00339             // Allocate memory for a 4 byte RGBA buffer
00340             if( !(oglIm->imData = (void *) malloc(w * h * 4))){
00341                     oglSys.ErrorBox("Error", "Could not allocate image memory");
00342                     exit( 0 );;
00343             }
00344         oglIm->w = w;
00345         oglIm->h = h;
00346 
00347             // Specification of our image alignment
00348             glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Contineous pixels
00349             glPixelStorei(GL_UNPACK_ROW_LENGTH, w); // Width of 1 line in our buffer
00350             glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00351             glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00352 
00353             glReadPixels( x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, oglIm->imData );
00354 
00355         glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
00356         glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
00357         glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
00358         oglIm->changed = 1;
00359     }
00360 
00361     void OglImCapture(OGLIMAGE* oglIm, int x, int y, int w, int h)
00362     {
00363         if (!oglIm)
00364             return;
00365         ReadPixels(oglIm, x, y, w, h);
00366     }
00367 
00368     OGLIMAGE* MyOglImage(int type, int w, int h)
00369     {
00370         OGLIMAGE* oglIm   = NewOglImage(type, w, h);
00371         oglIm->imData     = calloc(w*h,4);
00372         memset(oglIm->imData, 0x80, w*h*4);
00373         oglIm->imDataFunc = MyOglImDataFunc;
00374         oglIm->onDestroy  = MyOglImDestroy;
00375         return oglIm;
00376     }
00377 
00378 private:
00379     static void *MyOglImDataFunc(OGLIMAGE *oglIm)
00380     {
00381         return (void *) oglIm ? oglIm->imData : 0;
00382     }
00383 
00384     static void MyOglImDestroy(OGLIMAGE *oglIm)
00385     {
00386         if (!oglIm)
00387             return;
00388         if(oglIm->imData)
00389             free(oglIm->imData);
00390         oglIm->imData = 0;
00391     }
00392 
00393     void Init(int w, int h)
00394     {
00395 //SetBackground(oglTrRED);
00396         SetBorderFillShaded(-2);
00397         oglSys.SetAllowCameraMove(mOglWnd, CamMove_Mouse);
00398         oglSys.AllowPicking(mOglWnd, false, false);
00399         Friction(-150);
00400 
00401         mTargetOGLWND       = oglSys.GetTopOGLWND(mOglWnd);
00402         mShowCarousel       = true;
00403         mDragStarted        = false;
00404         mDragged            = false;
00405         mFlowing            = false;
00406         mIsRotatingTo       = false;
00407         mRotateToDuration   = 0;
00408         mDragPixThreshold   = 3;
00409         mCenterX            = 0;
00410         mCenterY            = 0;
00411         mCenterZ            = -4.5;
00412         mCenterRotY         = 0;
00413     }
00414 
00415     Carousel3DListener*             mListener;
00416     void*                           mListenerData;
00417 
00418     std::vector<OGLVIEW3D*>         mOglViews;
00419     std::vector<ChangingToView*>    mChangingToViews;
00420     std::vector<std::string>        mTitles;
00421 
00422     OGLWND*                         mTargetOGLWND;
00423     bool                            mShowCarousel;
00424     int                             mDragLastX;
00425     int                             mDragPixThreshold;
00426     int                             mTxtFontBase;
00427 
00428     //clock_t                         mRotateToStartTime;
00429     double                          mRotateToStartTime;
00430     bool                            mIsRotatingTo;
00431     //int                             mRotateToDuration;
00432     double                          mRotateToDuration;
00433     float                           mRotateToStart;
00434     float                           mRotateTo;
00435     float                           mCenterRotY;
00436     float                           mCenterX;
00437     float                           mCenterY;
00438     float                           mCenterZ;
00439     float                           mRadius;
00440 
00441     //clock_t                         mFlowDragStartTime;
00442     double                          mFlowDragStartTime;
00443     double                          mFlowSpeed;
00444     double                          mFriction;
00445     int                             mFlowDragDiff;
00446     int                             mFlowDragStartX;
00447     int                             mFlowDragLastX;
00448     int                             mFlowStartRotY;
00449     bool                            mDragStarted;
00450     bool                            mDragged;
00451     bool                            mFlowing;
00452 };
00453 
00454 } // namespace OglGui
00455 #endif

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