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

SourceForge.net Logo

©2005-2011 Laurent Ribon