| Home | Documentation | Download | Screenshots | Developer |
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.h"
class Viewer : public QGLViewer
{
protected:
void init();
void draw();
QString helpString() const;
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:
unsigned short transDir;
unsigned short 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]->setTranslationConstraintDir (constraints[previous]->translationConstraintDir());
constraints[activeConstraint]->setRotationConstraintType (constraints[previous]->rotationConstraintType());
constraints[activeConstraint]->setRotationConstraintDir (constraints[previous]->rotationConstraintDir());
camera()->frame()->setConstraint(constraints[activeConstraint]);
}
void Viewer::init()
{
restoreFromFile();
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]);
setDrawAxis();
help();
}
void Viewer::draw()
{
const float nbSteps = 500.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]->setTranslationConstraintDir(dir);
dir = Vec(0.0,0.0,0.0);
dir[rotDir] = 1.0;
constraints[activeConstraint]->setRotationConstraintDir(dir);
updateGL();
}
void Viewer::displayType(const AxisPlaneConstraint::Type type, const int x, const int y, const char c)
{
char text[12];
switch (type)
{
case AxisPlaneConstraint::FREE: sprintf(text, "FREE (%c)", c); break;
case AxisPlaneConstraint::PLANE: sprintf(text, "PLANE (%c)", c); break;
case AxisPlaneConstraint::AXIS: sprintf(text, "AXIS (%c)", c); break;
case AxisPlaneConstraint::FORBIDDEN: sprintf(text, "FORBIDDEN (%c)", c); break;
}
drawText(x, y, text);
}
void Viewer::displayDir(const unsigned short dir, const int x, const int y, const char c)
{
char text[6];
switch (dir)
{
case 0: sprintf(text, "X (%c)", c); break;
case 1: sprintf(text, "Y (%c)", c); break;
case 2: sprintf(text, "Z (%c)", c); break;
}
drawText(x, y, text);
}
void Viewer::displayText()
{
glColor3fv(foregroundColor().address());
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;
}
}
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>";
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 frame with the mouse. ";
text += "The constraints can be defined with respect to various coordinates ";
text += "systems : press <b>Space</b> to switch.<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)
{
// Read command lines arguments.
QApplication application(argc,argv);
// Instantiate the viewer.
Viewer v;
// Make the viewer window visible on screen.
v.show();
// Set the viewer as the application main widget.
application.setMainWidget(&v);
// Run main loop.
return application.exec();
}
Back to the main page