ObjetSimule.cpp

Aller à la documentation de ce fichier.
00001 /*
00002  * ObjetSimuleExpl.cpp : définition des objets animés.
00003  * Copyright (C) 2007 Florence Zara, LIRIS
00004  *               florence.zara@liris.univ-lyon1.fr
00005  *               http://liris.cnrs.fr/florence.zara/
00006  *
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License as published
00010  * by the Free Software Foundation; either version 2.1 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00028 #include <stdio.h>
00029 #include <vector>
00030 #include <string.h>
00031 #include <math.h>
00032 #include <iostream>
00033 #include <fstream>
00034 
00035 
00036 
00037 #include "Donnees.h"
00038 #include "Noeuds.h"
00039 #include "ObjetSimule.h"
00040 
00041 
00042 #ifdef WIN32
00043 #include <GL/glut.h> 
00044 #endif
00045 
00049 ObjetSimule::ObjetSimule(std::string fich_param) 
00050 : _Nb_Particules(0),
00051 _Nb_Ressorts(0), 
00052 _RessOS(),
00053 _Size(),
00054 P(0), 
00055 V(0), 
00056 A(0), 
00057 M(0),
00058 Force(0),
00059 Maillage(0)
00060 {
00061         
00063         Param_mesh(fich_param);
00064         
00065         
00066         /* Calcul du facteur d amortissement des ressorts */
00067         _RessOS.SetFactAmorti();
00068 
00069 
00070 }
00071         
00072 
00076 void ObjetSimule::init()
00077 {
00079         setOpenFile();
00080         
00083         setInit();
00084         
00085 }
00086 
00087 
00088 
00092 void ObjetSimule::setOpenFile()
00093 {
00096 
00097         std::ifstream _FichIn_Points(_Fich_Points.c_str());
00098 
00100         std::ifstream _FichIn_FaceSet(_Fich_FaceSet.c_str());
00101         
00103         std::ifstream _FichIn_Masses(_Fich_Masses.c_str());
00104 
00105         
00106         /* Fichier de donnees des positions */
00107         if (! _FichIn_Points)
00108                 std::cout << "Erreur d ouverture du fichier de donnees des points : " 
00109                         << _Fich_Points << std::endl;
00110 
00111         /* Fichier de donnees des faceSet */
00112         else if (! _FichIn_FaceSet)
00113                 std::cout << "Erreur d ouverture du fichier de donnees des faceSet : " 
00114                         << _Fich_FaceSet << std::endl; 
00115         
00116         /* Fichier des masses */
00117         else if (! _FichIn_Masses)
00118                 std::cout << "Erreur d ouverture du fichier de donnees des masses : " 
00119                         << _Fich_Masses << std::endl;
00120         
00121         else 
00122     {
00123                 /* Lecture du nombre de particules */
00124                 _FichIn_Points >> _Nb_Particules;
00125                 std::cout << "Nombre de particules " << _Nb_Particules <<std::endl;
00126                 
00127                 /* Allocation du maillage */
00128                 Maillage = new Mesh();
00129                 
00130     }//else
00131         
00132         /* Fermeture des fichiers */
00133         _FichIn_Points.close();
00134         _FichIn_FaceSet.close();
00135         _FichIn_Masses.close();
00136         
00137         std::cout << "Ouverture des fichiers de donnees... " << std::endl;
00138 }
00139 
00140 
00145 void ObjetSimule::setInit()
00146 { 
00147         /* Variable intermediaire pour la lecture des coordonnees des positions */
00148         float tmp_x, tmp_y, tmp_z;
00149         int tmp;
00150         
00151         /* Position min de toutes les particules */
00152         Coord Pmin (0.0,0.0,0.0);
00153         
00154         /* Position max de toutes les particules */
00155         Coord Pmax (0.0,0.0,0.0);
00156         
00157         
00159 
00160         std::ifstream _FichIn_Points(_Fich_Points.c_str());
00161         
00164         int trash;
00165         _FichIn_Points >> trash;
00166         
00168         while (!_FichIn_Points.eof())
00169         {
00170                 _FichIn_Points >> tmp_x;
00171                 _FichIn_Points >> tmp_y;
00172                 _FichIn_Points >> tmp_z;
00173                 
00175                 P.push_back(Coord(tmp_x, tmp_y, tmp_z));
00176         }
00177         
00178         
00180         std::ifstream _FichIn_Masses(_Fich_Masses.c_str());
00181 
00183         while (!_FichIn_Masses.eof())
00184         {
00185                 _FichIn_Masses >> tmp;
00186                 
00188                 M.push_back(tmp);
00189                                                                   
00190         }                                                         
00191 
00192         
00194         /* Calcul de Pmin et Pmax */
00195         for (int i=0; i<_Nb_Particules; ++i)
00196     {
00197                 Pmin = min(Pmin, P[i]);
00198                 Pmax = max(Pmax, P[i]);
00199     }
00200          
00201         
00202         /* Taille du tissu dans chacune des directions x, y, z */
00203         _Size.setX( fabs(Pmin.getX() - Pmax.getX()) );
00204         _Size.setY( fabs(Pmin.getY() - Pmax.getY()) );
00205         _Size.setZ( fabs(Pmin.getZ() - Pmax.getZ()) );
00206         
00207                         
00208         /*** Initialisation des tableaux pour chacune des particules ***/
00209         // bid = numero de bloc de la particule i
00210         for (int i=0; i<_Nb_Particules; ++i)
00211     {
00212                                 
00215                 V.push_back(Coord(0.0,0.0,0.0));
00216                 A.push_back(Coord(0.0,0.0,0.0));
00217                 Force.push_back(Coord(0.0,0.0,0.0));
00218                 
00219                 
00221                 /* Construction d une particule */
00222                 Particule *Part = new Particule();
00223                 
00224                 /* Attribution de son identificateur */
00225                 Part->SetId(i);
00226                 
00227                 /* Position de la particule */
00228                 Part->SetPosition(P[i]);
00229                 
00230                 /* Ajout de la particule dans le maillage */
00231                 Maillage->AddParticule(Part);
00232                 
00233                 
00234     }//for
00235         
00236         
00238         std::cout << "Position/mass read ..." << std::endl;
00239         
00240         
00242         /* Lecture de toutes les facettes */
00243         std::ifstream _FichIn_FaceSet(_Fich_FaceSet.c_str());
00244         
00246         int nb_facet = 0;
00247                 
00248         /* Construction des facettes */
00249         while (!_FichIn_FaceSet.eof())
00250     { 
00252                 FacetTriangle facet;
00253                 
00254                 _FichIn_FaceSet >> facet.fi;
00255                 _FichIn_FaceSet >> facet.fj;
00256                 _FichIn_FaceSet >> facet.fk;  
00257                 
00258                 /* Construction de la facette fi, fj, fk */
00259                 Maillage->MakeFace( Maillage->GetParticule(facet.fi), 
00260                                                         Maillage->GetParticule(facet.fj), 
00261                                                         Maillage->GetParticule(facet.fk), 
00262                                                         &_RessOS);
00263                 
00264                 // Recopie dans le tableau des indices des sommets
00265                 Maillage->_VIndices.push_back(facet.fi);
00266                 Maillage->_VIndices.push_back(facet.fj);
00267                 Maillage->_VIndices.push_back(facet.fk);
00268 
00269                 nb_facet ++; 
00270                 
00271     }
00272         
00273         /* Taille du tableau des indices des sommets */
00274         Maillage->_NFacets = nb_facet-1;
00275         Maillage->_VISize = 3 * Maillage->_NFacets;     
00276 
00277         
00279         _FichIn_FaceSet.close();
00280         _FichIn_Masses.close();
00281         _FichIn_Points.close();
00282 
00283         
00284         // Allocation du tableau des normales
00285         _NSize = 3 * _Nb_Particules;
00286         _Normals = new float[_NSize];
00287                         
00289         setNormals();
00290         
00292         std::cout << "Mesh build ..." << std::endl;
00293         
00294 }
00295 
00296 
00300 void ObjetSimule::Simulation(Coord gravite, float viscosite, int Tps)
00301 {
00302         /* Calcul des forces */  
00303         //std::cout << "Force.... " << std::endl;
00304     CalculForce();
00305 
00306         /* Calcul des accelerations (avec ajout de la gravite aux forces) */
00307         //std::cout << "Accel.... " << std::endl;
00308         CalculAccel(gravite);
00309                 
00310         /* Calcul des positions et vitesses */
00311         if (Tps == 0) 
00312         {
00313                 /* Calcul des vitesses et positions au temps 0 */
00314                 //std::cout << "PosVit Temps 0.... " << std::endl;
00315                 CalculPositionVitesseTps0(viscosite);
00316         }
00317         else
00318         {
00319                 /* Calcul des positions et vitesses au temps t */
00320                 //std::cout << "PosVit.... " << std::endl;
00321                 CalculPositionVitesse(viscosite);
00322                 
00323         }
00324         
00325         // Affichage des positions
00326 //      AffichagePos(Tps);
00327         
00329         setNormals();
00330         
00331 }
00332 
00333 
00337 void ObjetSimule::NormaleFace(Coord &normale, int a, int b, int c)
00338 {
00339         // Coordonnees des vecteurs AB et AC
00340         Coord AB, AC;
00341         
00342         
00343         /* Coordonnee du vecteur AB */
00344         AB.setX(P[b].getX() - P[a].getX());
00345         AB.setY(P[b].getY() - P[a].getY());
00346         AB.setZ(P[b].getZ() - P[a].getZ());
00347         
00348         /* Coordonnee du vecteur AC */
00349         AC.setX(P[c].getX() - P[a].getX());
00350         AC.setY(P[c].getY() - P[a].getY());
00351         AC.setZ(P[c].getZ() - P[a].getZ());
00352         
00353         /* Coordonnees de la normale */
00354         // Coordonnee en x de la normale 
00355         normale.setX( ((AB.getY()) * (AC.getZ())) - ((AB.getZ()) * (AC.getY())) );
00356         
00357         // Coordonnee en y de la normale 
00358         normale.setY( ((AB.getZ()) * (AC.getX())) - ((AB.getX()) * (AC.getZ())) );
00359         
00360         // Coordonnee en z de la normale 
00361         normale.setZ( ((AB.getX()) * (AC.getY())) - ((AB.getY()) * (AC.getX())) );
00362         
00363 }
00364 
00365 
00369 void ObjetSimule::setNormals()
00370 {
00371         // Normale d une face
00372         Coord normale;
00373         
00374         // Norme d une normale
00375         double Norme;
00376         
00377         // Indices des sommets d une face
00378         int a, b, c;
00379         
00380         /* Parcours des normales des sommets du maillage */
00381         for(unsigned int i=0; i<_NSize; ++i)
00382     {
00383                 // Initialisation des normales
00384                 _Normals[i] = 0;
00385     }
00386         
00387         /* Parcours des faces du maillage */
00388         for(unsigned int i=0; i<Maillage->_NFacets; ++i)
00389     {
00390                 // Sommets a, b, c de la face
00391                 a = Maillage->_VIndices[3 * i];
00392                 b = Maillage->_VIndices[(3 * i) + 1];
00393                 c = Maillage->_VIndices[(3 * i) + 2];
00394                 
00395                 // Calcul de la normale de la face
00396                 NormaleFace(normale, a, b, c); 
00397                 
00398                 // Modification des normales des sommets de la face
00399                 // Normale du sommet a
00400                 _Normals[(3 * a)] += normale.getX();
00401                 _Normals[(3 * a) + 1] += normale.getY();
00402                 _Normals[(3 * a) + 2] += normale.getZ();
00403                 
00404                 // Normale du sommet b
00405                 _Normals[(3 * b)] += normale.getX();
00406                 _Normals[(3 * b) + 1] += normale.getY();
00407                 _Normals[(3 * b) + 2] += normale.getZ();
00408                 
00409                 // Normale du sommet c
00410                 _Normals[(3 * c)] += normale.getX();
00411                 _Normals[(3 * c) + 1] += normale.getY();
00412                 _Normals[(3 * c) + 2] += normale.getZ();
00413                 
00414     }//for_i
00415         
00416         /* Parcours des normales des sommets */
00417         for(unsigned int i=0; i<_NSize; i+=3)
00418     {
00419                 // Norme de la normale
00420                 Norme = sqrt((_Normals[i] * _Normals[i]) 
00421                                          + (_Normals[i+1] * _Normals[i+1]) 
00422                                          + (_Normals[i+2] * _Normals[i+2]));
00423                 
00424                 // Normalisation de la normale
00425                 if (Norme !=0)
00426         {
00427                         _Normals[i] /= Norme;
00428                         _Normals[i+1] /= Norme;
00429                         _Normals[i+2] /= Norme;
00430         }
00431     }
00432 }
00433 
00434 
00438 void ObjetSimule::AffichagePos(int tps)
00439 {
00440         /* Affichage des vecteurs par bloc */
00441         for(int i=0; i<_Nb_Particules; ++i)
00442         {
00443                 // Affichage du temps
00444                 std::cout << "[T=" << tps;
00445                 
00446                 // Ecriture du numero de la particule
00447                 std::cout << " ; Part=" << i;
00448                 
00449                 std::cout << " ; P="; 
00450                 
00451                 // Affichage des coordonnees de la position
00452                 std::cout.precision(4);
00453                 
00454                 std::cout << P[i].getX() << " " <<  P[i].getY()  
00455                 <<  " " << P[i].getZ()  << std::endl;
00456                 
00457     }//for_i
00458 }
00459 
00460 
00465 void ObjetSimule::affiche()  
00466 {
00467         // std::cout << "------ ObjetSimule::affiche() ----------- " << std::endl;              
00468 
00469         
00471         glPushMatrix();
00472         
00473         /* Mise a l echelle des objets la scene */
00474         glScalef(0.3, 0.3, 0.3);
00475         
00476         /* Translation */
00477         glTranslatef(0, 3, 1);
00478         
00479         
00481 
00482         
00483         /* Restauration de la matrice courante */
00484         glPopMatrix();
00485         
00486 }

Généré le Thu Jan 24 19:11:42 2008 pour Animation 3D par  doxygen 1.5.1