Sophie

Sophie

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

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

<p>
 A <code>TriangleSetConstraint</code> constrains the camera displacement.
</p>
<p>
 The camera is constrained to stay above a given 'road' defined
 by triangles. Camera is in FLY mode.
</p>
<p>
 The example is a little bit complex : the computations needed
 to get the intersection of the Z-direction and the triangle are
 cut and pasted from the triangleSetConstraint class, in order to
 draw interesting debugging informations.
</p>


<h2>triSetConstraint.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="typ">void </span>init();
  <span class="typ">void </span>draw();
  <span class="typ">void </span>displayConstraint(qglviewer::Vec);
};</pre>


<h2>triSetConstraint.cpp</h2>
<pre>

<span class="dir">#include </span><span class="dstr">&quot;triSetConstraint.h&quot;</span><span class="dir">
</span><span class="dir">#include &lt;QGLViewer/triangleSetConstraint.h&gt;
</span><span class="dir">#include &lt;math.h&gt;
</span>
<span class="key">using namespace </span>qglviewer;


<span class="typ">static bool </span>segmentIntersection(<span class="typ">const </span>Vec&amp; p, <span class="typ">const </span>Vec&amp; dir1, <span class="typ">const </span>Vec&amp; norm,
				<span class="typ">const </span>Vec&amp; s1, <span class="typ">const </span>Vec&amp; s2,
				Vec&amp; inter)
{
  <span class="com">// dir1 is supposed to be normalized.
</span>  Vec perp = cross(dir1, norm);

  <span class="com">// Check for near-parallel lines
</span>  <span class="typ">float </span>n = perp.norm();

  <span class="com">// Degenerated case : parallel lines
</span>  <span class="key">if </span>(n &lt; <span class="num">1.E</span>-<span class="num">10</span>)
    <span class="key">return false</span>;

  perp /= n;

  <span class="typ">float </span>proj = (s2 - s1) * perp;
  <span class="typ">float </span>alpha = ((p-s1)*perp) / proj;
  <span class="key">if </span>( (alpha &lt; <span class="num">0.0</span>) || (alpha &gt; <span class="num">1.0</span>) )
    <span class="key">return false</span>;

  <span class="com">// else
</span>  inter = s1 + (s2-s1) * alpha;
  <span class="key">return true</span>;
}


<span class="com">/* Constrain the translation \p trans with respect to a path defined by a triangle set. See addTriangle() and addPoint(). */</span>
<span class="typ">void </span>Viewer::displayConstraint(Vec trans)
{
  TriangleSetConstraint* tsc = (TriangleSetConstraint*)(camera()-&gt;frame()-&gt;constraint());
  <span class="typ">unsigned int </span>currentTriangle = tsc-&gt;currentTriangle();
  trans = camera()-&gt;frame()-&gt;inverseTransformOf(trans);
  Vec pos, nextPos, start;
  start = camera()-&gt;position();
  pos = start;
  <span class="typ">unsigned short </span>nextEdge;
  <span class="typ">const float </span>dist = trans.norm();
  <span class="key">if </span>(dist &lt; <span class="num">1E</span>-<span class="num">8</span>)
    <span class="key">return</span>;
  trans /= dist;

  <span class="com">// Draw the current triangle
</span>  glColor3f(.<span class="num">6</span>,.<span class="num">2</span>,<span class="num">6</span>);
  glLineWidth(<span class="num">4.0</span>);
  glBegin(GL_TRIANGLES);
  glVertex3fv(tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">0</span>)).address());
  glVertex3fv(tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">1</span>)).address());
  glVertex3fv(tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">2</span>)).address());
  glEnd();

  glColor3f(.<span class="num">8</span>,.<span class="num">5</span>,<span class="num">0</span>);
  glPointSize(<span class="num">10.0</span>);
  glBegin(GL_POINTS); glVertex3fv(start.address()); glEnd();
  glLineWidth(<span class="num">1.0</span>);
  glBegin(GL_LINES); glVertex3fv(start.address()); glVertex3fv((start+trans).address()); glEnd();

  glColor3f(.<span class="num">4</span>,.<span class="num">6</span>,.<span class="num">7</span>);
  glPointSize(<span class="num">5.0</span>);

  <span class="key">while </span>(<span class="key">true</span>)
    {
      <span class="typ">float </span>step = <span class="num">-1.0E9f</span>;
      nextEdge = <span class="num">3</span>;
      Vec e1 = tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">0</span>)) - tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">1</span>));
      Vec e2 = tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">0</span>)) - tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,<span class="num">2</span>));
      Vec norm = cross(e1, e2);
      Vec res;

      <span class="key">for </span>(<span class="typ">unsigned short </span>edge=<span class="num">0</span>; edge&lt;<span class="num">3</span>; edge++)
	{
	  <span class="key">if </span>(segmentIntersection(pos, trans, norm,
				  tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,(edge+<span class="num">1</span>)%<span class="num">3</span>)),
				  tsc-&gt;point(tsc-&gt;trianglePoint(currentTriangle,(edge+<span class="num">2</span>)%<span class="num">3</span>)), res))
	    {
	      <span class="key">if </span>((res-pos)*trans &gt; step)
		{
		  step = (res-pos)*trans;
		  nextPos = res;
		  nextEdge = edge;
		}
	    }
	}

      glBegin(GL_POINTS); glVertex3fv(nextPos.address()); glEnd();

      <span class="typ">float </span>soFar = (nextPos-start)*trans;
      <span class="key">if </span>((soFar &gt; dist) || (tsc-&gt;neighTriangle(currentTriangle,nextEdge) == <span class="num">-1</span>))
	<span class="key">return</span>;

      currentTriangle = tsc-&gt;neighTriangle(currentTriangle,nextEdge);

      pos = nextPos;
    }
}

<span class="typ">static const float </span>nbSteps = <span class="num">20.0</span>;
<span class="typ">static const float </span>r = <span class="num">0.7</span>;

<span class="typ">void </span>Viewer::init()
{
  setSceneRadius(<span class="num">3.0</span>);
  camera()-&gt;setFlySpeed(<span class="num">0.001</span>);
  <span class="com">// Use fly mode mouse bindings
</span>  toggleCameraMode();
  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

  TriangleSetConstraint* tsc = <span class="key">new </span>TriangleSetConstraint();
  camera()-&gt;frame()-&gt;setConstraint(tsc);

  tsc-&gt;addPoint(Vec(<span class="num">1.0</span>,<span class="num">0.0</span>,<span class="num">0.0</span>));
  tsc-&gt;addPoint(Vec(r   ,<span class="num">0.0</span>,<span class="num">0.0</span>));
  <span class="key">for </span>(<span class="typ">int </span>i=<span class="num">1</span>; i&lt;nbSteps; ++i)
    {
      <span class="typ">float </span>angle = <span class="num">2.0 </span>* M_PI * i / nbSteps;
      tsc-&gt;addPoint(Vec(cos(angle)  , sin(angle)  , <span class="num">0.0</span>)); <span class="com">// index 2i
</span>      tsc-&gt;addPoint(Vec(r*cos(angle), r*sin(angle), <span class="num">0.0</span>)); <span class="com">// index 2i+1
</span>
      tsc-&gt;addTriangle(<span class="num">2</span>*i-1, <span class="num">2</span>*i, <span class="num">2</span>*i+<span class="num">1</span>);
      tsc-&gt;addTriangle(<span class="num">2</span>*i-1, <span class="num">2</span>*i-2, <span class="num">2</span>*i);
    }
  tsc-&gt;addTriangle(<span class="num">0</span>, <span class="num">2</span>*(<span class="typ">int</span>)nbSteps-2, <span class="num">2</span>*(<span class="typ">int</span>)nbSteps-1);
  tsc-&gt;addTriangle(<span class="num">0</span>, <span class="num">1</span>, <span class="num">2</span>*(<span class="typ">int</span>)nbSteps-1);
  tsc-&gt;setCurrentTriangle(<span class="num">1</span>);

  camera()-&gt;setOrientation(Quaternion(Vec(<span class="num">1</span>,<span class="num">0</span>,<span class="num">0</span>), M_PI/<span class="num">2.0</span>));
  camera()-&gt;setPosition(<span class="num">0.85</span>, <span class="num">0.05</span>, <span class="num">0.0</span>);
}

<span class="typ">void </span>Viewer::draw()
{
  <span class="com">// The camera is made visible by reseting the modelview matrix
</span>  glLoadIdentity();
  glTranslatef(<span class="num">0.0</span>,<span class="num">0.0</span>,<span class="num">-2.5</span>);

  <span class="com">// Draw Road
</span>  glNormal3f(<span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">1.0</span>);
  glColor3f(.<span class="num">2</span>,.<span class="num">6</span>,.<span class="num">8</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>angle = <span class="num">2.0 </span>* M_PI * i / nbSteps;
      glVertex3f(cos(angle),   sin(angle),   <span class="num">0.0</span>);
      glVertex3f(r*cos(angle), r*sin(angle), <span class="num">0.0</span>);
    }
  glEnd();

  <span class="com">// Draw camera position
</span>  Vec pos = camera()-&gt;position();
  glPointSize(<span class="num">5.0</span>);
  glBegin(GL_POINTS);
  glVertex3fv(pos.address());
  glEnd();

  displayConstraint(Vec(<span class="num">0</span>,<span class="num">0</span>,<span class="num">-1</span>));
}
</pre>


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

<span class="dir">#include </span><span class="dstr">&quot;triSetConstraint.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 Friday, November 7, 2003.</i>
</p>

</body>
</html>