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