Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

cam_focus.C

Go to the documentation of this file.
00001 #include "disp/cam_focus.H"
00002 #include "std/config.H"
00003 
00004 using namespace mlib;
00005 
00006 // The following don't have a more logical place to go:
00007 BaseCollide* BaseCollide::_instance = 0;
00008 BaseGravity* BaseGravity::_instance = 0;
00009 
00010 /*****************************************************************
00011  * CamFocus
00012  *****************************************************************/
00013 CamFocusptr  CamFocus::_cur = 0;
00014 
00015 // speed:    world space units per second
00016 // duration: seconds
00017 static const double SPEED         = Config::get_var_dbl("CAM_FOCUS_SPEED",0.5);
00018 static const double CAM_FOCUS_DUR = Config::get_var_dbl("CAM_FOCUS_DUR",  1.5);
00019 
00020 static const bool debug = Config::get_var_bool("DEBUG_CAM_FOCUS",false);
00021 
00022 inline double
00023 fdist(CCAMptr& d)
00024 {
00025    // return distance between "from" and "center" points,
00026    // interpreted as a kind of "feature size" for the camera
00027    return d ? d->data()->from().dist(d->data()->center()) : 1.0;
00028 }
00029 
00030 CamFocus::CamFocus(
00031    VIEWptr v,
00032    CWpt&   from,
00033    CWpt&   at,
00034    CWpt&   up,
00035    CWpt&   center,
00036    double  fw,
00037    double  fh
00038    ) :
00039    _view(v),
00040    _cam(v ? v->cam() : 0),
00041    _width (fw == 0 ? cam()->data()->width()  : fw),
00042    _height(fh == 0 ? cam()->data()->height() : fh),
00043    _orig_time(VIEW::peek()->frame_time()),
00044    _last_time(_orig_time),
00045    _duration(CAM_FOCUS_DUR),
00046    _speed(SPEED),
00047    _max_speed(fdist(_cam)/2.0) // max speed is one basic unit per 2 seconds
00048 {
00049    assert(cam() && cam()->data());
00050 
00051    Wpt a = at;
00052    if (from.is_equal(a)) {
00053       cerr << "CamFocus::CamFocus: ignoring zero length at vector" << endl;
00054       a = cam()->data()->at();
00055    }
00056 
00057    // take more time for long trips:
00058    double s = max(cam()->data()->from().dist(from)/_duration/_max_speed,1.0);
00059    err_adv(debug, "CamFocus::CamFocus: extending duration by %f", s);
00060    _duration *= s;
00061 
00062    setup(from, a, up - from, center);
00063 
00064    err_adv(debug, "CamFocus::CamFocus: using vectors");
00065 
00066    schedule();
00067 }
00068 
00069 CamFocus::CamFocus(VIEWptr v, CCAMptr &dest) :
00070    _view(v),
00071    _cam(v ? v->cam() : 0),
00072    _width(dest->data()->width()),
00073    _height(dest->data()->height()),
00074    _orig_time(VIEW::peek()->frame_time()),
00075    _last_time(_orig_time),
00076    _duration(CAM_FOCUS_DUR),
00077    _speed(SPEED),
00078    _max_speed(fdist(_cam)/2.0) // max speed is one basic unit per 2 seconds
00079 {
00080    assert(dest && dest->data());
00081    CAMdataptr d = dest->data();
00082    Wpt a = d->at();
00083    if (d->from().is_equal(a)) {
00084       cerr << "CamFocus::CamFocus: ignoring zero length at vector" << endl;
00085       a = cam()->data()->at();
00086    }
00087 
00088    // take more time for long trips:
00089    double s = max(cam()->data()->from().dist(d->from())/_duration/_max_speed,1.0);
00090    err_adv(debug, "CamFocus::CamFocus: extending duration by %f", s);
00091    _duration *= s;
00092 
00093    setup(d->from(), a, d->up_v(), d->center());
00094 
00095    err_adv(debug, "CamFocus::CamFocus: using cam");
00096 
00097    schedule();
00098 }
00099 
00100 CamFocus::~CamFocus()
00101 {
00102    err_adv(debug, "CamFocus::~CamFocus");
00103 
00104    unschedule();
00105 }
00106 
00107 inline Wtransf
00108 get_mat(CWpt& o, CWpt& at, CWpt& up, CWpt& center)
00109 {
00110    // create rotation matrix expressing camera orientation at target
00111    Wvec a = (at - o).normalized();                      // y
00112    Wvec u = (up - o).orthogonalized(a).normalized();    // z
00113    Wvec r = cross(a,u);                                 // x
00114    return Wtransf(r,a,u);
00115 }
00116 
00117 Wquat
00118 get_quat(CWpt& o, CWpt& at, CWpt& up, CWpt& center, Wvec& a, Wvec& u, Wvec& c)
00119 {
00120    Wtransf M = get_mat(o,at,up,center);
00121    Wtransf I = get_mat(o,at,up,center).transpose(); // same as M.inverse()
00122 
00123    // compute at, up, and center points in local coords:
00124    a = I * (at     - o);
00125    u = I * (up     - o);
00126    c = I * (center - o);
00127    
00128    return Wquat(M);
00129 }
00130 
00131 void
00132 CamFocus::setup(
00133    CWpt& o2, CWpt& a2, CWvec& u2, CWpt& c2
00134    )
00135 {
00136    CAMdataptr d = cam()->data();
00137 
00138    // camera parameters at start of animation:
00139    _o1 = d->from();
00140    _a1 = d->at();
00141    _u1 = d->up_v();
00142    _c1 = d->center();
00143 
00144    // camera parameters at end of animation:
00145    _o2 = o2;
00146    _a2 = a2;
00147    _u2 = u2;
00148    _c2 = c2;
00149 
00150    set_cur(this);
00151 }
00152 
00153 void
00154 CamFocus::set_cur(CamFocus* cf)
00155 {
00156    cancel_cur();
00157    _cur = cf;
00158 }
00159 
00160 void 
00161 CamFocus::cancel_cur()
00162 {
00163    if (_cur) {
00164       _cur->unschedule();
00165       _cur = 0;
00166    }
00167 }
00168 
00169 inline double
00170 remap(double t)
00171 {
00172    // add a sinuoid to remap t values so the animation
00173    // eases in and out, with max speed at the middle.
00174    // greater value of A increases the effect.
00175 
00176    static const double A = Config::get_var_dbl("CAM_FOCUS_REMAP_VAL",0.11);
00177    return t - A * sin(t * TWO_PI);
00178 }
00179 
00180 double 
00181 CamFocus::cartoon_t() const
00182 {
00183    return remap(t_param());
00184 }
00185 
00186 int
00187 CamFocus::tick(void)
00188 {
00189    CAMdataptr data(cam()->data());
00190 
00191    double   t = cartoon_t();
00192 
00193    Wpt  o = interp(_o1,_o2,t);
00194    Wpt  a = interp(_a1,_a2,t);
00195    Wvec u = interp(_u1,_u2,t);
00196    Wpt  c = interp(_c1,_c2,t);
00197    if (0 && debug) {
00198       cerr << "--------" << endl
00199            << "  this:   " << this << endl
00200            << "  frame:  " << VIEW::stamp() << endl
00201            << "  t:      " << t << endl
00202            << "  from:   " << o << endl
00203            << "  at:     " << a << endl
00204            << "  up:     " << u << endl
00205            << "  center: " << c << endl;
00206    }
00207    data->set_from  (o);
00208    data->set_at    (a);
00209    data->set_up    (o + u);
00210    data->set_center(c);
00211 
00212    // not interpolating for now:
00213    data->set_width (_width);
00214    data->set_height(_height);
00215    
00216    return 0; //(t < 1) ? 0 : -1;
00217 }
00218 
00219 /*****************************************************************
00220  * CamBreathe
00221  *****************************************************************/
00222 CamBreatheptr   CamBreathe::_breathe    = 0;
00223 double          CamBreathe::_size       = 1;
00224 
00225 CamBreathe::CamBreathe(CAMptr  &p) :
00226    _cam(p),_from(p->data()->from()),_at(p->data()->at()),
00227    _up(Wpt()+p->data()->up_v()),_cent(p->data()->center()),
00228    _width(p->data()->width()),_height(p->data()->height()),
00229    _speed(1), kKf(0.05), kKc(0.02), kKu(0.008)
00230 {
00231    _cent   = _at;
00232    _min    = _cam->data()->persp() ? 0.01 : 0.001;
00233    _width  = _cam->data()->width();
00234    _height = _cam->data()->height();
00235    _Kf     = 0;
00236    _Kc     = 0;
00237    _Ku     = 0;
00238    _breathe  = this;
00239    _tick     = 0;
00240    _stop     = false;
00241    _pause = false;
00242 }
00243 
00244 CamBreathe::~CamBreathe()
00245 {
00246 }
00247 
00248 int
00249 CamBreathe::tick(void)
00250 {
00251    if(_stop)
00252       return -1;
00253 
00254    if(_pause)
00255       return 0;
00256     
00257    _speed = 2;
00258    //_size = 0.005 ;
00259   
00260    cout << "Sixe: " << _size << endl;
00261    CAMdataptr data(_cam->data());
00262 
00263    Wvec upv(data->up_v());
00264 
00265    //"breathing" is just a simple sin wave: Sin(X*breathing speed) *
00266    //size of character
00267    data->set_from(data->from() + (sin(_tick * _speed) * upv * .005 * _size));
00268    data->set_at(data->at() + (sin(_tick * _speed) * upv * .005 * _size));
00269    data->set_up(data->up() + (sin(_tick * _speed) * upv * .005 * _size));
00270    data->set_center(data->at());
00271    data->set_width (fabs(_width));
00272    data->set_height(fabs(_height));
00273 
00274    _tick += .01;
00275    return 0;
00276 }
00277 
00278 /*****************************************************************
00279  * CamOrbit
00280  *****************************************************************/
00281 CamOrbitptr     CamOrbit::_orbit        = 0;
00282 CamCruiseptr    CamCruise::_cruise      = 0;
00283 
00284 int
00285 CamOrbit::tick(void)
00286 {
00287    if(_stop)
00288       return -1;
00289 
00290    if(_pause)
00291       return 0;
00292 
00293 
00294    CAMdataptr data(_cam->data());
00295    data->set_center(_cent);
00296 
00297    XYpt        cpt   = data->center();
00298    double      radsq = sqr(1+fabs(cpt[0])); // squared rad of virtual cylinder
00299 
00300    //Toss in some XY pts
00301    //to simulate a mouse movement
00302    //that produces rotation...
00303    //XYpt        tp    = XYpt(0.495, 0.5); 
00304    // XYpt        te    = XYpt(0.5,0.5);
00305 
00306    Wvec   op  (tp[0], 0, 0);             // get start and end X coordinates
00307    Wvec   oe  (te[0], 0, 0);             //    of cursor motion
00308    double opsq = op * op, oesq = oe * oe;
00309    double lop  = opsq > radsq ? 0 : sqrt(radsq - opsq);
00310    double loe  = oesq > radsq ? 0 : sqrt(radsq - oesq);
00311    //Wvec   nop  = Wvec(op[0], 0, lop).normalized();
00312    //Wvec   noe  = Wvec(oe[0], 0, loe).normalized();
00313    Wvec   nop  = Wvec(op[0], 0, lop).normalized();
00314    Wvec   noe  = Wvec(oe[0], 0, loe).normalized();
00315 
00316    double dot  = nop * noe;
00317 
00318    if (fabs(dot) > 0.0001) {
00319       data->rotate(Wline(data->center(), Wvec::Y()),
00320                    -1*Acos(dot) * Sign(te[0]-tp[0]));
00321 
00322       CAMdata   dd = CAMdata(*data);
00323       data->set_up(data->from() + Wvec::Y());
00324       if (data->right_v() * dd.right_v() < 0)
00325          *data = dd;
00326    }
00327 
00328 
00329    return 0;
00330 }
00331 
00332 CamOrbit::~CamOrbit()
00333 {
00334 }
00335 
00336 CamOrbit::CamOrbit(CAMptr  &p, mlib::Wpt center) :
00337    _cam(p),_from(p->data()->from()),_at(p->data()->at()),
00338    _up(Wpt()+p->data()->up_v()),_cent(p->data()->center()),
00339    _width(p->data()->width()),_height(p->data()->height()),
00340    _speed(1)
00341 {
00342    _cent   = center;
00343    _min    = _cam->data()->persp() ? 0.01 : 0.001;
00344    _width  = _cam->data()->width();
00345    _height = _cam->data()->height();
00346    _orbit  = this;
00347    _tick   = 0;
00348    //_size   = 1;
00349    _pause = false;
00350    _stop = false;
00351    tp    = XYpt(0.495, 0.5);
00352    te    = XYpt(0.5,0.5);
00353 }
00354 
00355 /*****************************************************************
00356  * CamCruise
00357  *****************************************************************/
00358 CamCruise::CamCruise(CAMptr  &p, mlib::Wpt center) :
00359    _cam(p),_from(p->data()->from()),_at(p->data()->at()),
00360    _up(Wpt()+p->data()->up_v()),_cent(p->data()->center()),
00361    _width(p->data()->width()),_height(p->data()->height()),
00362    _speed(2)
00363 {
00364    _speed = .1;
00365    _cent   = center;
00366    _min    = _cam->data()->persp() ? 0.01 : 0.001;
00367    _width  = _cam->data()->width();
00368    _height = _cam->data()->height();
00369    _cruise  = this;
00370    _tick   = 0;
00371    _pause = true;
00372    _stop = false;
00373    _target = false;
00374    _travel = false;
00375    _start = mlib::Wpt(0,0,0);
00376    _dest = mlib::Wpt(0,0,0);
00377    tp    = XYpt(0.2, 0.5);
00378    te    = XYpt(0.5,0.5);
00379    _t    = 0;
00380    //size=1,height=6,regularity=20,min_dist=.35
00381    
00382 }
00383 
00384 CamCruise::~CamCruise()
00385 {
00386 }
00387 
00388 int
00389 CamCruise::tick(void)
00390 {
00391    if(_stop)
00392       return -1;
00393 
00394    if(_pause)
00395       return 0;
00396 
00397    CAMdataptr data(_cam->data());
00398    //data->set_center(_cent);
00399    
00400 
00401    XYpt        cpt   = data->center();
00402    XYvec      delta(te-tp);
00403    double     ratio;
00404 
00405 
00406 
00407    if(_travel)
00408       {
00409    
00410          /* not working atm
00411             if(_clock.elapsed_time()>.1)
00412             {
00413             Wvec path(_dest - _start);
00414             //Wvec   nup  (_Ku * (_up     - data->up_v () - Wpt())),
00415             //         ncent(_Kc * (_at     - data->at   ())),
00416             //         nfrom(_Kf * (_from   - data->from ()));
00417             //data->translate(path);//1/path.length());
00418             //Wvec velocity = path * path.length()*_t*_t;
00419             //data->set_from(_from + velocity * _t);// + path.length()/2 * _t*_t);
00420             //data->set_at(_at + path * _t);
00421             //data->set_up(_up + path * _t);
00422             //cout << "start: " << _start << endl; 
00423             //cout << "From: " << data->from() << endl; 
00424 
00425             _t += (1-_t) * .05;
00426             Wvec velocity = _t * (_dest - data->from());
00427             Wvec upVel    = _t * (_up     - data->up_v () - Wpt());
00428             Wvec centVel  = _t * (_at     - data->at());
00429 
00430             data->set_from(data->from() + velocity);// + path.length()/2 * _t*_t);
00431             data->set_at(data->at() + velocity);
00432             data->set_up(data->up() + velocity);
00433             //data->set_at(data->at() + centVel);
00434             //data->set_up(data->up() + upVel);
00435             data->changed();
00436 
00437             _clock.set();
00438             cout << velocity.length() << " : " << _t << endl;
00439             cout << _dest << " : " << data->from() << endl;
00440                 
00441             //if((data->from()-_dest).length() >> _min) 
00442             //if(velocity.length() > _min) 
00443             //      {
00444             //      cout << "out" << endl;
00445             //      _travel = false;
00446             //      _t=0;
00447             //      }
00448             }
00449          */
00450          _travel = false;
00451       }
00452    else
00453       {
00454          //Collide            _collision;
00455 
00456          Wpt     spt  (XYpt(tp[0],te[1]));
00457          Wvec    svec (spt - Wline(data->from(), data->at_v()).project(spt));
00458 //      double  sfact(1 + delta[1]);
00459          Wvec velocity;
00460 
00461          if (data->persp()) {
00462             Wvec    movec(data->at() - data->from());
00463             Wvec    gravity = BaseGravity::instance()->get_dir(data->from());
00464             velocity = BaseCollide::instance()->get_move(data->from(), gravity + 
00465                                                          (_speed * movec.normalized() * (movec.length() * delta[1] * -4)));
00466             //velocity = .1 * movec.normalized() * (movec.length() * delta[1] * -4);
00467         
00468             data->set_center(data->at());
00469             data->translate(velocity);
00470   
00471             ratio = data->height() / data->width() * 
00472                (movec * data->at_v()) * data->width() / data->focal();
00473             data->changed();
00474 
00475          } else {
00476 
00477             Wpt     spt  (XYpt(te[0],_scale_pt[1]));
00478             Wvec    svec (spt - Wline(data->from(), data->at_v()).project(spt));
00479             double  sfact(1 + delta[1]);
00480             data->translate( .5 * svec * (1.0 - sfact));
00481             data->set_width (data->width() * sfact);
00482             data->set_height(data->height()* sfact);
00483             ratio = data->height();
00484             data->changed();
00485          }
00486 
00487       }
00488    return 0;
00489 
00490 }
00491 
00492 void 
00493 CamCruise::travel(mlib::Wpt p)
00494 { 
00495    cout << "traveling: " << p << endl;
00496    _travel = true;
00497    _pause = false;
00498    _start = _cam->data()->from();
00499    _dest = p;
00500    cout << "start: " << _start << endl; 
00501    cout << "From: " << p << endl; 
00502    _from = _cam->data()->from();
00503    _at       = _cam->data()->up();
00504    _up       = _cam->data()->from()-_cam->data()->at_v();
00505    _clock.set();
00506 }
00507 
00508 void 
00509 CamCruise::set_cruise(mlib::XYpt o, mlib::XYpt e)
00510 { 
00511    _pause = false;
00512    tp    = o;
00513    te    = e;
00514 }
00515 
00516 // end of file cam_focus.C

Generated on Mon Sep 18 11:39:29 2006 for jot by  doxygen 1.4.4