Constraints applied on the Camera Frame to limit its translation and/or rotation.
Try the different possible constraints using the T (translate) and R (rotate) keys. G and D change the constraint directions. Press Space to change the coordinate system (World or Camera) which defines the constraint directions.
Note that in order to apply a constraint to a camera, you need to apply it to the camera()->frame().
#include <QGLViewer/qglviewer.h> class Viewer : public QGLViewer { protected: virtual void init(); virtual void draw(); virtual QString helpString() const; virtual void keyPressEvent(QKeyEvent *); void displayText(); void displayType(const qglviewer::AxisPlaneConstraint::Type type, const int x, const int y, const char c); void displayDir(const unsigned short dir, const int x, const int y, const char c); private: int transDir; int rotDir; void changeConstraint(); qglviewer::AxisPlaneConstraint* constraints[2]; unsigned short activeConstraint; };
#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; i<nbSteps; ++i) { float ratio = i/nbSteps; float angle = 21.0*ratio; float c = cos(angle); float s = sin(angle); float r1 = 1.0 - 0.8*ratio; float r2 = 0.8 - 0.8*ratio; float alt = ratio - 0.5; const float nor = .5; const float up = sqrt(1.0-nor*nor); glColor3f(1-ratio, .2 , ratio); glNormal3f(nor*c, up, nor*s); glVertex3f(r1*c, alt, r1*s); glVertex3f(r2*c, alt+0.05, r2*s); } glEnd(); displayText(); } void Viewer::keyPressEvent(QKeyEvent *e) { switch (e->key()) { 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("<h2>C o n s t r a i n e d C a m e r a</h2>"); text += "The camera frame can be constrained to limit the camera displacements.<br><br>"; text += "Try the different translation (press <b>G</b> and <b>T</b>) and rotation "; text += "(<b>D</b> and <b>R</b>) constraints while moving the camera with the mouse. "; text += "The constraints can be defined with respect to various coordinates "; text += "systems : press <b>Space</b> to switch.<br><br>"; text += "You can easily define your own constraints to create a specific camera constraint."; return text; }
#include "constrainedCamera.h" #include <qapplication.h> int main(int argc, char** argv) { QApplication application(argc,argv); Viewer viewer; #if QT_VERSION < 0x040000 application.setMainWidget(&viewer); #else viewer.setWindowTitle("constrainedCamera"); #endif viewer.show(); return application.exec(); }
Back to the examples main page.