src/scene3D.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by                                                 *
00003  *         Pierre-yves JEZEQUEL, Julien MICHOT, Loic MOISAN,               *
00004  *         Julien PAPILLON, Sebastien PINEAUD, Barthelemy SERRES           *
00005  *                                                                         *
00006  *   https://sourceforge.net/projects/anidam                               *
00007  *                                                                         *
00008  *   This program is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 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 General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this program; if not, write to the                         *
00020  *   Free Software Foundation, Inc.,                                       *
00021  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00022  ***************************************************************************/
00023 #include <string>
00024 #include "scene3D.h"
00025 #include "skyBox.h"
00026 #include "waterdyn3d.h"
00027 #include "Terrain3D.h"
00028 
00029 #include <SDL.h>
00030 
00031 
00033 float dist = 0.0;
00034 int cpt_mvt = 0;
00035 int mvtPorte = 2;
00036 int posPorte = 0;
00037 bool debut_descente_chute = false;
00038 bool debut_descente_nuag = false;
00039 
00040 #include "C_Chute.h"
00041 #include "CallbackPorte.h"
00042 #include "CallbackTurbine.h"
00043 #include "keyboardEventHandler.h"
00044 
00045 
00046 
00047         osg::PositionAttitudeTransform * pat_dam;
00048          osg::PositionAttitudeTransform * pat1;
00049          osg::PositionAttitudeTransform * pat2_2;
00050          osg::Quat* quaternion; 
00051          osg::Geode * geo2;
00052 
00053  class findNodeVisitor : public osg::NodeVisitor
00054 {
00055         private:
00056                 std::string searchName;
00057                 
00058         public:
00059                 typedef std::vector<osg::Node*> TNodeList;
00060                 TNodeList results;
00061                 findNodeVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN){}
00062                 void setSearchName (const std::string &searchName){this->searchName=searchName;results.clear();}
00063                 virtual void apply (osg::Node &searchNode){
00064                         if (searchNode.getName().compare(0, searchName.length(),searchName)==0)
00065                                 results.push_back (&searchNode);
00066                         traverse(searchNode);   
00067                 }
00068 };
00069 
00070 void monter (){
00071         mvtPorte = LEVER;
00072 }
00073 
00074 void descendre (){
00075         mvtPorte = DESCENDRE;
00076 }
00077 
00078 void stop(){
00079         mvtPorte = ARRETER;
00080 }
00081 
00084 using namespace osg;
00085 
00086 Scene3D::Scene3D(){
00087         rootNode = new osg::Group();
00088         rootStateSet = rootNode->getOrCreateStateSet();
00089         soundMgr=NULL;
00090         trees=true;
00091         fogs=true;
00092         sound=false;
00093 }
00094 
00095 Scene3D::~Scene3D()
00096 { 
00097         if(soundMgr!=NULL)
00098         {
00099                 std::cout<< "suppression de la scene..."<<std::endl;
00100                 delete soundMgr;
00101         }
00102 }
00103 
00104 void Scene3D::attach(osgProducer::Viewer* sceneview){
00105         sceneview->setSceneData(rootNode.get());
00106         viewer = sceneview;
00107 }
00108 
00109 
00110 void Scene3D::update() {
00111 // x_rotator->run();
00112 // y_rotator->run();
00113 // z_rotator->run();
00114 }
00115 
00116 void Scene3D::optimize(osg::Node* root)
00117 {
00118         // run optimization over the scene graph after the soundnodes are added 
00119         // otherwise in this case the transformation added earlier would dissapear.
00120         osgUtil::Optimizer optimzer;
00121         optimzer.optimize(root);
00122 }
00123 void Scene3D::initSound(){
00124         
00125         //instanciation d'un objet SoundManager
00126         Scene3D::soundMgr = new SoundManager(rootNode.get());
00127         //initialisation du son...
00128         std::cout<< "initialisation du son..." << std::endl;
00129         this->sound = Scene3D::soundMgr->init();
00130 }
00131 
00132 
00133 void Scene3D::createScene() 
00134 {
00135         
00136         std::cout << "Création de la scene.." <<std::endl;
00137 
00139         osg::Group* terrain = new osg::Group;
00140         int nbtrees = 700;
00141     if(!trees) nbtrees=0;
00142 
00143         Terrain3D* t3D = new Terrain3D("Heightmap\\heightmap.bmp",terrain,nbtrees); 
00144         if(!t3D->Ok())
00145         {
00146                 std::cout <<"Erreur lors de la création de la HeightMap" << std::endl;
00147                 
00148                 //return 1;
00149         }
00150         std::cout <<"Terrain créé!\n";
00151         //terrain = t3D->getGeode();
00152         terrain->addChild(t3D->getGeode());
00153         
00154         float xMin=0;
00155         float xMax=512;
00156         float yMin=0;
00157         float yMax=512;
00158         float z=-10;
00159         
00160         
00161         osg::Geode* terrain_geode = new osg::Geode();
00162         
00163         osg::Geometry* underterrain_geometry = new osg::Geometry;
00164         osg::Vec3Array* coords = new osg::Vec3Array(4);
00165         (*coords)[0].set(xMin,yMax,z);
00166         (*coords)[1].set(xMin,yMin,z);
00167         (*coords)[2].set(xMax,yMin,z);
00168         (*coords)[3].set(xMax,yMax,z);
00169         underterrain_geometry->setVertexArray(coords);
00170         osg::Vec3Array* norms = new osg::Vec3Array(1);
00171         (*norms)[0].set(0.0f,0.0f,1.0f);
00172         underterrain_geometry->setNormalArray(norms);
00173         underterrain_geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
00174         osg::Vec4Array* colours = new osg::Vec4Array(1);
00175         (*colours)[0].set(0.0f,0.0f,0.0f,0.9f);
00176         underterrain_geometry->setColorArray(colours);
00177         underterrain_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00178         underterrain_geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
00179         
00180         terrain_geode->addDrawable(underterrain_geometry);
00181         
00182         
00183         
00184         
00185         terrain->addChild(terrain_geode);
00186         
00187         
00188         
00189         osg::PositionAttitudeTransform * pat = new osg::PositionAttitudeTransform();
00190         pat->addChild(terrain);
00191         osg::Quat*  quaternion = new osg::Quat();
00192         quaternion->makeRotate(0.50,0,0,1);
00193         pat->setAttitude(*quaternion);
00194         pat->setScale(osg::Vec3(0.2,0.2,0.15));
00195         pat->setPosition(osg::Vec3(29,-14,-9));
00196         
00197         terrain = pat;
00198 
00199                 
00200         //rootNode->addChild(n);
00201         
00203         std::cout << "Création des plans d'eau et du barrage..." <<std::endl;
00204         osg::Group* scene_all = initWater(rootNode,this->viewer,terrain,fogs);
00205         
00206         
00207         std::cout << "Création des chutes d'eau......";
00208         
00210         osg::Group* scene_particles = new osg::Group();
00211         creerChutesEtAnim(scene_particles);
00212         pat = new osg::PositionAttitudeTransform();
00213         pat->addChild(scene_particles);
00214         //pat->setScale(osg::Vec3(5,5,5));
00215         pat->setPosition(osg::Vec3(13.855,1.6,-15.42));
00216 
00217         //scene_all->addChild(pat);
00218         
00219         osg::PositionAttitudeTransform* pat2 = new osg::PositionAttitudeTransform();
00220         pat2->addChild(scene_all);
00221         //pat2->setScale(osg::Vec3(0.1,0.1,0.1));
00222         //pat2->setPosition(osg::Vec3(330,280,-60));
00223         
00224         std::cout << "........ [OK]" <<std::endl;
00225         
00226         
00228         SkyBox * sb = new SkyBox();
00229         osg::Node * n = sb->createSkyBox();
00230         
00231         osg::PositionAttitudeTransform* pat3 = new osg::PositionAttitudeTransform();
00232         pat3->addChild(pat);
00233         pat3->addChild(pat2);
00234         pat3->addChild(n);
00235         viewer->setSceneData(pat3);
00236         
00239         osg::Node * helico = osgDB::readNodeFile("Models/helicopter/as350b2.x");
00240         osg::Node * fishBoat = osgDB::readNodeFile("Models/boat/fishing-boat.3ds");
00241         osg::Node * fishBoat2 = osgDB::readNodeFile("Models/boat/dory.3ds");
00242         osg::Node * house = osgDB::readNodeFile("Models/objets/house01.3DS");
00243         
00245         rootNode->addChild(addObject(house,osg::Vec3d(-48,55,-7),osg::Vec3d(0.02, 0.02, 0.02)));
00246         
00248         //rootNode->addChild(addObject(fishBoat,osg::Vec3d(10,14,-8.8),osg::Vec3d(0.01, 0.01, 0.01)));
00249         rootNode->addChild(addObject(fishBoat2,osg::Vec3d(40,24,-8.83),osg::Vec3d(0.01, 0.01, 0.01)));
00250         
00251         //Ajout des nuages
00252         //setClouds(rootNode.get(),100);
00253         
00254         
00255         //Ajout de l'hélico
00256         osg::Vec3 center(29,-14,29);
00257         float radius = 100.0f;
00258         osg::Vec3 center1(10,-24,-9);
00259         osg::Vec3 center2(24,-10,29);
00260         std::cout << "Ajout de l'helico" << std::endl;
00261         
00262         float scale=1.5f;
00263         rootNode->addChild(this->createMovingModel(helico,scale,"data/Sounds/helicopter.wav",center,radius*0.8f,0.7));
00264 
00265         std::cout << "Objets ok." <<std::endl;
00266         
00269         if(this->sound)
00270         {
00271                 
00272                 addSoundSource("data/Sounds/waterfall1.wav",15,-3.5,-15.0,1.5f,20);
00273                 
00274                         
00275                 std::cout << "Sounds ok." <<std::endl;
00276                 
00277         }
00278         
00279         std::cout << "Création des lumières......";
00280         
00281         
00282         //return;
00283         
00284                 //Create 3 rotators, each with a unique PAT, and each with a unique axis
00285                 //x_rotator = new Rotator(*x_model_pat, Rotator::X_AXIS);
00286                 //y_rotator = new Rotator(*y_model_pat, Rotator::Y_AXIS);
00287                 //z_rotator = new Rotator(*z_model_pat, Rotator::Z_AXIS);
00288                 
00289                 // Create the lights
00290                 // Extract the light manager from the module registry, and initalize
00291                 // with the osg::Group node that contains the rest of our scene data.
00292         lightManager.init(rootNode.get());
00293         {
00294                 osg::Light * 
00295                                 light = lightManager.getOrCreateLight(LightManager::ONE);
00296                 // We turn off ambient light as it is on slightly as default by osg::Light.
00297                 light->setAmbient(osg::Vec4d(0.7, 0.7, 0.7, 0.7));
00298                 light->setDiffuse(osg::Vec4d(0.6, 0.5, 0.3, 1.0));      //Sun light
00299                 light->setPosition(osg::Vec4d(10.0, 0.0, 500.0, 1.0));
00300                         
00301                 /*
00302                 This determines how far the light will travel away from the light
00303                 source, by defining the level of attenuation. Note that this is
00304                 quadratic, meaning the light power is inversely proportional to
00305                 the distance squared. There is also constant and linear attenuation,
00306                 but those do not really provide a realistic method for attenuation.
00307                 */
00308                 light->setConstantAttenuation(0.05);
00309                 //light->setLinearAttenuation(0.05);
00310                 //light->setQuadraticAttenuation(0.05);
00311         }
00312         
00313         //Create second light
00314         {
00315                 osg::Light * 
00316                                 light = lightManager.getOrCreateLight(LightManager::TWO);
00317                 light->setAmbient(osg::Vec4d(1.0, .5, 0.0, 1.0));
00318                 light->setDiffuse(osg::Vec4d(1.0, 0.8, 0.0, 1.0));      //Green light
00319                 light->setPosition(osg::Vec4d(-300.0, 0.0, 10.0, 1.0));
00320                 light->setConstantAttenuation(0.05);
00321                 //light->setLinearAttenuation(0.05);
00322                 //light->setQuadraticAttenuation(0.05);
00323         }
00324                 
00325         //Create third light
00326         {
00327                 osg::Light * 
00328                                 light = lightManager.getOrCreateLight(LightManager::THREE);
00329                 light->setAmbient(osg::Vec4d(0.0, 0.0, 0.0, 1.0));
00330                 light->setDiffuse(osg::Vec4d(0.0, 1.0, 1.0, 1.0));      //Blue Light
00331                 light->setPosition(osg::Vec4d(-90.0, 30.0, 5.0, 1.0));
00332                 light->setConstantAttenuation(0.05);
00333                 //light->setLinearAttenuation(0.05);
00334                 light->setQuadraticAttenuation(0.05);
00335         }
00336         std::cout << ".......[OK]." <<std::endl;
00337         
00338         
00339         //this->setSky();
00340         //this->setSkyLightColor(osg::Vec4(0.24,0.23,0.14,1));
00341         std::cout << "Scene: done." <<std::endl;
00342         //rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
00343 }
00344 
00345 void Scene3D::setSky()
00346 {
00347                 // Create the root node
00348         root = new osg::MatrixTransform();  
00349         rootStateSet = root->getOrCreateStateSet();
00350         
00351         // Fog
00352         osg::Fog* fog = new osg::Fog();  
00353         fog->setMode(osg::Fog::LINEAR);
00354         fog->setDensity(0.9f);  
00355         rootStateSet->setAttribute(fog, osg::StateAttribute::ON);  
00356         rootStateSet->setMode(GL_FOG, osg::StateAttribute::ON);  
00357         
00358         // Sunlight
00359         osg::Light* light = new osg::Light;    
00360         light->setLightNum(0);  
00361         skyLight = new osg::LightSource();
00362         skyLight->setLight(light);
00363         skyLight->setLocalStateSetModes(osg::StateAttribute::ON); 
00364         rootStateSet->setAssociatedModes(light, osg::StateAttribute::ON);
00365         
00366         // Backlight
00367         osg::Light* light2 = new osg::Light;
00368         light2->setLightNum(1);
00369         backLight = new osg::LightSource();
00370         backLight->setLight(light2);
00371         backLight->setLocalStateSetModes(osg::StateAttribute::ON); 
00372         rootStateSet->setAssociatedModes(light2, osg::StateAttribute::ON);  
00373         
00374         /*
00375         osg::LightModel* lightModel = new osg::LightModel();
00376         lightModel->setAmbientIntensity(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
00377         lightModel->setLocalViewer(false);
00378         lightModel->setTwoSided(false);
00379         lightModel->setColorControl(osg::LightModel::SEPARATE_SPECULAR_COLOR);
00380         rootStateSet->setAttribute(lightModel);
00381         rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
00382         */      
00383         
00384         // Create the Skydome node
00385         skyDome = new osg::MatrixTransform();  
00386         skyDome->addChild(new osg::Node());
00387         clouds = new osg::MatrixTransform();  
00388         clouds->addChild(new osg::Node());
00389         // Don't load graphics for the skydome yet, this will be done in setSkyDome()
00390         
00391         // Create the Sky node and add the SkyLight, Clouds and SkyDome nodes as it's children
00392         sky = new osg::MatrixTransform();
00393         sky->addChild(skyLight.get());
00394         sky->addChild(backLight.get());
00395         sky->addChild(skyDome.get());
00396         sky->addChild(clouds.get());
00397         
00398         // Add the Sky Node as a child to the root node
00399         root->asGroup()->addChild(sky.get());   
00400         rootNode->addChild(root.get());
00401 }
00402 
00403 void Scene3D::setVisibilityRange(float range) 
00404 {
00405         osg::Fog* fog = dynamic_cast<osg::Fog*>(rootStateSet->getAttribute(osg::StateAttribute::FOG));
00406         fog->setStart(0.0f);
00407         fog->setEnd(range);  
00408 }
00409 
00410 
00411 
00415 void Scene3D::setClouds(osg::Node* node, float height) 
00416 {
00417         osg::Fog* fog = dynamic_cast<osg::Fog*>(rootStateSet->getAttribute(osg::StateAttribute::FOG));
00418         float visibilityRange = fog->getEnd();
00419         clouds->setMatrix(osg::Matrix::scale(visibilityRange*0.9, height, visibilityRange*0.9));
00420         clouds->removeChild(0, 1);  
00421         osg::StateSet* stateset = node->getOrCreateStateSet();
00422         stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
00423         clouds->addChild(node); 
00424 }
00425 
00426 
00430 void Scene3D::setSkyLightColor(const osg::Vec4& color) 
00431 { 
00432         osg::Light* light = dynamic_cast<osg::Light*>(skyLight->getLight());
00433         light->setDiffuse(color);   
00434         light->setAmbient(color * 0.4);
00435         
00436         osg::Light* light2 = dynamic_cast<osg::Light*>(backLight->getLight());
00437         light2->setDiffuse(color * 0.4);
00438         light2->setAmbient(color * 0.0);
00439 }
00440 
00441 
00445 void Scene3D::setSkyLightPosition(const osg::Vec2& headingAzimuth) 
00446 {  
00447         
00448         // Get current visibilityRange
00449         osg::Fog* fog = dynamic_cast<osg::Fog*>(rootStateSet->getAttribute(osg::StateAttribute::FOG));
00450         float visibilityRange = fog->getEnd();  
00451         
00452         osg::Matrix matrix;
00453         matrix.preMult(osg::Matrix::rotate(-osg::DegreesToRadians(headingAzimuth.x()), osg::Vec3(0.0f, 1.0f, 0.0f)));    
00454         matrix.preMult(osg::Matrix::rotate(osg::DegreesToRadians(headingAzimuth.y()), osg::Vec3(1.0f, 0.0f, 0.0f)));    
00455         matrix.preMult(osg::Matrix::translate(osg::Vec3(0.0f, 0.0f, -visibilityRange)));
00456         
00457         osg::Light* light = dynamic_cast<osg::Light*>(skyLight->getLight());  
00458         light->setPosition(osg::Vec4(matrix.getTrans(), 1.0f));
00459         
00460         osg::Light* light2 = dynamic_cast<osg::Light*>(backLight->getLight());  
00461         light2->setPosition(-osg::Vec4(matrix.getTrans(), 1.0f));
00462 }
00463 
00464 
00465 osg::Node* Scene3D::addObject(osg::Node* node,osg::Vec3d pos,osg::Vec3d scale)
00466 {
00467         // Update texture matrix for cubemaps
00468         struct TexMatCallback : public osg::NodeCallback
00469         {
00470                 public:
00471                 
00472                 TexMatCallback(osg::TexMat& tm) :
00473                         _texMat(tm)
00474                 {
00475                 }
00476                 
00477                 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
00478                 {
00479                         osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
00480                         if (cv)
00481                         {
00482                         const osg::Matrix& MV = cv->getModelViewMatrix();
00483                         const osg::Matrix R = osg::Matrix::rotate( osg::DegreesToRadians(112.0f), 0.0f,0.0f,1.0f)*
00484                                                 osg::Matrix::rotate( osg::DegreesToRadians(90.0f), 1.0f,0.0f,0.0f);
00485                 
00486                         osg::Quat q = MV.getRotate();
00487                         const osg::Matrix C = osg::Matrix::rotate( q.inverse() );
00488                 
00489                         _texMat.setMatrix( C*R );
00490                         }
00491                 
00492                         traverse(node,nv);
00493                 }
00494                 
00495                 osg::TexMat& _texMat;
00496         };
00497         
00498         osg::StateSet* stateset = new osg::StateSet();
00499         
00500         osg::PositionAttitudeTransform * 
00501         position = new osg::PositionAttitudeTransform();
00502         position->setPosition(pos);
00503         position->setScale(scale);
00504         position->addChild(node);
00505         
00506         osg::TexMat* texMat = new osg::TexMat;
00507         stateset->setTextureAttribute(0, texMat);
00508         
00509         osg::TexEnvCombine *te0 = new osg::TexEnvCombine;    
00510         te0->setCombine_RGB(osg::TexEnvCombine::REPLACE);
00511         te0->setSource0_RGB(osg::TexEnvCombine::TEXTURE0);
00512         te0->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
00513         
00514         osg::TexEnvCombine *te1 = new osg::TexEnvCombine;    
00515         
00516         te1->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
00517         te1->setSource0_RGB(osg::TexEnvCombine::TEXTURE1);
00518         te1->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
00519         te1->setSource1_RGB(osg::TexEnvCombine::PREVIOUS);
00520         te1->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
00521         te1->setSource2_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
00522         te1->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);
00523         stateset->setTextureAttributeAndModes(0, te0, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
00524         stateset->setTextureAttributeAndModes(1, te1, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
00525         
00526         osg::Group* group = new osg::Group;
00527         group->addChild(position);
00528         //group->setCullCallback(new TexMatCallback(*texMat));
00529         group->setStateSet( stateset );
00530         stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
00531         return group;
00532 }
00533 
00538 void Scene3D::addSoundSource (const std::string & strFile, float x,float y, float z,float factor, float dist)
00539 {
00540 
00541 // Nécessaire pour s'assurer de l'update du listener
00542     osg::ref_ptr<osgAL::SoundRoot> sound_root = new osgAL::SoundRoot;
00543 
00544 
00545 // Sa position dans le graphe n'est pas importante.
00546 // IL faut juste que le cullTraversal soit appelé après chaque chgement sur le sounManager.
00547     rootNode->addChild(sound_root.get());
00548 
00549 
00550     // Creationde la transformation à la quelle on va attacher le sounNode
00551     osg::ref_ptr<osg::PositionAttitudeTransform> sound_transform = new osg::PositionAttitudeTransform;
00552     rootNode->addChild(sound_transform.get());
00553     sound_transform->setPosition(osg::Vec3(x,y,z));
00554 
00555     // Creation de la sphère qui matérialise le son
00556     /*
00557     osg::ref_ptr<osg::Geode> geode = new osg::Geode;
00558     osg::TessellationHints* hints = new osg::TessellationHints;
00559     hints->setDetailRatio(0.5f);
00560     geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),2),hints));
00561     sound_transform->addChild(geode.get());
00562     */
00563     osg::ref_ptr<osgAL::SoundNode> sound_node = new osgAL::SoundNode;
00564     sound_transform->addChild(sound_node.get());        
00565     std::cerr << "Son d'ambiance : "<< strFile <<"... chargé." << std::endl;
00566 
00567         osg::ref_ptr<openalpp::Sample> sample = osgAL::SoundManager::instance()->getSample(strFile.c_str(), true);
00568         //std::cerr << "Loading sample: " << strFile << std::endl;
00569         
00570         // Creation du SOundState avec le nom du fichier que nous chargeons.
00571         osg::ref_ptr<osgAL::SoundState> sound_state = new osgAL::SoundState(strFile);
00572         sound_state->setSample(sample.get());
00573         sound_state->setGain(factor);
00574         sound_state->setReferenceDistance(dist*.1);
00575         sound_state->setRolloffFactor(3);
00576         sound_state->setPlay(true);
00577         sound_state->setLooping(true);
00578         
00579         // Allocation d'une source materielle pour ce soundState de priorité 10)
00580         sound_state->allocateSource(10, false);
00581         
00582         // Ajout du soundState au sound manager pour le retrouver ensuite
00583         osgAL::SoundManager::instance()->addSoundState(sound_state.get());
00584         
00585         sound_state->apply();
00586         sound_node->setSoundState(sound_state.get());
00587 
00588 }
00597 osg::Drawable* Scene3D::createShrub(const float & scale, osg::StateSet* bbState)
00598 {
00599         // Taille du shrub
00600         float width = 1.5f;
00601         float height = 3.0f;
00602         
00603         // Mise à l'échelle
00604         width *= scale;
00605         height *= scale;
00606         
00607         // Initialisation d'un Geometry
00608         osg::Geometry* shrubQuad = new osg::Geometry;
00609         
00610         // Declare an array of vertices, assign values so we can create a
00611         // quadrilateral centered relative to the Z axis
00612         osg::Vec3Array* shrubVerts = new osg::Vec3Array(4);
00613         (*shrubVerts)[0] = osg::Vec3(-width/2.0f, 0, 0);
00614         (*shrubVerts)[1] = osg::Vec3( width/2.0f, 0, 0);
00615         (*shrubVerts)[2] = osg::Vec3( width/2.0f, 0, height);
00616         (*shrubVerts)[3] = osg::Vec3(-width/2.0f, 0, height);
00617         shrubQuad->setVertexArray(shrubVerts);
00618         
00619         // Déclaration et assignation des coordonnées texture
00620         osg::Vec2Array* shrubTexCoords = new osg::Vec2Array(4);
00621         (*shrubTexCoords)[0].set(0.0f,0.0f);
00622         (*shrubTexCoords)[1].set(1.0f,0.0f);
00623         (*shrubTexCoords)[2].set(1.0f,1.0f);
00624         (*shrubTexCoords)[3].set(0.0f,1.0f);
00625         shrubQuad->setTexCoordArray(0,shrubTexCoords);
00626         
00627         // Ajout de primitives (QUADS) au geometry
00628         shrubQuad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
00629         
00630         // S'assurer que le géometry est dans l'état correct
00631         shrubQuad->setStateSet(bbState);
00632         
00633         return shrubQuad;
00634 }               
00635 
00640 void Scene3D::addTree (const std::string & strFile, float x,float y, float z)
00641 {
00642         
00643         osg::Billboard* shrubBillBoard = new osg::Billboard();
00644                                 
00645         shrubBillBoard->setMode(osg::Billboard::AXIAL_ROT);
00646         shrubBillBoard->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
00647         shrubBillBoard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f));
00648         
00649         
00650         osg::Texture2D *treeTexture = new osg::Texture2D;
00651         treeTexture->setImage(osgDB::readImageFile(strFile));
00652         
00653         osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
00654         alphaFunc->setFunction(osg::AlphaFunc::GEQUAL,0.5f);
00655         
00656         osg::StateSet* billBoardStateSet = new osg::StateSet;
00657         
00658         billBoardStateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
00659         billBoardStateSet->setTextureAttributeAndModes                                          (0, treeTexture, osg::StateAttribute::ON );
00660         billBoardStateSet->setAttributeAndModes
00661         (new osg::BlendFunc, osg::StateAttribute::ON );
00662         osg::AlphaFunc* alphaFunction = new osg::AlphaFunc;
00663         alphaFunction->setFunction(osg::AlphaFunc::GEQUAL,0.05f);
00664         billBoardStateSet->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON );
00665 
00666         osg::Drawable* shrub1Drawable = createShrub( 30.0f, billBoardStateSet);
00667 
00668         // Add these drawables to our billboard at various positions
00669         shrubBillBoard->addDrawable( shrub1Drawable , osg::Vec3(x,y,z) );
00670         rootNode->addChild(shrubBillBoard);
00671 
00672 }
00673 
00674 
00675 osg::ref_ptr<osg::Group> Scene3D::getRootNode()
00676 {
00677         return rootNode;
00678 }
00679 osg::ref_ptr<osg::MatrixTransform> Scene3D::getRoot()
00680 {
00681         return root;
00682 }
00683 
00684 bool Scene3D::isSoundEnabled()
00685 {
00686         return sound;
00687 }
00688 
00689 void Scene3D::creerChutesEtAnim(osg::Group* scene)
00690 {
00691         
00692         keyboardEventHandler* keh = new keyboardEventHandler();
00693         viewer->getEventHandlerList().push_front(keh); 
00694         keh->addFunction('u',monter);
00695         keh->addFunction('d',descendre);
00696         keh->addFunction('s',stop);
00697         
00698         
00699         
00700         float espacement_portes = 0.55;
00701         osg::Group* grp_particules_porte_turbine = new osg::Group();
00702         
00703         //scene->addChild(grp_particules);
00704         osg::PositionAttitudeTransform* pat ;
00705         
00706         
00707         
00708         
00709         
00710 
00711         osg::Group * node_emitter = new osg::Group;
00712 
00713         osg::Group* grp_particules = new osg::Group();
00714 
00715         C_Chute *chute = new C_Chute(grp_particules,node_emitter,"dust23.rgb");
00716         chute->type = CHU;
00717         chute->lifeTime = 1;
00718         chute->mass = 0.7;
00719         chute->range_min = -0.07;
00720         chute->range_max = 0;
00721         //chute->nbGenerate = 250;
00722         chute->nbGenerate = 0;
00723         chute->radiusRangeMin = -0.08;
00724         chute->radiusRangeMax = 0.08;
00725         chute->enableShooter = true;
00726         chute->speedRangeMin = 2;
00727         chute->speedRangeMax = 3;
00728         chute->thetaRangeMax = 0.1;
00729         chute->thetaRangeMin = -0.1;
00730         chute->phiRangeMax = 0;
00731         chute->phiRangeMin = 0;
00732         chute->vecAcceleration = osg::Vec3(0,0,-5);
00733         //chute->Creer_Chute(35.380,-20.516,15.893);
00734         chute->Creer_Chute(0,-0.05,1);
00735 
00736         C_Chute *chute2 = new C_Chute(grp_particules,node_emitter,"dust23.rgb");
00737         chute2->type = CHU;
00738         chute2->lifeTime = 1;
00739         chute2->mass = 0.7;
00740         chute2->range_min = -0.07;
00741         chute2->range_max = 0;
00742         //chute->nbGenerate = 250;
00743         chute2->nbGenerate = 0;
00744         chute2->radiusRangeMin = -0.08;
00745         chute2->radiusRangeMax = 0.08;
00746         chute2->enableShooter = true;
00747         chute2->speedRangeMin = 2;
00748         chute2->speedRangeMax = 3;
00749         chute2->thetaRangeMax = 0.1;
00750         chute2->thetaRangeMin = -0.1;
00751         chute2->phiRangeMax = 0;
00752         chute2->phiRangeMin = 0;
00753         chute2->vecAcceleration = osg::Vec3(0,0,-5);
00754         //chute->Creer_Chute(35.380,-20.516,15.893);
00755         chute2->Creer_Chute(0.5625,-0.05,1);
00756 
00757         C_Chute *chute3 = new C_Chute(grp_particules,node_emitter,"dust23.rgb");
00758         chute3->type = CHU;
00759         chute3->lifeTime = 1;
00760         chute3->mass = 0.7;
00761         chute3->range_min = -0.07;
00762         chute3->range_max = 0;
00763         //chute->nbGenerate = 250;
00764         chute3->nbGenerate = 0;
00765         chute3->radiusRangeMin = -0.08;
00766         chute3->radiusRangeMax = 0.08;
00767         chute3->enableShooter = true;
00768         chute3->speedRangeMin = 2;
00769         chute3->speedRangeMax = 3;
00770         chute3->thetaRangeMax = 0.1;
00771         chute3->thetaRangeMin = -0.1;
00772         chute3->phiRangeMax = 0;
00773         chute3->phiRangeMin = 0;
00774         chute3->vecAcceleration = osg::Vec3(0,0,-5);
00775         //chute->Creer_Chute(35.380,-20.516,15.893);
00776         chute3->Creer_Chute(1.125,-0.05,1);
00777 
00778         C_Chute *chutehz = new C_Chute(grp_particules,node_emitter,"dust23.rgb");
00779         chutehz->type = HZ;
00780         chutehz->lifeTime = 2.1;
00781         chutehz->mass = 0.02;
00782         chutehz->range_min = -0.07;
00783         chutehz->range_max = 0;
00784         //chute3->nbGenerate = 250;
00785         chutehz->nbGenerate = 0;
00786         chutehz->radiusRangeMin = -0.1;
00787         chutehz->radiusRangeMax = 0.1;
00788         chutehz->enableShooter = true;
00789         chutehz->speedRangeMin = 2;
00790         chutehz->speedRangeMax = 3;
00791         chutehz->thetaRangeMax = 0.2;
00792         chutehz->thetaRangeMin = -0.2;
00793         chutehz->phiRangeMax = 0;
00794         chutehz->phiRangeMin = 0;
00795         chutehz->vecAcceleration = osg::Vec3(0,-10,0);
00796         chutehz->Creer_Chute(0,-0.12,-1.6);
00797         
00798         C_Chute *chutehz2 = new C_Chute(grp_particules,node_emitter,"dust23.rgb");
00799         chutehz2->type = HZ;
00800         chutehz2->lifeTime = 2.1;
00801         chutehz2->mass = 0.02;
00802         chutehz2->range_min = -0.07;
00803         chutehz2->range_max = 0;
00804         //chute3->nbGenerate = 250;
00805         chutehz2->nbGenerate = 0;
00806         chutehz2->radiusRangeMin = -0.1;
00807         chutehz2->radiusRangeMax = 0.1;
00808         chutehz2->enableShooter = true;
00809         chutehz2->speedRangeMin = 2;
00810         chutehz2->speedRangeMax = 3;
00811         chutehz2->thetaRangeMax = 0.2;
00812         chutehz2->thetaRangeMin = -0.2;
00813         chutehz2->phiRangeMax = 0;
00814         chutehz2->phiRangeMin = 0;
00815         chutehz2->vecAcceleration = osg::Vec3(0,-10,0);
00816         chutehz2->Creer_Chute(0.5625,-0.12,-1.7);
00817 
00818         C_Chute *chutehz3 = new C_Chute(grp_particules,node_emitter,"dust23.rgb");
00819         chutehz3->type = HZ;
00820         chutehz3->lifeTime = 2.1;
00821         chutehz3->mass = 0.02;
00822         chutehz3->range_min = -0.07;
00823         chutehz3->range_max = 0;
00824         //chute3->nbGenerate = 250;
00825         chutehz3->nbGenerate = 0;
00826         chutehz3->radiusRangeMin = -0.1;
00827         chutehz3->radiusRangeMax = 0.1;
00828         chutehz3->enableShooter = true;
00829         chutehz3->speedRangeMin = 2;
00830         chutehz3->speedRangeMax = 3;
00831         chutehz3->thetaRangeMax = 0.2;
00832         chutehz3->thetaRangeMin = -0.2;
00833         chutehz3->phiRangeMax = 0;
00834         chutehz3->phiRangeMin = 0;
00835         chutehz3->vecAcceleration = osg::Vec3(0,-10,0);
00836         chutehz3->Creer_Chute(1.125,-0.12,-1.7);
00837         
00838         C_Chute *chutenuag = new C_Chute (grp_particules,node_emitter,"nuage.rgb");
00839         chutenuag->type = NUAG;
00840         chutenuag->lifeTime = 1;
00841         chutenuag->mass = 0.05;
00842         chutenuag->range_min = -0.03;
00843         chutenuag->range_max = 0.0;
00844         //chutenuag->nbGenerate = 200;
00845         chutenuag->nbGenerate = 0;
00846         chutenuag->enableShooter = true;
00847         chutenuag->radiusRangeMin = 0.0;
00848         chutenuag->radiusRangeMax = 0.05;
00849         chutenuag->thetaRangeMin = 0;//osg::PI/2;
00850         chutenuag->thetaRangeMax = 2*osg::PI;//3*osg::PI/2;
00851         chutenuag->phiRangeMin = 0;//osg::PI/2;
00852         chutenuag->phiRangeMax = 2*osg::PI;//3*osg::PI/2;
00853         chutenuag->speedRangeMin = 0.2;
00854         chutenuag->speedRangeMax = 1;
00855         chutenuag->enableAcc = false;
00856         //chutenuag->Creer_Chute(35.380,-21.5,17.2);    
00857         chutenuag->Creer_Chute(0,-0.5,2.1);     
00858 
00859         C_Chute *chutenuag2 = new C_Chute (grp_particules,node_emitter,"nuage.rgb");
00860         chutenuag2->type = NUAG;
00861         chutenuag2->lifeTime = 1;
00862         chutenuag2->mass = 0.05;
00863         chutenuag2->range_min = -0.03;
00864         chutenuag2->range_max = 0.0;
00865         //chutenuag->nbGenerate = 200;
00866         chutenuag2->nbGenerate = 0;
00867         chutenuag2->enableShooter = true;
00868         chutenuag2->radiusRangeMin = 0.0;
00869         chutenuag2->radiusRangeMax = 0.05;
00870         chutenuag2->thetaRangeMin = 0;//osg::PI/2;
00871         chutenuag2->thetaRangeMax = 2*osg::PI;//3*osg::PI/2;
00872         chutenuag2->phiRangeMin = 0;//osg::PI/2;
00873         chutenuag2->phiRangeMax = 2*osg::PI;//3*osg::PI/2;
00874         chutenuag2->speedRangeMin = 0.2;
00875         chutenuag2->speedRangeMax = 1;
00876         chutenuag2->enableAcc = false;
00877         //chutenuag->Creer_Chute(35.380,-21.5,17.2);    
00878         chutenuag2->Creer_Chute(0.5625,-0.5,2.1);       
00879 
00880         C_Chute *chutenuag3 = new C_Chute (grp_particules,node_emitter,"nuage.rgb");
00881         chutenuag3->type = NUAG;
00882         chutenuag3->lifeTime = 1;
00883         chutenuag3->mass = 0.05;
00884         chutenuag3->range_min = -0.03;
00885         chutenuag3->range_max = 0.0;
00886         chutenuag3->nbGenerate = 200;
00887         //chutenuag3->nbGenerate = 0;
00888         chutenuag3->enableShooter = true;
00889         chutenuag3->radiusRangeMin = 0.0;
00890         chutenuag3->radiusRangeMax = 0.05;
00891         chutenuag3->thetaRangeMin = 0;//osg::PI/2;
00892         chutenuag3->thetaRangeMax = 2*osg::PI;//3*osg::PI/2;
00893         chutenuag3->phiRangeMin = 0;//osg::PI/2;
00894         chutenuag3->phiRangeMax = 2*osg::PI;//3*osg::PI/2;
00895         chutenuag3->speedRangeMin = 0.2;
00896         chutenuag3->speedRangeMax = 1;
00897         chutenuag3->enableAcc = false;
00898         //chutenuag->Creer_Chute(35.380,-21.5,17.2);    
00899         chutenuag3->Creer_Chute(1.125,-0.5,2.1);        
00900         //R�cup�ration de tous les objets depuis le .3ds
00901         
00902 
00903         
00904         osg::Vec3 posis_part(-6.91,-2+1.2,7.75);
00905         
00906         pat = new osg::PositionAttitudeTransform();
00907         pat->addChild(grp_particules);
00908         pat->setPosition(posis_part);//+2.05
00909         //osg::Quat quaternion3;        quaternion3.makeRotate(1.57,1,0,0); pat->setAttitude(quaternion3);
00910         grp_particules_porte_turbine->addChild(pat);
00911         
00912         
00913         
00914         
00915         //scene->addChild(grp_particules);
00916 
00917         
00918 
00919         pat = new osg::PositionAttitudeTransform();
00920         pat->addChild(node_emitter);
00921         //pat->setPosition(osg::Vec3(-6.91,-2+2.05,8.52));//+2.05
00922         osg::Quat quaternion2;
00923         quaternion2.makeRotate(1.57,1,0,0);
00924         pat->setAttitude(quaternion2);
00925         pat->setPosition(posis_part);//+2.05
00926         //toto->setPosition(osg::Vec3(10,10,10));
00927         grp_particules_porte_turbine->addChild(pat);
00928 
00929         
00930         
00931         
00932         
00933         
00934         //R�cup�ration de tous les objets depuis le .3ds
00935         osg::Node * barrage = osgDB::readNodeFile("Models/barrage/essai44.3ds");
00936         
00937         //Barrage
00938         findNodeVisitor fnv;
00939         /*
00940         fnv.setSearchName("barrageHaut");
00941         barrage->accept(fnv);
00942         pat = new osg::PositionAttitudeTransform();
00943         pat->addChild(fnv.results[0]);
00944         pat->setPivotPoint(osg::Vec3(0,0,0));
00945         scene->addChild(pat);
00946         */
00947         
00948         osg::PositionAttitudeTransform* pat_porte_turbine = new osg::PositionAttitudeTransform();
00949         //pat_porte_turbine->setScale(osg::Vec3(10,10,10));
00950         //pat_porte_turbine->setPosition(osg::Vec3(80,0,10));
00951         osg::Quat quaternion3;  quaternion3.makeRotate(1.57,1,0,0);
00952         pat_porte_turbine->setAttitude(quaternion3);
00953 
00954         //Porte 1
00955         fnv.setSearchName("porte1");
00956         barrage->accept(fnv);
00957         osg::Geode * geo1 = dynamic_cast <osg::Geode * > (fnv.results[0]);
00958         pat1 = new osg::PositionAttitudeTransform();
00959         pat1->addChild(geo1);
00960         
00961         osg::StateSet * st = geo1->getOrCreateStateSet();
00962         osg::Image* image = osgDB::readImageFile("Models/barrage/metal4.gif");
00963         if (image)
00964         {
00965                 osg::Texture2D* texture = new osg::Texture2D;
00966                 texture->setImage(image);
00967                 st->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
00968                 
00969         }else std::cout<<"Erreur, impossible d'ouvrir la texture de la porte";
00970         
00971         pat_porte_turbine->addChild(pat1);
00972         
00973         //grp_particules->addChild(pat1);
00974 
00975         int colorindex=0;
00976         if(geo1)
00977         {
00978                 osg::Drawable * draw1 = geo1->getDrawable(0);
00979                 draw1->setUserData(new CallbackPorte(colorindex,draw1));
00980                 geo1->setUpdateCallback(new geodePorteCallback());
00981         }
00982 
00983         
00984         //Turbine 1
00985         fnv.setSearchName("turbine1");
00986         barrage->accept(fnv);
00987         geo2 = dynamic_cast <osg::Geode * > (fnv.results[0]);
00988         
00989         pat2_2 = new osg::PositionAttitudeTransform();
00990         quaternion = new osg::Quat();
00991         pat2_2->setPosition(osg::Vec3(0.02,0,0));
00992         pat2_2->addChild(geo2);
00993         
00994         pat_porte_turbine->addChild(pat2_2);
00995         
00996         st = pat2_2->getOrCreateStateSet();
00997         image = osgDB::readImageFile("Models/barrage/metal4.gif");
00998         if (image)
00999         {
01000                 osg::Texture2D* texture = new osg::Texture2D;
01001                 texture->setImage(image);
01002                 st->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
01003                 
01004         }else std::cout<<"Erreur, impossible d'ouvrir la texture de la turbine";
01005         
01006         // couleur sous la mer
01007         osg::Vec4 dark_blue = osg::Vec4(0.0, 0.0, 0.15, 0.9);
01008         
01009         FogCube* fogcube = new FogCube();
01010         fogcube->setMode(osg::Fog::LINEAR);
01011         fogcube->setColor(dark_blue);
01012         fogcube->setStart(0.0);
01013         fogcube->setEnd(40.0);
01014         fogcube->setDensity(0.075);
01015         //fogcube->addFog(damNode);
01016         fogcube->setCube(-50,50,-50,50,-50,50);
01017         fogcube->addFog(pat_porte_turbine);
01018         
01019         grp_particules_porte_turbine->addChild(pat_porte_turbine);
01020         pat = new osg::PositionAttitudeTransform();
01021         pat->addChild(pat_porte_turbine);
01022         pat->setPosition(osg::Vec3(espacement_portes,0,0));
01023         grp_particules_porte_turbine->addChild(pat);
01024         pat = new osg::PositionAttitudeTransform();
01025         pat->addChild(pat_porte_turbine);
01026         pat->setPosition(osg::Vec3(espacement_portes*2.0,0,0));
01027         grp_particules_porte_turbine->addChild(pat);
01028         //grp_particules->addChild(pat2_2);
01029         
01030         scene->addChild(grp_particules_porte_turbine);
01031         
01032         
01033         if(geo2)
01034         {
01035                 osg::Drawable * draw2 = geo2->getDrawable(0);
01036                 draw2->setUserData(new CallbackTurbine(colorindex,draw2));
01037                 geo2->setUpdateCallback(new geodeTurbineCallback());
01038         }
01039         
01040 }
01041 
01042 
01043 
01044 osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime,float speed)
01045 {
01046     // set up the animation path 
01047         osg::AnimationPath* animationPath = new osg::AnimationPath;
01048         animationPath->setLoopMode(osg::AnimationPath::LOOP);
01049     
01050         int numSamples = 240;
01051         float yaw = 0.0f;
01052         float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
01053         float roll = osg::inDegrees(-20.0f);
01054     
01055         double time=0.0f;
01056         double time_delta = looptime/(double)numSamples*(1/speed);
01057         for(int i=0;i<numSamples;++i)
01058         {
01059                 osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
01060                 osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(180.0f)),osg::Vec3(0.0,0.0,1.0)));
01061         
01062                 animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
01063 
01064                 yaw += yaw_delta;
01065                 time += time_delta;
01066 
01067         }
01068         return animationPath;    
01069 }
01070 
01071 osg::Node* Scene3D::createMovingModel(Node* n,float scale,const std::string & soundFile,const osg::Vec3& center, float radius, float speed)
01072 {
01073         float animationLength = 30.0f;
01074 
01075         osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength,speed);
01076 
01077         osg::Group* model = new osg::Group;
01078 
01079         if (n)
01080         {
01081                 const osg::BoundingSphere& bs = n->getBound();
01082 
01083         //float size = radius/bs.radius()*0.3f;
01084                 osg::MatrixTransform* positioned = new osg::MatrixTransform;
01085                 positioned->setDataVariance(osg::Object::STATIC);
01086                 positioned->setMatrix(osg::Matrix::translate(-bs.center())*
01087                                 osg::Matrix::scale(scale,scale,scale)*
01088                                 osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));
01089 
01090                 positioned->addChild(n);
01091 
01092                 if(sound && soundFile!=""){
01093         // Create a sound node
01094                         osg::ref_ptr<osgAL::SoundNode> sound_node = soundMgr->createSound(soundFile);
01095 
01096         // Add the sound node
01097                         positioned->addChild(sound_node.get());
01098                 }       
01099 
01100                 osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;    
01101                 xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
01102                 xform->addChild(positioned);
01103 
01104                 model->addChild(xform);
01105         }
01106  
01107         return model;
01108 }

Generated on Tue Jun 5 16:56:48 2007 for Anidam by  doxygen 1.5.1