<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>libQGLViewer spinningFrame example</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <link href="../qglviewer.css" rel="stylesheet" type="text/css" /> <link rel="shortcut icon" href="../images/qglviewer.ico" type="image/x-icon" /> <link rel="icon" href="../images/qglviewer.icon.png" type="image/png" /> </head> <body> <table class="banner"> <tr> <td align="center"><a href="../index.html"><b>Home</b></a></td> <td align="center"><a href="../refManual/hierarchy.html"><b>Documentation</b></a></td> <td align="center"><a href="../download.html"><b>Download</b></a></td> <td align="center" class="qindexHL"><a href="index.html"><b>Screenshots</b></a></td> <td align="center"><a href="../developer.html"><b>Developer</b></a></td> </tr> </table> <h1>The spinningFrame example</h1> <center> <img src="../images/spinningFrame.jpg" width="300" height="200" alt="spinningFrame"/> </center> <p> Illustration of the <code>SpinningFrame</code> class. </p> <p> A SpinningFrame is useful to animate Frames that have a rotation motion. An optional <code>rotationCenter</code> can be provided to create excentered motions. </p> <h2>spinningFrame.h</h2> <pre> <span class="dir">#include <QGLViewer/qglviewer.h> </span> <span class="key">class </span>Engine { <span class="key">public </span>: Engine(); <span class="typ">void </span>draw(); <span class="key">protected </span>: <span class="com">// The axis spinning frame of the conrod </span> qglviewer::SpinningFrame axisFrame_; qglviewer::SpinningFrame conrodFrame_; <span class="key">private</span>: <span class="typ">void </span>drawCone(<span class="typ">const float </span>zMin,<span class="typ">const float </span>zMax, <span class="typ">const float </span>r1, <span class="typ">const float </span>r2, <span class="typ">const float </span>nbSub); <span class="typ">void </span>drawCylinder(<span class="typ">const float </span>zMin,<span class="typ">const float </span>zMax, <span class="typ">const float </span>r1, <span class="typ">const float </span>r2, <span class="typ">const float </span>nbSub); }; <span class="key">class </span>Viewer : <span class="key">public </span>QGLViewer { <span class="key">protected </span>: <span class="key">virtual </span><span class="typ">void </span>draw(); <span class="key">virtual </span><span class="typ">void </span>init(); <span class="key">virtual </span>QString helpString() <span class="typ">const</span>; <span class="key">private </span>: Engine engine; };</pre> <h2>spinningFrame.cpp</h2> <pre> <span class="dir">#include </span><span class="dstr">"spinningFrame.h"</span><span class="dir"> </span><span class="dir">#include <math.h> </span> <span class="key">using namespace </span>qglviewer; <span class="key">using namespace </span>std; <span class="com">/////////////////////// E n g i n e /////////////////////////////// </span> Engine::Engine() { <span class="com">// Rotation around the Z axis. 0.04 radians increment. </span> axisFrame_.setSpinningQuaternion(Quaternion(Vec(<span class="num">0</span>,<span class="num">0</span>,<span class="num">1</span>), <span class="num">0.04</span>)); <span class="com">// Same as axisFrame_, but with a rotationCenter </span> conrodFrame_.setSpinningQuaternion(axisFrame_.spinningQuaternion()); <span class="com">// Default rotation center is the world origin. Kept unchanged. </span> conrodFrame_.setRotateAroundCenter(); <span class="com">// The conrodFrame_ position is excentered to define the rotation radius. </span> conrodFrame_.setPosition(Vec(<span class="num">0.4</span>, <span class="num">0.0</span>, <span class="num">0.0</span>)); <span class="com">// As the two spinningFrame are synchronized, there is not need to connect the two spinned() </span> <span class="com">// signals to the updateGL() slot. We connect the axisFrame_ spinned signal only. </span> QGLViewer::connectSignalToAllViewers(&axisFrame_, SIGNAL(spinned())); <span class="com">// Default update interval is 40 milliseconds. </span> axisFrame_.startSpinning(); conrodFrame_.startSpinning(); } <span class="typ">void </span>Engine::draw() { <span class="com">// axisFrame_ </span> glColor3f(.<span class="num">6</span>, .<span class="num">4</span>, .<span class="num">4</span>); glPushMatrix(); glMultMatrixd(axisFrame_.matrix()); drawCylinder(<span class="num">-0.3</span>, <span class="num">0.1</span>, <span class="num">0.1</span>, <span class="num">0.1</span>, <span class="num">50</span>); glRotatef(<span class="num">90</span>, <span class="num">0.0</span>, <span class="num">1.0</span>, <span class="num">0.0</span>); drawCone(<span class="num">0</span>, <span class="num">0.4</span>, <span class="num">0.1</span>, <span class="num">0.05</span>, <span class="num">50</span>); glPopMatrix(); <span class="com">// conrodFrame_ </span> glColor3f(.<span class="num">4</span>, .<span class="num">6</span>, .<span class="num">4</span>); glPushMatrix(); glMultMatrixd(conrodFrame_.matrix()); drawCylinder(<span class="num">-0.1</span>, <span class="num">0.4</span>, <span class="num">0.05</span>, <span class="num">0.05</span>, <span class="num">50</span>); drawCylinder(<span class="num">0.1</span>, <span class="num">0.3</span>, <span class="num">0.1</span>, <span class="num">0.1</span>, <span class="num">50</span>); glPopMatrix(); <span class="com">// Other parts </span> glColor3f(.<span class="num">8</span>, .<span class="num">8</span>, .<span class="num">8</span>); Vec p = conrodFrame_.position(); <span class="typ">const float </span>L = <span class="num">0.5</span>; <span class="typ">float </span>angle = atan2(p.x, L); glTranslatef(<span class="num">0.</span>, <span class="num">0.1 </span>+ p.y + L*cos(angle), .<span class="num">18</span>); glRotatef(<span class="num">-90</span>, <span class="num">1.0</span>, <span class="num">0.0</span>, <span class="num">0.0</span>); drawCylinder(<span class="num">0.0</span>, <span class="num">0.3</span>, <span class="num">0.15</span>, <span class="num">0.15</span>, <span class="num">50</span>); glRotatef(<span class="num">180</span>+<span class="num">180</span>*angle/M_PI, <span class="num">0.0</span>,<span class="num">-1.0</span>,<span class="num">0.0</span>); drawCone(<span class="num">0.0</span>, <span class="num">1.1</span>*L, <span class="num">0.04</span>, <span class="num">0.04</span>, <span class="num">50</span>); } <span class="com">// Draws a closed cylinder using drawCone() </span><span class="typ">void </span>Engine::drawCylinder(<span class="typ">const float </span>zMin,<span class="typ">const float </span>zMax, <span class="typ">const float </span>r1, <span class="typ">const float </span>r2, <span class="typ">const float </span>nbSub) { <span class="typ">float </span>cap = <span class="num">0.05 </span>* (zMax - zMin); drawCone(zMin-cap, zMin, <span class="num">0.0</span>, r1, nbSub); drawCone(zMin, zMax, r1, r2, nbSub); drawCone(zMax, zMax+cap, r2, <span class="num">0.0</span>, nbSub); } <span class="com">// Draws a truncated cone aligned with the Z axis. </span><span class="typ">void </span>Engine::drawCone(<span class="typ">const float </span>zMin,<span class="typ">const float </span>zMax, <span class="typ">const float </span>r1, <span class="typ">const float </span>r2, <span class="typ">const float </span>nbSub) { <span class="typ">float </span>angle,c,s; Vec normal, p1, p2; glBegin(GL_QUAD_STRIP); <span class="key">for </span>(<span class="typ">unsigned short </span>i=<span class="num">0</span>; i<=nbSub; ++i) { angle = <span class="num">2.0 </span>* 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,<span class="num">0.0</span>) , (p2-p1)); normal.normalize(); glNormal3fv(normal.address()); glVertex3fv(p1.address()); glVertex3fv(p2.address()); } glEnd(); } <span class="com">/////////////////////// V i e w e r /////////////////////// </span><span class="typ">void </span>Viewer::init() { restoreFromFile(); camera()->lookAt(<span class="num">0.0</span>, <span class="num">0.5</span>, <span class="num">0.0</span>); help(); } <span class="typ">void </span>Viewer::draw() { engine.draw(); } QString Viewer::helpString() <span class="typ">const </span>{ QString text(<span class="str">"<h2>S p i n n i n g F r a m e</h2>"</span>); text += <span class="str">"The main axis is animated using a <i>SpinningFrame</i> (red). "</span>; text += <span class="str">"An other <i>SpinningFrame</i> is used for the conrod (green), "</span>; text += <span class="str">"but a rotation center is defined, creating this circular motion. "</span>; text += <span class="str">"<i>SpinningFrame</i> are convenient to animate rotating scene objects."</span>; <span class="key">return </span>text; }</pre> <h2>main.cpp</h2> <pre> <span class="dir">#include </span><span class="dstr">"spinningFrame.h"</span><span class="dir"> </span><span class="dir">#include <qapplication.h> </span> <span class="typ">int </span>main(<span class="typ">int </span>argc, <span class="typ">char</span>** argv) { <span class="com">// Read command lines arguments. </span> QApplication application(argc,argv); <span class="com">// Instantiate the viewer. </span> Viewer v; <span class="com">// Make the viewer window visible on screen. </span> v.show(); <span class="com">// Set the viewer as the application main widget. </span> application.setMainWidget(&v); <span class="com">// Run main loop. </span> <span class="key">return </span>application.exec(); }</pre> <p> <a href="index.html">Go back</a> to the examples main page </p> <p> <a href="http://validator.w3.org/check/referer"><img src="../images/xhtml.png" alt="Valid XHTML 1.0!" height="31" width="88" border="0"/></a> <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="../images/css.png" width="88" height="31" alt="Valid CSS!" border="0"/></a> <i>Last modified on Thursday, February 5, 2004.</i> </p> </body> </html>