00001
00002
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>
00012
00013 namespace gui {
00014
00016
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
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;
00037 static const int initialSingle = 1;
00038
00039 static GraphicsVector center2d(0.5,0.5,0);
00040
00041
00042 SceneControl::SceneControl(ViewPort* projector, float scale, int initial_view )
00043
00044
00045 : m_detail(0.01f)
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
00063 m_scene = new Scene;
00064
00065
00066 m_2d_scene = new Scene;
00067 m_2d_view = &projector->copy(¢er2d, 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
00104
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
00153 {
00154
00155
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
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
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
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
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
00217 if (xmax-xmin <= 0.02 || ymax-ymin <= 0.02)
00218 return;
00219
00220
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
00230
00231 int SceneControl::do_command(const char * cmd)
00232
00233
00234
00235
00236
00237
00238 {
00239 int command = tolower(cmd[0]);
00240 int n = -1;
00241
00242 float angle=0;
00243 switch( command ){
00244 case 0:
00245
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;
00258 case 'p': move_up(); return 1;
00259 case 'f': move_right(); return 1;
00260 case 'n': move_down(); return 1;
00261 case 'm': zoom_in(); return 1;
00262 case 's': zoom_out(); return 1;
00263 case 'r': reset_view(); m_detail=0.01f; return 1;
00264 case 'u': return 1;
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
00297
00298 if( n==m_selected_view+1 || n==-1) return 0;
00299 if (n==0) {
00300
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 }
00339
00340