glc_flymover.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00062
00063 GLC_Mover* GLC_FlyMover::clone() const
00064 {
00065 return new GLC_FlyMover(*this);
00066 }
00067
00068
00070
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
00080 m_Velocity= distance / 5000;
00081
00082 GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
00083
00084
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
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
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 }