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

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
......@@ -285,7 +285,7 @@ public:
/// Setup the main menubar
void setupMenuBar();
/** @} */
//===========================================================================
......@@ -554,7 +554,7 @@ public:
/// Setup and update the global draw menu
void slotUpdateGlobalDrawMenu();
/// Change viewer layout that was selected in the combo box
void setViewerLayout(int _idx);
......@@ -579,18 +579,18 @@ public:
QAction* perspectiveProjectionAction_;
QAction* orthogonalProjectionAction_;
/// Action to globally set Animation
QAction* globalAnimationAction_;
/// Action to globally set backface culling
QAction* globalBackfaceCullingAction_;
/// Action to globally set Two-Sided lighting
QAction* globalTwosidedLightingAction_;
QAction* globalTwosidedLightingAction_;
/// Action to globally set multisampling
QAction* globalMultisamplingAction_;
QAction* globalMultisamplingAction_;
int activeDrawModes_;
......@@ -642,6 +642,9 @@ public:
/// Show / hide wheels
void slotSwitchWheels(bool _state);
/// Switch navigation mode
void slotSwitchNavigation(bool _egomode);
/// Set the snapShot name for all examiners
void slotSnapshotName();
......@@ -927,15 +930,15 @@ public:
/// Set two sided lighting for active viewer
void slotLocalChangeTwoSidedLighting(bool _lighting);
/// Set Multisampling for all viewers
void slotGlobalChangeMultisampling(bool _lighting);
/// Set Multisampling for active viewer
void slotLocalChangeMultisampling(bool _lighting);
/// When using first person mode move backward
void moveBack();
......
......@@ -250,7 +250,7 @@ void CoreWidget::setupMenuBar()
renderingOptionsMenu->addAction( orthogonalProjectionAction_);
// =====================
globalAnimationAction_ = renderingOptionsMenu->addAction(tr("Animation"));
globalAnimationAction_->setCheckable( true );
globalAnimationAction_->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"animation.png") );
......@@ -259,7 +259,7 @@ void CoreWidget::setupMenuBar()
//======================
globalBackfaceCullingAction_ = renderingOptionsMenu->addAction(tr("Backface Culling"));
globalBackfaceCullingAction_->setCheckable( true );
globalBackfaceCullingAction_->setCheckable( true );
globalBackfaceCullingAction_->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"backFaceCulling.png") );
connect(globalBackfaceCullingAction_, SIGNAL(triggered(bool)), this , SLOT( slotGlobalChangeBackFaceCulling(bool) ) );
......@@ -269,14 +269,14 @@ void CoreWidget::setupMenuBar()
globalTwosidedLightingAction_->setCheckable( true );
globalTwosidedLightingAction_->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"twosidedLighting.png") );
connect(globalTwosidedLightingAction_, SIGNAL(triggered(bool)), this , SLOT( slotGlobalChangeTwoSidedLighting(bool) ) );
//======================
globalMultisamplingAction_ = renderingOptionsMenu->addAction(tr("Multisampling"));
globalMultisamplingAction_->setCheckable( true );
// TODO:Icon for multisampling
// TODO:Icon for multisampling
// globalMultisamplingAction_->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"twosidedLighting.png") );
connect(globalMultisamplingAction_, SIGNAL(triggered(bool)), this , SLOT( slotGlobalChangeMultisampling(bool)) );
connect(globalMultisamplingAction_, SIGNAL(triggered(bool)), this , SLOT( slotGlobalChangeMultisampling(bool)) );
//============================================================================================================
// Other toplevel actions
......@@ -284,6 +284,17 @@ void CoreWidget::setupMenuBar()
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() ) );
QAction* homeAction = new QAction(tr("Restore Home View"),viewMenu_);
......@@ -470,7 +481,7 @@ void CoreWidget::slotViewMenuAboutToShow() {
uint enabledCount = 0;
uint disabledCount = 0;
for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
if ( PluginFunctions::viewerProperties(i).animation() )
enabledCount++;
......@@ -480,55 +491,55 @@ void CoreWidget::slotViewMenuAboutToShow() {
if ( enabledCount != 0 && disabledCount != 0 ) {
globalAnimationAction_->setChecked(Qt::PartiallyChecked);
globalAnimationAction_->setToolTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setStatusTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setText(tr("Disable animation"));
globalAnimationAction_->setToolTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setStatusTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setText(tr("Disable animation"));
} else if ( enabledCount == 4 ) {
globalAnimationAction_->setChecked( Qt::Checked );
globalAnimationAction_->setToolTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setStatusTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setText(tr("Disable animation"));
globalAnimationAction_->setToolTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setStatusTip(tr("Disable animation for all viewers"));
globalAnimationAction_->setText(tr("Disable animation"));
} else {
globalAnimationAction_->setChecked( Qt::Unchecked );
globalAnimationAction_->setToolTip(tr("Enable animation for all viewers"));
globalAnimationAction_->setStatusTip(tr("Enable animation for all viewers"));
globalAnimationAction_->setText(tr("Enable animation"));
globalAnimationAction_->setToolTip(tr("Enable animation for all viewers"));
globalAnimationAction_->setStatusTip(tr("Enable animation for all viewers"));
globalAnimationAction_->setText(tr("Enable animation"));
}
//=============================================================================================================================
enabledCount = 0;
disabledCount = 0;
disabledCount = 0;
for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
if ( PluginFunctions::viewerProperties(i).backFaceCulling() )
enabledCount++;
else
disabledCount++;
}
if ( enabledCount != 0 && disabledCount != 0 ) {
globalBackfaceCullingAction_->setChecked(Qt::PartiallyChecked);
globalBackfaceCullingAction_->setToolTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setStatusTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setText(tr("Disable backface culling"));
globalBackfaceCullingAction_->setToolTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setStatusTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setText(tr("Disable backface culling"));
} else if ( enabledCount == 4 ) {
globalBackfaceCullingAction_->setChecked( Qt::Checked );
globalBackfaceCullingAction_->setToolTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setStatusTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setText(tr("Disable backface culling"));
globalBackfaceCullingAction_->setToolTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setStatusTip(tr("Disable backface culling for all viewers"));
globalBackfaceCullingAction_->setText(tr("Disable backface culling"));
} else {
globalBackfaceCullingAction_->setChecked( Qt::Unchecked );
globalBackfaceCullingAction_->setToolTip(tr("Enable backface culling for all viewers"));
globalBackfaceCullingAction_->setStatusTip(tr("Enable backface culling for all viewers"));
globalBackfaceCullingAction_->setText(tr("Enable backface culling"));
globalBackfaceCullingAction_->setToolTip(tr("Enable backface culling for all viewers"));
globalBackfaceCullingAction_->setStatusTip(tr("Enable backface culling for all viewers"));
globalBackfaceCullingAction_->setText(tr("Enable backface culling"));
}
//=============================================================================================================================
enabledCount = 0;
disabledCount = 0;
for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
if ( PluginFunctions::viewerProperties(i).twoSidedLighting() )
enabledCount++;
......@@ -538,27 +549,27 @@ void CoreWidget::slotViewMenuAboutToShow() {
if ( enabledCount != 0 && disabledCount != 0 ) {
globalTwosidedLightingAction_->setChecked(Qt::PartiallyChecked);
globalTwosidedLightingAction_->setToolTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setStatusTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setText(tr("Disable two-sided lighting"));
globalTwosidedLightingAction_->setToolTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setStatusTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setText(tr("Disable two-sided lighting"));
} else if ( enabledCount == 4 ) {
globalTwosidedLightingAction_->setChecked( Qt::Checked );
globalTwosidedLightingAction_->setToolTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setStatusTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setText(tr("Disable two-sided lighting"));
globalTwosidedLightingAction_->setToolTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setStatusTip(tr("Disable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setText(tr("Disable two-sided lighting"));
} else {
globalTwosidedLightingAction_->setChecked( Qt::Unchecked );
globalTwosidedLightingAction_->setToolTip(tr("Enable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setStatusTip(tr("Enable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setText(tr("Enable two-sided lighting"));
globalTwosidedLightingAction_->setToolTip(tr("Enable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setStatusTip(tr("Enable two-sided lighting for all viewers"));
globalTwosidedLightingAction_->setText(tr("Enable two-sided lighting"));
}
//=============================================================================================================================
enabledCount = 0;
disabledCount = 0;
for ( int i = 0 ; i< PluginFunctions::viewers(); ++i ) {
if ( PluginFunctions::viewerProperties(i).multisampling() )
enabledCount++;
......@@ -568,21 +579,21 @@ void CoreWidget::slotViewMenuAboutToShow() {
if ( enabledCount != 0 && disabledCount != 0 ) {
globalMultisamplingAction_->setChecked(Qt::PartiallyChecked);
globalMultisamplingAction_->setToolTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setStatusTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setToolTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setStatusTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setText(tr("Disable Multisampling"));
} else if ( enabledCount == 4 ) {
globalMultisamplingAction_->setChecked( Qt::Checked );
globalMultisamplingAction_->setToolTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setStatusTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setToolTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setStatusTip(tr("Disable Multisampling for all viewers"));
globalMultisamplingAction_->setText(tr("Disable Multisampling"));
} else {
globalMultisamplingAction_->setChecked( Qt::Unchecked );
globalMultisamplingAction_->setToolTip(tr("Enable Multisampling for all viewers"));
globalMultisamplingAction_->setStatusTip(tr("Enable Multisampling for all viewers"));
globalMultisamplingAction_->setToolTip(tr("Enable Multisampling for all viewers"));
globalMultisamplingAction_->setStatusTip(tr("Enable Multisampling for all viewers"));
globalMultisamplingAction_->setText(tr("Enable Multisampling"));
}
uint perspectiveCount = 0;
uint orthogonalCount = 0;
......
......@@ -75,7 +75,7 @@ void CoreWidget::slotToggleStereoMode()
}
cursorPainter_->setEnabled (stereoActive_);
for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
examiner_widgets_[i]->setStereoMode(stereoActive_);
}
......@@ -120,10 +120,20 @@ void CoreWidget::slotContextHomeView() {
void CoreWidget::slotSwitchWheels(bool _state) {
std::vector< glViewer* >::iterator it = examiner_widgets_.begin();
for(; it != examiner_widgets_.end(); it++)
for(; it != examiner_widgets_.end(); it++)
_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
void CoreWidget::slotGlobalHomeView() {
for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
......@@ -186,7 +196,7 @@ void CoreWidget::slotLocalChangeAnimation(bool _animation){
void CoreWidget::slotGlobalChangeBackFaceCulling(bool _backFaceCulling){
for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
PluginFunctions::viewerProperties(i).backFaceCulling(_backFaceCulling);
}
/// Set Backface culling for active viewer
......@@ -582,14 +592,14 @@ void CoreWidget::slotCoordSysVisibility(bool _visible){
return;
}
if (_visible)
if (_visible)
coordSys->show();
else
else
coordSys->hide();
for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
examiner_widgets_[i]->updateGL();
}
void CoreWidget::slotSetViewingDirection(QAction* _action) {
......
......@@ -169,6 +169,7 @@ glViewer::glViewer( QGraphicsScene* _scene,
normalsMode_ = DONT_TOUCH_NORMALS;
projectionMode_ = PERSPECTIVE_PROJECTION;
navigationMode_ = NORMAL_NAVIGATION;
light_matrix_.identity();
......@@ -332,6 +333,23 @@ void glViewer::projectionMode(ProjectionMode _p)
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()
{
......@@ -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,157 +1723,207 @@ void glViewer::dropEvent(QGraphicsSceneDragDropEvent* _e)
//-----------------------------------------------------------------------------
void
glViewer::viewMouseEvent(QMouseEvent* _event)
{
QPointF f (mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
QPoint pos (f.x(), f.y());
void glViewer::viewMouseEvent(QMouseEvent* _event) {
switch (_event->type())
{
case QEvent::MouseButtonPress:
{
// shift key -> set rotation center
if (_event->modifiers() & Qt::ShiftModifier)
{
ACG::Vec3d c;
if (fast_pick(pos, c))
{
trackball_center_ = c;
trackball_radius_ = std::max(scene_radius_, (c-glstate_->eye()).norm()*0.9f);
}
}
if (navigationMode_ == NORMAL_NAVIGATION) {
lastPoint_hitSphere_ = mapToSphere( lastPoint2D_= pos,
lastPoint3D_ );
isRotating_ = true;
timer_->stop();
treatNormalNavigation(_event);
} else if (navigationMode_ == EGOSHOOTER_NAVIGATION) {
break;
}
treatEgoShooterNavigation(_event);
}
}
//----------------------------------------------------------------------------
case QEvent::MouseButtonDblClick:
{
if (allowRotation_)
flyTo(_event->pos(), _event->button()==Qt::MidButton);
break;
}
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());
case QEvent::MouseMove:
{
double factor = 1.0;
switch (_event->type()) {
if (_event->modifiers() == Qt::ShiftModifier)
factor = properties_.wheelZoomFactorShift();
case QEvent::MouseButtonDblClick: {
if (allowRotation_)
flyTo(_event->pos(), _event->button() == Qt::MidButton);
break;
}
// mouse button should be pressed
if (_event->buttons() & (Qt::LeftButton | Qt::MidButton))
{
QPoint newPoint2D = pos;
case QEvent::MouseMove: {
double value_x, value_y;
ACG::Vec3d newPoint3D;
bool newPoint_hitSphere = mapToSphere( newPoint2D, newPoint3D );
// 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());
makeCurrent();
double x = 2.0 * newpos.x() / glWidth();
double y = 2.0 * newpos.y() / glHeight();
// move in z direction
if ( (_event->buttons() & Qt::LeftButton) &&
(_event->buttons() & Qt::MidButton))
{
switch (projectionMode())
{
case PERSPECTIVE_PROJECTION:
{
value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 3.0 / (double) glHeight();
translate( ACG::Vec3d(0.0, 0.0, value_y * factor ) );
updateGL();
break;
}
case ORTHOGRAPHIC_PROJECTION:
{
value_y = ((newPoint2D.y() - lastPoint2D_.y())) * orthoWidth_ / (double) glHeight();
orthoWidth_ -= value_y * factor;
updateProjectionMatrix();
updateGL();
break;
}
}
}
double xo = 2.0 * oldpos.x() / glWidth();
double yo = 2.0 * oldpos.y() / glHeight();
// move in x,y direction
else if ( (_event->buttons() & Qt::MidButton) || (!allowRotation_ && (_event->buttons() & Qt::LeftButton)))
{
value_x = scene_radius_ * ((newPoint2D.x() - lastPoint2D_.x())) * 2.0 / (double) glWidth();
value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 2.0 / (double) glHeight();
translate( ACG::Vec3d(value_x * factor , -value_y * factor , 0.0) );
}
double diffx = xo - x;
double diffy = yo - y;
// rotate
else if (allowRotation_ && (_event->buttons() & Qt::LeftButton) )
{
ACG::Vec3d axis(1.0,0.0,0.0);
double angle(0.0);
ACG::Vec3d yaxis(0.0, 1.0, 0.0);
ACG::Vec3d xaxis(1.0, 0.0, 0.0);
if ( lastPoint_hitSphere_ ) {
ACG::Vec3d eye = glstate_->modelview().transform_point(glstate_->eye());
if ( ( newPoint_hitSphere = mapToSphere( newPoint2D,
newPoint3D ) ) ) {
axis = lastPoint3D_ % newPoint3D;
double cos_angle = ( lastPoint3D_ | newPoint3D );
if ( fabs(cos_angle) < 1.0 ) {
angle = acos( cos_angle ) * 180.0 / M_PI * factor ;
angle *= 2.0; // inventor rotation
}
}
glstate_->rotate(-diffx * 90, 0.0, 1.0, 0.0);
glstate_->rotate(diffy * 90, 1.0, 0.0, 0.0);
rotate(axis, angle);
rotate(yaxis, -diffx * 90, glstate_->eye());
rotate(xaxis, diffy * 90, glstate_->eye());
}
lastPoint2D_ = pos;
lastRotationAxis_ = axis;
lastRotationAngle_ = angle;
}
updateGL();
lastMoveTime_.restart();
lastPoint2D_ = newPoint2D;
lastPoint3D_ = newPoint3D;
lastPoint_hitSphere_ = newPoint_hitSphere;
break;
}
updateGL();
lastMoveTime_.restart();
}
break;
}
default: // avoid warning
break;
}
}
//----------------------------------------------------------------------------
void glViewer::treatNormalNavigation( QMouseEvent* _event ) {
case QEvent::MouseButtonRelease:
{
lastPoint_hitSphere_ = false;
// continue rotation ?
if ( isRotating_ &&
(_event->button() == Qt::LeftButton) &&
(!(_event->buttons() & Qt::MidButton)) &&
(lastMoveTime_.elapsed() < 50) && properties_.animation() )
timer_->start(0);
break;
}
// Normal navigation mode is selected
QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
QPoint pos(f.x(), f.y());
default: // avoid warning
break;
}
switch (_event->type()) {
case QEvent::MouseButtonPress: {
// shift key -> set rotation center
if (_event->modifiers() & Qt::ShiftModifier) {
ACG::Vec3d c;
if (fast_pick(pos, c)) {
trackball_center_ = c;
trackball_radius_ = std::max(scene_radius_, (c - glstate_->eye()).norm() * 0.9f);
}
}
lastPoint_hitSphere_ = mapToSphere(lastPoint2D_ = pos, lastPoint3D_);
isRotating_ = true;
timer_->stop();
}
break;
}
case QEvent::MouseButtonDblClick: {
if (allowRotation_)
flyTo(_event->pos(), _event->button() == Qt::MidButton);
break;
}
case QEvent::MouseMove: {
double factor = 1.0;
if (_event->modifiers() == Qt::ShiftModifier)
factor = properties_.wheelZoomFactorShift();