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

gfx/LookAtCameraManipulator.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: LookAtCameraManipulator.cpp 1030 2004-02-11 20:46:17Z jungd $
00019   $Revision: 1.6 $
00020   $Date: 2004-02-11 15:46:17 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <gfx/LookAtCameraManipulator>
00026 
00027 #include <base/Math>
00028 #include <base/Vector3>
00029 #include <base/Quat4>
00030 
00031 using gfx::LookAtCameraManipulator;
00032 
00033 using base::Math;
00034 using base::Vector3;
00035 using base::Quat4;
00036 
00037 
00038 #include <osgGA/TrackballManipulator>
00039 #include <osg/Notify>
00040 
00041 using namespace osg;
00042 using namespace osgGA;
00043 
00044 
00045 
00046 
00047 LookAtCameraManipulator::LookAtCameraManipulator(Real alpha, Real theta, Real d,
00048                                                  Real targetx, Real targety, Real targetz)
00049 {  
00050   halpha = Math::degToRad(alpha);
00051   htheta = Math::degToRad(theta);
00052   hd = Math::abs(d);
00053   target[0] = targetx;
00054   target[1] = targety;
00055   target[2] = targetz;
00056 }
00057 
00058 
00059 LookAtCameraManipulator::~LookAtCameraManipulator()
00060 {
00061 }
00062 
00063 
00064 void LookAtCameraManipulator::setNode(osg::Node*)
00065 {
00066 }
00067 
00068 
00069 const osg::Node* LookAtCameraManipulator::getNode() const
00070 {
00071     return 0;
00072 }
00073 
00074 
00075 osg::Node* LookAtCameraManipulator::getNode()
00076 {
00077     return 0;
00078 }
00079 /*
00080 void LookAtCameraManipulator::updateCamera(GUIActionAdapter& us)
00081 {
00082   _camera->setView(calcPos(), target, Vec3(0,0,1));
00083   _camera->ensureOrthogonalUpVector();
00084   us.requestRedraw();
00085 }
00086 */
00087 
00088 osg::Matrixd LookAtCameraManipulator::getMatrix() const
00089 {
00090   osg::Matrix m;
00091   m.makeLookAt(calcPos(), target, osg::Vec3(0,0,1));
00092   return m;
00093 }
00094                                                                                                                                                                                                                                             
00095 osg::Matrixd LookAtCameraManipulator::getInverseMatrix() const
00096 {
00097   return Matrixd::inverse(getMatrix());
00098 }
00099                                                                                                                                                             
00100 void LookAtCameraManipulator::setByMatrix(const osg::Matrixd& matrix)
00101 {
00102   osg::Vec3 eye, center, up;
00103   // bug workaround (getLookAt() should be a const method)
00104   osg::Matrixd m(matrix);
00105   m.getLookAt(eye, center, up,1.0f);
00106   target = center;
00107   d = (eye-center).length();
00108 }
00109 
00110 void LookAtCameraManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
00111 {
00112   Matrixd im( Matrixd::inverse(matrix) );
00113   setByMatrix(im);
00114 }
00115  
00116  
00117 
00118 
00119 void LookAtCameraManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
00120 {
00121   alpha = halpha;
00122   theta = htheta;
00123   d = hd;
00124 }
00125 
00126 
00127 void LookAtCameraManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
00128 {
00129 }
00130 
00131 
00132 bool LookAtCameraManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
00133 {
00134   switch(ea.getEventType())
00135     {
00136     case(GUIEventAdapter::PUSH): {
00137       x = ea.getX();
00138       y = ea.getY();
00139       ialpha = alpha;
00140       itheta = theta;
00141       id = d;
00142       itarget = target;
00143       us.requestContinuousUpdate(true);
00144       return true;
00145     } break;
00146       
00147     case(GUIEventAdapter::RELEASE):
00148       {
00149         us.requestContinuousUpdate(tracking);
00150         return true;
00151       }
00152       
00153     case(GUIEventAdapter::DRAG): {
00154       Int buttonMask = ea.getButtonMask();
00155 
00156       if (buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON) {
00157         Real dx = ea.getX() - x;
00158         Real dy = ea.getY() - y;
00159         alpha = ialpha - Math::degToRad(dx/8.0);
00160         if (alpha > 2*consts::Pi) alpha -= 2*consts::Pi;
00161         if (alpha < -2*consts::Pi) alpha += 2*consts::Pi;
00162         theta = itheta + Math::degToRad(dy/8.0);
00163         if (theta>Math::degToRad(89.9)) theta=Math::degToRad(89.9);
00164         if (theta<-Math::degToRad(89.9)) theta=-Math::degToRad(89.9);
00165         //updateCamera(us);
00166       }
00167       else if (buttonMask == GUIEventAdapter::RIGHT_MOUSE_BUTTON) {
00168         Real dy = ea.getY() - y;
00169         d = id + dy/100.0;
00170         if (d<0.1) d=0.1;
00171         //updateCamera(us);
00172       }
00173       else if (buttonMask == (GUIEventAdapter::LEFT_MOUSE_BUTTON | GUIEventAdapter::RIGHT_MOUSE_BUTTON)) {
00174         Real dx = ea.getX() - x;
00175         Real dy = ea.getY() - y;
00176         Vector3 slide(-dx/100.0,dy/100.0,0);
00177         Quat4 rotz(Vector3(0,0,1), alpha);
00178         slide = rotz.rotate(slide);
00179         Quat4 rotx(Vector3(1,0,0), -theta); 
00180         slide = rotx.rotate(slide);
00181         target[0] = itarget[0] - slide.x;
00182         target[1] = itarget[1] - slide.y;
00183         target[2] = itarget[2] - slide.z; 
00184         //updateCamera(us);
00185       }
00186     } break;
00187       
00188     case(GUIEventAdapter::MOVE): {
00189 
00190       return false;
00191     } break;
00192       
00193     case(GUIEventAdapter::KEYDOWN): {
00194       if (ea.getKey()==' ') {
00195         home(ea,us);
00196         us.requestContinuousUpdate(tracking);
00197         return true;
00198       }
00199       else if (ea.getKey()=='C') {
00200         Logcln("Camera parameters: alpha=" << Math::radToDeg(alpha) << " theta=" << Math::radToDeg(theta) << " d=" << d << "  target=" << target);
00201       }
00202     } break;
00203 
00204     case(GUIEventAdapter::FRAME):
00205       //if (tracking) updateCamera(us);
00206       return tracking;
00207     default:
00208       return false;
00209     }
00210   return false;
00211 }
00212 
00213 
00214 Vec3 LookAtCameraManipulator::calcPos() const
00215 {
00216   Vector3 eye(0,-d,0);
00217   Quat4 rotz(Vector3(0,0,1), alpha); // rot about z by alpha
00218   Quat4 rotx(Vector3(1,0,0), -theta); // rot about x by -theta
00219   Vector3 neweye( rotz.rotate(rotx.rotate(eye)) );
00220 
00221   return target+Vec3(neweye.x, neweye.y, neweye.z);
00222 }
00223 

Generated on Thu Jul 29 15:56:19 2004 for OpenSim by doxygen 1.3.6