| Home | Documentation | Download | Screenshots | Developer |
Illustration of the SpinningFrame class.
A SpinningFrame is useful to animate Frames that have a rotation motion. An optional rotationCenter can be provided to create excentered motions.
#include "qglviewer.h"
class Engine
{
public :
Engine();
void draw();
protected :
// The axis spinning frame of the conrod
qglviewer::SpinningFrame axisFrame_;
qglviewer::SpinningFrame conrodFrame_;
private:
void drawCone(const float zMin,const float zMax, const float r1, const float r2, const float nbSub);
void drawCylinder(const float zMin,const float zMax, const float r1, const float r2, const float nbSub);
};
class Viewer : public QGLViewer
{
protected :
void draw();
void init();
QString helpString() const;
private :
Engine engine;
};
#include "spinningFrame.h"
#include <math.h>
using namespace qglviewer;
using namespace std;
/////////////////////// E n g i n e ///////////////////////////////
Engine::Engine()
{
// Rotation around the Z axis. 0.04 radians increment.
axisFrame_.setSpinningQuaternion(Quaternion(Vec(0,0,1), 0.04));
// Same as axisFrame_, but with a rotationCenter
conrodFrame_.setSpinningQuaternion(axisFrame_.spinningQuaternion());
// Default rotation center is the world origin. Kept unchanged.
conrodFrame_.setRotateAroundCenter();
// The conrodFrame_ center is excentered to define the rotation radius.
conrodFrame_.setPosition(Vec(0.4, 0.0, 0.0));
// As the two spinningFrame are synchronized, there is not need to updateGL() for
// every SpinningFrame. We remove the first connection:
QGLViewer::disconnectSignalToAllViewers(&axisFrame_, SIGNAL(spinned()));
// Default update interval is 40 milliseconds.
axisFrame_.startSpinning();
conrodFrame_.startSpinning();
}
void Engine::draw()
{
// axisFrame_
glColor3f(.6, .4, .4);
glPushMatrix();
glMultMatrixd(axisFrame_.matrix());
drawCylinder(-0.3, 0.1, 0.1, 0.1, 50);
glRotatef(90, 0.0, 1.0, 0.0);
drawCone(0, 0.4, 0.1, 0.05, 50);
glPopMatrix();
// conrodFrame_
glColor3f(.4, .6, .4);
glPushMatrix();
glMultMatrixd(conrodFrame_.matrix());
drawCylinder(-0.1, 0.4, 0.05, 0.05, 50);
drawCylinder(0.1, 0.3, 0.1, 0.1, 50);
glPopMatrix();
// Other parts
glColor3f(.8, .8, .8);
Vec p = conrodFrame_.position();
const float L = 0.5;
float angle = atan2(p.x, L);
glTranslatef(0., 0.1 + p.y + L*cos(angle), .18);
glRotatef(-90, 1.0, 0.0, 0.0);
drawCylinder(0.0, 0.3, 0.15, 0.15, 50);
glRotatef(180+180*angle/M_PI, 0.0,-1.0,0.0);
drawCone(0.0, 1.1*L, 0.04, 0.04, 50);
}
// Draws a closed cylinder using drawCone()
void Engine::drawCylinder(const float zMin,const float zMax, const float r1, const float r2, const float nbSub)
{
float cap = 0.05 * (zMax - zMin);
drawCone(zMin-cap, zMin, 0.0, r1, nbSub);
drawCone(zMin, zMax, r1, r2, nbSub);
drawCone(zMax, zMax+cap, r2, 0.0, nbSub);
}
// Draws a truncated cone aligned with the Z axis.
void Engine::drawCone(const float zMin,const float zMax, const float r1, const float r2, const float nbSub)
{
float angle,c,s;
Vec normal, p1, p2;
glBegin(GL_QUAD_STRIP);
for (unsigned short i=0; i<=nbSub; ++i)
{
angle = 2.0 * M_PI * i / nbSub;
c = cos(angle);
s = sin(angle);
p1 = Vec(r1*c, r1*s, zMin);
p2 = Vec(r2*c, r2*s, zMax);
normal = cross(Vec(-s,c,0.0) , (p2-p1));
normal.normalize();
glNormal3fv(normal.address());
glVertex3fv(p1.address());
glVertex3fv(p2.address());
}
glEnd();
}
/////////////////////// V i e w e r ///////////////////////
void Viewer::init()
{
restoreFromFile();
camera()->lookAt(0.0, 0.5, 0.0);
help();
}
void Viewer::draw()
{
engine.draw();
}
QString Viewer::helpString() const
{
QString text("<h2>S p i n n i n g F r a m e</h2>");
text += "The main axis is animated using a <i>SpinningFrame</i> (red). ";
text += "An other <i>SpinningFrame</i> is used for the conrod (green), ";
text += "but a rotation center is defined, creating this circular motion. ";
text += "<i>SpinningFrame</i> are convenient to animate rotating scene objects.";
return text;
}
#include "spinningFrame.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