1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-03 19:52:10 +01:00
chebuzz 023df37b2b OP-98 GCS/ModelView - Update ModelView to use GLC_lib 2.0
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1260 ebee16cc-31ac-478f-84a7-5cbb03baadba
2010-08-10 17:16:57 +00:00

180 lines
5.2 KiB
C++

/****************************************************************************
This file is part of the GLC-lib library.
Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
Version 2.0.0, packaged on July 2010.
http://glc-lib.sourceforge.net
GLC-lib is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GLC-lib is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GLC-lib; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
//! \file glc_flymover.cpp Implementation of the GLC_FlyMover class.
#include "glc_flymover.h"
#include "glc_viewport.h"
#include "../maths/glc_utils_maths.h"
GLC_FlyMover::GLC_FlyMover(GLC_Viewport* pViewport, const QList<GLC_RepMover*>& repsList)
: GLC_Mover(pViewport, repsList)
, m_TurnRate(glc::toRadian(6))
, m_TimerId(0)
, m_TimerInterval(66)
, m_Velocity(1.0)
{
GLC_Mover::m_MoverInfo.m_VectorInfo.append(GLC_Vector3d());
GLC_Mover::m_MoverInfo.m_DoubleInfo.append(m_Velocity);
}
GLC_FlyMover::GLC_FlyMover(const GLC_FlyMover& flyMover)
: GLC_Mover(flyMover)
, m_TurnRate(flyMover.m_TurnRate)
, m_TimerId(0)
, m_TimerInterval(flyMover.m_TimerInterval)
, m_Velocity(flyMover.m_Velocity)
{
}
GLC_FlyMover::~GLC_FlyMover()
{
if (0 != m_TimerId)
{
QObject::killTimer(m_TimerId);
}
}
//////////////////////////////////////////////////////////////////////
//Get Functions
//////////////////////////////////////////////////////////////////////
GLC_Mover* GLC_FlyMover::clone() const
{
return new GLC_FlyMover(*this);
}
//////////////////////////////////////////////////////////////////////
//Set Functions
//////////////////////////////////////////////////////////////////////
void GLC_FlyMover::init(QMouseEvent * e)
{
m_PreviousVector= mapForFlying(static_cast<double>(e->x()), static_cast<double>(e->y()));
GLC_Point3d point= m_pViewport->unProject(e->x(), e->y());
const double distance= (point - m_pViewport->cameraHandle()->eye()).length();
m_pViewport->cameraHandle()->setDistTargetEye(distance);
// 5 secondes to travel
m_Velocity= distance / 5000;
GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
// Start the timer
m_TimerId= QObject::startTimer(m_TimerInterval);
}
bool GLC_FlyMover::move(QMouseEvent * e)
{
m_PreviousVector= mapForFlying(static_cast<double>(e->x()), static_cast<double>(e->y()));
GLC_Point3d point= m_pViewport->unProject(e->x(), e->y());
const double distance= (point - m_pViewport->cameraHandle()->eye()).length();
m_pViewport->cameraHandle()->setDistTargetEye(distance);
return false;
}
void GLC_FlyMover::ends()
{
QObject::killTimer(m_TimerId);
m_TimerId= 0;
}
void GLC_FlyMover::setFlyingVelocity(double velocity)
{
m_Velocity= velocity;
GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
}
void GLC_FlyMover::increaseVelocity(double factor)
{
m_Velocity*= factor;
GLC_Mover::m_MoverInfo.m_DoubleInfo.first()= m_Velocity;
}
void GLC_FlyMover::timerEvent(QTimerEvent*)
{
fly();
GLC_Vector3d direction(m_pViewport->cameraHandle()->forward());
direction.normalize();
direction= direction * m_Velocity * m_TimerInterval;
const GLC_Matrix4x4 translation(direction);
m_pViewport->cameraHandle()->move(translation);
emit updated();
}
GLC_Vector3d GLC_FlyMover::mapForFlying(double x, double y)
{
double AspectRatio;
const double winHSize= static_cast<double>(GLC_Mover::m_pViewport->viewHSize());
const double winVSize= static_cast<double>(GLC_Mover::m_pViewport->viewVSize());
// Change origin and cover
if (winHSize < winVSize)
{
AspectRatio= winVSize / winHSize;
x= ( (x - winHSize / 2.0 ) / ( winHSize / 2.0) ) / AspectRatio;
y= ( ( winVSize / 2.0 - y) / ( winVSize / 2.0 ) );
}
else
{
AspectRatio= winHSize / winVSize;
x= ( (x - winHSize / 2.0 ) / ( winHSize / 2.0) );
y= ( (winVSize / 2.0 - y) / (winVSize / 2.0 ) ) / AspectRatio;
}
GLC_Vector3d pos(x, y, 0.0);
if (pos.length() > 1.0)
{
pos.normalize();
}
GLC_Mover::m_MoverInfo.m_VectorInfo.first()= pos;
GLC_Mover::updateRepresentation();
double z= -cos(m_TurnRate) / sin(m_TurnRate);
pos.setZ(z);
pos.normalize();
return pos;
}
void GLC_FlyMover::fly()
{
const GLC_Matrix4x4 viewMatrix(m_pViewport->cameraHandle()->viewMatrix());
const GLC_Vector3d newPos= viewMatrix.inverted() * m_PreviousVector;
const GLC_Vector3d forward(GLC_Vector3d(m_pViewport->cameraHandle()->forward()).normalize());
// Compute rotation matrix
const GLC_Vector3d axe(forward ^ newPos);
if (!axe.isNull())
{
const double angle= acos(forward * newPos);
const GLC_Matrix4x4 rotation(axe, angle);
const GLC_Matrix4x4 trans1(-m_pViewport->cameraHandle()->eye());
const GLC_Matrix4x4 trans2(m_pViewport->cameraHandle()->eye());
const GLC_Matrix4x4 composition(trans2 * rotation * trans1);
m_pViewport->cameraHandle()->move(composition);
}
}