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

cam_pz.C

Go to the documentation of this file.
00001 #include "disp/ray.H"
00002 #include "geom/world.H"
00003 #include "gtex/smooth_shade.H"  // used in CAMwidget_anchor
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; // cheesy XY-space distance threshold
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  * CAMwidget_anchor:
00028  *
00029  *      Class used for those blue "camera balls"
00030  *****************************************************************/
00031 MAKE_PTR_SUBC(CAMwidget_anchor, GEOM);
00032 class CAMwidget_anchor : public GEOM {
00033  public:
00034    CAMwidget_anchor() : GEOM() {
00035       // Start with an empty LMESH:
00036       LMESHptr mesh = new LMESH();
00037 
00038       // Ensure mesh knows its containing GEOM:
00039       mesh->set_geom(this);
00040 
00041       // Make a ball shape
00042       mesh->Icosahedron();
00043       mesh->refine();           // smooth it once
00044 
00045       // Regardless of current rendering mode,
00046       // always use Gouraud shading:
00047       mesh->set_render_style(SmoothShadeTexture::static_name());
00048 
00049       // Color the Patch blue:
00050       mesh->patch(0)->set_color(COLOR(0.1, 0.1, 0.9));
00051 //      mesh->patch(0)->set_transp(0.9);
00052 
00053       // Store the mesh:
00054       _body = mesh;
00055 
00056       set_name("CAMwidget_anchor");
00057    }
00058 
00059    // We're not in the picking game:
00060    virtual int draw_vis_ref() { return 0; }
00061 
00062    virtual bool needs_blend() const { return false; }
00063 };
00064 
00065 /*****************************************************************
00066  *
00067  *  Cam_int : the camera interactor
00068  *
00069  *   The camera interactor is an FSA that allows the camera to
00070  * be translated, zoomed, and rotated.  The FSA has 4 states
00071  * corresponding to 
00072  *   a "virtual cylinder" rotation state - _cam_rot,
00073  *   a camera panning translation state  - _cam_pan,
00074  *   a camera zooming translation state  - _cam_zoom,  and
00075  *   a "choosing" state in which the interactor tries 
00076  *     to choose between zooming and panning. 
00077  *
00078  *  _entry -> _cam_rot
00079  *            _cam_choose -> _cam_pan
00080  *                                    -> _cam_zoom
00081  * The interactor is initiated when one of the _entry arcs  
00082  * occurs.  The primary entry event calls the down() function which 
00083  * determines if the camera should transtion to the rotation state 
00084  * or the choosing state.  The secondary entry event always 
00085  * transitions to the rotation state (this second event is often
00086  * connected to a dedicated camera rotation trackball).
00087  *
00088  *****************************************************************/
00089 Cam_int::Cam_int(
00090    CEvent    &down_ev,
00091    CEvent    &move_ev, 
00092    CEvent    &up_ev,   // 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 //     _phys       += Arc(trans_up_ev  , Cb(&Cam_int::physup, (State *)-1));
00138 //     _phys       += Arc(move_ev      , Cb(&Cam_int::physmove));
00139 
00140 // XXX - ?
00141 //   _entry2     += Arc(trans_down_ev, Cb(&Cam_int::physdown,&_phys));
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); // Don't allow picking of anchor
00151    NETWORK.set(_anchor, 0);// Don't network the anchor
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    // de-activate current CamFocus, if any:
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    //Notify all the CAMobs's of the start of mouse down
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    // Did we click on a camera icon?
00244    CamIcon *icon = CamIcon::intersect_all(ptr->cur()); 
00245    if (icon) {
00246 
00247       // XXX - fix
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    // if someone has already clicked to make a dot, and is now clicking
00261    // on that same dot, we want to drag out a zoom region.
00262      // alexni 11/9/03, disabled this since it definitely has some problems working correctly
00263      /*
00264    if (is_dot && (ptr->cur().dist(_camwidg.anchor_pos()) < DOT_DIST)) {
00265       s = &_cam_drag;
00266       return 0;
00267    } // if someone has already clicked to make a dot and they're not clicking 
00268      // on it now, OR if the user is clicking on the perimeter of the screen, 
00269      // then we want to go into rotation mode.
00270    else */ 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    /*alexni- is there a better way to handle this?  we want to save the camera if we're going to enter a mode that causes change to the camera */
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 //left-click:test for any buttons used in this camera mode
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    /* if we got this far, we actually have a valid choice, so save the camera */   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    // Switch to different fsa?
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])); // squared rad of virtual cylinder
00500    XYpt        tp    = ptr->old(); 
00501    XYpt        te    = ptr->cur();
00502 
00503    Wvec   op  (tp[0], 0, 0);             // get start and end X coordinates
00504    Wvec   oe  (te[0], 0, 0);             //    of cursor motion
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 //      double tdist = Acos(Wvec::Y() * dvec.normalized());
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);  // reset everyone watching us
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    // Delete
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    // Are we close to the cam globe?
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);  // reset everyone watching us
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,                   // from
00651                 ray.surf(),             // at
00652                 from + Wvec::Y(),       // up
00653                 ray.surf(),             // center
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);  // reset everyone watching us
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          // Create the anchor (blue ball) on the surface:
00681          _camwidg.display_anchor(ray.surf());
00682          // If clicked on a mesh, make it the "center of interest":
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 // reset() - UP observer method
00697 //   Cam_int is an observer of 'UP' events on other objects.
00698 // In particular, Cam_int observes the 'UP' events of ObjManip
00699 // so that the Cam_int can clear its widget after an object
00700 // is dragged.
00701 //
00702 void
00703 Cam_int::reset(int rst)
00704 {
00705    if (rst)
00706       _camwidg.undisplay_anchor();
00707 }
00708 
00709 // Make a view (camera icon)
00710 void
00711 Cam_int::make_view(
00712    CXYpt  &curpt
00713    )
00714 {
00715    // Create new cam icon
00716    _icon = CamIcon::create(curpt, _view->cam());
00717    _geom = 0;
00718    
00719    reset(1);
00720 }

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