00001 #include "disp/ray.H"
00002 #include "geom/world.H"
00003 #include "gtex/smooth_shade.H"
00004 #include "mesh/lmesh.H"
00005 #include "std/time.H"
00006
00007 #include "manip/cam_pz.H"
00008
00009 using namespace mlib;
00010
00011 static double DOT_DIST = 0.012;
00012
00013 ARRAY<CamIcon *> CamIcon::_icons;
00014 CamIcon *CamIcon::_orig_icon;
00015
00016 CamIcon *
00017 CamIcon::intersect_all(CXYpt &pt)
00018 {
00019 CamIcon *icon = 0;
00020 for (int i = 0; !icon && i < _icons.num(); i++)
00021 if (_icons[i]->intersect_icon(pt))
00022 icon = _icons[i];
00023 return icon;
00024 }
00025
00026
00027
00028
00029
00030
00031 MAKE_PTR_SUBC(CAMwidget_anchor, GEOM);
00032 class CAMwidget_anchor : public GEOM {
00033 public:
00034 CAMwidget_anchor() : GEOM() {
00035
00036 LMESHptr mesh = new LMESH();
00037
00038
00039 mesh->set_geom(this);
00040
00041
00042 mesh->Icosahedron();
00043 mesh->refine();
00044
00045
00046
00047 mesh->set_render_style(SmoothShadeTexture::static_name());
00048
00049
00050 mesh->patch(0)->set_color(COLOR(0.1, 0.1, 0.9));
00051
00052
00053
00054 _body = mesh;
00055
00056 set_name("CAMwidget_anchor");
00057 }
00058
00059
00060 virtual int draw_vis_ref() { return 0; }
00061
00062 virtual bool needs_blend() const { return false; }
00063 };
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 Cam_int::Cam_int(
00090 CEvent &down_ev,
00091 CEvent &move_ev,
00092 CEvent &up_ev,
00093
00094 CEvent &down2_ev,
00095 CEvent &up2_ev,
00096
00097 CEvent &rot_down_ev,
00098 CEvent &trans_down_ev,
00099 CEvent &zoom_down_ev,
00100
00101 CEvent &rot_up_ev,
00102 CEvent &trans_up_ev,
00103 CEvent &zoom_up_ev
00104 )
00105 {
00106 _cam_rot += Arc(move_ev, Cb(&Cam_int::rot));
00107 _cam_rot += Arc(up_ev, Cb(&Cam_int::up, (State *)-1));
00108 _cam_rot += Arc(up2_ev, Cb(&Cam_int::up, (State *)-1));
00109 _cam_pan += Arc(move_ev, Cb(&Cam_int::pan));
00110 _cam_pan += Arc(up_ev, Cb(&Cam_int::up, (State *)-1));
00111 _cam_pan += Arc(down2_ev,Cb(&Cam_int::noop, &_cam_rot));
00112 _cam_zoom += Arc(move_ev, Cb(&Cam_int::zoom));
00113 _cam_zoom += Arc(up_ev, Cb(&Cam_int::up, (State *)-1));
00114 _cam_zoom += Arc(down2_ev,Cb(&Cam_int::noop, &_cam_rot));
00115 _cam_choose += Arc(down2_ev,Cb(&Cam_int::noop, &_cam_rot));
00116 _cam_choose += Arc(move_ev, Cb(&Cam_int::choose));
00117 _cam_choose += Arc(up_ev, Cb(&Cam_int::up, (State *)-1));
00118 _cam_drag += Arc(move_ev, Cb(&Cam_int::drag, &_cam_drag));
00119 _cam_drag += Arc(up_ev, Cb(&Cam_int::dragup,(State *)-1));
00120
00121 _move_view += Arc(move_ev, Cb(&Cam_int::move, &_move_view));
00122 _move_view += Arc(up_ev, Cb(&Cam_int::moveup, (State *)-1));
00123 _icon_click += Arc(move_ev, Cb(&Cam_int::iconmove, &_icon_click));
00124 _icon_click += Arc(up_ev, Cb(&Cam_int::iconup, (State *)-1));
00125
00126 _entry += Arc(down_ev, Cb(&Cam_int::down, &_cam_choose));
00127 _entry += Arc(down2_ev, Cb(&Cam_int::down2));
00128
00129
00130 _but_trans += Arc(move_ev , Cb(&Cam_int::pan2, &_but_trans));
00131 _but_trans += Arc(trans_up_ev , Cb(&Cam_int::noop, (State *)-1));
00132 _but_rot += Arc(move_ev , Cb(&Cam_int::rot2, &_but_rot));
00133 _but_rot += Arc(rot_up_ev , Cb(&Cam_int::noop, (State *)-1));
00134 _but_zoom += Arc(move_ev , Cb(&Cam_int::zoom2, &_but_zoom));
00135 _but_zoom += Arc(zoom_up_ev , Cb(&Cam_int::noop, (State *)-1));
00136
00137
00138
00139
00140
00141
00142 _entry2 += Arc(trans_down_ev, Cb(&Cam_int::predown,&_but_trans));
00143 _entry2 += Arc(rot_down_ev, Cb(&Cam_int::predown,&_but_rot));
00144 _entry2 += Arc(zoom_down_ev, Cb(&Cam_int::predown,&_but_zoom));
00145 }
00146
00147 Cam_int::CAMwidget::CAMwidget():_a_displayed(0)
00148 {
00149 _anchor = new CAMwidget_anchor;
00150 _anchor->set_pickable(0);
00151 NETWORK.set(_anchor, 0);
00152 CONSTRAINT.set(_anchor, GEOM::SCREEN_WIDGET);
00153 WORLD::create (_anchor, false);
00154 WORLD::undisplay(_anchor, false);
00155 }
00156
00157 void
00158 Cam_int::CAMwidget::undisplay_anchor()
00159 {
00160 WORLD::undisplay(_anchor, false);
00161 _a_displayed=0;
00162 }
00163
00164 void
00165 Cam_int::CAMwidget::display_anchor(
00166 CWpt &p
00167 )
00168 {
00169 WORLD::display(_anchor, false);
00170 _a_displayed = 1;
00171
00172 Wvec delt(p-Wpt(XYpt(p)+XYvec(VEXEL(5,5)), p));
00173 Wtransf ff = Wtransf(p) * Wtransf::scaling(delt.length());
00174 _anchor->set_xform(Wtransf(p) * Wtransf::scaling(1.5*delt.length()));
00175 }
00176
00177 void
00178 Cam_int::CAMwidget::drag_anchor(
00179 CXYpt &p2d
00180 )
00181 {
00182 Wpt apos(_anchor->xform().origin());
00183 Wpt p (Wplane(apos,Wvec(XYpt())).intersect(p2d));
00184 double rad = (p-apos).length();
00185 Wtransf ff = Wtransf(apos) * Wtransf::scaling(rad);
00186 _anchor->set_xform(Wtransf(apos) * Wtransf::scaling(rad));
00187 }
00188
00189 int
00190 Cam_int::predown(
00191 CEvent &e,
00192 State *&
00193 )
00194 {
00195
00196 CamFocus::cancel_cur();
00197
00198 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00199 DEVice_2d *ptr = btns->ptr2d();
00200
00201 _view = e.view();
00202
00203 _do_reset = 0;
00204 _dtime = the_time();
00205 _dist = 0;
00206 _scale_pt = ptr->cur();
00207 _start_pix= ptr->cur();
00208
00209 CAMdataptr data(_view->cam()->data());
00210 RAYhit r (_view->intersect(ptr->cur()));
00211 if (r.success()) {
00212 double dist = r.dist();
00213 _down_pt = r.point() + dist * r.vec();
00214 } else {
00215 _down_pt = Wplane(data->center(),data->at_v()).intersect(ptr->cur());
00216 }
00217 _down_pt_2d = _down_pt;
00218
00219
00220
00221 data->start_manip();
00222 return 0;
00223 }
00224
00225 int
00226 Cam_int::down(
00227 CEvent &e,
00228 State *&s
00229 )
00230 {
00231 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00232 DEVice_2d *ptr = btns->ptr2d();
00233 VIEWptr view(e.view());
00234 int is_dot = _camwidg.anchor_displayed();
00235 int x, y; view->get_size(x,y);
00236 PIXEL curpix(ptr->cur());
00237 XYpt curpt (curpix[0]/x*2-1, curpix[1]/y*2-1);
00238
00239 predown(e,s);
00240
00241
00242
00243
00244 CamIcon *icon = CamIcon::intersect_all(ptr->cur());
00245 if (icon) {
00246
00247
00248
00249 _icon = icon;
00250 switch (icon->test_down(e, s)) {
00251 case CamIcon::RESIZE : _resizing = true;
00252 case CamIcon::FOCUS : s = &_icon_click;
00253 brcase CamIcon::MOVE : {
00254 s = &_move_view;
00255 return move(e, s);
00256 }
00257 }
00258 return 0;
00259 } else
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 if ((fabs(curpt[0]) > .85 || fabs(curpt[1]) > .9) || is_dot) {
00271 if (is_dot)
00272 view->cam()->data()->set_center(_camwidg.anchor_wpt());
00273 _do_reset = is_dot;
00274
00275 if(!is_dot){
00276
00277 VIEWptr view(e.view());
00278 view->save_cam();
00279 }
00280
00281 s = &_cam_rot;
00282 return 0;
00283 }
00284
00285 return 0;
00286 }
00287
00288
00289 int
00290 Cam_int::down2(
00291 CEvent &e,
00292 State *&s
00293 )
00294 {
00295 DEVice_buttons *btns = (DEVice_buttons *)e._d;
00296 DEVice_2d *ptr = btns->ptr2d();
00297
00298 _view = e.view();
00299
00300 CAMdataptr data(_view->cam()->data());
00301 RAYhit r (_view->intersect(ptr->cur()));
00302 if (r.success()) {
00303 if(r.geom()->name() == "eye_button")
00304 {
00305 s = (State *)-1;
00306 BaseJOTapp::cam_switch(e,s);
00307 }
00308 }
00309 return 0;
00310 }
00311
00312
00313 int
00314 Cam_int::choose(
00315 CEvent &e,
00316 State *&s
00317 )
00318 {
00319 DEVice_2d *ptr =(DEVice_2d *)e._d;
00320 PIXEL te (ptr->cur());
00321 XYvec delta(ptr->delta());
00322 double tdelt(the_time() - _dtime);
00323
00324 _dist += sqrt(delta * delta);
00325
00326 VEXEL sdelt(te - _start_pix);
00327
00328 int xa=0,ya=1;
00329 if (Config::get_var_bool("FLIP_CAM_MANIP",false,true))
00330 swap(xa,ya);
00331
00332 if (fabs(sdelt[ya])/sdelt.length() > 0.9 && tdelt > 0.05) {
00333 s = &_cam_zoom;
00334 ptr->set_old(_start_pix);
00335 } else if (tdelt < 0.1 && _dist < 0.03)
00336 return 0;
00337 else {
00338 if (fabs(sdelt[xa])/sdelt.length() > 0.6 )
00339 s = &_cam_pan;
00340 else s = &_cam_zoom;
00341 ptr->set_old(_start_pix);
00342 }
00343 VIEWptr view(e.view());
00344 view->save_cam();
00345
00346 return 0;
00347 }
00348
00349 int
00350 Cam_int::drag(
00351 CEvent &e,
00352 State *&s
00353 )
00354 {
00355 DEVice_2d *ptr=(DEVice_2d *)e._d;
00356 PIXEL curpt(ptr->cur());
00357
00358
00359 if ((curpt - _start_pix).length() > 20 &&
00360 (curpt - _start_pix).normalized() * VEXEL(1,1).normalized() > 0.5) {
00361 make_view(ptr->cur());
00362 s = &_move_view;
00363 return move(e, s);
00364 }
00365 if ((curpt - _start_pix).length() > 20 &&
00366 (curpt - _start_pix).normalized() * VEXEL(-1,-1).normalized() > 0.5)
00367 _camwidg.drag_anchor(_camwidg.anchor_pos());
00368 else _camwidg.drag_anchor(ptr->cur());
00369
00370 return 0;
00371 }
00372
00373 int
00374 Cam_int::zoom2(
00375 CEvent &e,
00376 State *&
00377 )
00378 {
00379 DEVice_2d *ptr = (DEVice_2d *)e._d;
00380 CAMptr cam (e.view()->cam());
00381 PIXEL curpt (ptr->cur());
00382 XYpt startpt(_start_pix);
00383 int w,h; e.view()->get_size(w,h);
00384
00385 double zoom_factor = 1 + Sign(ptr->delta()[0]) *
00386 (PIXEL(ptr->cur())-PIXEL(ptr->old())).length()/(w/4);
00387
00388 cam->set_zoom(cam->zoom() * zoom_factor);
00389 cam->set_min (cam->min() + NDCvec(XYpt(_start_pix) - startpt));
00390
00391 ptr->set_cur(curpt);
00392 cam->data()->changed();
00393
00394 return 0;
00395 }
00396
00397 int
00398 Cam_int::rot2(
00399 CEvent &e,
00400 State *&
00401 )
00402 {
00403 CAMptr cam(e.view()->cam());
00404
00405 cam->set_zoom(1);
00406 cam->set_min(NDCpt(XYpt(-1,-1)));
00407 cam->data()->changed();
00408
00409 return 0;
00410 }
00411
00412 int
00413 Cam_int::pan2(
00414 CEvent &e,
00415 State *&
00416 )
00417 {
00418 DEVice_2d *ptr=(DEVice_2d *)e._d;
00419 CAMptr cam (e.view()->cam());
00420 PIXEL curpt(ptr->cur());
00421
00422 cam->set_min(cam->min() + NDCvec(ptr->delta()));
00423 cam->data()->changed();
00424 ptr->set_cur(curpt);
00425 return 0;
00426 }
00427
00428 int
00429 Cam_int::pan(
00430 CEvent &e,
00431 State *&
00432 )
00433 {
00434 DEVice_2d *ptr=(DEVice_2d *)e._d;
00435 CAMptr cam (e.view()->cam());
00436 CAMdataptr data (cam->data());
00437 Wvec delta(Wpt(ptr->cur(),_down_pt) - Wpt(ptr->old(),_down_pt));
00438
00439 data->translate(-delta);
00440 data->set_at(Wline(data->from(), data->at_v()).project(_down_pt));
00441 data->set_center(data->at());
00442 return 0;
00443 }
00444
00445 int
00446 Cam_int::zoom(
00447 CEvent &e,
00448 State *&
00449 )
00450 {
00451 DEVice_2d *ptr=(DEVice_2d *)e._d;
00452 CAMptr cam (e.view()->cam());
00453 CAMdataptr data (cam->data());
00454 XYvec delta(ptr->delta());
00455 double ratio;
00456
00457 if (data->persp()) {
00458 Wvec movec(_down_pt - data->from());
00459
00460 data->set_center(_down_pt);
00461 data->translate(movec.normalized() * (movec.length() * delta[1] * -4));
00462
00463 ratio = cam->height() / cam->width() *
00464 (movec * data->at_v()) * data->width() / data->focal();
00465
00466 } else {
00467 Wpt spt (XYpt(ptr->cur()[0],_scale_pt[1]));
00468 Wvec svec (spt - Wline(data->from(), data->at_v()).project(spt));
00469 double sfact(1 + delta[1]);
00470 data->translate( svec * (1.0 - sfact));
00471 data->set_width (data->width() * sfact);
00472 data->set_height(data->height()* sfact);
00473 ratio = data->height();
00474 }
00475
00476 data->translate(-delta[0]/2 * data->right_v() * ratio);
00477 data->set_at(Wline(data->from(), data->at_v()).project(data->center()));
00478 data->set_center(data->at());
00479
00480
00481 return 0;
00482 }
00483
00484 int
00485 Cam_int::rot(
00486 CEvent &e,
00487 State *&
00488 )
00489 {
00490 CAMptr cam (e.view()->cam());
00491 CAMdataptr data(cam->data());
00492 DEVice_2d *ptr=(DEVice_2d *)e._d;
00493
00494 cam->set_zoom(1);
00495 cam->set_min(NDCpt(XYpt(-1,-1)));
00496 cam->data()->changed();
00497
00498 XYpt cpt = data->center();
00499 double radsq = sqr(1+fabs(cpt[0]));
00500 XYpt tp = ptr->old();
00501 XYpt te = ptr->cur();
00502
00503 Wvec op (tp[0], 0, 0);
00504 Wvec oe (te[0], 0, 0);
00505 double opsq = op * op, oesq = oe * oe;
00506 double lop = opsq > radsq ? 0 : sqrt(radsq - opsq);
00507 double loe = oesq > radsq ? 0 : sqrt(radsq - oesq);
00508 Wvec nop = Wvec(op[0], 0, lop).normalized();
00509 Wvec noe = Wvec(oe[0], 0, loe).normalized();
00510 double dot = nop * noe;
00511
00512 if (fabs(dot) > 0.0001) {
00513 data->rotate(Wline(data->center(), Wvec::Y()),
00514 -2*Acos(dot) * Sign(te[0]-tp[0]));
00515
00516 Wvec dvec = data->from() - data->center();
00517 double rdist = te[1]-tp[1];
00518
00519
00520 CAMdata dd = CAMdata(*data);
00521
00522 Wline raxe(data->center(),data->right_v());
00523 data->rotate(raxe, rdist);
00524 data->set_up(data->from() + Wvec::Y());
00525 if (data->right_v() * dd.right_v() < 0)
00526 *data = dd;
00527 }
00528
00529 return 0;
00530 }
00531
00532 inline void
00533 print_gel(GEL* gel)
00534 {
00535 if (gel)
00536 cerr << ": " << gel->class_name();
00537 cerr << endl;
00538 }
00539
00540 int
00541 Cam_int::focus(
00542 CEvent &e,
00543 State *&
00544 )
00545 {
00546 GEOM::find_cam_focus(e.view(), DEVice_2d::last->cur());
00547 return 0;
00548 }
00549
00550 int
00551 Cam_int::move(
00552 CEvent &e,
00553 State *&
00554 )
00555 {
00556 if (_icon) _icon->set_icon_loc(((DEVice_2d *)e._d)->cur());
00557 return 0;
00558 }
00559
00560 int
00561 Cam_int::moveup(
00562 CEvent &,
00563 State *&
00564 )
00565 {
00566 for (int i = 0; i < _up_obs.num(); i++)
00567 _up_obs[i]->reset(_do_reset);
00568 _geom = 0;
00569 _icon = 0;
00570 return 0;
00571 }
00572
00573 int
00574 Cam_int::iconmove(
00575 CEvent &e,
00576 State *&s
00577 )
00578 {
00579 if (_resizing) return _icon->icon_move(e, s);
00580 return 0;
00581 }
00582
00583 int
00584 Cam_int::iconup(
00585 CEvent &e,
00586 State *&s
00587 )
00588 {
00589 if (_resizing) {
00590 _resizing = false;
00591 const int retval = _icon->resize_up(e, s);
00592 _icon = 0;
00593 return retval;
00594 }
00595 DEVice_buttons *btns=(DEVice_buttons *)e._d;
00596 DEVice_2d *ptr=btns->ptr2d();
00597 PIXEL curpt(ptr->cur());
00598
00599
00600 if (the_time() - _dtime < 0.25 && _icon &&
00601 (curpt - _start_pix).length() > 20 &&
00602 (curpt - _start_pix).normalized() * VEXEL(1,1).normalized() > 0.5) {
00603 _icon->remove_icon();
00604 _icon = 0;
00605 return 0;
00606 }
00607
00608 if (_icon->intersect_icon(ptr->cur())) {
00609 new CamFocus(e.view(), _icon->cam());
00610 }
00611 return 0;
00612 }
00613
00614 int
00615 Cam_int::dragup(
00616 CEvent &e,
00617 State *&s
00618 )
00619 {
00620 DEVice_buttons *btns=(DEVice_buttons *)e._d;
00621 DEVice_2d *ptr=btns->ptr2d();
00622 VIEWptr view(e.view());
00623 CAMptr cam (view->cam());
00624 PIXEL curpt(ptr->cur());
00625
00626 double elapsed = the_time() - _dtime;
00627
00628 if (ptr->cur().dist(_camwidg.anchor_pos()) < DOT_DIST && elapsed < 0.25)
00629 return up(e,s);
00630
00631 reset(1);
00632
00633 for (int i = 0; i < _up_obs.num(); i++)
00634 _up_obs[i]->reset(_do_reset);
00635
00636 if ((curpt - _start_pix).length() > 20 &&
00637 (curpt - _start_pix).normalized() * VEXEL(-1,0).normalized() > 0.5)
00638 return 0;
00639
00640 RAYhit ray(view->intersect(_camwidg.anchor_pos()));
00641 if (!ray.success())
00642 return 0;
00643
00644 CAMdataptr data(cam->data());
00645 double dist = _camwidg.anchor_size() * 2*data->focal()/data->height();
00646 Wvec dirvec((data->from() - ray.surf()).normalized());
00647
00648 Wpt from = ray.surf() + dist * dirvec;
00649 new CamFocus(view,
00650 from,
00651 ray.surf(),
00652 from + Wvec::Y(),
00653 ray.surf(),
00654 data->width(), data->height());
00655
00656 return 0;
00657 }
00658
00659 int
00660 Cam_int::up(
00661 CEvent &e,
00662 State *&s
00663 )
00664 {
00665 DEVice_buttons *btns=(DEVice_buttons *)e._d;
00666 DEVice_2d *ptr=btns->ptr2d();
00667 VIEWptr view(e.view());
00668 CAMptr cam (view->cam());
00669
00670 for (int i = 0; i < _up_obs.num(); i++)
00671 _up_obs[i]->reset(_do_reset);
00672
00673 if (_camwidg.anchor_displayed()) {
00674 if (ptr->cur().dist(_camwidg.anchor_pos()) < DOT_DIST)
00675 focus(e,s);
00676 reset(1);
00677 } else if (ptr->cur().dist(_down_pt_2d) < DOT_DIST) {
00678 RAYhit ray(view->intersect(ptr->cur()));
00679 if (ray.success()) {
00680
00681 _camwidg.display_anchor(ray.surf());
00682
00683 BMESHptr m = gel_to_bmesh(ray.geom());
00684 if (m)
00685 BMESH::set_center_of_interest(m);
00686 } else {
00687 Wplane hitp(cam->data()->center(), cam->data()->at_v());
00688 _camwidg.display_anchor(hitp.intersect(ray.screen_point()));
00689 }
00690 }
00691 cam->data()->end_manip();
00692 return 0;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702 void
00703 Cam_int::reset(int rst)
00704 {
00705 if (rst)
00706 _camwidg.undisplay_anchor();
00707 }
00708
00709
00710 void
00711 Cam_int::make_view(
00712 CXYpt &curpt
00713 )
00714 {
00715
00716 _icon = CamIcon::create(curpt, _view->cam());
00717 _geom = 0;
00718
00719 reset(1);
00720 }