00001
00002
00003
00004
00005
00006 #ifndef OglGui_ViewSphere_h
00007 #define OglGui_ViewSphere_h
00008
00009 #ifndef OglGui_Window_h
00010 #include "OglGui/Window.h"
00011 #endif
00012
00013 #define MyFabs(f) ((f<0)?(-f):(f))
00014 #define SPHERE_TAG (1<<24)
00015 #define NCOL 10
00016 #define NROW 24
00017
00018 namespace OglGui
00019 {
00020
00022 static char *viewSpherekeyCmd[] = {
00023 "", "",
00024 "i", "show/hide this information",
00025 "?", "show/hide 3D viewer keys",
00026 "", "",
00027 "F9", "Object shape 0 (ownerdrawn)",
00028 "F1..F8", "Object shape 1 .. 8",
00029 "", "",
00030 "E/e", "Increase/Decrease ring Extrusion",
00031 "R/r", "Increase/Decrease sphere Radius",
00032 "", "",
00033 "f", "Toggle Fill with central viewer",
00034 "F", "Toggle Fixed/Polar view dimensions",
00035 "=", "Toggle Double/Single Ring",
00036 "v", "Toggle vertical/horizontal ring",
00037 "t", "Toggle Text",
00038 "", "",
00039 "9", "Rotate Sphere 90 deg over Z-axis",
00040 "", "",
00041 "A", "Animate swirling viewers",
00042 "Ctrl A/a", "Increase/Decrease Animation steps",
00043 "C", "Row change",
00044 "c", "Column change",
00045 "S/s", "Increase/Decrease rotate ring speed",
00046 "a", "Toggle Auto rotate ring",
00047 "ScrollWheel", "Rotate ring",
00048 "", "",
00049 "#", "Pauze/Continue",
00050 "CTRL x,y,z / X,Y,Z", "Decrease/Increase Spheres X/Y/Z rotation speed",
00051 "ESC", "Reset Sphere Rotation",
00052 "@KEY", "@ACTION",
00053 NULL, NULL
00054 };
00055
00056
00057 class ViewSphere : public Window
00058 {
00059 public:
00060
00061 ViewSphere(int x, int y, int w, int h) :
00062 Window(x, y, w, h, false)
00063 {
00064 Init();
00065 InitSphere();
00066 }
00067
00068 ViewSphere(Window *parent, int w, int h) :
00069 Window(parent, w, h, false)
00070 {
00071 Init();
00072 InitSphere();
00073 }
00074
00075 ViewSphere(Window *parent, int x, int y, int w, int h) :
00076 Window(parent, x, y, w, h, false)
00077 {
00078 Init();
00079 InitSphere();
00080 }
00081
00082 void
00083 InitSphere()
00084 {
00085 int i, j;
00086 OGLVIEW3D *oglView;
00087
00088 for( i=0; i<7; i++ )
00089 {
00090 char buf[100];
00091
00092 sprintf(buf, "Im_%d.png", i+1 );
00093 if( !(oglIm[i] = TryReadPNG( buf )) )
00094 printf("Reading mock-up image %s failed\n", buf);
00095 }
00096
00097 for( i=0; i<NCOL; i++ )
00098 for( j=0; j<NROW; j++ )
00099 {
00100 oglView = view3DSys.View3D( mOglWnd, oglIm[(i+j)%7], 0,0,0, 1.96f,1.4f,1 );
00101 oglSys.ReleaseOglImage(oglIm[(i+j)%7]);
00102
00103
00104 view3DSys.SetZoom( oglView, 1.76f, 1.2f );
00105 view3DSys.SetTags( oglView, FlexViewTags | SPHERE_TAG );
00106 view3DSys.SetBgColor( oglView, oglWHITE );
00107
00108 view3DSys.SetObject3D( oglView, 0 );
00109
00110
00111
00112 }
00113
00114 SetBackground( oglWHITE );
00115
00116
00117
00118
00119 centralView = view3DSys.View3D( mOglWnd, oglIm[0], 0,0,-20,
00120 2 * mRadius - 0.3f, 2 * mRadius - 0.3f,1.0f );
00121 centralView->drawMode = OGL_FILL;
00122 centralView->object3D = OGL_SPHERE;
00123 centralView->drawColor = 0x80c0f0c0;
00124 view3DSys.SetTags( centralView, visibleTag|selectableTag|sizableTag );
00125
00126 oglSys.SetAllowCameraMove( mOglWnd, 1 );
00127 oglSys.AllowPicking( mOglWnd, 1, 1 );
00128 oglSys.SetAlwaysDraw( mOglWnd, 1 );
00129 }
00130
00131 void InitAnimation()
00132 {
00133 LIST *obj;
00134 OGLVIEW3D *view;
00135 int i = 0;
00136
00137 mAnimCnt = mAnimSteps;
00138 ForAllElements( obj, mOglWnd->objectList ){
00139 view = (OGLVIEW3D *) obj->info;
00140 view->x -= i * 0.1f;
00141 view->y -= i * 0.1f;
00142 i++;
00143 }
00144 }
00145
00146 virtual void InitFunc()
00147 {
00148 OGLWND* oglWnd = oglSys.GetTopOGLWND( mOglWnd );
00149 void* font = 0;
00150
00151
00152 #if defined(Q_OS_WIN) || (!defined(OGL_USING_GLUT) && !defined(OGL_USING_QT))
00153 font = (void*) CreateFont(
00154 -12, 0, 0, 0, FW_NORMAL, 0, 0, 0,
00155 ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
00156 ANTIALIASED_QUALITY, VARIABLE_PITCH | FF_DONTCARE, (LPCTSTR) "Verdana" );
00157 #endif
00158
00159 txtFontBase = oglSys.Create3DFont( mOglWnd, font, 1, 0.6f, NULL );
00160
00161 #if defined(Q_OS_WIN) || (!defined(OGL_USING_GLUT) && !defined(OGL_USING_QT))
00162
00163 DeleteObject( (HFONT) font );
00164 #endif
00165 Window::InitFunc();
00166
00167 InitAnimation();
00168 sphereInfoBox = oglSys.InfoBoxStrArr( oglWnd, &viewSpherekeyCmd[0], 2, 20, 0x0080ff, oglRED, oglWHITE );
00169 }
00170
00171 virtual void
00172 ExitFunc()
00173 {
00174 oglSys.InfoBoxDestroy( sphereInfoBox );
00175
00176 }
00177
00178 virtual void
00179 KeyboardFunc( INT c, INT state )
00180 {
00181 INT shiftDown = state & oglShift;
00182 FLOAT add = shiftDown ? 0.01f : -0.01f;
00183
00184 if( c=='c' ){
00185 mVertRingNr += 1;
00186 if( mVertRingNr == NCOL )
00187 mVertRingNr = 0;
00188 }
00189 else if( c=='C' ){
00190 mHorRingNr += 1;
00191 if( mHorRingNr == NROW )
00192 mHorRingNr = 0;
00193 }
00194 else if (c=='s' || c=='S')
00195 mRotRingDelta += (c=='S') ? 0.05f : -0.05f;
00196 else if( c == 'R' || c == 'r' )
00197 mRadius += (c=='R') ? 0.2f : -0.2f;
00198 else if( !(c==oglCTRL('x')) && !(c==oglCTRL('y')) && !(c==oglCTRL('z')) )
00199 Window::KeyboardFunc( c, state );
00200
00201 if( c == 'i' )
00202 mKeyInfo = !mKeyInfo;
00203
00204 if (c==oglCTRL('s'))
00205 mSphereRotDx = mSphereRotDy = mSphereRotDz = 0.0f;
00206
00207 if( c == oglESC ) {
00208 mSphereRotDx = mSphereRotDy = mSphereRotDz = 0.0f;
00209 mSphereRotX = mSphereRotY = mSphereRotZ = 0.0f;
00210 }
00211
00212 if( c == oglFUNC(9) )
00213 c = oglFUNC(0);
00214 if( c >= oglFUNC(0) && c <= oglFUNC(8) )
00215 view3DSys.Object3DTagged( mOglWnd, visibleTag, 1, c - oglFUNC(0) );
00216
00217
00218
00219 if( c == oglCTRL('x') && (mSphereRotDx += add) ) oglSys.SetAlwaysDraw( mOglWnd, 1 );
00220 if( c == oglCTRL('y') && (mSphereRotDy += add) ) oglSys.SetAlwaysDraw( mOglWnd, 1 );
00221 if( c == oglCTRL('z') && (mSphereRotDz += add) ) oglSys.SetAlwaysDraw( mOglWnd, 1 );
00222
00223 if( c == '#' )
00224 oglSys.SetAlwaysDraw( mOglWnd, !oglSys.GetAlwaysDraw(mOglWnd) );
00225
00226 if( c == 'e' || c == 'E' )
00227 mStdStickOut += (c == 'E') ? 0.05f : -0.05f;
00228 if( c == '9' )
00229 mSphereRotZ += 90;
00230 if( c == 'f' )
00231 mShowCentralView = !mShowCentralView;
00232
00233 if( c == 'F' && !(mAdjustViewDims = !mAdjustViewDims) )
00234 view3DSys.SizeTagged( mOglWnd, SPHERE_TAG, 1, 1.96f, 1.4f, 1.f, 0 );
00235
00236 if( c == 't' )
00237 mShowText = !mShowText;
00238 if( c == 'v' )
00239 mStdVertRing = !mStdVertRing;
00240 if( c == '=' )
00241 mDblRing = !mDblRing;
00242
00243
00244 if( c == 'a' && (mAutoRotateRing = !mAutoRotateRing) )
00245 oglSys.SetAlwaysDraw( mOglWnd, 1 );
00246
00247
00248 if( c == 'A' && !mAnimCnt )
00249 InitAnimation();
00250 if( c == oglCTRL('a') ){
00251 mAnimSteps += (state & oglShift) ? 50 : -50;
00252 if( mAnimSteps < 100 ) mAnimSteps = 100;
00253 }
00254
00255 oglSys.UpdateSceneFlag( mOglWnd, 1 );
00256 }
00257
00258
00259 void
00260 DoViewTransRot( OGLVIEW3D *view )
00261 {
00262 glTranslatef( view->x, view->y, view->z );
00263
00264
00265 glRotatef( view->xRot, 1.0f, 0.0f, 0.0f );
00266 glRotatef( view->yRot, 0.0f, 1.0f, 0.0f );
00267 glRotatef( view->zRot, 0.0f, 0.0f, 1.0f );
00268 }
00269
00270 void
00271 HandleAnimation()
00272 {
00273 LIST *obj;
00274 OGLVIEW3D *view;
00275 int cnt = 0;
00276
00277 if( mAnimCnt && (mAnimCnt-- >= 0) ){
00278 ForAllElements( obj, mOglWnd->objectList ){
00279 view = (OGLVIEW3D *) obj->info;
00280 view->x += (cnt*0.1f) / mAnimSteps;
00281 view->y += (cnt*0.1f) / mAnimSteps;
00282 view->zRot += (720.0f / mAnimSteps);
00283 view->xRot += (720.0f / mAnimSteps);
00284 view->yRot += (720.0f / mAnimSteps);
00285 cnt++;
00286 }
00287 }
00288 }
00289
00290 virtual void
00291 DisplayFunc()
00292 {
00293 SCENE3D *scene3D;
00294 LIST *obj;
00295 OGLVIEW3D *view;
00296 OGC myOGC;
00297 int i, j;
00298 float angle, rad, stickOut;
00299 float hW, hH;
00300
00301 if( (scene3D = (SCENE3D *) mOglWnd->sceneInfo) ){
00302 if (scene3D->isLighting)
00303 glEnable(GL_LIGHTING);
00304 }
00305
00306 OGCSave( &myOGC );
00307 HandleAnimation();
00308
00309 view3DSys.View3DCameraTransform( mOglWnd );
00310
00311 glTranslatef( mSphereX, mSphereY, mSphereZ );
00312 glRotatef( mSphereRotX, 1.0f, 0.0f, 0.0f );
00313 glRotatef( mSphereRotY, 0.0f, 1.0f, 0.0f );
00314 glRotatef( mSphereRotZ, 0.0f, 0.0f, 1.0f );
00315 obj = mOglWnd->objectList;
00316 for( i=0; i<NCOL; i++)
00317 {
00318 glPushMatrix();
00319 glRotatef( i * 180/NCOL, 0.0f, 1.0f, 0.0f );
00320
00321 for( j=0; j<NROW; j++)
00322 {
00323 angle = stickOut = 0.f;
00324 view = (OGLVIEW3D *) obj->info;
00325
00326
00327 if( (i%NCOL) && (j==NROW/4 || j==3*NROW/4) ){
00328 obj = obj->next;
00329 continue;
00330 }
00331
00332 glPushMatrix();
00333
00334 if( (mDblRing || mStdVertRing) && i==mVertRingNr )
00335 {
00336 glRotatef( mRotRingAngle, 1.0f, 0.0f, 0.0f );
00337 stickOut = mStdStickOut + (mDblRing ? 0.2f : 0.0f );
00338 angle += mRotRingAngle;
00339 }
00340 else if( (mDblRing || !mStdVertRing) && (j==mHorRingNr ||
00341 (j == ((mHorRingNr<=NROW/2) ? NROW/2-mHorRingNr : NROW + (NROW/2-mHorRingNr))) ) )
00342 {
00343 glRotatef( mRotRingAngle, 0.0f, 1.0f, 0.0f );
00344 stickOut = mStdStickOut;
00345 }
00346
00347
00348 rad = mRadius + stickOut;
00349 angle += (j*360/NROW);
00350 glRotatef( j * 360/NROW, 1.0f, 0.0f, 0.0f );
00351 glTranslatef( 0.0f, 0.0f, -rad);
00352
00353 hH = (OGL_PI * rad) / NROW;
00354 hW = (OGL_PI * (rad*MyFabs(cos(DEG2RAD(angle))))) / (2 * NCOL);
00355 if( mAdjustViewDims )
00356 view3DSys.SetDimensions(view, FRETAIN, FRETAIN, FRETAIN, 2*hW, 2*hH, FRETAIN);
00357
00358 view3DSys.DrawView( (OGLVIEW3D *) obj->info );
00359
00360 DoViewTransRot( view );
00361
00362
00363 if( !view->object3D )
00364 {
00365 float hW0, hW1;
00366 hW0 = (float) (OGL_PI_05 * rad*MyFabs(cos(DEG2RAD(angle - 90.0/NCOL )))) / NCOL;
00367 hW1 = (float) (OGL_PI_05 * rad*MyFabs(cos(DEG2RAD(angle + 90.0/NCOL )))) / NCOL;
00368 glColor3f( 1.0f, 1.0f, 1.0f );
00369 glEnable( GL_TEXTURE_2D );
00370 #ifndef OGL_USING_GLUT
00371 glNormal3f( 0.f, 0.f, 1.f );
00372 #else
00373 glNormal3f( 0.f, 0.f, -1.f );
00374 #endif
00375 glBegin( GL_QUADS );
00376 glTexCoord2f(0.f, 1.f); glVertex3f( hW1, hH, -0.01f );
00377 glTexCoord2f(1.f, 1.f); glVertex3f( -hW1, hH, -0.01f );
00378 glTexCoord2f(1.f, 0.f); glVertex3f( -hW0, -hH, -0.01f );
00379 glTexCoord2f(0.f, 0.f); glVertex3f( hW0, -hH, -0.01f );
00380
00381 glEnd();
00382 glDisable( GL_TEXTURE_2D );
00383 }
00384
00385
00386
00387 if( mShowText ){
00388 char buf[100];
00389 sprintf( buf, "%d,%d", i, j );
00390 glPushMatrix();
00391 glRotatef( 180.0f, 1.0f, 0.0f, 0.0f );
00392 glColor3f( 1.0f, 1.0f, 0.0f );
00393 float oldLineWidth = GetLineWidth();
00394 SetLineWidth(2.0f);
00395 oglSys.Printf3D( txtFontBase, -0.25f, 0.0f, 0.1f, 0.4f, 0.4f, 0.2f, buf );
00396 SetLineWidth(oldLineWidth);
00397 glPopMatrix();
00398 }
00399 obj = obj->next;
00400 glPopMatrix();
00401 }
00402 glPopMatrix();
00403 }
00404 glLoadName(0);
00405
00406 if( mShowCentralView )
00407 {
00408 view3DSys.View3DCameraTransform( mOglWnd );
00409 view3DSys.DrawView( centralView );
00410 }
00411
00412
00413 if( mSphereRotating ){
00414
00415 mSphereRotX += mSphereRotDx;
00416 mSphereRotY += mSphereRotDy;
00417 mSphereRotZ += mSphereRotDz;
00418 }
00419 if ( mAutoRotateRing )
00420 mRotRingAngle += mRotRingDelta;
00421
00422 {
00423 SCENE3D *scene3D = (SCENE3D *) mOglWnd->sceneInfo;
00424 if( scene3D->showKeys ){
00425 oglSys.InfoBoxCenter( mOglWnd, view3DKeyInfoBox );
00426 oglSys.InfoBoxDraw( mOglWnd, view3DKeyInfoBox );
00427 }
00428 }
00429
00430 if( !mOglWnd->hitDetecting && mKeyInfo ){
00431 oglSys.InfoBoxCenter( mOglWnd, sphereInfoBox );
00432 oglSys.InfoBoxDraw( mOglWnd, sphereInfoBox );
00433 }
00434 OGCRestore( &myOGC );
00435 glDisable(GL_LIGHTING);
00436 }
00437
00438 virtual void
00439 MouseFunc( int msg, int but, int state, int x, int y )
00440 {
00441 if( msg == oglMouseWheelUp || msg == oglMouseWheelDown )
00442 {
00443 mRotRingAngle += (msg == oglMouseWheelUp) ? 3 : -3;
00444 }
00445 else
00446 Window::MouseFunc( msg, but, state, x, y );
00447 }
00448
00449 private:
00450 float mSphereX, mSphereY, mSphereZ;
00451 float mSphereRotX, mSphereRotY, mSphereRotZ;
00452 float mSphereRotDx, mSphereRotDy, mSphereRotDz;
00453 float mRotRingDelta;
00454 bool mSphereRotating;
00455 bool mShowText;
00456 bool mAdjustViewDims;
00457 int mAnimSteps;
00458 int mAnimCnt;
00459
00460 float mRadius;
00461 float mStdStickOut;
00462
00463 float mRotRingAngle;
00464 int mVertRingNr;
00465 int mHorRingNr;
00466 int txtFontBase;
00467 bool mStdVertRing;
00468 bool mDblRing;
00469 bool mAutoRotateRing;
00470
00471 OGLIMAGE *oglIm[7];
00472 OGLVIEW3D *centralView;
00473 bool mShowCentralView;
00474 bool mKeyInfo;
00475
00476 INFOBOX *sphereInfoBox;
00477
00478 void Init()
00479 {
00480 for (int i=0 ; i<7; i++)
00481 oglIm[i] = 0;
00482
00483
00484
00485 mAdjustViewDims = true;
00486
00487 mSphereX = mSphereY = 0;
00488 mSphereZ=-20;
00489 mSphereRotY = mSphereRotX = mSphereRotZ = 0;
00490 mSphereRotDx = mSphereRotDy= mSphereRotDz = 0;
00491 mRotRingDelta = 0.5f;
00492 mSphereRotating = true;
00493
00494
00495
00496 mShowCentralView = false;
00497 mRadius = 6.0f;
00498 mStdStickOut = 0.2f;
00499 mRotRingAngle = 0.0f;
00500 mVertRingNr = 0;
00501 mHorRingNr = 0;
00502 mStdVertRing = true;
00503 mDblRing = false;
00504 mKeyInfo = false;
00505 mShowText = true;
00506 mAnimSteps = 200;
00507 mAnimCnt = mAnimSteps;
00508 mAutoRotateRing = true;
00509 }
00510 };
00511
00512 }
00513 #endif