/**************************************************************************** Copyright (C) 2002-2006 Gilles Debunne (Gilles.Debunne@imag.fr) This file is part of the QGLViewer library. Version 2.2.4-1, released on December 12, 2006. http://artis.imag.fr/Members/Gilles.Debunne/QGLViewer libQGLViewer is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libQGLViewer 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 General Public License for more details. You should have received a copy of the GNU General Public License along with libQGLViewer; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ #include "constrainedCamera.h" using namespace qglviewer; using namespace std; static AxisPlaneConstraint::Type nextTranslationConstraintType(const AxisPlaneConstraint::Type& type) { switch (type) { case AxisPlaneConstraint::FREE : return AxisPlaneConstraint::PLANE; break; case AxisPlaneConstraint::PLANE : return AxisPlaneConstraint::AXIS; break; case AxisPlaneConstraint::AXIS : return AxisPlaneConstraint::FORBIDDEN; break; case AxisPlaneConstraint::FORBIDDEN : return AxisPlaneConstraint::FREE; break; default : return AxisPlaneConstraint::FREE; } } static AxisPlaneConstraint::Type nextRotationConstraintType(const AxisPlaneConstraint::Type& type) { switch (type) { case AxisPlaneConstraint::FREE : return AxisPlaneConstraint::AXIS; break; case AxisPlaneConstraint::PLANE : return AxisPlaneConstraint::FREE; break; case AxisPlaneConstraint::AXIS : return AxisPlaneConstraint::FORBIDDEN; break; case AxisPlaneConstraint::FORBIDDEN : return AxisPlaneConstraint::FREE; break; default : return AxisPlaneConstraint::FREE; } } void Viewer::changeConstraint() { unsigned short previous = activeConstraint; activeConstraint = (activeConstraint+1)%2; constraints[activeConstraint]->setTranslationConstraintType(constraints[previous]->translationConstraintType()); constraints[activeConstraint]->setTranslationConstraintDirection(constraints[previous]->translationConstraintDirection()); constraints[activeConstraint]->setRotationConstraintType(constraints[previous]->rotationConstraintType()); constraints[activeConstraint]->setRotationConstraintDirection(constraints[previous]->rotationConstraintDirection()); camera()->frame()->setConstraint(constraints[activeConstraint]); } void Viewer::init() { restoreStateFromFile(); constraints[0] = new WorldConstraint(); // Note that a CameraConstraint(camera) would produce the same results: // A CameraConstraint is a LocalConstraint when applied to the camera frame ! constraints[1] = new LocalConstraint(); transDir = 0; rotDir = 0; activeConstraint = 0; camera()->frame()->setConstraint(constraints[activeConstraint]); setAxisIsDrawn(); setKeyDescription(Qt::Key_G, "Change translation constraint direction"); setKeyDescription(Qt::Key_D, "Change rotation constraint direction"); setKeyDescription(Qt::Key_Space, "Change constraint reference"); setKeyDescription(Qt::Key_T, "Change translation constraint type"); setKeyDescription(Qt::Key_R, "Change rotation constraint type"); help(); } void Viewer::draw() { const float nbSteps = 200.0; glBegin(GL_QUAD_STRIP); for (float i=0; ikey()) { case Qt::Key_G : transDir = (transDir+1)%3; break; case Qt::Key_D : rotDir = (rotDir+1)%3; break; case Qt::Key_Space: changeConstraint(); break; case Qt::Key_T : constraints[activeConstraint]->setTranslationConstraintType(nextTranslationConstraintType(constraints[activeConstraint]->translationConstraintType())); break; case Qt::Key_R : constraints[activeConstraint]->setRotationConstraintType(nextRotationConstraintType(constraints[activeConstraint]->rotationConstraintType())); break; default: QGLViewer::keyPressEvent(e); } Vec dir(0.0, 0.0, 0.0); dir[transDir] = 1.0; constraints[activeConstraint]->setTranslationConstraintDirection(dir); dir = Vec(0.0, 0.0, 0.0); dir[rotDir] = 1.0; constraints[activeConstraint]->setRotationConstraintDirection(dir); updateGL(); } void Viewer::displayType(const AxisPlaneConstraint::Type type, const int x, const int y, const char c) { QString text; switch (type) { case AxisPlaneConstraint::FREE: text = QString("FREE (%1)").arg(c); break; case AxisPlaneConstraint::PLANE: text = QString("PLANE (%1)").arg(c); break; case AxisPlaneConstraint::AXIS: text = QString("AXIS (%1)").arg(c); break; case AxisPlaneConstraint::FORBIDDEN: text = QString("FORBIDDEN (%1)").arg(c); break; } drawText(x, y, text); } void Viewer::displayDir(const unsigned short dir, const int x, const int y, const char c) { QString text; switch (dir) { case 0: text = QString("X (%1)").arg(c); break; case 1: text = QString("Y (%1)").arg(c); break; case 2: text = QString("Z (%1)").arg(c); break; } drawText(x, y, text); } void Viewer::displayText() { qglColor(foregroundColor()); glDisable(GL_LIGHTING); drawText(10,height()-30, "TRANSLATION :"); displayDir(transDir, 190, height()-30, 'G'); displayType(constraints[activeConstraint]->translationConstraintType(), 10, height()-60, 'T'); drawText(width()-220,height()-30, "ROTATION :"); displayDir(rotDir, width()-100, height()-30, 'D'); displayType(constraints[activeConstraint]->rotationConstraintType(), width()-220, height()-60, 'R'); switch (activeConstraint) { case 0 : drawText(20,20, "Constraint direction defined w/r to WORLD (SPACE)"); break; case 1 : drawText(20,20, "Constraint direction defined w/r to CAMERA (SPACE)"); break; } glEnable(GL_LIGHTING); } QString Viewer::helpString() const { QString text("

C o n s t r a i n e d C a m e r a

"); text += "The camera frame can be constrained to limit the camera displacements.

"; text += "Try the different translation (press G and T) and rotation "; text += "(D and R) constraints while moving the camera with the mouse. "; text += "The constraints can be defined with respect to various coordinates "; text += "systems : press Space to switch.

"; text += "You can easily define your own constraints to create a specific camera constraint."; return text; }