00001 #include "std/config.H"
00002 #include "geom/world.H"
00003 #include "kbd_nav.H"
00004
00005 using mlib::Wvec;
00006 using mlib::CWvec;
00007 using mlib::Wtransf;
00008
00009 #define STEP_LEFT '4'
00010 #define STEP_RIGHT '6'
00011 #define STEP_BACK '2'
00012 #define STEP_FRONT '8'
00013 #define STEP_UP '1'
00014 #define STEP_DOWN '3'
00015 #define STEP_TILTUP '0'
00016 #define STEP_TILTDOWN '5'
00017 #define STEP_ROTLEFT '7'
00018 #define STEP_ROTRIGHT '9'
00019
00020
00021 inline double sign (double x) { return x>0 ? 1 : -1; }
00022 inline double sqr_signed(double x) { return sqr(x)*sign(x); }
00023 inline Wvec project (CWvec &v1, CWvec &v2)
00024 { return (v1 * v2.normalized()) * v2.normalized(); }
00025
00026
00027 kbd_nav::kbd_nav(
00028 VIEWptr &view
00029 ):_data(view->cam()->data())
00030 {
00031 _speed_lr = _speed_fb = _speed_ud = _speed_tilt = _speed_rot = 0;
00032
00033 for (int i = 0; i < 256; i++)
00034 _kmap[i] = 0;
00035
00036 for (const char *c = "1234567890"; *c; c++) {
00037 Event down_ev(NULL, Evd(*c, KEYD));
00038 Event up_ev (NULL, Evd(*c, KEYU));
00039 _entry += Arc(up_ev, Cb(&Key_int::up));
00040 _entry += Arc(down_ev, Cb(&Key_int::down));
00041 }
00042 VIEWint_list::add(view, &_entry);
00043 WORLD::timer_callback(this);
00044 }
00045
00046 int
00047 kbd_nav::tick()
00048 {
00049 static bool KBD_NAVIGATION = Config::get_var_bool("KBD_NAVIGATION",false,true);
00050
00051 if (!KBD_NAVIGATION) return 0;
00052
00053 double decay = 30;
00054 int frames_to_full = 5;
00055 int rate = (int)(decay/frames_to_full) + 1;
00056 double cam_speed_hack = 0.3;
00057 double cam_rot_speed_hack = 0.25;
00058 double coeff = cam_speed_hack /sqr(decay);
00059 double coeff_rot = cam_rot_speed_hack/sqr(decay);
00060 double factor = 9;
00061
00062 if (_kmap[(int)STEP_LEFT ]&2) step_left (rate);
00063 if (_kmap[(int)STEP_RIGHT ]&2) step_right (rate);
00064 if (_kmap[(int)STEP_BACK ]&2) step_back (rate);
00065 if (_kmap[(int)STEP_FRONT ]&2) step_front (rate);
00066 if (_kmap[(int)STEP_UP ]&2) step_up (rate);
00067 if (_kmap[(int)STEP_DOWN ]&2) step_down (rate);
00068 if (_kmap[(int)STEP_TILTUP ]&2) step_tilt_up (rate);
00069 if (_kmap[(int)STEP_TILTDOWN]&2) step_tilt_down(rate);
00070 if (_kmap[(int)STEP_ROTLEFT ]&2) step_rot_left (rate);
00071 if (_kmap[(int)STEP_ROTRIGHT]&2) step_rot_right(rate);
00072
00073 _speed_lr += _speed_lr > 0 ? -1 : (_speed_lr < 0 ? 1 : 0);
00074 _speed_fb += _speed_fb > 0 ? -1 : (_speed_fb < 0 ? 1 : 0);
00075 _speed_ud += _speed_ud > 0 ? -1 : (_speed_ud < 0 ? 1 : 0);
00076 _speed_tilt += _speed_tilt > 0 ? -1 : (_speed_tilt < 0 ? 1 : 0);
00077 _speed_rot += _speed_rot > 0 ? -1 : (_speed_rot < 0 ? 1 : 0);
00078
00079 _speed_lr = clamp(_speed_lr, (int)-decay, (int)decay);
00080 _speed_fb = clamp(_speed_fb, (int)-decay, (int)decay);
00081 _speed_ud = clamp(_speed_ud, (int)-decay, (int)decay);
00082 _speed_tilt = clamp(_speed_tilt, (int)-decay, (int)decay);
00083 _speed_rot = clamp(_speed_rot, (int)-decay, (int)decay);
00084
00085 Wvec ATV((_data->at_v() - project(_data->at_v(), Wvec::Y())).normalized());
00086 Wvec delt((-sqr_signed(_speed_lr)*coeff*_data->right_v() +
00087 sqr_signed(_speed_ud)*coeff*_data->pup_v ()/2.0)-
00088 sqr_signed(_speed_fb)*coeff*ATV );
00089 _data->translate(delt);
00090
00091 const double rads = sqr_signed(_speed_tilt) * coeff_rot / factor;
00092 if (rads != 0) {
00093 Wtransf xf(Wtransf::rotation(_data->right_v(), rads));
00094 _data->set_at(_data->from() + xf * (_data->at() - _data->from()));
00095 }
00096
00097 _data->swivel(-sqr_signed(_speed_rot) * coeff_rot / factor);
00098 if (!_data->persp()) {
00099 _data->set_width (_data->width() + _speed_fb/1000.);
00100 _data->set_height(_data->height() + _speed_fb/1000.);
00101 }
00102
00103 #define DOWN_SHIFT(X) ((X & 1) + (X << 1))
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 _kmap[(int)STEP_LEFT ] = DOWN_SHIFT(_kmap[(int)STEP_LEFT ]);
00117 _kmap[(int)STEP_RIGHT ] = DOWN_SHIFT(_kmap[(int)STEP_RIGHT ]);
00118 _kmap[(int)STEP_BACK ] = DOWN_SHIFT(_kmap[(int)STEP_BACK ]);
00119 _kmap[(int)STEP_FRONT ] = DOWN_SHIFT(_kmap[(int)STEP_FRONT ]);
00120 _kmap[(int)STEP_UP ] = DOWN_SHIFT(_kmap[(int)STEP_UP ]);
00121 _kmap[(int)STEP_DOWN ] = DOWN_SHIFT(_kmap[(int)STEP_DOWN ]);
00122 _kmap[(int)STEP_TILTUP ] = DOWN_SHIFT(_kmap[(int)STEP_TILTUP ]);
00123 _kmap[(int)STEP_TILTDOWN] = DOWN_SHIFT(_kmap[(int)STEP_TILTDOWN]);
00124 _kmap[(int)STEP_ROTLEFT ] = DOWN_SHIFT(_kmap[(int)STEP_ROTLEFT ]);
00125 _kmap[(int)STEP_ROTRIGHT] = DOWN_SHIFT(_kmap[(int)STEP_ROTRIGHT]);
00126
00127 return 0;
00128 }
00129
00130