Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

SceneControl.cxx

Go to the documentation of this file.
00001 //     $Id: SceneControl.cxx,v 1.1.1.1 2001/01/04 01:01:11 burnett Exp $
00002 //  Author: Toby Burnett
00003 //
00004 
00005 #include <string>
00006 #include "gui/SceneControl.h"
00007 #include "gui/ViewPort.h"
00008 #include "gui/Scene.h"
00009 
00010 
00011 #include <ctype.h>      // for tolower
00012 
00013 namespace gui {
00014 
00016 // euler angles and perspective constant used as defaults for ViewPort objects
00017 static float eulers[4][4] =
00018   { { 0.,  0.,  0., 0.},
00019     { 0., 90.,  0., 0.},
00020     {90., 90.,  0., 0.},
00021     {11.,110.,  4., 0.25} };
00022 // set of euler angles with the z-axis up
00023 static float eulers_z_up[4][4] =
00024   { { 0.,  0.,    0., 0.},
00025     {180., 90.,  90., 0.},
00026     {-90., 90.,  90., 0.},
00027     {-20.,-81., -90., 0.25} };
00028 
00029 
00030 static const char  *title[]={
00031                 "View 1, Front(X-Y)",
00032                 "View 2, Side (Z-Y)",
00033                 "View 3, Plan (X-Z)",
00034                 "View 4, General" };
00035 
00036 static const int  initialView = 1;             // Define initial selected view
00037 static const int  initialSingle = 1;           // Define initial format
00038 
00039 static GraphicsVector center2d(0.5,0.5,0);              // center for 2-d view
00040 
00041 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00042 SceneControl::SceneControl(ViewPort* projector, float scale, int initial_view )
00043 //----------------------------------------------------------
00044 // implement constructor for abstract base class to manage display
00045 :  m_detail(0.01f)   // stuff for doCommand
00046 ,  m_axis(1)
00047 {
00048     m_max_view = sizeof(title)/sizeof(char*);
00049 
00050 
00051     for( int i=0; i< m_max_view; i++) {
00052         if( scale>0)
00053             m_views.push_back( &projector->copy(&m_reference_point, scale, eulers[i], title[i]));
00054         else
00055             m_views.push_back( &projector->copy(&m_reference_point, -scale, eulers_z_up[i], title[i]));
00056 
00057     }
00058 
00059     select_view_number(scale>0?initial_view:2);
00060     set_single(initialSingle);
00061 
00062     //create a scene to control
00063     m_scene = new Scene;
00064 
00065     // setup 2-d scene and view
00066     m_2d_scene = new Scene;
00067     m_2d_view = &projector->copy(&center2d, 0.5, eulers[0], "" );
00068 
00069 }
00070 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00071 SceneControl::~SceneControl()
00072 {
00073     delete m_scene;
00074     for( int i=0; i<m_max_view; i++)delete  m_views[i];
00075     delete m_2d_scene;
00076     delete m_2d_view;   
00077 }
00078 
00079 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00080 void SceneControl::draw()
00081 //-----------------------
00082 {
00083     m_2d_view->set_quad(0,0);
00084 
00085     if( (m_scene->enabled()) ) { 
00086         
00087         if( m_single_view ){
00088             m_current_view->set_quad(0,0);
00089             m_scene->draw(m_current_view);
00090         }
00091         else{
00092             for( int i=0; i<m_max_view; i++){
00093                 m_views[i]->set_quad(i+1, i==m_selected_view);
00094                 m_scene->draw(m_views[i]);
00095             }
00096         }
00097     }
00098     m_2d_scene->draw(m_2d_view);
00099 
00100 }
00101 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00102 void SceneControl::redisplay(Draw2D* temp)
00103 // if the ViewPorts are Projectors, redisplay using temporary canvas
00104 // (i.e., to postcript)
00105 {
00106     Draw2D* current = view().canvas();
00107     int i;
00108     for( i=0; i<m_max_view; i++) { m_views[i]->set_canvas(temp);}
00109     m_2d_view->set_canvas(temp);
00110     
00111     draw();
00112 
00113     for( i=0; i<m_max_view; i++) { m_views[i]->set_canvas(current);}
00114     m_2d_view->set_canvas(current);
00115 }
00116 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00117 void SceneControl::resize(int width, int height)
00118 {
00119     for(int i=0; i<m_max_view; i++)
00120         m_views[i]->setAspectRatio( (float)width/(float)height);
00121 }
00122 
00123 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00124 void SceneControl::displaycurrent(int hl)
00125 //--------------------------------------
00126 {
00127     if( m_single_view) m_current_view->set_quad(0,0);
00128     else m_current_view->set_quad(m_selected_view+1, hl);
00129     m_scene->draw(m_current_view);
00130     m_2d_scene->draw(m_2d_view);
00131 }
00132 
00133 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00134 void SceneControl::select_view_number(int number)
00135 //-----------------------------------------------
00136 {
00137     if( number<1 || number>m_max_view ) return;
00138     m_current_view = m_views[number-1];
00139     m_selected_view = number-1;
00140 }
00141 
00142 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00143 void SceneControl::set_single(int value)
00144 //--------------------------------------
00145 {
00146     m_single_view= value;
00147 }
00148 
00149 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00150 void SceneControl::move_by(float x, float y)
00151 //-----------------------------------------
00152 //  adjust m_reference_point,in direction perpendicular to current view
00153 {   
00154 
00155     // prevent motion if click out of view
00156     if( abs(x) < 1.0 && abs(y) < 1.0 )
00157 
00158         m_reference_point += m_current_view->transformToWorld(x,y);
00159 } 
00160 void SceneControl::move_left( float howfar){ move_by( howfar,0);}
00161 void SceneControl::move_right(float howfar){ move_by(-howfar,0);}
00162 void SceneControl::move_up(   float howfar){ move_by(0,-howfar);}
00163 void SceneControl::move_down( float howfar){ move_by(0, howfar);}
00164 
00165 //------------------------------------------------------------------
00166 //                 adjust magnification (zoom)
00167 
00168 void SceneControl::zoom_in(float howfar) { m_current_view->zoom(1+howfar);}
00169 void SceneControl::zoom_out(float howfar){ m_current_view->zoom(1-howfar);}
00170 void SceneControl::set_zoom(float z)     { m_current_view->setZoom(z);}
00171 
00172 
00173 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00174 void SceneControl::reset_view()
00175 //----------------------------
00176 {   m_reference_point = m_origin; 
00177     m_current_view->reset();
00178 }
00179 
00180 //----------------------------------------------------------------
00181 //             rotate viewer position
00182 
00183 void
00184 SceneControl::rotate_euler(const float* delta)
00185 {
00186     m_current_view->rotateEuler(delta);
00187 }
00188 
00189 void
00190 SceneControl::rotate_euler(float dx, float dy, float dz){
00191     float theta[3]={dx,dy,dz};
00192     m_current_view->rotateEuler(theta);
00193 }
00194 
00195 void SceneControl::rotate_x(float theta){ m_current_view->rotateX(theta);}
00196 void SceneControl::rotate_y(float theta){ m_current_view->rotateY(theta);}
00197 void SceneControl::rotate_z(float theta){ m_current_view->rotateZ(theta);}
00198 
00199 //----------------------------------------------------------------
00200 //             change perspective
00201 void SceneControl::move_out(float d){   m_current_view->moveOut(d);}
00202 void SceneControl::move_in(float d) {   m_current_view->moveIn(d);}
00203 void SceneControl::set_view_distance(float d){ m_current_view->setPerspective(d);}
00204 
00205 //----------------------------------------------------------------
00206 //              set detail level
00207 void SceneControl::set_detail(float d){ m_current_view->setDetail(d);}
00208 
00209 void SceneControl::setViewPort (float xmin, float ymin, float xmax, float ymax)
00210 {
00211   if (xmin > xmax) {   float h = xmax; xmax = xmin; xmin = h; }
00212   if (ymin > ymax) {   float h = ymax; ymax = ymin; ymin = h; }
00213 
00214    move_by ((xmin+xmax)/2, (ymin+ymax)/2);
00215 
00216    // zoom too much ?
00217    if (xmax-xmin <= 0.02  ||  ymax-ymin <= 0.02)
00218       return;
00219 
00220    // no, so zoom in
00221    if (xmax - xmin > ymax-ymin)
00222       zoom_in (2/(xmax-xmin) - 1);
00223    else
00224       zoom_in (2/(ymax-ymin) - 1);
00225 }
00226 
00227 //
00229 //                    Built-in character control stuff
00230 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00231 int SceneControl::do_command(const char * cmd)
00232 //--------------------------------------------
00233 // doCommand -- for interactive modification of view parameters
00234 //  return -1: unrecognized
00235 //          0: ok, no redisplay needed
00236 //          1: must redisplay quadrant -- displaycurrent(1);
00237 //          2: redisplay all           -- display();
00238 {
00239    int command = tolower(cmd[0]);
00240    int n = -1;
00241 
00242    float angle=0;
00243    switch( command ){
00244      case 0:
00245           // extended command
00246           command = cmd[1];
00247           switch( command ) {
00248             case 75: move_left(); return 1;
00249             case 72: move_up();   return 1;
00250             case 77: move_right(); return 1;
00251             case 80: move_down();  return 1;
00252             case 73: zoom_in();    return 1;
00253             case 81: zoom_out();   return 1;
00254             case 71: reset_view(); m_detail=0.01f; return 1;
00255             default: return -1;
00256           }
00257      case 'b': move_left();  return 1;        // Back
00258      case 'p': move_up();    return 1;         // uP
00259      case 'f': move_right(); return 1;         // Forward
00260      case 'n': move_down();  return 1;         // dowN
00261      case 'm': zoom_in();    return 1;         // Small
00262      case 's': zoom_out();   return 1;         // Large
00263      case 'r': reset_view();  m_detail=0.01f; return 1;
00264      case 'u': return 1;                   //Update
00265 
00266      case '0': n=0; break;
00267      case '1': n=1; break;
00268      case '2': n=2; break;
00269      case '3': n=3; break;
00270      case '4': n=4; break;
00271 
00272      case 'x': m_axis=0; return 0;
00273      case 'y': m_axis=1; return 0;
00274      case 'z': m_axis=2; return 0;
00275      case 'd': m_axis=3; return 0;
00276 
00277      case 'i': move_in(); return 1;
00278      case 'o': move_out(); return 1;
00279 
00280      case '>': angle=1.; break;
00281      case '.': angle=10; break;
00282      case '<': angle=-1; break;
00283      case ',': angle=-10; break;
00284 
00285      default: return -1;
00286    }
00287    if (angle ) {
00288                 switch( m_axis ) {
00289               case 0: rotate_x(angle); return 1;
00290               case 1: rotate_y(angle); return 1;
00291               case 2: rotate_z(angle); return 1;
00292               case 3: set_detail(m_detail *= angle>0? 2. : 0.5 ); return 1;
00293            }
00294    }
00295 
00296     // here if view changed
00297 
00298     if( n==m_selected_view+1 || n==-1) return 0;
00299     if (n==0) {
00300        // toggling quad views 
00301          if (m_single_view)  set_single(0);
00302          else            set_single(1);
00303          return 2;
00304     }
00305     select_view_number(n);
00306     return 2;
00307 
00308 }
00309 
00310 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00311 void 
00312 SceneControl::print_commands(std::ostream& cout)
00313 {
00314 cout <<
00315 "\n"
00316 "Keystroke display commands:\n"
00317 "===========================\n"
00318 "  b,f  \t move left,right  (Back,Forward)\n"
00319 "  p,n  \t move up,down     (uP, Down)\n"
00320 "  m,s  \t zoom in,out      (Magnify, Shrink)\n"
00321 "  i,o  \t move in,out      (In, Out)\n"
00322 "  r    \t reset view  (Reset)\n"
00323 "  0    \t toggle single/quad view\n"
00324 "  1,2,3,4\t select  view#\n"
00325 "  u    \t update     (Update)\n"
00326 "\n"
00327 "Following set action for ,.\n"
00328 "  x,y,z\t set x,y,z axis for rotation\n"
00329 "  d    \t modify detail level by x2 \n"
00330 "  ,    \t (comma)  rotate left by 10 deg\n"
00331 "  <    \t rotate left by 1 deg\n"
00332 "  .    \t (period) rotate right by 10 deg\n"
00333 "  >    \t rotate right by 1 deg\n"
00334 ;
00335     cout.flush();
00336 }
00337 
00338 } // namespace gui
00339 
00340 

Generated at Mon Nov 26 18:18:11 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000