00001 #include "disp/cam_focus.H"
00002 #include "std/config.H"
00003 
00004 using namespace mlib;
00005 
00006 
00007 BaseCollide* BaseCollide::_instance = 0;
00008 BaseGravity* BaseGravity::_instance = 0;
00009 
00010 
00011 
00012 
00013 CamFocusptr  CamFocus::_cur = 0;
00014 
00015 
00016 
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    
00026    
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) 
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    
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) 
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    
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    
00111    Wvec a = (at - o).normalized();                      
00112    Wvec u = (up - o).orthogonalized(a).normalized();    
00113    Wvec r = cross(a,u);                                 
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(); 
00122 
00123    
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    
00139    _o1 = d->from();
00140    _a1 = d->at();
00141    _u1 = d->up_v();
00142    _c1 = d->center();
00143 
00144    
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    
00173    
00174    
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    
00213    data->set_width (_width);
00214    data->set_height(_height);
00215    
00216    return 0; 
00217 }
00218 
00219 
00220 
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    
00259   
00260    cout << "Sixe: " << _size << endl;
00261    CAMdataptr data(_cam->data());
00262 
00263    Wvec upv(data->up_v());
00264 
00265    
00266    
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 
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])); 
00299 
00300    
00301    
00302    
00303    
00304    
00305 
00306    Wvec   op  (tp[0], 0, 0);             
00307    Wvec   oe  (te[0], 0, 0);             
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    
00312    
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    
00349    _pause = false;
00350    _stop = false;
00351    tp    = XYpt(0.495, 0.5);
00352    te    = XYpt(0.5,0.5);
00353 }
00354 
00355 
00356 
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    
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    
00399    
00400 
00401    XYpt        cpt   = data->center();
00402    XYvec      delta(te-tp);
00403    double     ratio;
00404 
00405 
00406 
00407    if(_travel)
00408       {
00409    
00410          
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450          _travel = false;
00451       }
00452    else
00453       {
00454          
00455 
00456          Wpt     spt  (XYpt(tp[0],te[1]));
00457          Wvec    svec (spt - Wline(data->from(), data->at_v()).project(spt));
00458 
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             
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