Commit 6fe89f58 authored by Mike Kremer's avatar Mike Kremer
Browse files

Implemented 3D-First-Person-Shooter navigation mode that still doesn't work too well.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@7014 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 37a72c9e
...@@ -642,6 +642,9 @@ public: ...@@ -642,6 +642,9 @@ public:
/// Show / hide wheels /// Show / hide wheels
void slotSwitchWheels(bool _state); void slotSwitchWheels(bool _state);
/// Switch navigation mode
void slotSwitchNavigation(bool _egomode);
/// Set the snapShot name for all examiners /// Set the snapShot name for all examiners
void slotSnapshotName(); void slotSnapshotName();
......
...@@ -284,6 +284,17 @@ void CoreWidget::setupMenuBar() ...@@ -284,6 +284,17 @@ void CoreWidget::setupMenuBar()
viewMenu_->addSeparator(); viewMenu_->addSeparator();
QAction* navigationSwitchAction = new QAction( tr("Ego-shooter Navigation"), viewMenu_ );
navigationSwitchAction->setCheckable( true );
navigationSwitchAction->setStatusTip( tr("Switch between normal and ego-shooter navigation mode."));
navigationSwitchAction->setWhatsThis( tr("Switch between normal and ego-shooter navigation mode."));
navigationSwitchAction->setChecked( false );
connect( navigationSwitchAction, SIGNAL( toggled(bool) ), this, SLOT( slotSwitchNavigation(bool) ) );
viewMenu_->addAction( navigationSwitchAction);
viewMenu_->addSeparator();
connect( viewMenu_,SIGNAL( aboutToShow() ), this, SLOT( slotViewMenuAboutToShow() ) ); connect( viewMenu_,SIGNAL( aboutToShow() ), this, SLOT( slotViewMenuAboutToShow() ) );
QAction* homeAction = new QAction(tr("Restore Home View"),viewMenu_); QAction* homeAction = new QAction(tr("Restore Home View"),viewMenu_);
......
...@@ -124,6 +124,16 @@ void CoreWidget::slotSwitchWheels(bool _state) { ...@@ -124,6 +124,16 @@ void CoreWidget::slotSwitchWheels(bool _state) {
_state ? (*it)->slotShowWheels() : (*it)->slotHideWheels(); _state ? (*it)->slotShowWheels() : (*it)->slotHideWheels();
} }
/// Switch navigation mode
void CoreWidget::slotSwitchNavigation(bool _egomode) {
std::vector< glViewer* >::iterator it = examiner_widgets_.begin();
for(; it != examiner_widgets_.end(); it++) {
_egomode ? (*it)->navigationMode(glViewer::EGOSHOOTER_NAVIGATION) :
(*it)->navigationMode(glViewer::NORMAL_NAVIGATION);
}
}
/// Set the viewer to home position /// Set the viewer to home position
void CoreWidget::slotGlobalHomeView() { void CoreWidget::slotGlobalHomeView() {
for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i ) for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
......
...@@ -169,6 +169,7 @@ glViewer::glViewer( QGraphicsScene* _scene, ...@@ -169,6 +169,7 @@ glViewer::glViewer( QGraphicsScene* _scene,
normalsMode_ = DONT_TOUCH_NORMALS; normalsMode_ = DONT_TOUCH_NORMALS;
projectionMode_ = PERSPECTIVE_PROJECTION; projectionMode_ = PERSPECTIVE_PROJECTION;
navigationMode_ = NORMAL_NAVIGATION;
light_matrix_.identity(); light_matrix_.identity();
...@@ -332,6 +333,23 @@ void glViewer::projectionMode(ProjectionMode _p) ...@@ -332,6 +333,23 @@ void glViewer::projectionMode(ProjectionMode _p)
updateProjectionMatrix(); updateProjectionMatrix();
} }
void glViewer::toggleNavigationMode()
{
if (navigationMode_ == NORMAL_NAVIGATION)
navigationMode(EGOSHOOTER_NAVIGATION);
else
navigationMode(NORMAL_NAVIGATION);
}
void glViewer::navigationMode(NavigationMode _n)
{
if ((navigationMode_ = _n) == NORMAL_NAVIGATION)
emit navigationModeChanged( true );
else
emit navigationModeChanged( false );
}
void glViewer::updateProjectionMatrix() void glViewer::updateProjectionMatrix()
{ {
...@@ -1563,6 +1581,29 @@ void glViewer::mouseMoveEvent(QGraphicsSceneMouseEvent* _e) ...@@ -1563,6 +1581,29 @@ void glViewer::mouseMoveEvent(QGraphicsSceneMouseEvent* _e)
} }
} }
//----------------------------------------------------------------------------------
void glViewer::keyPressEvent ( QKeyEvent* _event ) {
_event->accept();
switch (properties_.actionMode()) {
case Viewer::ExamineMode:
viewKeyEvent(_event);
break;
default: // avoid warning
break;
}
}
//----------------------------------------------------------------------------------
bool glViewer::viewKeyPressEvent(QKeyEvent* _event) {
_event->accept();
return true;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -1682,79 +1723,132 @@ void glViewer::dropEvent(QGraphicsSceneDragDropEvent* _e) ...@@ -1682,79 +1723,132 @@ void glViewer::dropEvent(QGraphicsSceneDragDropEvent* _e)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void glViewer::viewMouseEvent(QMouseEvent* _event) {
glViewer::viewMouseEvent(QMouseEvent* _event)
{
QPointF f (mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
QPoint pos (f.x(), f.y());
switch (_event->type()) if (navigationMode_ == NORMAL_NAVIGATION) {
{
case QEvent::MouseButtonPress: treatNormalNavigation(_event);
{
} else if (navigationMode_ == EGOSHOOTER_NAVIGATION) {
treatEgoShooterNavigation(_event);
}
}
//----------------------------------------------------------------------------
void glViewer::treatEgoShooterNavigation( QMouseEvent* _event) {
// Ego-shooter navigation mode is selected
QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
QPoint pos(f.x(), f.y());
switch (_event->type()) {
case QEvent::MouseButtonDblClick: {
if (allowRotation_)
flyTo(_event->pos(), _event->button() == Qt::MidButton);
break;
}
case QEvent::MouseMove: {
// Considering center point of screen as origin
QPoint newpos = QPoint(pos.x() - glWidth() / 2, glHeight() / 2 - pos.y());
QPoint oldpos = QPoint(lastPoint2D_.x() - glWidth() / 2, glHeight() / 2 - lastPoint2D_.y());
double x = 2.0 * newpos.x() / glWidth();
double y = 2.0 * newpos.y() / glHeight();
double xo = 2.0 * oldpos.x() / glWidth();
double yo = 2.0 * oldpos.y() / glHeight();
double diffx = xo - x;
double diffy = yo - y;
ACG::Vec3d yaxis(0.0, 1.0, 0.0);
ACG::Vec3d xaxis(1.0, 0.0, 0.0);
ACG::Vec3d eye = glstate_->modelview().transform_point(glstate_->eye());
glstate_->rotate(-diffx * 90, 0.0, 1.0, 0.0);
glstate_->rotate(diffy * 90, 1.0, 0.0, 0.0);
rotate(yaxis, -diffx * 90, glstate_->eye());
rotate(xaxis, diffy * 90, glstate_->eye());
lastPoint2D_ = pos;
updateGL();
lastMoveTime_.restart();
break;
}
default: // avoid warning
break;
}
}
//----------------------------------------------------------------------------
void glViewer::treatNormalNavigation( QMouseEvent* _event ) {
// Normal navigation mode is selected
QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
QPoint pos(f.x(), f.y());
switch (_event->type()) {
case QEvent::MouseButtonPress: {
// shift key -> set rotation center // shift key -> set rotation center
if (_event->modifiers() & Qt::ShiftModifier) if (_event->modifiers() & Qt::ShiftModifier) {
{
ACG::Vec3d c; ACG::Vec3d c;
if (fast_pick(pos, c)) if (fast_pick(pos, c)) {
{
trackball_center_ = c; trackball_center_ = c;
trackball_radius_ = std::max(scene_radius_, (c-glstate_->eye()).norm()*0.9f); trackball_radius_ = std::max(scene_radius_, (c - glstate_->eye()).norm() * 0.9f);
} }
} }
lastPoint_hitSphere_ = mapToSphere( lastPoint2D_= pos, lastPoint_hitSphere_ = mapToSphere(lastPoint2D_ = pos, lastPoint3D_);
lastPoint3D_ );
isRotating_ = true; isRotating_ = true;
timer_->stop(); timer_->stop();
break; break;
} }
case QEvent::MouseButtonDblClick: {
case QEvent::MouseButtonDblClick:
{
if (allowRotation_) if (allowRotation_)
flyTo(_event->pos(), _event->button()==Qt::MidButton); flyTo(_event->pos(), _event->button() == Qt::MidButton);
break; break;
} }
case QEvent::MouseMove: {
case QEvent::MouseMove:
{
double factor = 1.0; double factor = 1.0;
if (_event->modifiers() == Qt::ShiftModifier) if (_event->modifiers() == Qt::ShiftModifier)
factor = properties_.wheelZoomFactorShift(); factor = properties_.wheelZoomFactorShift();
// mouse button should be pressed // mouse button should be pressed
if (_event->buttons() & (Qt::LeftButton | Qt::MidButton)) if (_event->buttons() & (Qt::LeftButton | Qt::MidButton)) {
{
QPoint newPoint2D = pos; QPoint newPoint2D = pos;
double value_x, value_y; double value_x, value_y;
ACG::Vec3d newPoint3D; ACG::Vec3d newPoint3D;
bool newPoint_hitSphere = mapToSphere( newPoint2D, newPoint3D ); bool newPoint_hitSphere = mapToSphere(newPoint2D, newPoint3D);
makeCurrent(); makeCurrent();
// move in z direction // move in z direction
if ( (_event->buttons() & Qt::LeftButton) && if ((_event->buttons() & Qt::LeftButton) && (_event->buttons() & Qt::MidButton)) {
(_event->buttons() & Qt::MidButton)) switch (projectionMode()) {
{ case PERSPECTIVE_PROJECTION: {
switch (projectionMode())
{
case PERSPECTIVE_PROJECTION:
{
value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 3.0 / (double) glHeight(); value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 3.0 / (double) glHeight();
translate( ACG::Vec3d(0.0, 0.0, value_y * factor ) ); translate(ACG::Vec3d(0.0, 0.0, value_y * factor));
updateGL(); updateGL();
break; break;
} }
case ORTHOGRAPHIC_PROJECTION: case ORTHOGRAPHIC_PROJECTION: {
{
value_y = ((newPoint2D.y() - lastPoint2D_.y())) * orthoWidth_ / (double) glHeight(); value_y = ((newPoint2D.y() - lastPoint2D_.y())) * orthoWidth_ / (double) glHeight();
orthoWidth_ -= value_y * factor; orthoWidth_ -= value_y * factor;
updateProjectionMatrix(); updateProjectionMatrix();
...@@ -1765,27 +1859,24 @@ glViewer::viewMouseEvent(QMouseEvent* _event) ...@@ -1765,27 +1859,24 @@ glViewer::viewMouseEvent(QMouseEvent* _event)
} }
// move in x,y direction // move in x,y direction
else if ( (_event->buttons() & Qt::MidButton) || (!allowRotation_ && (_event->buttons() & Qt::LeftButton))) else if ((_event->buttons() & Qt::MidButton) || (!allowRotation_ && (_event->buttons() & Qt::LeftButton))) {
{
value_x = scene_radius_ * ((newPoint2D.x() - lastPoint2D_.x())) * 2.0 / (double) glWidth(); value_x = scene_radius_ * ((newPoint2D.x() - lastPoint2D_.x())) * 2.0 / (double) glWidth();
value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 2.0 / (double) glHeight(); value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 2.0 / (double) glHeight();
translate( ACG::Vec3d(value_x * factor , -value_y * factor , 0.0) ); translate(ACG::Vec3d(value_x * factor, -value_y * factor, 0.0));
} }
// rotate // rotate
else if (allowRotation_ && (_event->buttons() & Qt::LeftButton) ) else if (allowRotation_ && (_event->buttons() & Qt::LeftButton)) {
{ ACG::Vec3d axis(1.0, 0.0, 0.0);
ACG::Vec3d axis(1.0,0.0,0.0);
double angle(0.0); double angle(0.0);
if ( lastPoint_hitSphere_ ) { if (lastPoint_hitSphere_) {
if ( ( newPoint_hitSphere = mapToSphere( newPoint2D, if ((newPoint_hitSphere = mapToSphere(newPoint2D, newPoint3D))) {
newPoint3D ) ) ) {
axis = lastPoint3D_ % newPoint3D; axis = lastPoint3D_ % newPoint3D;
double cos_angle = ( lastPoint3D_ | newPoint3D ); double cos_angle = (lastPoint3D_ | newPoint3D);
if ( fabs(cos_angle) < 1.0 ) { if (fabs(cos_angle) < 1.0) {
angle = acos( cos_angle ) * 180.0 / M_PI * factor ; angle = acos(cos_angle) * 180.0 / M_PI * factor;
angle *= 2.0; // inventor rotation angle *= 2.0; // inventor rotation
} }
} }
...@@ -1808,17 +1899,12 @@ glViewer::viewMouseEvent(QMouseEvent* _event) ...@@ -1808,17 +1899,12 @@ glViewer::viewMouseEvent(QMouseEvent* _event)
break; break;
} }
case QEvent::MouseButtonRelease: {
case QEvent::MouseButtonRelease:
{
lastPoint_hitSphere_ = false; lastPoint_hitSphere_ = false;
// continue rotation ? // continue rotation ?
if ( isRotating_ && if (isRotating_ && (_event->button() == Qt::LeftButton) && (!(_event->buttons() & Qt::MidButton))
(_event->button() == Qt::LeftButton) && && (lastMoveTime_.elapsed() < 50) && properties_.animation())
(!(_event->buttons() & Qt::MidButton)) &&
(lastMoveTime_.elapsed() < 50) && properties_.animation() )
timer_->start(0); timer_->start(0);
break; break;
} }
...@@ -1826,14 +1912,19 @@ glViewer::viewMouseEvent(QMouseEvent* _event) ...@@ -1826,14 +1912,19 @@ glViewer::viewMouseEvent(QMouseEvent* _event)
default: // avoid warning default: // avoid warning
break; break;
} }
}
//-----------------------------------------------------------------------------
} void glViewer::viewKeyEvent( QKeyEvent* _event) {
// Only react if in ego-shooter mode
if (navigationMode_ == EGOSHOOTER_NAVIGATION) {
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
glViewer::lightMouseEvent(QMouseEvent* _event) glViewer::lightMouseEvent(QMouseEvent* _event)
{ {
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include <QDragEnterEvent> #include <QDragEnterEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QAction> #include <QAction>
#include <QKeyEvent>
#include <QSize> #include <QSize>
#include <QMap> #include <QMap>
#include <QString> #include <QString>
...@@ -191,11 +192,21 @@ public: ...@@ -191,11 +192,21 @@ public:
PERSPECTIVE_PROJECTION //!< perspective PERSPECTIVE_PROJECTION //!< perspective
}; };
/// Navigation mode
enum NavigationMode {
NORMAL_NAVIGATION, //!< Normal mode
EGOSHOOTER_NAVIGATION //!< Egoshooter mode
};
/// Changes the projection mode and updates the projection matrix. /// Changes the projection mode and updates the projection matrix.
void projectionMode(ProjectionMode _p); void projectionMode(ProjectionMode _p);
/// get current projection mode /// get current projection mode
ProjectionMode projectionMode() const { return projectionMode_; } ProjectionMode projectionMode() const { return projectionMode_; }
/// Changes the navigation mode
void navigationMode(NavigationMode _n);
/// get current navigation mode
NavigationMode navigationMode() const { return navigationMode_; }
/** Sets the center and dimension of the whole scene. This point is /** Sets the center and dimension of the whole scene. This point is
used as fixpoint for rotations and to set the eye point far used as fixpoint for rotations and to set the eye point far
...@@ -217,7 +228,6 @@ public: ...@@ -217,7 +228,6 @@ public:
*/ */
double scene_radius() const { return scene_radius_; } double scene_radius() const { return scene_radius_; }
/// set the viewing direction /// set the viewing direction
void viewingDirection( const ACG::Vec3d& _dir, const ACG::Vec3d& _up ); void viewingDirection( const ACG::Vec3d& _dir, const ACG::Vec3d& _up );
...@@ -341,10 +351,13 @@ public slots: ...@@ -341,10 +351,13 @@ public slots:
virtual void orthographicProjection(); virtual void orthographicProjection();
/// toggle projection mode /// toggle projection mode
virtual void toggleProjectionMode(); virtual void toggleProjectionMode();
/// toggle navigation mode
virtual void toggleNavigationMode();
signals: signals:
void projectionModeChanged( bool _ortho ); void projectionModeChanged( bool _ortho );
void navigationModeChanged( bool _normal );
public slots: public slots:
...@@ -437,6 +450,8 @@ protected: ...@@ -437,6 +450,8 @@ protected:
void viewMouseEvent( QMouseEvent* _event); void viewMouseEvent( QMouseEvent* _event);
/// specialized viewer: handle wheel events /// specialized viewer: handle wheel events
void viewWheelEvent(QWheelEvent* _event); void viewWheelEvent(QWheelEvent* _event);
/// specialized viewer: hande key events
void viewKeyEvent( QKeyEvent* _event);
/// optional: hande mouse events to rotate light /// optional: hande mouse events to rotate light
void lightMouseEvent( QMouseEvent* /* _event */ ); void lightMouseEvent( QMouseEvent* /* _event */ );
...@@ -533,6 +548,7 @@ private: ...@@ -533,6 +548,7 @@ private:
// modi // modi
NormalsMode normalsMode_; NormalsMode normalsMode_;
ProjectionMode projectionMode_; ProjectionMode projectionMode_;
NavigationMode navigationMode_;
// helper // helper
...@@ -651,7 +667,7 @@ private: ...@@ -651,7 +667,7 @@ private:
* *
* This function is called by the internal gl widget when receiving a key press event. * This function is called by the internal gl widget when receiving a key press event.
*/ */
virtual void keyPressEvent(QKeyEvent* _event) { _event->ignore(); }; virtual void keyPressEvent(QKeyEvent* _event);
/** \brief Get keyRelease events from the glArea /** \brief Get keyRelease events from the glArea
* *
...@@ -668,7 +684,7 @@ private: ...@@ -668,7 +684,7 @@ private:
* *
* @return If the derived class handled the event it has to return true otherwise false * @return If the derived class handled the event it has to return true otherwise false
*/ */
virtual bool viewKeyPressEvent(QKeyEvent* /*_event*/) { return false; }; virtual bool viewKeyPressEvent(QKeyEvent* _event);
/** @} */ /** @} */
...@@ -834,6 +850,12 @@ private: ...@@ -834,6 +850,12 @@ private:
/// virtual trackball: map 2D screen point to unit sphere /// virtual trackball: map 2D screen point to unit sphere
bool mapToSphere(const QPoint& _p, ACG::Vec3d& _result) const; bool mapToSphere(const QPoint& _p, ACG::Vec3d& _result) const;
/// Navigate through scene if ego-shooter mode has been selected
void treatEgoShooterNavigation( QMouseEvent* _event);
/// Navigate through scene if normal mode has been selected
void treatNormalNavigation( QMouseEvent* _event);
// mouse interaction // mouse interaction
ACG::Vec3d lastPoint3D_; ACG::Vec3d lastPoint3D_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment