Home Documentation Download Screenshots Developper

spinningFrame

spinningFrame

Frame spinning capabilities using a QTimer

Note : this example is deprecated. Use the spinningFrame class (to come) instead. You should be able to set the frame rotation axis and speed over time with this class.

spinningFrame.h

#include "qglviewer.h"

class Engine : public QObject
{
  Q_OBJECT
    
public :
  Engine();
  void draw();
  void addViewer(const QGLViewer* v) { connect(timer_, SIGNAL(timeout()), v, SLOT(updateGL())); };
  
protected :
  // The axis frame of the conrod
  qglviewer::Frame frame_;
  // A QTimer that regurily calls update()
  QTimer* timer_;

 protected slots:
  void update();
  
private:
  // Utility function
  void drawCone(const float zMin,const float zMax, const float r1, const float r2, const float nbSub);
};



class Viewer : public QGLViewer
{
protected :
  void draw();
  void init();
  void help();
  
  protected: 
  Engine engine;
};

main.cpp

#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();
}

spinningFrame.cpp

#include "spinningFrame.h"
#include <math.h>

using namespace qglviewer;
using namespace std;

///////////////////////   V i e w e r  ///////////////////////
void Viewer::init()
{
  engine.addViewer(this);
  camera.lookAt(0.0, 0.5, 0.0);
  help();
}

void Viewer::draw()
{
  engine.draw();
}

void Viewer::help()
{
  cout << endl << "\t\t- -  S p i n n i n g F r a m e  - -" << endl << endl;
  cout << "Using a QTimer, a Frame can be animated. The timer regularly updates" << endl;
  cout << "the angle of the rotation axis and asks for a viewer display update." << endl;
  cout << "Only the main axis is spinning, the positions of the other parts are" << endl;
  cout << "infered, using the frame coordinate system transformation functions." << endl << endl;
}

///////////////////////   E n g i n e ///////////////////////////////

Engine::Engine()
{
  timer_ = new QTimer();
  connect(timer_, SIGNAL(timeout()), this, SLOT(update()));
  timer_->start(40); // 25Hz
}

void Engine::update()
{
  static Quaternion increment(Vec(0.0 ,0.0 ,1.0 ), 0.04);
  frame_.rotate(increment);
}

void Engine::draw()
{
  glPushMatrix();

  glMultMatrixd(frame_.matrix());

  drawCone(-0.32, -0.3, 0., 0.1, 50);
  drawCone(-0.3, 0.1, 0.1, 0.1, 50);
  drawCone(0.1, 0.12, 0.1, 0.0, 50);

  glRotatef(90, 0.0,1.0,0.0);
  drawCone(0, 0.4, 0.1, 0.05, 50);
  
  glRotatef(-90, 0.0,1.0,0.0);
  glTranslatef(0.4,0,0);
  drawCone(-0.12, -0.1, 0.0, 0.05, 50);
  drawCone(-0.1, 0.3, 0.05, 0.05, 50);
  drawCone(0.3, 0.32, 0.05, 0.0, 50);

  drawCone(0.13, 0.14, 0.06, 0.1, 50);
  drawCone(0.14, 0.27, 0.1, 0.1, 50);
  drawCone(0.27, 0.28, 0.1, 0.06, 50);

  glPopMatrix();

  Vec p = frame_.inverseCoordinatesOf(Vec(.4,0.,0.));
  const float L = 0.5;
  float angle = atan2(p.x, L);
  glTranslatef(0., 0.1 + p.y + L*cos(angle), .2);
  glRotatef(-90, 1.0,0.0,0.0);
  drawCone(0.0, 0.3, 0.15, 0.15, 50);
  drawCone(0.3, 0.33, 0.15, 0., 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 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();
}

Back to the main page

Valid XHTML 1.0! Valid CSS!