Sophie

Sophie

distrib > Mandriva > 10.0-com > i586 > by-pkgid > 9347541fe87a5ea3f3b8dbc50f660e8e > files > 182

libQGLViewer-devel-1.3.6-1mdk.i586.rpm

#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.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;
}