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
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
00060
00061 GLC_Mover* GLC_FlyMover::clone() const
00062 {
00063 return new GLC_FlyMover(*this);
00064 }
00065
00066
00068
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
00078 m_Velocity= distance / 5000;
00079
00080 GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
00081
00082
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
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
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 }