Sophie

Sophie

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

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

<p>
 The LGPL lib3ds library is used to load and display a 3ds scene.
</p>
<p>
 You need to install the lib3ds library (version 1.2) in order to compile this file.
 See <a href="http://lib3ds.sourceforge.net/">http://lib3ds.sourceforge.net/</a>.
</p>
<p>
 The current version (Ver 1.2, Dec 2002) of the lib3ds library is flawed and a patched
 version is available on the <a href="../rpm.html">libQGLViewer rpm page</a>.
</p>
<p>
 Alternately, you can add the following line in <code>lib3ds/file.h</code> :
 extern LIB3DSAPI void lib3ds_file_bounding_box(Lib3dsFile *file, Lib3dsVector min, Lib3dsVector max);
</p>
<p>
 Once this is done, edit <code>3dsViewer.pro</code>, set <code>LIB3DS_IS_INSTALLED</code> to
 <code>yes</code> and set <code>INCLUDEPATH</code> and <code>LIBS</code> to the path where you
 installed lib3ds.
</p>
<p>
 Press '<b>L</b>' (load) to load a new 3DS scene. 
</p>


<h2>3dsViewer.h</h2>
<pre>

<span class="dir">#include &lt;QGLViewer/qglviewer.h&gt;
</span>
<span class="dir">#include &lt;lib3ds/file.h&gt;
</span><span class="dir">#include &lt;lib3ds/node.h&gt;
</span>
<span class="key">class </span>Viewer : <span class="key">public </span>QGLViewer
{
<span class="key">public </span>:
  Viewer() : file(NULL), current_frame(<span class="num">0.0</span>), camera_name(NULL) {};

<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>animate();
  <span class="key">virtual </span><span class="typ">void </span>init();
  <span class="key">virtual </span><span class="typ">void </span>keyPressEvent(QKeyEvent *e);
  <span class="key">virtual </span>QString helpString() <span class="typ">const</span>;

  <span class="typ">void </span>renderNode(Lib3dsNode *node);
  <span class="typ">void </span>loadFile();
  <span class="typ">void </span>initScene();

<span class="key">private </span>:
  Lib3dsFile *file;
  <span class="typ">float </span>current_frame;
  <span class="typ">char</span>* camera_name;
};</pre>


<h2>3dsViewer.cpp</h2>
<pre>

<span class="dir">#include </span><span class="dstr">&quot;3dsViewer.h&quot;</span><span class="dir">
</span>
<span class="dir">#include &lt;lib3ds/camera.h&gt;
</span><span class="dir">#include &lt;lib3ds/mesh.h&gt;
</span><span class="dir">#include &lt;lib3ds/material.h&gt;
</span><span class="dir">#include &lt;lib3ds/matrix.h&gt;
</span><span class="dir">#include &lt;lib3ds/vector.h&gt;
</span><span class="dir">#include &lt;lib3ds/light.h&gt;
</span><span class="dir">#include &lt;string.h&gt;
</span><span class="dir">#include &lt;stdlib.h&gt;
</span><span class="dir">#include &lt;math.h&gt;
</span><span class="dir">#include &lt;qfiledialog.h&gt;
</span>
<span class="key">using namespace </span>std;
<span class="key">using namespace </span>qglviewer;


<span class="typ">void </span>Viewer::keyPressEvent(QKeyEvent *e)
{
  <span class="key">switch </span>(e-&gt;key())
    {
    <span class="key">case </span>Qt::Key_L : loadFile(); <span class="key">break</span>;
    <span class="key">default</span>:         QGLViewer::keyPressEvent(e);
    }
}

QString Viewer::helpString() <span class="typ">const
</span>{
  QString text(<span class="str">&quot;&lt;h2&gt;3 d s V i e w e r&lt;/h2&gt;&quot;</span>);
  text += <span class="str">&quot;This example uses the lib3ds library to load a 3ds object file. &quot;</span>;
  text += <span class="str">&quot;Press &lt;b&gt;L&lt;/b&gt;(oad) to open a 3ds file. &quot;</span>;
  text += <span class="str">&quot;Note that certain 3ds files contain animated sequences that can &quot;</span>;
  text += <span class="str">&quot;be played using the &lt;b&gt;Return&lt;/b&gt; (animate) key.&quot;</span>;
  <span class="key">return </span>text;
}

<span class="typ">void </span>Viewer::loadFile()
{
  QString name = QFileDialog::getOpenFileName(<span class="str">&quot;&quot;</span>, <span class="str">&quot;3DS files (*.3ds *.3DS);;All files (*)&quot;</span>, <span class="key">this</span>);

  <span class="com">// In case of Cancel
</span>  <span class="key">if </span>(name.isEmpty())
    <span class="key">return</span>;

  file = lib3ds_file_load(name.latin1());
  <span class="key">if </span>(!file)
    {
      cout &lt;&lt; <span class="str">&quot;Error : Unable to open file &quot;</span> &lt;&lt; name &lt;&lt; endl;
      exit(<span class="num">1</span>);
    }

  <span class="key">if </span>(file-&gt;cameras)
    camera_name = file-&gt;cameras-&gt;name;
  <span class="key">else
    </span>camera_name = NULL;

  lib3ds_file_eval(file,<span class="num">0</span>);

  initScene();

  <span class="typ">float </span>min[<span class="num">3</span>], max[<span class="num">3</span>];
  lib3ds_file_bounding_box(file, min, max);
  setSceneBoundingBox(Vec(min), Vec(max));
  <span class="key">if </span>(!file-&gt;cameras)
    camera()-&gt;showEntireScene();
  <span class="key">else
    </span>updateGL();
  stopAnimation();
}


<span class="typ">void </span>Viewer::init()
{
  glShadeModel(GL_SMOOTH);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glDisable(GL_LIGHT1);
  glDepthFunc(GL_LEQUAL);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_COLOR_MATERIAL);
  glEnable(GL_CULL_FACE);
  glCullFace(GL_BACK);

  restoreFromFile();
  help();
  loadFile();
}


<span class="typ">void </span>Viewer::initScene()
{
  <span class="key">if </span>(!file)
    <span class="key">return</span>;

  <span class="com">// Lights
</span>  GLfloat amb[] = {<span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">1.0</span>};
  GLfloat dif[] = {<span class="num">1.0</span>, <span class="num">1.0</span>, <span class="num">1.0</span>, <span class="num">1.0</span>};
  GLfloat spe[] = {<span class="num">1.0</span>, <span class="num">1.0</span>, <span class="num">1.0</span>, <span class="num">1.0</span>};
  GLfloat pos[] = {<span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">1.0</span>};
  <span class="typ">int </span>li=GL_LIGHT0;
  <span class="key">for </span>(Lib3dsLight* l=file-&gt;lights; l; l=l-&gt;next)
    {
      glEnable(li);

      glLightfv(li, GL_AMBIENT,  amb);
      glLightfv(li, GL_DIFFUSE,  dif);
      glLightfv(li, GL_SPECULAR, spe);

      pos[<span class="num">0</span>] = l-&gt;position[<span class="num">0</span>];
      pos[<span class="num">1</span>] = l-&gt;position[<span class="num">1</span>];
      pos[<span class="num">2</span>] = l-&gt;position[<span class="num">2</span>];
      glLightfv(li, GL_POSITION, pos);

      <span class="key">if </span>(!l-&gt;spot_light)
	  <span class="key">continue</span>;

      pos[<span class="num">0</span>] = l-&gt;spot[<span class="num">0</span>] - l-&gt;position[<span class="num">0</span>];
      pos[<span class="num">1</span>] = l-&gt;spot[<span class="num">1</span>] - l-&gt;position[<span class="num">1</span>];
      pos[<span class="num">2</span>] = l-&gt;spot[<span class="num">2</span>] - l-&gt;position[<span class="num">2</span>];
      glLightfv(li, GL_SPOT_DIRECTION, pos);
      ++li;
    }

  <span class="com">// Camera
</span>  Lib3dsNode* c = lib3ds_file_node_by_name(file, camera_name, LIB3DS_CAMERA_NODE);
  Lib3dsNode* t = lib3ds_file_node_by_name(file, camera_name, LIB3DS_TARGET_NODE);
  <span class="key">if </span>(!c || !t)
    <span class="key">return</span>;

  <span class="com">// Lib3dsMatrix M;
</span>  <span class="com">// lib3ds_matrix_camera(M, c-&gt;data.camera.pos, t-&gt;data.target.pos, c-&gt;data.camera.roll);
</span>
  <span class="com">// cout &lt;&lt; &quot;Pos = &quot; &lt;&lt; Vec(c-&gt;data.camera.pos) &lt;&lt; endl;
</span>  <span class="com">// cout &lt;&lt; &quot;Tar = &quot; &lt;&lt; Vec(t-&gt;data.target.pos) &lt;&lt; endl;
</span>  <span class="com">// cout &lt;&lt; &quot;Rol = &quot; &lt;&lt; c-&gt;data.camera.roll &lt;&lt; endl;
</span>
  camera()-&gt;setPosition(Vec(c-&gt;data.camera.pos));
  camera()-&gt;lookAt(Vec(t-&gt;data.target.pos));
  Vec up=camera()-&gt;frame()-&gt;transformOf(Vec(<span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">1.0</span>));
  <span class="typ">float </span>angle=atan2(up.x, up.y);
  Quaternion q(Vec(<span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">1.0</span>), c-&gt;data.camera.roll-angle);
  camera()-&gt;frame()-&gt;rotate(q);
  camera()-&gt;setFieldOfView(M_PI/<span class="num">180.0</span>*c-&gt;data.camera.fov);
}


<span class="typ">void </span>Viewer::renderNode(Lib3dsNode *node)
{
  <span class="key">for </span>(Lib3dsNode* p=node-&gt;childs; p!=<span class="num">0</span>; p=p-&gt;next)
    renderNode(p);

  <span class="key">if </span>(node-&gt;type == LIB3DS_OBJECT_NODE)
    {
      <span class="key">if </span>(strcmp(node-&gt;name,<span class="str">&quot;$$$DUMMY&quot;</span>)==<span class="num">0</span>)
	<span class="key">return</span>;

      <span class="key">if </span>(!node-&gt;user.d)
	{
	  Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node-&gt;name);
	  <span class="key">if </span>(!mesh)
	    <span class="key">return</span>;

	  node-&gt;user.d = glGenLists(<span class="num">1</span>);
	  glNewList(node-&gt;user.d, GL_COMPILE);

	  Lib3dsVector *normalL = <span class="key">new </span>Lib3dsVector[<span class="num">3</span>*mesh-&gt;faces];

	  Lib3dsMatrix M;
	  lib3ds_matrix_copy(M, mesh-&gt;matrix);
	  lib3ds_matrix_inv(M);
	  glMultMatrixf(&amp;M[<span class="num">0</span>][<span class="num">0</span>]);

	  lib3ds_mesh_calculate_normals(mesh, normalL);

	  <span class="key">for </span>(<span class="typ">unsigned int </span>p=<span class="num">0</span>; p&lt;mesh-&gt;faces; ++p)
	    {
	      Lib3dsFace *f=&amp;mesh-&gt;faceL[p];
	      Lib3dsMaterial *mat=<span class="num">0</span>;
	      <span class="key">if </span>(f-&gt;material[<span class="num">0</span>])
		mat=lib3ds_file_material_by_name(file, f-&gt;material);

	      <span class="key">if </span>(mat)
		{
		  <span class="typ">static </span>GLfloat a[<span class="num">4</span>]={<span class="num">0</span>,<span class="num">0</span>,<span class="num">0</span>,<span class="num">1</span>};
		  <span class="typ">float </span>s;
		  glMaterialfv(GL_FRONT, GL_AMBIENT, a);
		  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat-&gt;diffuse);
		  glMaterialfv(GL_FRONT, GL_SPECULAR, mat-&gt;specular);
		  s = pow(<span class="num">2</span>, <span class="num">10.0</span>*mat-&gt;shininess);
		  <span class="key">if </span>(s&gt;<span class="num">128.0</span>)
		    s=<span class="num">128.0</span>;
		  glMaterialf(GL_FRONT, GL_SHININESS, s);
		}
	      <span class="key">else
		</span>{
		  Lib3dsRgba a={<span class="num">0.2</span>, <span class="num">0.2</span>, <span class="num">0.2</span>, <span class="num">1.0</span>};
		  Lib3dsRgba d={<span class="num">0.8</span>, <span class="num">0.8</span>, <span class="num">0.8</span>, <span class="num">1.0</span>};
		  Lib3dsRgba s={<span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">0.0</span>, <span class="num">1.0</span>};
		  glMaterialfv(GL_FRONT, GL_AMBIENT, a);
		  glMaterialfv(GL_FRONT, GL_DIFFUSE, d);
		  glMaterialfv(GL_FRONT, GL_SPECULAR, s);
		}

	      glBegin(GL_TRIANGLES);
	      glNormal3fv(f-&gt;normal);
	      <span class="key">for </span>(<span class="typ">int </span>i=<span class="num">0</span>; i&lt;<span class="num">3</span>; ++i)
		{
		  glNormal3fv(normalL[<span class="num">3</span>*p+i]);
		  glVertex3fv(mesh-&gt;pointL[f-&gt;points[i]].pos);
		}
	      glEnd();
	    }

	  <span class="key">delete</span>[] normalL;

	  glEndList();
	}

      <span class="key">if </span>(node-&gt;user.d)
	{
	  glPushMatrix();
	  Lib3dsObjectData* d = &amp;node-&gt;data.object;
	  glMultMatrixf(&amp;node-&gt;matrix[<span class="num">0</span>][<span class="num">0</span>]);
	  glTranslatef(-d-&gt;pivot[<span class="num">0</span>], -d-&gt;pivot[<span class="num">1</span>], -d-&gt;pivot[<span class="num">2</span>]);
	  glCallList(node-&gt;user.d);
	  glPopMatrix();
	}
    }
}


<span class="typ">void </span>Viewer::draw()
{
  <span class="key">if </span>(!file)
    <span class="key">return</span>;

  <span class="key">for </span>(Lib3dsNode* p=file-&gt;nodes; p!=<span class="num">0</span>; p=p-&gt;next)
    renderNode(p);
}


<span class="typ">void </span>Viewer::animate()
{
  current_frame++;
  <span class="key">if </span>(current_frame &gt; file-&gt;frames)
    current_frame=<span class="num">0</span>;
  lib3ds_file_eval(file, current_frame);
  initScene();
}</pre>


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

<span class="dir">#include </span><span class="dstr">&quot;3dsViewer.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, show it on screen.
</span>  Viewer viewer;
  viewer.show();

  <span class="com">// Set the viewer as the application main widget.
</span>  application.setMainWidget(&amp;viewer);

  <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>