Sophie

Sophie

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

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

<!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 constrainedFrame 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 constrainedFrame example</h1>
<center>
  <img src="../images/constrainedFrame.jpg" width="300" height="200" alt="constrainedFrame"/>
</center>

<p>
 Constraints can limit the translation and/or rotation of a (Manipulated)Frame.
</p>
<p>
 Try the different possible constraints using the T (translate) and R (rotate) keys. G and D change
 the constraint directions. Press Space to change the coordinate system (World, Camera or Local)
 which defines the constraint directions.
</p>
<p>
 Press the Control key while moving the mouse to move the camera.
</p>


<h2>constrainedFrame.h</h2>
<pre>

<span class="dir">#include &lt;QGLViewer/qglviewer.h&gt;
</span>
<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>init();
  <span class="key">virtual </span><span class="typ">void </span>draw();
  <span class="key">virtual </span>QString helpString() <span class="typ">const</span>;
  <span class="key">virtual </span><span class="typ">void </span>keyPressEvent(QKeyEvent *);

  <span class="typ">void </span>displayText();
  <span class="typ">void </span>displayType(<span class="typ">const </span>qglviewer::AxisPlaneConstraint::Type type, <span class="typ">const int </span>x, <span class="typ">const int </span>y, <span class="typ">const char </span>c);
  <span class="typ">void </span>displayDir(<span class="typ">const unsigned short </span>dir, <span class="typ">const int </span>x, <span class="typ">const int </span>y, <span class="typ">const char </span>c);

<span class="key">private</span>:
  <span class="typ">int </span>transDir;
  <span class="typ">int </span>rotDir;

  qglviewer::ManipulatedFrame* frame;

  <span class="typ">void </span>changeConstraint();
  qglviewer::AxisPlaneConstraint* constraints[<span class="num">3</span>];
  <span class="typ">unsigned short </span>activeConstraint;
};</pre>


<h2>constrainedFrame.cpp</h2>
<pre>

<span class="dir">#include </span><span class="dstr">&quot;constrainedFrame.h&quot;</span><span class="dir">
</span>
<span class="key">using namespace </span>qglviewer;
<span class="key">using namespace </span>std;

<span class="typ">static </span>AxisPlaneConstraint::Type nextTranslationConstraintType(<span class="typ">const </span>AxisPlaneConstraint::Type&amp; type)
{
  <span class="key">switch </span>(type)
    {
    <span class="key">case </span>AxisPlaneConstraint::FREE  : <span class="key">return </span>AxisPlaneConstraint::PLANE; <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::PLANE : <span class="key">return </span>AxisPlaneConstraint::AXIS;  <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::AXIS  : <span class="key">return </span>AxisPlaneConstraint::FORBIDDEN;  <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::FORBIDDEN : <span class="key">return </span>AxisPlaneConstraint::FREE; <span class="key">break</span>;
    <span class="key">default </span>: <span class="key">return </span>AxisPlaneConstraint::FREE;
    }
}

<span class="typ">static </span>AxisPlaneConstraint::Type nextRotationConstraintType(<span class="typ">const </span>AxisPlaneConstraint::Type&amp; type)
{
  <span class="key">switch </span>(type)
    {
    <span class="key">case </span>AxisPlaneConstraint::FREE  : <span class="key">return </span>AxisPlaneConstraint::AXIS; <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::PLANE : <span class="key">return </span>AxisPlaneConstraint::FREE; <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::AXIS  : <span class="key">return </span>AxisPlaneConstraint::FORBIDDEN;  <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::FORBIDDEN : <span class="key">return </span>AxisPlaneConstraint::FREE; <span class="key">break</span>;
    <span class="key">default </span>: <span class="key">return </span>AxisPlaneConstraint::FREE;
    }
}

<span class="typ">void </span>Viewer::changeConstraint()
{
  <span class="typ">unsigned short </span>previous = activeConstraint;
  activeConstraint = (activeConstraint+<span class="num">1</span>)%<span class="num">3</span>;

  constraints[activeConstraint]-&gt;setTranslationConstraintType(constraints[previous]-&gt;translationConstraintType());
  constraints[activeConstraint]-&gt;setTranslationConstraintDir (constraints[previous]-&gt;translationConstraintDir());
  constraints[activeConstraint]-&gt;setRotationConstraintType   (constraints[previous]-&gt;rotationConstraintType());
  constraints[activeConstraint]-&gt;setRotationConstraintDir    (constraints[previous]-&gt;rotationConstraintDir());

  frame-&gt;setConstraint(constraints[activeConstraint]);
}

<span class="typ">void </span>Viewer::init()
{
  constraints[<span class="num">0</span>] = <span class="key">new </span>LocalConstraint();
  constraints[<span class="num">1</span>] = <span class="key">new </span>WorldConstraint();
  constraints[<span class="num">2</span>] = <span class="key">new </span>CameraConstraint(camera());

  transDir = <span class="num">0</span>; <span class="com">// X direction
</span>  rotDir   = <span class="num">0</span>; <span class="com">// X direction
</span>  activeConstraint = <span class="num">0</span>;

  frame = <span class="key">new </span>ManipulatedFrame();
  setManipulatedFrame(frame);
  frame-&gt;setConstraint(constraints[activeConstraint]);

  <span class="com">// Preserve CAMERA bindings, see setMouseStateKey documentation.
</span>  setMouseStateKey(QGLViewer::CAMERA, Qt::AltButton);
  <span class="com">// The frames can be move without any key pressed
</span>  setMouseStateKey(QGLViewer::FRAME, Qt::NoButton);
  <span class="com">// The camera can always be moved with the Control key.
</span>  setMouseStateKey(QGLViewer::CAMERA, Qt::ControlButton);

  setDrawAxis();

  restoreFromFile();
  help();
}

<span class="typ">void </span>Viewer::draw()
{
  glMultMatrixd(frame-&gt;matrix());
  drawAxis(<span class="num">0.4</span>);
  <span class="typ">const float </span>scale = <span class="num">0.3</span>;
  glScalef(scale, scale, scale);

  <span class="typ">const float </span>nbSteps = <span class="num">500.0</span>;
  glBegin(GL_QUAD_STRIP);
  <span class="key">for </span>(<span class="typ">float </span>i=<span class="num">0</span>; i&lt;nbSteps; ++i)
    {
      <span class="typ">float </span>ratio = i/nbSteps;
      <span class="typ">float </span>angle = <span class="num">21.0</span>*ratio;
      <span class="typ">float </span>c = cos(angle);
      <span class="typ">float </span>s = sin(angle);
      <span class="typ">float </span>r1 = <span class="num">1.0 </span>- <span class="num">0.8</span>*ratio;
      <span class="typ">float </span>r2 = <span class="num">0.8 </span>- <span class="num">0.8</span>*ratio;
      <span class="typ">float </span>alt = ratio <span class="num">- 0.5</span>;
      <span class="typ">const float </span>nor = .<span class="num">5</span>;
      <span class="typ">const float </span>up = sqrt(<span class="num">1.0</span>-nor*nor);
      glColor3f(<span class="num">1</span>-ratio, .<span class="num">2 </span>, ratio);
      glNormal3f(nor*c*scale, up*scale, nor*s*scale);
      glVertex3f(r1*c, alt, r1*s);
      glVertex3f(r2*c, alt+<span class="num">0.05</span>, r2*s);
    }
  glEnd();

  displayText();
}

<span class="typ">void </span>Viewer::keyPressEvent(QKeyEvent *e)
{
  <span class="key">switch </span>(e-&gt;key())
    {
    <span class="key">case </span>Qt::Key_G : transDir = (transDir+<span class="num">1</span>)%<span class="num">3</span>; <span class="key">break</span>;
    <span class="key">case </span>Qt::Key_D : rotDir   = (rotDir+<span class="num">1</span>)%<span class="num">3</span>;   <span class="key">break</span>;
    <span class="key">case </span>Qt::Key_Space: changeConstraint();     <span class="key">break</span>;
    <span class="key">case </span>Qt::Key_T :
      constraints[activeConstraint]-&gt;setTranslationConstraintType(nextTranslationConstraintType(constraints[activeConstraint]-&gt;translationConstraintType()));
      <span class="key">break</span>;
    <span class="key">case </span>Qt::Key_R :
      constraints[activeConstraint]-&gt;setRotationConstraintType(nextRotationConstraintType(constraints[activeConstraint]-&gt;rotationConstraintType()));
      <span class="key">break</span>;
    <span class="key">default</span>:
      QGLViewer::keyPressEvent(e);
    }

  Vec dir(<span class="num">0.0</span>,<span class="num">0.0</span>,<span class="num">0.0</span>);
  dir[transDir] = <span class="num">1.0</span>;
  constraints[activeConstraint]-&gt;setTranslationConstraintDir(dir);

  dir = Vec(<span class="num">0.0</span>,<span class="num">0.0</span>,<span class="num">0.0</span>);
  dir[rotDir] = <span class="num">1.0</span>;
  constraints[activeConstraint]-&gt;setRotationConstraintDir(dir);

  updateGL();
}

<span class="typ">void </span>Viewer::displayType(<span class="typ">const </span>AxisPlaneConstraint::Type type, <span class="typ">const int </span>x, <span class="typ">const int </span>y, <span class="typ">const char </span>c)
{
  <span class="typ">char </span>text[<span class="num">12</span>];
  <span class="key">switch </span>(type)
    {
    <span class="key">case </span>AxisPlaneConstraint::FREE:  sprintf(text, <span class="str">&quot;FREE (%c)&quot;</span>, c);  <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::PLANE: sprintf(text, <span class="str">&quot;PLANE (%c)&quot;</span>, c); <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::AXIS:  sprintf(text, <span class="str">&quot;AXIS (%c)&quot;</span>, c);  <span class="key">break</span>;
    <span class="key">case </span>AxisPlaneConstraint::FORBIDDEN:   sprintf(text, <span class="str">&quot;FORBIDDEN (%c)&quot;</span>, c);   <span class="key">break</span>;
    }
  drawText(x, y, text);
}

<span class="typ">void </span>Viewer::displayDir(<span class="typ">const unsigned short </span>dir, <span class="typ">const int </span>x, <span class="typ">const int </span>y, <span class="typ">const char </span>c)
{
  <span class="typ">char </span>text[<span class="num">6</span>];
  <span class="key">switch </span>(dir)
    {
    <span class="key">case </span><span class="num">0</span>:  sprintf(text, <span class="str">&quot;X (%c)&quot;</span>, c);  <span class="key">break</span>;
    <span class="key">case </span><span class="num">1</span>:  sprintf(text, <span class="str">&quot;Y (%c)&quot;</span>, c);  <span class="key">break</span>;
    <span class="key">case </span><span class="num">2</span>:  sprintf(text, <span class="str">&quot;Z (%c)&quot;</span>, c);  <span class="key">break</span>;
    }
  drawText(x, y, text);
}

<span class="typ">void </span>Viewer::displayText()
{
  glColor3fv(foregroundColor().address());
  glDisable(GL_LIGHTING);
  drawText(<span class="num">10</span>, height()<span class="num">-30</span>, <span class="str">&quot;TRANSLATION :&quot;</span>);
  displayDir(transDir, <span class="num">190</span>, height()<span class="num">-30</span>, <span class="str">'G'</span>);
  displayType(constraints[activeConstraint]-&gt;translationConstraintType(), <span class="num">10</span>, height()<span class="num">-60</span>, <span class="str">'T'</span>);

  drawText(width()<span class="num">-220</span>,height()<span class="num">-30</span>, <span class="str">&quot;ROTATION&quot;</span>);
  displayDir(rotDir, width()<span class="num">-100</span>, height()<span class="num">-30</span>, <span class="str">'D'</span>);
  displayType(constraints[activeConstraint]-&gt;rotationConstraintType(), width()<span class="num">-220</span>, height()<span class="num">-60</span>, <span class="str">'R'</span>);

  <span class="key">switch </span>(activeConstraint)
    {
    <span class="key">case </span><span class="num">0 </span>: drawText(<span class="num">20</span>,<span class="num">20</span>, <span class="str">&quot;Constraint direction defined w/r to LOCAL (SPACE)&quot;</span>); <span class="key">break</span>;
    <span class="key">case </span><span class="num">1 </span>: drawText(<span class="num">20</span>,<span class="num">20</span>, <span class="str">&quot;Constraint direction defined w/r to WORLD (SPACE)&quot;</span>); <span class="key">break</span>;
    <span class="key">case </span><span class="num">2 </span>: drawText(<span class="num">20</span>,<span class="num">20</span>, <span class="str">&quot;Constraint direction defined w/r to CAMERA (SPACE)&quot;</span>); <span class="key">break</span>;
    }
}

QString Viewer::helpString() <span class="typ">const
</span>{
  QString text(<span class="str">&quot;&lt;h2&gt;C o n s t r a i n e d F r a m e&lt;/h2&gt;&quot;</span>);
  text += <span class="str">&quot;A manipulated frame can be constrained in its displacement.&lt;br&gt;&quot;</span>;
  text += <span class="str">&quot;Try the different translation (press &lt;b&gt;G&lt;/b&gt; and &lt;b&gt;T&lt;/b&gt;) and rotation &quot;</span>;
  text += <span class="str">&quot;(&lt;b&gt;D&lt;/b&gt; and &lt;b&gt;R&lt;/b&gt;) constraints while moving the frame with the mouse.&lt;br&gt;&quot;</span>;
  text += <span class="str">&quot;The constraints can be defined with respect to various coordinates&quot;</span>;
  text += <span class="str">&quot;systems : press &lt;b&gt;Space&lt;/b&gt; to switch.&lt;br&gt;&quot;</span>;
  text += <span class="str">&quot;Press the &lt;b&gt;Control&lt;/b&gt; key while moving the mouse to move the camera.&lt;br&gt;&quot;</span>;
  text += <span class="str">&quot;You can easily define your own constraints to create a specific frame behavior.&quot;</span>;
  <span class="key">return </span>text;
}
</pre>


<h2>main.cpp</h2>
<pre>

<span class="dir">#include </span><span class="dstr">&quot;constrainedFrame.h&quot;</span><span class="dir">
</span><span class="dir">#include &lt;qapplication.h&gt;
</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(&amp;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>