SpinningFrame
s are handy to create rotations.
A SpinningFrame is useful to animate Frames that have a rotation motion.
An optional rotationCenter
can be provided to create excentered motions.
#include <QGLViewer/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 : virtual void draw(); virtual void init(); virtual 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_ position 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 connect the two spinned() // signals to the updateGL() slot. We connect the axisFrame_ spinned signal only. QGLViewer::connectSignalToAllViewers(&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); glVertex3fv(p1); glVertex3fv(p2); } 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.<br><br>"; 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(); }
Go back to the examples main page