glc_flymover.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  Version 2.0.0 Beta 1, packaged on April 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU General Public License as published by
00011  the Free Software Foundation; either version 2 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU General Public License for more details.
00018 
00019  You should have received a copy of the GNU General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023  *****************************************************************************/
00025 
00026 #include "glc_flymover.h"
00027 #include "glc_viewport.h"
00028 #include "../maths/glc_utils_maths.h"
00029 
00030 GLC_FlyMover::GLC_FlyMover(GLC_Viewport* pViewport, const QList<GLC_RepMover*>& repsList)
00031 : GLC_Mover(pViewport, repsList)
00032 , m_TurnRate(glc::toRadian(6))
00033 , m_TimerId(0)
00034 , m_TimerInterval(66)
00035 , m_Velocity(1.0)
00036 {
00037         GLC_Mover::m_MoverInfo.m_VectorInfo.append(GLC_Vector3d());
00038         GLC_Mover::m_MoverInfo.m_DoubleInfo.append(m_Velocity);
00039 }
00040 
00041 GLC_FlyMover::GLC_FlyMover(const GLC_FlyMover& flyMover)
00042 : GLC_Mover(flyMover)
00043 , m_TurnRate(flyMover.m_TurnRate)
00044 , m_TimerId(0)
00045 , m_TimerInterval(flyMover.m_TimerInterval)
00046 , m_Velocity(flyMover.m_Velocity)
00047 {
00048 
00049 }
00050 
00051 GLC_FlyMover::~GLC_FlyMover()
00052 {
00053         if (0 != m_TimerId)
00054         {
00055                 QObject::killTimer(m_TimerId);
00056         }
00057 }
00058 
00060 //Get Functions
00062 
00063 GLC_Mover* GLC_FlyMover::clone() const
00064 {
00065         return new GLC_FlyMover(*this);
00066 }
00067 
00068 
00070 //Set Functions
00072 
00073 void GLC_FlyMover::init(QMouseEvent * e)
00074 {
00075         m_PreviousVector= mapForFlying(static_cast<double>(e->x()), static_cast<double>(e->y()));
00076         GLC_Point3d point= m_pViewport->unProject(e->x(), e->y());
00077         const double distance= (point - m_pViewport->cameraHandle()->eye()).length();
00078         m_pViewport->cameraHandle()->setDistTargetEye(distance);
00079         // 5 secondes to travel
00080         m_Velocity= distance / 5000;
00081 
00082         GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
00083 
00084         // Start the timer
00085         m_TimerId= QObject::startTimer(m_TimerInterval);
00086 }
00087 
00088 bool GLC_FlyMover::move(QMouseEvent * e)
00089 {
00090         m_PreviousVector= mapForFlying(static_cast<double>(e->x()), static_cast<double>(e->y()));
00091         GLC_Point3d point= m_pViewport->unProject(e->x(), e->y());
00092         const double distance= (point - m_pViewport->cameraHandle()->eye()).length();
00093         m_pViewport->cameraHandle()->setDistTargetEye(distance);
00094 
00095         return false;
00096 }
00097 void GLC_FlyMover::ends()
00098 {
00099         QObject::killTimer(m_TimerId);
00100         m_TimerId= 0;
00101 }
00102 
00103 void GLC_FlyMover::setFlyingVelocity(double velocity)
00104 {
00105         m_Velocity= velocity;
00106         GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
00107 }
00108 
00109 void GLC_FlyMover::increaseVelocity(double factor)
00110 {
00111         m_Velocity*= factor;
00112         GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
00113 }
00114 
00115 void GLC_FlyMover::timerEvent(QTimerEvent*)
00116 {
00117         fly();
00118         GLC_Vector3d direction(m_pViewport->cameraHandle()->forward());
00119         direction.normalize();
00120         direction= direction * m_Velocity * m_TimerInterval;
00121         const GLC_Matrix4x4 translation(direction);
00122         m_pViewport->cameraHandle()->move(translation);
00123 
00124         emit updated();
00125 }
00126 
00127 GLC_Vector3d GLC_FlyMover::mapForFlying(double x, double y)
00128 {
00129         double AspectRatio;
00130         const double winHSize= static_cast<double>(GLC_Mover::m_pViewport->viewHSize());
00131         const double winVSize= static_cast<double>(GLC_Mover::m_pViewport->viewVSize());
00132 
00133 
00134         // Change origin and cover
00135         if (winHSize < winVSize)
00136         {
00137                 AspectRatio= winVSize / winHSize;
00138                 x= ( (x - winHSize  / 2.0 ) / ( winHSize / 2.0) ) / AspectRatio;
00139                 y= ( ( winVSize / 2.0 - y) / ( winVSize / 2.0 ) );
00140         }
00141         else
00142         {
00143                 AspectRatio= winHSize / winVSize;
00144                 x= ( (x - winHSize  / 2.0 ) / ( winHSize / 2.0) );
00145                 y= ( (winVSize / 2.0 - y) / (winVSize / 2.0 ) ) / AspectRatio;
00146         }
00147 
00148         GLC_Vector3d pos(x, y, 0.0);
00149 
00150         if (pos.length() > 1.0)
00151         {
00152                 pos.normalize();
00153         }
00154         GLC_Mover::m_MoverInfo.m_VectorInfo.first()= pos;
00155         GLC_Mover::updateRepresentation();
00156 
00157         double z= -cos(m_TurnRate) / sin(m_TurnRate);
00158         pos.setZ(z);
00159         pos.normalize();
00160         return pos;
00161 }
00162 void GLC_FlyMover::fly()
00163 {
00164         const GLC_Matrix4x4 viewMatrix(m_pViewport->cameraHandle()->viewMatrix());
00165         const GLC_Vector3d newPos= viewMatrix.inverted() * m_PreviousVector;
00166         const GLC_Vector3d forward(GLC_Vector3d(m_pViewport->cameraHandle()->forward()).normalize());
00167 
00168         // Compute rotation matrix
00169         const GLC_Vector3d axe(forward ^ newPos);
00170         if (!axe.isNull())
00171         {
00172                 const double angle= acos(forward * newPos);
00173                 const GLC_Matrix4x4 rotation(axe, angle);
00174                 const GLC_Matrix4x4 trans1(-m_pViewport->cameraHandle()->eye());
00175                 const GLC_Matrix4x4 trans2(m_pViewport->cameraHandle()->eye());
00176                 const GLC_Matrix4x4 composition(trans2 * rotation * trans1);
00177                 m_pViewport->cameraHandle()->move(composition);
00178         }
00179 }

SourceForge.net Logo

©2005 Laurent Ribon