arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

ManipEvents.cpp

Go to the documentation of this file.
00001 ///////////////////////////////////////////////////////////////////////////
00002 //              _____________  ______________________    __   __  _____
00003 //             /  ________  |  |   ___   ________   /   |  \ /  \   |
00004 //            |  |       |  |_ |  |_ |  |       /  /    \__  |      |
00005 //            |  |  ___  |  || |  || |  |      /  /        | |      |
00006 //            |  | |   \ |  || |  || |  |     /  /      \__/ \__/ __|__
00007 //            |  | |_@  ||  || |  || |  |    /  /          Institute
00008 //            |  |___/  ||  ||_|  || |  |   /  /_____________________
00009 //             \_______/  \______/ | |__|  /___________________________
00010 //                        |  |__|  |
00011 //                         \______/
00012 //                    University of Utah       
00013 //                           2003
00014 ///////////////////////////////////////////////////////////////////////////
00015 
00016 //ManipEvents.cpp
00017 // Joe Kniss
00018 
00019 
00020 #include "ManipEvents.h"
00021 #include "../eventGutz/mouseEvent.h"
00022 #include <iostream>
00023 
00024 const float defaultRad = .8f;
00025 
00026 using namespace gutz;
00027 using namespace std;
00028 
00029 ///////////////////////////////////////////////////////////////////////////
00030 ///////////////////////////////////////////////////////////////////////////
00031 /// RotateManipEvent
00032 ///////////////////////////////////////////////////////////////////////////
00033 ///////////////////////////////////////////////////////////////////////////
00034 
00035 bool RotateManipEvent::startEvent(Manip *m, const MouseEvent &me)
00036 {
00037    if(me.isButtonDown())
00038    {
00039       _rad = m->getRad(me);
00040       _tumbquat = quatf_id;
00041    }
00042    return true;
00043 }
00044 
00045 bool RotateManipEvent::handleEvent(Manip *m, const MouseMoveEvent &mme)
00046 {
00047    vec2f pt1 = mme.getLast();
00048    vec2f pt2 = mme.getPos();
00049    /// compute the projection of the center onto the screen
00050    vec3f scrC = m->getScreenPosLocal(m->getCenter());
00051    /// flip the y position of screen center
00052    scrC.y = m->getScreenY() - scrC.y;
00053 
00054    /// offset screen center to the objects center projected to the screen,
00055    /// and scale-bias so that we are in the [-1,1] range
00056    pt1.x =   (pt1.x - scrC.x) * 2.0f/float(m->getScreenX());
00057    pt1.y =   -(pt1.y - scrC.y) * 2.0f/float(m->getScreenY());
00058    pt2.x =   (pt2.x - scrC.x) * 2.0f/float(m->getScreenX());
00059    pt2.y =   -(pt2.y - scrC.y) * 2.0f/float(m->getScreenY());
00060 
00061    quatf tmpquat = trackball(pt1, pt2, _rad);     //quat for small rotation
00062    tmpquat.normalize();
00063 
00064    /// set the trackquat, for tumble
00065    _tumbquat = m->getInvCamQuat().mult( tmpquat.mult( m->getCamQuat() ) );
00066    _tumbquat.normalize();
00067    m->setCenterQuat( _tumbquat.mult( m->getCenterQuat() ) );
00068  
00069   return true;
00070 }
00071 
00072 void RotateManipEvent::endEvent(Manip *m, const MouseEvent &me)
00073 {
00074   _tumbquat = quatf_id;
00075 }
00076 
00077 /// really this should keep a time signature an scale based on that
00078 bool RotateManipEvent::tumble(Manip *m)
00079 {
00080    if( g_abs(_tumbquat[3]) > .9999 ) return false;
00081 
00082    //reset the track quaternion to the right speed
00083    float thet = _tumbquat[3];
00084    thet = acos(thet);
00085    vec3f axis(_tumbquat[0]/sin(thet),
00086               _tumbquat[1]/sin(thet),
00087               _tumbquat[2]/sin(thet));
00088    thet*=_speed*2;
00089    quatf tumb(thet, axis);
00090 
00091    m->setCenterQuat( tumb.mult( m->getCenterQuat() ) ); 
00092    return true;
00093 }
00094 
00095 ///////////////////////////////////////////////////////////////////////////
00096 ///////////////////////////////////////////////////////////////////////////
00097 /// TransXYManipEvent
00098 ///////////////////////////////////////////////////////////////////////////
00099 ///////////////////////////////////////////////////////////////////////////
00100 
00101 bool TransXYManipEvent::startEvent(Manip *m, const MouseEvent &me)
00102 {
00103    if(me.isButtonDown())
00104    {
00105       _lastTrans = vec3f_zero;
00106    }
00107    return true;
00108 }
00109 
00110 vec3f TransXYManipEvent::getDelta(Manip *m, const MouseMoveEvent &mme) const
00111 {
00112    vec3f delta;
00113 
00114    if(mme.z() == 0 && m->getParent()) /// didn't have a picked point
00115    {
00116       /// use ray-plane intersection to compute the delta vector
00117       /// get the ray through the screen points (curr&last) from the eye
00118       const vec3f lastDir = m->getParent()->getLocalEyeRayScreen(mme.getLast());
00119       const vec3f currDir = m->getParent()->getLocalEyeRayScreen(mme.getPos());
00120       const vec3f lastPoint = m->getParent()->getLocalPosScreen(mme.getLast());
00121       const vec3f currPoint = m->getParent()->getLocalPosScreen(mme.getPos());
00122       /// intersect rays with plane at our local position oriented with view direction
00123       const float tl = 
00124          intersectRayPlane(lastPoint,lastDir,
00125                            m->getLocalPos(),m->getParent()->getLocalViewDir());
00126       const float tc = 
00127          intersectRayPlane(currPoint,currDir,
00128                            m->getLocalPos(),m->getParent()->getLocalViewDir());
00129       /// compute delta based on the current & last intersections
00130       // delta = current point - last
00131       // current point = curren point + tc * current direction vector (ray equation)
00132       delta = (currPoint + tc * currDir) - (lastPoint + tl * lastDir);
00133    }
00134    else if(m->getParent()) /// we DID have a valid pick point
00135    {
00136       /// therfore the points from the event just need to be translated to
00137       ///  our (parents) LOCAL space
00138       delta = m->getParent()->getLocalPosScreen(mme.getPos())
00139               - m->getParent()->getLocalPosScreen(mme.getLast());
00140    }
00141    else /// else we didn't have a parent, we just have to use the points...
00142    {
00143       delta = mme.getPos() - mme.getLast();
00144    }
00145    return delta;
00146 }
00147 
00148 
00149 bool TransXYManipEvent::handleEvent(Manip *m, const MouseMoveEvent &mme)
00150 {
00151 
00152    _lastTrans = getDelta(m, mme);
00153    m->setLocalPos( m->getLocalPos() + _lastTrans );
00154 
00155    return true;
00156 }
00157 
00158 void TransXYManipEvent::endEvent(Manip *m, const MouseEvent &me)
00159 {
00160    _lastTrans = vec3f_zero;
00161 }
00162 
00163 bool TransXYManipEvent::tumble(Manip *m)
00164 {
00165    if( _lastTrans == vec3f_zero ) return false;
00166    m->setLocalPos( m->getLocalPos() + _lastTrans * _speed );
00167    return true;
00168 }
00169 
00170 ///////////////////////////////////////////////////////////////////////////
00171 ///////////////////////////////////////////////////////////////////////////
00172 /// TransZManipEvent
00173 ///////////////////////////////////////////////////////////////////////////
00174 ///////////////////////////////////////////////////////////////////////////
00175 
00176 bool TransZManipEvent::handleEvent(Manip *m, const MouseMoveEvent &mme)
00177 {
00178    _lastTrans = getDelta(m, mme);
00179    float del = _lastTrans.norm();
00180    if( (-mme.dx() + mme.dy()) > 0.0f ) del = -del;
00181    vec3f vdir = vec3f_z;
00182    if(m->getParent()) vdir = m->getParent()->getLocalViewDir();
00183    _lastTrans = vdir * del;
00184    m->setLocalPos( m->getLocalPos() + _lastTrans );
00185    return true;
00186 }
00187 
00188 ///////////////////////////////////////////////////////////////////////////
00189 ///////////////////////////////////////////////////////////////////////////
00190 /// TransZManipEvent
00191 ///////////////////////////////////////////////////////////////////////////
00192 ///////////////////////////////////////////////////////////////////////////
00193 
00194 bool TransPlaneManipEvent::startEvent(Manip *m, const MouseEvent &me)
00195 {
00196    if( _pnorm == vec3f_zero ) return false;
00197 
00198    if(me.isButtonDown())
00199    {
00200       if(me.z())
00201       {
00202          _start = me.getWorldPos();
00203       }
00204       else
00205       {
00206          _start = _ppos;
00207       }
00208       _lastTrans = vec3f_zero;
00209    }
00210    return true;
00211 }
00212 
00213 
00214 bool TransPlaneManipEvent::handleEvent(Manip *m, const MouseMoveEvent &mme)
00215 {
00216    vec3f lpos = mme.getLast();
00217    vec3f cpos = mme.getPos();
00218    vec3f lray = mme.getLast();
00219    vec3f cray = mme.getPos();
00220    vec3f ppos =  _start;
00221    vec3f pnorm = _pnorm;
00222    if( m->getParent() )
00223    {
00224       lpos  = m->getParent()->getLocalPosScreen( lpos );
00225       cpos  = m->getParent()->getLocalPosScreen( cpos );
00226       lray  = m->getParent()->getLocalEyeRayScreen( lray );
00227       cray  = m->getParent()->getLocalEyeRayScreen( cray );
00228       ppos  = m->getParent()->getLocalPosWorld( ppos );
00229       pnorm = m->getParent()->getLocalDirWorld( pnorm );
00230    }
00231 
00232    float tl = gutz::intersectRayPlane(lpos,lray,ppos,pnorm);
00233    float tc = gutz::intersectRayPlane(cpos,cray,ppos,pnorm);
00234 
00235    _lastTrans = ( cpos + cray * tc ) - ( lpos + lray * tl );
00236 
00237    m->setLocalPos( m->getLocalPos() + _lastTrans );
00238 
00239    return true;
00240 }

Send questions, comments, and bug reports to:
jmk